From 9f518de27b9be0e374bc5234f9951306a0786447 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 22 Dec 2019 23:43:36 +0200 Subject: [PATCH 001/128] 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 From 67dfd0614911f378d5685442acf6dc50f82f512a Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Mon, 23 Dec 2019 02:39:44 +0200 Subject: [PATCH 002/128] Started working on macOS platform layer. --- platform_mac/mac_4ed.mm | 16 ++++++++++++++++ platform_mac/{mac_4ed.cpp => mac_4ed_old.cpp} | 0 platform_mac/{mac_4ed.m => mac_4ed_old.m} | 0 platform_win32/win32_4ed.cpp | 2 +- 4 files changed, 17 insertions(+), 1 deletion(-) create mode 100644 platform_mac/mac_4ed.mm rename platform_mac/{mac_4ed.cpp => mac_4ed_old.cpp} (100%) rename platform_mac/{mac_4ed.m => mac_4ed_old.m} (100%) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm new file mode 100644 index 00000000..e5993845 --- /dev/null +++ b/platform_mac/mac_4ed.mm @@ -0,0 +1,16 @@ +int +main(int arg_count, char **args){ + Thread_Context _tctx = {}; + thread_ctx_init(&_tctx, ThreadKind_Main, + get_base_allocator_system(), + get_base_allocator_system()); + + block_zero_struct(&global_mac_vars); + global_mac_vars.tctx = &_tctx; + + // NOTE(yuval): Application Core Update + Application_Step_Result result = {}; + if (app.step != 0){ + result = app.step(mac_vars.tctx, &target, base_ptr, &input); + } +} \ No newline at end of file diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed_old.cpp similarity index 100% rename from platform_mac/mac_4ed.cpp rename to platform_mac/mac_4ed_old.cpp diff --git a/platform_mac/mac_4ed.m b/platform_mac/mac_4ed_old.m similarity index 100% rename from platform_mac/mac_4ed.m rename to platform_mac/mac_4ed_old.m diff --git a/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index 0ed48a78..e1fec7a4 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -335,7 +335,7 @@ system_set_fullscreen_sig(){ internal system_is_fullscreen_sig(){ - // NOTE(allen): Report the fullscreen status as it would be set at the beginning of the + // NOTE(allen): Report the fullscreen status as it would be set at the beginning of the // next frame. That is, take into account all fullscreen toggle requests that have come in // already this frame. Read: "full_screen XOR do_toggle" b32 result = (win32vars.full_screen != win32vars.do_toggle); From d28a1d6aba92c48f2f57d938214a1a20a9e73643 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 22 Dec 2019 20:50:54 -0800 Subject: [PATCH 003/128] Fixed theme config --- custom/4coder_config.cpp | 8 +++--- custom/4coder_default_colors.cpp | 23 +++++++++++++++++ custom/4coder_default_hooks.cpp | 42 +++++++++++++++++++++++++++++--- custom/4coder_insertion.cpp | 16 ++++++------ 4 files changed, 73 insertions(+), 16 deletions(-) diff --git a/custom/4coder_config.cpp b/custom/4coder_config.cpp index bb283b16..7cff6e52 100644 --- a/custom/4coder_config.cpp +++ b/custom/4coder_config.cpp @@ -1555,11 +1555,9 @@ load_config_and_apply(Application_Links *app, Arena *out_arena, Config_Data *con change_mode(app, config->mode); global_set_setting(app, GlobalSetting_LAltLCtrlIsAltGr, config->lalt_lctrl_is_altgr); - // TODO(allen): -#if 0 - change_theme(app, config->default_theme_name.str, config->default_theme_name.size); - #endif - + Color_Table *colors = get_color_table_by_name(config->default_theme_name); + set_active_color(colors); + Face_Description description = {}; if (override_font_size != 0){ description.parameters.pt_size = override_font_size; diff --git a/custom/4coder_default_colors.cpp b/custom/4coder_default_colors.cpp index 7e9bdd53..e0820dd9 100644 --- a/custom/4coder_default_colors.cpp +++ b/custom/4coder_default_colors.cpp @@ -156,6 +156,13 @@ set_default_color_scheme(Application_Links *app){ //////////////////////////////// +function void +set_active_color(Color_Table *table){ + if (table != 0){ + active_color_table = *table; + } +} + function void save_theme(Color_Table table, String_Const_u8 name){ Color_Table_Node *node = push_array(&global_theme_arena, Color_Table_Node, 1); @@ -165,4 +172,20 @@ save_theme(Color_Table table, String_Const_u8 name){ node->table = table; } +//////////////////////////////// + +function Color_Table* +get_color_table_by_name(String_Const_u8 name){ + Color_Table *result = 0; + for (Color_Table_Node *node = global_theme_list.first; + node != 0; + node = node->next){ + if (string_match(node->name, name)){ + result = &node->table; + break; + } + } + return(result); +} + // BOTTOM diff --git a/custom/4coder_default_hooks.cpp b/custom/4coder_default_hooks.cpp index 76c0db40..38ce6ea3 100644 --- a/custom/4coder_default_hooks.cpp +++ b/custom/4coder_default_hooks.cpp @@ -11,12 +11,12 @@ CUSTOM_DOC("Default command for responding to a startup event") User_Input input = get_current_input(app); if (match_core_code(&input, CoreCode_Startup)){ String_Const_u8_Array file_names = input.event.core.file_names; + load_themes_default_folder(app); default_4coder_initialize(app, file_names); default_4coder_side_by_side_panels(app, file_names); if (global_config.automatically_load_project){ load_project(app); } - load_themes_default_folder(app); } } @@ -932,8 +932,44 @@ BUFFER_HOOK_SIG(default_begin_buffer){ } BUFFER_HOOK_SIG(default_new_file){ - // buffer_id - // no meaning for return + Scratch_Block scratch(app); + String_Const_u8 file_name = push_buffer_base_name(app, scratch, buffer_id); + if (!string_match(string_postfix(file_name, 2), string_u8_litexpr(".h"))) { + return(0); + } + + List_String_Const_u8 guard_list = {}; + for (u64 i = 0; i < file_name.size; ++i){ + u8 c[2] = {}; + u64 c_size = 1; + u8 ch = file_name.str[i]; + if (ch == '.'){ + c[0] = '_'; + } + else if (ch >= 'A' && ch <= 'Z'){ + c_size = 2; + c[0] = '_'; + c[1] = ch; + } + else if (ch >= 'a' && ch <= 'z'){ + c[0] = ch - ('a' - 'A'); + } + String_Const_u8 part = push_string_copy(scratch, SCu8(c, c_size)); + string_list_push(scratch, &guard_list, part); + } + String_Const_u8 guard = string_list_flatten(scratch, guard_list); + + Buffer_Insertion insert = begin_buffer_insertion_at_buffered(app, buffer_id, 0, scratch, KB(16)); + insertf(&insert, + "#ifndef %.*s\n" + "#define %.*s\n" + "\n" + "#endif //%.*s\n", + string_expand(guard), + string_expand(guard), + string_expand(guard)); + end_buffer_insertion(&insert); + return(0); } diff --git a/custom/4coder_insertion.cpp b/custom/4coder_insertion.cpp index e548aa29..2d250954 100644 --- a/custom/4coder_insertion.cpp +++ b/custom/4coder_insertion.cpp @@ -44,7 +44,7 @@ insert_string__no_buffering(Buffer_Insertion *insertion, String_Const_u8 string) insertion->at += string.size; } -static void +function void insert__flush(Buffer_Insertion *insertion){ Cursor *cursor = insertion->cursor; u64 pos = insertion->temp.temp_memory_cursor.pos; @@ -53,7 +53,7 @@ insert__flush(Buffer_Insertion *insertion){ end_temp(insertion->temp); } -static char* +function char* insert__reserve(Buffer_Insertion *insertion, u64 size){ char *space = push_array(insertion->cursor, char, size); if (space == 0){ @@ -63,14 +63,14 @@ insert__reserve(Buffer_Insertion *insertion, u64 size){ return(space); } -static void +function void end_buffer_insertion(Buffer_Insertion *insertion){ if (insertion->buffering){ insert__flush(insertion); } } -static void +function void insert_string(Buffer_Insertion *insertion, String_Const_u8 string){ if (!insertion->buffering){ insert_string__no_buffering(insertion, string); @@ -86,7 +86,7 @@ insert_string(Buffer_Insertion *insertion, String_Const_u8 string){ } } -static u64 +function u64 insertf(Buffer_Insertion *insertion, char *format, ...){ Scratch_Block scratch(insertion->app); va_list args; @@ -97,12 +97,12 @@ insertf(Buffer_Insertion *insertion, char *format, ...){ return(string.size); } -static void +function void insertc(Buffer_Insertion *insertion, char C){ insert_string(insertion, SCu8(&C, 1)); } -static b32 +function b32 insert_line_from_buffer(Buffer_Insertion *insertion, Buffer_ID buffer_id, i32 line, i32 truncate_at){ b32 success = is_valid_line(insertion->app, buffer_id, line); if (success){ @@ -112,7 +112,7 @@ insert_line_from_buffer(Buffer_Insertion *insertion, Buffer_ID buffer_id, i32 li return(success); } -static b32 +function b32 insert_line_from_buffer(Buffer_Insertion *insertion, Buffer_ID buffer_id, i32 line){ return(insert_line_from_buffer(insertion, buffer_id, line, 0)); } From 19effd6b0c702e67a90df823143922113952943e Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 23 Dec 2019 09:15:18 -0800 Subject: [PATCH 004/128] Updated theme files; jump lister for function lists fixed --- custom/4coder_default_colors.cpp | 2 +- custom/4coder_default_framework_variables.cpp | 5 +++++ custom/4coder_draw.cpp | 17 ++++++++++++++--- custom/4coder_function_list.cpp | 9 +++++---- custom/4coder_jump_lister.cpp | 3 ++- custom/4coder_keyboard_macro.cpp | 3 --- custom/generated/command_metadata.h | 10 +++++----- ship_files/themes/theme-4coder.4coder | 2 +- ship_files/themes/theme-handmade-hero.4coder | 2 +- ship_files/themes/theme-hjortshoej.4coder | 2 +- ship_files/themes/theme-midnight.4coder | 2 +- ship_files/themes/theme-stb-dark.4coder | 2 +- ship_files/themes/theme-stb.4coder | 2 +- ship_files/themes/theme-strange.4coder | 2 +- ship_files/themes/theme-sunlight.4coder | 2 +- ship_files/themes/theme-twilight.4coder | 2 +- ship_files/themes/theme-wombat.4coder | 2 +- 17 files changed, 42 insertions(+), 27 deletions(-) diff --git a/custom/4coder_default_colors.cpp b/custom/4coder_default_colors.cpp index e0820dd9..9a9ba453 100644 --- a/custom/4coder_default_colors.cpp +++ b/custom/4coder_default_colors.cpp @@ -123,7 +123,7 @@ set_default_color_scheme(Application_Links *app){ default_color_table.arrays[defcolor_list_item] = make_colors(arena, 0xFF181818); default_color_table.arrays[defcolor_list_item_hover] = make_colors(arena, 0xFF252525); default_color_table.arrays[defcolor_list_item_active] = make_colors(arena, 0xFF323232); - default_color_table.arrays[defcolor_cursor] = make_colors(arena, 0xFF00EE00); + default_color_table.arrays[defcolor_cursor] = make_colors(arena, 0xFF00EE00, 0xFFEE7700); default_color_table.arrays[defcolor_at_cursor] = make_colors(arena, 0xFF0C0C0C); default_color_table.arrays[defcolor_highlight_cursor_line] = make_colors(arena, 0xFF1E1E1E); default_color_table.arrays[defcolor_highlight] = make_colors(arena, 0xFFDDEE00); diff --git a/custom/4coder_default_framework_variables.cpp b/custom/4coder_default_framework_variables.cpp index bc8ded69..859143ff 100644 --- a/custom/4coder_default_framework_variables.cpp +++ b/custom/4coder_default_framework_variables.cpp @@ -86,5 +86,10 @@ global Mapping framework_mapping = {}; global Buffer_Modified_Set global_buffer_modified_set = {}; +//////////////////////////////// + +global b32 global_keyboard_macro_is_recording = false; +global Range_i64 global_keyboard_macro_range = {}; + // BOTTOM diff --git a/custom/4coder_draw.cpp b/custom/4coder_draw.cpp index 7ee104c6..006bbd31 100644 --- a/custom/4coder_draw.cpp +++ b/custom/4coder_draw.cpp @@ -706,17 +706,27 @@ draw_highlight_range(Application_Links *app, View_ID view_id, return(has_highlight_range); } +function i32 +default_cursor_sub_id(void){ + i32 result = 0; + if (global_keyboard_macro_is_recording){ + result = 1; + } + return(result); +} + 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){ + i32 cursor_sub_id = default_cursor_sub_id(); 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)); + fcolor_id(defcolor_cursor, cursor_sub_id)); 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, @@ -729,7 +739,7 @@ draw_original_4coder_style_cursor_mark_highlight(Application_Links *app, View_ID fcolor_id(defcolor_mark)); draw_character_wire_frame(app, text_layout_id, cursor_pos, roundness, outline_thickness, - fcolor_id(defcolor_cursor)); + fcolor_id(defcolor_cursor, cursor_sub_id)); } } } @@ -740,6 +750,7 @@ draw_notepad_style_cursor_highlight(Application_Links *app, View_ID view_id, f32 roundness){ b32 has_highlight_range = draw_highlight_range(app, view_id, buffer, text_layout_id, roundness); if (!has_highlight_range){ + i32 cursor_sub_id = default_cursor_sub_id(); 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){ @@ -749,7 +760,7 @@ draw_notepad_style_cursor_highlight(Application_Links *app, View_ID view_id, 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)); + draw_character_i_bar(app, text_layout_id, cursor_pos, fcolor_id(defcolor_cursor, cursor_sub_id)); } } diff --git a/custom/4coder_function_list.cpp b/custom/4coder_function_list.cpp index 1fcce23c..80ac51d8 100644 --- a/custom/4coder_function_list.cpp +++ b/custom/4coder_function_list.cpp @@ -277,13 +277,14 @@ CUSTOM_DOC("Creates a jump list of lines of the current buffer that appear to de CUSTOM_COMMAND_SIG(list_all_functions_current_buffer_lister) CUSTOM_DOC("Creates a lister of locations that look like function definitions and declarations in the buffer.") { + Heap *heap = &global_heap; View_ID view = get_active_view(app, Access_ReadVisible); Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); if (buffer != 0){ list_all_functions(app, buffer); view = get_active_view(app, Access_Always); buffer = view_get_buffer(app, view, Access_Always); - Marker_List *list = get_marker_list_for_buffer(buffer); + Marker_List *list = get_or_make_list_for_buffer(app, heap, buffer); if (list != 0){ Jump_Lister_Result jump = get_jump_index_from_user(app, list, "Function:"); @@ -301,13 +302,13 @@ CUSTOM_DOC("Creates a jump list of lines from all buffers that appear to define CUSTOM_COMMAND_SIG(list_all_functions_all_buffers_lister) CUSTOM_DOC("Creates a lister of locations that look like function definitions and declarations all buffers.") { + Heap *heap = &global_heap; list_all_functions(app, 0); View_ID view = get_active_view(app, Access_Always); Buffer_ID buffer = view_get_buffer(app, view, Access_Always); - Marker_List *list = get_marker_list_for_buffer(buffer); + Marker_List *list = get_or_make_list_for_buffer(app, heap, buffer); if (list != 0){ - Jump_Lister_Result jump = get_jump_index_from_user(app, list, - "Function:"); + Jump_Lister_Result jump = get_jump_index_from_user(app, list, "Function:"); jump_to_jump_lister_result(app, view, list, &jump); } } diff --git a/custom/4coder_jump_lister.cpp b/custom/4coder_jump_lister.cpp index d81cca76..5803d00c 100644 --- a/custom/4coder_jump_lister.cpp +++ b/custom/4coder_jump_lister.cpp @@ -59,9 +59,10 @@ jump_to_jump_lister_result(Application_Links *app, View_ID view, CUSTOM_COMMAND_SIG(view_jump_list_with_lister) CUSTOM_DOC("When executed on a buffer with jumps, creates a persistent lister for all the jumps") { + Heap *heap = &global_heap; View_ID view = get_active_view(app, Access_Always); Buffer_ID buffer = view_get_buffer(app, view, Access_Always); - Marker_List *list = get_marker_list_for_buffer(buffer); + Marker_List *list = get_or_make_list_for_buffer(app, heap, buffer); if (list != 0){ Jump_Lister_Result jump = get_jump_index_from_user(app, list, "Jump:"); jump_to_jump_lister_result(app, view, list, &jump); diff --git a/custom/4coder_keyboard_macro.cpp b/custom/4coder_keyboard_macro.cpp index 0d455c9c..eb721c11 100644 --- a/custom/4coder_keyboard_macro.cpp +++ b/custom/4coder_keyboard_macro.cpp @@ -4,9 +4,6 @@ // TOP -global b32 global_keyboard_macro_is_recording = false; -global Range_i64 global_keyboard_macro_range = {}; - function Buffer_ID get_keyboard_log_buffer(Application_Links *app){ return(get_buffer_by_name(app, string_u8_litexpr("*keyboard*"), Access_Always)); diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index db1e23b1..b45e901f 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -320,14 +320,14 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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(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, 54 }, +{ 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, 77 }, +{ 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, 41 }, { 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_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, 296 }, +{ 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, 302 }, { 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 }, diff --git a/ship_files/themes/theme-4coder.4coder b/ship_files/themes/theme-4coder.4coder index ad8da31d..224fb242 100644 --- a/ship_files/themes/theme-4coder.4coder +++ b/ship_files/themes/theme-4coder.4coder @@ -6,7 +6,7 @@ defcolor_margin_active = 0xFF323232; defcolor_list_item = defcolor_margin; defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; -defcolor_cursor = 0xFF00EE00; +defcolor_cursor = {0xFF00EE00, 0xFFEE7700}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF1E1E1E; defcolor_highlight = 0xFFDDEE00; diff --git a/ship_files/themes/theme-handmade-hero.4coder b/ship_files/themes/theme-handmade-hero.4coder index 1a314b8d..de1af82a 100644 --- a/ship_files/themes/theme-handmade-hero.4coder +++ b/ship_files/themes/theme-handmade-hero.4coder @@ -7,7 +7,7 @@ defcolor_margin_active = 0xFF404040; defcolor_list_item = defcolor_margin; defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; -defcolor_cursor = 0xFF40FF40; +defcolor_cursor = {0xFF40FF40, 0xFFFF4040}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF121E12; defcolor_highlight = 0xFF703419; diff --git a/ship_files/themes/theme-hjortshoej.4coder b/ship_files/themes/theme-hjortshoej.4coder index d7709ee4..917de699 100644 --- a/ship_files/themes/theme-hjortshoej.4coder +++ b/ship_files/themes/theme-hjortshoej.4coder @@ -7,7 +7,7 @@ defcolor_margin_active = 0xFF5C5C5C; defcolor_list_item = defcolor_margin; defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; -defcolor_cursor = 0xFF000000; +defcolor_cursor = {0xFF000000, 0xFF002020}; defcolor_at_cursor = 0xFFD6D6D6; defcolor_highlight_cursor_line = 0xFFB8B098; defcolor_mark = 0xFF525252; diff --git a/ship_files/themes/theme-midnight.4coder b/ship_files/themes/theme-midnight.4coder index e77a1e46..cfa30340 100644 --- a/ship_files/themes/theme-midnight.4coder +++ b/ship_files/themes/theme-midnight.4coder @@ -6,7 +6,7 @@ defcolor_margin_active = 0xFF484848; defcolor_list_item = defcolor_margin; defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; -defcolor_cursor = 0xFFDDDDDD; +defcolor_cursor = {0xFFDDDDDD, 0xFFDDF0F0}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF383838; defcolor_mark = 0xFF808080; diff --git a/ship_files/themes/theme-stb-dark.4coder b/ship_files/themes/theme-stb-dark.4coder index c52c1728..5461f890 100644 --- a/ship_files/themes/theme-stb-dark.4coder +++ b/ship_files/themes/theme-stb-dark.4coder @@ -6,7 +6,7 @@ defcolor_margin_active = 0xFF484848; defcolor_list_item = defcolor_margin; defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; -defcolor_cursor = 0xFFDDDDDD; +defcolor_cursor = {0xFFDDDDDD, 0xFFDDF0F0}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF383838; defcolor_mark = 0xFF808080; diff --git a/ship_files/themes/theme-stb.4coder b/ship_files/themes/theme-stb.4coder index b8c0fc00..3cdce02b 100644 --- a/ship_files/themes/theme-stb.4coder +++ b/ship_files/themes/theme-stb.4coder @@ -6,7 +6,7 @@ defcolor_margin_active = 0xFF5C5C5C; defcolor_list_item = defcolor_margin; defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; -defcolor_cursor = 0xFF000000; +defcolor_cursor = {0xFF000000, 0xFF002020}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFFBCBCBC; defcolor_mark = 0xFF525252; diff --git a/ship_files/themes/theme-strange.4coder b/ship_files/themes/theme-strange.4coder index b98b5d15..a023e650 100644 --- a/ship_files/themes/theme-strange.4coder +++ b/ship_files/themes/theme-strange.4coder @@ -7,7 +7,7 @@ defcolor_margin_active = 0xFF9A99E7; defcolor_list_item = defcolor_margin; defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; -defcolor_cursor = 0xFFd96e26; +defcolor_cursor = {0xFFd96e26, 0xFFd9d926}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF002222; defcolor_mark = 0xFF808080; diff --git a/ship_files/themes/theme-sunlight.4coder b/ship_files/themes/theme-sunlight.4coder index dd74810e..9439f4e3 100644 --- a/ship_files/themes/theme-sunlight.4coder +++ b/ship_files/themes/theme-sunlight.4coder @@ -6,7 +6,7 @@ defcolor_margin_active = 0xFFB7B7B7; defcolor_list_item = defcolor_margin; defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; -defcolor_cursor = 0xFF222222; +defcolor_cursor = {0xFF222222, 0xFF442244}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFFC7C7C7; defcolor_mark = 0xFF797979; diff --git a/ship_files/themes/theme-twilight.4coder b/ship_files/themes/theme-twilight.4coder index 95a53d5d..ce266643 100644 --- a/ship_files/themes/theme-twilight.4coder +++ b/ship_files/themes/theme-twilight.4coder @@ -6,7 +6,7 @@ defcolor_margin_active = 0xFF405D82; defcolor_list_item = defcolor_margin; defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; -defcolor_cursor = 0xFFEEE800; +defcolor_cursor = {0xFFEEE800, 0xFFEE00E8}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF151F2A; defcolor_mark = 0xFF8BA8CC; diff --git a/ship_files/themes/theme-wombat.4coder b/ship_files/themes/theme-wombat.4coder index 2f5e2dc7..4a0501c2 100644 --- a/ship_files/themes/theme-wombat.4coder +++ b/ship_files/themes/theme-wombat.4coder @@ -7,7 +7,7 @@ defcolor_margin_active = 0xFF323232; defcolor_list_item = defcolor_margin; defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; -defcolor_cursor = 0xFF656565; +defcolor_cursor = {0xFF656565, 0xFF654065}; defcolor_highlight = 0xFF636066; defcolor_mark = defcolor_cursor; defcolor_text_default = 0xFFe3e0d7; From 65774dec4651752259f1a26aa5753e9ee9e8bf23 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Mon, 23 Dec 2019 20:40:51 +0200 Subject: [PATCH 005/128] Replaced readlink -f with realpath which works for both macOS and Linux. Might need to replace this with an implementation of readlink -f if we find that this doesn't work well enough for both macOS and Linux. --- bin/build.sh | 4 ++-- custom/bin/buildsuper_x64.sh | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/build.sh b/bin/build.sh index 491067b0..90b1fa46 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -4,8 +4,8 @@ set -e # Set up directories (mirrors build.bat) -# NOTE(yuval): Temporary fix that works only for macOS -ME="$(greadlink -f "$0")" +# NOTE(yuval): Replaced readlink with realpath which works for both macOS and Linux +ME="$(realpath "$0")" LOCATION="$(dirname "$ME")" SRC_ROOT="$(dirname "$LOCATION")" PROJECT_ROOT="$(dirname "$SRC_ROOT")" diff --git a/custom/bin/buildsuper_x64.sh b/custom/bin/buildsuper_x64.sh index 2c83d6b1..e04e79cf 100755 --- a/custom/bin/buildsuper_x64.sh +++ b/custom/bin/buildsuper_x64.sh @@ -4,7 +4,7 @@ set -e # Store the real CWD -ME="$(readlink -f "$0")" +ME="$(realpath "$0")" LOCATION="$(dirname "$ME")" CODE_HOME="$(dirname "$LOCATION")" From a14f530051940d683daebd7e877f5a3e6f2535ad Mon Sep 17 00:00:00 2001 From: Ryan Fleury Date: Mon, 23 Dec 2019 12:24:39 -0700 Subject: [PATCH 006/128] Fix of 0-dimension resizing bug --- opengl/4ed_opengl_render.cpp | 15 ++++++++++++++- 1 file changed, 14 insertions(+), 1 deletion(-) diff --git a/opengl/4ed_opengl_render.cpp b/opengl/4ed_opengl_render.cpp index 3e83095d..d9d696c3 100644 --- a/opengl/4ed_opengl_render.cpp +++ b/opengl/4ed_opengl_render.cpp @@ -286,7 +286,20 @@ gl_render(Render_Target *t){ group != 0; group = group->next){ Rect_i32 box = Ri32(group->clip_box); - glScissor(box.x0, height - box.y1, box.x1 - box.x0, box.y1 - box.y0); + + Rect_i32 scissor_box = + { + box.x0, height - box.y1, box.x1 - box.x0, box.y1 - box.y0, + }; + if (scissor_box.x1 < 0) + { + scissor_box.x1 = 0; + } + if (scissor_box.y1 < 0) + { + scissor_box.y1 = 0; + } + glScissor(scissor_box.x0, scissor_box.y0, scissor_box.x1, scissor_box.y1); i32 vertex_count = group->vertex_list.vertex_count; if (vertex_count > 0){ From 8be1e685bf788c57a3e658c335246596e46a11db Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 23 Dec 2019 11:47:33 -0800 Subject: [PATCH 007/128] Fixed enclosure code to work on first byte of enclosure range --- bin/build_optimized.bat | 2 +- custom/4coder_helper.cpp | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/bin/build_optimized.bat b/bin/build_optimized.bat index 6e8741f6..4069b540 100644 --- a/bin/build_optimized.bat +++ b/bin/build_optimized.bat @@ -1,3 +1,3 @@ @echo off -call build.bat /DOPT_BUILD \ No newline at end of file +call bin\build.bat /DOPT_BUILD diff --git a/custom/4coder_helper.cpp b/custom/4coder_helper.cpp index db627f48..d074e891 100644 --- a/custom/4coder_helper.cpp +++ b/custom/4coder_helper.cpp @@ -788,7 +788,7 @@ enclose_boundary(Application_Links *app, Buffer_ID buffer, Range_i64 range, range.min = new_min; } i64 new_max = func(app, buffer, Side_Max, Scan_Forward, range.max - 1); - i64 new_max_check = func(app, buffer, Side_Min, Scan_Forward, range.max - 1); + i64 new_max_check = func(app, buffer, Side_Min, Scan_Forward, range.max); if (new_max_check >= new_max && new_max > range.max){ range.max = new_max; } @@ -1897,7 +1897,7 @@ push_token_or_word_under_pos(Application_Links *app, Arena *arena, Buffer_ID buf String_Const_u8 result = {}; Token *token = get_token_from_pos(app, buffer, pos); if (token != 0 && token->size > 0 && token->kind != TokenBaseKind_Whitespace){ - Range_i64 range = Ii64(token->pos, token->pos + token->size); + Range_i64 range = Ii64(token); result = push_buffer_range(app, arena, buffer, range); } return(result); From 1c867f117586262af955a4680f4c529212dccda1 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 23 Dec 2019 11:54:06 -0800 Subject: [PATCH 008/128] Touch up scissor box fix --- opengl/4ed_opengl_render.cpp | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/opengl/4ed_opengl_render.cpp b/opengl/4ed_opengl_render.cpp index d9d696c3..48f3ef6f 100644 --- a/opengl/4ed_opengl_render.cpp +++ b/opengl/4ed_opengl_render.cpp @@ -287,18 +287,13 @@ gl_render(Render_Target *t){ group = group->next){ Rect_i32 box = Ri32(group->clip_box); - Rect_i32 scissor_box = - { + Rect_i32 scissor_box = { box.x0, height - box.y1, box.x1 - box.x0, box.y1 - box.y0, }; - if (scissor_box.x1 < 0) - { - scissor_box.x1 = 0; - } - if (scissor_box.y1 < 0) - { - scissor_box.y1 = 0; - } + scissor_box.x0 = clamp_bot(0, scissor_box.x0); + scissor_box.y0 = clamp_bot(0, scissor_box.y0); + scissor_box.x1 = clamp_bot(0, scissor_box.x1); + scissor_box.y1 = clamp_bot(0, scissor_box.y1); glScissor(scissor_box.x0, scissor_box.y0, scissor_box.x1, scissor_box.y1); i32 vertex_count = group->vertex_list.vertex_count; From ccb3767c55fbb6f1c3112a60fbd185b0189b947d Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 23 Dec 2019 12:18:07 -0800 Subject: [PATCH 009/128] Fixed case insensitive find first functions --- custom/4coder_base_types.cpp | 12 ++++++++---- 1 file changed, 8 insertions(+), 4 deletions(-) diff --git a/custom/4coder_base_types.cpp b/custom/4coder_base_types.cpp index 9f7b3483..09717a43 100644 --- a/custom/4coder_base_types.cpp +++ b/custom/4coder_base_types.cpp @@ -4728,9 +4728,10 @@ string_find_first(String_Const_char str, String_Const_char needle, String_Match_ i = str.size; if (str.size >= needle.size){ i = 0; + char c = character_to_upper(needle.str[0]); u64 one_past_last = str.size - needle.size + 1; for (;i < one_past_last; i += 1){ - if (str.str[i] == needle.str[0]){ + if (character_to_upper(str.str[i]) == c){ String_Const_char source_part = string_prefix(string_skip(str, i), needle.size); if (string_match(source_part, needle, rule)){ break; @@ -4751,9 +4752,10 @@ string_find_first(String_Const_u8 str, String_Const_u8 needle, String_Match_Rule i = str.size; if (str.size >= needle.size){ i = 0; + u8 c = character_to_upper(needle.str[0]); u64 one_past_last = str.size - needle.size + 1; for (;i < one_past_last; i += 1){ - if (str.str[i] == needle.str[0]){ + if (character_to_upper(str.str[i]) == c){ String_Const_u8 source_part = string_prefix(string_skip(str, i), needle.size); if (string_match(source_part, needle, rule)){ break; @@ -4774,9 +4776,10 @@ string_find_first(String_Const_u16 str, String_Const_u16 needle, String_Match_Ru i = str.size; if (str.size >= needle.size){ i = 0; + u16 c = character_to_upper(needle.str[0]); u64 one_past_last = str.size - needle.size + 1; for (;i < one_past_last; i += 1){ - if (str.str[i] == needle.str[0]){ + if (character_to_upper(str.str[i]) == c){ String_Const_u16 source_part = string_prefix(string_skip(str, i), needle.size); if (string_match(source_part, needle, rule)){ break; @@ -4797,9 +4800,10 @@ string_find_first(String_Const_u32 str, String_Const_u32 needle, String_Match_Ru i = str.size; if (str.size >= needle.size){ i = 0; + u32 c = character_to_upper(needle.str[0]); u64 one_past_last = str.size - needle.size + 1; for (;i < one_past_last; i += 1){ - if (str.str[i] == needle.str[0]){ + if (character_to_upper(str.str[i]) == c){ String_Const_u32 source_part = string_prefix(string_skip(str, i), needle.size); if (string_match(source_part, needle, rule)){ break; From 921a68e765ca951b14b06c28d57be6c0eacbb259 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 24 Dec 2019 01:22:56 +0200 Subject: [PATCH 010/128] Created separate build files for macOS. --- bin/4ed_build.cpp | 3 +- bin/build-mac.sh | 43 ++++++++++++++++++++++++++ bin/build.sh | 5 ++- bin/build_x86-mac.sh | 5 +++ custom/bin/buildsuper_x64-mac.sh | 30 ++++++++++++++++++ custom/bin/buildsuper_x64.sh | 5 ++- custom/bin/buildsuper_x86-mac.sh | 53 ++++++++++++++++++++++++++++++++ custom/bin/buildsuper_x86.sh | 3 +- platform_mac/mac_4ed.mm | 39 +++++++++++++++-------- platform_mac/mac_4ed_old.m | 16 ++++++---- 10 files changed, 175 insertions(+), 27 deletions(-) create mode 100755 bin/build-mac.sh create mode 100644 bin/build_x86-mac.sh create mode 100755 custom/bin/buildsuper_x64-mac.sh create mode 100755 custom/bin/buildsuper_x86-mac.sh diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index 235e2813..90a1e350 100644 --- a/bin/4ed_build.cpp +++ b/bin/4ed_build.cpp @@ -90,7 +90,7 @@ char *includes[] = { "custom", FOREIGN "/freetype2", 0, }; 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 *mac_platform_layer[] = { "platform_mac/mac_4ed_old.m", 0 }; char **platform_layers[Platform_COUNT] = { windows_platform_layer, @@ -387,6 +387,7 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha fm_finish_build_line(&line); Temp_Dir temp = fm_pushdir(out_path); + printf("Build: g++ %s -o %s\n", line.build_options, out_file); systemf("g++ %s -o %s", line.build_options, out_file); fm_popdir(temp); } diff --git a/bin/build-mac.sh b/bin/build-mac.sh new file mode 100755 index 00000000..9d77d2e9 --- /dev/null +++ b/bin/build-mac.sh @@ -0,0 +1,43 @@ +#!/bin/bash + +# If any command errors, stop the script +set -e + +# Set up directories (mirrors build.bat) +# NOTE(yuval): Replaced readlink with realpath which works for both macOS and Linux +ME="$(realpath "$0")" +LOCATION="$(dirname "$ME")" +SRC_ROOT="$(dirname "$LOCATION")" +PROJECT_ROOT="$(dirname "$SRC_ROOT")" +if [ ! -d "$PROJECT_ROOT/build" ]; then +mkdir "$PROJECT_ROOT/build" +fi +BUILD_ROOT="$PROJECT_ROOT/build" +BIN_ROOT="$SRC_ROOT/bin" +CUSTOM_ROOT="$SRC_ROOT/custom" +CUSTOM_BIN="$CUSTOM_ROOT/bin" + +# Get the build mode +BUILD_MODE="$1" +if [ -z "$BUILD_MODE" ]; then + BUILD_MODE="-DDEV_BUILD" +fi + +# Get the OS specific flags +chmod +rx "$BIN_ROOT/detect_os.sh" +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-null-dereference -Wno-switch" +fi + +FLAGS="-D_GNU_SOURCE -fPIC -fpermissive $BUILD_MODE" +INCLUDES="-I$SRC_ROOT -I$CUSTOM_ROOT" + +# Execute +clang++ $WARNINGS $FLAGS $INCLUDES "$BIN_ROOT/4ed_build.cpp" -g -o "$BUILD_ROOT/build" +pushd "$SRC_ROOT" +"$BUILD_ROOT/build" +popd diff --git a/bin/build.sh b/bin/build.sh index 90b1fa46..0d01ab2d 100755 --- a/bin/build.sh +++ b/bin/build.sh @@ -4,8 +4,7 @@ set -e # Set up directories (mirrors build.bat) -# NOTE(yuval): Replaced readlink with realpath which works for both macOS and Linux -ME="$(realpath "$0")" +ME="$(readlink -f "$0")" LOCATION="$(dirname "$ME")" SRC_ROOT="$(dirname "$LOCATION")" PROJECT_ROOT="$(dirname "$SRC_ROOT")" @@ -30,7 +29,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-null-dereference -Wno-switch" +WARNINGS="-Wno-write-strings -Wno-comment -Wno-logical-op-parentheses -Wno-null-dereference -Wno-switch" fi FLAGS="-D_GNU_SOURCE -fPIC -fpermissive $BUILD_MODE" diff --git a/bin/build_x86-mac.sh b/bin/build_x86-mac.sh new file mode 100644 index 00000000..3642eddf --- /dev/null +++ b/bin/build_x86-mac.sh @@ -0,0 +1,5 @@ +#!/bin/bash + +./build.sh -DDEV_BUILD_X86 + + diff --git a/custom/bin/buildsuper_x64-mac.sh b/custom/bin/buildsuper_x64-mac.sh new file mode 100755 index 00000000..e04e79cf --- /dev/null +++ b/custom/bin/buildsuper_x64-mac.sh @@ -0,0 +1,30 @@ +#!/bin/bash + +# If any command errors, stop the script +set -e + +# Store the real CWD +ME="$(realpath "$0")" +LOCATION="$(dirname "$ME")" +CODE_HOME="$(dirname "$LOCATION")" + +# Find the most reasonable candidate build file +SOURCE="$1" +if [ -z "$SOURCE" ]; then + SOURCE="$(readlink -f "$CODE_HOME/4coder_default_bindings.cpp")" +fi + +# 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 +meta_macros="-DMETA_PASS" +g++ -I"$CODE_HOME" $meta_macros $arch $opts $debug -std=gnu++0x "$SOURCE" -E -o $preproc_file +g++ -I"$CODE_HOME" $opts $debug -std=gnu++0x "$CODE_HOME/4coder_metadata_generator.cpp" -o "$CODE_HOME/metadata_generator" +"$CODE_HOME/metadata_generator" -R "$CODE_HOME" "$PWD/$preproc_file" + +g++ -I"$CODE_HOME" $arch $opts $debug -std=gnu++0x "$SOURCE" -shared -o custom_4coder.so -fPIC + +rm "$CODE_HOME/metadata_generator" +rm $preproc_file diff --git a/custom/bin/buildsuper_x64.sh b/custom/bin/buildsuper_x64.sh index e04e79cf..6b49d4ab 100755 --- a/custom/bin/buildsuper_x64.sh +++ b/custom/bin/buildsuper_x64.sh @@ -4,7 +4,7 @@ set -e # Store the real CWD -ME="$(realpath "$0")" +ME="$(readlink -f "$0")" LOCATION="$(dirname "$ME")" CODE_HOME="$(dirname "$LOCATION")" @@ -14,8 +14,7 @@ if [ -z "$SOURCE" ]; then SOURCE="$(readlink -f "$CODE_HOME/4coder_default_bindings.cpp")" fi -# 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" +opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-writable-strings -g" arch=-m64 preproc_file=4coder_command_metadata.i diff --git a/custom/bin/buildsuper_x86-mac.sh b/custom/bin/buildsuper_x86-mac.sh new file mode 100755 index 00000000..e3dde9b0 --- /dev/null +++ b/custom/bin/buildsuper_x86-mac.sh @@ -0,0 +1,53 @@ +#!/bin/bash + +# Store the real CWD +REAL_PWD="$PWD" + +# Find the code home folder +TARGET_FILE="$0" +cd `dirname $TARGET_FILE` +TARGET_FILE=`basename $TARGET_FILE` +while [ -L "$TARGET_FILE" ] +do + TARGET_FILE=`readlink $TARGET_FILE` + cd `dirname $TARGET_FILE` + TARGET_FILE=`basename $TARGET_FILE` +done +PHYS_DIR=`pwd -P` +SCRIPT_FILE=$PHYS_DIR/$TARGET_FILE +code_home=$(dirname "$SCRIPT_FILE") + +# Find the most reasonable candidate build file +SOURCE="$1" +if [ -z "$SOURCE" ]; then + SOURCE="$code_home/4coder_default_bindings.cpp" +fi + +TARGET_FILE="$SOURCE" +cd `dirname $TARGET_FILE` +TARGET_FILE=`basename $TARGET_FILE` +while [ -L "$TARGET_FILE" ] +do + TARGET_FILE=`readlink $TARGET_FILE` + cd `dirname $TARGET_FILE` + TARGET_FILE=`basename $TARGET_FILE` +done +PHYS_DIR=`pwd -P` +SOURCE=$PHYS_DIR/$TARGET_FILE + +# 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" +preproc_file=4coder_command_metadata.i +meta_macros="-DMETA_PASS" +g++ -I"$code_home" $meta_macros $arch $opts $debug -std=gnu++0x "$SOURCE" -E -o $preproc_file +g++ -I"$code_home" $opts $debug -std=gnu++0x "$code_home/4coder_metadata_generator.cpp" -o metadata_generator +./metadata_generator -R "$code_home" "$PWD/$preproc_file" + +g++ -I"$code_home" $arch $opts $debug -std=gnu++0x "$SOURCE" -shared -o custom_4coder.so -fPIC + +rm metadata_generator +rm $preproc_file + diff --git a/custom/bin/buildsuper_x86.sh b/custom/bin/buildsuper_x86.sh index e3dde9b0..46d0ab6e 100755 --- a/custom/bin/buildsuper_x86.sh +++ b/custom/bin/buildsuper_x86.sh @@ -35,8 +35,7 @@ done PHYS_DIR=`pwd -P` SOURCE=$PHYS_DIR/$TARGET_FILE -# 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" +opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-writable-strings -g" arch=-m32 cd "$REAL_PWD" diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index e5993845..8182c122 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -1,16 +1,31 @@ +// #include + int main(int arg_count, char **args){ - Thread_Context _tctx = {}; - thread_ctx_init(&_tctx, ThreadKind_Main, - get_base_allocator_system(), - get_base_allocator_system()); - - block_zero_struct(&global_mac_vars); - global_mac_vars.tctx = &_tctx; - - // NOTE(yuval): Application Core Update - Application_Step_Result result = {}; - if (app.step != 0){ - result = app.step(mac_vars.tctx, &target, base_ptr, &input); + @autoreleasepool{ + // NOTE(yuval): NSApplication & Delegate Creation + NSApplication* app = [NSApplication sharedApplication]; + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; + + App_Delegate* app_delegate = [[App_Delegate alloc] init]; + [app setDelegate:app_delegate]; + + [NSApp finishLaunching]; + +#if 0 + Thread_Context _tctx = {}; + thread_ctx_init(&_tctx, ThreadKind_Main, + get_base_allocator_system(), + get_base_allocator_system()); + + block_zero_struct(&global_mac_vars); + global_mac_vars.tctx = &_tctx; + + // NOTE(yuval): Application Core Update + Application_Step_Result result = {}; + if (app.step != 0){ + result = app.step(mac_vars.tctx, &target, base_ptr, &input); + } +#endif } } \ No newline at end of file diff --git a/platform_mac/mac_4ed_old.m b/platform_mac/mac_4ed_old.m index ebadc1ca..098da2fe 100644 --- a/platform_mac/mac_4ed_old.m +++ b/platform_mac/mac_4ed_old.m @@ -9,6 +9,7 @@ // TOP +#if 0 #define IS_OBJC_LAYER #include "4coder_base_types.h" @@ -23,6 +24,8 @@ #define external #include "osx_objective_c_to_cpp_links.h" +#endif + #include #import @@ -30,7 +33,7 @@ #import #import #import - +#if 0 #include #include #include @@ -814,9 +817,9 @@ osx_list_loadable_fonts(void){ NSString *font_n = fonts[i]; char *font_n_c = (char*)[font_n UTF8String]; NSFont *font = [font_manager - fontWithFamily:font_n - traits:NSUnboldFontMask|NSUnitalicFontMask - weight:5 + fontWithFamily:font_n + traits:NSUnboldFontMask|NSUnitalicFontMask + weight:5 size:12]; NSString *path = get_font_path(font); char *path_c = 0; @@ -840,9 +843,10 @@ OSX_Keyboard_Modifiers osx_get_modifiers(void){ return(osx_mods_nsevent_to_struct([NSEvent modifierFlags])); } - +#endif int main(int argc, char **argv){ +#if 0 memset(&osx_objc, 0, sizeof(osx_objc)); u32 clipboard_size = KB(16); @@ -887,7 +891,7 @@ main(int argc, char **argv){ [NSApp run]; } - +#endif return(0); } From 42f06f0eecda062dc1ed6444e0db332316648b94 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 24 Dec 2019 02:46:58 +0200 Subject: [PATCH 011/128] Added clang compiler support. The macOS platform now uses clang instead of gcc as its compiler. --- 4ed_api_implementation.cpp | 26 +- 4ed_buffer.cpp | 4 +- 4ed_string_matching.cpp | 4 +- bin/4ed_build.cpp | 135 +++++- bin/build-mac.sh | 2 +- custom/4coder_base_types.cpp | 2 +- custom/4coder_base_types.h | 67 ++- custom/4coder_command_map.cpp | 32 +- custom/4coder_file_moving.h | 14 +- custom/bin/buildsuper_x64-mac.sh | 8 +- custom/generated/command_metadata.h | 458 +++++++++--------- .../Resources/DWARF/metadata_generator | Bin 486440 -> 136740 bytes platform_mac/mac_4ed.mm | 2 +- 13 files changed, 430 insertions(+), 324 deletions(-) diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 933262b4..9086beac 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -453,7 +453,7 @@ buffer_line_y_difference(Application_Links *app, Buffer_ID buffer_id, i64 line_a, i64 line_b){ Models *models = (Models*)app->cmd_context; Editing_File *file = imp_get_file(models, buffer_id); - f32 result = {}; + f32 result = 0.0f; if (api_check_buffer(file)){ Face *face = font_set_face_from_id(&models->font_set, face_id); if (face != 0){ @@ -527,7 +527,7 @@ buffer_relative_character_from_pos(Application_Links *app, Buffer_ID buffer_id, { Models *models = (Models*)app->cmd_context; Editing_File *file = imp_get_file(models, buffer_id); - i64 result = {}; + i64 result = 0; if (api_check_buffer(file)){ Face *face = font_set_face_from_id(&models->font_set, face_id); if (face != 0){ @@ -563,7 +563,7 @@ api(custom) function f32 view_line_y_difference(Application_Links *app, View_ID view_id, i64 line_a, i64 line_b){ Models *models = (Models*)app->cmd_context; View *view = imp_get_view(models, view_id); - f32 result = {}; + f32 result = 0.0f; if (api_check_view(view)){ result = view_line_y_difference(app->tctx, models, view, line_a, line_b); } @@ -607,7 +607,7 @@ api(custom) function i64 view_relative_character_from_pos(Application_Links *app, View_ID view_id, i64 base_line, i64 pos){ Models *models = (Models*)app->cmd_context; View *view = imp_get_view(models, view_id); - i64 result = {}; + i64 result = 0; if (api_check_view(view)){ result = view_relative_character_from_pos(app->tctx, models, view, base_line, pos); } @@ -618,7 +618,7 @@ api(custom) function i64 view_pos_from_relative_character(Application_Links *app, View_ID view_id, i64 base_line, i64 character){ Models *models = (Models*)app->cmd_context; View *view = imp_get_view(models, view_id); - i64 result = {}; + i64 result = 0; if (api_check_view(view)){ result = view_pos_from_relative_character(app->tctx, models, view, base_line, character); } @@ -702,7 +702,7 @@ api(custom) function Dirty_State buffer_get_dirty_state(Application_Links *app, Buffer_ID buffer_id){ Models *models = (Models*)app->cmd_context; Editing_File *file = imp_get_file(models, buffer_id); - Dirty_State result = {}; + Dirty_State result = 0; if (api_check_buffer(file)){ result = file->state.dirty; } @@ -1680,7 +1680,7 @@ view_set_buffer(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Se // TODO(allen): remove this! api(custom) function b32 -view_post_fade(Application_Links *app, View_ID view_id, f32 seconds, Range_i64 range, +view_post_fade(Application_Links *app, View_ID view_id, f32 seconds, Range_i64 range, ARGB_Color color){ Models *models = (Models*)app->cmd_context; View *view = imp_get_view(models, view_id); @@ -2390,7 +2390,7 @@ set_global_face(Application_Links *app, Face_ID id) b32 result = false; Face *face = font_set_face_from_id(&models->font_set, id); if (face != 0){ - models->global_face_id = face->id; + models->global_face_id = face->id; result = true; } return(result); @@ -2796,7 +2796,7 @@ api(custom) function Text_Layout_ID text_layout_create(Application_Links *app, Buffer_ID buffer_id, Rect_f32 rect, Buffer_Point buffer_point){ Models *models = (Models*)app->cmd_context; Editing_File *file = imp_get_file(models, buffer_id); - Text_Layout_ID result = {}; + Text_Layout_ID result = 0; if (api_check_buffer(file)){ Thread_Context *tctx = app->tctx; Scratch_Block scratch(tctx); @@ -2826,10 +2826,10 @@ text_layout_create(Application_Links *app, Buffer_ID buffer_id, Rect_f32 rect, B Range_i64 visible_line_number_range = Ii64(buffer_point.line_number, line_number); Range_i64 visible_range = Ii64(buffer_get_first_pos_from_line_number(buffer, visible_line_number_range.min), - buffer_get_last_pos_from_line_number(buffer, visible_line_number_range.max)); + buffer_get_last_pos_from_line_number(buffer, visible_line_number_range.max)); i64 item_count = range_size_inclusive(visible_range); - ARGB_Color *colors_array = push_array_zero(arena, ARGB_Color, item_count); + ARGB_Color *colors_array = push_array_zero(arena, ARGB_Color, item_count); result = text_layout_new(&models->text_layouts, arena, buffer_id, buffer_point, visible_range, visible_line_number_range, rect, colors_array, layout_func); @@ -2944,7 +2944,7 @@ text_layout_character_on_screen(Application_Links *app, Text_Layout_ID layout_id y += line.height; } - // TODO(allen): optimization: This is some fairly heavy computation. We really + // TODO(allen): optimization: This is some fairly heavy computation. We really // need to accelerate the (pos -> item) lookup within a single // Buffer_Layout_Item_List. b32 is_first_item = true; @@ -2987,7 +2987,7 @@ paint_text_color(Application_Links *app, Text_Layout_ID layout_id, Range_i64 ran range.max = clamp_top(range.max, layout->visible_range.max); range.min -= layout->visible_range.min; range.max -= layout->visible_range.min; - ARGB_Color *color_ptr = layout->item_colors + range.min; + ARGB_Color *color_ptr = layout->item_colors + range.min; for (i64 i = range.min; i < range.max; i += 1, color_ptr += 1){ *color_ptr = color; } diff --git a/4ed_buffer.cpp b/4ed_buffer.cpp index c625e6f0..c155b9dc 100644 --- a/4ed_buffer.cpp +++ b/4ed_buffer.cpp @@ -705,7 +705,7 @@ buffer_get_pos_range_from_line_number(Gap_Buffer *buffer, i64 line_number){ internal i64 buffer_get_first_pos_from_line_number(Gap_Buffer *buffer, i64 line_number){ - i64 result = {}; + i64 result = 0; if (line_number < 1){ result = 0; } @@ -720,7 +720,7 @@ buffer_get_first_pos_from_line_number(Gap_Buffer *buffer, i64 line_number){ internal i64 buffer_get_last_pos_from_line_number(Gap_Buffer *buffer, i64 line_number){ - i64 result = {}; + i64 result = 0; if (line_number < 1){ result = 0; } diff --git a/4ed_string_matching.cpp b/4ed_string_matching.cpp index 4fd28843..2907d24b 100644 --- a/4ed_string_matching.cpp +++ b/4ed_string_matching.cpp @@ -125,7 +125,7 @@ find_all_matches_forward(Arena *arena, i32 maximum_output_count, jump_back_0: if (n + 1 == needle.size){ - String_Match_Flag flags = {}; + String_Match_Flag flags = 0; if (!(last_insensitive >= 0 && j <= (u64)last_insensitive && (u64)last_insensitive < j + needle.size)){ @@ -245,7 +245,7 @@ find_all_matches_backward(Arena *arena, i32 maximum_output_count, jump_back_0: if (n + 1 == needle.size){ - String_Match_Flag flags = {}; + String_Match_Flag flags = 0; if (!(last_insensitive < size && j >= last_insensitive && last_insensitive > j - (i64)needle.size)){ diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index 90a1e350..146169fb 100644 --- a/bin/4ed_build.cpp +++ b/bin/4ed_build.cpp @@ -43,6 +43,7 @@ char *platform_names[] = { enum{ Compiler_CL, Compiler_GCC, + Compiler_Clang, // Compiler_COUNT, Compiler_None = Compiler_COUNT, @@ -51,6 +52,7 @@ enum{ char *compiler_names[] = { "cl", "gcc", + "clang" }; #if OS_WINDOWS @@ -67,6 +69,8 @@ char *compiler_names[] = { # define This_Compiler Compiler_CL #elif COMPILER_GCC # define This_Compiler Compiler_GCC +#elif COMPILER_CLANG +# define This_Compiler Compiler_Clang #else # error This compilers is not enumerated. #endif @@ -90,7 +94,7 @@ char *includes[] = { "custom", FOREIGN "/freetype2", 0, }; 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_old.m", 0 }; +char *mac_platform_layer[] = { "platform_mac/mac_4ed.mm", 0 }; char **platform_layers[Platform_COUNT] = { windows_platform_layer, @@ -100,12 +104,12 @@ char **platform_layers[Platform_COUNT] = { 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 *mac_clang_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 }, + {windows_cl_platform_inc, 0 , 0}, + {0 , linux_gcc_platform_inc, 0}, + {0 , 0 , mac_clang_platform_inc}, }; char *default_custom_target = "../code/custom/4coder_default_bindings.cpp"; @@ -298,25 +302,6 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha #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 @@ -387,11 +372,105 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha fm_finish_build_line(&line); Temp_Dir temp = fm_pushdir(out_path); - printf("Build: g++ %s -o %s\n", line.build_options, out_file); systemf("g++ %s -o %s", line.build_options, out_file); fm_popdir(temp); } +#elif COMPILER_CLANG + +#if OS_MAC + +# define CLANG_OPTS \ +"-Wno-write-strings -Wno-deprecated-declarations " \ +"-Wno-comment -Wno-switch -Wno-null-dereference " \ +"-Wno-tautological-compare " \ +"-Wno-unused-result -Wno-missing-declarations -std=c++11 " + +#define CLANG_LIBS_COMMON \ +"-framework Cocoa -framework QuartzCore " \ +"-framework CoreServices " \ +"-framework OpenGL -framework IOKit " + +#define CLANG_LIBS_X64 CLANG_LIBS_COMMON \ +FOREIGN "/x64/libfreetype-mac.a" + +#define CLANG_LIBS_X86 CLANG_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, CLANG_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, CLANG_LIBS_X64); + } + else if (arch == Arch_X86) + { + fm_add_to_line(line, CLANG_LIBS_X86); + } + } + + fm_finish_build_line(&line); + + Temp_Dir temp = fm_pushdir(out_path); + systemf("clang++ %s -o %s", line.build_options, out_file); + fm_popdir(temp); +} + #else # error build function not defined for this compiler #endif @@ -428,7 +507,11 @@ buildsuper(Arena *arena, char *cdir, char *file, u32 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_script_postfix = ""; + if (This_OS == Platform_Mac){ + build_script_postfix = "-mac"; + } + char *build_script = fm_str(arena, "custom/bin/buildsuper_", arch_names[arch], build_script_postfix, BAT); char *build_command = fm_str(arena, "\"", cdir, "/", build_script, "\" \"", file, "\""); if (This_OS == Platform_Windows){ diff --git a/bin/build-mac.sh b/bin/build-mac.sh index 9d77d2e9..83062702 100755 --- a/bin/build-mac.sh +++ b/bin/build-mac.sh @@ -30,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-null-dereference -Wno-switch" +WARNINGS="-Wno-write-strings -Wno-comment -Wno-null-dereference -Wno-logical-op-parentheses -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 2209ff55..f3910953 100644 --- a/custom/4coder_base_types.cpp +++ b/custom/4coder_base_types.cpp @@ -6963,7 +6963,7 @@ global_const u8 base64_reverse[128] = { function u64 digit_count_from_integer(u64 x, u32 radix){ - u64 result = {}; + u64 result = 0; if (radix >= 2 && radix <= 16){ if (x == 0){ result = 1; diff --git a/custom/4coder_base_types.h b/custom/4coder_base_types.h index 3ca3f926..358485d9 100644 --- a/custom/4coder_base_types.h +++ b/custom/4coder_base_types.h @@ -31,14 +31,34 @@ # error architecture not supported yet # endif +#elif defined(__clang__) + +# define COMPILER_CLANG 1 + +# if defined(__APPLE__) && defined(__MACH__) +# define OS_MAC 1 +# else +# error This compiler/platform combo is not supported yet +# endif + +# if defined(__amd64__) || defined(__amd64) || defined(__x86_64__) || defined(__x86_64) +# define ARCH_X64 1 +# elif defined(i386) || defined(__i386) || defined(__i386__) +# define ARCH_X86 1 +# elif defined(__aarch64__) +# define ARCH_ARM64 1 +# elif defined(__arm__) +# define ARCH_ARM32 1 +# else +# error architecture not supported yet +# endif + #elif defined(__GNUC__) || defined(__GNUG__) # define COMPILER_GCC 1 # if defined(__gnu_linux__) # define OS_LINUX 1 -# elif defined(__APPLE__) && defined(__MACH__) -# define OS_MAC 1 # else # error This compiler/platform combo is not supported yet # endif @@ -92,6 +112,9 @@ #if !defined(COMPILER_GCC) #define COMPILER_GCC 0 #endif +#if !defined(COMPILER_CLANG) +#define COMPILER_CLANG 0 +#endif #if !defined(OS_WINDOWS) #define OS_WINDOWS 0 #endif @@ -836,7 +859,7 @@ enum{ struct String_Const_char{ char *str; - u64 size; + u64 size; }; struct String_Const_u8{ union{ @@ -924,25 +947,25 @@ struct Node_String_Const_u32{ struct List_String_Const_char{ Node_String_Const_char *first; Node_String_Const_char *last; - u64 total_size; + u64 total_size; i32 node_count; }; struct List_String_Const_u8{ Node_String_Const_u8 *first; Node_String_Const_u8 *last; - u64 total_size; + u64 total_size; i32 node_count; }; struct List_String_Const_u16{ Node_String_Const_u16 *first; Node_String_Const_u16 *last; - u64 total_size; + u64 total_size; i32 node_count; }; struct List_String_Const_u32{ Node_String_Const_u32 *first; Node_String_Const_u32 *last; - u64 total_size; + u64 total_size; i32 node_count; }; @@ -953,7 +976,7 @@ struct Node_String_Const_Any{ struct List_String_Const_Any{ Node_String_Const_Any *first; Node_String_Const_Any *last; - u64 total_size; + u64 total_size; i32 node_count; }; @@ -962,40 +985,40 @@ struct String_char{ String_Const_char string; struct{ char *str; - u64 size; + u64 size; }; }; - u64 cap; + u64 cap; }; struct String_u8{ union{ String_Const_u8 string; struct{ u8 *str; - u64 size; + u64 size; }; }; - u64 cap; + u64 cap; }; struct String_u16{ union{ String_Const_u16 string; struct{ u16 *str; - u64 size; + u64 size; }; }; - u64 cap; + u64 cap; }; struct String_u32{ union{ String_Const_u32 string; struct{ u32 *str; - u64 size; + u64 size; }; }; - u64 cap; + u64 cap; }; struct String_Any{ @@ -1003,8 +1026,8 @@ struct String_Any{ union{ struct{ void *str; - u64 size; - u64 cap; + u64 size; + u64 cap; }; String_char s_char; String_u8 s_u8; @@ -1091,7 +1114,7 @@ struct Base_Allocator{ struct Cursor{ u8 *base; - u64 pos; + u64 pos; u64 cap; }; struct Temp_Memory_Cursor{ @@ -1231,7 +1254,7 @@ struct Heap_Node{ struct{ Heap_Basic_Node order; Heap_Basic_Node alloc; - u64 size; + u64 size; }; u8 force_size__[64]; }; @@ -1242,8 +1265,8 @@ struct Heap{ Arena *arena; Heap_Basic_Node in_order; Heap_Basic_Node free_nodes; - u64 used_space; - u64 total_space; + u64 used_space; + u64 total_space; }; #endif diff --git a/custom/4coder_command_map.cpp b/custom/4coder_command_map.cpp index d2114d07..0d0ae016 100644 --- a/custom/4coder_command_map.cpp +++ b/custom/4coder_command_map.cpp @@ -425,21 +425,21 @@ function Command_Trigger_List map_get_triggers_recursive(Arena *arena, Mapping *mapping, Command_Map *map, Command_Binding binding){ Command_Trigger_List result = {}; if (mapping != 0){ - for (i32 safety_counter = 0; - map != 0 && safety_counter < 40; - safety_counter += 1){ - Command_Trigger_List list = map_get_triggers_non_recursive(mapping, map, binding); - - for (Command_Trigger *node = list.first, *next = 0; - node != 0; - node = next){ - next = node->next; - Command_Trigger *nnode = push_array_write(arena, Command_Trigger, 1, node); - sll_queue_push(result.first, result.last, nnode); + for (i32 safety_counter = 0; + map != 0 && safety_counter < 40; + safety_counter += 1){ + Command_Trigger_List list = map_get_triggers_non_recursive(mapping, map, binding); + + for (Command_Trigger *node = list.first, *next = 0; + node != 0; + node = next){ + next = node->next; + Command_Trigger *nnode = push_array_write(arena, Command_Trigger, 1, node); + sll_queue_push(result.first, result.last, nnode); + } + + map = mapping_get_map(mapping, map->parent); } - - map = mapping_get_map(mapping, map->parent); - } } return(result); } @@ -721,7 +721,7 @@ map_set_binding_l(Mapping *mapping, Command_Map *map, Custom_Command_Function *c va_start(args, code2); Command_Binding binding = {}; binding.custom = custom; - map_set_binding_lv(mapping, map, binding, code1, code2, args); + map_set_binding_lv(mapping, map, binding, code1, code2, args); va_end(args); } #endif @@ -755,7 +755,7 @@ map_set_binding_l(m, map, BindFWrap_(F), InputEventKind_MouseMove, 0, __VA_ARGS_ #define BindCore(F, K, ...) \ map_set_binding_l(m, map, BindFWrap_(F), InputEventKind_Core, (K), __VA_ARGS__, 0) -#elif COMPILER_GCC +#elif COMPILER_GCC | COMPILER_CLANG #define Bind(F, K, ...) \ map_set_binding_l(m, map, BindFWrap_(F), InputEventKind_KeyStroke, (K), ##__VA_ARGS__, 0) diff --git a/custom/4coder_file_moving.h b/custom/4coder_file_moving.h index b9beb7fe..3b8f0172 100644 --- a/custom/4coder_file_moving.h +++ b/custom/4coder_file_moving.h @@ -115,7 +115,7 @@ internal void fm__swap_ptr(char **A, char **B); fm__swap_ptr(&line.build_options, &line.build_options_prev); \ }while(0) -#elif COMPILER_GCC +#elif COMPILER_GCC | COMPILER_CLANG #define fm_add_to_line(line, str, ...) do{ \ snprintf(line.build_options, line.build_max, "%s " str, \ @@ -259,9 +259,9 @@ extern "C"{ #define OPEN_ALWAYS 4 #define TRUNCATE_EXISTING 5 -#define FILE_ATTRIBUTE_READONLY 0x00000001 -#define FILE_ATTRIBUTE_NORMAL 0x00000080 -#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 +#define FILE_ATTRIBUTE_READONLY 0x00000001 +#define FILE_ATTRIBUTE_NORMAL 0x00000080 +#define FILE_ATTRIBUTE_TEMPORARY 0x00000100 global u64 perf_frequency; @@ -370,9 +370,9 @@ fm_copy_file(char *file, char *newname){ internal void fm_copy_all(char *source, char *folder){ - fprintf(stdout, "copy %s to %s\n", source, folder); - fflush(stdout); - systemf("xcopy /s /e /y /q %s %s > nul", source, folder); + fprintf(stdout, "copy %s to %s\n", source, folder); + fflush(stdout); + systemf("xcopy /s /e /y /q %s %s > nul", source, folder); } internal void diff --git a/custom/bin/buildsuper_x64-mac.sh b/custom/bin/buildsuper_x64-mac.sh index e04e79cf..9f6bce10 100755 --- a/custom/bin/buildsuper_x64-mac.sh +++ b/custom/bin/buildsuper_x64-mac.sh @@ -15,16 +15,16 @@ if [ -z "$SOURCE" ]; then fi # 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" +opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-missing-declarations -Wno-logical-op-parentheses -g" arch=-m64 preproc_file=4coder_command_metadata.i meta_macros="-DMETA_PASS" -g++ -I"$CODE_HOME" $meta_macros $arch $opts $debug -std=gnu++0x "$SOURCE" -E -o $preproc_file -g++ -I"$CODE_HOME" $opts $debug -std=gnu++0x "$CODE_HOME/4coder_metadata_generator.cpp" -o "$CODE_HOME/metadata_generator" +clang++ -I"$CODE_HOME" $meta_macros $arch $opts $debug -std=gnu++0x "$SOURCE" -E -o $preproc_file +clang++ -I"$CODE_HOME" $opts $debug -std=gnu++0x "$CODE_HOME/4coder_metadata_generator.cpp" -o "$CODE_HOME/metadata_generator" "$CODE_HOME/metadata_generator" -R "$CODE_HOME" "$PWD/$preproc_file" -g++ -I"$CODE_HOME" $arch $opts $debug -std=gnu++0x "$SOURCE" -shared -o custom_4coder.so -fPIC +clang++ -I"$CODE_HOME" $arch $opts $debug -std=gnu++0x "$SOURCE" -shared -o custom_4coder.so -fPIC rm "$CODE_HOME/metadata_generator" rm $preproc_file diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index a6e993c2..46c04cd1 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, "../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 }, +{ PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 375 }, +{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 385 }, +{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 154 }, +{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 128 }, +{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 186 }, +{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 578 }, +{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 480 }, +{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 243 }, +{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 842 }, +{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 180 }, +{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_docs.cpp", 49, 190 }, +{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 668 }, +{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 149 }, +{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 19 }, +{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_docs.cpp", 49, 175 }, +{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 28 }, +{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1798 }, +{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 7 }, +{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 23 }, +{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 162 }, +{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1221 }, +{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1396 }, +{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 134 }, +{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_cli_command.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_cli_command.cpp", 56, 7 }, +{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 740 }, +{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 2184 }, +{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 509 }, +{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 651 }, +{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 637 }, +{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 579 }, +{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 673 }, +{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 515 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 597 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 634 }, +{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 563 }, +{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_code_index_listers.cpp", 63, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 57 }, +{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 44 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1542 }, +{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1336 }, +{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 249 }, +{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 265 }, +{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 338 }, +{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 421 }, +{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 530 }, +{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1370 }, +{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 523 }, +{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 495 }, +{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 332 }, +{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1461 }, +{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1792 }, +{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1493 }, +{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 310 }, +{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 366 }, +{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 106 }, +{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 226 }, +{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 219 }, +{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 212 }, +{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "/Users/yuvaldolev/4ed/code/custom/4coder_profile_inspect.cpp", 60, 886 }, +{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1186 }, +{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1298 }, +{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 994 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1550 }, +{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1265 }, +{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 27 }, +{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 99 }, +{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 115 }, +{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 427 }, +{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 1230 }, +{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 644 }, +{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 630 }, +{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_log_parser.cpp", 55, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 187 }, +{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 403 }, +{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1518 }, +{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 552 }, +{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 658 }, +{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 439 }, +{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 433 }, +{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 721 }, +{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 727 }, +{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 445 }, +{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 712 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_code_index.cpp", 55, 1160 }, +{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 20 }, +{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 34 }, +{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 137 }, +{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_lister.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 392 }, +{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 639 }, +{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 88 }, +{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts an underscore.", 22, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 395 }, +{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 76 }, +{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 73 }, +{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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/Resources/DWARF/metadata_generator b/custom/metadata_generator.dSYM/Contents/Resources/DWARF/metadata_generator index 28c1007f45ecd0a4f588766b5e518e8d7fe6dc50..5c9e294020b8a7516616fb4a8862795a763a2d5f 100644 GIT binary patch literal 136740 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 Yd#&*^$M^S#2(V=a_-h7h($ diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 8182c122..34991d33 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -1,4 +1,4 @@ -// #include +#include int main(int arg_count, char **args){ From 18dd91197fca9c4666744852f1fcb204f1a3d7a3 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 24 Dec 2019 02:53:25 +0200 Subject: [PATCH 013/128] The new (very basic) macOS platform layer compiles! --- platform_mac/mac_4ed.mm | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 34991d33..0c7a2c5e 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -1,5 +1,29 @@ #include +@interface App_Delegate : NSObject +@end + +@implementation App_Delegate +- (void)applicationDidFinishLaunching:(id)sender{ +} + +- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)sender{ + return YES; +} + +- (void)applicationWillTerminate:(NSNotification *)notification{ +} + +- (NSSize)windowWillResize:(NSWindow*)window toSize:(NSSize)frame_size{ + // frame_size.height = ((f32)frame_size.width / global_aspect_ratio); + return frame_size; +} + +- (void)windowWillClose:(id)sender { + // global_running = false; +} +@end + int main(int arg_count, char **args){ @autoreleasepool{ From 54f5e72aa50e94ffa460324755b538cd422caad0 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 24 Dec 2019 16:57:05 +0200 Subject: [PATCH 014/128] Added a c++ platform layer file. --- platform_mac/mac_4ed.cpp | 1 + platform_mac/mac_4ed.mm | 51 ++++++++++++++++++++++++++++++++++++---- 2 files changed, 48 insertions(+), 4 deletions(-) create mode 100644 platform_mac/mac_4ed.cpp diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp new file mode 100644 index 00000000..a5486f8e --- /dev/null +++ b/platform_mac/mac_4ed.cpp @@ -0,0 +1 @@ +/* Mac C++ layer for 4coder */ \ No newline at end of file diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 0c7a2c5e..52390586 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -1,5 +1,36 @@ +/* Mac Objective C layer for 4coder */ + #include +#define FPS 60 +#define frame_useconds (1000000 / FPS) + +#include "4coder_base_types.h" +#include "4coder_version.h" +#include "4coder_events.h" + +#include "4coder_system_types.h" +#define STATIC_LINK_API +#include "generated/system_api.h" + +#include "generated/system_api.cpp" + +#include "4coder_base_types.cpp" + +//////////////////////////////// + +#define SLASH '\\' +#define DLL "dll" + +#include "4coder_hash_functions.cpp" +#include "4coder_system_allocator.cpp" +#include "4coder_codepoint_map.cpp" + +#include "4ed_mem.cpp" +#include "4ed_font_set.cpp" + +//////////////////////////////// + @interface App_Delegate : NSObject @end @@ -19,7 +50,7 @@ return frame_size; } -- (void)windowWillClose:(id)sender { +- (void)windowWillClose:(id)sender{ // global_running = false; } @end @@ -27,7 +58,7 @@ int main(int arg_count, char **args){ @autoreleasepool{ - // NOTE(yuval): NSApplication & Delegate Creation + // NOTE(yuval): Create NSApplication & Delegate NSApplication* app = [NSApplication sharedApplication]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; @@ -36,7 +67,7 @@ main(int arg_count, char **args){ [NSApp finishLaunching]; -#if 0 + // NOTE(yuval): Context Setup Thread_Context _tctx = {}; thread_ctx_init(&_tctx, ThreadKind_Main, get_base_allocator_system(), @@ -45,11 +76,23 @@ main(int arg_count, char **args){ block_zero_struct(&global_mac_vars); global_mac_vars.tctx = &_tctx; + API_VTable_system system_vtable = {}; + system_api_fill_vtable(&system_vtable); + + API_VTable_graphics graphics_vtable = {}; + graphics_api_fill_vtable(&graphics_vtable); + + API_VTable_font font_vtable = {}; + font_api_fill_vtable(&font_vtable); + + // NOTE(yuval): Memory + global_mac_vars.frame_arena = reserve_arena(global_mac_vars.tctx); + global_target.arean = make_arena_system(KB(256)); + // NOTE(yuval): Application Core Update Application_Step_Result result = {}; if (app.step != 0){ result = app.step(mac_vars.tctx, &target, base_ptr, &input); } -#endif } } \ No newline at end of file From e3e5f857ea5c964fc2fabdce076b60d3a3c8ff07 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 24 Dec 2019 22:31:24 +0200 Subject: [PATCH 015/128] Added empty implementations of all the system api functions to mac_4ed_functions.cpp --- bin/4ed_build.cpp | 2 +- custom/generated/system_api.h | 94 ++--- platform_mac/mac_4ed.cpp | 94 ++++- platform_mac/mac_4ed.mm | 58 +-- platform_mac/mac_4ed_functions.cpp | 348 ++++++++++++++++++ platform_mac/mac_4ed_old.cpp | 2 +- platform_mac/mac_4ed_old.m | 16 +- platform_mac/mac_objective_c_to_cpp_links.h | 13 + ...s.h => osx_objective_c_to_cpp_links_old.h} | 0 9 files changed, 518 insertions(+), 109 deletions(-) create mode 100644 platform_mac/mac_4ed_functions.cpp create mode 100644 platform_mac/mac_objective_c_to_cpp_links.h rename platform_mac/{osx_objective_c_to_cpp_links.h => osx_objective_c_to_cpp_links_old.h} (100%) diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index 146169fb..f15d0040 100644 --- a/bin/4ed_build.cpp +++ b/bin/4ed_build.cpp @@ -94,7 +94,7 @@ char *includes[] = { "custom", FOREIGN "/freetype2", 0, }; 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.mm", 0 }; +char *mac_platform_layer[] = { "platform_mac/mac_4ed.mm", "platform_mac/mac_4ed.cpp", 0 }; char **platform_layers[Platform_COUNT] = { windows_platform_layer, diff --git a/custom/generated/system_api.h b/custom/generated/system_api.h index ce9536da..f67a518f 100644 --- a/custom/generated/system_api.h +++ b/custom/generated/system_api.h @@ -93,53 +93,53 @@ typedef b32 system_set_fullscreen_type(b32 full_screen); typedef b32 system_is_fullscreen_type(void); typedef Input_Modifier_Set system_get_keyboard_modifiers_type(Arena* arena); struct API_VTable_system{ -system_get_path_type *get_path; -system_get_canonical_type *get_canonical; -system_get_file_list_type *get_file_list; -system_quick_file_attributes_type *quick_file_attributes; -system_load_handle_type *load_handle; -system_load_attributes_type *load_attributes; -system_load_file_type *load_file; -system_load_close_type *load_close; -system_save_file_type *save_file; -system_load_library_type *load_library; -system_release_library_type *release_library; -system_get_proc_type *get_proc; -system_now_time_type *now_time; -system_wake_up_timer_create_type *wake_up_timer_create; -system_wake_up_timer_release_type *wake_up_timer_release; -system_wake_up_timer_set_type *wake_up_timer_set; -system_signal_step_type *signal_step; -system_sleep_type *sleep; -system_post_clipboard_type *post_clipboard; -system_cli_call_type *cli_call; -system_cli_begin_update_type *cli_begin_update; -system_cli_update_step_type *cli_update_step; -system_cli_end_update_type *cli_end_update; -system_open_color_picker_type *open_color_picker; -system_get_screen_scale_factor_type *get_screen_scale_factor; -system_thread_launch_type *thread_launch; -system_thread_join_type *thread_join; -system_thread_free_type *thread_free; -system_thread_get_id_type *thread_get_id; -system_acquire_global_frame_mutex_type *acquire_global_frame_mutex; -system_release_global_frame_mutex_type *release_global_frame_mutex; -system_mutex_make_type *mutex_make; -system_mutex_acquire_type *mutex_acquire; -system_mutex_release_type *mutex_release; -system_mutex_free_type *mutex_free; -system_condition_variable_make_type *condition_variable_make; -system_condition_variable_wait_type *condition_variable_wait; -system_condition_variable_signal_type *condition_variable_signal; -system_condition_variable_free_type *condition_variable_free; -system_memory_allocate_type *memory_allocate; -system_memory_set_protection_type *memory_set_protection; -system_memory_free_type *memory_free; -system_memory_annotation_type *memory_annotation; -system_show_mouse_cursor_type *show_mouse_cursor; -system_set_fullscreen_type *set_fullscreen; -system_is_fullscreen_type *is_fullscreen; -system_get_keyboard_modifiers_type *get_keyboard_modifiers; + system_get_path_type *get_path; + system_get_canonical_type *get_canonical; + system_get_file_list_type *get_file_list; + system_quick_file_attributes_type *quick_file_attributes; + system_load_handle_type *load_handle; + system_load_attributes_type *load_attributes; + system_load_file_type *load_file; + system_load_close_type *load_close; + system_save_file_type *save_file; + system_load_library_type *load_library; + system_release_library_type *release_library; + system_get_proc_type *get_proc; + system_now_time_type *now_time; + system_wake_up_timer_create_type *wake_up_timer_create; + system_wake_up_timer_release_type *wake_up_timer_release; + system_wake_up_timer_set_type *wake_up_timer_set; + system_signal_step_type *signal_step; + system_sleep_type *sleep; + system_post_clipboard_type *post_clipboard; + system_cli_call_type *cli_call; + system_cli_begin_update_type *cli_begin_update; + system_cli_update_step_type *cli_update_step; + system_cli_end_update_type *cli_end_update; + system_open_color_picker_type *open_color_picker; + system_get_screen_scale_factor_type *get_screen_scale_factor; + system_thread_launch_type *thread_launch; + system_thread_join_type *thread_join; + system_thread_free_type *thread_free; + system_thread_get_id_type *thread_get_id; + system_acquire_global_frame_mutex_type *acquire_global_frame_mutex; + system_release_global_frame_mutex_type *release_global_frame_mutex; + system_mutex_make_type *mutex_make; + system_mutex_acquire_type *mutex_acquire; + system_mutex_release_type *mutex_release; + system_mutex_free_type *mutex_free; + system_condition_variable_make_type *condition_variable_make; + system_condition_variable_wait_type *condition_variable_wait; + system_condition_variable_signal_type *condition_variable_signal; + system_condition_variable_free_type *condition_variable_free; + system_memory_allocate_type *memory_allocate; + system_memory_set_protection_type *memory_set_protection; + system_memory_free_type *memory_free; + system_memory_annotation_type *memory_annotation; + system_show_mouse_cursor_type *show_mouse_cursor; + system_set_fullscreen_type *set_fullscreen; + system_is_fullscreen_type *is_fullscreen; + system_get_keyboard_modifiers_type *get_keyboard_modifiers; }; #if defined(STATIC_LINK_API) internal String_Const_u8 system_get_path(Arena* arena, System_Path_Code path_code); diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp index a5486f8e..7272be87 100644 --- a/platform_mac/mac_4ed.cpp +++ b/platform_mac/mac_4ed.cpp @@ -1 +1,93 @@ -/* Mac C++ layer for 4coder */ \ No newline at end of file +/* Mac C++ layer for 4coder */ + +#include "4coder_base_types.h" +#include "4coder_version.h" +#include "4coder_events.h" + +#include "4coder_table.h" +#include "4coder_types.h" +#include "4coder_default_colors.h" + +#include "4coder_system_types.h" +#define STATIC_LINK_API +#include "generated/system_api.h" + +#include "4ed_font_interface.h" +#define STATIC_LINK_API +#include "generated/graphics_api.h" +#define STATIC_LINK_API +#include "generated/font_api.h" + +#include "4ed_font_set.h" +#include "4ed_render_target.h" +#include "4ed_search_list.h" +#include "4ed.h" + +#include "generated/system_api.cpp" +#include "generated/graphics_api.cpp" +#include "generated/font_api.cpp" + +#include "4coder_base_types.cpp" +#include "4coder_stringf.cpp" +#include "4coder_events.cpp" +#include "4coder_hash_functions.cpp" +#include "4coder_table.cpp" +#include "4coder_log.cpp" + +#include "4ed_search_list.cpp" + +//////////////////////////////// + +#define SLASH '\\' +#define DLL "dll" + +#include "4coder_hash_functions.cpp" +#include "4coder_system_allocator.cpp" +#include "4coder_codepoint_map.cpp" + +#include "4ed_mem.cpp" +#include "4ed_font_set.cpp" + +//////////////////////////////// + +struct Mac_Vars { + Thread_Context *tctx; + + Arena* frame_arena; +}; + +//////////////////////////////// + +Mac_Vars global_mac_vars; +global Render_Target global_target; + +//////////////////////////////// + +#include "mac_4ed_functions.cpp" + +//////////////////////////////// + +external void +mac_init() { + // NOTE(yuval): Context Setup + Thread_Context _tctx = {}; + thread_ctx_init(&_tctx, ThreadKind_Main, + get_base_allocator_system(), + get_base_allocator_system()); + + block_zero_struct(&global_mac_vars); + global_mac_vars.tctx = &_tctx; + + API_VTable_system system_vtable = {}; + system_api_fill_vtable(&system_vtable); + + API_VTable_graphics graphics_vtable = {}; + graphics_api_fill_vtable(&graphics_vtable); + + API_VTable_font font_vtable = {}; + font_api_fill_vtable(&font_vtable); + + // NOTE(yuval): Memory + global_mac_vars.frame_arena = reserve_arena(global_mac_vars.tctx); + global_target.arena = make_arena_system(KB(256)); +} \ No newline at end of file diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 52390586..538e2f4a 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -1,35 +1,13 @@ /* Mac Objective C layer for 4coder */ -#include - -#define FPS 60 -#define frame_useconds (1000000 / FPS) - #include "4coder_base_types.h" -#include "4coder_version.h" -#include "4coder_events.h" +#include "mac_objective_c_to_cpp_links.h" -#include "4coder_system_types.h" -#define STATIC_LINK_API -#include "generated/system_api.h" - -#include "generated/system_api.cpp" - -#include "4coder_base_types.cpp" - -//////////////////////////////// - -#define SLASH '\\' -#define DLL "dll" - -#include "4coder_hash_functions.cpp" -#include "4coder_system_allocator.cpp" -#include "4coder_codepoint_map.cpp" - -#include "4ed_mem.cpp" -#include "4ed_font_set.cpp" - -//////////////////////////////// +#undef function +#undef internal +#undef global +#undef external +#include @interface App_Delegate : NSObject @end @@ -67,32 +45,14 @@ main(int arg_count, char **args){ [NSApp finishLaunching]; - // NOTE(yuval): Context Setup - Thread_Context _tctx = {}; - thread_ctx_init(&_tctx, ThreadKind_Main, - get_base_allocator_system(), - get_base_allocator_system()); - - block_zero_struct(&global_mac_vars); - global_mac_vars.tctx = &_tctx; - - API_VTable_system system_vtable = {}; - system_api_fill_vtable(&system_vtable); - - API_VTable_graphics graphics_vtable = {}; - graphics_api_fill_vtable(&graphics_vtable); - - API_VTable_font font_vtable = {}; - font_api_fill_vtable(&font_vtable); - - // NOTE(yuval): Memory - global_mac_vars.frame_arena = reserve_arena(global_mac_vars.tctx); - global_target.arean = make_arena_system(KB(256)); + mac_init(); +#if 0 // NOTE(yuval): Application Core Update Application_Step_Result result = {}; if (app.step != 0){ result = app.step(mac_vars.tctx, &target, base_ptr, &input); } +#endif } } \ No newline at end of file diff --git a/platform_mac/mac_4ed_functions.cpp b/platform_mac/mac_4ed_functions.cpp new file mode 100644 index 00000000..7288250c --- /dev/null +++ b/platform_mac/mac_4ed_functions.cpp @@ -0,0 +1,348 @@ +/* General macOS Functions */ + +function +system_get_path_sig(){ + String_Const_u8 result = {}; + + NotImplemented; + + return result; +} + +function +system_get_canonical_sig(){ + String_Const_u8 result = {}; + + NotImplemented; + + return result; +} + +function +system_get_file_list_sig(){ + File_List result = {}; + + NotImplemented; + + return result; +} + +function +system_quick_file_attributes_sig(){ + File_Attributes result = {}; + + NotImplemented; + + return result; +} + +function +system_load_handle_sig(){ + b32 result = false; + + NotImplemented; + + return result; +} + +function +system_load_attributes_sig(){ + File_Attributes result = {}; + + NotImplemented; + + return result; +} + +function +system_load_file_sig(){ + b32 result = false; + + NotImplemented; + + return result; +} + +function +system_load_close_sig(){ + b32 result = false; + + NotImplemented; + + return result; +} + +function +system_save_file_sig(){ + File_Attributes result = {}; + + NotImplemented; + + return result; +} + +function +system_load_library_sig(){ + b32 result = false; + + NotImplemented; + + return result; +} + +function +system_release_library_sig(){ + b32 result = false; + + NotImplemented; + + return result; +} + +function +system_get_proc_sig(){ + Void_Func* result = 0; + + NotImplemented; + + return result; +} + +function +system_now_time_sig(){ + u64 result = 0; + + NotImplemented; + + return result; +} + +function +system_wake_up_timer_create_sig(){ + Plat_Handle result = {}; + + NotImplemented; + + return result; +} + +function +system_wake_up_timer_release_sig(){ + NotImplemented; +} + +function +system_wake_up_timer_set_sig(){ + NotImplemented; +} + +function +system_signal_step_sig(){ + NotImplemented; +} + +function +system_sleep_sig(){ + NotImplemented; +} + +function +system_post_clipboard_sig(){ + NotImplemented; +} + +function +system_cli_call_sig(){ + b32 result = false; + + NotImplemented; + + return result; +} + +function +system_cli_begin_update_sig(){ + NotImplemented; +} + +function +system_cli_update_step_sig(){ + b32 result = false; + + NotImplemented; + + return result; +} + +function +system_cli_end_update_sig(){ + b32 result = false; + + NotImplemented; + + return result; +} + +function +system_open_color_picker_sig(){ + NotImplemented; +} + +function +system_get_screen_scale_factor_sig(){ + f32 result = 0.0f; + + NotImplemented; + + return result; +} + +function +system_thread_launch_sig(){ + System_Thread result = {}; + + NotImplemented; + + return result; +} + +function +system_thread_join_sig(){ + NotImplemented; +} + +function +system_thread_free_sig(){ + NotImplemented; +} + +function +system_thread_get_id_sig(){ + i32 result = 0; + + NotImplemented; + + return result; +} + +function +system_acquire_global_frame_mutex_sig(){ + NotImplemented; +} + +function +system_release_global_frame_mutex_sig(){ + NotImplemented; +} + +function +system_mutex_make_sig(){ + System_Mutex result = {}; + + NotImplemented; + + return result; +} + +function +system_mutex_acquire_sig(){ + NotImplemented; +} + +function +system_mutex_release_sig(){ + NotImplemented; +} + +function +system_mutex_free_sig(){ + NotImplemented; +} + +function +system_condition_variable_make_sig(){ + System_Condition_Variable result = {}; + + NotImplemented; + + return result; +} + +function +system_condition_variable_wait_sig(){ + NotImplemented; +} + +function +system_condition_variable_signal_sig(){ + NotImplemented; +} + +function +system_condition_variable_free_sig(){ + NotImplemented; +} + +function +system_memory_allocate_sig(){ + void* result = 0; + + NotImplemented; + + return result; +} + +function +system_memory_set_protection_sig(){ + b32 result = false; + + NotImplemented; + + return result; +} + +function +system_memory_free_sig(){ + NotImplemented; +} + +function +system_memory_annotation_sig(){ + Memory_Annotation result = {}; + + NotImplemented; + + return result; +} + +function +system_show_mouse_cursor_sig(){ + NotImplemented; +} + +function +system_set_fullscreen_sig(){ + b32 result = false; + + NotImplemented; + + return result; +} + +function +system_is_fullscreen_sig(){ + b32 result = false; + + NotImplemented; + + return result; +} + +function +system_get_keyboard_modifiers_sig(){ + Input_Modifier_Set result = {}; + + NotImplemented; + + return result; +} diff --git a/platform_mac/mac_4ed_old.cpp b/platform_mac/mac_4ed_old.cpp index 77b111ec..81e7ffc3 100644 --- a/platform_mac/mac_4ed_old.cpp +++ b/platform_mac/mac_4ed_old.cpp @@ -782,7 +782,7 @@ osx_init(){ osxvars.input.first_step = true; // - // HACK(allen): + // HACK(allen): // Previously zipped stuff is here, it should be zipped in the new pattern now. // diff --git a/platform_mac/mac_4ed_old.m b/platform_mac/mac_4ed_old.m index 098da2fe..ebadc1ca 100644 --- a/platform_mac/mac_4ed_old.m +++ b/platform_mac/mac_4ed_old.m @@ -9,7 +9,6 @@ // TOP -#if 0 #define IS_OBJC_LAYER #include "4coder_base_types.h" @@ -24,8 +23,6 @@ #define external #include "osx_objective_c_to_cpp_links.h" -#endif - #include #import @@ -33,7 +30,7 @@ #import #import #import -#if 0 + #include #include #include @@ -817,9 +814,9 @@ osx_list_loadable_fonts(void){ NSString *font_n = fonts[i]; char *font_n_c = (char*)[font_n UTF8String]; NSFont *font = [font_manager - fontWithFamily:font_n - traits:NSUnboldFontMask|NSUnitalicFontMask - weight:5 + fontWithFamily:font_n + traits:NSUnboldFontMask|NSUnitalicFontMask + weight:5 size:12]; NSString *path = get_font_path(font); char *path_c = 0; @@ -843,10 +840,9 @@ OSX_Keyboard_Modifiers osx_get_modifiers(void){ return(osx_mods_nsevent_to_struct([NSEvent modifierFlags])); } -#endif + int main(int argc, char **argv){ -#if 0 memset(&osx_objc, 0, sizeof(osx_objc)); u32 clipboard_size = KB(16); @@ -891,7 +887,7 @@ main(int argc, char **argv){ [NSApp run]; } -#endif + return(0); } diff --git a/platform_mac/mac_objective_c_to_cpp_links.h b/platform_mac/mac_objective_c_to_cpp_links.h new file mode 100644 index 00000000..09605098 --- /dev/null +++ b/platform_mac/mac_objective_c_to_cpp_links.h @@ -0,0 +1,13 @@ +/* Types and functions for communication between C++ and Objective-C layers. */ + +#if !defined(MAC_OBJECTIVE_C_TO_CPP_LINKS_H) +#define MAC_OBJECTIVE_C_TO_CPP_LINKS_H + +// In C++ layer. +external void* +mac_init(); + +// In Objective-C layer. + +#endif + diff --git a/platform_mac/osx_objective_c_to_cpp_links.h b/platform_mac/osx_objective_c_to_cpp_links_old.h similarity index 100% rename from platform_mac/osx_objective_c_to_cpp_links.h rename to platform_mac/osx_objective_c_to_cpp_links_old.h From 57c0707284cb845773a06d1780db3e1f57fe89b4 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Wed, 25 Dec 2019 03:17:12 +0200 Subject: [PATCH 016/128] Implemented system_get_path. --- platform_mac/mac_4ed.cpp | 27 ++++- platform_mac/mac_4ed.mm | 16 +++ platform_mac/mac_4ed_functions.cpp | 128 +++++++++++++++----- platform_mac/mac_objective_c_to_cpp_links.h | 4 +- platform_win32/win32_4ed_functions.cpp | 4 +- 5 files changed, 140 insertions(+), 39 deletions(-) diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp index 7272be87..ec82755a 100644 --- a/platform_mac/mac_4ed.cpp +++ b/platform_mac/mac_4ed.cpp @@ -36,6 +36,11 @@ #include "4ed_search_list.cpp" +#include "mac_objective_c_to_cpp_links.h" + +#include +#include + //////////////////////////////// #define SLASH '\\' @@ -54,12 +59,14 @@ struct Mac_Vars { Thread_Context *tctx; Arena* frame_arena; + + String_Const_u8 binary_path; }; //////////////////////////////// -Mac_Vars global_mac_vars; -global Render_Target global_target; +Mac_Vars mac_vars; +global Render_Target target; //////////////////////////////// @@ -75,8 +82,8 @@ mac_init() { get_base_allocator_system(), get_base_allocator_system()); - block_zero_struct(&global_mac_vars); - global_mac_vars.tctx = &_tctx; + block_zero_struct(&mac_vars); + mac_vars.tctx = &_tctx; API_VTable_system system_vtable = {}; system_api_fill_vtable(&system_vtable); @@ -88,6 +95,14 @@ mac_init() { font_api_fill_vtable(&font_vtable); // NOTE(yuval): Memory - global_mac_vars.frame_arena = reserve_arena(global_mac_vars.tctx); - global_target.arena = make_arena_system(KB(256)); + mac_vars.frame_arena = reserve_arena(mac_vars.tctx); + target.arena = make_arena_system(KB(256)); + +#if 0 + mac_vars.cursor_show = MouseCursorShow_Always; + mac_vars.prev_cursor_show = MouseCursorShow_Always; + + dll_init_sentinel(&mac_vars.free_mac_objects); + dll_init_sentinel(&mac_vars.timer_objects); +#endif } \ No newline at end of file diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 538e2f4a..cdd47d24 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -1,6 +1,7 @@ /* Mac Objective C layer for 4coder */ #include "4coder_base_types.h" + #include "mac_objective_c_to_cpp_links.h" #undef function @@ -9,6 +10,13 @@ #undef external #include +#include // NOTE(yuval): Used for proc_pidpath + +#include +#include // NOTE(yuval): Used for getpid + +#define external extern "C" + @interface App_Delegate : NSObject @end @@ -33,6 +41,14 @@ } @end +external i32 +mac_get_binary_path(void *buffer, u32 size){ + pid_t pid = getpid(); + i32 bytes_read = proc_pidpath(pid, buffer, size); + + return bytes_read; +} + int main(int arg_count, char **args){ @autoreleasepool{ diff --git a/platform_mac/mac_4ed_functions.cpp b/platform_mac/mac_4ed_functions.cpp index 7288250c..e157019b 100644 --- a/platform_mac/mac_4ed_functions.cpp +++ b/platform_mac/mac_4ed_functions.cpp @@ -1,12 +1,47 @@ -/* General macOS Functions */ +/* macOS System/Graphics/Font API Implementations */ + +//////////////////////////////// function system_get_path_sig(){ String_Const_u8 result = {}; - NotImplemented; + switch (path_code){ + case SystemPath_CurrentDirectory: + { + char *working_dir = getcwd(NULL, 0); + u64 working_dir_length = cstring_length(working_dir); + + // TODO(yuval): Maybe use push_string_copy instead + u8 *out = push_array(arena, u8, working_dir_length); + block_copy(out, working_dir, working_dir_length); + + free(working_dir); + + result = SCu8(out, working_dir_length); + } break; + + case SystemPath_Binary: + { + local_persist b32 has_stashed_4ed_path = false; + if (!has_stashed_4ed_path){ + local_const i32 binary_path_capacity = KB(32); + u8 *memory = (u8*)system_memory_allocate(binary_path_capacity, string_u8_litexpr(file_name_line_number)); + i32 size = mac_get_binary_path(memory, binary_path_capacity); + Assert(size <= binary_path_capacity - 1); + + mac_vars.binary_path = SCu8(memory, size); + mac_vars.binary_path = string_remove_last_folder(mac_vars.binary_path); + mac_vars.binary_path.str[mac_vars.binary_path.size] = 0; + + has_stashed_4ed_path = true; + } + + result = push_string_copy(arena, mac_vars.binary_path); + } break; + } - return result; + return(result); } function @@ -15,7 +50,7 @@ system_get_canonical_sig(){ NotImplemented; - return result; + return(result); } function @@ -24,7 +59,7 @@ system_get_file_list_sig(){ NotImplemented; - return result; + return(result); } function @@ -33,7 +68,7 @@ system_quick_file_attributes_sig(){ NotImplemented; - return result; + return(result); } function @@ -42,7 +77,7 @@ system_load_handle_sig(){ NotImplemented; - return result; + return(result); } function @@ -51,7 +86,7 @@ system_load_attributes_sig(){ NotImplemented; - return result; + return(result); } function @@ -60,7 +95,7 @@ system_load_file_sig(){ NotImplemented; - return result; + return(result); } function @@ -69,7 +104,7 @@ system_load_close_sig(){ NotImplemented; - return result; + return(result); } function @@ -78,7 +113,7 @@ system_save_file_sig(){ NotImplemented; - return result; + return(result); } function @@ -87,7 +122,7 @@ system_load_library_sig(){ NotImplemented; - return result; + return(result); } function @@ -96,7 +131,7 @@ system_release_library_sig(){ NotImplemented; - return result; + return(result); } function @@ -105,7 +140,7 @@ system_get_proc_sig(){ NotImplemented; - return result; + return(result); } function @@ -114,7 +149,7 @@ system_now_time_sig(){ NotImplemented; - return result; + return(result); } function @@ -123,7 +158,7 @@ system_wake_up_timer_create_sig(){ NotImplemented; - return result; + return(result); } function @@ -157,7 +192,7 @@ system_cli_call_sig(){ NotImplemented; - return result; + return(result); } function @@ -171,7 +206,7 @@ system_cli_update_step_sig(){ NotImplemented; - return result; + return(result); } function @@ -180,7 +215,7 @@ system_cli_end_update_sig(){ NotImplemented; - return result; + return(result); } function @@ -194,7 +229,7 @@ system_get_screen_scale_factor_sig(){ NotImplemented; - return result; + return(result); } function @@ -203,7 +238,7 @@ system_thread_launch_sig(){ NotImplemented; - return result; + return(result); } function @@ -222,7 +257,7 @@ system_thread_get_id_sig(){ NotImplemented; - return result; + return(result); } function @@ -241,7 +276,7 @@ system_mutex_make_sig(){ NotImplemented; - return result; + return(result); } function @@ -265,7 +300,7 @@ system_condition_variable_make_sig(){ NotImplemented; - return result; + return(result); } function @@ -289,7 +324,7 @@ system_memory_allocate_sig(){ NotImplemented; - return result; + return(result); } function @@ -298,7 +333,7 @@ system_memory_set_protection_sig(){ NotImplemented; - return result; + return(result); } function @@ -312,7 +347,7 @@ system_memory_annotation_sig(){ NotImplemented; - return result; + return(result); } function @@ -326,7 +361,7 @@ system_set_fullscreen_sig(){ NotImplemented; - return result; + return(result); } function @@ -335,7 +370,7 @@ system_is_fullscreen_sig(){ NotImplemented; - return result; + return(result); } function @@ -344,5 +379,38 @@ system_get_keyboard_modifiers_sig(){ NotImplemented; - return result; + return(result); } + +//////////////////////////////// + +function +graphics_get_texture_sig(){ + u32 result = 0; + + NotImplemented; + + return(result); +} + +function +graphics_fill_texture_sig(){ + b32 result = false; + + NotImplemented; + + return(result); +} + +//////////////////////////////// + +function +font_make_face_sig(){ + Face* result = 0; + + NotImplemented; + + return(result); +} + +//////////////////////////////// \ No newline at end of file diff --git a/platform_mac/mac_objective_c_to_cpp_links.h b/platform_mac/mac_objective_c_to_cpp_links.h index 09605098..0dc4ae3a 100644 --- a/platform_mac/mac_objective_c_to_cpp_links.h +++ b/platform_mac/mac_objective_c_to_cpp_links.h @@ -4,10 +4,12 @@ #define MAC_OBJECTIVE_C_TO_CPP_LINKS_H // In C++ layer. -external void* +external void mac_init(); // In Objective-C layer. +external i32 +mac_get_binary_path(void* buffer, u32 size); #endif diff --git a/platform_win32/win32_4ed_functions.cpp b/platform_win32/win32_4ed_functions.cpp index 8e139ea1..5e7533b3 100644 --- a/platform_win32/win32_4ed_functions.cpp +++ b/platform_win32/win32_4ed_functions.cpp @@ -444,7 +444,7 @@ color_picker_hook(HWND Window, UINT Message, WPARAM WParam, LPARAM LParam){ // Would it have killed you to update rgbResult continuously, or at least // provide a GetCurrentColor() call??? // - // Anyway, since the color picker doesn't tell us when the color is + // Anyway, since the color picker doesn't tell us when the color is // changed, what we do is watch for messages that repaint the color // swatch, which is dialog id 0x2c5, and then we sample it to see what // color it is. No, I'm not fucking kidding, that's what we do. @@ -533,7 +533,7 @@ internal system_open_color_picker_sig(){ // TODO(allen): review // NOTE(casey): Because this is going to be used by a semi-permanent thread, we need to - // copy it to system memory where it can live as long as it wants, no matter what we do + // copy it to system memory where it can live as long as it wants, no matter what we do // over here on the 4coder threads. Color_Picker *perm = (Color_Picker*)system_memory_allocate(sizeof(Color_Picker), string_u8_litexpr(file_name_line_number)); *perm = *picker; From 9b0708a40cf61ab7a718f65d7db6da025210ee6c Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Wed, 25 Dec 2019 23:31:21 +0200 Subject: [PATCH 017/128] Implemented system_get_canonical. --- platform_mac/mac_4ed.mm | 21 ++++++++++++++++++++- platform_mac/mac_4ed_functions.cpp | 5 +---- 2 files changed, 21 insertions(+), 5 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index cdd47d24..d3c4f601 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -12,7 +12,7 @@ #include // NOTE(yuval): Used for proc_pidpath -#include +#include // NOTE(yuval): Used for pid_t #include // NOTE(yuval): Used for getpid #define external extern "C" @@ -41,6 +41,21 @@ } @end +external String_Const_u8 +mac_standardize_path(Arena* arena, String_Const_u8 path){ + NSString *path_ns_str = + [[NSString alloc] initWithBytes:path.data length:path.size encoding:NSUTF8StringEncoding]; + + NSString *standardized_path_ns_str = [path_ns_str stringByStandardizingPath]; + String_Const_u8 standardized_path = SCu8([standardized_path_ns_str UTF8String],[standardized_path_ns_str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); + + String_Const_u8 result = push_string_copy(arena, standardized_path); + + [path release]; + + return result; +} + external i32 mac_get_binary_path(void *buffer, u32 size){ pid_t pid = getpid(); @@ -52,6 +67,10 @@ mac_get_binary_path(void *buffer, u32 size){ int main(int arg_count, char **args){ @autoreleasepool{ + NSFileManager *fileManager = [[NSFileManager alloc] init]; + NSString *displayNameAtPath = [fileManager displayNameAtPath:@"build"]; + NSLog(@"Display Name: %@", displayNameAtPath); + // NOTE(yuval): Create NSApplication & Delegate NSApplication* app = [NSApplication sharedApplication]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; diff --git a/platform_mac/mac_4ed_functions.cpp b/platform_mac/mac_4ed_functions.cpp index e157019b..bb385e2e 100644 --- a/platform_mac/mac_4ed_functions.cpp +++ b/platform_mac/mac_4ed_functions.cpp @@ -46,10 +46,7 @@ system_get_path_sig(){ function system_get_canonical_sig(){ - String_Const_u8 result = {}; - - NotImplemented; - + String_Const_u8 result = mac_standardize_path(arena, name); return(result); } From 2f9a4dbe3a6121a4015c19c4370cca05017f1827 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 26 Dec 2019 00:19:50 +0200 Subject: [PATCH 018/128] Fixed compilation errors and tested system_get_canonical. --- platform_mac/mac_4ed.cpp | 15 ++++++++++++++- platform_mac/mac_4ed.mm | 14 +++++--------- platform_mac/mac_objective_c_to_cpp_links.h | 13 +++++++++++-- 3 files changed, 30 insertions(+), 12 deletions(-) diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp index ec82755a..7b66f04d 100644 --- a/platform_mac/mac_4ed.cpp +++ b/platform_mac/mac_4ed.cpp @@ -48,6 +48,7 @@ #include "4coder_hash_functions.cpp" #include "4coder_system_allocator.cpp" +#include "4coder_malloc_allocator.cpp" #include "4coder_codepoint_map.cpp" #include "4ed_mem.cpp" @@ -74,8 +75,20 @@ global Render_Target target; //////////////////////////////// +external String_Const_u8 +mac_SCu8(u8* str, u64 size){ + String_Const_u8 result = SCu8(str, size); + return(result); +} + +external String_Const_u8 +mac_push_string_copy(Arena *arena, String_Const_u8 src){ + String_Const_u8 result = push_string_copy(arena, src); + return(result); +} + external void -mac_init() { +mac_init(){ // NOTE(yuval): Context Setup Thread_Context _tctx = {}; thread_ctx_init(&_tctx, ThreadKind_Main, diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index d3c4f601..a39fe56e 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -47,13 +47,13 @@ mac_standardize_path(Arena* arena, String_Const_u8 path){ [[NSString alloc] initWithBytes:path.data length:path.size encoding:NSUTF8StringEncoding]; NSString *standardized_path_ns_str = [path_ns_str stringByStandardizingPath]; - String_Const_u8 standardized_path = SCu8([standardized_path_ns_str UTF8String],[standardized_path_ns_str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); + String_Const_u8 standardized_path = mac_SCu8((u8*)[standardized_path_ns_str UTF8String],[standardized_path_ns_str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); - String_Const_u8 result = push_string_copy(arena, standardized_path); + String_Const_u8 result = mac_push_string_copy(arena, standardized_path); - [path release]; + [path_ns_str release]; - return result; + return(result); } external i32 @@ -61,16 +61,12 @@ mac_get_binary_path(void *buffer, u32 size){ pid_t pid = getpid(); i32 bytes_read = proc_pidpath(pid, buffer, size); - return bytes_read; + return(bytes_read); } int main(int arg_count, char **args){ @autoreleasepool{ - NSFileManager *fileManager = [[NSFileManager alloc] init]; - NSString *displayNameAtPath = [fileManager displayNameAtPath:@"build"]; - NSLog(@"Display Name: %@", displayNameAtPath); - // NOTE(yuval): Create NSApplication & Delegate NSApplication* app = [NSApplication sharedApplication]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; diff --git a/platform_mac/mac_objective_c_to_cpp_links.h b/platform_mac/mac_objective_c_to_cpp_links.h index 0dc4ae3a..c5f4db62 100644 --- a/platform_mac/mac_objective_c_to_cpp_links.h +++ b/platform_mac/mac_objective_c_to_cpp_links.h @@ -3,13 +3,22 @@ #if !defined(MAC_OBJECTIVE_C_TO_CPP_LINKS_H) #define MAC_OBJECTIVE_C_TO_CPP_LINKS_H -// In C++ layer. +// In C++ layer +external String_Const_u8 +mac_SCu8(u8* str, u64 size); + +external String_Const_u8 +mac_push_string_copy(Arena *arena, String_Const_u8 src); + external void mac_init(); -// In Objective-C layer. +// In Objective-C layer external i32 mac_get_binary_path(void* buffer, u32 size); +external String_Const_u8 +mac_standardize_path(Arena* arena, String_Const_u8 path); + #endif From 131769223346d8471470580ac4471aa1bbe64fc8 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 26 Dec 2019 03:16:34 +0200 Subject: [PATCH 019/128] Work on system_get_file_list. --- platform_mac/mac_4ed.cpp | 10 +++- platform_mac/mac_4ed.mm | 21 +++++++ platform_mac/mac_4ed_functions.cpp | 92 +++++++++++++++++++++++++++++- 3 files changed, 120 insertions(+), 3 deletions(-) diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp index 7b66f04d..f9f57fb6 100644 --- a/platform_mac/mac_4ed.cpp +++ b/platform_mac/mac_4ed.cpp @@ -38,8 +38,10 @@ #include "mac_objective_c_to_cpp_links.h" -#include -#include +#include // NOTE(yuval): Used for getcwd +#include // NOTE(yuval): Used for opendir, readdir + +#include // NOTE(yuval): Used for free //////////////////////////////// @@ -89,6 +91,10 @@ mac_push_string_copy(Arena *arena, String_Const_u8 src){ external void mac_init(){ + Arena test_arena = make_arena_malloc(); + system_get_file_list(&test_arena, + string_u8_litexpr("/Users/yuvaldolev/Desktop")); + // NOTE(yuval): Context Setup Thread_Context _tctx = {}; thread_ctx_init(&_tctx, ThreadKind_Main, diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index a39fe56e..ca147bb1 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -41,6 +41,27 @@ } @end +#if 0 +external File_List +mac_get_file_list(Arena* arena, String_Const_u8 directory){ + File_List result = {}; + + NSString *directory_ns_string = + [[NSString alloc] + initWithBytes:directory.data length:directory.size encoding:NSUTF8StringEncoding]; + + NSFileManager *file_manager = [NSFileManager defaultManager]; + NSDirectoryEnumerator *dirEnum = [file_manager enumeratorAtPath:directory_ns_string]; + + NSString *filename; + while ((filename = [dirEnum nextObject])){ + NSLog(filename); + } + + [directory_ns_string release]; +} +#endif + external String_Const_u8 mac_standardize_path(Arena* arena, String_Const_u8 path){ NSString *path_ns_str = diff --git a/platform_mac/mac_4ed_functions.cpp b/platform_mac/mac_4ed_functions.cpp index bb385e2e..1790e857 100644 --- a/platform_mac/mac_4ed_functions.cpp +++ b/platform_mac/mac_4ed_functions.cpp @@ -54,7 +54,97 @@ function system_get_file_list_sig(){ File_List result = {}; - NotImplemented; + u8* c_directory = push_array(arena, u8, directory.size + 1); + block_copy(c_directory, directory.str, directory.size); + c_directory[directory.size] = 0; + + DIR *dir = opendir((char*)c_directory); + if (dir){ + File_Info* first = 0; + File_Info* last = 0; + i32 count = 0; + + for (struct dirent *entry = readdir(dir); + entry; + entry = readdir(dir)){ + char *c_file_name = entry->d_name; + String_Const_u8 file_name = SCu8(c_file_name); + if (string_match(file_name, string_u8_litexpr(".")) || string_match(file_name, string_u8_litexpr(".."))){ + continue; + } + + File_Info* info = push_array(arena, File_Info, 1); + sll_queue_push(first, last, info); + count += 1; + + info->file_name = push_string_copy(arena, file_name); + //info->attributes.size = + + /*++file_count; + i32 size = 0; + for (; fname[size]; ++size); + character_count += size + 1;*/ + } + +#if 0 + i32 required_size = character_count + file_count * sizeof(File_Info); + if (file_list->block_size < required_size){ + system_memory_free(file_list->block, file_list->block_size); + file_list->block = system_memory_allocate(required_size); + file_list->block_size = required_size; + } + + file_list->infos = (File_Info*)file_list->block; + char *cursor = (char*)(file_list->infos + file_count); + + if (file_list->block != 0){ + rewinddir(d); + File_Info *info_ptr = file_list->infos; + for (struct dirent *entry = readdir(d); + entry != 0; + entry = readdir(d)){ + char *fname = entry->d_name; + if (match(fname, ".") || match(fname, "..")){ + continue; + } + char *cursor_start = cursor; + i32 length = copy_fast_unsafe_cc(cursor_start, fname); + cursor += length; + + if (entry->d_type == DT_LNK){ + struct stat st; + if (stat(entry->d_name, &st) != -1){ + info_ptr->folder = S_ISDIR(st.st_mode); + } + else{ + info_ptr->folder = false; + } + } + else{ + info_ptr->folder = (entry->d_type == DT_DIR); + } + + info_ptr->filename = cursor_start; + info_ptr->filename_len = length; + *cursor++ = 0; + ++info_ptr; + } + } + + file_list->count = file_count; + +#endif + + closedir(dir); + } + else{ + + /*system_memory_free(file_list->block, file_list->block_size); + file_list->block = 0; + file_list->block_size = 0; + file_list->infos = 0; + file_list->count = 0;*/ + } return(result); } From 3131e45c12db515b945472f826f259c6fb067f0d Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 26 Dec 2019 03:39:40 +0200 Subject: [PATCH 020/128] Errors regarding File_List which is used in mac_get_file_list (not implemented yet). --- platform_mac/mac_4ed.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index ca147bb1..badc89e2 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -2,6 +2,10 @@ #include "4coder_base_types.h" +#include "4coder_table.h" +#include "4coder_events.h" +#include "4coder_types.h" + #include "mac_objective_c_to_cpp_links.h" #undef function @@ -41,7 +45,6 @@ } @end -#if 0 external File_List mac_get_file_list(Arena* arena, String_Const_u8 directory){ File_List result = {}; @@ -60,7 +63,6 @@ mac_get_file_list(Arena* arena, String_Const_u8 directory){ [directory_ns_string release]; } -#endif external String_Const_u8 mac_standardize_path(Arena* arena, String_Const_u8 path){ From ea29a6e13ee7c4400989d778440c31f0ab2d5702 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 26 Dec 2019 17:54:06 +0200 Subject: [PATCH 021/128] Work on system_get_file_list. File attribute retrieval now works. --- platform_mac/mac_4ed.cpp | 7 +++- platform_mac/mac_4ed.mm | 6 +++- platform_mac/mac_4ed_functions.cpp | 50 +++++++++++++++++++++++++--- platform_unix/unix_4ed_functions.cpp | 2 +- 4 files changed, 58 insertions(+), 7 deletions(-) diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp index f9f57fb6..f3c188d7 100644 --- a/platform_mac/mac_4ed.cpp +++ b/platform_mac/mac_4ed.cpp @@ -38,8 +38,13 @@ #include "mac_objective_c_to_cpp_links.h" +#include +#include + #include // NOTE(yuval): Used for getcwd #include // NOTE(yuval): Used for opendir, readdir +#include // NOTE(yuval): Used for struct stat +#include // NOTE(yuval): Used for stat #include // NOTE(yuval): Used for free @@ -95,6 +100,7 @@ mac_init(){ system_get_file_list(&test_arena, string_u8_litexpr("/Users/yuvaldolev/Desktop")); +#if 0 // NOTE(yuval): Context Setup Thread_Context _tctx = {}; thread_ctx_init(&_tctx, ThreadKind_Main, @@ -117,7 +123,6 @@ mac_init(){ mac_vars.frame_arena = reserve_arena(mac_vars.tctx); target.arena = make_arena_system(KB(256)); -#if 0 mac_vars.cursor_show = MouseCursorShow_Always; mac_vars.prev_cursor_show = MouseCursorShow_Always; diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index badc89e2..0e3e9485 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -2,9 +2,11 @@ #include "4coder_base_types.h" +#if 0 #include "4coder_table.h" #include "4coder_events.h" #include "4coder_types.h" +#endif #include "mac_objective_c_to_cpp_links.h" @@ -45,6 +47,7 @@ } @end +#if 0 external File_List mac_get_file_list(Arena* arena, String_Const_u8 directory){ File_List result = {}; @@ -58,11 +61,12 @@ mac_get_file_list(Arena* arena, String_Const_u8 directory){ NSString *filename; while ((filename = [dirEnum nextObject])){ - NSLog(filename); + NSLog(@"%@", filename); } [directory_ns_string release]; } +#endif external String_Const_u8 mac_standardize_path(Arena* arena, String_Const_u8 path){ diff --git a/platform_mac/mac_4ed_functions.cpp b/platform_mac/mac_4ed_functions.cpp index 1790e857..a61bca38 100644 --- a/platform_mac/mac_4ed_functions.cpp +++ b/platform_mac/mac_4ed_functions.cpp @@ -69,6 +69,7 @@ system_get_file_list_sig(){ entry = readdir(dir)){ char *c_file_name = entry->d_name; String_Const_u8 file_name = SCu8(c_file_name); + if (string_match(file_name, string_u8_litexpr(".")) || string_match(file_name, string_u8_litexpr(".."))){ continue; } @@ -78,12 +79,53 @@ system_get_file_list_sig(){ count += 1; info->file_name = push_string_copy(arena, file_name); - //info->attributes.size = + + // NOTE(yuval): Get file attributes + { + Temp_Memory temp = begin_temp(arena); + + b32 append_slash = false; + u64 file_path_size = directory.size + file_name.size; + if (string_get_character(directory, directory.size - 1) != '/') { + append_slash = true; + file_path_size += 1; + } + + char* file_path = push_array(arena, char, file_path_size + 1); + char* file_path_at = file_path; + + block_copy(file_path_at, directory.str, directory.size); + file_path_at += directory.size; + + if (append_slash) { + *file_path_at = '/'; + file_path_at += 1; + } + + block_copy(file_path_at, file_name.str, file_name.size); + file_path_at += file_name.size; + + *file_path_at = 0; + + printf("File Path: %s ", file_path); + + struct stat file_stat; + if (stat(file_path, &file_stat) == 0){ + info->attributes.size = file_stat.st_size; + info->attributes.last_write_time = ; + info->attributes.flags = ; + } else { + char* error_message = strerror(errno); + printf("ERROR: stat failed with error message '%s'!\n", error_message); + } + + end_temp(temp); + } /*++file_count; - i32 size = 0; - for (; fname[size]; ++size); - character_count += size + 1;*/ +i32 size = 0; +for (; fname[size]; ++size); +character_count += size + 1;*/ } #if 0 diff --git a/platform_unix/unix_4ed_functions.cpp b/platform_unix/unix_4ed_functions.cpp index 75e121fb..d6fe65b7 100644 --- a/platform_unix/unix_4ed_functions.cpp +++ b/platform_unix/unix_4ed_functions.cpp @@ -64,7 +64,7 @@ Sys_Memory_Allocate_Sig(system_memory_allocate){ return(result); } -internal +internal Sys_Memory_Set_Protection_Sig(system_memory_set_protection){ bool32 result = true; From 9c3a2d95503479aa8a6d8ea63cfe2e73a578f4ee Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 26 Dec 2019 21:30:13 +0200 Subject: [PATCH 022/128] Finished implmenting system_get_file_list. --- platform_mac/mac_4ed.cpp | 17 ++++-- platform_mac/mac_4ed_functions.cpp | 89 +++++++----------------------- 2 files changed, 31 insertions(+), 75 deletions(-) diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp index f3c188d7..7a3acc4e 100644 --- a/platform_mac/mac_4ed.cpp +++ b/platform_mac/mac_4ed.cpp @@ -38,9 +38,6 @@ #include "mac_objective_c_to_cpp_links.h" -#include -#include - #include // NOTE(yuval): Used for getcwd #include // NOTE(yuval): Used for opendir, readdir #include // NOTE(yuval): Used for struct stat @@ -97,8 +94,18 @@ mac_push_string_copy(Arena *arena, String_Const_u8 src){ external void mac_init(){ Arena test_arena = make_arena_malloc(); - system_get_file_list(&test_arena, - string_u8_litexpr("/Users/yuvaldolev/Desktop")); + File_List list = system_get_file_list(&test_arena, + string_u8_litexpr("/Users/yuvaldolev/Desktop")); + + for (u32 index = 0; index < list.count; ++index) { + File_Info* info = list.infos[index]; + + printf("File_Info{file_name:'%.*s', " + "attributes:{size:%llu, last_write_time:%llu, flags:{IsDirectory:%d}}}\n", + (i32)info->file_name.size, info->file_name.str, + info->attributes.size, info->attributes.last_write_time, + ((info->attributes.flags & FileAttribute_IsDirectory) != 0)); + } #if 0 // NOTE(yuval): Context Setup diff --git a/platform_mac/mac_4ed_functions.cpp b/platform_mac/mac_4ed_functions.cpp index a61bca38..3047ba18 100644 --- a/platform_mac/mac_4ed_functions.cpp +++ b/platform_mac/mac_4ed_functions.cpp @@ -86,7 +86,7 @@ system_get_file_list_sig(){ b32 append_slash = false; u64 file_path_size = directory.size + file_name.size; - if (string_get_character(directory, directory.size - 1) != '/') { + if (string_get_character(directory, directory.size - 1) != '/'){ append_slash = true; file_path_size += 1; } @@ -97,7 +97,7 @@ system_get_file_list_sig(){ block_copy(file_path_at, directory.str, directory.size); file_path_at += directory.size; - if (append_slash) { + if (append_slash){ *file_path_at = '/'; file_path_at += 1; } @@ -107,85 +107,34 @@ system_get_file_list_sig(){ *file_path_at = 0; - printf("File Path: %s ", file_path); - struct stat file_stat; if (stat(file_path, &file_stat) == 0){ info->attributes.size = file_stat.st_size; - info->attributes.last_write_time = ; - info->attributes.flags = ; - } else { - char* error_message = strerror(errno); - printf("ERROR: stat failed with error message '%s'!\n", error_message); + info->attributes.last_write_time = file_stat.st_mtimespec.tv_sec; + info->attributes.flags = 0; + + if (S_ISDIR(file_stat.st_mode)) { + info->attributes.flags |= FileAttribute_IsDirectory; + } + } end_temp(temp); } - - /*++file_count; -i32 size = 0; -for (; fname[size]; ++size); -character_count += size + 1;*/ } -#if 0 - i32 required_size = character_count + file_count * sizeof(File_Info); - if (file_list->block_size < required_size){ - system_memory_free(file_list->block, file_list->block_size); - file_list->block = system_memory_allocate(required_size); - file_list->block_size = required_size; - } - - file_list->infos = (File_Info*)file_list->block; - char *cursor = (char*)(file_list->infos + file_count); - - if (file_list->block != 0){ - rewinddir(d); - File_Info *info_ptr = file_list->infos; - for (struct dirent *entry = readdir(d); - entry != 0; - entry = readdir(d)){ - char *fname = entry->d_name; - if (match(fname, ".") || match(fname, "..")){ - continue; - } - char *cursor_start = cursor; - i32 length = copy_fast_unsafe_cc(cursor_start, fname); - cursor += length; - - if (entry->d_type == DT_LNK){ - struct stat st; - if (stat(entry->d_name, &st) != -1){ - info_ptr->folder = S_ISDIR(st.st_mode); - } - else{ - info_ptr->folder = false; - } - } - else{ - info_ptr->folder = (entry->d_type == DT_DIR); - } - - info_ptr->filename = cursor_start; - info_ptr->filename_len = length; - *cursor++ = 0; - ++info_ptr; - } - } - - file_list->count = file_count; - -#endif - closedir(dir); - } - else{ - /*system_memory_free(file_list->block, file_list->block_size); - file_list->block = 0; - file_list->block_size = 0; - file_list->infos = 0; - file_list->count = 0;*/ + result.infos = push_array(arena, File_Info*, count); + result.count = count; + + i32 index = 0; + for (File_Info* node = first; + node != 0; + node = node->next){ + result.infos[index] = node; + index += 1; + } } return(result); From 074400495f2fc73c1df68e4d32b656eb75c11628 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Fri, 27 Dec 2019 00:16:15 +0200 Subject: [PATCH 023/128] Implemented all system file handling functions. --- platform_mac/mac_4ed.cpp | 6 +- platform_mac/mac_4ed_functions.cpp | 120 ++++++++++++++++---- platform_mac/mac_objective_c_to_cpp_links.h | 6 +- 3 files changed, 105 insertions(+), 27 deletions(-) diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp index 7a3acc4e..000d4336 100644 --- a/platform_mac/mac_4ed.cpp +++ b/platform_mac/mac_4ed.cpp @@ -38,10 +38,12 @@ #include "mac_objective_c_to_cpp_links.h" -#include // NOTE(yuval): Used for getcwd #include // NOTE(yuval): Used for opendir, readdir -#include // NOTE(yuval): Used for struct stat +#include // NOTE(yuval): Used for errno +#include // NOTE(yuval): Used for open +#include // NOTE(yuval): Used for getcwd, read, write #include // NOTE(yuval): Used for stat +#include // NOTE(yuval): Used for struct stat #include // NOTE(yuval): Used for free diff --git a/platform_mac/mac_4ed_functions.cpp b/platform_mac/mac_4ed_functions.cpp index 3047ba18..e0b3d198 100644 --- a/platform_mac/mac_4ed_functions.cpp +++ b/platform_mac/mac_4ed_functions.cpp @@ -50,6 +50,44 @@ system_get_canonical_sig(){ return(result); } +function File_Attributes +mac_get_file_attributes(struct stat file_stat) { + File_Attributes result; + result.size = file_stat.st_size; + result.last_write_time = file_stat.st_mtimespec.tv_sec; + + result.flags = 0; + if (S_ISDIR(file_stat.st_mode)) { + result.flags |= FileAttribute_IsDirectory; + } + + return(result); +} + +function inline File_Attributes +mac_file_attributes_from_path(char* path) { + File_Attributes result = {}; + + struct stat file_stat; + if (stat(path, &file_stat) == 0){ + result = mac_get_file_attributes(file_stat); + } + + return(result); +} + +function inline File_Attributes +mac_file_attributes_from_fd(i32 fd) { + File_Attributes result = {}; + + struct stat file_stat; + if (fstat(fd, &file_stat) == 0){ + result = mac_get_file_attributes(file_stat); + } + + return(result); +} + function system_get_file_list_sig(){ File_List result = {}; @@ -107,17 +145,7 @@ system_get_file_list_sig(){ *file_path_at = 0; - struct stat file_stat; - if (stat(file_path, &file_stat) == 0){ - info->attributes.size = file_stat.st_size; - info->attributes.last_write_time = file_stat.st_mtimespec.tv_sec; - info->attributes.flags = 0; - - if (S_ISDIR(file_stat.st_mode)) { - info->attributes.flags |= FileAttribute_IsDirectory; - } - - } + info->attributes = mac_file_attributes_from_path(file_path); end_temp(temp); } @@ -142,9 +170,15 @@ system_get_file_list_sig(){ function system_quick_file_attributes_sig(){ - File_Attributes result = {}; + Temp_Memory temp = begin_temp(scratch); - NotImplemented; + char* c_file_name = push_array(scratch, char, file_name.size + 1); + block_copy(c_file_name, file_name.str, file_name.size); + c_file_name[file_name.size] = 0; + + File_Attributes result = mac_file_attributes_from_path(c_file_name); + + end_temp(temp); return(result); } @@ -153,34 +187,53 @@ function system_load_handle_sig(){ b32 result = false; - NotImplemented; + i32 fd = open(file_name, O_RDONLY); + if ((fd != -1) && (fd != 0)) { + *(i32*)out = fd; + result = true; + } return(result); } function system_load_attributes_sig(){ - File_Attributes result = {}; - - NotImplemented; + i32 fd = *(i32*)(&handle); + File_Attributes result = mac_file_attributes_from_fd(fd); return(result); } function system_load_file_sig(){ - b32 result = false; + i32 fd = *(i32*)(&handle); - NotImplemented; + do{ + ssize_t bytes_read = read(fd, buffer, size); + if (bytes_read == -1){ + if (errno != EINTR){ + // NOTE(yuval): An error occured while reading from the file descriptor + break; + } + } else{ + size -= bytes_read; + buffer += bytes_read; + } + } while (size > 0); + b32 result = (size == 0); return(result); } function system_load_close_sig(){ - b32 result = false; + b32 result = true; - NotImplemented; + i32 fd = *(i32*)(&handle); + if (close(fd) == -1){ + // NOTE(yuval): An error occured while close the file descriptor + result = false; + } return(result); } @@ -189,7 +242,30 @@ function system_save_file_sig(){ File_Attributes result = {}; - NotImplemented; + i32 fd = open(file_name, O_WRONLY | O_TRUNC | O_CREAT, 00640); + if (fd != -1) { + u8* data_str = data.str; + u64 data_size = data.size; + + do{ + ssize_t bytes_written = write(fd, data.str, data.size); + if (bytes_written == -1){ + if (errno != EINTR){ + // NOTE(yuval): An error occured while writing to the file descriptor + break; + } + } else{ + data.size -= bytes_written; + data.str += bytes_written; + } + } while (data.size > 0); + + if (data.size == 0) { + result = mac_file_attributes_from_fd(fd); + } + + close(fd); + } return(result); } diff --git a/platform_mac/mac_objective_c_to_cpp_links.h b/platform_mac/mac_objective_c_to_cpp_links.h index c5f4db62..ab043fc1 100644 --- a/platform_mac/mac_objective_c_to_cpp_links.h +++ b/platform_mac/mac_objective_c_to_cpp_links.h @@ -14,11 +14,11 @@ external void mac_init(); // In Objective-C layer -external i32 -mac_get_binary_path(void* buffer, u32 size); - external String_Const_u8 mac_standardize_path(Arena* arena, String_Const_u8 path); +external i32 +mac_get_binary_path(void* buffer, u32 size); + #endif From 0a5f6d51f651a0914872b1dac7791c9591b420e2 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 26 Dec 2019 17:12:13 -0800 Subject: [PATCH 024/128] removing dead min/max macros --- custom/4coder_base_types.h | 2 - custom/generated/command_metadata.h | 458 +++++++++--------- .../Resources/DWARF/metadata_generator | Bin 136740 -> 138399 bytes 3 files changed, 229 insertions(+), 231 deletions(-) diff --git a/custom/4coder_base_types.h b/custom/4coder_base_types.h index 358485d9..20517f7f 100644 --- a/custom/4coder_base_types.h +++ b/custom/4coder_base_types.h @@ -291,8 +291,6 @@ enum{ #define Max(a,b) (((a)>(b))?(a):(b)) #define Min(a,b) (((a)<(b))?(a):(b)) -#define max(a,b) (((a)>(b))?(a):(b)) -#define min(a,b) (((a)<(b))?(a):(b)) #define clamp_top(a,b) Min(a,b) #define clamp_bot(a,b) Max(a,b) #define clamp_(a,x,b) ((a>x)?a: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 HK1Tl^sgkr2 literal 136740 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 Date: Thu, 26 Dec 2019 19:47:12 -0800 Subject: [PATCH 025/128] Get 4coder_types.h to work with a dumb hack for now --- platform_mac/mac_4ed.cpp | 4 ++-- platform_mac/mac_4ed.mm | 7 ++++++- 2 files changed, 8 insertions(+), 3 deletions(-) diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp index 000d4336..b2636154 100644 --- a/platform_mac/mac_4ed.cpp +++ b/platform_mac/mac_4ed.cpp @@ -49,8 +49,8 @@ //////////////////////////////// -#define SLASH '\\' -#define DLL "dll" +#define SLASH '/' +#define DLL "so" #include "4coder_hash_functions.cpp" #include "4coder_system_allocator.cpp" diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 0e3e9485..c2519d04 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -2,10 +2,15 @@ #include "4coder_base_types.h" -#if 0 +#if 1 #include "4coder_table.h" #include "4coder_events.h" +// NOTE(allen): This is a very unfortunate hack, but hopefully there will never be a need to use the Marker +// type in the platform layer. If that changes then instead change the name of Marker and make a transition +// macro that is only included in custom code. +#define Marker Marker__SAVE_THIS_IDENTIFIER #include "4coder_types.h" +#undef Marker #endif #include "mac_objective_c_to_cpp_links.h" From 15c71887212b2bc4606b72b0a061a10aafb0ccc7 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 26 Dec 2019 20:14:13 -0800 Subject: [PATCH 026/128] Permanently get off of min/max, extend setup_cl with 2019 default paths --- custom/4coder_base_types.h | 2 -- custom/4coder_types.h | 1 + custom/bin/setup_cl_generic.bat | 7 +++++++ 3 files changed, 8 insertions(+), 2 deletions(-) diff --git a/custom/4coder_base_types.h b/custom/4coder_base_types.h index 3ca3f926..5d309777 100644 --- a/custom/4coder_base_types.h +++ b/custom/4coder_base_types.h @@ -268,8 +268,6 @@ enum{ #define Max(a,b) (((a)>(b))?(a):(b)) #define Min(a,b) (((a)<(b))?(a):(b)) -#define max(a,b) (((a)>(b))?(a):(b)) -#define min(a,b) (((a)<(b))?(a):(b)) #define clamp_top(a,b) Min(a,b) #define clamp_bot(a,b) Max(a,b) #define clamp_(a,x,b) ((a>x)?a:((b Date: Thu, 26 Dec 2019 21:20:19 -0800 Subject: [PATCH 027/128] Finished API extension for padded layout rectangles giving more reliable xy navigation commands --- 4ed_api_implementation.cpp | 28 ++++ 4ed_buffer.cpp | 47 ------ 4ed_file.cpp | 15 ++ 4ed_view.cpp | 11 ++ custom/4coder_base_commands.cpp | 22 ++- custom/4coder_layout.cpp | 20 ++- custom/4coder_layout_rule.cpp | 13 +- custom/generated/command_metadata.h | 152 ++++++++++---------- custom/generated/custom_api.cpp | 4 + custom/generated/custom_api.h | 10 ++ custom/generated/custom_api_constructor.cpp | 18 ++- custom/generated/custom_api_master_list.h | 2 + 12 files changed, 196 insertions(+), 146 deletions(-) diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 933262b4..5c5d31b6 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -521,6 +521,23 @@ buffer_relative_box_of_pos(Application_Links *app, Buffer_ID buffer_id, f32 widt return(result); } +api(custom) function Rect_f32 +buffer_padded_box_of_pos(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos){ + Models *models = (Models*)app->cmd_context; + Editing_File *file = imp_get_file(models, buffer_id); + Rect_f32 result = {}; + if (api_check_buffer(file)){ + Face *face = font_set_face_from_id(&models->font_set, face_id); + if (face != 0){ + Layout_Function *layout_func = file_get_layout_func(file); + result = file_padded_box_of_pos(app->tctx, models, file, + layout_func, width, face, + base_line, pos); + } + } + return(result); +} + api(custom) function i64 buffer_relative_character_from_pos(Application_Links *app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos) @@ -603,6 +620,17 @@ view_relative_box_of_pos(Application_Links *app, View_ID view_id, i64 base_line, return(result); } +api(custom) function Rect_f32 +view_padded_box_of_pos(Application_Links *app, View_ID view_id, i64 base_line, i64 pos){ + Models *models = (Models*)app->cmd_context; + View *view = imp_get_view(models, view_id); + Rect_f32 result = {}; + if (api_check_view(view)){ + result = view_padded_box_of_pos(app->tctx, models, view, base_line, pos); + } + return(result); +} + api(custom) function i64 view_relative_character_from_pos(Application_Links *app, View_ID view_id, i64 base_line, i64 pos){ Models *models = (Models*)app->cmd_context; diff --git a/4ed_buffer.cpp b/4ed_buffer.cpp index c625e6f0..842d7220 100644 --- a/4ed_buffer.cpp +++ b/4ed_buffer.cpp @@ -646,53 +646,6 @@ buffer_remeasure_starts(Thread_Context *tctx, Gap_Buffer *buffer, Batch_Edit *ba } } -#if 0 -internal void -buffer_remeasure_starts(Arena *scratch, Gap_Buffer *buffer, - Range_i64 old_line_indexes, i64 line_shift, i64 text_shift){ - Temp_Memory temp = begin_temp(scratch); - buffer_starts__ensure_max_size(buffer, buffer->line_start_count + line_shift); - - i64 new_line_indexes_opl = old_line_indexes.one_past_last + line_shift; - i64 old_line_start_count = buffer->line_start_count; - i64 *line_start_ptr = buffer->line_starts + old_line_indexes.one_past_last; - for (i64 i = old_line_indexes.one_past_last; - i < old_line_start_count; - i += 1, line_start_ptr += 1){ - *line_start_ptr += text_shift; - } - block_copy_dynamic_array(buffer->line_starts + new_line_indexes_opl, - buffer->line_starts + old_line_indexes.one_past_last, - buffer->line_start_count - old_line_indexes.one_past_last); - - i64 first_pos = buffer->line_starts[old_line_indexes.first]; - i64 write_counter = old_line_indexes.first + 1; - i64 pos = first_pos; - List_String_Const_u8 list = buffer_get_chunks(scratch, buffer); - buffer_chunks_clamp(&list, Ii64(first_pos, buffer_size(buffer))); - for (Node_String_Const_u8 *node = list.first; - node != 0; - node = node->next){ - u8 *byte = node->string.str; - u8 *byte_opl = byte + node->string.size; - for (;byte < byte_opl; byte += 1){ - pos += 1; - if (*byte == '\n'){ - buffer->line_starts[write_counter] = pos; - write_counter += 1; - if (write_counter == new_line_indexes_opl){ - goto double_break; - } - } - } - } - double_break:; - - buffer->line_start_count += line_shift; - end_temp(temp); -} -#endif - internal Range_i64 buffer_get_pos_range_from_line_number(Gap_Buffer *buffer, i64 line_number){ Range_i64 result = {}; diff --git a/4ed_file.cpp b/4ed_file.cpp index a201fe9b..c3c18d64 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -440,6 +440,21 @@ file_relative_xy_of_pos(Thread_Context *tctx, Models *models, Editing_File *file return(rect_center(rect)); } +function Rect_f32 +file_padded_box_of_pos(Thread_Context *tctx, Models *models, Editing_File *file, + Layout_Function *layout_func, f32 width, Face *face, + i64 base_line, i64 pos){ + i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1; + Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, line_number); + Rect_f32 result = layout_padded_box_of_pos(line, pos); + + f32 y_difference = file_line_y_difference(tctx, models, file, layout_func, width, face, line_number, base_line); + result.y0 += y_difference; + result.y1 += y_difference; + + return(result); +} + internal Buffer_Point file_normalize_buffer_point(Thread_Context *tctx, Models *models, Editing_File *file, Layout_Function *layout_func, f32 width, Face *face, diff --git a/4ed_view.cpp b/4ed_view.cpp index dd7a25a2..1d5a2e0b 100644 --- a/4ed_view.cpp +++ b/4ed_view.cpp @@ -234,6 +234,17 @@ view_relative_xy_of_pos(Thread_Context *tctx, Models *models, View *view, return(rect_center(rect)); } +function Rect_f32 +view_padded_box_of_pos(Thread_Context *tctx, Models *models, View *view, + i64 base_line, i64 pos){ + Editing_File *file = view->file; + Face *face = file_get_face(models, file); + f32 width = view_width(tctx, models, view); + Layout_Function *layout_func = file_get_layout_func(file); + return(file_padded_box_of_pos(tctx, models, file, + layout_func, width, face, base_line, pos)); +} + internal Buffer_Point view_normalize_buffer_point(Thread_Context *tctx, Models *models, View *view, Buffer_Point point){ diff --git a/custom/4coder_base_commands.cpp b/custom/4coder_base_commands.cpp index 0cb42ebc..b04bb7c6 100644 --- a/custom/4coder_base_commands.cpp +++ b/custom/4coder_base_commands.cpp @@ -281,9 +281,15 @@ move_vertical_pixels(Application_Links *app, View_ID view, f32 pixels){ ProfileScope(app, "move vertical pixels"); i64 pos = view_get_cursor_pos(app, view); Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos)); - Vec2_f32 p = view_relative_xy_of_pos(app, view, cursor.line, pos); + Rect_f32 r = view_padded_box_of_pos(app, view, cursor.line, pos); + Vec2_f32 p = {}; p.x = view_get_preferred_x(app, view); - p.y += pixels; + if (pixels > 0.f){ + p.y = r.y1 + pixels; + } + else{ + p.y = r.y0 + pixels; + } i64 new_pos = view_pos_at_relative_xy(app, view, cursor.line, p); view_set_cursor(app, view, seek_pos(new_pos)); no_mark_snap_to_cursor_if_shift(app, view); @@ -299,20 +305,12 @@ internal void move_vertical_lines(Application_Links *app, View_ID view, i64 lines){ if (lines > 0){ for (i64 i = 0; i < lines; i += 1){ - i64 pos = view_get_cursor_pos(app, view); - Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos)); - Rect_f32 box = view_relative_box_of_pos(app, view, cursor.line, cursor.pos); - f32 half_height = rect_height(box)*0.5f; - move_vertical_pixels(app, half_height + 2.f); + move_vertical_pixels(app, 1.f); } } else{ for (i64 i = 0; i > lines; i -= 1){ - i64 pos = view_get_cursor_pos(app, view); - Buffer_Cursor cursor = view_compute_cursor(app, view, seek_pos(pos)); - Rect_f32 box = view_relative_box_of_pos(app, view, cursor.line, cursor.pos); - f32 half_height = rect_height(box)*0.5f; - move_vertical_pixels(app, -half_height - 2.f); + move_vertical_pixels(app, -1.f); } } } diff --git a/custom/4coder_layout.cpp b/custom/4coder_layout.cpp index c36c1be0..72c9d5e3 100644 --- a/custom/4coder_layout.cpp +++ b/custom/4coder_layout.cpp @@ -15,7 +15,6 @@ layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){ } else{ if (0.f < p.x && p.x < max_f32){ - f32 bottom_padding = list.bottom_padding; f32 closest_x = -max_f32; for (Layout_Item_Block *block = list.first; block != 0; @@ -30,7 +29,7 @@ layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){ if (p.y < item->rect.y0){ goto double_break; } - if (item->rect.y1 + bottom_padding <= p.y){ + if (item->padded_y1 <= p.y){ continue; } f32 dist0 = p.x - item->rect.x0; @@ -68,7 +67,7 @@ layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){ goto double_break_2; } prev_item = item; - if (item->rect.y1 <= p.y){ + if (item->padded_y1 <= p.y){ continue; } } @@ -97,7 +96,7 @@ layout_nearest_pos_to_xy(Layout_Item_List list, Vec2_f32 p){ if (p.y < item->rect.y0){ goto double_break_3; } - if (item->rect.y1 <= p.y){ + if (item->padded_y1 <= p.y){ continue; } closest_item = item; @@ -160,6 +159,19 @@ layout_box_of_pos(Layout_Item_List list, i64 index){ return(result); } +function Rect_f32 +layout_padded_box_of_pos(Layout_Item_List list, i64 index){ + Rect_f32 result = {}; + Layout_Item *item = layout_get_first_with_index(list, index); + if (item != 0){ + result.x0 = item->rect.x0; + result.y0 = item->rect.y0; + result.x1 = item->rect.x1; + result.y1 = item->padded_y1; + } + return(result); +} + internal i64 layout_get_pos_at_character(Layout_Item_List list, i64 character){ i64 result = 0; diff --git a/custom/4coder_layout_rule.cpp b/custom/4coder_layout_rule.cpp index 56056c93..ce9e5aec 100644 --- a/custom/4coder_layout_rule.cpp +++ b/custom/4coder_layout_rule.cpp @@ -56,7 +56,7 @@ layout_item_list_finish(Layout_Item_List *list, f32 bottom_padding){ } function void -layout_write(Arena *arena, Layout_Item_List *list, Face_ID face, i64 index, u32 codepoint, Layout_Item_Flag flags, Rect_f32 rect){ +layout_write(Arena *arena, Layout_Item_List *list, Face_ID face, i64 index, u32 codepoint, Layout_Item_Flag flags, Rect_f32 rect, f32 padded_y1){ Temp_Memory restore_point = begin_temp(arena); Layout_Item *item = push_array(arena, Layout_Item, 1); Layout_Item_Block *block = list->last; @@ -95,6 +95,7 @@ layout_write(Arena *arena, Layout_Item_List *list, Face_ID face, i64 index, u32 item->codepoint = codepoint; item->flags = flags; item->rect = rect; + item->padded_y1 = padded_y1; list->height = Max(list->height, rect.y1); } @@ -179,7 +180,7 @@ lr_tb_write_with_advance_with_flags(LefRig_TopBot_Layout_Vars *vars, Face_ID fac } vars->p.x = f32_ceil32(vars->p.x); f32 next_x = vars->p.x + advance; - layout_write(arena, list, face, index, codepoint, flags, Rf32(vars->p, V2f32(next_x, vars->text_y))); + layout_write(arena, list, face, index, codepoint, flags, Rf32(vars->p, V2f32(next_x, vars->text_y)), vars->line_y); vars->p.x = next_x; } @@ -219,15 +220,15 @@ lr_tb_write_byte_with_advance(LefRig_TopBot_Layout_Vars *vars, Face_ID face, f32 f32 text_y = vars->text_y; Layout_Item_Flag flags = LayoutItemFlag_Special_Character; - layout_write(arena, list, face, index, '\\', flags, Rf32(p, V2f32(next_x, text_y))); + layout_write(arena, list, face, index, '\\', flags, Rf32(p, V2f32(next_x, text_y)), vars->line_y); p.x = next_x; flags = LayoutItemFlag_Ghost_Character; next_x += metrics->byte_sub_advances[1]; - layout_write(arena, list, face, index, integer_symbols[hi], flags, Rf32(p, V2f32(next_x, text_y))); + layout_write(arena, list, face, index, integer_symbols[hi], flags, Rf32(p, V2f32(next_x, text_y)), vars->line_y); p.x = next_x; next_x += metrics->byte_sub_advances[2]; - layout_write(arena, list, face, index, integer_symbols[lo], flags, Rf32(p, V2f32(next_x, text_y))); + layout_write(arena, list, face, index, integer_symbols[lo], flags, Rf32(p, V2f32(next_x, text_y)), vars->line_y); vars->p.x = final_next_x; } @@ -242,7 +243,7 @@ lr_tb_write_byte(LefRig_TopBot_Layout_Vars *vars, Face_ID face, function void lr_tb_write_blank_dim(LefRig_TopBot_Layout_Vars *vars, Face_ID face, Vec2_f32 dim, Arena *arena, Layout_Item_List *list, i64 index){ - layout_write(arena, list, face, index, ' ', 0, Rf32_xy_wh(vars->p, dim)); + layout_write(arena, list, face, index, ' ', 0, Rf32_xy_wh(vars->p, dim), vars->line_y); vars->p.x += dim.x; } diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index b45e901f..f9491504 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -257,14 +257,14 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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(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, 611 }, { 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(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, 576 }, { 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 }, @@ -272,7 +272,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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(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, 619 }, { 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 }, @@ -281,39 +281,39 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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(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, 682 }, +{ 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, 1796 }, { 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_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, 1219 }, +{ 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, 1394 }, { 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(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, 1380 }, { 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(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 738 }, { 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_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, 746 }, { 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(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, 649 }, +{ 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, 635 }, { 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(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, 671 }, { 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 }, @@ -323,7 +323,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 54 }, { 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, 77 }, { 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, 41 }, -{ 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_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1540 }, { 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, 296 }, @@ -343,52 +343,52 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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(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, 1334 }, { 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_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, 693 }, { 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(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 336 }, +{ 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, 348 }, +{ 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, 354 }, +{ 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, 407 }, +{ 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, 431 }, +{ 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, 419 }, +{ 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, 437 }, +{ 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, 514 }, +{ 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, 528 }, +{ 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, 486 }, +{ 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, 471 }, +{ 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, 500 }, +{ 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, 1374 }, +{ 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, 1368 }, +{ 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, 445 }, +{ 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, 507 }, +{ 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, 521 }, +{ 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, 479 }, +{ 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, 463 }, +{ 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, 493 }, +{ 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, 330 }, +{ 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, 342 }, +{ 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, 401 }, +{ 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, 425 }, +{ 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, 413 }, { 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_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, 1459 }, +{ 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, 1790 }, { 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_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, 1491 }, { 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(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, 372 }, +{ 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, 364 }, { 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 }, @@ -401,28 +401,28 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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(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, 1147 }, +{ 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, 1168 }, +{ 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, 1184 }, +{ 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, 1629 }, +{ 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, 1714 }, +{ 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, 1296 }, +{ 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, 1558 }, +{ 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, 1057 }, +{ 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, 1048 }, +{ 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, 1039 }, +{ 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, 980 }, +{ 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, 992 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1548 }, { 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(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, 1263 }, +{ 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, 974 }, +{ 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, 986 }, { 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_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, 537 }, { 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 }, @@ -440,34 +440,34 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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_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, 642 }, +{ 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, 628 }, { 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(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, 1516 }, { 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(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, 563 }, +{ 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, 550 }, +{ 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, 656 }, +{ 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, 665 }, { 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_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 719 }, +{ 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, 725 }, { 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_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, 710 }, { 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(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, 1616 }, +{ 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, 1643 }, +{ 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, 1504 }, { 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 }, diff --git a/custom/generated/custom_api.cpp b/custom/generated/custom_api.cpp index 0a839ac5..3ab062df 100644 --- a/custom/generated/custom_api.cpp +++ b/custom/generated/custom_api.cpp @@ -25,12 +25,14 @@ vtable->buffer_line_y_difference = buffer_line_y_difference; vtable->buffer_line_shift_y = buffer_line_shift_y; vtable->buffer_pos_at_relative_xy = buffer_pos_at_relative_xy; vtable->buffer_relative_box_of_pos = buffer_relative_box_of_pos; +vtable->buffer_padded_box_of_pos = buffer_padded_box_of_pos; vtable->buffer_relative_character_from_pos = buffer_relative_character_from_pos; vtable->buffer_pos_from_relative_character = buffer_pos_from_relative_character; vtable->view_line_y_difference = view_line_y_difference; vtable->view_line_shift_y = view_line_shift_y; vtable->view_pos_at_relative_xy = view_pos_at_relative_xy; vtable->view_relative_box_of_pos = view_relative_box_of_pos; +vtable->view_padded_box_of_pos = view_padded_box_of_pos; vtable->view_relative_character_from_pos = view_relative_character_from_pos; vtable->view_pos_from_relative_character = view_pos_from_relative_character; vtable->buffer_exists = buffer_exists; @@ -203,12 +205,14 @@ buffer_line_y_difference = vtable->buffer_line_y_difference; buffer_line_shift_y = vtable->buffer_line_shift_y; buffer_pos_at_relative_xy = vtable->buffer_pos_at_relative_xy; buffer_relative_box_of_pos = vtable->buffer_relative_box_of_pos; +buffer_padded_box_of_pos = vtable->buffer_padded_box_of_pos; buffer_relative_character_from_pos = vtable->buffer_relative_character_from_pos; buffer_pos_from_relative_character = vtable->buffer_pos_from_relative_character; view_line_y_difference = vtable->view_line_y_difference; view_line_shift_y = vtable->view_line_shift_y; view_pos_at_relative_xy = vtable->view_pos_at_relative_xy; view_relative_box_of_pos = vtable->view_relative_box_of_pos; +view_padded_box_of_pos = vtable->view_padded_box_of_pos; view_relative_character_from_pos = vtable->view_relative_character_from_pos; view_pos_from_relative_character = vtable->view_pos_from_relative_character; buffer_exists = vtable->buffer_exists; diff --git a/custom/generated/custom_api.h b/custom/generated/custom_api.h index 27bb15db..5b3bb02f 100644 --- a/custom/generated/custom_api.h +++ b/custom/generated/custom_api.h @@ -23,12 +23,14 @@ #define custom_buffer_line_shift_y_sig() Line_Shift_Vertical custom_buffer_line_shift_y(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 line, f32 y_shift) #define custom_buffer_pos_at_relative_xy_sig() i64 custom_buffer_pos_at_relative_xy(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, Vec2_f32 relative_xy) #define custom_buffer_relative_box_of_pos_sig() Rect_f32 custom_buffer_relative_box_of_pos(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos) +#define custom_buffer_padded_box_of_pos_sig() Rect_f32 custom_buffer_padded_box_of_pos(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos) #define custom_buffer_relative_character_from_pos_sig() i64 custom_buffer_relative_character_from_pos(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos) #define custom_buffer_pos_from_relative_character_sig() i64 custom_buffer_pos_from_relative_character(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 relative_character) #define custom_view_line_y_difference_sig() f32 custom_view_line_y_difference(Application_Links* app, View_ID view_id, i64 line_a, i64 line_b) #define custom_view_line_shift_y_sig() Line_Shift_Vertical custom_view_line_shift_y(Application_Links* app, View_ID view_id, i64 line, f32 y_shift) #define custom_view_pos_at_relative_xy_sig() i64 custom_view_pos_at_relative_xy(Application_Links* app, View_ID view_id, i64 base_line, Vec2_f32 relative_xy) #define custom_view_relative_box_of_pos_sig() Rect_f32 custom_view_relative_box_of_pos(Application_Links* app, View_ID view_id, i64 base_line, i64 pos) +#define custom_view_padded_box_of_pos_sig() Rect_f32 custom_view_padded_box_of_pos(Application_Links* app, View_ID view_id, i64 base_line, i64 pos) #define custom_view_relative_character_from_pos_sig() i64 custom_view_relative_character_from_pos(Application_Links* app, View_ID view_id, i64 base_line, i64 pos) #define custom_view_pos_from_relative_character_sig() i64 custom_view_pos_from_relative_character(Application_Links* app, View_ID view_id, i64 base_line, i64 character) #define custom_buffer_exists_sig() b32 custom_buffer_exists(Application_Links* app, Buffer_ID buffer_id) @@ -197,12 +199,14 @@ typedef f32 custom_buffer_line_y_difference_type(Application_Links* app, Buffer_ typedef Line_Shift_Vertical custom_buffer_line_shift_y_type(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 line, f32 y_shift); typedef i64 custom_buffer_pos_at_relative_xy_type(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, Vec2_f32 relative_xy); typedef Rect_f32 custom_buffer_relative_box_of_pos_type(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos); +typedef Rect_f32 custom_buffer_padded_box_of_pos_type(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos); typedef i64 custom_buffer_relative_character_from_pos_type(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos); typedef i64 custom_buffer_pos_from_relative_character_type(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 relative_character); typedef f32 custom_view_line_y_difference_type(Application_Links* app, View_ID view_id, i64 line_a, i64 line_b); typedef Line_Shift_Vertical custom_view_line_shift_y_type(Application_Links* app, View_ID view_id, i64 line, f32 y_shift); typedef i64 custom_view_pos_at_relative_xy_type(Application_Links* app, View_ID view_id, i64 base_line, Vec2_f32 relative_xy); typedef Rect_f32 custom_view_relative_box_of_pos_type(Application_Links* app, View_ID view_id, i64 base_line, i64 pos); +typedef Rect_f32 custom_view_padded_box_of_pos_type(Application_Links* app, View_ID view_id, i64 base_line, i64 pos); typedef i64 custom_view_relative_character_from_pos_type(Application_Links* app, View_ID view_id, i64 base_line, i64 pos); typedef i64 custom_view_pos_from_relative_character_type(Application_Links* app, View_ID view_id, i64 base_line, i64 character); typedef b32 custom_buffer_exists_type(Application_Links* app, Buffer_ID buffer_id); @@ -372,12 +376,14 @@ custom_buffer_line_y_difference_type *buffer_line_y_difference; custom_buffer_line_shift_y_type *buffer_line_shift_y; custom_buffer_pos_at_relative_xy_type *buffer_pos_at_relative_xy; custom_buffer_relative_box_of_pos_type *buffer_relative_box_of_pos; +custom_buffer_padded_box_of_pos_type *buffer_padded_box_of_pos; custom_buffer_relative_character_from_pos_type *buffer_relative_character_from_pos; custom_buffer_pos_from_relative_character_type *buffer_pos_from_relative_character; custom_view_line_y_difference_type *view_line_y_difference; custom_view_line_shift_y_type *view_line_shift_y; custom_view_pos_at_relative_xy_type *view_pos_at_relative_xy; custom_view_relative_box_of_pos_type *view_relative_box_of_pos; +custom_view_padded_box_of_pos_type *view_padded_box_of_pos; custom_view_relative_character_from_pos_type *view_relative_character_from_pos; custom_view_pos_from_relative_character_type *view_pos_from_relative_character; custom_buffer_exists_type *buffer_exists; @@ -548,12 +554,14 @@ internal f32 buffer_line_y_difference(Application_Links* app, Buffer_ID buffer_i internal Line_Shift_Vertical buffer_line_shift_y(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 line, f32 y_shift); internal i64 buffer_pos_at_relative_xy(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, Vec2_f32 relative_xy); internal Rect_f32 buffer_relative_box_of_pos(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos); +internal Rect_f32 buffer_padded_box_of_pos(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos); internal i64 buffer_relative_character_from_pos(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos); internal i64 buffer_pos_from_relative_character(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 relative_character); internal f32 view_line_y_difference(Application_Links* app, View_ID view_id, i64 line_a, i64 line_b); internal Line_Shift_Vertical view_line_shift_y(Application_Links* app, View_ID view_id, i64 line, f32 y_shift); internal i64 view_pos_at_relative_xy(Application_Links* app, View_ID view_id, i64 base_line, Vec2_f32 relative_xy); internal Rect_f32 view_relative_box_of_pos(Application_Links* app, View_ID view_id, i64 base_line, i64 pos); +internal Rect_f32 view_padded_box_of_pos(Application_Links* app, View_ID view_id, i64 base_line, i64 pos); internal i64 view_relative_character_from_pos(Application_Links* app, View_ID view_id, i64 base_line, i64 pos); internal i64 view_pos_from_relative_character(Application_Links* app, View_ID view_id, i64 base_line, i64 character); internal b32 buffer_exists(Application_Links* app, Buffer_ID buffer_id); @@ -724,12 +732,14 @@ global custom_buffer_line_y_difference_type *buffer_line_y_difference = 0; global custom_buffer_line_shift_y_type *buffer_line_shift_y = 0; global custom_buffer_pos_at_relative_xy_type *buffer_pos_at_relative_xy = 0; global custom_buffer_relative_box_of_pos_type *buffer_relative_box_of_pos = 0; +global custom_buffer_padded_box_of_pos_type *buffer_padded_box_of_pos = 0; global custom_buffer_relative_character_from_pos_type *buffer_relative_character_from_pos = 0; global custom_buffer_pos_from_relative_character_type *buffer_pos_from_relative_character = 0; global custom_view_line_y_difference_type *view_line_y_difference = 0; global custom_view_line_shift_y_type *view_line_shift_y = 0; global custom_view_pos_at_relative_xy_type *view_pos_at_relative_xy = 0; global custom_view_relative_box_of_pos_type *view_relative_box_of_pos = 0; +global custom_view_padded_box_of_pos_type *view_padded_box_of_pos = 0; global custom_view_relative_character_from_pos_type *view_relative_character_from_pos = 0; global custom_view_pos_from_relative_character_type *view_pos_from_relative_character = 0; global custom_buffer_exists_type *buffer_exists = 0; diff --git a/custom/generated/custom_api_constructor.cpp b/custom/generated/custom_api_constructor.cpp index f72a65da..c30e0dd3 100644 --- a/custom/generated/custom_api_constructor.cpp +++ b/custom/generated/custom_api_constructor.cpp @@ -161,6 +161,15 @@ api_param(arena, call, "i64", "base_line"); api_param(arena, call, "i64", "pos"); } { +API_Call *call = api_call_with_location(arena, result, string_u8_litexpr("buffer_padded_box_of_pos"), string_u8_litexpr("Rect_f32"), string_u8_litexpr("")); +api_param(arena, call, "Application_Links*", "app"); +api_param(arena, call, "Buffer_ID", "buffer_id"); +api_param(arena, call, "f32", "width"); +api_param(arena, call, "Face_ID", "face_id"); +api_param(arena, call, "i64", "base_line"); +api_param(arena, call, "i64", "pos"); +} +{ API_Call *call = api_call_with_location(arena, result, string_u8_litexpr("buffer_relative_character_from_pos"), string_u8_litexpr("i64"), string_u8_litexpr("")); api_param(arena, call, "Application_Links*", "app"); api_param(arena, call, "Buffer_ID", "buffer_id"); @@ -207,6 +216,13 @@ api_param(arena, call, "i64", "base_line"); api_param(arena, call, "i64", "pos"); } { +API_Call *call = api_call_with_location(arena, result, string_u8_litexpr("view_padded_box_of_pos"), string_u8_litexpr("Rect_f32"), string_u8_litexpr("")); +api_param(arena, call, "Application_Links*", "app"); +api_param(arena, call, "View_ID", "view_id"); +api_param(arena, call, "i64", "base_line"); +api_param(arena, call, "i64", "pos"); +} +{ API_Call *call = api_call_with_location(arena, result, string_u8_litexpr("view_relative_character_from_pos"), string_u8_litexpr("i64"), string_u8_litexpr("")); api_param(arena, call, "Application_Links*", "app"); api_param(arena, call, "View_ID", "view_id"); @@ -968,7 +984,7 @@ api_param(arena, call, "i64", "pos"); API_Call *call = api_call_with_location(arena, result, string_u8_litexpr("paint_text_color"), string_u8_litexpr("void"), string_u8_litexpr("")); api_param(arena, call, "Application_Links*", "app"); api_param(arena, call, "Text_Layout_ID", "layout_id"); -api_param(arena, call, "Interval_i64", "range"); +api_param(arena, call, "Range_i64", "range"); api_param(arena, call, "ARGB_Color", "color"); } { diff --git a/custom/generated/custom_api_master_list.h b/custom/generated/custom_api_master_list.h index 53c10b50..4ad7edf4 100644 --- a/custom/generated/custom_api_master_list.h +++ b/custom/generated/custom_api_master_list.h @@ -23,12 +23,14 @@ api(custom) function f32 buffer_line_y_difference(Application_Links* app, Buffer api(custom) function Line_Shift_Vertical buffer_line_shift_y(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 line, f32 y_shift); api(custom) function i64 buffer_pos_at_relative_xy(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, Vec2_f32 relative_xy); api(custom) function Rect_f32 buffer_relative_box_of_pos(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos); +api(custom) function Rect_f32 buffer_padded_box_of_pos(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos); api(custom) function i64 buffer_relative_character_from_pos(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 pos); api(custom) function i64 buffer_pos_from_relative_character(Application_Links* app, Buffer_ID buffer_id, f32 width, Face_ID face_id, i64 base_line, i64 relative_character); api(custom) function f32 view_line_y_difference(Application_Links* app, View_ID view_id, i64 line_a, i64 line_b); api(custom) function Line_Shift_Vertical view_line_shift_y(Application_Links* app, View_ID view_id, i64 line, f32 y_shift); api(custom) function i64 view_pos_at_relative_xy(Application_Links* app, View_ID view_id, i64 base_line, Vec2_f32 relative_xy); api(custom) function Rect_f32 view_relative_box_of_pos(Application_Links* app, View_ID view_id, i64 base_line, i64 pos); +api(custom) function Rect_f32 view_padded_box_of_pos(Application_Links* app, View_ID view_id, i64 base_line, i64 pos); api(custom) function i64 view_relative_character_from_pos(Application_Links* app, View_ID view_id, i64 base_line, i64 pos); api(custom) function i64 view_pos_from_relative_character(Application_Links* app, View_ID view_id, i64 base_line, i64 character); api(custom) function b32 buffer_exists(Application_Links* app, Buffer_ID buffer_id); From 874024f8fb5f7eeabaec5cb556baff415bda9018 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Fri, 27 Dec 2019 23:30:46 +0200 Subject: [PATCH 028/128] Added section comments to mac_4ed_functions.cpp --- platform_mac/mac_4ed_functions.cpp | 34 ++++++++++++++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/platform_mac/mac_4ed_functions.cpp b/platform_mac/mac_4ed_functions.cpp index e0b3d198..2c22135e 100644 --- a/platform_mac/mac_4ed_functions.cpp +++ b/platform_mac/mac_4ed_functions.cpp @@ -1,5 +1,9 @@ /* macOS System/Graphics/Font API Implementations */ +////////////////////// +// System API // +////////////////////// + //////////////////////////////// function @@ -50,6 +54,8 @@ system_get_canonical_sig(){ return(result); } +//////////////////////////////// + function File_Attributes mac_get_file_attributes(struct stat file_stat) { File_Attributes result; @@ -270,6 +276,8 @@ system_save_file_sig(){ return(result); } +//////////////////////////////// + function system_load_library_sig(){ b32 result = false; @@ -297,6 +305,8 @@ system_get_proc_sig(){ return(result); } +//////////////////////////////// + function system_now_time_sig(){ u64 result = 0; @@ -335,11 +345,15 @@ system_sleep_sig(){ NotImplemented; } +//////////////////////////////// + function system_post_clipboard_sig(){ NotImplemented; } +//////////////////////////////// + function system_cli_call_sig(){ b32 result = false; @@ -372,6 +386,8 @@ system_cli_end_update_sig(){ return(result); } +//////////////////////////////// + function system_open_color_picker_sig(){ NotImplemented; @@ -386,6 +402,8 @@ system_get_screen_scale_factor_sig(){ return(result); } +//////////////////////////////// + function system_thread_launch_sig(){ System_Thread result = {}; @@ -472,6 +490,8 @@ system_condition_variable_free_sig(){ NotImplemented; } +//////////////////////////////// + function system_memory_allocate_sig(){ void* result = 0; @@ -504,6 +524,8 @@ system_memory_annotation_sig(){ return(result); } +//////////////////////////////// + function system_show_mouse_cursor_sig(){ NotImplemented; @@ -538,6 +560,12 @@ system_get_keyboard_modifiers_sig(){ //////////////////////////////// +//////////////////////// +// Graphics API // +//////////////////////// + +//////////////////////////////// + function graphics_get_texture_sig(){ u32 result = 0; @@ -558,6 +586,12 @@ graphics_fill_texture_sig(){ //////////////////////////////// +//////////////////// +// Font API // +//////////////////// + +//////////////////////////////// + function font_make_face_sig(){ Face* result = 0; From da150cd322a7804a5789524a8905018590eed5ee Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Fri, 27 Dec 2019 23:59:59 +0200 Subject: [PATCH 030/128] Merged mac_4ed.cpp into mac_4ed.mm so now we have only 1 main file for the macOS platform layer. --- bin/4ed_build.cpp | 2 +- custom/generated/command_metadata.h | 458 +++++++++--------- .../Resources/DWARF/metadata_generator | Bin 138399 -> 136740 bytes platform_mac/mac_4ed.cpp | 141 ------ platform_mac/mac_4ed.mm | 167 +++++-- ...4ed_functions.cpp => mac_4ed_functions.mm} | 15 +- 6 files changed, 362 insertions(+), 421 deletions(-) delete mode 100644 platform_mac/mac_4ed.cpp rename platform_mac/{mac_4ed_functions.cpp => mac_4ed_functions.mm} (94%) diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index f15d0040..146169fb 100644 --- a/bin/4ed_build.cpp +++ b/bin/4ed_build.cpp @@ -94,7 +94,7 @@ char *includes[] = { "custom", FOREIGN "/freetype2", 0, }; 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.mm", "platform_mac/mac_4ed.cpp", 0 }; +char *mac_platform_layer[] = { "platform_mac/mac_4ed.mm", 0 }; char **platform_layers[Platform_COUNT] = { windows_platform_layer, diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index d19e25ba..46c04cd1 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 375 }, -{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 385 }, -{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 154 }, -{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 128 }, -{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 186 }, -{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 578 }, -{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 480 }, -{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 243 }, -{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 842 }, -{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 180 }, -{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 190 }, -{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 668 }, -{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 149 }, -{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 19 }, -{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 175 }, -{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 28 }, -{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1798 }, -{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 7 }, -{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 23 }, -{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 162 }, -{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1221 }, -{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1396 }, -{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 134 }, -{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 7 }, -{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 740 }, -{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 2184 }, -{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 509 }, -{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 651 }, -{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 637 }, -{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 579 }, -{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 673 }, -{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 515 }, -{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 597 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 634 }, -{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 563 }, -{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 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, "/Users/allenwebster/4ed/code/custom/4coder_code_index_listers.cpp", 65, 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 57 }, -{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 44 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1542 }, -{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1336 }, -{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 249 }, -{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 265 }, -{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 338 }, -{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 421 }, -{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 530 }, -{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1370 }, -{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 523 }, -{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 495 }, -{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 332 }, -{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1461 }, -{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1792 }, -{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1493 }, -{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 310 }, -{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 366 }, -{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 106 }, -{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 226 }, -{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 219 }, -{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 212 }, -{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "/Users/allenwebster/4ed/code/custom/4coder_profile_inspect.cpp", 62, 886 }, -{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1186 }, -{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1298 }, -{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 994 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1550 }, -{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1265 }, -{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 27 }, -{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 99 }, -{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 115 }, -{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 427 }, -{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 1230 }, -{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 644 }, -{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 630 }, -{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "/Users/allenwebster/4ed/code/custom/4coder_log_parser.cpp", 57, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 187 }, -{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 403 }, -{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1518 }, -{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 552 }, -{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 658 }, -{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 439 }, -{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 433 }, -{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 721 }, -{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 727 }, -{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 445 }, -{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 712 }, -{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "/Users/allenwebster/4ed/code/custom/4coder_code_index.cpp", 57, 1160 }, -{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 20 }, -{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 34 }, -{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 137 }, -{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_lister.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 392 }, -{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 639 }, -{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 88 }, -{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts an underscore.", 22, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 395 }, -{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 76 }, -{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 73 }, -{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 100 }, +{ PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 375 }, +{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 385 }, +{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 154 }, +{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 128 }, +{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 186 }, +{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 578 }, +{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 480 }, +{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 243 }, +{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 842 }, +{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 180 }, +{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_docs.cpp", 49, 190 }, +{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 668 }, +{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 149 }, +{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 19 }, +{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_docs.cpp", 49, 175 }, +{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 28 }, +{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1798 }, +{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 7 }, +{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 23 }, +{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 162 }, +{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1221 }, +{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1396 }, +{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 134 }, +{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_cli_command.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_cli_command.cpp", 56, 7 }, +{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 740 }, +{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 2184 }, +{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 509 }, +{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 651 }, +{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 637 }, +{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 579 }, +{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 673 }, +{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 515 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 597 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 634 }, +{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 563 }, +{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_code_index_listers.cpp", 63, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 57 }, +{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 44 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1542 }, +{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1336 }, +{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 249 }, +{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 265 }, +{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 338 }, +{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 421 }, +{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 530 }, +{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1370 }, +{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 523 }, +{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 495 }, +{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 332 }, +{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1461 }, +{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1792 }, +{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1493 }, +{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 310 }, +{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 366 }, +{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 106 }, +{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 226 }, +{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 219 }, +{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 212 }, +{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "/Users/yuvaldolev/4ed/code/custom/4coder_profile_inspect.cpp", 60, 886 }, +{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1186 }, +{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1298 }, +{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 994 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1550 }, +{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1265 }, +{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 27 }, +{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 99 }, +{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 115 }, +{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 427 }, +{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 1230 }, +{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 644 }, +{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 630 }, +{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_log_parser.cpp", 55, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 187 }, +{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 403 }, +{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1518 }, +{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 552 }, +{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 658 }, +{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 439 }, +{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 433 }, +{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 721 }, +{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 727 }, +{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 445 }, +{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 712 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_code_index.cpp", 55, 1160 }, +{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 20 }, +{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 34 }, +{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 137 }, +{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_lister.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 392 }, +{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 639 }, +{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 88 }, +{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts an underscore.", 22, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 395 }, +{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 76 }, +{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 73 }, +{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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/Resources/DWARF/metadata_generator b/custom/metadata_generator.dSYM/Contents/Resources/DWARF/metadata_generator index d94c7b9522fc39f45009ef4ef8c1d9cfafae8580..133e453d1c931a6805c0b6e109b54aada975ee7d 100644 GIT binary patch literal 136740 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 aPWq;gb0w``BQS}fj=Gqpe2u_k^nU?nKY9-U literal 138399 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 HK1Tl^sgkr2 diff --git a/platform_mac/mac_4ed.cpp b/platform_mac/mac_4ed.cpp deleted file mode 100644 index b2636154..00000000 --- a/platform_mac/mac_4ed.cpp +++ /dev/null @@ -1,141 +0,0 @@ -/* Mac C++ layer for 4coder */ - -#include "4coder_base_types.h" -#include "4coder_version.h" -#include "4coder_events.h" - -#include "4coder_table.h" -#include "4coder_types.h" -#include "4coder_default_colors.h" - -#include "4coder_system_types.h" -#define STATIC_LINK_API -#include "generated/system_api.h" - -#include "4ed_font_interface.h" -#define STATIC_LINK_API -#include "generated/graphics_api.h" -#define STATIC_LINK_API -#include "generated/font_api.h" - -#include "4ed_font_set.h" -#include "4ed_render_target.h" -#include "4ed_search_list.h" -#include "4ed.h" - -#include "generated/system_api.cpp" -#include "generated/graphics_api.cpp" -#include "generated/font_api.cpp" - -#include "4coder_base_types.cpp" -#include "4coder_stringf.cpp" -#include "4coder_events.cpp" -#include "4coder_hash_functions.cpp" -#include "4coder_table.cpp" -#include "4coder_log.cpp" - -#include "4ed_search_list.cpp" - -#include "mac_objective_c_to_cpp_links.h" - -#include // NOTE(yuval): Used for opendir, readdir -#include // NOTE(yuval): Used for errno -#include // NOTE(yuval): Used for open -#include // NOTE(yuval): Used for getcwd, read, write -#include // NOTE(yuval): Used for stat -#include // NOTE(yuval): Used for struct stat - -#include // NOTE(yuval): Used for free - -//////////////////////////////// - -#define SLASH '/' -#define DLL "so" - -#include "4coder_hash_functions.cpp" -#include "4coder_system_allocator.cpp" -#include "4coder_malloc_allocator.cpp" -#include "4coder_codepoint_map.cpp" - -#include "4ed_mem.cpp" -#include "4ed_font_set.cpp" - -//////////////////////////////// - -struct Mac_Vars { - Thread_Context *tctx; - - Arena* frame_arena; - - String_Const_u8 binary_path; -}; - -//////////////////////////////// - -Mac_Vars mac_vars; -global Render_Target target; - -//////////////////////////////// - -#include "mac_4ed_functions.cpp" - -//////////////////////////////// - -external String_Const_u8 -mac_SCu8(u8* str, u64 size){ - String_Const_u8 result = SCu8(str, size); - return(result); -} - -external String_Const_u8 -mac_push_string_copy(Arena *arena, String_Const_u8 src){ - String_Const_u8 result = push_string_copy(arena, src); - return(result); -} - -external void -mac_init(){ - Arena test_arena = make_arena_malloc(); - File_List list = system_get_file_list(&test_arena, - string_u8_litexpr("/Users/yuvaldolev/Desktop")); - - for (u32 index = 0; index < list.count; ++index) { - File_Info* info = list.infos[index]; - - printf("File_Info{file_name:'%.*s', " - "attributes:{size:%llu, last_write_time:%llu, flags:{IsDirectory:%d}}}\n", - (i32)info->file_name.size, info->file_name.str, - info->attributes.size, info->attributes.last_write_time, - ((info->attributes.flags & FileAttribute_IsDirectory) != 0)); - } - -#if 0 - // NOTE(yuval): Context Setup - Thread_Context _tctx = {}; - thread_ctx_init(&_tctx, ThreadKind_Main, - get_base_allocator_system(), - get_base_allocator_system()); - - block_zero_struct(&mac_vars); - mac_vars.tctx = &_tctx; - - API_VTable_system system_vtable = {}; - system_api_fill_vtable(&system_vtable); - - API_VTable_graphics graphics_vtable = {}; - graphics_api_fill_vtable(&graphics_vtable); - - API_VTable_font font_vtable = {}; - font_api_fill_vtable(&font_vtable); - - // NOTE(yuval): Memory - mac_vars.frame_arena = reserve_arena(mac_vars.tctx); - target.arena = make_arena_system(KB(256)); - - mac_vars.cursor_show = MouseCursorShow_Always; - mac_vars.prev_cursor_show = MouseCursorShow_Always; - - dll_init_sentinel(&mac_vars.free_mac_objects); - dll_init_sentinel(&mac_vars.timer_objects); -#endif -} \ No newline at end of file diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index c2519d04..de73ec52 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -1,17 +1,47 @@ /* Mac Objective C layer for 4coder */ #include "4coder_base_types.h" - -#if 1 -#include "4coder_table.h" +#include "4coder_version.h" #include "4coder_events.h" + +#include "4coder_table.h" + // NOTE(allen): This is a very unfortunate hack, but hopefully there will never be a need to use the Marker // type in the platform layer. If that changes then instead change the name of Marker and make a transition // macro that is only included in custom code. #define Marker Marker__SAVE_THIS_IDENTIFIER #include "4coder_types.h" #undef Marker -#endif + +#include "4coder_default_colors.h" + +#include "4coder_system_types.h" +#define STATIC_LINK_API +#include "generated/system_api.h" + +#include "4ed_font_interface.h" +#define STATIC_LINK_API +#include "generated/graphics_api.h" +#define STATIC_LINK_API +#include "generated/font_api.h" + +#include "4ed_font_set.h" +#include "4ed_render_target.h" +#include "4ed_search_list.h" +#include "4ed.h" + +#include "generated/system_api.cpp" +#include "generated/graphics_api.cpp" +#include "generated/font_api.cpp" + +#include "4coder_base_types.cpp" +#include "4coder_stringf.cpp" +#include "4coder_events.cpp" +#include "4coder_hash_functions.cpp" +#include "4coder_table.cpp" +#include "4coder_log.cpp" + +#include "4ed_search_list.cpp" #include "mac_objective_c_to_cpp_links.h" @@ -19,13 +49,22 @@ #undef internal #undef global #undef external -#include +#import #include // NOTE(yuval): Used for proc_pidpath -#include // NOTE(yuval): Used for pid_t -#include // NOTE(yuval): Used for getpid +#include // NOTE(yuval): Used for opendir, readdir +#include // NOTE(yuval): Used for errno +#include // NOTE(yuval): Used for open +#include // NOTE(yuval): Used for getcwd, read, write, getpid +#include // NOTE(yuval): Used for stat +#include // NOTE(yuval): Used for struct stat, pid_t +#include // NOTE(yuval): Used for free + +#define function static +#define internal static +#define global static #define external extern "C" @interface App_Delegate : NSObject @@ -52,49 +91,39 @@ } @end -#if 0 -external File_List -mac_get_file_list(Arena* arena, String_Const_u8 directory){ - File_List result = {}; - - NSString *directory_ns_string = - [[NSString alloc] - initWithBytes:directory.data length:directory.size encoding:NSUTF8StringEncoding]; - - NSFileManager *file_manager = [NSFileManager defaultManager]; - NSDirectoryEnumerator *dirEnum = [file_manager enumeratorAtPath:directory_ns_string]; - - NSString *filename; - while ((filename = [dirEnum nextObject])){ - NSLog(@"%@", filename); - } - - [directory_ns_string release]; -} -#endif +//////////////////////////////// -external String_Const_u8 -mac_standardize_path(Arena* arena, String_Const_u8 path){ - NSString *path_ns_str = - [[NSString alloc] initWithBytes:path.data length:path.size encoding:NSUTF8StringEncoding]; - - NSString *standardized_path_ns_str = [path_ns_str stringByStandardizingPath]; - String_Const_u8 standardized_path = mac_SCu8((u8*)[standardized_path_ns_str UTF8String],[standardized_path_ns_str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); - - String_Const_u8 result = mac_push_string_copy(arena, standardized_path); - - [path_ns_str release]; - - return(result); -} +#define SLASH '/' +#define DLL "so" -external i32 -mac_get_binary_path(void *buffer, u32 size){ - pid_t pid = getpid(); - i32 bytes_read = proc_pidpath(pid, buffer, size); +#include "4coder_hash_functions.cpp" +#include "4coder_system_allocator.cpp" +#include "4coder_malloc_allocator.cpp" +#include "4coder_codepoint_map.cpp" + +#include "4ed_mem.cpp" +#include "4ed_font_set.cpp" + +//////////////////////////////// + +struct Mac_Vars { + Thread_Context *tctx; - return(bytes_read); -} + Arena* frame_arena; + + String_Const_u8 binary_path; +}; + +//////////////////////////////// + +Mac_Vars mac_vars; +global Render_Target target; + +//////////////////////////////// + +#import "mac_4ed_functions.mm" + +//////////////////////////////// int main(int arg_count, char **args){ @@ -108,7 +137,49 @@ main(int arg_count, char **args){ [NSApp finishLaunching]; - mac_init(); + Arena test_arena = make_arena_malloc(); + File_List list = system_get_file_list(&test_arena, + string_u8_litexpr("/Users/yuvaldolev/Desktop/imgui")); + + for (u32 index = 0; index < list.count; ++index) { + File_Info* info = list.infos[index]; + + printf("File_Info{file_name:'%.*s', " + "attributes:{size:%llu, last_write_time:%llu, flags:{IsDirectory:%d}}}\n", + (i32)info->file_name.size, info->file_name.str, + info->attributes.size, info->attributes.last_write_time, + ((info->attributes.flags & FileAttribute_IsDirectory) != 0)); + } + +#if 0 + // NOTE(yuval): Context Setup + Thread_Context _tctx = {}; + thread_ctx_init(&_tctx, ThreadKind_Main, + get_base_allocator_system(), + get_base_allocator_system()); + + block_zero_struct(&mac_vars); + mac_vars.tctx = &_tctx; + + API_VTable_system system_vtable = {}; + system_api_fill_vtable(&system_vtable); + + API_VTable_graphics graphics_vtable = {}; + graphics_api_fill_vtable(&graphics_vtable); + + API_VTable_font font_vtable = {}; + font_api_fill_vtable(&font_vtable); + + // NOTE(yuval): Memory + mac_vars.frame_arena = reserve_arena(mac_vars.tctx); + target.arena = make_arena_system(KB(256)); + + mac_vars.cursor_show = MouseCursorShow_Always; + mac_vars.prev_cursor_show = MouseCursorShow_Always; + + dll_init_sentinel(&mac_vars.free_mac_objects); + dll_init_sentinel(&mac_vars.timer_objects); +#endif #if 0 // NOTE(yuval): Application Core Update diff --git a/platform_mac/mac_4ed_functions.cpp b/platform_mac/mac_4ed_functions.mm similarity index 94% rename from platform_mac/mac_4ed_functions.cpp rename to platform_mac/mac_4ed_functions.mm index 2c22135e..00b4ecc4 100644 --- a/platform_mac/mac_4ed_functions.cpp +++ b/platform_mac/mac_4ed_functions.mm @@ -31,7 +31,9 @@ system_get_path_sig(){ if (!has_stashed_4ed_path){ local_const i32 binary_path_capacity = KB(32); u8 *memory = (u8*)system_memory_allocate(binary_path_capacity, string_u8_litexpr(file_name_line_number)); - i32 size = mac_get_binary_path(memory, binary_path_capacity); + + pid_t pid = getpid(); + i32 size = proc_pidpath(pid, memory, binary_path_capacity); Assert(size <= binary_path_capacity - 1); mac_vars.binary_path = SCu8(memory, size); @@ -50,7 +52,16 @@ system_get_path_sig(){ function system_get_canonical_sig(){ - String_Const_u8 result = mac_standardize_path(arena, name); + NSString *path_ns_str = + [[NSString alloc] initWithBytes:name.data length:name.size encoding:NSUTF8StringEncoding]; + + NSString *standardized_path_ns_str = [path_ns_str stringByStandardizingPath]; + String_Const_u8 standardized_path = mac_SCu8((u8*)[standardized_path_ns_str UTF8String],[standardized_path_ns_str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); + + String_Const_u8 result = push_string_copy(arena, standardized_path); + + [path_ns_str release]; + return(result); } From a91158ebf0dcc2c1a5114d63d48c275dbf707681 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sat, 28 Dec 2019 01:54:33 +0200 Subject: [PATCH 031/128] Implemented all system library handling functions. --- platform_mac/mac_4ed.mm | 9 +++-- platform_mac/mac_4ed_functions.mm | 63 +++++++++++++++++++++++++------ 2 files changed, 58 insertions(+), 14 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index de73ec52..b1bd4d7f 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -1,4 +1,4 @@ -/* Mac Objective C layer for 4coder */ +/* Mac Objective-C layer for 4coder */ #include "4coder_base_types.h" #include "4coder_version.h" @@ -54,6 +54,7 @@ #include // NOTE(yuval): Used for proc_pidpath #include // NOTE(yuval): Used for opendir, readdir +#include // NOTE(yuval): Used for dlopen, dlclose, dlsym #include // NOTE(yuval): Used for errno #include // NOTE(yuval): Used for open #include // NOTE(yuval): Used for getcwd, read, write, getpid @@ -67,6 +68,8 @@ #define global static #define external extern "C" +//////////////////////////////// + @interface App_Delegate : NSObject @end @@ -116,7 +119,7 @@ struct Mac_Vars { //////////////////////////////// -Mac_Vars mac_vars; +global Mac_Vars mac_vars; global Render_Target target; //////////////////////////////// @@ -139,7 +142,7 @@ main(int arg_count, char **args){ Arena test_arena = make_arena_malloc(); File_List list = system_get_file_list(&test_arena, - string_u8_litexpr("/Users/yuvaldolev/Desktop/imgui")); + string_u8_litexpr("/Users/yuvaldolev/Desktop")); for (u32 index = 0; index < list.count; ++index) { File_Info* info = list.infos[index]; diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 00b4ecc4..291e3061 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -200,13 +200,25 @@ system_quick_file_attributes_sig(){ return(result); } +function inline Plat_Handle +mac_to_plat_handle(i32 fd){ + Plat_Handle result = *(Plat_Handle*)(&fd); + return result; +} + +function inline i32 +mac_to_fd(Plat_Handle handle){ + i32 result = *(i32*)(&handle); + return result; +} + function system_load_handle_sig(){ b32 result = false; i32 fd = open(file_name, O_RDONLY); if ((fd != -1) && (fd != 0)) { - *(i32*)out = fd; + *out = mac_to_plat_handle(fd); result = true; } @@ -215,7 +227,7 @@ system_load_handle_sig(){ function system_load_attributes_sig(){ - i32 fd = *(i32*)(&handle); + i32 fd = mac_to_fd(handle); File_Attributes result = mac_file_attributes_from_fd(fd); return(result); @@ -223,7 +235,7 @@ system_load_attributes_sig(){ function system_load_file_sig(){ - i32 fd = *(i32*)(&handle); + i32 fd = mac_to_fd(handle); do{ ssize_t bytes_read = read(fd, buffer, size); @@ -246,7 +258,7 @@ function system_load_close_sig(){ b32 result = true; - i32 fd = *(i32*)(&handle); + i32 fd = mac_to_fd(handle); if (close(fd) == -1){ // NOTE(yuval): An error occured while close the file descriptor result = false; @@ -289,29 +301,58 @@ system_save_file_sig(){ //////////////////////////////// +function inline System_Library +mac_to_system_library(void* dl_handle){ + System_Library result = *(System_Library*)(&dl_handle); + return result; +} + +function inline void* +mac_to_dl_handle(System_Library system_lib){ + void* result = *(void**)(&system_lib); + return result; +} + function system_load_library_sig(){ b32 result = false; - NotImplemented; + void* lib = 0; + + // NOTE(yuval): Open library handle + { + Temp_Memory temp = begin_temp(scratch); + + char* c_file_name = push_array(scratch, char, file_name.size + 1); + block_copy(c_file_name, file_name.str, file_name.size); + c_file_name[file_name.size] = 0; + + lib = dlopen(c_file_name, RTLD_LAZY | RTLD_GLOBAL); + + end_temp(temp); + } + + if (lib){ + *out = mac_to_system_library(lib); + result = true; + } return(result); } function system_release_library_sig(){ - b32 result = false; - - NotImplemented; + void* lib = mac_to_dl_handle(handle); + i32 rc = dlclose(lib); + b32 result = (rc == 0); return(result); } function system_get_proc_sig(){ - Void_Func* result = 0; - - NotImplemented; + void* lib = mac_to_dl_handle(handle); + Void_Func* result = (Void_Func*)dlsym(lib, proc_name); return(result); } From 8020dcf385dc65ab8f69b4d26334acb65a985da8 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 29 Dec 2019 00:11:34 +0200 Subject: [PATCH 032/128] Implemented system_now_time. --- platform_mac/mac_4ed_functions.mm | 12 +++++++++--- platform_mac/mac_4ed_old.m | 6 +++--- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 291e3061..a59fbad1 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -56,7 +56,7 @@ system_get_canonical_sig(){ [[NSString alloc] initWithBytes:name.data length:name.size encoding:NSUTF8StringEncoding]; NSString *standardized_path_ns_str = [path_ns_str stringByStandardizingPath]; - String_Const_u8 standardized_path = mac_SCu8((u8*)[standardized_path_ns_str UTF8String],[standardized_path_ns_str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); + String_Const_u8 standardized_path = SCu8((u8*)[standardized_path_ns_str UTF8String],[standardized_path_ns_str lengthOfBytesUsingEncoding:NSUTF8StringEncoding]); String_Const_u8 result = push_string_copy(arena, standardized_path); @@ -361,9 +361,15 @@ system_get_proc_sig(){ function system_now_time_sig(){ - u64 result = 0; + u64 now = mach_absolute_time(); - NotImplemented; + // NOTE(yuval): Elapsed nanoseconds calculation + u64 result = (u64)(((f32)now) * + ((f32)mac_vars.timebase_info.numer) / + ((f32)mac_vars.timebase_info.denom)); + + // NOTE(yuval): Conversion to useconds + result *= 1.0E-3; return(result); } diff --git a/platform_mac/mac_4ed_old.m b/platform_mac/mac_4ed_old.m index ebadc1ca..fad0565e 100644 --- a/platform_mac/mac_4ed_old.m +++ b/platform_mac/mac_4ed_old.m @@ -814,9 +814,9 @@ osx_list_loadable_fonts(void){ NSString *font_n = fonts[i]; char *font_n_c = (char*)[font_n UTF8String]; NSFont *font = [font_manager - fontWithFamily:font_n - traits:NSUnboldFontMask|NSUnitalicFontMask - weight:5 + fontWithFamily:font_n + traits:NSUnboldFontMask|NSUnitalicFontMask + weight:5 size:12]; NSString *path = get_font_path(font); char *path_c = 0; From 76069e9ac1e61a53e6ec19444716ad4de47e5c75 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 29 Dec 2019 03:09:28 +0200 Subject: [PATCH 033/128] Created basic Mac_Object structure and mac object allocation function. --- platform_mac/mac_4ed.mm | 139 +++++++++++++++++++++++------- platform_mac/mac_4ed_functions.mm | 24 +++--- 2 files changed, 120 insertions(+), 43 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index b1bd4d7f..501614b1 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -70,6 +70,113 @@ //////////////////////////////// +#define SLASH '/' +#define DLL "so" + +#include "4coder_hash_functions.cpp" +#include "4coder_system_allocator.cpp" +#include "4coder_malloc_allocator.cpp" +#include "4coder_codepoint_map.cpp" + +#include "4ed_mem.cpp" +#include "4ed_font_set.cpp" + +//////////////////////////////// + +typedef i32 Win32_Object_Kind; +enum{ + Win32ObjectKind_ERROR = 0, + Win32ObjectKind_Timer = 1, + Win32ObjectKind_Thread = 2, + Win32ObjectKind_Mutex = 3, + Win32ObjectKind_CV = 4, +}; + +struct Mac_Object{ + Node node; + Mac_Object_Kind kind; + + union{ + struct{ + NSTimer* timer; + } timer; + }; +}; + +struct Mac_Vars { + Thread_Context *tctx; + + Arena* frame_arena; + + String_Const_u8 binary_path; + + Node free_mac_objects; + Node timer_objects; +}; + +//////////////////////////////// + +global Mac_Vars mac_vars; +global Render_Target target; + +//////////////////////////////// + +function inline Plat_Handle +mac_to_plat_handle(Mac_Object* object){ + Plat_Handle result = *(Plat_Handle*)(&object); + return(result); +} + +function inline Mac_Object* +mac_to_object(Plat_Handle handle){ + Mac_Object* result = *(Mac_Object**)(&handle); + return(result); +} + +function +mac_alloc_object(Mac_Object_Kind kind){ + Mac_Object* result = 0; + + if (mac_vars.free_mac_objects.next != &mac_vars.free_mac_objects){ + result = CastFromMember(Mac_Object, node, mac_vars.free_mac_objects.next); + } + + if (!result){ + i32 count = 512; + Mac_Object* objects = (Mac_Object*)system_memory_allocate(count * sizeof(Mac_Object), file_name_line_number); + + // NOTE(yuval): Link the first chain of the dll to the sentinel + objects[0].node.prev = &mac_vars.free_mac_objects; + mac_vars.free_mac_objects.next = &objects[0].node; + + // NOTE(yuval): Link all dll chains to each other + for (i32 chain_index = 1; chain_index < count; chain_index += 1){ + objects[chain_index - 1].node.next = &objects[chain_index].node; + objects[chain_index].node.prev = &objects[chain_index - 1].node; + } + + // NOTE(yuval): Link the last chain of the dll to the sentinel + objects[count - 1].node.next = &mac_vars.free_mac_objects; + mac_vars.free_mac_objects.prev = &objects[count - 1].node; + + result = CastFromMember(Mac_Object, node, mac_vars.free_mac_objects.next); + } + + Assert(result); + dll_remove(&result->node); + block_zero_struct(result); + result->kind = kind; + + return(result); +} + + +//////////////////////////////// + +#import "mac_4ed_functions.mm" + +//////////////////////////////// + @interface App_Delegate : NSObject @end @@ -96,38 +203,6 @@ //////////////////////////////// -#define SLASH '/' -#define DLL "so" - -#include "4coder_hash_functions.cpp" -#include "4coder_system_allocator.cpp" -#include "4coder_malloc_allocator.cpp" -#include "4coder_codepoint_map.cpp" - -#include "4ed_mem.cpp" -#include "4ed_font_set.cpp" - -//////////////////////////////// - -struct Mac_Vars { - Thread_Context *tctx; - - Arena* frame_arena; - - String_Const_u8 binary_path; -}; - -//////////////////////////////// - -global Mac_Vars mac_vars; -global Render_Target target; - -//////////////////////////////// - -#import "mac_4ed_functions.mm" - -//////////////////////////////// - int main(int arg_count, char **args){ @autoreleasepool{ diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index a59fbad1..a4009db7 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -203,13 +203,13 @@ system_quick_file_attributes_sig(){ function inline Plat_Handle mac_to_plat_handle(i32 fd){ Plat_Handle result = *(Plat_Handle*)(&fd); - return result; + return(result); } function inline i32 mac_to_fd(Plat_Handle handle){ i32 result = *(i32*)(&handle); - return result; + return(result); } function @@ -304,13 +304,13 @@ system_save_file_sig(){ function inline System_Library mac_to_system_library(void* dl_handle){ System_Library result = *(System_Library*)(&dl_handle); - return result; + return(result); } function inline void* mac_to_dl_handle(System_Library system_lib){ void* result = *(void**)(&system_lib); - return result; + return(result); } function @@ -363,14 +363,13 @@ function system_now_time_sig(){ u64 now = mach_absolute_time(); - // NOTE(yuval): Elapsed nanoseconds calculation - u64 result = (u64)(((f32)now) * - ((f32)mac_vars.timebase_info.numer) / - ((f32)mac_vars.timebase_info.denom)); + // NOTE(yuval): Now time nanoseconds conversion + f64 now_nano = (f64)(((f64)now) * + ((f64)mac_vars.timebase_info.numer) / + ((f64)mac_vars.timebase_info.denom)); // NOTE(yuval): Conversion to useconds - result *= 1.0E-3; - + u64 result = (u64)(now_nano * 1.0E-3); return(result); } @@ -378,7 +377,10 @@ function system_wake_up_timer_create_sig(){ Plat_Handle result = {}; - NotImplemented; + NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval: 0.0 + target: view + selector: @selector(requestDisplay) + userInfo: nil repeats:NO]; return(result); } From dc213307a92c8f3e477b7f9f2080a6940a7b2ed9 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Mon, 30 Dec 2019 00:34:53 +0200 Subject: [PATCH 034/128] Implemented all system wake up timer functions. --- platform_mac/mac_4ed.mm | 38 +++++++++++-------- platform_mac/mac_4ed_functions.mm | 63 ++++++++++++++++++------------- 2 files changed, 59 insertions(+), 42 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 501614b1..9a87b069 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -83,13 +83,13 @@ //////////////////////////////// -typedef i32 Win32_Object_Kind; +typedef i32 Mac_Object_Kind; enum{ - Win32ObjectKind_ERROR = 0, - Win32ObjectKind_Timer = 1, - Win32ObjectKind_Thread = 2, - Win32ObjectKind_Mutex = 3, - Win32ObjectKind_CV = 4, + MacObjectKind_ERROR = 0, + MacObjectKind_Timer = 1, + MacObjectKind_Thread = 2, + MacObjectKind_Mutex = 3, + MacObjectKind_CV = 4, }; struct Mac_Object{ @@ -122,7 +122,7 @@ global Render_Target target; //////////////////////////////// function inline Plat_Handle -mac_to_plat_handle(Mac_Object* object){ +mac_to_plat_handle(Mac_Object *object){ Plat_Handle result = *(Plat_Handle*)(&object); return(result); } @@ -135,7 +135,7 @@ mac_to_object(Plat_Handle handle){ function mac_alloc_object(Mac_Object_Kind kind){ - Mac_Object* result = 0; + Mac_Object *result = 0; if (mac_vars.free_mac_objects.next != &mac_vars.free_mac_objects){ result = CastFromMember(Mac_Object, node, mac_vars.free_mac_objects.next); @@ -143,19 +143,19 @@ mac_alloc_object(Mac_Object_Kind kind){ if (!result){ i32 count = 512; - Mac_Object* objects = (Mac_Object*)system_memory_allocate(count * sizeof(Mac_Object), file_name_line_number); + Mac_Object *objects = (Mac_Object*)system_memory_allocate(count * sizeof(Mac_Object), file_name_line_number_lit_u8); - // NOTE(yuval): Link the first chain of the dll to the sentinel + // NOTE(yuval): Link the first node of the dll to the sentinel objects[0].node.prev = &mac_vars.free_mac_objects; mac_vars.free_mac_objects.next = &objects[0].node; - // NOTE(yuval): Link all dll chains to each other + // NOTE(yuval): Link all dll nodes to each other for (i32 chain_index = 1; chain_index < count; chain_index += 1){ objects[chain_index - 1].node.next = &objects[chain_index].node; objects[chain_index].node.prev = &objects[chain_index - 1].node; } - // NOTE(yuval): Link the last chain of the dll to the sentinel + // NOTE(yuval): Link the last node of the dll to the sentinel objects[count - 1].node.next = &mac_vars.free_mac_objects; mac_vars.free_mac_objects.prev = &objects[count - 1].node; @@ -170,6 +170,14 @@ mac_alloc_object(Mac_Object_Kind kind){ return(result); } +function +mac_free_object(Mac_Object *object){ + if (object->node.next != 0){ + dll_remove(&object->node); + } + + dll_insert(&mac_vars.free_mac_objects, &object->node); +} //////////////////////////////// @@ -188,7 +196,7 @@ mac_alloc_object(Mac_Object_Kind kind){ return YES; } -- (void)applicationWillTerminate:(NSNotification *)notification{ +- (void)applicationWillTerminate:(NSNotification*)notification{ } - (NSSize)windowWillResize:(NSWindow*)window toSize:(NSSize)frame_size{ @@ -207,10 +215,10 @@ int main(int arg_count, char **args){ @autoreleasepool{ // NOTE(yuval): Create NSApplication & Delegate - NSApplication* app = [NSApplication sharedApplication]; + NSApplication *app = [NSApplication sharedApplication]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - App_Delegate* app_delegate = [[App_Delegate alloc] init]; + App_Delegate *app_delegate = [[App_Delegate alloc] init]; [app setDelegate:app_delegate]; [NSApp finishLaunching]; diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index a4009db7..b98780d8 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -82,7 +82,7 @@ mac_get_file_attributes(struct stat file_stat) { } function inline File_Attributes -mac_file_attributes_from_path(char* path) { +mac_file_attributes_from_path(char *path) { File_Attributes result = {}; struct stat file_stat; @@ -109,7 +109,7 @@ function system_get_file_list_sig(){ File_List result = {}; - u8* c_directory = push_array(arena, u8, directory.size + 1); + u8 *c_directory = push_array(arena, u8, directory.size + 1); block_copy(c_directory, directory.str, directory.size); c_directory[directory.size] = 0; @@ -129,7 +129,7 @@ system_get_file_list_sig(){ continue; } - File_Info* info = push_array(arena, File_Info, 1); + File_Info *info = push_array(arena, File_Info, 1); sll_queue_push(first, last, info); count += 1; @@ -146,8 +146,8 @@ system_get_file_list_sig(){ file_path_size += 1; } - char* file_path = push_array(arena, char, file_path_size + 1); - char* file_path_at = file_path; + char *file_path = push_array(arena, char, file_path_size + 1); + char *file_path_at = file_path; block_copy(file_path_at, directory.str, directory.size); file_path_at += directory.size; @@ -174,7 +174,7 @@ system_get_file_list_sig(){ result.count = count; i32 index = 0; - for (File_Info* node = first; + for (File_Info *node = first; node != 0; node = node->next){ result.infos[index] = node; @@ -189,7 +189,7 @@ function system_quick_file_attributes_sig(){ Temp_Memory temp = begin_temp(scratch); - char* c_file_name = push_array(scratch, char, file_name.size + 1); + char *c_file_name = push_array(scratch, char, file_name.size + 1); block_copy(c_file_name, file_name.str, file_name.size); c_file_name[file_name.size] = 0; @@ -273,9 +273,6 @@ system_save_file_sig(){ i32 fd = open(file_name, O_WRONLY | O_TRUNC | O_CREAT, 00640); if (fd != -1) { - u8* data_str = data.str; - u64 data_size = data.size; - do{ ssize_t bytes_written = write(fd, data.str, data.size); if (bytes_written == -1){ @@ -302,14 +299,14 @@ system_save_file_sig(){ //////////////////////////////// function inline System_Library -mac_to_system_library(void* dl_handle){ +mac_to_system_library(void *dl_handle){ System_Library result = *(System_Library*)(&dl_handle); return(result); } function inline void* mac_to_dl_handle(System_Library system_lib){ - void* result = *(void**)(&system_lib); + void *result = *(void**)(&system_lib); return(result); } @@ -317,13 +314,13 @@ function system_load_library_sig(){ b32 result = false; - void* lib = 0; + void *lib = 0; // NOTE(yuval): Open library handle { Temp_Memory temp = begin_temp(scratch); - char* c_file_name = push_array(scratch, char, file_name.size + 1); + char *c_file_name = push_array(scratch, char, file_name.size + 1); block_copy(c_file_name, file_name.str, file_name.size); c_file_name[file_name.size] = 0; @@ -342,7 +339,7 @@ system_load_library_sig(){ function system_release_library_sig(){ - void* lib = mac_to_dl_handle(handle); + void *lib = mac_to_dl_handle(handle); i32 rc = dlclose(lib); b32 result = (rc == 0); @@ -351,8 +348,8 @@ system_release_library_sig(){ function system_get_proc_sig(){ - void* lib = mac_to_dl_handle(handle); - Void_Func* result = (Void_Func*)dlsym(lib, proc_name); + void *lib = mac_to_dl_handle(handle); + Void_Func *result = (Void_Func*)dlsym(lib, proc_name); return(result); } @@ -364,9 +361,9 @@ system_now_time_sig(){ u64 now = mach_absolute_time(); // NOTE(yuval): Now time nanoseconds conversion - f64 now_nano = (f64)(((f64)now) * - ((f64)mac_vars.timebase_info.numer) / - ((f64)mac_vars.timebase_info.denom)); + f64 now_nano = (f64)((f64)now * + (f64)mac_vars.timebase_info.numer / + (f64)mac_vars.timebase_info.denom); // NOTE(yuval): Conversion to useconds u64 result = (u64)(now_nano * 1.0E-3); @@ -375,24 +372,36 @@ system_now_time_sig(){ function system_wake_up_timer_create_sig(){ - Plat_Handle result = {}; + Mac_Object *object = mac_alloc_object(MacObjectKind_Timer); + dll_insert(&mac_vars.timer_objects, &object->node); - NSTimer* timer = [NSTimer scheduledTimerWithTimeInterval: 0.0 - target: view - selector: @selector(requestDisplay) - userInfo: nil repeats:NO]; + object->timer.timer = nil; + Plat_Handle result = mac_to_plat_handle(object); return(result); } function system_wake_up_timer_release_sig(){ - NotImplemented; + Mac_Object *object = (Mac_Object*)mac_to_object(handle); + if (object->kind == MacObjectKind_Timer){ + if ((object->timer != nil) && [object->timer isValid]) { + [object->timer invalidate]; + mac_free_object(object); + } + } } function system_wake_up_timer_set_sig(){ - NotImplemented; + Mac_Object *object = (Mac_Object*)mac_to_object(handle); + if (object->kind == MacObjectKind_Timer){ + f64 time_seconds = ((f64)time_milliseconds / 1000.0); + object->timer = [NSTimer scheduledTimerWithTimeInterval: time_seconds + target: mac_vars.view + selector: @selector(requestDisplay) + userInfo: nil repeats:NO]; + } } function From 50b8a646146f115eb072efabeebe9206f34a9e43 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Mon, 30 Dec 2019 02:33:30 +0200 Subject: [PATCH 035/128] The projects compiles. --- platform_mac/mac_4ed.mm | 48 +++++++++++++++++++++++++++---- platform_mac/mac_4ed_functions.mm | 6 ++-- 2 files changed, 46 insertions(+), 8 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 9a87b069..aa0790b7 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -52,6 +52,7 @@ #import #include // NOTE(yuval): Used for proc_pidpath +#include // NOTE(yuval): Used for mach_absolute_time, mach_timebase_info, mach_timebase_info_data_t #include // NOTE(yuval): Used for opendir, readdir #include // NOTE(yuval): Used for dlopen, dlclose, dlsym @@ -83,6 +84,16 @@ //////////////////////////////// +@interface App_Delegate : NSObject +@end + +@interface Opengl_View : NSOpenGLView +@end + +//////////////////////////////// + +//////////////////////////////// + typedef i32 Mac_Object_Kind; enum{ MacObjectKind_ERROR = 0, @@ -110,6 +121,11 @@ struct Mac_Vars { String_Const_u8 binary_path; + NSWindow* window; + Opengl_View* view; + + mach_timebase_info_data_t timebase_info; + Node free_mac_objects; Node timer_objects; }; @@ -133,7 +149,7 @@ mac_to_object(Plat_Handle handle){ return(result); } -function +function Mac_Object* mac_alloc_object(Mac_Object_Kind kind){ Mac_Object *result = 0; @@ -170,7 +186,7 @@ mac_alloc_object(Mac_Object_Kind kind){ return(result); } -function +function void mac_free_object(Mac_Object *object){ if (object->node.next != 0){ dll_remove(&object->node); @@ -185,9 +201,6 @@ mac_free_object(Mac_Object *object){ //////////////////////////////// -@interface App_Delegate : NSObject -@end - @implementation App_Delegate - (void)applicationDidFinishLaunching:(id)sender{ } @@ -209,6 +222,28 @@ mac_free_object(Mac_Object *object){ } @end +@implementation Opengl_View +- (id)init { + self = [super init]; + return self; +} + +- (void)prepareOpenGL { + [super prepareOpenGL]; + [[self openGLContext] makeCurrentContext]; +} + +- (void)reshape { + [super reshape]; + + NSRect bounds = [self bounds]; + // [global_opengl_context makeCurrentContext]; + // [global_opengl_context update]; + // glViewport(0, 0, (GLsizei)bounds.size.width, + // (GLsizei)bounds.size.height); +} +@end + //////////////////////////////// int @@ -265,6 +300,9 @@ main(int arg_count, char **args){ dll_init_sentinel(&mac_vars.free_mac_objects); dll_init_sentinel(&mac_vars.timer_objects); + + // NOTE(yuval): Get the timebase info + mach_timebase_info(&mac_vars.timebase_info); #endif #if 0 diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index b98780d8..35e406e0 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -385,8 +385,8 @@ function system_wake_up_timer_release_sig(){ Mac_Object *object = (Mac_Object*)mac_to_object(handle); if (object->kind == MacObjectKind_Timer){ - if ((object->timer != nil) && [object->timer isValid]) { - [object->timer invalidate]; + if ((object->timer.timer != nil) && [object->timer.timer isValid]) { + [object->timer.timer invalidate]; mac_free_object(object); } } @@ -397,7 +397,7 @@ system_wake_up_timer_set_sig(){ Mac_Object *object = (Mac_Object*)mac_to_object(handle); if (object->kind == MacObjectKind_Timer){ f64 time_seconds = ((f64)time_milliseconds / 1000.0); - object->timer = [NSTimer scheduledTimerWithTimeInterval: time_seconds + object->timer.timer = [NSTimer scheduledTimerWithTimeInterval: time_seconds target: mac_vars.view selector: @selector(requestDisplay) userInfo: nil repeats:NO]; From 1d6be32462892f6a7dd5b3db28332232e2a7dd81 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Mon, 30 Dec 2019 03:21:21 +0200 Subject: [PATCH 036/128] Setup window and basic opengl view. --- platform_mac/mac_4ed.mm | 70 +++++++++++++++++++++---------- platform_mac/mac_4ed_functions.mm | 4 +- 2 files changed, 50 insertions(+), 24 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index aa0790b7..15d73837 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -84,10 +84,11 @@ //////////////////////////////// -@interface App_Delegate : NSObject +@interface AppDelegate : NSObject @end -@interface Opengl_View : NSOpenGLView +@interface OpenGLView : NSOpenGLView +- (void)requestDisplay; @end //////////////////////////////// @@ -122,7 +123,7 @@ struct Mac_Vars { String_Const_u8 binary_path; NSWindow* window; - Opengl_View* view; + OpenGLView* view; mach_timebase_info_data_t timebase_info; @@ -201,7 +202,7 @@ mac_free_object(Mac_Object *object){ //////////////////////////////// -@implementation App_Delegate +@implementation AppDelegate - (void)applicationDidFinishLaunching:(id)sender{ } @@ -222,18 +223,18 @@ mac_free_object(Mac_Object *object){ } @end -@implementation Opengl_View +@implementation OpenGLView - (id)init { self = [super init]; return self; } -- (void)prepareOpenGL { +- (void)prepareOpenGL{ [super prepareOpenGL]; [[self openGLContext] makeCurrentContext]; } -- (void)reshape { +- (void)reshape{ [super reshape]; NSRect bounds = [self bounds]; @@ -242,35 +243,63 @@ mac_free_object(Mac_Object *object){ // glViewport(0, 0, (GLsizei)bounds.size.width, // (GLsizei)bounds.size.height); } + +- (void)requestDisplay{ + printf("Display Requested\n"); +} @end //////////////////////////////// int main(int arg_count, char **args){ + block_zero_struct(&mac_vars); + @autoreleasepool{ // NOTE(yuval): Create NSApplication & Delegate NSApplication *app = [NSApplication sharedApplication]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - App_Delegate *app_delegate = [[App_Delegate alloc] init]; + AppDelegate *app_delegate = [[AppDelegate alloc] init]; [app setDelegate:app_delegate]; - [NSApp finishLaunching]; + // NOTE(yuval): Create NSWindow + float w = 1280.0f; + float h = 720.0f; + NSRect screen_rect = [[NSScreen mainScreen] frame]; + NSRect initial_frame = NSMakeRect((screen_rect.size.width - w) * 0.5f, (screen_rect.size.height - h) * 0.5f, w, h); + + NSWindow* window = [[NSWindow alloc] initWithContentRect: initial_frame + styleMask: NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable + backing: NSBackingStoreBuffered + defer: NO]; + + [window setBackgroundColor: NSColor.blackColor]; + [window setDelegate: app_delegate]; + [window setTitle: @"4coder"]; + [window makeKeyAndOrderFront: nil]; + + // NOTE(yuval): Create OpenGLView + NSView* content_view = [window contentView]; + + // TODO(yuval): Finish view setup! + mac_vars.view = [[OpenGLView alloc] init]; + [mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [mac_vars.view setFrame:[content_view bounds]]; + + [content_view addSubview:mac_vars.view]; + + dll_init_sentinel(&mac_vars.free_mac_objects); + dll_init_sentinel(&mac_vars.timer_objects); Arena test_arena = make_arena_malloc(); - File_List list = system_get_file_list(&test_arena, - string_u8_litexpr("/Users/yuvaldolev/Desktop")); + Plat_Handle timer = system_wake_up_timer_create(); + system_wake_up_timer_set(timer, 5000); + + // NOTE(yuval): Start the app's run loop + [NSApp run]; + - for (u32 index = 0; index < list.count; ++index) { - File_Info* info = list.infos[index]; - - printf("File_Info{file_name:'%.*s', " - "attributes:{size:%llu, last_write_time:%llu, flags:{IsDirectory:%d}}}\n", - (i32)info->file_name.size, info->file_name.str, - info->attributes.size, info->attributes.last_write_time, - ((info->attributes.flags & FileAttribute_IsDirectory) != 0)); - } #if 0 // NOTE(yuval): Context Setup @@ -279,7 +308,6 @@ main(int arg_count, char **args){ get_base_allocator_system(), get_base_allocator_system()); - block_zero_struct(&mac_vars); mac_vars.tctx = &_tctx; API_VTable_system system_vtable = {}; diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 35e406e0..f191f69d 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -563,9 +563,7 @@ system_condition_variable_free_sig(){ function system_memory_allocate_sig(){ - void* result = 0; - - NotImplemented; + void* result = malloc(size); return(result); } From 912174e7250add2af2293f953305a729260b0eac Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 31 Dec 2019 00:04:33 +0200 Subject: [PATCH 037/128] Experimentations with redrawing the opengl view. --- platform_mac/mac_4ed.mm | 84 ++++++++++++++++++++++++++----- platform_mac/mac_4ed_functions.mm | 8 +-- 2 files changed, 76 insertions(+), 16 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 15d73837..db01684c 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -244,8 +244,42 @@ mac_free_object(Mac_Object *object){ // (GLsizei)bounds.size.height); } +- (void)drawRect:(NSRect)bounds{ + // [self getFrame]; + printf("Draw Rect!\n"); +} + +- (BOOL)acceptsFirstResponder{ + return YES; +} + +- (BOOL)becomeFirstResponder{ + return YES; +} + +- (BOOL)resignFirstResponder{ + return YES; +} + +- (void)keyDown:(NSEvent *)event{ + printf("Key Down!\n"); + [self requestDisplay]; +} + +- (void)mouseMoved:(NSEvent*)event{ + printf("Mouse Moved!\n"); + [self requestDisplay]; +} + +- (void)mouseDown:(NSEvent*)event{ + printf("Mouse Down!\n"); + [self requestDisplay]; +} + - (void)requestDisplay{ printf("Display Requested\n"); + + [self setNeedsDisplayInRect:[mac_vars.window frame]]; } @end @@ -269,25 +303,28 @@ main(int arg_count, char **args){ NSRect screen_rect = [[NSScreen mainScreen] frame]; NSRect initial_frame = NSMakeRect((screen_rect.size.width - w) * 0.5f, (screen_rect.size.height - h) * 0.5f, w, h); - NSWindow* window = [[NSWindow alloc] initWithContentRect: initial_frame - styleMask: NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable - backing: NSBackingStoreBuffered - defer: NO]; + u32 style_mask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable; - [window setBackgroundColor: NSColor.blackColor]; - [window setDelegate: app_delegate]; - [window setTitle: @"4coder"]; - [window makeKeyAndOrderFront: nil]; + mac_vars.window = [[NSWindow alloc] initWithContentRect:initial_frame + styleMask:style_mask + backing:NSBackingStoreBuffered + defer:NO]; + + [mac_vars.window setBackgroundColor:NSColor.blackColor]; + [mac_vars.window setDelegate:app_delegate]; + [mac_vars.window setTitle:@"4coder"]; + [mac_vars.window setAcceptsMouseMovedEvents:YES]; // NOTE(yuval): Create OpenGLView - NSView* content_view = [window contentView]; + NSView* content_view = [mac_vars.window contentView]; // TODO(yuval): Finish view setup! mac_vars.view = [[OpenGLView alloc] init]; - [mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [mac_vars.view setFrame:[content_view bounds]]; + [mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [content_view addSubview:mac_vars.view]; + [mac_vars.window makeKeyAndOrderFront:nil]; dll_init_sentinel(&mac_vars.free_mac_objects); dll_init_sentinel(&mac_vars.timer_objects); @@ -297,9 +334,32 @@ main(int arg_count, char **args){ system_wake_up_timer_set(timer, 5000); // NOTE(yuval): Start the app's run loop +#if 1 [NSApp run]; - - +#else + for (;;) { + u64 count = 0; + + NSEvent* event; + do { + event = [NSApp nextEventMatchingMask:NSEventMaskAny + untilDate:nil//[NSDate distantFuture] + inMode:NSDefaultRunLoopMode + dequeue:YES]; + + if (event != nil) { + // printf("Event: %lu\n", [event type]); + ++count; + } + + [NSApp sendEvent:event]; + } while (event != nil); + + if (count > 1) { + printf("Count: %llu\n", count); + } + } +#endif #if 0 // NOTE(yuval): Context Setup diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index f191f69d..f1938a76 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -397,10 +397,10 @@ system_wake_up_timer_set_sig(){ Mac_Object *object = (Mac_Object*)mac_to_object(handle); if (object->kind == MacObjectKind_Timer){ f64 time_seconds = ((f64)time_milliseconds / 1000.0); - object->timer.timer = [NSTimer scheduledTimerWithTimeInterval: time_seconds - target: mac_vars.view - selector: @selector(requestDisplay) - userInfo: nil repeats:NO]; + object->timer.timer = [NSTimer scheduledTimerWithTimeInterval:time_seconds + target:mac_vars.view + selector:@selector(requestDisplay) + userInfo:nil repeats:NO]; } } From aff4a783e04cc01b3146e9413738395dc5b45457 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 31 Dec 2019 01:56:12 +0200 Subject: [PATCH 038/128] Implemented system_get_screen_scale_factor. --- platform_mac/mac_4ed.mm | 16 +++++++++++++--- platform_mac/mac_4ed_functions.mm | 15 +++++++++------ 2 files changed, 22 insertions(+), 9 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index db01684c..22947925 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -124,6 +124,7 @@ struct Mac_Vars { NSWindow* window; OpenGLView* view; + f32 screen_scale_factor; mach_timebase_info_data_t timebase_info; @@ -266,10 +267,12 @@ mac_free_object(Mac_Object *object){ [self requestDisplay]; } +/* - (void)mouseMoved:(NSEvent*)event{ printf("Mouse Moved!\n"); [self requestDisplay]; } +*/ - (void)mouseDown:(NSEvent*)event{ printf("Mouse Down!\n"); @@ -329,9 +332,16 @@ main(int arg_count, char **args){ dll_init_sentinel(&mac_vars.free_mac_objects); dll_init_sentinel(&mac_vars.timer_objects); - Arena test_arena = make_arena_malloc(); - Plat_Handle timer = system_wake_up_timer_create(); - system_wake_up_timer_set(timer, 5000); + // NOTE(yuval): Screen scale factor calculation + { + NSScreen* screen = [NSScreen mainScreen]; + NSDictionary* desc = [screen deviceDescription]; + NSSize size = [[desc valueForKey:NSDeviceResolution] sizeValue]; + f32 max_dpi = Max(size.width, size.height); + mac_vars.screen_scale_factor = (max_dpi / 72.0f); + } + + printf("screen scale factor: %f\n", system_get_screen_scale_factor()); // NOTE(yuval): Start the app's run loop #if 1 diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index f1938a76..1da70846 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -406,12 +406,18 @@ system_wake_up_timer_set_sig(){ function system_signal_step_sig(){ - NotImplemented; + [mac_vars.view requestDisplay]; } function system_sleep_sig(){ - NotImplemented; + u64 nanoseconds = (microseconds * Thousand(1)); + u64 abs_sleep_time = (u64)((f64)nanoseconds * + (f64)mac_vars.timebase_info.denom / + (f64)mac_vars.timebase_info.numer); + + u64 now = mach_absolute_time(); + mach_wait_until(now + abs_sleep_time); } //////////////////////////////// @@ -464,10 +470,7 @@ system_open_color_picker_sig(){ function system_get_screen_scale_factor_sig(){ - f32 result = 0.0f; - - NotImplemented; - + f32 result = mac_vars.screen_scale_factor; return(result); } From cbdc6a14e0fe2dc28b2ece5e5c237e901061cf80 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 31 Dec 2019 03:22:50 +0200 Subject: [PATCH 039/128] Implemented all system thread handling functions. --- platform_mac/mac_4ed.mm | 15 ++++++- platform_mac/mac_4ed_functions.mm | 73 ++++++++++++++++++++++--------- 2 files changed, 67 insertions(+), 21 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 22947925..f21d9d46 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -145,9 +145,22 @@ mac_to_plat_handle(Mac_Object *object){ return(result); } + +function inline System_Thread +mac_to_system_thread(Mac_Object *object){ + System_Thread result = *(System_Thread*)(&object); + return(result); +} + function inline Mac_Object* mac_to_object(Plat_Handle handle){ - Mac_Object* result = *(Mac_Object**)(&handle); + Mac_Object *result = *(Mac_Object**)(&handle); + return(result); +} + +function inline Mac_Object* +mac_to_object(System_Thread thread){ + Mac_Object *result = *(Mac_Object**)(&thread); return(result); } diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 1da70846..d099c2d8 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -383,7 +383,7 @@ system_wake_up_timer_create_sig(){ function system_wake_up_timer_release_sig(){ - Mac_Object *object = (Mac_Object*)mac_to_object(handle); + Mac_Object *object = mac_to_object(handle); if (object->kind == MacObjectKind_Timer){ if ((object->timer.timer != nil) && [object->timer.timer isValid]) { [object->timer.timer invalidate]; @@ -394,7 +394,7 @@ system_wake_up_timer_release_sig(){ function system_wake_up_timer_set_sig(){ - Mac_Object *object = (Mac_Object*)mac_to_object(handle); + Mac_Object *object = mac_to_object(handle); if (object->kind == MacObjectKind_Timer){ f64 time_seconds = ((f64)time_milliseconds / 1000.0); object->timer.timer = [NSTimer scheduledTimerWithTimeInterval:time_seconds @@ -476,44 +476,67 @@ system_get_screen_scale_factor_sig(){ //////////////////////////////// +function void* +mac_thread_wrapper(void *ptr){ + Mac_Object *object = (Mac_Object*)ptr; + Thread_Function *proc = object->thread.proc; + void *object_ptr = object->thread.ptr; + + pthread_mutex_lock(&mac_vars.thread_launch_mutex); + { + mac_vars.waiting_for_launch = false; + pthread_cond_signal(&mac_vars.thread_launch_cv); + } + pthread_mutex_unlock(&mac_vars.thread_launch_mutex); + + proc(object_ptr); + + return(0); +} + function system_thread_launch_sig(){ - System_Thread result = {}; + Mac_Object *object = mac_alloc_object(MacObjectKind_Thread); + object->thread.proc = proc; + object->thread.ptr = ptr; - NotImplemented; + pthread_mutex_lock(&mac_vars.thread_launch_mutex); + { + mac_vars.waiting_for_launch = true; + pthread_create(&object->thread.thread, 0, mac_thread_wrapper, object); + + while (mac_vars.waiting_for_launch){ + pthread_cond_wait(&mac_vars.thread_launch_cv, &mac_vars.thread_launch_mutex); + } + } + pthread_mutex_unlock(&mac_vars.thread_launch_mutex); + System_Thread result = mac_to_system_thread(object); return(result); } function system_thread_join_sig(){ - NotImplemented; + Mac_Object *object = mac_to_object(thread); + if (object->kind == MacObjectKind_Thread){ + pthread_join(object->thread.thread, 0); + } } function system_thread_free_sig(){ - NotImplemented; + Mac_Object* object = mac_to_object(thread); + if (object->kind == MacObjectKind_Thread){ + mac_free_object(object); + } } function system_thread_get_id_sig(){ - i32 result = 0; - - NotImplemented; - + i32 result = (i32)pthread_getthreadid_np(); return(result); } -function -system_acquire_global_frame_mutex_sig(){ - NotImplemented; -} - -function -system_release_global_frame_mutex_sig(){ - NotImplemented; -} - function system_mutex_make_sig(){ System_Mutex result = {}; @@ -538,6 +561,16 @@ system_mutex_free_sig(){ NotImplemented; } +function +system_acquire_global_frame_mutex_sig(){ + NotImplemented; +} + +function +system_release_global_frame_mutex_sig(){ + NotImplemented; +} + function system_condition_variable_make_sig(){ System_Condition_Variable result = {}; From 9263a4a59f1a5b89eac71056017a5228e3a17454 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 31 Dec 2019 13:14:05 +0200 Subject: [PATCH 040/128] Implemented all system mutex and cv handling functions. --- platform_mac/mac_4ed.mm | 55 +++++++++++++------------- platform_mac/mac_4ed_functions.mm | 66 +++++++++++++++++++++---------- 2 files changed, 74 insertions(+), 47 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index f21d9d46..0de68e77 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -58,6 +58,7 @@ #include // NOTE(yuval): Used for dlopen, dlclose, dlsym #include // NOTE(yuval): Used for errno #include // NOTE(yuval): Used for open +#include // NOTE(yuval): Used for threads, mutexes, cvs #include // NOTE(yuval): Used for getcwd, read, write, getpid #include // NOTE(yuval): Used for stat #include // NOTE(yuval): Used for struct stat, pid_t @@ -109,9 +110,16 @@ struct Mac_Object{ Mac_Object_Kind kind; union{ + NSTimer* timer; + struct{ - NSTimer* timer; - } timer; + pthread_t thread; + Thread_Function *proc; + void *ptr; + } thread; + + pthread_mutex_t mutex; + pthread_cond_t cv; }; }; @@ -130,6 +138,12 @@ struct Mac_Vars { Node free_mac_objects; Node timer_objects; + + pthread_mutex_t thread_launch_mutex; + pthread_cond_t thread_launch_cv; + b32 waiting_for_launch; + + System_Mutex global_frame_mutex; }; //////////////////////////////// @@ -139,31 +153,6 @@ global Render_Target target; //////////////////////////////// -function inline Plat_Handle -mac_to_plat_handle(Mac_Object *object){ - Plat_Handle result = *(Plat_Handle*)(&object); - return(result); -} - - -function inline System_Thread -mac_to_system_thread(Mac_Object *object){ - System_Thread result = *(System_Thread*)(&object); - return(result); -} - -function inline Mac_Object* -mac_to_object(Plat_Handle handle){ - Mac_Object *result = *(Mac_Object**)(&handle); - return(result); -} - -function inline Mac_Object* -mac_to_object(System_Thread thread){ - Mac_Object *result = *(Mac_Object**)(&thread); - return(result); -} - function Mac_Object* mac_alloc_object(Mac_Object_Kind kind){ Mac_Object *result = 0; @@ -210,6 +199,18 @@ mac_free_object(Mac_Object *object){ dll_insert(&mac_vars.free_mac_objects, &object->node); } +function inline Plat_Handle +mac_to_plat_handle(Mac_Object *object){ + Plat_Handle result = *(Plat_Handle*)(&object); + return(result); +} + +function inline Mac_Object* +mac_to_object(Plat_Handle handle){ + Mac_Object *result = *(Mac_Object**)(&handle); + return(result); +} + //////////////////////////////// #import "mac_4ed_functions.mm" diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index d099c2d8..082d3094 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -375,7 +375,7 @@ system_wake_up_timer_create_sig(){ Mac_Object *object = mac_alloc_object(MacObjectKind_Timer); dll_insert(&mac_vars.timer_objects, &object->node); - object->timer.timer = nil; + object->timer = nil; Plat_Handle result = mac_to_plat_handle(object); return(result); @@ -385,8 +385,8 @@ function system_wake_up_timer_release_sig(){ Mac_Object *object = mac_to_object(handle); if (object->kind == MacObjectKind_Timer){ - if ((object->timer.timer != nil) && [object->timer.timer isValid]) { - [object->timer.timer invalidate]; + if ((object->timer != nil) && [object->timer isValid]) { + [object->timer invalidate]; mac_free_object(object); } } @@ -397,7 +397,7 @@ system_wake_up_timer_set_sig(){ Mac_Object *object = mac_to_object(handle); if (object->kind == MacObjectKind_Timer){ f64 time_seconds = ((f64)time_milliseconds / 1000.0); - object->timer.timer = [NSTimer scheduledTimerWithTimeInterval:time_seconds + object->timer = [NSTimer scheduledTimerWithTimeInterval:time_seconds target:mac_vars.view selector:@selector(requestDisplay) userInfo:nil repeats:NO]; @@ -511,7 +511,7 @@ system_thread_launch_sig(){ } pthread_mutex_unlock(&mac_vars.thread_launch_mutex); - System_Thread result = mac_to_system_thread(object); + System_Thread result = mac_to_plat_handle(object); return(result); } @@ -533,66 +533,92 @@ system_thread_free_sig(){ function system_thread_get_id_sig(){ - i32 result = (i32)pthread_getthreadid_np(); + pthread_t id = pthread_self(); + i32 result = *(i32*)(&id); return(result); } function system_mutex_make_sig(){ - System_Mutex result = {}; - - NotImplemented; + Mac_Object *object = mac_alloc_object(MacObjectKind_Mutex); + pthread_mutex_init(&object->mutex, 0); + System_Mutex result = mac_to_plat_handle(object); return(result); } function system_mutex_acquire_sig(){ - NotImplemented; + Mac_Object *object = mac_to_object(mutex); + if (object->kind == MacObjectKind_Mutex){ + pthread_mutex_lock(&object->mutex); + } } function system_mutex_release_sig(){ - NotImplemented; + Mac_Object *object = mac_to_object(mutex); + if (object->kind == MacObjectKind_Mutex){ + pthread_mutex_unlock(&object->mutex); + } } function system_mutex_free_sig(){ - NotImplemented; + Mac_Object *object = mac_to_object(mutex); + if (object->kind == MacObjectKind_Mutex){ + pthread_mutex_destroy(&object->mutex); + mac_free_object(object); + } } function system_acquire_global_frame_mutex_sig(){ - NotImplemented; + if (tctx->kind == ThreadKind_AsyncTasks){ + system_mutex_acquire(mac_vars.global_frame_mutex); + } } function system_release_global_frame_mutex_sig(){ - NotImplemented; + if (tctx->kind == ThreadKind_AsyncTasks){ + system_mutex_release(mac_vars.global_frame_mutex); + } } function system_condition_variable_make_sig(){ - System_Condition_Variable result = {}; - - NotImplemented; + Mac_Object *object = mac_alloc_object(MacObjectKind_CV); + pthread_cond_init(&object->cv, 0); + System_Condition_Variable result = mac_to_plat_handle(object); return(result); } function system_condition_variable_wait_sig(){ - NotImplemented; + Mac_Object *object_cv = mac_to_object(cv); + Mac_Object *object_mutex = mac_to_object(mutex); + if ((object_cv->kind == MacObjectKind_CV) && (object_mutex->kind == MacObjectKind_Mutex)){ + pthread_cond_wait(&object_cv->cv, &object_mutex->mutex); + } } function system_condition_variable_signal_sig(){ - NotImplemented; + Mac_Object *object = mac_to_object(cv); + if (object->kind == MacObjectKind_CV){ + pthread_cond_signal(&object->cv); + } } function system_condition_variable_free_sig(){ - NotImplemented; + Mac_Object *object = mac_to_object(cv); + if (object->kind == MacObjectKind_CV){ + pthread_cond_destroy(&object->cv); + mac_free_object(object); + } } //////////////////////////////// From 8c7600ba09ad637e810d81b5cab7f3a89b245d77 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 31 Dec 2019 23:36:12 +0200 Subject: [PATCH 041/128] Implemented all system memory handling functions. --- platform_mac/mac_4ed.mm | 15 ++-- platform_mac/mac_4ed_functions.mm | 121 ++++++++++++++++++++++++++++-- 2 files changed, 120 insertions(+), 16 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 0de68e77..ed67979f 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -60,6 +60,7 @@ #include // NOTE(yuval): Used for open #include // NOTE(yuval): Used for threads, mutexes, cvs #include // NOTE(yuval): Used for getcwd, read, write, getpid +#include // NOTE(yuval): Used for mmap, munmap, mprotect #include // NOTE(yuval): Used for stat #include // NOTE(yuval): Used for struct stat, pid_t @@ -359,29 +360,23 @@ main(int arg_count, char **args){ // NOTE(yuval): Start the app's run loop #if 1 + printf("Running using NSApp run\n"); [NSApp run]; #else + printf("Running using manual event loop\n"); + for (;;) { u64 count = 0; NSEvent* event; do { event = [NSApp nextEventMatchingMask:NSEventMaskAny - untilDate:nil//[NSDate distantFuture] + untilDate:[NSDate distantFuture] inMode:NSDefaultRunLoopMode dequeue:YES]; - if (event != nil) { - // printf("Event: %lu\n", [event type]); - ++count; - } - [NSApp sendEvent:event]; } while (event != nil); - - if (count > 1) { - printf("Count: %llu\n", count); - } } #endif diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 082d3094..4ef30169 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -623,32 +623,141 @@ system_condition_variable_free_sig(){ //////////////////////////////// +struct Memory_Annotation_Tracker_Node{ + Memory_Annotation_Tracker_Node *next; + Memory_Annotation_Tracker_Node *prev; + String_Const_u8 location; + u64 size; +}; + +struct Memory_Annotation_Tracker{ + Memory_Annotation_Tracker_Node *first; + Memory_Annotation_Tracker_Node *last; + i32 count; +}; + +global Memory_Annotation_Tracker memory_tracker = {}; +global pthread_mutex_t memory_tracker_mutex; + +global_const u64 ALLOCATION_SIZE_ADJUSTMENT = 64; + +function void* +mac_memory_allocate_extended(void *base, u64 size, String_Const_u8 location){ + u64 adjusted_size = size + ALLOCATION_SIZE_ADJUSTMENT; + void *memory = mmap(base, adjusted_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + + Memory_Annotation_Tracker_Node *node = (Memory_Annotation_Tracker_Node*)memory; + + pthread_mutex_lock(&memory_tracker_mutex); + { + zdll_push_back(memory_tracker.first, memory_tracker.last, node); + memory_tracker.count += 1; + } + pthread_mutex_unlock(&memory_tracker_mutex); + + node->location = location; + node->size = size; + + void* result = (node + 1); + return(result); +} + +function void +mac_memory_free_extended(void *ptr){ + Memory_Annotation_Tracker_Node *node = (Memory_Annotation_Tracker_Node*)ptr; + node -= 1; + + pthread_mutex_lock(&memory_tracker_mutex); + { + zdll_remove(memory_tracker.first, memory_tracker.last, node); + memory_tracker.count -= 1; + } + pthread_mutex_unlock(&memory_tracker_mutex); + + munmap(node, node->size + ALLOCATION_SIZE_ADJUSTMENT); +} + function system_memory_allocate_sig(){ - void* result = malloc(size); - + void* result = mac_memory_allocate_extended(0, size, location); return(result); } function system_memory_set_protection_sig(){ - b32 result = false; + b32 result = true; - NotImplemented; + int protect = 0; + switch (flags & 0x7){ + case 0: + { + protect = PROT_NONE; + } break; + + case MemProtect_Read: + { + protect = PROT_READ; + } break; + + case MemProtect_Write: + case MemProtect_Read | MemProtect_Write: + { + protect = PROT_READ | PROT_WRITE; + } break; + + case MemProtect_Execute: + { + protect = PROT_EXEC; + } break; + + case MemProtect_Execute | MemProtect_Read: + { + protect = PROT_READ | PROT_EXEC; + } break; + + // NOTE(inso): some W^X protection things might be unhappy about this one + case MemProtect_Execute | MemProtect_Write: + case MemProtect_Execute | MemProtect_Write | MemProtect_Read: + { + protect = PROT_READ | PROT_WRITE | PROT_EXEC; + } break; + } + + Memory_Annotation_Tracker_Node *node = (Memory_Annotation_Tracker_Node*)ptr; + node -= 1; + + if(mprotect(node, size, protect) == -1){ + result = false; + } return(result); } function system_memory_free_sig(){ - NotImplemented; + mac_memory_free_extended(ptr); } function system_memory_annotation_sig(){ Memory_Annotation result = {}; - NotImplemented; + pthread_mutex_lock(&memory_tracker_mutex); + { + for (Memory_Annotation_Tracker_Node *node = memory_tracker.first; + node != 0; + node = node->next){ + Memory_Annotation_Node *r_node = push_array(arena, Memory_Annotation_Node, 1); + sll_queue_push(result.first, result.last, r_node); + result.count += 1; + + r_node->location = node->location; + r_node->address = node + 1; + r_node->size = node->size; + } + + } + pthread_mutex_unlock(&memory_tracker_mutex); return(result); } From 26fd4cd230396d3b1e8081638dce1ce22094da46 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Wed, 1 Jan 2020 00:07:21 +0200 Subject: [PATCH 042/128] Finished most of the system api functions (a few will be implemented later). --- platform_mac/mac_4ed.mm | 38 +++++++++++++++++++++++++++++++ platform_mac/mac_4ed_functions.mm | 21 +++++++---------- 2 files changed, 46 insertions(+), 13 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index ed67979f..90463bc6 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -71,6 +71,37 @@ #define global static #define external extern "C" +struct Control_Keys{ + b8 l_ctrl; + b8 r_ctrl; + b8 l_alt; + b8 r_alt; +}; + +struct Mac_Input_Chunk_Transient{ + Input_List event_list; + b8 mouse_l_press; + b8 mouse_l_release; + b8 mouse_r_press; + b8 mouse_r_release; + b8 out_of_window; + i8 mouse_wheel; + b8 trying_to_kill; +}; + +struct Mac_Input_Chunk_Persistent{ + Vec2_i32 mouse; + Control_Keys controls; + Input_Modifier_Set_Fixed modifiers; + b8 mouse_l; + b8 mouse_r; +}; + +struct Mac_Input_Chunk{ + Mac_Input_Chunk_Transient trans; + Mac_Input_Chunk_Persistent pers; +}; + //////////////////////////////// #define SLASH '/' @@ -128,6 +159,13 @@ struct Mac_Vars { Thread_Context *tctx; Arena* frame_arena; + Mac_Input_Chunk input_chunk; + + b8 full_screen; + b8 do_toggle; + + i32 cursor_show; + i32 prev_cursor_show; String_Const_u8 binary_path; diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 4ef30169..bae982e8 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -766,33 +766,28 @@ system_memory_annotation_sig(){ function system_show_mouse_cursor_sig(){ - NotImplemented; + mac_vars.cursor_show = show; } function system_set_fullscreen_sig(){ - b32 result = false; + // NOTE(yuval): Read comment in system_set_fullscreen_sig in win32_4ed.cpp + mac_vars.do_toggle = (mac_vars.full_screen != full_screen); - NotImplemented; - - return(result); + b32 success = true; + return(success); } function system_is_fullscreen_sig(){ - b32 result = false; - - NotImplemented; - + // NOTE(yuval): Read comment in system_is_fullscreen_sig in win32_4ed.cpp + b32 result = (mac_vars.full_screen != mac_vars.do_toggle); return(result); } function system_get_keyboard_modifiers_sig(){ - Input_Modifier_Set result = {}; - - NotImplemented; - + Input_Modifier_Set result = copy_modifier_set(arena, &mac_vars.input_chunk.pers.modifiers); return(result); } From 0cfb8b319ce15d2184d9149685a350a4c13edc27 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Wed, 1 Jan 2020 04:16:39 +0200 Subject: [PATCH 043/128] Work on setting up the opengl view. --- platform_mac/mac_4ed.mm | 78 +++++++++++++++++++++++++++++++++++------ 1 file changed, 67 insertions(+), 11 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 90463bc6..33b75381 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -121,6 +121,7 @@ struct Mac_Input_Chunk{ @end @interface OpenGLView : NSOpenGLView +- (void)init_opengl; - (void)requestDisplay; @end @@ -156,6 +157,8 @@ struct Mac_Object{ }; struct Mac_Vars { + b32 gl_is_initialized; + Thread_Context *tctx; Arena* frame_arena; @@ -266,26 +269,39 @@ mac_to_object(Plat_Handle handle){ - (void)applicationWillTerminate:(NSNotification*)notification{ } - -- (NSSize)windowWillResize:(NSWindow*)window toSize:(NSSize)frame_size{ - // frame_size.height = ((f32)frame_size.width / global_aspect_ratio); - return frame_size; -} - -- (void)windowWillClose:(id)sender{ - // global_running = false; -} @end @implementation OpenGLView -- (id)init { +- (id)init{ self = [super init]; + if (self == nil){ + return nil; + } + + [self init_opengl]; + return self; } -- (void)prepareOpenGL{ +- (void)dealloc +{ + [super dealloc]; +} + +- (void)prepareOpenGL +{ [super prepareOpenGL]; + [[self openGLContext] makeCurrentContext]; + + // NOTE(yuval): Setup vsync + GLint swapInt = 1; + [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; +} + +- (void)awakeFromNib +{ + [self init_gl]; } - (void)reshape{ @@ -332,6 +348,44 @@ mac_to_object(Plat_Handle handle){ [self requestDisplay]; } +- (void)init_opengl{ + if (mac_vars.gl_is_initialized){ + return; + } + + [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + + // NOTE(yuval): Setup OpenGL + NSOpenGLPixelFormatAttribute opengl_attrs[] = { + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, + NSOpenGLPFAAccelerated, + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAColorSize, 32, + NSOpenGLPFAAlphaSize, 8, + NSOpenGLPFADepthSize, 24, + // NSOpenGLPFASampleBuffers, 1, + // NSOpenGLPFASamples, 16, + 0 + }; + + NSOpenGLPixelFormat *pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:opengl_attrs]; + if (pixel_format == nil){ + fprintf(stderr, "Error creating OpenGLPixelFormat\n"); + exit(1); + } + + NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nil]; + + [self setPixelFormat:format]; + [self setOpenGLContext:context]; + + [context makeCurrentContext]; + + [pixel_format release]; + + mac_vars.gl_is_initialized = true; +} + - (void)requestDisplay{ printf("Display Requested\n"); @@ -345,6 +399,8 @@ int main(int arg_count, char **args){ block_zero_struct(&mac_vars); + mac_vars.gl_is_initialized = false; + @autoreleasepool{ // NOTE(yuval): Create NSApplication & Delegate NSApplication *app = [NSApplication sharedApplication]; From debdda8184e937a47501a2d59cf3239f684f5526 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Wed, 1 Jan 2020 18:38:48 +0200 Subject: [PATCH 044/128] Started working on getting the opengl renderer to work but encountered a few errors on the way... --- bin/4ed_build.cpp | 1 + opengl/4ed_opengl_defines.h | 4 +- platform_mac/mac_4ed.mm | 312 +++++++++++++++++++++++++++--------- 3 files changed, 243 insertions(+), 74 deletions(-) diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index 146169fb..03a9a1b2 100644 --- a/bin/4ed_build.cpp +++ b/bin/4ed_build.cpp @@ -467,6 +467,7 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha fm_finish_build_line(&line); Temp_Dir temp = fm_pushdir(out_path); + // systemf("clang++ %s -E -o %s", line.build_options, "4ed.i"); systemf("clang++ %s -o %s", line.build_options, out_file); fm_popdir(temp); } diff --git a/opengl/4ed_opengl_defines.h b/opengl/4ed_opengl_defines.h index be20f65e..558b1e98 100644 --- a/opengl/4ed_opengl_defines.h +++ b/opengl/4ed_opengl_defines.h @@ -12,7 +12,9 @@ #if !defined(FRED_OPENGL_DEFINES_H) #define FRED_OPENGL_DEFINES_H -#include +// NOTE(yuval): This file does not exist on MacOS. +// opengl has been included from the platform layer +// #include #define GL_TEXTURE_MAX_LEVEL 0x813D diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 33b75381..148108d0 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -54,6 +54,10 @@ #include // NOTE(yuval): Used for proc_pidpath #include // NOTE(yuval): Used for mach_absolute_time, mach_timebase_info, mach_timebase_info_data_t +#define GL_GLEXT_LEGACY +#include +#include + #include // NOTE(yuval): Used for opendir, readdir #include // NOTE(yuval): Used for dlopen, dlclose, dlsym #include // NOTE(yuval): Used for errno @@ -71,6 +75,9 @@ #define global static #define external extern "C" +// NOTE(yuval): This is a hack to fix the CALL_CONVENTION not being defined problem in 4coder_base_types.h +#define CALL_CONVENTION + struct Control_Keys{ b8 l_ctrl; b8 r_ctrl; @@ -172,6 +179,8 @@ struct Mac_Vars { String_Const_u8 binary_path; + String_Const_u8 clipboard_contents; + NSWindow* window; OpenGLView* view; f32 screen_scale_factor; @@ -186,6 +195,8 @@ struct Mac_Vars { b32 waiting_for_launch; System_Mutex global_frame_mutex; + + Log_Function *log_string; }; //////////////////////////////// @@ -255,10 +266,39 @@ mac_to_object(Plat_Handle handle){ //////////////////////////////// +#include "4ed_font_provider_freetype.h" +#include "4ed_font_provider_freetype.h" + +#include "opengl/4ed_opengl_render.cpp" + #import "mac_4ed_functions.mm" //////////////////////////////// +function void +mac_error_box(char *msg, b32 shutdown = true){ + NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + + NSString *title_string = @"Error"; + NSString *message_string = [NSString stringWithUTF8String:msg]; + [alert setMessageText:title_string]; + [alert setInformativeText:message_string]; + + [alert runModal]; + + if (shutdown){ + exit(1); + } +} + +function b32 +mac_file_can_be_made(u8* filename){ + b32 result = access((char*)filename, W_OK) == 0; + return(result); +} + +//////////////////////////////// + @implementation AppDelegate - (void)applicationDidFinishLaunching:(id)sender{ } @@ -301,17 +341,14 @@ mac_to_object(Plat_Handle handle){ - (void)awakeFromNib { - [self init_gl]; + [self init_opengl]; } - (void)reshape{ [super reshape]; NSRect bounds = [self bounds]; - // [global_opengl_context makeCurrentContext]; - // [global_opengl_context update]; - // glViewport(0, 0, (GLsizei)bounds.size.width, - // (GLsizei)bounds.size.height); + // mac_resize(rect.size.width, rect.size.height); } - (void)drawRect:(NSRect)bounds{ @@ -319,6 +356,11 @@ mac_to_object(Plat_Handle handle){ printf("Draw Rect!\n"); } +- (BOOL)windowShouldClose:(NSWindow*)sender{ + // osx_try_to_close(); + return(NO); +} + - (BOOL)acceptsFirstResponder{ return YES; } @@ -332,19 +374,14 @@ mac_to_object(Plat_Handle handle){ } - (void)keyDown:(NSEvent *)event{ - printf("Key Down!\n"); [self requestDisplay]; } -/* - (void)mouseMoved:(NSEvent*)event{ - printf("Mouse Moved!\n"); [self requestDisplay]; } -*/ - (void)mouseDown:(NSEvent*)event{ - printf("Mouse Down!\n"); [self requestDisplay]; } @@ -374,9 +411,9 @@ mac_to_object(Plat_Handle handle){ exit(1); } - NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:format shareContext:nil]; + NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:nil]; - [self setPixelFormat:format]; + [self setPixelFormat:pixel_format]; [self setOpenGLContext:context]; [context makeCurrentContext]; @@ -397,50 +434,47 @@ mac_to_object(Plat_Handle handle){ int main(int arg_count, char **args){ - block_zero_struct(&mac_vars); - - mac_vars.gl_is_initialized = false; - @autoreleasepool{ // NOTE(yuval): Create NSApplication & Delegate - NSApplication *app = [NSApplication sharedApplication]; + NSApplication *ns_app = [NSApplication sharedApplication]; [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; AppDelegate *app_delegate = [[AppDelegate alloc] init]; - [app setDelegate:app_delegate]; + [ns_app setDelegate:app_delegate]; - // NOTE(yuval): Create NSWindow - float w = 1280.0f; - float h = 720.0f; - NSRect screen_rect = [[NSScreen mainScreen] frame]; - NSRect initial_frame = NSMakeRect((screen_rect.size.width - w) * 0.5f, (screen_rect.size.height - h) * 0.5f, w, h); + pthread_mutex_init(&memory_tracker_mutex, 0); - u32 style_mask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable; + // NOTE(yuval): Context Setup + Thread_Context _tctx = {}; + thread_ctx_init(&_tctx, ThreadKind_Main, + get_base_allocator_system(), + get_base_allocator_system()); - mac_vars.window = [[NSWindow alloc] initWithContentRect:initial_frame - styleMask:style_mask - backing:NSBackingStoreBuffered - defer:NO]; + block_zero_struct(&mac_vars); + mac_vars.tctx = &_tctx; - [mac_vars.window setBackgroundColor:NSColor.blackColor]; - [mac_vars.window setDelegate:app_delegate]; - [mac_vars.window setTitle:@"4coder"]; - [mac_vars.window setAcceptsMouseMovedEvents:YES]; + API_VTable_system system_vtable = {}; + system_api_fill_vtable(&system_vtable); - // NOTE(yuval): Create OpenGLView - NSView* content_view = [mac_vars.window contentView]; + API_VTable_graphics graphics_vtable = {}; + graphics_api_fill_vtable(&graphics_vtable); - // TODO(yuval): Finish view setup! - mac_vars.view = [[OpenGLView alloc] init]; - [mac_vars.view setFrame:[content_view bounds]]; - [mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + API_VTable_font font_vtable = {}; + font_api_fill_vtable(&font_vtable); - [content_view addSubview:mac_vars.view]; - [mac_vars.window makeKeyAndOrderFront:nil]; + // NOTE(yuval): Memory + mac_vars.frame_arena = reserve_arena(mac_vars.tctx); + target.arena = make_arena_system(KB(256)); + + mac_vars.cursor_show = MouseCursorShow_Always; + mac_vars.prev_cursor_show = MouseCursorShow_Always; dll_init_sentinel(&mac_vars.free_mac_objects); dll_init_sentinel(&mac_vars.timer_objects); + pthread_mutex_init(&mac_vars.thread_launch_mutex, 0); + pthread_cond_init(&mac_vars.thread_launch_cv, 0); + // NOTE(yuval): Screen scale factor calculation { NSScreen* screen = [NSScreen mainScreen]; @@ -450,7 +484,171 @@ main(int arg_count, char **args){ mac_vars.screen_scale_factor = (max_dpi / 72.0f); } - printf("screen scale factor: %f\n", system_get_screen_scale_factor()); + // NOTE(yuval): Load core + System_Library core_library = {}; + App_Functions app = {}; + { + App_Get_Functions *get_funcs = 0; + Scratch_Block scratch(mac_vars.tctx, Scratch_Share); + Path_Search_List search_list = {}; + search_list_add_system_path(scratch, &search_list, SystemPath_Binary); + + String_Const_u8 core_path = get_full_path(scratch, &search_list, SCu8("4ed_app.so")); + if (system_load_library(scratch, core_path, &core_library)){ + get_funcs = (App_Get_Functions*)system_get_proc(core_library, "app_get_functions"); + if (get_funcs != 0){ + app = get_funcs(); + } + else{ + char msg[] = "Failed to get application code from '4ed_app.so'."; + mac_error_box(msg); + } + } + else{ + char msg[] = "Could not load '4ed_app.so'. This file should be in the same directory as the main '4ed' executable."; + mac_error_box(msg); + } + } + + // NOTE(yuval): Send api vtables to core + app.load_vtables(&system_vtable, &font_vtable, &graphics_vtable); + mac_vars.log_string = app.get_logger(); + + // NOTE(yuval): Init & command line parameters + Plat_Settings plat_settings = {}; + void *base_ptr = 0; + { + Scratch_Block scratch(mac_vars.tctx, Scratch_Share); + String_Const_u8 curdir = system_get_path(scratch, SystemPath_CurrentDirectory); + curdir = string_mod_replace_character(curdir, '\\', '/'); + char **files = 0; + i32 *file_count = 0; + base_ptr = app.read_command_line(mac_vars.tctx, curdir, &plat_settings, &files, &file_count, arg_count, args); + { + i32 end = *file_count; + i32 i = 0, j = 0; + for (; i < end; ++i){ + if (mac_file_can_be_made((u8*)files[i])){ + files[j] = files[i]; + ++j; + } + } + *file_count = j; + } + } + + // NOTE(yuval): Load custom layer + System_Library custom_library = {}; + Custom_API custom = {}; + { + char custom_not_found_msg[] = "Did not find a library for the custom layer."; + char custom_fail_version_msg[] = "Failed to load custom code due to missing version information or a version mismatch. Try rebuilding with buildsuper."; + char custom_fail_init_apis[] = "Failed to load custom code due to missing 'init_apis' symbol. Try rebuilding with buildsuper"; + + Scratch_Block scratch(mac_vars.tctx, Scratch_Share); + String_Const_u8 default_file_name = string_u8_litexpr("custom_4coder.so"); + Path_Search_List search_list = {}; + search_list_add_system_path(scratch, &search_list, SystemPath_CurrentDirectory); + search_list_add_system_path(scratch, &search_list, SystemPath_Binary); + String_Const_u8 custom_file_names[2] = {}; + i32 custom_file_count = 1; + if (plat_settings.custom_dll != 0){ + custom_file_names[0] = SCu8(plat_settings.custom_dll); + if (!plat_settings.custom_dll_is_strict){ + custom_file_names[1] = default_file_name; + custom_file_count += 1; + } + } + else{ + custom_file_names[0] = default_file_name; + } + String_Const_u8 custom_file_name = {}; + for (i32 i = 0; i < custom_file_count; i += 1){ + custom_file_name = get_full_path(scratch, &search_list, custom_file_names[i]); + if (custom_file_name.size > 0){ + break; + } + } + b32 has_library = false; + if (custom_file_name.size > 0){ + if (system_load_library(scratch, custom_file_name, &custom_library)){ + has_library = true; + } + } + + if (!has_library){ + mac_error_box(custom_not_found_msg); + } + custom.get_version = (_Get_Version_Type*)system_get_proc(custom_library, "get_version"); + if (custom.get_version == 0 || custom.get_version(MAJOR, MINOR, PATCH) == 0){ + mac_error_box(custom_fail_version_msg); + } + custom.init_apis = (_Init_APIs_Type*)system_get_proc(custom_library, "init_apis"); + if (custom.init_apis == 0){ + mac_error_box(custom_fail_init_apis); + } + } + + // + // Window and GL View Initialization + // + + // NOTE(yuval): Create NSWindow + float w; + float h; + if (plat_settings.set_window_size){ + w = (float)plat_settings.window_w; + h = (float)plat_settings.window_h; + } else{ + w = 800.0f; + h = 800.0f; + } + + NSRect screen_rect = [[NSScreen mainScreen] frame]; + NSRect initial_frame = NSMakeRect((screen_rect.size.width - w) * 0.5f, (screen_rect.size.height - h) * 0.5f, w, h); + + u32 style_mask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable; + + mac_vars.window = [[NSWindow alloc] initWithContentRect:initial_frame + styleMask:style_mask + backing:NSBackingStoreBuffered + defer:NO]; + + [mac_vars.window setMinSize:NSMakeSize(100, 100)]; + [mac_vars.window setBackgroundColor:NSColor.blackColor]; + [mac_vars.window setDelegate:app_delegate]; + [mac_vars.window setTitle:@"4coder"]; + [mac_vars.window setAcceptsMouseMovedEvents:YES]; + + // NOTE(yuval): Create OpenGLView + NSView* content_view = [mac_vars.window contentView]; + + mac_vars.gl_is_initialized = false; + + mac_vars.view = [[OpenGLView alloc] init]; + [mac_vars.view setFrame:[content_view bounds]]; + [mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + + // NOTE(yuval): Display opengl view and window + [content_view addSubview:mac_vars.view]; + [mac_vars.window makeKeyAndOrderFront:nil]; + + // + // TODO(yuval): Misc System Initializations + + // NOTE(yuval): Get the timebase info + mach_timebase_info(&mac_vars.timebase_info); + + // + // App init + // + + { + Scratch_Block scratch(mac_vars.tctx, Scratch_Share); + String_Const_u8 curdir = system_get_path(scratch, SystemPath_CurrentDirectory); + curdir = string_mod_replace_character(curdir, '\\', '/'); + app.init(mac_vars.tctx, &target, base_ptr, mac_vars.clipboard_contents, curdir, custom); + } // NOTE(yuval): Start the app's run loop #if 1 @@ -474,38 +672,6 @@ main(int arg_count, char **args){ } #endif -#if 0 - // NOTE(yuval): Context Setup - Thread_Context _tctx = {}; - thread_ctx_init(&_tctx, ThreadKind_Main, - get_base_allocator_system(), - get_base_allocator_system()); - - mac_vars.tctx = &_tctx; - - API_VTable_system system_vtable = {}; - system_api_fill_vtable(&system_vtable); - - API_VTable_graphics graphics_vtable = {}; - graphics_api_fill_vtable(&graphics_vtable); - - API_VTable_font font_vtable = {}; - font_api_fill_vtable(&font_vtable); - - // NOTE(yuval): Memory - mac_vars.frame_arena = reserve_arena(mac_vars.tctx); - target.arena = make_arena_system(KB(256)); - - mac_vars.cursor_show = MouseCursorShow_Always; - mac_vars.prev_cursor_show = MouseCursorShow_Always; - - dll_init_sentinel(&mac_vars.free_mac_objects); - dll_init_sentinel(&mac_vars.timer_objects); - - // NOTE(yuval): Get the timebase info - mach_timebase_info(&mac_vars.timebase_info); -#endif - #if 0 // NOTE(yuval): Application Core Update Application_Step_Result result = {}; From 6f827801e5132abaaa29d6db204d76844708b13b Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 2 Jan 2020 01:13:32 +0200 Subject: [PATCH 045/128] macOS platform layer initialization and very basic update functions. The 4coder beta has been rendered successfully for the first time on macOS! --- custom/4coder_base_types.h | 5 +- .../Resources/DWARF/metadata_generator | Bin 136740 -> 136740 bytes opengl/4ed_opengl_defines.h | 7 -- opengl/4ed_opengl_render.cpp | 19 ++-- platform_mac/mac_4ed.mm | 95 +++++++++++------- platform_mac/mac_4ed_functions.mm | 20 ++-- platform_mac/mac_4ed_opengl.mm | 23 +++++ platform_mac/mac_4ed_opengl_funcs.h | 17 ++++ 8 files changed, 120 insertions(+), 66 deletions(-) create mode 100644 platform_mac/mac_4ed_opengl.mm create mode 100644 platform_mac/mac_4ed_opengl_funcs.h diff --git a/custom/4coder_base_types.h b/custom/4coder_base_types.h index 20517f7f..6811fe58 100644 --- a/custom/4coder_base_types.h +++ b/custom/4coder_base_types.h @@ -144,12 +144,13 @@ #endif #endif +// NOTE(yuval): Changed this so that CALL_CONVENTION will be defined for all platforms #if OS_WINDOWS # if ARCH_32BIT # define CALL_CONVENTION __stdcall -# else -# define CALL_CONVENTION # endif +#else +# define CALL_CONVENTION #endif #if defined(JUST_GUESS_INTS) diff --git a/custom/metadata_generator.dSYM/Contents/Resources/DWARF/metadata_generator b/custom/metadata_generator.dSYM/Contents/Resources/DWARF/metadata_generator index 133e453d1c931a6805c0b6e109b54aada975ee7d..815fd87182819f59da407a6ef16a81b7f4629669 100644 GIT binary patch delta 1990 zcmY+Fdr;I>6vyx7cYgR2cDb7)gp3Re{h`iSP#H@r3e7YPGsPp3G?C%qLJnAimXuL0 zr9%(2hlM{IA7v6+B8Y>os6D1J>@{gGUd|8#W;r=I{o_(2yZ3Wm_uO;O zz1!AdwRKocJ#rx3{Sn0;5<=X-j}F@t>2itew$m~&bcQN2q&M1EZnz6)KwDvmIMc$Q z>VcbCRA~sc5tAT8l_7-MgxN)o6|h5@vPynnC;8-D*%k8n=w2siyC9+v2wHtczMg`eH^iMPlvblc_*&|D3 zQQcY6)%er{(Pvnx0Qz$beORd&Fvii&(R@`2Sbr1XbIMRP0PXVyWu@c-=qvIz&k`bm zO%h&5PYOr=^_1N1&XMtVMC!ho)V07-q&&%C&O0KJ+6-!A$pw29e!*`i6~g3`bD6`? zdFg3VtB~MK&a07x`wFN23|VnzA_ny{jN)1MEVlM1ActWy>MmmT;uFhd*+?!k6%!AY zlRgeV8&yP>y^?~KF!`8V<|3FTQhh|-*28qFTQ;C>Q^)lluby^m3rdLiu8L%C`vU;&3aPI;<59N`2N zscyhstO-%QIunMI^pxrY@b;;fnx-%KX?oGA${^I#PBGkZ6Fh&3%zQs0xy;{zS@g1V zpLFmR?BZWYbq?FG3yCApy}BK{hz96(dj;=GH0r0})zHWH$iAq8A85MYek74H$c67G z@7wX{A@0IS(ZHmLJ5HorWvf9)B+~u?eaC$=6#D*NxiCM;OZvsscPACeO}&w6_M9EE zIQXWaMv{f-Tmzq0L%8#JveQ7zcrdtEFxrOj0c}ISxBB_ph08M)>Mg?(YF?%gr`UQo zRJQ^2-u3|Q1pLIBy@0y`6u@tvf$U>~T=*Q8Z8KbEAtoLwb=J8b8d@E>P8rs5nU&h8 z#xc6a_wkWPqqW*-gEp#ljQ(Jwx=5pS+GtCr2%>pM4RFNA`$xa4SA~!_8acY z)zA+(DGWF%=yDDs1z7{#kdwktM0JKEQ@Hs56h?FkejmRJCk-VNgwW4kFMPU@n1)k^ vr3!sww$q}g4UakjmA(vTLhrZA;V79G+PX`Y8M4G4+bu82{LtAwvSQPJn!iU% delta 2006 zcmY+Fe@vBC7{|}yeO`QpdpS1-44I6JZKaz9o5m$Xp{*60@}s~~F!_xWYoRlWs4iwB zi)^LA>r!VXVkSSN$g7mAm0`0Vx=bKih)A(qF4sSQFJipF!p7We@ zJG-sUZmVTLj-3(_(41S-;{H`2G>a2L*jw%iagriDQ@ z0AFBHg(1{anD`kg4Ixw$WyVs|)P$EM!w?{{yxA4vM}G=?ARovllIs^Q$_gf9@pM8pg-vg5rQQ ztcei3D^sj%A*hxu(z+3%Lo&zuI|T2@ITpcNM>r^z6$5DGaOw7uWirpdjZ_J+i$yP@ z4r?*Fz_6Vx;WEoH_0mRCwU{V36Y(I#vw=9}ESqB`n8Dm9hB-ol6fek=BwLz(gN(DO^qg^zvoM z<#Y(v*+bc~Dq+C9fi^I?kkJt_LL_svV}TXRWvfg&Z0N_CN?ei67rsM+X9C=$~g-BqN zgg4QX!jXR+CJ&0f35wcc#gbcWznxXU{b>&Sog)&dt)NbpoVO=(WW4`EP$5h{NtZbW zotK(Ol_KG}oaeJ7+|#_3X0l?;L=5Uz7{#;hIc)VWKn}z6I0q56AD?J0(^hhsshD_Z zJ?Z1gVx#i#W2hj%B}_gxm$?+CiS%Sx9UEXe(>Zq zBGnJLhczdtL46W}06n9I0K9!VNiDM%evo!JRT+hv4pS6&;1thykeQ!_NG|gaU?#od z+%FycRqWzFNOcZv*oDLq=-zz|yNCqn_S=bfCKC12@Ot3W`{YnW!9|+wzaL1XjB?>G zk@rA6dWyR;C>jomxC2GXHMSaYL}J0epzpa)Mgte`my7e0Qb@m``Yw5q+{~MqYR}sx zi~YL|HJ&U)Z#8`0GK4#iC+!AW#)HBAC}W2qe83JvzrXr9v~ihcLhUguq3+BOVvw!h zhU#vB-rHWl62N8F>;v2jpc?%48^}J&&xOxnS)1W93o-Ffsk6>XXs9fFopo5pWmamV zTF2-*-_N>mqYc_ZC9lR-GTiQy9B7g`af_Sw4Oj0)~!=p|>r7y$BfurqmEJ8jQcxjJ(%#bDa - #define GL_TEXTURE_MAX_LEVEL 0x813D #define GL_MULTISAMPLE 0x809D @@ -226,9 +222,6 @@ typedef void GL_Debug_Function(GLenum src, void *user_data); typedef GL_Debug_Function *GLDEBUGPROC; -#define GL_FUNC(N,R,P) typedef R (CALL_CONVENTION N##_Function)P; N##_Function *N = 0; -#include "4ed_opengl_funcs.h" - #endif // BOTTOM diff --git a/opengl/4ed_opengl_render.cpp b/opengl/4ed_opengl_render.cpp index 3e83095d..e3413ae0 100644 --- a/opengl/4ed_opengl_render.cpp +++ b/opengl/4ed_opengl_render.cpp @@ -9,8 +9,6 @@ // TOP -#include "4ed_opengl_defines.h" - internal void gl__bind_texture(Render_Target *t, i32 texid){ if (t->bound_texture != texid){ @@ -225,11 +223,16 @@ gl_render(Render_Target *t){ #if !SHIP_MODE glEnable(GL_DEBUG_OUTPUT); glEnable(GL_DEBUG_OUTPUT_SYNCHRONOUS); - glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, 0, false); - glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, 0, false); - glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, 0, true); - glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, 0, true); - glDebugMessageCallback(gl__error_callback, 0); + if (glDebugMessageControl){ + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_NOTIFICATION, 0, 0, false); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_LOW, 0, 0, false); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_MEDIUM, 0, 0, true); + glDebugMessageControl(GL_DONT_CARE, GL_DONT_CARE, GL_DEBUG_SEVERITY_HIGH, 0, 0, true); + } + + if (glDebugMessageCallback){ + glDebugMessageCallback(gl__error_callback, 0); + } #endif //////////////////////////////// @@ -256,7 +259,7 @@ gl_render(Render_Target *t){ //////////////////////////////// - { + { t->fallback_texture_id = gl__get_texture(V3i32(2, 2, 1), TextureKind_Mono); u8 white_block[] = { 0xFF, 0xFF, 0xFF, 0xFF, }; gl__fill_texture(TextureKind_Mono, 0, V3i32(0, 0, 0), V3i32(2, 2, 1), white_block); diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 148108d0..3886cdcd 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -54,10 +54,6 @@ #include // NOTE(yuval): Used for proc_pidpath #include // NOTE(yuval): Used for mach_absolute_time, mach_timebase_info, mach_timebase_info_data_t -#define GL_GLEXT_LEGACY -#include -#include - #include // NOTE(yuval): Used for opendir, readdir #include // NOTE(yuval): Used for dlopen, dlclose, dlsym #include // NOTE(yuval): Used for errno @@ -75,9 +71,6 @@ #define global static #define external extern "C" -// NOTE(yuval): This is a hack to fix the CALL_CONVENTION not being defined problem in 4coder_base_types.h -#define CALL_CONVENTION - struct Control_Keys{ b8 l_ctrl; b8 r_ctrl; @@ -168,9 +161,12 @@ struct Mac_Vars { Thread_Context *tctx; - Arena* frame_arena; + Arena *frame_arena; Mac_Input_Chunk input_chunk; + void *base_ptr; + u64 timer_start; + b8 full_screen; b8 do_toggle; @@ -181,8 +177,8 @@ struct Mac_Vars { String_Const_u8 clipboard_contents; - NSWindow* window; - OpenGLView* view; + NSWindow *window; + OpenGLView *view; f32 screen_scale_factor; mach_timebase_info_data_t timebase_info; @@ -203,6 +199,7 @@ struct Mac_Vars { global Mac_Vars mac_vars; global Render_Target target; +global App_Functions app; //////////////////////////////// @@ -266,10 +263,12 @@ mac_to_object(Plat_Handle handle){ //////////////////////////////// -#include "4ed_font_provider_freetype.h" -#include "4ed_font_provider_freetype.h" +#include +#include +#import "mac_4ed_opengl.mm" -#include "opengl/4ed_opengl_render.cpp" +#include "4ed_font_provider_freetype.h" +#include "4ed_font_provider_freetype.cpp" #import "mac_4ed_functions.mm" @@ -297,6 +296,14 @@ mac_file_can_be_made(u8* filename){ return(result); } +function void +mac_resize(float width, float height){ + if ((width > 0.0f) && (height > 0.0f)){ + target.width = width; + target.height = height; + } +} + //////////////////////////////// @implementation AppDelegate @@ -323,13 +330,11 @@ mac_file_can_be_made(u8* filename){ return self; } -- (void)dealloc -{ +- (void)dealloc{ [super dealloc]; } -- (void)prepareOpenGL -{ +- (void)prepareOpenGL{ [super prepareOpenGL]; [[self openGLContext] makeCurrentContext]; @@ -339,8 +344,7 @@ mac_file_can_be_made(u8* filename){ [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; } -- (void)awakeFromNib -{ +- (void)awakeFromNib{ [self init_opengl]; } @@ -352,8 +356,23 @@ mac_file_can_be_made(u8* filename){ } - (void)drawRect:(NSRect)bounds{ - // [self getFrame]; - printf("Draw Rect!\n"); + // NOTE(yuval): Read comment in win32_4ed.cpp's main loop + system_mutex_release(mac_vars.global_frame_mutex); + + Application_Step_Input input = {}; + + // NOTE(yuval): Application Core Update + Application_Step_Result result = {}; + if (app.step != 0){ + result = app.step(mac_vars.tctx, &target, mac_vars.base_ptr, &input); + } + + CGLLockContext([[self openGLContext] CGLContextObj]); + [[self openGLContext] makeCurrentContext]; + gl_render(&target); + [[self openGLContext] flushBuffer]; + CGLUnlockContext([[self openGLContext] CGLContextObj]); + } - (BOOL)windowShouldClose:(NSWindow*)sender{ @@ -424,8 +443,6 @@ mac_file_can_be_made(u8* filename){ } - (void)requestDisplay{ - printf("Display Requested\n"); - [self setNeedsDisplayInRect:[mac_vars.window frame]]; } @end @@ -486,7 +503,6 @@ main(int arg_count, char **args){ // NOTE(yuval): Load core System_Library core_library = {}; - App_Functions app = {}; { App_Get_Functions *get_funcs = 0; Scratch_Block scratch(mac_vars.tctx, Scratch_Share); @@ -516,14 +532,14 @@ main(int arg_count, char **args){ // NOTE(yuval): Init & command line parameters Plat_Settings plat_settings = {}; - void *base_ptr = 0; + mac_vars.base_ptr = 0; { Scratch_Block scratch(mac_vars.tctx, Scratch_Share); String_Const_u8 curdir = system_get_path(scratch, SystemPath_CurrentDirectory); curdir = string_mod_replace_character(curdir, '\\', '/'); char **files = 0; i32 *file_count = 0; - base_ptr = app.read_command_line(mac_vars.tctx, curdir, &plat_settings, &files, &file_count, arg_count, args); + mac_vars.base_ptr = app.read_command_line(mac_vars.tctx, curdir, &plat_settings, &files, &file_count, arg_count, args); { i32 end = *file_count; i32 i = 0, j = 0; @@ -593,6 +609,9 @@ main(int arg_count, char **args){ // Window and GL View Initialization // + // NOTE(yuval): Load OpenGL functions + mac_gl_load_functions(); + // NOTE(yuval): Create NSWindow float w; float h; @@ -601,9 +620,11 @@ main(int arg_count, char **args){ h = (float)plat_settings.window_h; } else{ w = 800.0f; - h = 800.0f; + h = 600.0f; } + mac_resize(w, h); + NSRect screen_rect = [[NSScreen mainScreen] frame]; NSRect initial_frame = NSMakeRect((screen_rect.size.width - w) * 0.5f, (screen_rect.size.height - h) * 0.5f, w, h); @@ -635,6 +656,7 @@ main(int arg_count, char **args){ // // TODO(yuval): Misc System Initializations + // // NOTE(yuval): Get the timebase info mach_timebase_info(&mac_vars.timebase_info); @@ -647,9 +669,18 @@ main(int arg_count, char **args){ Scratch_Block scratch(mac_vars.tctx, Scratch_Share); String_Const_u8 curdir = system_get_path(scratch, SystemPath_CurrentDirectory); curdir = string_mod_replace_character(curdir, '\\', '/'); - app.init(mac_vars.tctx, &target, base_ptr, mac_vars.clipboard_contents, curdir, custom); + app.init(mac_vars.tctx, &target, mac_vars.base_ptr, mac_vars.clipboard_contents, curdir, custom); } + // + // Main loop + // + + mac_vars.global_frame_mutex = system_mutex_make(); + system_mutex_acquire(mac_vars.global_frame_mutex); + + mac_vars.timer_start = system_now_time(); + // NOTE(yuval): Start the app's run loop #if 1 printf("Running using NSApp run\n"); @@ -671,13 +702,5 @@ main(int arg_count, char **args){ } while (event != nil); } #endif - -#if 0 - // NOTE(yuval): Application Core Update - Application_Step_Result result = {}; - if (app.step != 0){ - result = app.step(mac_vars.tctx, &target, base_ptr, &input); - } -#endif } } \ No newline at end of file diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index bae982e8..46543bab 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -406,7 +406,10 @@ system_wake_up_timer_set_sig(){ function system_signal_step_sig(){ - [mac_vars.view requestDisplay]; + [NSTimer scheduledTimerWithTimeInterval:0.0 + target:mac_vars.view + selector:@selector(requestDisplay) + userInfo:nil repeats:NO]; } function @@ -801,19 +804,13 @@ system_get_keyboard_modifiers_sig(){ function graphics_get_texture_sig(){ - u32 result = 0; - - NotImplemented; - + u32 result = gl__get_texture(dim, texture_kind); return(result); } function graphics_fill_texture_sig(){ - b32 result = false; - - NotImplemented; - + b32 result = gl__fill_texture(texture_kind, texture, p, dim, data); return(result); } @@ -827,10 +824,7 @@ graphics_fill_texture_sig(){ function font_make_face_sig(){ - Face* result = 0; - - NotImplemented; - + Face* result = ft__font_make_face(arena, description, scale_factor); return(result); } diff --git a/platform_mac/mac_4ed_opengl.mm b/platform_mac/mac_4ed_opengl.mm new file mode 100644 index 00000000..b87492ba --- /dev/null +++ b/platform_mac/mac_4ed_opengl.mm @@ -0,0 +1,23 @@ +/* Mac OpenGL layer for 4coder */ + +#include "opengl/4ed_opengl_defines.h" + +#define GL_FUNC(N,R,P) typedef R (CALL_CONVENTION N##_Function)P; N##_Function *N = 0; +#include "mac_4ed_opengl_funcs.h" + +#include "opengl/4ed_opengl_render.cpp" + +function b32 +mac_gl_load_functions(){ + b32 result = true; + + // NOTE(yuval): Open the gl dynamic library + void* gl_image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY); + + // NOTE(yuval): Load gl functions +#define GL_FUNC(f,R,P) Stmnt((f) = (f##_Function*)dlsym(gl_image, #f); \ + (result) &= (f != 0);); +#include "mac_4ed_opengl_funcs.h" + + return result; +} diff --git a/platform_mac/mac_4ed_opengl_funcs.h b/platform_mac/mac_4ed_opengl_funcs.h new file mode 100644 index 00000000..649847f9 --- /dev/null +++ b/platform_mac/mac_4ed_opengl_funcs.h @@ -0,0 +1,17 @@ +/* Mac OpenGL functions for 4coder */ + +// TOP +/* Usage: +#define GL_FUNC(N,R,P) ~~~~ +#include "4ed_opengl_funcs.h" +*/ + +GL_FUNC(glDebugMessageControl, void, (GLenum source, GLenum type, GLenum severity, GLsizei count, const GLuint *ids, GLboolean enabled)) +GL_FUNC(glDebugMessageCallback, void, (GLDEBUGPROC callback, const void *userParam)) + +GL_FUNC(glGenVertexArrays, void, (GLsizei n, GLuint *arrays)) +GL_FUNC(glBindVertexArray, void, (GLuint array)) + +GL_FUNC(glVertexAttribIPointer, void, (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer)) + +#undef GL_FUNC From 0420a9a852a396394b75fb8ce15c420941ecaae3 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 2 Jan 2020 02:21:33 +0200 Subject: [PATCH 046/128] Implemented resizing (seems to be really slow for some reason...) and basic input (actually we're not receiving user input yet, but the we're sending the app an empty input struct with only a few parameters being updated like if it's the first step.). --- platform_mac/mac_4ed.mm | 51 +++++++++++++++++++++++++++++++++++------ 1 file changed, 44 insertions(+), 7 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 3886cdcd..85e988d6 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -1,5 +1,8 @@ /* Mac Objective-C layer for 4coder */ +#define FPS 60 +#define frame_useconds (1000000 / FPS) + #include "4coder_base_types.h" #include "4coder_version.h" #include "4coder_events.h" @@ -164,11 +167,9 @@ struct Mac_Vars { Arena *frame_arena; Mac_Input_Chunk input_chunk; - void *base_ptr; - u64 timer_start; - b8 full_screen; b8 do_toggle; + b32 send_exit_signal; i32 cursor_show; i32 prev_cursor_show; @@ -182,6 +183,9 @@ struct Mac_Vars { f32 screen_scale_factor; mach_timebase_info_data_t timebase_info; + b32 first; + void *base_ptr; + u64 timer_start; Node free_mac_objects; Node timer_objects; @@ -302,6 +306,8 @@ mac_resize(float width, float height){ target.width = width; target.height = height; } + + system_signal_step(0); } //////////////////////////////// @@ -352,15 +358,42 @@ mac_resize(float width, float height){ [super reshape]; NSRect bounds = [self bounds]; - // mac_resize(rect.size.width, rect.size.height); + mac_resize(bounds.size.width, bounds.size.height); } - (void)drawRect:(NSRect)bounds{ // NOTE(yuval): Read comment in win32_4ed.cpp's main loop system_mutex_release(mac_vars.global_frame_mutex); + // NOTE(yuval): Prepare the Frame Input + Mac_Input_Chunk input_chunk = mac_vars.input_chunk; Application_Step_Input input = {}; + input.first_step = mac_vars.first; + input.dt = frame_useconds / 1000000.0f; + input.events = input_chunk.trans.event_list; + + input.mouse.out_of_window = input_chunk.trans.out_of_window; + + input.mouse.l = input_chunk.pers.mouse_l; + input.mouse.press_l = input_chunk.trans.mouse_l_press; + input.mouse.release_l = input_chunk.trans.mouse_l_release; + + input.mouse.r = input_chunk.pers.mouse_r; + input.mouse.press_r = input_chunk.trans.mouse_r_press; + input.mouse.release_r = input_chunk.trans.mouse_r_release; + + input.mouse.wheel = input_chunk.trans.mouse_wheel; + input.mouse.p = input_chunk.pers.mouse; + + input.trying_to_kill = input_chunk.trans.trying_to_kill; + + // NOTE(yuval): See comment in win32_4ed.cpp's main loop + if (mac_vars.send_exit_signal){ + input.trying_to_kill = true; + mac_vars.send_exit_signal = false; + } + // NOTE(yuval): Application Core Update Application_Step_Result result = {}; if (app.step != 0){ @@ -373,10 +406,12 @@ mac_resize(float width, float height){ [[self openGLContext] flushBuffer]; CGLUnlockContext([[self openGLContext] CGLContextObj]); + mac_vars.first = false; } - (BOOL)windowShouldClose:(NSWindow*)sender{ // osx_try_to_close(); + printf("Window Closing!\n"); return(NO); } @@ -419,8 +454,8 @@ mac_resize(float width, float height){ NSOpenGLPFAColorSize, 32, NSOpenGLPFAAlphaSize, 8, NSOpenGLPFADepthSize, 24, - // NSOpenGLPFASampleBuffers, 1, - // NSOpenGLPFASamples, 16, + NSOpenGLPFASampleBuffers, 1, + NSOpenGLPFASamples, 16, 0 }; @@ -638,7 +673,7 @@ main(int arg_count, char **args){ [mac_vars.window setMinSize:NSMakeSize(100, 100)]; [mac_vars.window setBackgroundColor:NSColor.blackColor]; [mac_vars.window setDelegate:app_delegate]; - [mac_vars.window setTitle:@"4coder"]; + [mac_vars.window setTitle:@WINDOW_NAME]; [mac_vars.window setAcceptsMouseMovedEvents:YES]; // NOTE(yuval): Create OpenGLView @@ -676,6 +711,8 @@ main(int arg_count, char **args){ // Main loop // + mac_vars.first = true; + mac_vars.global_frame_mutex = system_mutex_make(); system_mutex_acquire(mac_vars.global_frame_mutex); From d1b9977a634fc3e085c579a46b8bf05b708446fd Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 2 Jan 2020 04:37:23 +0200 Subject: [PATCH 047/128] Started working on high-dpi support. --- platform_mac/mac_4ed.mm | 74 ++++++++++++++++++++++++++++++++--------- 1 file changed, 59 insertions(+), 15 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 85e988d6..7136ae2e 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -162,6 +162,8 @@ struct Mac_Object{ struct Mac_Vars { b32 gl_is_initialized; + i32 width, height; + Thread_Context *tctx; Arena *frame_arena; @@ -303,8 +305,14 @@ mac_file_can_be_made(u8* filename){ function void mac_resize(float width, float height){ if ((width > 0.0f) && (height > 0.0f)){ - target.width = width; - target.height = height; + NSSize coord_size = NSMakeSize(width, height); + NSSize backing_size = [mac_vars.view convertSizeToBacking:coord_size]; + + mac_vars.width = (i32)backing_size.width; + mac_vars.height = (i32)backing_size.height; + + target.width = (i32)backing_size.width; + target.height = (i32)backing_size.height; } system_signal_step(0); @@ -361,6 +369,20 @@ mac_resize(float width, float height){ mac_resize(bounds.size.width, bounds.size.height); } +- (void)viewDidChangeBackingProperties{ + + // NOTE(yuval): Screen scale factor calculation + NSScreen* screen = [NSScreen mainScreen]; + NSDictionary* desc = [screen deviceDescription]; + NSSize size = [[desc valueForKey:NSDeviceResolution] sizeValue]; + f32 max_dpi = Max(size.width, size.height); + mac_vars.screen_scale_factor = (max_dpi / 72.0f); + + NSRect frame = [screen frame]; + printf("Screen: w:%f h:%f\n", frame.size.width, frame.size.height); + printf("Scale Factor: %f\n\n", mac_vars.screen_scale_factor); +} + - (void)drawRect:(NSRect)bounds{ // NOTE(yuval): Read comment in win32_4ed.cpp's main loop system_mutex_release(mac_vars.global_frame_mutex); @@ -388,6 +410,8 @@ mac_resize(float width, float height){ input.trying_to_kill = input_chunk.trans.trying_to_kill; + block_zero_struct(&mac_vars.input_chunk.trans); + // NOTE(yuval): See comment in win32_4ed.cpp's main loop if (mac_vars.send_exit_signal){ input.trying_to_kill = true; @@ -407,6 +431,8 @@ mac_resize(float width, float height){ CGLUnlockContext([[self openGLContext] CGLContextObj]); mac_vars.first = false; + + linalloc_clear(mac_vars.frame_arena); } - (BOOL)windowShouldClose:(NSWindow*)sender{ @@ -428,15 +454,30 @@ mac_resize(float width, float height){ } - (void)keyDown:(NSEvent *)event{ - [self requestDisplay]; + NSString* characters = [event characters]; + if ([characters length] != 0) { + u32 character_code = [characters characterAtIndex:0]; + + // NOTE(yuval): Control characters generate character_codes < 32 + if (character_code > 31) { + // TODO(yuval): This is actually in utf16!!! + String_Const_u32 str_32 = SCu32(&character_code, 1); + String_Const_u8 str_8 = string_u8_from_string_u32(mac_vars.frame_arena, str_32).string; + + Input_Event event = {}; + event.kind = InputEventKind_TextInsert; + event.text.string = str_8; + push_input_event(mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list, &event); + + system_signal_step(0); + } + } } - (void)mouseMoved:(NSEvent*)event{ - [self requestDisplay]; } - (void)mouseDown:(NSEvent*)event{ - [self requestDisplay]; } - (void)init_opengl{ @@ -478,7 +519,9 @@ mac_resize(float width, float height){ } - (void)requestDisplay{ - [self setNeedsDisplayInRect:[mac_vars.window frame]]; + CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height); + NSRect rect = NSRectFromCGRect(cg_rect); + [self setNeedsDisplayInRect:rect]; } @end @@ -648,20 +691,18 @@ main(int arg_count, char **args){ mac_gl_load_functions(); // NOTE(yuval): Create NSWindow - float w; - float h; + i32 w; + i32 h; if (plat_settings.set_window_size){ - w = (float)plat_settings.window_w; - h = (float)plat_settings.window_h; + w = plat_settings.window_w; + h = plat_settings.window_h; } else{ - w = 800.0f; - h = 600.0f; + w = 800; + h = 600; } - mac_resize(w, h); - NSRect screen_rect = [[NSScreen mainScreen] frame]; - NSRect initial_frame = NSMakeRect((screen_rect.size.width - w) * 0.5f, (screen_rect.size.height - h) * 0.5f, w, h); + NSRect initial_frame = NSMakeRect((f32)(screen_rect.size.width - w) * 0.5f, (f32)(screen_rect.size.height - h) * 0.5f, w, h); u32 style_mask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable; @@ -684,11 +725,14 @@ main(int arg_count, char **args){ mac_vars.view = [[OpenGLView alloc] init]; [mac_vars.view setFrame:[content_view bounds]]; [mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [mac_vars.view setWantsBestResolutionOpenGLSurface:YES]; // NOTE(yuval): Display opengl view and window [content_view addSubview:mac_vars.view]; [mac_vars.window makeKeyAndOrderFront:nil]; + mac_resize(w, h); + // // TODO(yuval): Misc System Initializations // From 4e0549f270338cf57f8cbb733131f3cdc31a5580 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Fri, 3 Jan 2020 00:09:22 +0200 Subject: [PATCH 048/128] OpenGL renderer abstraction. The OpenGL renderer is now in its own view that's separate from the main 4coder view which handles all input and updates. Also added a Window Delegate which handled window events. --- platform_mac/mac_4ed.mm | 174 +++++++++++------------------- platform_mac/mac_4ed_functions.mm | 8 +- platform_mac/mac_4ed_opengl.mm | 127 ++++++++++++++++++++-- 3 files changed, 184 insertions(+), 125 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 7136ae2e..958d1399 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -120,11 +120,13 @@ struct Mac_Input_Chunk{ //////////////////////////////// -@interface AppDelegate : NSObject +@interface FCoderAppDelegate : NSObject @end -@interface OpenGLView : NSOpenGLView -- (void)init_opengl; +@interface FCoderWindowDelegate : NSObject +@end + +@interface FCoderView : NSView - (void)requestDisplay; @end @@ -160,8 +162,6 @@ struct Mac_Object{ }; struct Mac_Vars { - b32 gl_is_initialized; - i32 width, height; Thread_Context *tctx; @@ -181,7 +181,7 @@ struct Mac_Vars { String_Const_u8 clipboard_contents; NSWindow *window; - OpenGLView *view; + FCoderView *view; f32 screen_scale_factor; mach_timebase_info_data_t timebase_info; @@ -318,69 +318,61 @@ mac_resize(float width, float height){ system_signal_step(0); } +function inline void +mac_resize(NSWindow *window){ + NSRect bounds = [[window contentView] bounds]; + mac_resize(bounds.size.width, bounds.size.height); +} + //////////////////////////////// -@implementation AppDelegate +// TODO(yuval): mac_resize(bounds.size.width, bounds.size.height); + +@implementation FCoderAppDelegate - (void)applicationDidFinishLaunching:(id)sender{ } - (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)sender{ - return YES; + return(YES); } - (void)applicationWillTerminate:(NSNotification*)notification{ } @end -@implementation OpenGLView +@implementation FCoderWindowDelegate +- (BOOL)windowShouldClose:(id)sender { + mac_vars.input_chunk.trans.trying_to_kill = true; + system_signal_step(0); + + return(NO); +} + +- (void)windowDidResize:(NSNotification*)notification { + mac_resize(mac_vars.window); +} + +- (void)windowDidMiniaturize:(NSNotification*)notification { +} + +- (void)windowDidDeminiaturize:(NSNotification*)notification { +} +@end + +@implementation FCoderView - (id)init{ self = [super init]; - if (self == nil){ - return nil; - } - - [self init_opengl]; - - return self; + return(self); } - (void)dealloc{ [super dealloc]; } -- (void)prepareOpenGL{ - [super prepareOpenGL]; - - [[self openGLContext] makeCurrentContext]; - - // NOTE(yuval): Setup vsync - GLint swapInt = 1; - [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; -} - -- (void)awakeFromNib{ - [self init_opengl]; -} - -- (void)reshape{ - [super reshape]; - - NSRect bounds = [self bounds]; - mac_resize(bounds.size.width, bounds.size.height); -} - - (void)viewDidChangeBackingProperties{ - // NOTE(yuval): Screen scale factor calculation - NSScreen* screen = [NSScreen mainScreen]; - NSDictionary* desc = [screen deviceDescription]; - NSSize size = [[desc valueForKey:NSDeviceResolution] sizeValue]; - f32 max_dpi = Max(size.width, size.height); - mac_vars.screen_scale_factor = (max_dpi / 72.0f); - - NSRect frame = [screen frame]; - printf("Screen: w:%f h:%f\n", frame.size.width, frame.size.height); - printf("Scale Factor: %f\n\n", mac_vars.screen_scale_factor); + printf("Backing changed!\n"); + mac_resize(mac_vars.window); } - (void)drawRect:(NSRect)bounds{ @@ -424,33 +416,29 @@ mac_resize(float width, float height){ result = app.step(mac_vars.tctx, &target, mac_vars.base_ptr, &input); } - CGLLockContext([[self openGLContext] CGLContextObj]); - [[self openGLContext] makeCurrentContext]; - gl_render(&target); - [[self openGLContext] flushBuffer]; - CGLUnlockContext([[self openGLContext] CGLContextObj]); + // NOTE(yuval): Quit the app + if (result.perform_kill){ + printf("Terminating 4coder!\n"); + [NSApp terminate:nil]; + } + + mac_gl_render(&target); mac_vars.first = false; linalloc_clear(mac_vars.frame_arena); } -- (BOOL)windowShouldClose:(NSWindow*)sender{ - // osx_try_to_close(); - printf("Window Closing!\n"); - return(NO); -} - - (BOOL)acceptsFirstResponder{ - return YES; + return(YES); } - (BOOL)becomeFirstResponder{ - return YES; + return(YES); } - (BOOL)resignFirstResponder{ - return YES; + return(YES); } - (void)keyDown:(NSEvent *)event{ @@ -480,44 +468,6 @@ mac_resize(float width, float height){ - (void)mouseDown:(NSEvent*)event{ } -- (void)init_opengl{ - if (mac_vars.gl_is_initialized){ - return; - } - - [self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - - // NOTE(yuval): Setup OpenGL - NSOpenGLPixelFormatAttribute opengl_attrs[] = { - NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, - NSOpenGLPFAAccelerated, - NSOpenGLPFADoubleBuffer, - NSOpenGLPFAColorSize, 32, - NSOpenGLPFAAlphaSize, 8, - NSOpenGLPFADepthSize, 24, - NSOpenGLPFASampleBuffers, 1, - NSOpenGLPFASamples, 16, - 0 - }; - - NSOpenGLPixelFormat *pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:opengl_attrs]; - if (pixel_format == nil){ - fprintf(stderr, "Error creating OpenGLPixelFormat\n"); - exit(1); - } - - NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:nil]; - - [self setPixelFormat:pixel_format]; - [self setOpenGLContext:context]; - - [context makeCurrentContext]; - - [pixel_format release]; - - mac_vars.gl_is_initialized = true; -} - - (void)requestDisplay{ CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height); NSRect rect = NSRectFromCGRect(cg_rect); @@ -531,11 +481,13 @@ int main(int arg_count, char **args){ @autoreleasepool{ // NOTE(yuval): Create NSApplication & Delegate - NSApplication *ns_app = [NSApplication sharedApplication]; + [NSApplication sharedApplication]; + Assert(NSApp != nil); + [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - AppDelegate *app_delegate = [[AppDelegate alloc] init]; - [ns_app setDelegate:app_delegate]; + FCoderAppDelegate *app_delegate = [[FCoderAppDelegate alloc] init]; + [NSApp setDelegate:app_delegate]; pthread_mutex_init(&memory_tracker_mutex, 0); @@ -687,10 +639,7 @@ main(int arg_count, char **args){ // Window and GL View Initialization // - // NOTE(yuval): Load OpenGL functions - mac_gl_load_functions(); - - // NOTE(yuval): Create NSWindow + // NOTE(yuval): Create Window & Window Delegate i32 w; i32 h; if (plat_settings.set_window_size){ @@ -711,23 +660,24 @@ main(int arg_count, char **args){ backing:NSBackingStoreBuffered defer:NO]; + FCoderWindowDelegate *window_delegate = [[FCoderWindowDelegate alloc] init]; + [mac_vars.window setDelegate:window_delegate]; + [mac_vars.window setMinSize:NSMakeSize(100, 100)]; [mac_vars.window setBackgroundColor:NSColor.blackColor]; - [mac_vars.window setDelegate:app_delegate]; [mac_vars.window setTitle:@WINDOW_NAME]; [mac_vars.window setAcceptsMouseMovedEvents:YES]; - // NOTE(yuval): Create OpenGLView NSView* content_view = [mac_vars.window contentView]; - mac_vars.gl_is_initialized = false; + // NOTE(yuval): Initialize the renderer + mac_gl_init(mac_vars.window); - mac_vars.view = [[OpenGLView alloc] init]; + // NOTE(yuval): Create the 4coder view + mac_vars.view = [[FCoderView alloc] init]; [mac_vars.view setFrame:[content_view bounds]]; [mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - [mac_vars.view setWantsBestResolutionOpenGLSurface:YES]; - // NOTE(yuval): Display opengl view and window [content_view addSubview:mac_vars.view]; [mac_vars.window makeKeyAndOrderFront:nil]; diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 46543bab..aa3f619d 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -362,8 +362,8 @@ system_now_time_sig(){ // NOTE(yuval): Now time nanoseconds conversion f64 now_nano = (f64)((f64)now * - (f64)mac_vars.timebase_info.numer / - (f64)mac_vars.timebase_info.denom); + ((f64)mac_vars.timebase_info.numer / + (f64)mac_vars.timebase_info.denom)); // NOTE(yuval): Conversion to useconds u64 result = (u64)(now_nano * 1.0E-3); @@ -416,8 +416,8 @@ function system_sleep_sig(){ u64 nanoseconds = (microseconds * Thousand(1)); u64 abs_sleep_time = (u64)((f64)nanoseconds * - (f64)mac_vars.timebase_info.denom / - (f64)mac_vars.timebase_info.numer); + ((f64)mac_vars.timebase_info.denom / + (f64)mac_vars.timebase_info.numer)); u64 now = mach_absolute_time(); mach_wait_until(now + abs_sleep_time); diff --git a/platform_mac/mac_4ed_opengl.mm b/platform_mac/mac_4ed_opengl.mm index b87492ba..dd89c079 100644 --- a/platform_mac/mac_4ed_opengl.mm +++ b/platform_mac/mac_4ed_opengl.mm @@ -7,17 +7,126 @@ #include "opengl/4ed_opengl_render.cpp" -function b32 -mac_gl_load_functions(){ - b32 result = true; +@interface OpenGLView : NSOpenGLView +- (void)initGL; +- (void)render:(Render_Target*)target; +@end + +global OpenGLView *opengl_view; + +@implementation OpenGLView{ + b32 glIsInitialized; +} + +- (id)init{ + self = [super init]; + if (self == nil){ + return nil; + } - // NOTE(yuval): Open the gl dynamic library - void* gl_image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY); + glIsInitialized = false; + [self initGL]; + + return self; +} + +- (void)dealloc{ + [super dealloc]; +} + +- (void)prepareOpenGL{ + [super prepareOpenGL]; + + [[self openGLContext] makeCurrentContext]; + + // NOTE(yuval): Setup vsync + GLint swapInt = 1; + printf("Using vsync: %d\n", swapInt); + [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; +} + +- (void)awakeFromNib{ + [self initGL]; +} + +- (void)reshape{ + [super reshape]; + + [[self openGLContext] makeCurrentContext]; + [[self openGLContext] update]; +} + +- (void)initGL{ + if (glIsInitialized){ + return; + } + + // NOTE(yuval): Setup OpenGL + NSOpenGLPixelFormatAttribute opengl_attrs[] = { + NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersion3_2Core, + NSOpenGLPFAAccelerated, + NSOpenGLPFADoubleBuffer, + NSOpenGLPFAColorSize, 32, + NSOpenGLPFAAlphaSize, 8, + NSOpenGLPFADepthSize, 24, + NSOpenGLPFASampleBuffers, 1, + NSOpenGLPFASamples, 16, + 0 + }; + + NSOpenGLPixelFormat *pixel_format = [[NSOpenGLPixelFormat alloc] initWithAttributes:opengl_attrs]; + if (pixel_format == nil){ + fprintf(stderr, "Error creating OpenGLPixelFormat\n"); + exit(1); + } + + NSOpenGLContext *context = [[NSOpenGLContext alloc] initWithFormat:pixel_format shareContext:nil]; + + [self setPixelFormat:pixel_format]; + [self setOpenGLContext:context]; + + [context makeCurrentContext]; + + [pixel_format release]; + + glIsInitialized = true; +} + +- (void)render:(Render_Target*)target{ + Assert(glIsInitialized); + + CGLLockContext([[self openGLContext] CGLContextObj]); + [[self openGLContext] makeCurrentContext]; + gl_render(target); + [[self openGLContext] flushBuffer]; + CGLUnlockContext([[self openGLContext] CGLContextObj]); +} +@end + +function void +mac_gl_init(NSWindow *window){ + // NOTE(yuval): Create OpenGLView + NSView *content_view = [window contentView]; + + opengl_view = [[OpenGLView alloc] init]; + [opengl_view setFrame:[content_view bounds]]; + [opengl_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [opengl_view setWantsBestResolutionOpenGLSurface:YES]; + + // NOTE(yuval): Add the OpenGL view as a subview of the window + [content_view addSubview:opengl_view]; // NOTE(yuval): Load gl functions -#define GL_FUNC(f,R,P) Stmnt((f) = (f##_Function*)dlsym(gl_image, #f); \ - (result) &= (f != 0);); -#include "mac_4ed_opengl_funcs.h" + void *gl_image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY); - return result; +#define GL_FUNC(f,R,P) ((f) = (f##_Function*)dlsym(gl_image, #f)); +#include "mac_4ed_opengl_funcs.h" } + +function void +mac_gl_render(Render_Target* target){ + f64 begin_time = system_now_time() / 1000000.0; + [opengl_view render:target]; + f64 end_time = system_now_time() / 1000000.0; + printf("Render Time: %fs\n", (end_time - begin_time)); +} \ No newline at end of file From 13ee76effe9e6fd46e39de80977376d43a4d1008 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 2 Jan 2020 14:37:01 -0800 Subject: [PATCH 049/128] Added hard exit API; fixed exit menus --- 4ed.cpp | 11 ++++------- 4ed_api_implementation.cpp | 7 +++++++ 4ed_app_models.h | 3 ++- custom/4coder_base_commands.cpp | 2 +- custom/4coder_build_commands.cpp | 4 ++-- custom/4coder_cli_command.cpp | 4 ++++ custom/4coder_default_hooks.cpp | 8 +------- custom/generated/command_metadata.h | 4 ++-- custom/generated/custom_api.cpp | 2 ++ custom/generated/custom_api.h | 5 +++++ custom/generated/custom_api_constructor.cpp | 4 ++++ custom/generated/custom_api_master_list.h | 1 + platform_win32/win32_4ed.cpp | 1 + 13 files changed, 36 insertions(+), 20 deletions(-) diff --git a/4ed.cpp b/4ed.cpp index 8059d581..7f10ef54 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -201,6 +201,7 @@ App_Read_Command_Line_Sig(app_read_command_line){ App_Init_Sig(app_init){ Models *models = (Models*)base_ptr; models->keep_playing = true; + models->hard_exit = false; models->config_api = api; models->virtual_event_arena = reserve_arena(tctx); @@ -727,13 +728,9 @@ App_Step_Sig(app_step){ } // NOTE(allen): if the exit signal has been sent, run the exit hook. - if (input->trying_to_kill){ - models->keep_playing = false; - } - if (!models->keep_playing){ - if (co_send_core_event(tctx, models, CoreCode_TryExit)){ + if (!models->keep_playing || input->trying_to_kill){ + co_send_core_event(tctx, models, CoreCode_TryExit); models->keep_playing = true; - } } // NOTE(allen): rendering @@ -806,7 +803,7 @@ App_Step_Sig(app_step){ models->prev_mouse_panel = mouse_panel; app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr; - app_result.perform_kill = !models->keep_playing; + app_result.perform_kill = models->hard_exit; app_result.animating = models->animate_next_frame; if (models->animate_next_frame){ // NOTE(allen): Silence the timer, because we're going to do another frame right away anyways. diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 5c5d31b6..5829cd27 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -2761,6 +2761,13 @@ send_exit_signal(Application_Links *app) models->keep_playing = false; } +api(custom) function void +hard_exit(Application_Links *app) +{ + Models *models = (Models*)app->cmd_context; + models->hard_exit = true; +} + api(custom) function void set_window_title(Application_Links *app, String_Const_u8 title) { diff --git a/4ed_app_models.h b/4ed_app_models.h index 4c7a4bf3..670b0c26 100644 --- a/4ed_app_models.h +++ b/4ed_app_models.h @@ -105,7 +105,8 @@ struct Models{ Hot_Directory hot_directory; - b32 keep_playing; + b8 keep_playing; + b8 hard_exit; b32 has_new_title; char *title_space; diff --git a/custom/4coder_base_commands.cpp b/custom/4coder_base_commands.cpp index b04bb7c6..b5877959 100644 --- a/custom/4coder_base_commands.cpp +++ b/custom/4coder_base_commands.cpp @@ -65,7 +65,7 @@ CUSTOM_DOC("Inserts whatever text was used to trigger this command.") } CUSTOM_COMMAND_SIG(write_space) -CUSTOM_DOC("Inserts an underscore.") +CUSTOM_DOC("Inserts a space.") { write_text(app, string_u8_litexpr(" ")); } diff --git a/custom/4coder_build_commands.cpp b/custom/4coder_build_commands.cpp index cc7e6dc1..1988b2fe 100644 --- a/custom/4coder_build_commands.cpp +++ b/custom/4coder_build_commands.cpp @@ -63,7 +63,7 @@ standard_build_exec_command(Application_Links *app, View_ID view, String_Const_u standard_build_exec_flags); } -static b32 + function b32 standard_search_and_build_from_dir(Application_Links *app, View_ID view, String_Const_u8 start_dir){ Scratch_Block scratch(app); @@ -83,7 +83,7 @@ standard_search_and_build_from_dir(Application_Links *app, View_ID view, String_ // NOTE(allen): Build String_Const_u8 path = string_remove_last_folder(full_file_path); #if OS_WINDOWS - String_Const_u8 command = push_u8_stringf(scratch, "%.*s/%.*s", + String_Const_u8 command = push_u8_stringf(scratch, "\"%.*s/%.*s\"", string_expand(path), string_expand(cmd_string)); #elif OS_LINUX || OS_MAC diff --git a/custom/4coder_cli_command.cpp b/custom/4coder_cli_command.cpp index 446c4b86..038e0ed9 100644 --- a/custom/4coder_cli_command.cpp +++ b/custom/4coder_cli_command.cpp @@ -29,12 +29,16 @@ CUSTOM_DOC("Queries for an output buffer name and system command, runs the syste bar_out.string = SCu8(out_buffer_space, (u64)0); bar_out.string_capacity = sizeof(out_buffer_space); if (!query_user_string(app, &bar_out)) return; + bar_out.string.size = clamp_top(bar_out.string.size, sizeof(out_buffer_space) - 1); + out_buffer_space[bar_out.string.size] = 0; Query_Bar bar_cmd = {}; bar_cmd.prompt = string_u8_litexpr("Command: "); bar_cmd.string = SCu8(command_space, (u64)0); bar_cmd.string_capacity = sizeof(command_space); if (!query_user_string(app, &bar_cmd)) return; + bar_cmd.string.size = clamp_top(bar_cmd.string.size, sizeof(command_space) - 1); + command_space[bar_cmd.string.size] = 0; String_Const_u8 hot = push_hot_directory(app, scratch); { diff --git a/custom/4coder_default_hooks.cpp b/custom/4coder_default_hooks.cpp index 38ce6ea3..c898d3bf 100644 --- a/custom/4coder_default_hooks.cpp +++ b/custom/4coder_default_hooks.cpp @@ -43,13 +43,7 @@ CUSTOM_DOC("Default command for responding to a try-exit event") } } if (do_exit){ - // NOTE(allen): By leaving try exit unhandled we indicate - // that the core should take responsibility for handling this, - // and it will handle it by exiting 4coder. If we leave this - // event marked as handled on the other hand (for instance by - // running a confirmation GUI that cancels the exit) then 4coder - // will not exit. - leave_current_input_unhandled(app); + hard_exit(app); } } } diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index f9491504..38218855 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -285,7 +285,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 1796 }, { 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(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, 51 }, { 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 }, @@ -474,7 +474,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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_space, 0), false, "write_space", 11, "Inserts a space.", 16, "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 }, diff --git a/custom/generated/custom_api.cpp b/custom/generated/custom_api.cpp index 3ab062df..0aef628d 100644 --- a/custom/generated/custom_api.cpp +++ b/custom/generated/custom_api.cpp @@ -156,6 +156,7 @@ vtable->try_release_face = try_release_face; vtable->push_hot_directory = push_hot_directory; vtable->set_hot_directory = set_hot_directory; vtable->send_exit_signal = send_exit_signal; +vtable->hard_exit = hard_exit; vtable->set_window_title = set_window_title; vtable->draw_string_oriented = draw_string_oriented; vtable->get_string_advance = get_string_advance; @@ -336,6 +337,7 @@ try_release_face = vtable->try_release_face; push_hot_directory = vtable->push_hot_directory; set_hot_directory = vtable->set_hot_directory; send_exit_signal = vtable->send_exit_signal; +hard_exit = vtable->hard_exit; set_window_title = vtable->set_window_title; draw_string_oriented = vtable->draw_string_oriented; get_string_advance = vtable->get_string_advance; diff --git a/custom/generated/custom_api.h b/custom/generated/custom_api.h index 5b3bb02f..178479d4 100644 --- a/custom/generated/custom_api.h +++ b/custom/generated/custom_api.h @@ -154,6 +154,7 @@ #define custom_push_hot_directory_sig() String_Const_u8 custom_push_hot_directory(Application_Links* app, Arena* arena) #define custom_set_hot_directory_sig() void custom_set_hot_directory(Application_Links* app, String_Const_u8 string) #define custom_send_exit_signal_sig() void custom_send_exit_signal(Application_Links* app) +#define custom_hard_exit_sig() void custom_hard_exit(Application_Links* app) #define custom_set_window_title_sig() void custom_set_window_title(Application_Links* app, String_Const_u8 title) #define custom_draw_string_oriented_sig() Vec2_f32 custom_draw_string_oriented(Application_Links* app, Face_ID font_id, ARGB_Color color, String_Const_u8 str, Vec2_f32 point, u32 flags, Vec2_f32 delta) #define custom_get_string_advance_sig() f32 custom_get_string_advance(Application_Links* app, Face_ID font_id, String_Const_u8 str) @@ -330,6 +331,7 @@ typedef b32 custom_try_release_face_type(Application_Links* app, Face_ID id, Fac typedef String_Const_u8 custom_push_hot_directory_type(Application_Links* app, Arena* arena); typedef void custom_set_hot_directory_type(Application_Links* app, String_Const_u8 string); typedef void custom_send_exit_signal_type(Application_Links* app); +typedef void custom_hard_exit_type(Application_Links* app); typedef void custom_set_window_title_type(Application_Links* app, String_Const_u8 title); typedef Vec2_f32 custom_draw_string_oriented_type(Application_Links* app, Face_ID font_id, ARGB_Color color, String_Const_u8 str, Vec2_f32 point, u32 flags, Vec2_f32 delta); typedef f32 custom_get_string_advance_type(Application_Links* app, Face_ID font_id, String_Const_u8 str); @@ -507,6 +509,7 @@ custom_try_release_face_type *try_release_face; custom_push_hot_directory_type *push_hot_directory; custom_set_hot_directory_type *set_hot_directory; custom_send_exit_signal_type *send_exit_signal; +custom_hard_exit_type *hard_exit; custom_set_window_title_type *set_window_title; custom_draw_string_oriented_type *draw_string_oriented; custom_get_string_advance_type *get_string_advance; @@ -685,6 +688,7 @@ internal b32 try_release_face(Application_Links* app, Face_ID id, Face_ID replac internal String_Const_u8 push_hot_directory(Application_Links* app, Arena* arena); internal void set_hot_directory(Application_Links* app, String_Const_u8 string); internal void send_exit_signal(Application_Links* app); +internal void hard_exit(Application_Links* app); internal void set_window_title(Application_Links* app, String_Const_u8 title); internal Vec2_f32 draw_string_oriented(Application_Links* app, Face_ID font_id, ARGB_Color color, String_Const_u8 str, Vec2_f32 point, u32 flags, Vec2_f32 delta); internal f32 get_string_advance(Application_Links* app, Face_ID font_id, String_Const_u8 str); @@ -863,6 +867,7 @@ global custom_try_release_face_type *try_release_face = 0; global custom_push_hot_directory_type *push_hot_directory = 0; global custom_set_hot_directory_type *set_hot_directory = 0; global custom_send_exit_signal_type *send_exit_signal = 0; +global custom_hard_exit_type *hard_exit = 0; global custom_set_window_title_type *set_window_title = 0; global custom_draw_string_oriented_type *draw_string_oriented = 0; global custom_get_string_advance_type *get_string_advance = 0; diff --git a/custom/generated/custom_api_constructor.cpp b/custom/generated/custom_api_constructor.cpp index c30e0dd3..2520a502 100644 --- a/custom/generated/custom_api_constructor.cpp +++ b/custom/generated/custom_api_constructor.cpp @@ -906,6 +906,10 @@ API_Call *call = api_call_with_location(arena, result, string_u8_litexpr("send_e api_param(arena, call, "Application_Links*", "app"); } { +API_Call *call = api_call_with_location(arena, result, string_u8_litexpr("hard_exit"), string_u8_litexpr("void"), string_u8_litexpr("")); +api_param(arena, call, "Application_Links*", "app"); +} +{ API_Call *call = api_call_with_location(arena, result, string_u8_litexpr("set_window_title"), string_u8_litexpr("void"), string_u8_litexpr("")); api_param(arena, call, "Application_Links*", "app"); api_param(arena, call, "String_Const_u8", "title"); diff --git a/custom/generated/custom_api_master_list.h b/custom/generated/custom_api_master_list.h index 4ad7edf4..97617c5e 100644 --- a/custom/generated/custom_api_master_list.h +++ b/custom/generated/custom_api_master_list.h @@ -154,6 +154,7 @@ api(custom) function b32 try_release_face(Application_Links* app, Face_ID id, Fa api(custom) function String_Const_u8 push_hot_directory(Application_Links* app, Arena* arena); api(custom) function void set_hot_directory(Application_Links* app, String_Const_u8 string); api(custom) function void send_exit_signal(Application_Links* app); +api(custom) function void hard_exit(Application_Links* app); api(custom) function void set_window_title(Application_Links* app, String_Const_u8 title); api(custom) function Vec2_f32 draw_string_oriented(Application_Links* app, Face_ID font_id, ARGB_Color color, String_Const_u8 str, Vec2_f32 point, u32 flags, Vec2_f32 delta); api(custom) function f32 get_string_advance(Application_Links* app, Face_ID font_id, String_Const_u8 str); diff --git a/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index 0ed48a78..432d9b3a 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -640,6 +640,7 @@ win32_keycode_init(void){ keycode_lookup_table[VK_SPACE] = KeyCode_Space; keycode_lookup_table[VK_OEM_3] = KeyCode_Tick; keycode_lookup_table[VK_OEM_MINUS] = KeyCode_Minus; + keycode_lookup_table[VK_OEM_PLUS] = KeyCode_Equal; keycode_lookup_table[VK_OEM_4] = KeyCode_LeftBracket; keycode_lookup_table[VK_OEM_6] = KeyCode_RightBracket; keycode_lookup_table[VK_OEM_1] = KeyCode_Semicolon; From 2d78eade2f5c9c913cfe7f427678a9cfacced659 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 2 Jan 2020 16:00:34 -0800 Subject: [PATCH 050/128] Added checker for missing documentation, --- custom/4coder_doc_content_types.cpp | 16 +++++++ docs/4ed_doc_custom_api_buffer.cpp | 66 +++++++++++++++++++++++++++++ docs/4ed_doc_custom_api_global.cpp | 10 +++++ docs/4ed_doc_custom_api_main.cpp | 2 + docs/4ed_doc_custom_api_view.cpp | 27 ++++++++++++ docs/4ed_doc_helper.cpp | 15 +++++++ 6 files changed, 136 insertions(+) diff --git a/custom/4coder_doc_content_types.cpp b/custom/4coder_doc_content_types.cpp index 423db68b..4b4a3367 100644 --- a/custom/4coder_doc_content_types.cpp +++ b/custom/4coder_doc_content_types.cpp @@ -204,5 +204,21 @@ doc_paragraph(Arena *arena, Doc_Block *block){ par->kind = DocParagraphKind_Text; } +//////////////////////////////// + +function Doc_Page* +doc_get_page(Doc_Cluster *cluster, String_Const_u8 name){ + Doc_Page *result = 0; + for (Doc_Page *page = cluster->first_page; + page != 0; + page = page->next){ + if (string_match(name, page->name)){ + result = page; + break; + } + } + return(result); +} + // BOTTOM diff --git a/docs/4ed_doc_custom_api_buffer.cpp b/docs/4ed_doc_custom_api_buffer.cpp index a9fac64f..e6519167 100644 --- a/docs/4ed_doc_custom_api_buffer.cpp +++ b/docs/4ed_doc_custom_api_buffer.cpp @@ -384,6 +384,39 @@ doc_custom_api__buffer(Arena *arena, API_Definition *api_def, Doc_Cluster *clust //////////////////////////////// + if (begin_doc_call(arena, cluster, api_def, "buffer_padded_box_of_pos", &func)){ + doc_function_brief(arena, &func, "Compute the rectangle around a character at a particular byte position, relative to the top left corner of a given line"); + + // params + Doc_Block *params = doc_function_begin_params(arena, &func); + doc_custom_app_ptr(arena, &func); + + doc_function_param(arena, &func, "buffer_id"); + doc_text(arena, params, "the id of the buffer who's layout will be measured"); + + doc_function_param(arena, &func, "width"); + doc_text(arena, params, "the width parameter of the layout, passed to layout rules as a recommended wrap point"); + + doc_function_param(arena, &func, "face_id"); + doc_text(arena, params, "the face parameter of the layout, passed to layout rules as a recommended face"); + + doc_function_param(arena, &func, "base_line"); + doc_text(arena, params, "the line number of the line that serves as the relative starting point of the measurement"); + + doc_function_param(arena, &func, "pos"); + doc_text(arena, params, "the absolute byte index of the position to query"); + + // return + Doc_Block *ret = doc_function_return(arena, &func); + doc_text(arena, ret, "the rectangle around a character in the layout that is closest to including the given query position in it's span, with coordinates set relative to the top left corner of the base line, on success, when the buffer exists and contains the base line and query position, cleared to zero otherwise"); + + // details + Doc_Block *det = doc_function_details(arena, &func); + doc_text(arena, det, "Line numbers are 1 based."); + } + + //////////////////////////////// + if (begin_doc_call(arena, cluster, api_def, "buffer_relative_character_from_pos", &func)){ doc_function_brief(arena, &func, "Compute a character index relative to a particular lines first character"); @@ -627,6 +660,39 @@ doc_custom_api__buffer(Arena *arena, API_Definition *api_def, Doc_Cluster *clust //////////////////////////////// + if (begin_doc_call(arena, cluster, api_def, "buffer_set_layout", &func)){ + doc_function_brief(arena, &func, "Set the layout function of a buffer"); + + // params + Doc_Block *params = doc_function_begin_params(arena, &func); + doc_custom_app_ptr(arena, &func); + + doc_function_param(arena, &func, "buffer_id"); + doc_text(arena, params, "the id of the buffer to be modified"); + + doc_function_param(arena, &func, "layout_func"); + doc_text(arena, params, "the new layout function for the buffer's layout"); + + // return + Doc_Block *ret = doc_function_return(arena, &func); + doc_text(arena, ret, "non-zero on success, when the buffer exists, otherwise zero"); + } + + //////////////////////////////// + + if (begin_doc_call(arena, cluster, api_def, "buffer_clear_layout_cache", &func)){ + doc_function_brief(arena, &func, "Clear all the layout information cached in the buffer"); + + // params + Doc_Block *params = doc_function_begin_params(arena, &func); + doc_custom_app_ptr(arena, &func); + + doc_function_param(arena, &func, "buffer_id"); + doc_text(arena, params, "the id of the buffer to be modified"); + } + + //////////////////////////////// + if (begin_doc_call(arena, cluster, api_def, "buffer_get_layout", &func)){ doc_function_brief(arena, &func, "Retrieve the layout rule of a buffer"); diff --git a/docs/4ed_doc_custom_api_global.cpp b/docs/4ed_doc_custom_api_global.cpp index 04be9f89..3071886d 100644 --- a/docs/4ed_doc_custom_api_global.cpp +++ b/docs/4ed_doc_custom_api_global.cpp @@ -1174,6 +1174,16 @@ doc_custom_api__global(Arena *arena, API_Definition *api_def, Doc_Cluster *clust //////////////////////////////// + if (begin_doc_call(arena, cluster, api_def, "hard_exit", &func)){ + doc_function_brief(arena, &func, "Exits 4coder at the end of the frame, no matter what; for instance, call from the exit signal handler to actual exit 4coder."); + + // params + doc_function_begin_params(arena, &func); + doc_custom_app_ptr(arena, &func); + } + + //////////////////////////////// + if (begin_doc_call(arena, cluster, api_def, "set_window_title", &func)){ doc_function_brief(arena, &func, "Set the title of the 4coder window"); diff --git a/docs/4ed_doc_custom_api_main.cpp b/docs/4ed_doc_custom_api_main.cpp index 96258558..6d22c1fe 100644 --- a/docs/4ed_doc_custom_api_main.cpp +++ b/docs/4ed_doc_custom_api_main.cpp @@ -60,6 +60,8 @@ int main(void){ API_Definition *api_def = api_get_api(&def_list, string_u8_litexpr("custom")); Doc_Cluster *cluster = doc_custom_api(&arena, api_def); + doc_api_check_full_coverage(&arena, cluster, api_def); + for (Doc_Log *node = cluster->first_log; node != 0; node = node->next){ diff --git a/docs/4ed_doc_custom_api_view.cpp b/docs/4ed_doc_custom_api_view.cpp index dcaaf804..37c3bde5 100644 --- a/docs/4ed_doc_custom_api_view.cpp +++ b/docs/4ed_doc_custom_api_view.cpp @@ -133,6 +133,33 @@ doc_custom_api__view(Arena *arena, API_Definition *api_def, Doc_Cluster *cluster //////////////////////////////// + if (begin_doc_call(arena, cluster, api_def, "view_padded_box_of_pos", &func)){ + doc_function_brief(arena, &func, "Compute the rectangle around a character at a particular byte position, relative to the top left corner of a given line"); + + // params + Doc_Block *params = doc_function_begin_params(arena, &func); + doc_custom_app_ptr(arena, &func); + + doc_function_param(arena, &func, "view_id"); + doc_text(arena, params, "the id of the view who's layout will be measured"); + + doc_function_param(arena, &func, "base_line"); + doc_text(arena, params, "the line number of the line that serves as the relative starting point of the measurement"); + + doc_function_param(arena, &func, "pos"); + doc_text(arena, params, "the absolute byte index of the position to query"); + + // return + Doc_Block *ret = doc_function_return(arena, &func); + doc_text(arena, ret, "the rectangle around a character in the layout that is closest to including the given query position in it's span, with coordinates set relative to the top left corner of the base line, on success, when the view exists and contains the base line and query position, cleared to zero otherwise"); + + // details + Doc_Block *det = doc_function_details(arena, &func); + doc_text(arena, det, "Line numbers are 1 based."); + } + + //////////////////////////////// + if (begin_doc_call(arena, cluster, api_def, "view_relative_character_from_pos", &func)){ doc_function_brief(arena, &func, "Compute a character index relative to a particular lines first character"); diff --git a/docs/4ed_doc_helper.cpp b/docs/4ed_doc_helper.cpp index 5ffd065e..a28f402a 100644 --- a/docs/4ed_doc_helper.cpp +++ b/docs/4ed_doc_helper.cpp @@ -155,4 +155,19 @@ doc_function_add_related(Arena *arena, Doc_Block *rel, char *name){ content->page_link = SCu8(name); } +//////////////////////////////// + +function void +doc_api_check_full_coverage(Arena *arena, Doc_Cluster *cluster, API_Definition *api_def){ + for (API_Call *call = api_def->first_call; + call != 0; + call = call->next){ + String_Const_u8 name = call->name; + Doc_Page *page = doc_get_page(cluster, name); + if (page == 0){ + doc_errorf(arena, cluster, "missing documentation for %.*s", string_expand(name)); + } + } +} + // BOTTOM From 0fceec19a9cf4ffa988c24c356b04b8410c6e0f7 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sat, 4 Jan 2020 03:24:52 +0200 Subject: [PATCH 051/128] Basic metal renderer (only rendering a triangle as of right now). --- bin/4ed_build.cpp | 4 +- metal/4ed_metal_render.mm | 136 +++++++++++++++++++++++++++++++++ metal/AAPLShaderTypes.h | 33 ++++++++ metal/AAPLShaders.metal | 64 ++++++++++++++++ opengl/4ed_opengl_render.cpp | 12 +++ platform_mac/mac_4ed.mm | 33 ++++++-- platform_mac/mac_4ed_metal.mm | 29 +++++++ platform_mac/mac_4ed_opengl.mm | 34 +++++++-- 8 files changed, 332 insertions(+), 13 deletions(-) create mode 100644 metal/4ed_metal_render.mm create mode 100644 metal/AAPLShaderTypes.h create mode 100644 metal/AAPLShaders.metal create mode 100644 platform_mac/mac_4ed_metal.mm diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index 03a9a1b2..0a98abdb 100644 --- a/bin/4ed_build.cpp +++ b/bin/4ed_build.cpp @@ -389,7 +389,7 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha #define CLANG_LIBS_COMMON \ "-framework Cocoa -framework QuartzCore " \ "-framework CoreServices " \ -"-framework OpenGL -framework IOKit " +"-framework OpenGL -framework IOKit -framework Metal -framework MetalKit " #define CLANG_LIBS_X64 CLANG_LIBS_COMMON \ FOREIGN "/x64/libfreetype-mac.a" @@ -398,7 +398,7 @@ FOREIGN "/x64/libfreetype-mac.a" FOREIGN "/x86/libfreetype-mac.a" #else -# error gcc options not set for this platform +# error clang options not set for this platform #endif internal void diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm new file mode 100644 index 00000000..e715a8fe --- /dev/null +++ b/metal/4ed_metal_render.mm @@ -0,0 +1,136 @@ +/* 4coder Metal render implementation */ + +#undef clamp +#undef function +#import +#import + +// Header shared between C code here, which executes Metal API commands, and .metal files, which +// uses these types as inputs to the shaders. +#import "AAPLShaderTypes.h" + +#define function static +#define clamp(a,x,b) clamp_((a),(x),(b)) + +@interface FCoderMetalRenderer : NSObject +- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)mtkView; +@end + +@implementation FCoderMetalRenderer{ + id _device; + + // The render pipeline generated from the vertex and fragment shaders in the .metal shader file. + id _pipelineState; + + // The command queue used to pass commands to the device. + id _commandQueue; + + // The current size of the view, used as an input to the vertex shader. + vector_uint2 _viewportSize; +} + +- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)mtkView{ + self = [super init]; + if(self) + { + NSError *error = nil; + + _device = mtkView.device; + + // Load all the shader files with a .metal file extension in the project. + id defaultLibrary = [_device newLibraryWithFile:@"shaders/AAPLShaders.metallib" + error:&error]; + Assert(error == nil); + + id vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"]; + id fragmentFunction = [defaultLibrary newFunctionWithName:@"fragmentShader"]; + + // Configure a pipeline descriptor that is used to create a pipeline state. + MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; + pipelineStateDescriptor.label = @"Simple Pipeline"; + pipelineStateDescriptor.vertexFunction = vertexFunction; + pipelineStateDescriptor.fragmentFunction = fragmentFunction; + pipelineStateDescriptor.colorAttachments[0].pixelFormat = mtkView.colorPixelFormat; + + _pipelineState = [_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor + error:&error]; + + // Pipeline State creation could fail if the pipeline descriptor isn't set up properly. + // If the Metal API validation is enabled, you can find out more information about what + // went wrong. (Metal API validation is enabled by default when a debug build is run + // from Xcode.) + NSAssert(_pipelineState, @"Failed to created pipeline state: %@", error); + + // Create the command queue + _commandQueue = [_device newCommandQueue]; + + u32 max_buffer_size = (u32)[_device maxBufferLength]; + printf("Max Buffer Size: %u - Which is %lu vertices\n", max_buffer_size, (max_buffer_size / sizeof(Render_Vertex))); + } + + return self; +} + +/// Called whenever view changes orientation or is resized +- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size{ + // Save the size of the drawable to pass to the vertex shader. + +} + +/// Called whenever the view needs to render a frame. +- (void)drawInMTKView:(nonnull MTKView *)view{ + CGSize size = [view drawableSize]; + _viewportSize.x = size.width; + _viewportSize.y = size.height; + + static const AAPLVertex triangleVertices[] = + { + // 2D positions, RGBA colors + { { 250, -250 }, { 1, 0, 0, 1 } }, + { { -250, -250 }, { 0, 1, 0, 1 } }, + { { 0, 250 }, { 0, 0, 1, 1 } }, + }; + + // Create a new command buffer for each render pass to the current drawable. + id commandBuffer = [_commandQueue commandBuffer]; + commandBuffer.label = @"MyCommand"; + + // Obtain a renderPassDescriptor generated from the view's drawable textures. + MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor; + + if(renderPassDescriptor != nil) + { + // Create a render command encoder. + id renderEncoder = + [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; + renderEncoder.label = @"MyRenderEncoder"; + + // Set the region of the drawable to draw into. + [renderEncoder setViewport:(MTLViewport){0.0, 0.0, (double)_viewportSize.x, (double)_viewportSize.y, 0.0, 1.0 }]; + + [renderEncoder setRenderPipelineState:_pipelineState]; + + // Pass in the parameter data. + [renderEncoder setVertexBytes:triangleVertices + length:sizeof(triangleVertices) + atIndex:AAPLVertexInputIndexVertices]; + + [renderEncoder setVertexBytes:&_viewportSize + length:sizeof(_viewportSize) + atIndex:AAPLVertexInputIndexViewportSize]; + + // Draw the triangle. + [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle + vertexStart:0 + vertexCount:3]; + + [renderEncoder endEncoding]; + + // Schedule a present once the framebuffer is complete using the current drawable. + [commandBuffer presentDrawable:view.currentDrawable]; + } + + // Finalize rendering here & push the command buffer to the GPU. + [commandBuffer commit]; +} +@end \ No newline at end of file diff --git a/metal/AAPLShaderTypes.h b/metal/AAPLShaderTypes.h new file mode 100644 index 00000000..be46a81a --- /dev/null +++ b/metal/AAPLShaderTypes.h @@ -0,0 +1,33 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Header containing types and enum constants shared between Metal shaders and C/ObjC source +*/ + +#ifndef AAPLShaderTypes_h +#define AAPLShaderTypes_h + +#undef clamp +#include +#define clamp(a,x,b) clamp_((a),(x),(b)) + +// Buffer index values shared between shader and C code to ensure Metal shader buffer inputs +// match Metal API buffer set calls. +typedef enum AAPLVertexInputIndex +{ + AAPLVertexInputIndexVertices = 0, + AAPLVertexInputIndexViewportSize = 1, +} AAPLVertexInputIndex; + +// This structure defines the layout of vertices sent to the vertex +// shader. This header is shared between the .metal shader and C code, to guarantee that +// the layout of the vertex array in the C code matches the layout that the .metal +// vertex shader expects. +typedef struct +{ + vector_float2 position; + vector_float4 color; +} AAPLVertex; + +#endif /* AAPLShaderTypes_h */ diff --git a/metal/AAPLShaders.metal b/metal/AAPLShaders.metal new file mode 100644 index 00000000..60c3736b --- /dev/null +++ b/metal/AAPLShaders.metal @@ -0,0 +1,64 @@ +/* +See LICENSE folder for this sample’s licensing information. + +Abstract: +Metal shaders used for this sample +*/ + +#include +#include + +using namespace metal; + +// Include header shared between this Metal shader code and C code executing Metal API commands. +#import "AAPLShaderTypes.h" + +// Vertex shader outputs and fragment shader inputs +typedef struct +{ + // The [[position]] attribute of this member indicates that this value + // is the clip space position of the vertex when this structure is + // returned from the vertex function. + float4 position [[position]]; + + // Since this member does not have a special attribute, the rasterizer + // interpolates its value with the values of the other triangle vertices + // and then passes the interpolated value to the fragment shader for each + // fragment in the triangle. + float4 color; + +} RasterizerData; + +vertex RasterizerData +vertexShader(uint vertexID [[vertex_id]], + constant AAPLVertex *vertices [[buffer(AAPLVertexInputIndexVertices)]], + constant vector_uint2 *viewportSizePointer [[buffer(AAPLVertexInputIndexViewportSize)]]) +{ + RasterizerData out; + + // Index into the array of positions to get the current vertex. + // The positions are specified in pixel dimensions (i.e. a value of 100 + // is 100 pixels from the origin). + float2 pixelSpacePosition = vertices[vertexID].position.xy; + + // Get the viewport size and cast to float. + vector_float2 viewportSize = vector_float2(*viewportSizePointer); + + + // To convert from positions in pixel space to positions in clip-space, + // divide the pixel coordinates by half the size of the viewport. + out.position = vector_float4(0.0, 0.0, 0.0, 1.0); + out.position.xy = pixelSpacePosition / (viewportSize / 2.0); + + // Pass the input color directly to the rasterizer. + out.color = vertices[vertexID].color; + + return out; +} + +fragment float4 fragmentShader(RasterizerData in [[stage_in]]) +{ + // Return the interpolated color. + return in.color; +} + diff --git a/opengl/4ed_opengl_render.cpp b/opengl/4ed_opengl_render.cpp index e3413ae0..7c2d5524 100644 --- a/opengl/4ed_opengl_render.cpp +++ b/opengl/4ed_opengl_render.cpp @@ -285,6 +285,9 @@ gl_render(Render_Target *t){ t->free_texture_first = 0; t->free_texture_last = 0; + u32 all_vertex_count = 0; + + u64 begin_draw = system_now_time(); for (Render_Group *group = t->group_first; group != 0; group = group->next){ @@ -339,9 +342,18 @@ gl_render(Render_Target *t){ glDisableVertexAttribArray(gpu_program.vertex_c); glDisableVertexAttribArray(gpu_program.vertex_ht); } + + all_vertex_count += vertex_count; } + u64 end_draw = system_now_time(); + printf("Draw time: %fs\n", mac_get_time_diff_sec(begin_draw, end_draw)); + u64 begin_flush = system_now_time(); glFlush(); + u64 end_flush = system_now_time(); + printf("Flush time: %fs\n", mac_get_time_diff_sec(begin_flush, end_flush)); + + printf("Drawn %d Vertices\n", all_vertex_count); } // BOTTOM diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 958d1399..cae3a944 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -273,11 +273,24 @@ mac_to_object(Plat_Handle handle){ #include #import "mac_4ed_opengl.mm" +#import "mac_4ed_metal.mm" + #include "4ed_font_provider_freetype.h" #include "4ed_font_provider_freetype.cpp" #import "mac_4ed_functions.mm" + + +//////////////////////////////// + +global Key_Code keycode_lookup_table[255]; + +function void +mac_key_code_init(void){ + +} + //////////////////////////////// function void @@ -326,8 +339,6 @@ mac_resize(NSWindow *window){ //////////////////////////////// -// TODO(yuval): mac_resize(bounds.size.width, bounds.size.height); - @implementation FCoderAppDelegate - (void)applicationDidFinishLaunching:(id)sender{ } @@ -376,6 +387,13 @@ mac_resize(NSWindow *window){ } - (void)drawRect:(NSRect)bounds{ + /* NOTE(yuval): Force the graphics context to clear to black so we don't +get a flash of white until the app is ready to draw. In practice on modern macOS, +this only gets called for window creation and other extraordinary events. +(Taken From SDL) */ + [[NSColor blackColor] setFill]; + NSRectFill(bounds); + // NOTE(yuval): Read comment in win32_4ed.cpp's main loop system_mutex_release(mac_vars.global_frame_mutex); @@ -422,7 +440,8 @@ mac_resize(NSWindow *window){ [NSApp terminate:nil]; } - mac_gl_render(&target); + // mac_gl_render(&target); + mac_metal_render(&target); mac_vars.first = false; @@ -670,17 +689,19 @@ main(int arg_count, char **args){ NSView* content_view = [mac_vars.window contentView]; - // NOTE(yuval): Initialize the renderer - mac_gl_init(mac_vars.window); - // NOTE(yuval): Create the 4coder view mac_vars.view = [[FCoderView alloc] init]; [mac_vars.view setFrame:[content_view bounds]]; [mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + // NOTE(yuval): Display window and view [content_view addSubview:mac_vars.view]; [mac_vars.window makeKeyAndOrderFront:nil]; + // NOTE(yuval): Initialize the renderer + mac_gl_init(mac_vars.window); + mac_metal_init(mac_vars.window); + mac_resize(w, h); // diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm new file mode 100644 index 00000000..05ed482e --- /dev/null +++ b/platform_mac/mac_4ed_metal.mm @@ -0,0 +1,29 @@ +#import "metal/4ed_metal_render.mm" + +global MTKView *metal_view; +global FCoderMetalRenderer *metal_renderer; + +function void +mac_metal_init(NSWindow *window){ + // NOTE(yuval): Create Metal view + NSView *content_view = [window contentView]; + + metal_view = [[MTKView alloc] initWithFrame:[content_view bounds]]; + [metal_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + + metal_view.device = MTLCreateSystemDefaultDevice(); + + // NOTE(yuval): Add the Metal view as a subview of the window + [content_view addSubview:metal_view]; + + // NOTE(yuval): Create the Metal renderer + metal_renderer = [[FCoderMetalRenderer alloc] initWithMetalKitView:metal_view]; +} + +function void +mac_metal_render(Render_Target* target){ + u64 begin_time = system_now_time(); + [metal_renderer drawInMTKView:metal_view]; + u64 end_time = system_now_time(); + printf("Metal Render Time: %fs\n\n", mac_get_time_diff_sec(begin_time, end_time)); +} \ No newline at end of file diff --git a/platform_mac/mac_4ed_opengl.mm b/platform_mac/mac_4ed_opengl.mm index dd89c079..ba1f4dee 100644 --- a/platform_mac/mac_4ed_opengl.mm +++ b/platform_mac/mac_4ed_opengl.mm @@ -5,6 +5,11 @@ #define GL_FUNC(N,R,P) typedef R (CALL_CONVENTION N##_Function)P; N##_Function *N = 0; #include "mac_4ed_opengl_funcs.h" +f64 mac_get_time_diff_sec(u64 begin, u64 end){ + f64 result = ((end - begin) / 1000000.0); + return result; +} + #include "opengl/4ed_opengl_render.cpp" @interface OpenGLView : NSOpenGLView @@ -12,8 +17,6 @@ - (void)render:(Render_Target*)target; @end -global OpenGLView *opengl_view; - @implementation OpenGLView{ b32 glIsInitialized; } @@ -95,14 +98,35 @@ global OpenGLView *opengl_view; - (void)render:(Render_Target*)target{ Assert(glIsInitialized); + u64 context_lock_begin = system_now_time(); CGLLockContext([[self openGLContext] CGLContextObj]); + u64 context_lock_end = system_now_time(); + printf("Context lock time: %fs\n", mac_get_time_diff_sec(context_lock_begin, context_lock_end)); + + u64 make_current_context_begin = system_now_time(); [[self openGLContext] makeCurrentContext]; + u64 make_current_context_end = system_now_time(); + printf("Make current context time: %fs\n", mac_get_time_diff_sec(make_current_context_begin, make_current_context_end)); + + u64 gl_render_begin = system_now_time(); gl_render(target); + u64 gl_render_end = system_now_time(); + printf("GL render time: %fs\n", mac_get_time_diff_sec(gl_render_begin, gl_render_end)); + + u64 gl_flush_buffer_begin = system_now_time(); [[self openGLContext] flushBuffer]; + u64 gl_flush_buffer_end = system_now_time(); + printf("GL flush buffer time: %fs\n", mac_get_time_diff_sec(gl_flush_buffer_begin, gl_flush_buffer_end)); + + u64 context_unlock_begin = system_now_time(); CGLUnlockContext([[self openGLContext] CGLContextObj]); + u64 context_unlock_end = system_now_time(); + printf("Context unlock time: %fs\n", mac_get_time_diff_sec(context_unlock_begin, context_unlock_end)); } @end +global OpenGLView *opengl_view; + function void mac_gl_init(NSWindow *window){ // NOTE(yuval): Create OpenGLView @@ -125,8 +149,8 @@ mac_gl_init(NSWindow *window){ function void mac_gl_render(Render_Target* target){ - f64 begin_time = system_now_time() / 1000000.0; + u64 begin_time = system_now_time(); [opengl_view render:target]; - f64 end_time = system_now_time() / 1000000.0; - printf("Render Time: %fs\n", (end_time - begin_time)); + u64 end_time = system_now_time(); + printf("Render Time: %fs\n\n", mac_get_time_diff_sec(begin_time, end_time)); } \ No newline at end of file From b52f1cee246a37ed5850df7cc08af3230237e20f Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 5 Jan 2020 03:13:47 +0200 Subject: [PATCH 052/128] Metal projection matrix test. --- bin/4ed_build.cpp | 11 +- metal/4ed_metal_render.mm | 245 +++++++++++++++++++++++++++++++++- platform_mac/mac_4ed_metal.mm | 8 +- 3 files changed, 250 insertions(+), 14 deletions(-) diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index 0a98abdb..8640443b 100644 --- a/bin/4ed_build.cpp +++ b/bin/4ed_build.cpp @@ -380,11 +380,12 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha #if OS_MAC -# define CLANG_OPTS \ -"-Wno-write-strings -Wno-deprecated-declarations " \ -"-Wno-comment -Wno-switch -Wno-null-dereference " \ -"-Wno-tautological-compare " \ -"-Wno-unused-result -Wno-missing-declarations -std=c++11 " +# define CLANG_OPTS \ +"-Wno-write-strings -Wno-deprecated-declarations " \ +"-Wno-comment -Wno-switch -Wno-null-dereference " \ +"-Wno-tautological-compare -Wno-unused-result " \ +"-Wno-missing-declarations -Wno-nullability-completeness " \ +"-std=c++11 " #define CLANG_LIBS_COMMON \ "-framework Cocoa -framework QuartzCore " \ diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index e715a8fe..442a3e50 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -5,12 +5,88 @@ #import #import -// Header shared between C code here, which executes Metal API commands, and .metal files, which -// uses these types as inputs to the shaders. -#import "AAPLShaderTypes.h" - +#include "AAPLShaderTypes.h" #define function static -#define clamp(a,x,b) clamp_((a),(x),(b)) + +struct Metal_Renderer{ + MTKView *view; + + id device; + id pipeline_state; + id command_queue; + id buffer; +}; + +global_const u32 metal_max_vertices = (1<<16); + +global_const char *metal__shaders_source = R"( +#include +#include + +using namespace metal; + +// Buffer index values shared between shader and C code to ensure Metal shader buffer inputs +// match Metal API buffer set calls. +typedef enum AAPLVertexInputIndex +{ + AAPLVertexInputIndexVertices = 0, + AAPLVertexInputIndexViewportSize = 1, +} AAPLVertexInputIndex; + +// This structure defines the layout of vertices sent to the vertex +// shader. This header is shared between the .metal shader and C code, to guarantee that +// the layout of the vertex array in the C code matches the layout that the .metal +// vertex shader expects. +typedef struct +{ + vector_float2 position; + vector_float4 color; +} AAPLVertex; + +// Vertex shader outputs and fragment shader inputs +typedef struct +{ + // The [[position]] attribute of this member indicates that this value + // is the clip space position of the vertex when this structure is + // returned from the vertex function. + float4 position [[position]]; + + // Since this member does not have a special attribute, the rasterizer + // interpolates its value with the values of the other triangle vertices + // and then passes the interpolated value to the fragment shader for each + // fragment in the triangle. + float4 color; + +} RasterizerData; + +vertex RasterizerData +vertexShader(uint vertexID [[vertex_id]], + constant AAPLVertex *vertices [[buffer(AAPLVertexInputIndexVertices)]], + constant float4x4 &projMatrix[[buffer(AAPLVertexInputIndexViewportSize)]]) +{ + RasterizerData out; + + // Index into the array of positions to get the current vertex. + // The positions are specified in pixel dimensions (i.e. a value of 100 + // is 100 pixels from the origin). + float2 pixelSpacePosition = vertices[vertexID].position.xy; + + // To convert from positions in pixel space to positions in clip-space, + // divide the pixel coordinates by half the size of the viewport. + out.position = float4(pixelSpacePosition, 0.0, 1.0) * projMatrix; + + // Pass the input color directly to the rasterizer. + out.color = vertices[vertexID].color; + + return out; +} + +fragment float4 fragmentShader(RasterizerData in [[stage_in]]) +{ + // Return the interpolated color. + return in.color; +} +)"; @interface FCoderMetalRenderer : NSObject - (nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)mtkView; @@ -133,4 +209,161 @@ // Finalize rendering here & push the command buffer to the GPU. [commandBuffer commit]; } -@end \ No newline at end of file +@end + +function b32 +metal_init(Metal_Renderer *renderer, MTKView *view){ + NSError *error = nil; + + renderer->view = view; + renderer->device = view.device; + + // NOTE(yuval): Compile the shaders + id vertex_function = nil; + id fragment_function = nil; + { + NSString *shaders_source_str = [NSString stringWithUTF8String:metal__shaders_source]; + + MTLCompileOptions *options = [[MTLCompileOptions alloc] init]; + options.fastMathEnabled = YES; + + id shader_library = [renderer->device newLibraryWithSource:shaders_source_str + options:options error:&error]; + vertex_function = [shader_library newFunctionWithName:@"vertexShader"]; + fragment_function = [shader_library newFunctionWithName:@"fragmentShader"]; + + [options release]; + } + + if (error != nil){ + return(false); + } + + // NOTE(yuval): Configure the pipeline descriptor + { + MTLRenderPipelineDescriptor *pipeline_state_descriptor = [[MTLRenderPipelineDescriptor alloc] init]; + pipeline_state_descriptor.label = @"4coder Metal Renderer Pipeline"; + pipeline_state_descriptor.vertexFunction = vertex_function; + pipeline_state_descriptor.fragmentFunction = fragment_function; + pipeline_state_descriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat; + + renderer->pipeline_state = [renderer->device newRenderPipelineStateWithDescriptor:pipeline_state_descriptor + error:&error]; + } + + if (error != nil){ + return(false); + } + + // NOTE(yuval): Create the command queue + renderer->command_queue = [renderer->device newCommandQueue]; + + // NOTE(yuval): Create the vertex buffer + { + u32 buffer_size = (metal_max_vertices * sizeof(Render_Vertex)); + MTLResourceOptions options = MTLCPUCacheModeWriteCombined|MTLResourceStorageModeManaged; + renderer->buffer = [renderer->device newBufferWithLength:buffer_size + options:options]; + } + + return(true); +} + +function void +metal_render(Metal_Renderer *renderer, Render_Target *t){ + static const AAPLVertex triangleVertices[] = { + // 2D positions, RGBA colors + { { 200, 100 }, { 1, 0, 0, 1 } }, + { { 100, 100 }, { 0, 1, 0, 1 } }, + { { 150, 200 }, { 0, 0, 1, 1 } }, + }; + + // NOTE(yuval): Create the command buffer + id command_buffer = [renderer->command_queue commandBuffer]; + command_buffer.label = @"4coder Metal Render Command"; + + // NOTE(yuval): Obtain the render pass descriptor from the renderer's view + MTLRenderPassDescriptor *render_pass_descriptor = renderer->view.currentRenderPassDescriptor; + if (render_pass_descriptor != nil){ + // NOTE(yuval): Create the render command encoder + id render_encoder + = [command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor]; + render_encoder.label = @"4coder Render Encoder"; + + // NOTE(yuval): Set the region of the drawable to draw into + [render_encoder setViewport:(MTLViewport){0.0, 0.0, (double)t->width, (double)t->height, 0.0, 1.0}]; + + // NOTE(yuval): Set the render pipeline to use for drawing + [render_encoder setRenderPipelineState:renderer->pipeline_state]; + + // NOTE(yuval): Pass in the parameter data + [render_encoder setVertexBytes:triangleVertices + length:sizeof(triangleVertices) + atIndex:AAPLVertexInputIndexVertices]; + +#if 0 + vector_uint2 viewport_size = {(u32)t->width, (u32)t->height}; + [render_encoder setVertexBytes:&viewport_size + length:sizeof(viewport_size) + atIndex:AAPLVertexInputIndexViewportSize]; +#else + float left = 0, right = (float)t->width; + float bottom = 0, top = (float)t->height; + float near_depth = -1.0f, far_depth = 1.0f; + float m[16] = { + 2.0f / (right - left), 0.0f, 0.0f, 0.0f, + 0.0f, 2.0f / (top - bottom), 0.0f, 0.0f, + 0.0f, 0.0f, -1.0f / (far_depth - near_depth), 0.0f, + -((right + left) / (right - left)), -((top + bottom) / (top - bottom)), + (-near_depth) * (far_depth - near_depth), 1.0f + }; + + float sLength = 1.0f / (right - left); + float sHeight = 1.0f / (top - bottom); + float sDepth = 1.0f / (far_depth - near_depth); + + simd::float4 P; + simd::float4 Q; + simd::float4 R; + simd::float4 S; + + P.x = 2.0f * sLength; + P.y = 0.0f; + P.z = 0.0f; + P.w = -((right + left) / (right - left)); + + Q.x = 0.0f; + Q.y = 2.0f * sHeight; + Q.z = 0.0f; + Q.w = -((top + bottom) / (top - bottom)); + + R.x = 0.0f; + R.y = 0.0f; + R.z = sDepth; + R.w = -near_depth * sDepth; + + S.x = 0.0f; + S.y = 0.0f; + S.z = 0.0f; + S.w = 1.0f; + + simd_float4x4 proj = simd::float4x4(P, Q, R, S); + + [render_encoder setVertexBytes:&proj + length:sizeof(proj) + atIndex:AAPLVertexInputIndexViewportSize]; +#endif + + // NOTE(yuval): Draw the triangle + [render_encoder drawPrimitives:MTLPrimitiveTypeTriangle + vertexStart:0 + vertexCount:3]; + + [render_encoder endEncoding]; + + // NOTE(yuval): Schedule a present once the framebuffer is complete using the current drawable + [command_buffer presentDrawable:renderer->view.currentDrawable]; + } + + [command_buffer commit]; +} \ No newline at end of file diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm index 05ed482e..ff69d8d3 100644 --- a/platform_mac/mac_4ed_metal.mm +++ b/platform_mac/mac_4ed_metal.mm @@ -1,7 +1,7 @@ #import "metal/4ed_metal_render.mm" +global Metal_Renderer metal_renderer; global MTKView *metal_view; -global FCoderMetalRenderer *metal_renderer; function void mac_metal_init(NSWindow *window){ @@ -17,13 +17,15 @@ mac_metal_init(NSWindow *window){ [content_view addSubview:metal_view]; // NOTE(yuval): Create the Metal renderer - metal_renderer = [[FCoderMetalRenderer alloc] initWithMetalKitView:metal_view]; + //metal_renderer = [[FCoderMetalRenderer alloc] initWithMetalKitView:metal_view]; + metal_init(&metal_renderer, metal_view); } function void mac_metal_render(Render_Target* target){ u64 begin_time = system_now_time(); - [metal_renderer drawInMTKView:metal_view]; + //[metal_renderer drawInMTKView:metal_view]; + metal_render(&metal_renderer, target); u64 end_time = system_now_time(); printf("Metal Render Time: %fs\n\n", mac_get_time_diff_sec(begin_time, end_time)); } \ No newline at end of file From 813ba593e3fe263c79139fc8fe4079e2570155be Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 5 Jan 2020 03:44:16 +0200 Subject: [PATCH 053/128] Fixed flipped projection matrix. --- metal/4ed_metal_render.mm | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index 442a3e50..99a6de2f 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -73,7 +73,7 @@ vertexShader(uint vertexID [[vertex_id]], // To convert from positions in pixel space to positions in clip-space, // divide the pixel coordinates by half the size of the viewport. - out.position = float4(pixelSpacePosition, 0.0, 1.0) * projMatrix; + out.position = projMatrix * float4(pixelSpacePosition, 0.0, 1.0); // Pass the input color directly to the rasterizer. out.color = vertices[vertexID].color; @@ -315,7 +315,7 @@ metal_render(Metal_Renderer *renderer, Render_Target *t){ 0.0f, 2.0f / (top - bottom), 0.0f, 0.0f, 0.0f, 0.0f, -1.0f / (far_depth - near_depth), 0.0f, -((right + left) / (right - left)), -((top + bottom) / (top - bottom)), - (-near_depth) * (far_depth - near_depth), 1.0f + (-near_depth) / (far_depth - near_depth), 1.0f }; float sLength = 1.0f / (right - left); @@ -330,21 +330,21 @@ metal_render(Metal_Renderer *renderer, Render_Target *t){ P.x = 2.0f * sLength; P.y = 0.0f; P.z = 0.0f; - P.w = -((right + left) / (right - left)); + P.w = 0.0f; Q.x = 0.0f; Q.y = 2.0f * sHeight; Q.z = 0.0f; - Q.w = -((top + bottom) / (top - bottom)); + Q.w = 0.0f; R.x = 0.0f; R.y = 0.0f; R.z = sDepth; - R.w = -near_depth * sDepth; + R.w = 0.0f; - S.x = 0.0f; - S.y = 0.0f; - S.z = 0.0f; + S.x = -((right + left) / (right - left)); + S.y = -((top + bottom) / (top - bottom)); + S.z = -near_depth * sDepth; S.w = 1.0f; simd_float4x4 proj = simd::float4x4(P, Q, R, S); From efad77240152051750eb6f60272916b76d383c64 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Mon, 6 Jan 2020 02:55:07 +0200 Subject: [PATCH 054/128] Work on metal renderer. Only semi-working for now. --- metal/4ed_metal_render.mm | 414 ++++++++++++++--------------------- metal/AAPLShaderTypes.h | 8 - opengl/4ed_opengl_render.cpp | 2 +- platform_mac/mac_4ed.mm | 2 +- 4 files changed, 171 insertions(+), 255 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index 99a6de2f..cf760786 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -15,6 +15,7 @@ struct Metal_Renderer{ id pipeline_state; id command_queue; id buffer; + id capture_scope; }; global_const u32 metal_max_vertices = (1<<16); @@ -25,193 +26,94 @@ global_const char *metal__shaders_source = R"( using namespace metal; -// Buffer index values shared between shader and C code to ensure Metal shader buffer inputs -// match Metal API buffer set calls. -typedef enum AAPLVertexInputIndex -{ - AAPLVertexInputIndexVertices = 0, - AAPLVertexInputIndexViewportSize = 1, -} AAPLVertexInputIndex; +//////////////////////////////// -// This structure defines the layout of vertices sent to the vertex -// shader. This header is shared between the .metal shader and C code, to guarantee that -// the layout of the vertex array in the C code matches the layout that the .metal -// vertex shader expects. -typedef struct -{ - vector_float2 position; - vector_float4 color; -} AAPLVertex; +typedef struct{ +packed_float2 xy; + packed_float3 uvw; +uint32_t color; +float half_thickness; +} Vertex; -// Vertex shader outputs and fragment shader inputs -typedef struct -{ - // The [[position]] attribute of this member indicates that this value - // is the clip space position of the vertex when this structure is - // returned from the vertex function. - float4 position [[position]]; - - // Since this member does not have a special attribute, the rasterizer - // interpolates its value with the values of the other triangle vertices - // and then passes the interpolated value to the fragment shader for each - // fragment in the triangle. +// NOTE(yuval): Vertex shader outputs and fragment shader inputs +typedef struct{ +// NOTE(yuval): Vertex shader output +float4 position [[position]]; + +// NOTE(yuval): Fragment shader inputs float4 color; - -} RasterizerData; + float3 uvw; + float2 xy; + float2 adjusted_half_dim; + float half_thickness; +} Rasterizer_Data; -vertex RasterizerData -vertexShader(uint vertexID [[vertex_id]], - constant AAPLVertex *vertices [[buffer(AAPLVertexInputIndexVertices)]], - constant float4x4 &projMatrix[[buffer(AAPLVertexInputIndexViewportSize)]]) -{ - RasterizerData out; +//////////////////////////////// + +vertex Rasterizer_Data +vertex_shader(uint vertex_id [[vertex_id]], constant Vertex *vertices [[buffer(0)]], +constant float4x4 &proj [[buffer(1)]]){ + constant Vertex *in = &vertices[vertex_id]; + Rasterizer_Data out; - // Index into the array of positions to get the current vertex. - // The positions are specified in pixel dimensions (i.e. a value of 100 - // is 100 pixels from the origin). - float2 pixelSpacePosition = vertices[vertexID].position.xy; + // NOTE(yuval): Calculate position in NDC + out.position = proj * float4(in->xy, 0.0, 1.0); - // To convert from positions in pixel space to positions in clip-space, - // divide the pixel coordinates by half the size of the viewport. - out.position = projMatrix * float4(pixelSpacePosition, 0.0, 1.0); + // NOTE(yuval): Convert color to float4 format + out.color.b = ((float((in->color ) & 0xFFu)) / 255.0); + out.color.g = ((float((in->color >> 8u) & 0xFFu)) / 255.0); + out.color.r = ((float((in->color >> 16u) & 0xFFu)) / 255.0); + out.color.a = ((float((in->color >> 24u) & 0xFFu)) / 255.0); - // Pass the input color directly to the rasterizer. - out.color = vertices[vertexID].color; + // NOTE(yuval): Pass uvw coordinates to the fragment shader + out.uvw = in->uvw; - return out; + // NOTE(yuval): Calculate adjusted half dim + float2 center = in->uvw.xy; + float2 half_dim = abs(in->xy - center); + out.adjusted_half_dim = (half_dim - in->uvw.zz + float2(0.5, 0.5)); + + // NOTE(yuval): Pass half_thickness to the fragment shader + out.half_thickness = in->half_thickness; + + // NOTE(yuval): Pass xy to the fragment shader + out.xy = in->xy; + + return(out); } -fragment float4 fragmentShader(RasterizerData in [[stage_in]]) -{ - // Return the interpolated color. - return in.color; +//////////////////////////////// + +float +rectangle_sd(float2 p, float2 b){ +float2 d = (abs(p) - b); +float result = (length(max(d, float2(0.0, 0.0))) + min(max(d.x, d.y), 0.0)); + +return(result); +} + +fragment float4 +fragment_shader(Rasterizer_Data in [[stage_in]]){ +float has_thickness = step(0.49, in.half_thickness); +// float does_not_have_thickness = (1.0 - has_thickness); + +// TODO(yuval): Sample texture here. + +float2 center = in.uvw.xy; +float roundness = in.uvw.z; +float sd = rectangle_sd(in.xy - center, in.adjusted_half_dim); +sd = sd - roundness; +sd = (abs(sd + in.half_thickness) - in.half_thickness); +float shape_value = (1.0 - smoothstep(-1.0, 0.0, sd)); +shape_value *= has_thickness; + + // TOOD(yuval): Add sample_value to alpha + float4 out_color = in.color;// float4(in.color.xyz, in.color.a * (shape_value)); + return(out_color); } )"; -@interface FCoderMetalRenderer : NSObject -- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)mtkView; -@end - -@implementation FCoderMetalRenderer{ - id _device; - - // The render pipeline generated from the vertex and fragment shaders in the .metal shader file. - id _pipelineState; - - // The command queue used to pass commands to the device. - id _commandQueue; - - // The current size of the view, used as an input to the vertex shader. - vector_uint2 _viewportSize; -} - -- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView *)mtkView{ - self = [super init]; - if(self) - { - NSError *error = nil; - - _device = mtkView.device; - - // Load all the shader files with a .metal file extension in the project. - id defaultLibrary = [_device newLibraryWithFile:@"shaders/AAPLShaders.metallib" - error:&error]; - Assert(error == nil); - - id vertexFunction = [defaultLibrary newFunctionWithName:@"vertexShader"]; - id fragmentFunction = [defaultLibrary newFunctionWithName:@"fragmentShader"]; - - // Configure a pipeline descriptor that is used to create a pipeline state. - MTLRenderPipelineDescriptor *pipelineStateDescriptor = [[MTLRenderPipelineDescriptor alloc] init]; - pipelineStateDescriptor.label = @"Simple Pipeline"; - pipelineStateDescriptor.vertexFunction = vertexFunction; - pipelineStateDescriptor.fragmentFunction = fragmentFunction; - pipelineStateDescriptor.colorAttachments[0].pixelFormat = mtkView.colorPixelFormat; - - _pipelineState = [_device newRenderPipelineStateWithDescriptor:pipelineStateDescriptor - error:&error]; - - // Pipeline State creation could fail if the pipeline descriptor isn't set up properly. - // If the Metal API validation is enabled, you can find out more information about what - // went wrong. (Metal API validation is enabled by default when a debug build is run - // from Xcode.) - NSAssert(_pipelineState, @"Failed to created pipeline state: %@", error); - - // Create the command queue - _commandQueue = [_device newCommandQueue]; - - u32 max_buffer_size = (u32)[_device maxBufferLength]; - printf("Max Buffer Size: %u - Which is %lu vertices\n", max_buffer_size, (max_buffer_size / sizeof(Render_Vertex))); - } - - return self; -} - -/// Called whenever view changes orientation or is resized -- (void)mtkView:(nonnull MTKView *)view drawableSizeWillChange:(CGSize)size{ - // Save the size of the drawable to pass to the vertex shader. - -} - -/// Called whenever the view needs to render a frame. -- (void)drawInMTKView:(nonnull MTKView *)view{ - CGSize size = [view drawableSize]; - _viewportSize.x = size.width; - _viewportSize.y = size.height; - - static const AAPLVertex triangleVertices[] = - { - // 2D positions, RGBA colors - { { 250, -250 }, { 1, 0, 0, 1 } }, - { { -250, -250 }, { 0, 1, 0, 1 } }, - { { 0, 250 }, { 0, 0, 1, 1 } }, - }; - - // Create a new command buffer for each render pass to the current drawable. - id commandBuffer = [_commandQueue commandBuffer]; - commandBuffer.label = @"MyCommand"; - - // Obtain a renderPassDescriptor generated from the view's drawable textures. - MTLRenderPassDescriptor *renderPassDescriptor = view.currentRenderPassDescriptor; - - if(renderPassDescriptor != nil) - { - // Create a render command encoder. - id renderEncoder = - [commandBuffer renderCommandEncoderWithDescriptor:renderPassDescriptor]; - renderEncoder.label = @"MyRenderEncoder"; - - // Set the region of the drawable to draw into. - [renderEncoder setViewport:(MTLViewport){0.0, 0.0, (double)_viewportSize.x, (double)_viewportSize.y, 0.0, 1.0 }]; - - [renderEncoder setRenderPipelineState:_pipelineState]; - - // Pass in the parameter data. - [renderEncoder setVertexBytes:triangleVertices - length:sizeof(triangleVertices) - atIndex:AAPLVertexInputIndexVertices]; - - [renderEncoder setVertexBytes:&_viewportSize - length:sizeof(_viewportSize) - atIndex:AAPLVertexInputIndexViewportSize]; - - // Draw the triangle. - [renderEncoder drawPrimitives:MTLPrimitiveTypeTriangle - vertexStart:0 - vertexCount:3]; - - [renderEncoder endEncoding]; - - // Schedule a present once the framebuffer is complete using the current drawable. - [commandBuffer presentDrawable:view.currentDrawable]; - } - - // Finalize rendering here & push the command buffer to the GPU. - [commandBuffer commit]; -} -@end - -function b32 +function void metal_init(Metal_Renderer *renderer, MTKView *view){ NSError *error = nil; @@ -229,15 +131,13 @@ metal_init(Metal_Renderer *renderer, MTKView *view){ id shader_library = [renderer->device newLibraryWithSource:shaders_source_str options:options error:&error]; - vertex_function = [shader_library newFunctionWithName:@"vertexShader"]; - fragment_function = [shader_library newFunctionWithName:@"fragmentShader"]; + vertex_function = [shader_library newFunctionWithName:@"vertex_shader"]; + fragment_function = [shader_library newFunctionWithName:@"fragment_shader"]; [options release]; } - if (error != nil){ - return(false); - } + Assert(error == nil); // NOTE(yuval): Configure the pipeline descriptor { @@ -246,14 +146,17 @@ metal_init(Metal_Renderer *renderer, MTKView *view){ pipeline_state_descriptor.vertexFunction = vertex_function; pipeline_state_descriptor.fragmentFunction = fragment_function; pipeline_state_descriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat; + pipeline_state_descriptor.colorAttachments[0].blendingEnabled = YES; + pipeline_state_descriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; + pipeline_state_descriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + pipeline_state_descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; + pipeline_state_descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; renderer->pipeline_state = [renderer->device newRenderPipelineStateWithDescriptor:pipeline_state_descriptor error:&error]; } - if (error != nil){ - return(false); - } + Assert(error == nil); // NOTE(yuval): Create the command queue renderer->command_queue = [renderer->device newCommandQueue]; @@ -266,17 +169,20 @@ metal_init(Metal_Renderer *renderer, MTKView *view){ options:options]; } - return(true); + // NOTE(yuval): Create a capture scope for gpu frame capture + renderer->capture_scope = [[MTLCaptureManager sharedCaptureManager] + newCaptureScopeWithDevice:renderer->device]; + renderer->capture_scope.label = @"4coder Metal Capture Scope"; } function void metal_render(Metal_Renderer *renderer, Render_Target *t){ - static const AAPLVertex triangleVertices[] = { - // 2D positions, RGBA colors - { { 200, 100 }, { 1, 0, 0, 1 } }, - { { 100, 100 }, { 0, 1, 0, 1 } }, - { { 150, 200 }, { 0, 0, 1, 1 } }, - }; + [renderer->capture_scope beginScope]; + + i32 width = t->width; + i32 height = t->height; + + Font_Set* font_set = (Font_Set*)t->font_set; // NOTE(yuval): Create the command buffer id command_buffer = [renderer->command_queue commandBuffer]; @@ -285,79 +191,95 @@ metal_render(Metal_Renderer *renderer, Render_Target *t){ // NOTE(yuval): Obtain the render pass descriptor from the renderer's view MTLRenderPassDescriptor *render_pass_descriptor = renderer->view.currentRenderPassDescriptor; if (render_pass_descriptor != nil){ + render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0f, 0.0f, 1.0f, 1.0f); + // NOTE(yuval): Create the render command encoder id render_encoder = [command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor]; render_encoder.label = @"4coder Render Encoder"; // NOTE(yuval): Set the region of the drawable to draw into - [render_encoder setViewport:(MTLViewport){0.0, 0.0, (double)t->width, (double)t->height, 0.0, 1.0}]; + [render_encoder setViewport:(MTLViewport){0.0, 0.0, (double)width, (double)height, 0.0, 1.0}]; // NOTE(yuval): Set the render pipeline to use for drawing [render_encoder setRenderPipelineState:renderer->pipeline_state]; - // NOTE(yuval): Pass in the parameter data - [render_encoder setVertexBytes:triangleVertices - length:sizeof(triangleVertices) - atIndex:AAPLVertexInputIndexVertices]; - -#if 0 - vector_uint2 viewport_size = {(u32)t->width, (u32)t->height}; - [render_encoder setVertexBytes:&viewport_size - length:sizeof(viewport_size) - atIndex:AAPLVertexInputIndexViewportSize]; -#else - float left = 0, right = (float)t->width; - float bottom = 0, top = (float)t->height; + // NOTE(yuval): Calculate and pass in the projection matrix + float left = 0, right = (float)width; + float bottom = (float)height, top = 0; float near_depth = -1.0f, far_depth = 1.0f; - float m[16] = { + float proj[16] = { 2.0f / (right - left), 0.0f, 0.0f, 0.0f, 0.0f, 2.0f / (top - bottom), 0.0f, 0.0f, 0.0f, 0.0f, -1.0f / (far_depth - near_depth), 0.0f, -((right + left) / (right - left)), -((top + bottom) / (top - bottom)), - (-near_depth) / (far_depth - near_depth), 1.0f + -(near_depth / (far_depth - near_depth)), 1.0f }; - float sLength = 1.0f / (right - left); - float sHeight = 1.0f / (top - bottom); - float sDepth = 1.0f / (far_depth - near_depth); - - simd::float4 P; - simd::float4 Q; - simd::float4 R; - simd::float4 S; - - P.x = 2.0f * sLength; - P.y = 0.0f; - P.z = 0.0f; - P.w = 0.0f; - - Q.x = 0.0f; - Q.y = 2.0f * sHeight; - Q.z = 0.0f; - Q.w = 0.0f; - - R.x = 0.0f; - R.y = 0.0f; - R.z = sDepth; - R.w = 0.0f; - - S.x = -((right + left) / (right - left)); - S.y = -((top + bottom) / (top - bottom)); - S.z = -near_depth * sDepth; - S.w = 1.0f; - - simd_float4x4 proj = simd::float4x4(P, Q, R, S); - - [render_encoder setVertexBytes:&proj - length:sizeof(proj) - atIndex:AAPLVertexInputIndexViewportSize]; -#endif - - // NOTE(yuval): Draw the triangle - [render_encoder drawPrimitives:MTLPrimitiveTypeTriangle - vertexStart:0 - vertexCount:3]; + for (Render_Group *group = t->group_first; + group; + group = group->next){ + // NOTE(yuval): Set scissor rect + { + Rect_i32 box = Ri32(group->clip_box); + MTLScissorRect scissor_rect; + + CGSize frame = [renderer->view drawableSize]; + printf("Drawable Size - w:%f h:%f\n", frame.width, frame.height); + + NSUInteger x0 = (NSUInteger)Min(Max(0, box.x0), frame.width - 1); + NSUInteger x1 = (NSUInteger)Min(Max(0, box.x1), frame.width); + NSUInteger y0 = (NSUInteger)Min(Max(0, box.y0), frame.height - 1); + NSUInteger y1 = (NSUInteger)Min(Max(0, box.y1), frame.height); + + scissor_rect.x = x0; + scissor_rect.y = y0; + scissor_rect.width = (x1 - x0); + scissor_rect.height = (y1 - y0); + + [render_encoder setScissorRect:scissor_rect]; + } + + i32 vertex_count = group->vertex_list.vertex_count; + if (vertex_count > 0){ + // TODO(yuval): Bind a texture + { + Face* face = font_set_face_from_id(font_set, group->face_id); + if (face != 0){ + // TODO(yuval): Bind face texture + } else{ + // TODO(yuval): Bind default texture + } + } + + // NOTE(yuval): Copy the vertex data to the vertex buffer + { + u8 *cursor = (u8*)[renderer->buffer contents]; + for (Render_Vertex_Array_Node *node = group->vertex_list.first; + node; + node = node->next){ + i32 size = node->vertex_count * sizeof(*node->vertices); + memcpy(cursor, node->vertices, size); + cursor += size; + } + } + + // NOTE(yuval): Pass the vertex buffer to the vertex shader + [render_encoder setVertexBuffer:renderer->buffer + offset:0 + atIndex:0]; + + // NOTE(yuval): Pass the projection matrix to the vertex shader + [render_encoder setVertexBytes:&proj + length:sizeof(proj) + atIndex:1]; + + // NOTE(yuval): Draw the vertices + [render_encoder drawPrimitives:MTLPrimitiveTypeTriangle + vertexStart:0 + vertexCount:vertex_count]; + } + } [render_encoder endEncoding]; @@ -366,4 +288,6 @@ metal_render(Metal_Renderer *renderer, Render_Target *t){ } [command_buffer commit]; + + [renderer->capture_scope endScope]; } \ No newline at end of file diff --git a/metal/AAPLShaderTypes.h b/metal/AAPLShaderTypes.h index be46a81a..a464b446 100644 --- a/metal/AAPLShaderTypes.h +++ b/metal/AAPLShaderTypes.h @@ -12,14 +12,6 @@ Header containing types and enum constants shared between Metal shaders and C/Ob #include #define clamp(a,x,b) clamp_((a),(x),(b)) -// Buffer index values shared between shader and C code to ensure Metal shader buffer inputs -// match Metal API buffer set calls. -typedef enum AAPLVertexInputIndex -{ - AAPLVertexInputIndexVertices = 0, - AAPLVertexInputIndexViewportSize = 1, -} AAPLVertexInputIndex; - // This structure defines the layout of vertices sent to the vertex // shader. This header is shared between the .metal shader and C code, to guarantee that // the layout of the vertex array in the C code matches the layout that the .metal diff --git a/opengl/4ed_opengl_render.cpp b/opengl/4ed_opengl_render.cpp index 7c2d5524..2246eaeb 100644 --- a/opengl/4ed_opengl_render.cpp +++ b/opengl/4ed_opengl_render.cpp @@ -129,7 +129,7 @@ sd = abs(sd + half_thickness) - half_thickness; float shape_value = 1.0 - smoothstep(-1.0, 0.0, sd); shape_value *= has_thickness; -out_color = vec4(fragment_color.xyz, fragment_color.a*(sample_value + shape_value)); +out_color = fragment_color;//vec4(fragment_color.xyz, fragment_color.a*(sample_value + shape_value)); } )foo"; diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index cae3a944..3cf2c7e6 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -440,7 +440,7 @@ this only gets called for window creation and other extraordinary events. [NSApp terminate:nil]; } - // mac_gl_render(&target); + //mac_gl_render(&target); mac_metal_render(&target); mac_vars.first = false; From a34d95b848962e6144da9bce6aa165410741ee94 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 7 Jan 2020 02:55:28 +0200 Subject: [PATCH 055/128] Metal renderer is now working (no textures yet). --- metal/4ed_metal_render.mm | 302 +++++++++++++++++++++++++--------- platform_mac/mac_4ed_metal.mm | 14 +- 2 files changed, 231 insertions(+), 85 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index cf760786..fb21d113 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -8,17 +8,26 @@ #include "AAPLShaderTypes.h" #define function static -struct Metal_Renderer{ - MTKView *view; - - id device; - id pipeline_state; - id command_queue; - id buffer; - id capture_scope; -}; +//////////////////////////////// -global_const u32 metal_max_vertices = (1<<16); +// TODO(yuval): Convert this to a struct when I handle my own caching solution +@interface Metal_Buffer : NSObject +@property (nonatomic, strong) id buffer; +@property (nonatomic, readonly) u32 size; +@property (nonatomic, assign) NSTimeInterval last_reuse_time; + +- (instancetype)initWithSize:(u32)size usingDevice:(id)device; +@end + +@interface Metal_Renderer : NSObject +@property (nonatomic) Render_Target *target; + +- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtkView; +- (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size; +- (void)add_reusable_buffer:(Metal_Buffer*)buffer; +@end + +//////////////////////////////// global_const char *metal__shaders_source = R"( #include @@ -29,10 +38,10 @@ using namespace metal; //////////////////////////////// typedef struct{ -packed_float2 xy; - packed_float3 uvw; -uint32_t color; -float half_thickness; +float2 xy [[attribute(0)]]; + float3 uvw [[attribute(1)]]; +uint32_t color [[attribute(2)]]; +float half_thickness [[attribute(3)]]; } Vertex; // NOTE(yuval): Vertex shader outputs and fragment shader inputs @@ -51,33 +60,32 @@ float4 position [[position]]; //////////////////////////////// vertex Rasterizer_Data -vertex_shader(uint vertex_id [[vertex_id]], constant Vertex *vertices [[buffer(0)]], +vertex_shader(Vertex in [[stage_in]], constant float4x4 &proj [[buffer(1)]]){ - constant Vertex *in = &vertices[vertex_id]; Rasterizer_Data out; // NOTE(yuval): Calculate position in NDC - out.position = proj * float4(in->xy, 0.0, 1.0); + out.position = proj * float4(in.xy, 0.0, 1.0); // NOTE(yuval): Convert color to float4 format - out.color.b = ((float((in->color ) & 0xFFu)) / 255.0); - out.color.g = ((float((in->color >> 8u) & 0xFFu)) / 255.0); - out.color.r = ((float((in->color >> 16u) & 0xFFu)) / 255.0); - out.color.a = ((float((in->color >> 24u) & 0xFFu)) / 255.0); + out.color.b = ((float((in.color ) & 0xFFu)) / 255.0); + out.color.g = ((float((in.color >> 8u) & 0xFFu)) / 255.0); + out.color.r = ((float((in.color >> 16u) & 0xFFu)) / 255.0); + out.color.a = ((float((in.color >> 24u) & 0xFFu)) / 255.0); // NOTE(yuval): Pass uvw coordinates to the fragment shader - out.uvw = in->uvw; + out.uvw = in.uvw; // NOTE(yuval): Calculate adjusted half dim - float2 center = in->uvw.xy; - float2 half_dim = abs(in->xy - center); - out.adjusted_half_dim = (half_dim - in->uvw.zz + float2(0.5, 0.5)); + float2 center = in.uvw.xy; + float2 half_dim = abs(in.xy - center); + out.adjusted_half_dim = (half_dim - in.uvw.zz + float2(0.5, 0.5)); // NOTE(yuval): Pass half_thickness to the fragment shader - out.half_thickness = in->half_thickness; + out.half_thickness = in.half_thickness; // NOTE(yuval): Pass xy to the fragment shader - out.xy = in->xy; + out.xy = in.xy; return(out); } @@ -113,12 +121,48 @@ shape_value *= has_thickness; } )"; -function void -metal_init(Metal_Renderer *renderer, MTKView *view){ +//////////////////////////////// + +@implementation Metal_Buffer +- (instancetype)initWithSize:(u32)size usingDevice:(id)device{ + self = [super init]; + if (self == nil){ + return(nil); + } + + // NOTE(yuval): Create the vertex buffer + MTLResourceOptions options = MTLCPUCacheModeWriteCombined|MTLResourceStorageModeManaged; + _buffer = [device newBufferWithLength:size options:options]; + _size = size; + + // NOTE(yuval): Set the last_reuse_time to the current time + _last_reuse_time = [NSDate date].timeIntervalSince1970; + + return(self); +} +@end + +//////////////////////////////// + +@implementation Metal_Renderer{ + id device; + id pipeline_state; + id command_queue; + id capture_scope; + + NSMutableArray *buffer_cache; + NSTimeInterval last_buffer_cache_purge_time; +} + +- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtk_view{ + self = [super init]; + if (self == nil){ + return(nil); + } + NSError *error = nil; - renderer->view = view; - renderer->device = view.device; + device = mtk_view.device; // NOTE(yuval): Compile the shaders id vertex_function = nil; @@ -129,7 +173,7 @@ metal_init(Metal_Renderer *renderer, MTKView *view){ MTLCompileOptions *options = [[MTLCompileOptions alloc] init]; options.fastMathEnabled = YES; - id shader_library = [renderer->device newLibraryWithSource:shaders_source_str + id shader_library = [device newLibraryWithSource:shaders_source_str options:options error:&error]; vertex_function = [shader_library newFunctionWithName:@"vertex_shader"]; fragment_function = [shader_library newFunctionWithName:@"fragment_shader"]; @@ -141,55 +185,78 @@ metal_init(Metal_Renderer *renderer, MTKView *view){ // NOTE(yuval): Configure the pipeline descriptor { + MTLVertexDescriptor *vertexDescriptor = [MTLVertexDescriptor vertexDescriptor]; + vertexDescriptor.attributes[0].offset = OffsetOfMember(Render_Vertex, xy); + vertexDescriptor.attributes[0].format = MTLVertexFormatFloat2; // position + vertexDescriptor.attributes[0].bufferIndex = 0; + vertexDescriptor.attributes[1].offset = OffsetOfMember(Render_Vertex, uvw); + vertexDescriptor.attributes[1].format = MTLVertexFormatFloat3; // texCoords + vertexDescriptor.attributes[1].bufferIndex = 0; + vertexDescriptor.attributes[2].offset = OffsetOfMember(Render_Vertex, color); + vertexDescriptor.attributes[2].format = MTLVertexFormatUInt; // color + vertexDescriptor.attributes[2].bufferIndex = 0; + vertexDescriptor.attributes[3].offset = OffsetOfMember(Render_Vertex, half_thickness); + vertexDescriptor.attributes[3].format = MTLVertexFormatFloat; // position + vertexDescriptor.attributes[3].bufferIndex = 0; + vertexDescriptor.layouts[0].stepRate = 1; + vertexDescriptor.layouts[0].stepFunction = MTLVertexStepFunctionPerVertex; + vertexDescriptor.layouts[0].stride = sizeof(Render_Vertex); + MTLRenderPipelineDescriptor *pipeline_state_descriptor = [[MTLRenderPipelineDescriptor alloc] init]; pipeline_state_descriptor.label = @"4coder Metal Renderer Pipeline"; pipeline_state_descriptor.vertexFunction = vertex_function; pipeline_state_descriptor.fragmentFunction = fragment_function; - pipeline_state_descriptor.colorAttachments[0].pixelFormat = view.colorPixelFormat; + pipeline_state_descriptor.vertexDescriptor = vertexDescriptor; + pipeline_state_descriptor.colorAttachments[0].pixelFormat = mtk_view.colorPixelFormat; pipeline_state_descriptor.colorAttachments[0].blendingEnabled = YES; + pipeline_state_descriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; + pipeline_state_descriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; pipeline_state_descriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; pipeline_state_descriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; - pipeline_state_descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; - pipeline_state_descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; + /*pipeline_state_descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; + pipeline_state_descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;*/ - renderer->pipeline_state = [renderer->device newRenderPipelineStateWithDescriptor:pipeline_state_descriptor + pipeline_state = [device newRenderPipelineStateWithDescriptor:pipeline_state_descriptor error:&error]; } Assert(error == nil); // NOTE(yuval): Create the command queue - renderer->command_queue = [renderer->device newCommandQueue]; + command_queue = [device newCommandQueue]; - // NOTE(yuval): Create the vertex buffer - { - u32 buffer_size = (metal_max_vertices * sizeof(Render_Vertex)); - MTLResourceOptions options = MTLCPUCacheModeWriteCombined|MTLResourceStorageModeManaged; - renderer->buffer = [renderer->device newBufferWithLength:buffer_size - options:options]; - } + // NOTE(yuval): Initialize buffer caching + buffer_cache = [NSMutableArray array]; + last_buffer_cache_purge_time = [NSDate date].timeIntervalSince1970; // NOTE(yuval): Create a capture scope for gpu frame capture - renderer->capture_scope = [[MTLCaptureManager sharedCaptureManager] - newCaptureScopeWithDevice:renderer->device]; - renderer->capture_scope.label = @"4coder Metal Capture Scope"; + capture_scope = [[MTLCaptureManager sharedCaptureManager] + newCaptureScopeWithDevice:device]; + capture_scope.label = @"4coder Metal Capture Scope"; + + return(self); } -function void -metal_render(Metal_Renderer *renderer, Render_Target *t){ - [renderer->capture_scope beginScope]; +- (void)mtkView:(nonnull MTKView*)view drawableSizeWillChange:(CGSize)size{ + // NOTE(yuval): Nothing to do here because we use the render target's dimentions for rendering +} + +- (void)drawInMTKView:(nonnull MTKView*)view{ + printf("Metal Renderer Draw!\n"); - i32 width = t->width; - i32 height = t->height; + [capture_scope beginScope]; - Font_Set* font_set = (Font_Set*)t->font_set; + i32 width = _target->width; + i32 height = _target->height; + + Font_Set* font_set = (Font_Set*)_target->font_set; // NOTE(yuval): Create the command buffer - id command_buffer = [renderer->command_queue commandBuffer]; + id command_buffer = [command_queue commandBuffer]; command_buffer.label = @"4coder Metal Render Command"; // NOTE(yuval): Obtain the render pass descriptor from the renderer's view - MTLRenderPassDescriptor *render_pass_descriptor = renderer->view.currentRenderPassDescriptor; + MTLRenderPassDescriptor *render_pass_descriptor = view.currentRenderPassDescriptor; if (render_pass_descriptor != nil){ render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0f, 0.0f, 1.0f, 1.0f); @@ -202,7 +269,7 @@ metal_render(Metal_Renderer *renderer, Render_Target *t){ [render_encoder setViewport:(MTLViewport){0.0, 0.0, (double)width, (double)height, 0.0, 1.0}]; // NOTE(yuval): Set the render pipeline to use for drawing - [render_encoder setRenderPipelineState:renderer->pipeline_state]; + [render_encoder setRenderPipelineState:pipeline_state]; // NOTE(yuval): Calculate and pass in the projection matrix float left = 0, right = (float)width; @@ -216,22 +283,44 @@ metal_render(Metal_Renderer *renderer, Render_Target *t){ -(near_depth / (far_depth - near_depth)), 1.0f }; - for (Render_Group *group = t->group_first; + // NOTE(yuval): Calculate required vertex buffer size + i32 all_vertex_count = 0; + for (Render_Group *group = _target->group_first; group; group = group->next){ + all_vertex_count += group->vertex_list.vertex_count; + } + + u32 vertex_buffer_size = (all_vertex_count * sizeof(Render_Vertex)); + + // NOTE(yuval): Find & Get a vertex buffer matching the required size + Metal_Buffer *buffer = [self get_reusable_buffer_with_size:vertex_buffer_size]; + + // NOTE(yuval): Pass the vertex buffer to the vertex shader + [render_encoder setVertexBuffer:buffer.buffer + offset:0 + atIndex:0]; + + // NOTE(yuval): Pass the projection matrix to the vertex shader + [render_encoder setVertexBytes:&proj + length:sizeof(proj) + atIndex:1]; + + u32 buffer_offset = 0; + i32 count = 0; + for (Render_Group *group = _target->group_first; + group; + group = group->next, ++count){ // NOTE(yuval): Set scissor rect { Rect_i32 box = Ri32(group->clip_box); + + NSUInteger x0 = (NSUInteger)Min(Max(0, box.x0), width - 1); + NSUInteger x1 = (NSUInteger)Min(Max(0, box.x1), width); + NSUInteger y0 = (NSUInteger)Min(Max(0, box.y0), height - 1); + NSUInteger y1 = (NSUInteger)Min(Max(0, box.y1), height); + MTLScissorRect scissor_rect; - - CGSize frame = [renderer->view drawableSize]; - printf("Drawable Size - w:%f h:%f\n", frame.width, frame.height); - - NSUInteger x0 = (NSUInteger)Min(Max(0, box.x0), frame.width - 1); - NSUInteger x1 = (NSUInteger)Min(Max(0, box.x1), frame.width); - NSUInteger y0 = (NSUInteger)Min(Max(0, box.y0), frame.height - 1); - NSUInteger y1 = (NSUInteger)Min(Max(0, box.y1), frame.height); - scissor_rect.x = x0; scissor_rect.y = y0; scissor_rect.width = (x1 - x0); @@ -254,7 +343,9 @@ metal_render(Metal_Renderer *renderer, Render_Target *t){ // NOTE(yuval): Copy the vertex data to the vertex buffer { - u8 *cursor = (u8*)[renderer->buffer contents]; + + u8 *group_buffer_contents = (u8*)[buffer.buffer contents] + buffer_offset; + u8 *cursor = group_buffer_contents; for (Render_Vertex_Array_Node *node = group->vertex_list.first; node; node = node->next){ @@ -262,32 +353,85 @@ metal_render(Metal_Renderer *renderer, Render_Target *t){ memcpy(cursor, node->vertices, size); cursor += size; } + + NSUInteger data_size = (NSUInteger)(cursor - group_buffer_contents); + NSRange modify_range = NSMakeRange(buffer_offset, data_size); + [buffer.buffer didModifyRange:modify_range]; } - // NOTE(yuval): Pass the vertex buffer to the vertex shader - [render_encoder setVertexBuffer:renderer->buffer - offset:0 - atIndex:0]; - - // NOTE(yuval): Pass the projection matrix to the vertex shader - [render_encoder setVertexBytes:&proj - length:sizeof(proj) - atIndex:1]; + // NOTE(yuval): Set the vertex buffer offset to the beginning of the group's vertices + [render_encoder setVertexBufferOffset:buffer_offset atIndex:0]; // NOTE(yuval): Draw the vertices [render_encoder drawPrimitives:MTLPrimitiveTypeTriangle vertexStart:0 vertexCount:vertex_count]; + + buffer_offset += (vertex_count * sizeof(Render_Vertex)); //((((vertex_count * sizeof(Render_Vertex)) + 256) / 256) * 256); } } [render_encoder endEncoding]; // NOTE(yuval): Schedule a present once the framebuffer is complete using the current drawable - [command_buffer presentDrawable:renderer->view.currentDrawable]; + [command_buffer presentDrawable:view.currentDrawable]; + + [command_buffer addCompletedHandler:^(id){ + dispatch_async(dispatch_get_main_queue(), ^{ + [self add_reusable_buffer:buffer]; + }); + }]; } + // NOTE(yuval): Finalize rendering here and push the command buffer to the GPU [command_buffer commit]; - [renderer->capture_scope endScope]; -} \ No newline at end of file + [capture_scope endScope]; +} + +- (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size{ + // NOTE(yuval): This routine is a modified version of Dear ImGui's MetalContext::dequeueReusableBufferOfLength in imgui_impl_metal.mm + + NSTimeInterval now = [NSDate date].timeIntervalSince1970; + + // NOTE(yuval): Purge old buffers that haven't been useful for a while + if ((now - last_buffer_cache_purge_time) > 1.0){ + NSMutableArray *survivors = [NSMutableArray array]; + for (Metal_Buffer *candidate in buffer_cache){ + if (candidate.last_reuse_time > last_buffer_cache_purge_time){ + [survivors addObject:candidate]; + } + } + + buffer_cache = [survivors mutableCopy]; + last_buffer_cache_purge_time = now; + } + + // NOTE(yuval): See if we have a buffer we can reuse + Metal_Buffer *best_candidate = 0; + for (Metal_Buffer *candidate in buffer_cache){ + if ((candidate.size >= size) && ((!best_candidate) || (best_candidate.last_reuse_time > candidate.last_reuse_time))){ + best_candidate = candidate; + } + } + + Metal_Buffer *result; + if (best_candidate){ + [buffer_cache removeObject:best_candidate]; + best_candidate.last_reuse_time = now; + result = best_candidate; + } else{ + result = [[Metal_Buffer alloc] initWithSize:size usingDevice:device]; + } + + // NOTE(yuval): No luck; make a new buffer + + return result; +} + +- (void)add_reusable_buffer:(Metal_Buffer*)buffer{ + // NOTE(yuval): This routine is a modified version of Dear ImGui's MetalContext::enqueueReusableBuffer in imgui_impl_metal.mm + + [buffer_cache addObject:buffer]; +} +@end diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm index ff69d8d3..4970feab 100644 --- a/platform_mac/mac_4ed_metal.mm +++ b/platform_mac/mac_4ed_metal.mm @@ -1,6 +1,6 @@ #import "metal/4ed_metal_render.mm" -global Metal_Renderer metal_renderer; +global Metal_Renderer *metal_renderer; global MTKView *metal_view; function void @@ -10,22 +10,24 @@ mac_metal_init(NSWindow *window){ metal_view = [[MTKView alloc] initWithFrame:[content_view bounds]]; [metal_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [metal_view setPaused:YES]; + [metal_view setEnableSetNeedsDisplay:NO]; metal_view.device = MTLCreateSystemDefaultDevice(); // NOTE(yuval): Add the Metal view as a subview of the window [content_view addSubview:metal_view]; - // NOTE(yuval): Create the Metal renderer - //metal_renderer = [[FCoderMetalRenderer alloc] initWithMetalKitView:metal_view]; - metal_init(&metal_renderer, metal_view); + // NOTE(yuval): Create the Metal renderer and set it as the Metal view's delegate + metal_renderer = [[Metal_Renderer alloc] initWithMetalKitView:metal_view]; + metal_view.delegate = metal_renderer; } function void mac_metal_render(Render_Target* target){ u64 begin_time = system_now_time(); - //[metal_renderer drawInMTKView:metal_view]; - metal_render(&metal_renderer, target); + metal_renderer.target = target; + [metal_view draw]; u64 end_time = system_now_time(); printf("Metal Render Time: %fs\n\n", mac_get_time_diff_sec(begin_time, end_time)); } \ No newline at end of file From a18ef3197a7ecfaa39a48ac5e17ea6ac3d56e53c Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Wed, 8 Jan 2020 01:45:36 +0200 Subject: [PATCH 056/128] Implemented my own vertex buffers management, also started working on textures. --- metal/4ed_metal_render.mm | 163 ++++++++++++++++++++------------------ platform_mac/mac_4ed.mm | 4 +- 2 files changed, 88 insertions(+), 79 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index fb21d113..a1d8e7f0 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -10,14 +10,19 @@ //////////////////////////////// -// TODO(yuval): Convert this to a struct when I handle my own caching solution -@interface Metal_Buffer : NSObject -@property (nonatomic, strong) id buffer; -@property (nonatomic, readonly) u32 size; -@property (nonatomic, assign) NSTimeInterval last_reuse_time; +struct Metal_Buffer{ + Node node; + + id buffer; + u32 size; + u64 last_reuse_time; +}; -- (instancetype)initWithSize:(u32)size usingDevice:(id)device; -@end +struct Metal_Texture{ + +}; + +//////////////////////////////// @interface Metal_Renderer : NSObject @property (nonatomic) Render_Target *target; @@ -39,7 +44,7 @@ using namespace metal; typedef struct{ float2 xy [[attribute(0)]]; - float3 uvw [[attribute(1)]]; +float3 uvw [[attribute(1)]]; uint32_t color [[attribute(2)]]; float half_thickness [[attribute(3)]]; } Vertex; @@ -50,11 +55,11 @@ typedef struct{ float4 position [[position]]; // NOTE(yuval): Fragment shader inputs - float4 color; - float3 uvw; - float2 xy; - float2 adjusted_half_dim; - float half_thickness; +float4 color; +float3 uvw; +float2 xy; +float2 adjusted_half_dim; +float half_thickness; } Rasterizer_Data; //////////////////////////////// @@ -62,32 +67,32 @@ float4 position [[position]]; vertex Rasterizer_Data vertex_shader(Vertex in [[stage_in]], constant float4x4 &proj [[buffer(1)]]){ - Rasterizer_Data out; - - // NOTE(yuval): Calculate position in NDC - out.position = proj * float4(in.xy, 0.0, 1.0); - - // NOTE(yuval): Convert color to float4 format - out.color.b = ((float((in.color ) & 0xFFu)) / 255.0); - out.color.g = ((float((in.color >> 8u) & 0xFFu)) / 255.0); - out.color.r = ((float((in.color >> 16u) & 0xFFu)) / 255.0); - out.color.a = ((float((in.color >> 24u) & 0xFFu)) / 255.0); - - // NOTE(yuval): Pass uvw coordinates to the fragment shader - out.uvw = in.uvw; - - // NOTE(yuval): Calculate adjusted half dim - float2 center = in.uvw.xy; - float2 half_dim = abs(in.xy - center); - out.adjusted_half_dim = (half_dim - in.uvw.zz + float2(0.5, 0.5)); - - // NOTE(yuval): Pass half_thickness to the fragment shader - out.half_thickness = in.half_thickness; - - // NOTE(yuval): Pass xy to the fragment shader - out.xy = in.xy; - - return(out); +Rasterizer_Data out; + +// NOTE(yuval): Calculate position in NDC +out.position = proj * float4(in.xy, 0.0, 1.0); + +// NOTE(yuval): Convert color to float4 format +out.color.b = ((float((in.color ) & 0xFFu)) / 255.0); +out.color.g = ((float((in.color >> 8u) & 0xFFu)) / 255.0); +out.color.r = ((float((in.color >> 16u) & 0xFFu)) / 255.0); +out.color.a = ((float((in.color >> 24u) & 0xFFu)) / 255.0); + +// NOTE(yuval): Pass uvw coordinates to the fragment shader +out.uvw = in.uvw; + +// NOTE(yuval): Calculate adjusted half dim +float2 center = in.uvw.xy; +float2 half_dim = abs(in.xy - center); +out.adjusted_half_dim = (half_dim - in.uvw.zz + float2(0.5, 0.5)); + +// NOTE(yuval): Pass half_thickness to the fragment shader +out.half_thickness = in.half_thickness; + +// NOTE(yuval): Pass xy to the fragment shader +out.xy = in.xy; + +return(out); } //////////////////////////////// @@ -115,32 +120,28 @@ sd = (abs(sd + in.half_thickness) - in.half_thickness); float shape_value = (1.0 - smoothstep(-1.0, 0.0, sd)); shape_value *= has_thickness; - // TOOD(yuval): Add sample_value to alpha - float4 out_color = in.color;// float4(in.color.xyz, in.color.a * (shape_value)); - return(out_color); +// TOOD(yuval): Add sample_value to alpha +float4 out_color = in.color;// float4(in.color.xyz, in.color.a * (shape_value)); +return(out_color); } )"; //////////////////////////////// -@implementation Metal_Buffer -- (instancetype)initWithSize:(u32)size usingDevice:(id)device{ - self = [super init]; - if (self == nil){ - return(nil); - } +function Metal_Buffer* +metal__make_buffer(u32 size, id device){ + Metal_Buffer *result = (Metal_Buffer*)malloc(sizeof(Metal_Buffer)); // NOTE(yuval): Create the vertex buffer MTLResourceOptions options = MTLCPUCacheModeWriteCombined|MTLResourceStorageModeManaged; - _buffer = [device newBufferWithLength:size options:options]; - _size = size; + result->buffer = [device newBufferWithLength:size options:options]; + result->size = size; // NOTE(yuval): Set the last_reuse_time to the current time - _last_reuse_time = [NSDate date].timeIntervalSince1970; + result->last_reuse_time = system_now_time(); - return(self); + return result; } -@end //////////////////////////////// @@ -150,8 +151,8 @@ shape_value *= has_thickness; id command_queue; id capture_scope; - NSMutableArray *buffer_cache; - NSTimeInterval last_buffer_cache_purge_time; + Node buffer_cache; + u64 last_buffer_cache_purge_time; } - (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtk_view{ @@ -182,6 +183,7 @@ shape_value *= has_thickness; } Assert(error == nil); + Assert((vertex_function != nil) && (fragment_function != nil)); // NOTE(yuval): Configure the pipeline descriptor { @@ -226,8 +228,8 @@ shape_value *= has_thickness; command_queue = [device newCommandQueue]; // NOTE(yuval): Initialize buffer caching - buffer_cache = [NSMutableArray array]; - last_buffer_cache_purge_time = [NSDate date].timeIntervalSince1970; + dll_init_sentinel(&buffer_cache); + last_buffer_cache_purge_time = system_now_time(); // NOTE(yuval): Create a capture scope for gpu frame capture capture_scope = [[MTLCaptureManager sharedCaptureManager] @@ -249,7 +251,7 @@ shape_value *= has_thickness; i32 width = _target->width; i32 height = _target->height; - Font_Set* font_set = (Font_Set*)_target->font_set; + Font_Set *font_set = (Font_Set*)_target->font_set; // NOTE(yuval): Create the command buffer id command_buffer = [command_queue commandBuffer]; @@ -297,7 +299,7 @@ shape_value *= has_thickness; Metal_Buffer *buffer = [self get_reusable_buffer_with_size:vertex_buffer_size]; // NOTE(yuval): Pass the vertex buffer to the vertex shader - [render_encoder setVertexBuffer:buffer.buffer + [render_encoder setVertexBuffer:buffer->buffer offset:0 atIndex:0]; @@ -344,7 +346,7 @@ shape_value *= has_thickness; // NOTE(yuval): Copy the vertex data to the vertex buffer { - u8 *group_buffer_contents = (u8*)[buffer.buffer contents] + buffer_offset; + u8 *group_buffer_contents = (u8*)[buffer->buffer contents] + buffer_offset; u8 *cursor = group_buffer_contents; for (Render_Vertex_Array_Node *node = group->vertex_list.first; node; @@ -356,7 +358,7 @@ shape_value *= has_thickness; NSUInteger data_size = (NSUInteger)(cursor - group_buffer_contents); NSRange modify_range = NSMakeRange(buffer_offset, data_size); - [buffer.buffer didModifyRange:modify_range]; + [buffer->buffer didModifyRange:modify_range]; } // NOTE(yuval): Set the vertex buffer offset to the beginning of the group's vertices @@ -367,7 +369,7 @@ shape_value *= has_thickness; vertexStart:0 vertexCount:vertex_count]; - buffer_offset += (vertex_count * sizeof(Render_Vertex)); //((((vertex_count * sizeof(Render_Vertex)) + 256) / 256) * 256); + buffer_offset += (vertex_count * sizeof(Render_Vertex)); } } @@ -392,46 +394,53 @@ shape_value *= has_thickness; - (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size{ // NOTE(yuval): This routine is a modified version of Dear ImGui's MetalContext::dequeueReusableBufferOfLength in imgui_impl_metal.mm - NSTimeInterval now = [NSDate date].timeIntervalSince1970; + u64 now = system_now_time(); // NOTE(yuval): Purge old buffers that haven't been useful for a while - if ((now - last_buffer_cache_purge_time) > 1.0){ - NSMutableArray *survivors = [NSMutableArray array]; - for (Metal_Buffer *candidate in buffer_cache){ - if (candidate.last_reuse_time > last_buffer_cache_purge_time){ - [survivors addObject:candidate]; + if ((now - last_buffer_cache_purge_time) > 1000000){ + Node prev_buffer_cache = buffer_cache; + dll_init_sentinel(&buffer_cache); + + for (Node *node = prev_buffer_cache.next; + node != &buffer_cache; + node = node->next){ + Metal_Buffer *candidate = CastFromMember(Metal_Buffer, node, node); + if (candidate->last_reuse_time > last_buffer_cache_purge_time){ + dll_insert(&buffer_cache, node); } } - buffer_cache = [survivors mutableCopy]; last_buffer_cache_purge_time = now; } // NOTE(yuval): See if we have a buffer we can reuse Metal_Buffer *best_candidate = 0; - for (Metal_Buffer *candidate in buffer_cache){ - if ((candidate.size >= size) && ((!best_candidate) || (best_candidate.last_reuse_time > candidate.last_reuse_time))){ + for (Node *node = buffer_cache.next; + node != &buffer_cache; + node = node->next){ + Metal_Buffer *candidate = CastFromMember(Metal_Buffer, node, node); + if ((candidate->size >= size) && ((!best_candidate) || (best_candidate->last_reuse_time > candidate->last_reuse_time))){ best_candidate = candidate; } } Metal_Buffer *result; if (best_candidate){ - [buffer_cache removeObject:best_candidate]; - best_candidate.last_reuse_time = now; + // NOTE(yuval): A best candidate has been found! Remove it from the buffer list and set its last reuse time. + dll_remove(&best_candidate->node); + best_candidate->last_reuse_time = now; result = best_candidate; } else{ - result = [[Metal_Buffer alloc] initWithSize:size usingDevice:device]; + // NOTE(yuval): No luck; make a new buffer. + result = metal__make_buffer(size, device); } - // NOTE(yuval): No luck; make a new buffer - return result; } - (void)add_reusable_buffer:(Metal_Buffer*)buffer{ // NOTE(yuval): This routine is a modified version of Dear ImGui's MetalContext::enqueueReusableBuffer in imgui_impl_metal.mm - [buffer_cache addObject:buffer]; + dll_insert(&buffer_cache, &buffer->node); } @end diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 3cf2c7e6..6ea09e72 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -460,8 +460,8 @@ this only gets called for window creation and other extraordinary events. return(YES); } -- (void)keyDown:(NSEvent *)event{ - NSString* characters = [event characters]; +- (void)keyDown:(NSEvent*)event{ + NSString *characters = [event characters]; if ([characters length] != 0) { u32 character_code = [characters characterAtIndex:0]; From 521fb82113b9d6d49e30774bf00a6d173ee976ff Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Wed, 8 Jan 2020 21:44:47 +0200 Subject: [PATCH 057/128] The Metal renderer is now fully functioning. --- metal/4ed_metal_render.mm | 82 ++++++++++++++++++++++++++++--- platform_mac/mac_4ed.mm | 8 +++ platform_mac/mac_4ed_functions.mm | 6 +-- platform_mac/mac_4ed_metal.mm | 20 ++++++++ 4 files changed, 105 insertions(+), 11 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index a1d8e7f0..147af602 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -10,6 +10,8 @@ //////////////////////////////// +typedef id Metal_Texture; + struct Metal_Buffer{ Node node; @@ -18,22 +20,24 @@ struct Metal_Buffer{ u64 last_reuse_time; }; -struct Metal_Texture{ - -}; - //////////////////////////////// @interface Metal_Renderer : NSObject @property (nonatomic) Render_Target *target; - (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtkView; +- (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind; +- (b32)fill_texture:(u32)texture kind:(Texture_Kind)kind pos:(Vec3_i32)p dim:(Vec3_i32)dim data:(void*)data; - (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size; - (void)add_reusable_buffer:(Metal_Buffer*)buffer; @end //////////////////////////////// +global_const u32 metal__max_textures = 256; + +//////////////////////////////// + global_const char *metal__shaders_source = R"( #include #include @@ -106,11 +110,14 @@ return(result); } fragment float4 -fragment_shader(Rasterizer_Data in [[stage_in]]){ +fragment_shader(Rasterizer_Data in [[stage_in]], +texture2d_array in_texture [[texture(0)]]){ float has_thickness = step(0.49, in.half_thickness); -// float does_not_have_thickness = (1.0 - has_thickness); +float does_not_have_thickness = (1.0 - has_thickness); -// TODO(yuval): Sample texture here. +constexpr sampler texture_sampler(coord::normalized, min_filter::linear, mag_filter::linear, mip_filter::linear); +half sample_value = in_texture.sample(texture_sampler, in.uvw.xy, in.uvw.z).r; +sample_value *= does_not_have_thickness; float2 center = in.uvw.xy; float roundness = in.uvw.z; @@ -121,7 +128,7 @@ float shape_value = (1.0 - smoothstep(-1.0, 0.0, sd)); shape_value *= has_thickness; // TOOD(yuval): Add sample_value to alpha -float4 out_color = in.color;// float4(in.color.xyz, in.color.a * (shape_value)); +float4 out_color = float4(in.color.xyz, in.color.a * (sample_value + shape_value)); return(out_color); } )"; @@ -153,6 +160,9 @@ metal__make_buffer(u32 size, id device){ Node buffer_cache; u64 last_buffer_cache_purge_time; + + Metal_Texture *textures; + u32 next_texture_handle_index; } - (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtk_view{ @@ -209,6 +219,7 @@ metal__make_buffer(u32 size, id device){ pipeline_state_descriptor.vertexFunction = vertex_function; pipeline_state_descriptor.fragmentFunction = fragment_function; pipeline_state_descriptor.vertexDescriptor = vertexDescriptor; + pipeline_state_descriptor.sampleCount = mtk_view.sampleCount; pipeline_state_descriptor.colorAttachments[0].pixelFormat = mtk_view.colorPixelFormat; pipeline_state_descriptor.colorAttachments[0].blendingEnabled = YES; pipeline_state_descriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; @@ -231,6 +242,10 @@ metal__make_buffer(u32 size, id device){ dll_init_sentinel(&buffer_cache); last_buffer_cache_purge_time = system_now_time(); + // NOTE(yuval): Initialize the textures array + textures = (Metal_Texture*)system_memory_allocate(metal__max_textures * sizeof(Metal_Texture), file_name_line_number_lit_u8); + next_texture_handle_index = 0; + // NOTE(yuval): Create a capture scope for gpu frame capture capture_scope = [[MTLCaptureManager sharedCaptureManager] newCaptureScopeWithDevice:device]; @@ -338,6 +353,12 @@ metal__make_buffer(u32 size, id device){ Face* face = font_set_face_from_id(font_set, group->face_id); if (face != 0){ // TODO(yuval): Bind face texture + u32 texture_handle = face->texture; + Metal_Texture texture = textures[texture_handle]; + if (texture != 0){ + [render_encoder setFragmentTexture:texture + atIndex:0]; + } } else{ // TODO(yuval): Bind default texture } @@ -391,6 +412,51 @@ metal__make_buffer(u32 size, id device){ [capture_scope endScope]; } +- (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind{ + u32 handle = next_texture_handle_index; + + // NOTE(yuval): Create a texture descriptor + MTLTextureDescriptor *texture_descriptor = [[MTLTextureDescriptor alloc] init]; + texture_descriptor.textureType = MTLTextureType2DArray; + texture_descriptor.pixelFormat = MTLPixelFormatR8Unorm; + texture_descriptor.width = dim.x; + texture_descriptor.height = dim.y; + texture_descriptor.depth = dim.z; + + // NOTE(yuval): Create the texture from the device using the descriptor and add it to the textures array + Metal_Texture texture = [device newTextureWithDescriptor:texture_descriptor]; + textures[handle] = texture; + + next_texture_handle_index += 1; + + return handle; +} + +- (b32)fill_texture:(u32)handle kind:(Texture_Kind)kind pos:(Vec3_i32)p dim:(Vec3_i32)dim data:(void*)data{ + b32 result = false; + + if (data){ + Metal_Texture texture = textures[handle]; + + if (texture != 0){ + MTLRegion replace_region = { + {(NSUInteger)p.x, (NSUInteger)p.y, (NSUInteger)p.z}, + {(NSUInteger)dim.x, (NSUInteger)dim.y, (NSUInteger)dim.z} + }; + + // NOTE(yuval): Fill the texture with data + [texture replaceRegion:replace_region + mipmapLevel:0 + withBytes:data + bytesPerRow:dim.x]; + + result = true; + } + } + + return result; +} + - (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size{ // NOTE(yuval): This routine is a modified version of Dear ImGui's MetalContext::dequeueReusableBufferOfLength in imgui_impl_metal.mm diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 6ea09e72..05d07a2a 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -318,6 +318,7 @@ mac_file_can_be_made(u8* filename){ function void mac_resize(float width, float height){ if ((width > 0.0f) && (height > 0.0f)){ +#if 1 NSSize coord_size = NSMakeSize(width, height); NSSize backing_size = [mac_vars.view convertSizeToBacking:coord_size]; @@ -326,6 +327,13 @@ mac_resize(float width, float height){ target.width = (i32)backing_size.width; target.height = (i32)backing_size.height; +#else + mac_vars.width = (i32)width; + mac_vars.height = (i32)height; + + target.width = (i32)width; + target.height = (i32)height; +#endif } system_signal_step(0); diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index aa3f619d..11dac318 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -30,7 +30,7 @@ system_get_path_sig(){ local_persist b32 has_stashed_4ed_path = false; if (!has_stashed_4ed_path){ local_const i32 binary_path_capacity = KB(32); - u8 *memory = (u8*)system_memory_allocate(binary_path_capacity, string_u8_litexpr(file_name_line_number)); + u8 *memory = (u8*)system_memory_allocate(binary_path_capacity, file_name_line_number_lit_u8); pid_t pid = getpid(); i32 size = proc_pidpath(pid, memory, binary_path_capacity); @@ -804,13 +804,13 @@ system_get_keyboard_modifiers_sig(){ function graphics_get_texture_sig(){ - u32 result = gl__get_texture(dim, texture_kind); + u32 result = mac_metal_get_texture(dim, texture_kind); return(result); } function graphics_fill_texture_sig(){ - b32 result = gl__fill_texture(texture_kind, texture, p, dim, data); + b32 result = mac_metal_fill_texture(texture_kind, texture, p, dim, data); return(result); } diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm index 4970feab..063e618a 100644 --- a/platform_mac/mac_4ed_metal.mm +++ b/platform_mac/mac_4ed_metal.mm @@ -12,6 +12,7 @@ mac_metal_init(NSWindow *window){ [metal_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [metal_view setPaused:YES]; [metal_view setEnableSetNeedsDisplay:NO]; + [metal_view setSampleCount:4]; metal_view.device = MTLCreateSystemDefaultDevice(); @@ -30,4 +31,23 @@ mac_metal_render(Render_Target* target){ [metal_view draw]; u64 end_time = system_now_time(); printf("Metal Render Time: %fs\n\n", mac_get_time_diff_sec(begin_time, end_time)); +} + +function u32 +mac_metal_get_texture(Vec3_i32 dim, Texture_Kind texture_kind){ + u32 result = [metal_renderer get_texture_of_dim:dim + kind:texture_kind]; + + return result; +} + +function b32 +mac_metal_fill_texture(Texture_Kind texture_kind, u32 texture, Vec3_i32 p, Vec3_i32 dim, void *data){ + b32 result = [metal_renderer fill_texture:texture + kind:texture_kind + pos:p + dim:dim + data:data]; + + return result; } \ No newline at end of file From 912bcae8a7ff287d555b0fe375f5a134edb9b22a Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 9 Jan 2020 02:15:25 +0200 Subject: [PATCH 058/128] Started working on an abstraction for the macOS renderer implementations. --- metal/4ed_metal_render.mm | 7 +- opengl/4ed_opengl_render.cpp | 13 +-- platform_mac/mac_4ed.mm | 61 +++++++------- platform_mac/mac_4ed_functions.mm | 4 +- platform_mac/mac_4ed_metal.mm | 7 +- platform_mac/mac_4ed_opengl.mm | 129 ++++++++++++++++++------------ platform_mac/mac_4ed_renderer.h | 42 ++++++++++ platform_mac/mac_4ed_renderer.mm | 33 ++++++++ 8 files changed, 194 insertions(+), 102 deletions(-) create mode 100644 platform_mac/mac_4ed_renderer.h create mode 100644 platform_mac/mac_4ed_renderer.mm diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index 147af602..d5126396 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -263,8 +263,10 @@ metal__make_buffer(u32 size, id device){ [capture_scope beginScope]; - i32 width = _target->width; - i32 height = _target->height; + // HACK(yuval): This is the best way I found to force valid width and height without drawing on the next drawing cycle (1 frame delay). + CGSize drawable_size = [view drawableSize]; + i32 width = (i32)Min(_target->width, drawable_size.width); + i32 height = (i32)Min(_target->height, drawable_size.height); Font_Set *font_set = (Font_Set*)_target->font_set; @@ -332,6 +334,7 @@ metal__make_buffer(u32 size, id device){ { Rect_i32 box = Ri32(group->clip_box); + NSUInteger x0 = (NSUInteger)Min(Max(0, box.x0), width - 1); NSUInteger x1 = (NSUInteger)Min(Max(0, box.x1), width); NSUInteger y0 = (NSUInteger)Min(Max(0, box.y0), height - 1); diff --git a/opengl/4ed_opengl_render.cpp b/opengl/4ed_opengl_render.cpp index 2246eaeb..69071502 100644 --- a/opengl/4ed_opengl_render.cpp +++ b/opengl/4ed_opengl_render.cpp @@ -129,7 +129,7 @@ sd = abs(sd + half_thickness) - half_thickness; float shape_value = 1.0 - smoothstep(-1.0, 0.0, sd); shape_value *= has_thickness; -out_color = fragment_color;//vec4(fragment_color.xyz, fragment_color.a*(sample_value + shape_value)); +out_color = vec4(fragment_color.xyz, fragment_color.a*(sample_value + shape_value)); } )foo"; @@ -285,8 +285,6 @@ gl_render(Render_Target *t){ t->free_texture_first = 0; t->free_texture_last = 0; - u32 all_vertex_count = 0; - u64 begin_draw = system_now_time(); for (Render_Group *group = t->group_first; group != 0; @@ -342,18 +340,9 @@ gl_render(Render_Target *t){ glDisableVertexAttribArray(gpu_program.vertex_c); glDisableVertexAttribArray(gpu_program.vertex_ht); } - - all_vertex_count += vertex_count; } - u64 end_draw = system_now_time(); - printf("Draw time: %fs\n", mac_get_time_diff_sec(begin_draw, end_draw)); - u64 begin_flush = system_now_time(); glFlush(); - u64 end_flush = system_now_time(); - printf("Flush time: %fs\n", mac_get_time_diff_sec(begin_flush, end_flush)); - - printf("Drawn %d Vertices\n", all_vertex_count); } // BOTTOM diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 05d07a2a..33f645f7 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -132,8 +132,6 @@ struct Mac_Input_Chunk{ //////////////////////////////// -//////////////////////////////// - typedef i32 Mac_Object_Kind; enum{ MacObjectKind_ERROR = 0, @@ -203,7 +201,12 @@ struct Mac_Vars { //////////////////////////////// +#include "mac_4ed_renderer.h" + +//////////////////////////////// + global Mac_Vars mac_vars; +global Mac_Renderer *renderer; global Render_Target target; global App_Functions app; @@ -269,30 +272,6 @@ mac_to_object(Plat_Handle handle){ //////////////////////////////// -#include -#include -#import "mac_4ed_opengl.mm" - -#import "mac_4ed_metal.mm" - -#include "4ed_font_provider_freetype.h" -#include "4ed_font_provider_freetype.cpp" - -#import "mac_4ed_functions.mm" - - - -//////////////////////////////// - -global Key_Code keycode_lookup_table[255]; - -function void -mac_key_code_init(void){ - -} - -//////////////////////////////// - function void mac_error_box(char *msg, b32 shutdown = true){ NSAlert *alert = [[[NSAlert alloc] init] autorelease]; @@ -309,6 +288,26 @@ mac_error_box(char *msg, b32 shutdown = true){ } } +//////////////////////////////// + +#import "mac_4ed_renderer.mm" + +#include "4ed_font_provider_freetype.h" +#include "4ed_font_provider_freetype.cpp" + +#import "mac_4ed_functions.mm" + +//////////////////////////////// + +global Key_Code keycode_lookup_table[255]; + +function void +mac_key_code_init(void){ + +} + +//////////////////////////////// + function b32 mac_file_can_be_made(u8* filename){ b32 result = access((char*)filename, W_OK) == 0; @@ -389,7 +388,7 @@ mac_resize(NSWindow *window){ } - (void)viewDidChangeBackingProperties{ - // NOTE(yuval): Screen scale factor calculation + // TODO(yuval): Screen scale factor calculation printf("Backing changed!\n"); mac_resize(mac_vars.window); } @@ -449,7 +448,8 @@ this only gets called for window creation and other extraordinary events. } //mac_gl_render(&target); - mac_metal_render(&target); + //mac_metal_render(&target); + renderer->render(renderer, &target); mac_vars.first = false; @@ -707,8 +707,9 @@ main(int arg_count, char **args){ [mac_vars.window makeKeyAndOrderFront:nil]; // NOTE(yuval): Initialize the renderer - mac_gl_init(mac_vars.window); - mac_metal_init(mac_vars.window); + //mac_gl_init(mac_vars.window); + //mac_metal_init(mac_vars.window, &target); + renderer = mac_init_renderer(MacRenderer_OpenGL, mac_vars.window, &target); mac_resize(w, h); diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 11dac318..c1c37bae 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -804,13 +804,13 @@ system_get_keyboard_modifiers_sig(){ function graphics_get_texture_sig(){ - u32 result = mac_metal_get_texture(dim, texture_kind); + u32 result = renderer->get_texture(renderer, dim, texture_kind); return(result); } function graphics_fill_texture_sig(){ - b32 result = mac_metal_fill_texture(texture_kind, texture, p, dim, data); + b32 result = renderer->fill_texture(renderer, texture_kind, texture, p, dim, data); return(result); } diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm index 063e618a..ba44930b 100644 --- a/platform_mac/mac_4ed_metal.mm +++ b/platform_mac/mac_4ed_metal.mm @@ -4,7 +4,7 @@ global Metal_Renderer *metal_renderer; global MTKView *metal_view; function void -mac_metal_init(NSWindow *window){ +mac_metal_init(NSWindow *window, Render_Target *target){ // NOTE(yuval): Create Metal view NSView *content_view = [window contentView]; @@ -26,11 +26,8 @@ mac_metal_init(NSWindow *window){ function void mac_metal_render(Render_Target* target){ - u64 begin_time = system_now_time(); metal_renderer.target = target; [metal_view draw]; - u64 end_time = system_now_time(); - printf("Metal Render Time: %fs\n\n", mac_get_time_diff_sec(begin_time, end_time)); } function u32 @@ -50,4 +47,4 @@ mac_metal_fill_texture(Texture_Kind texture_kind, u32 texture, Vec3_i32 p, Vec3_ data:data]; return result; -} \ No newline at end of file +} diff --git a/platform_mac/mac_4ed_opengl.mm b/platform_mac/mac_4ed_opengl.mm index ba1f4dee..0a73c9c9 100644 --- a/platform_mac/mac_4ed_opengl.mm +++ b/platform_mac/mac_4ed_opengl.mm @@ -1,24 +1,38 @@ /* Mac OpenGL layer for 4coder */ +#include "mac_4ed_renderer.h" + +//////////////////////////////// +#include +#include + #include "opengl/4ed_opengl_defines.h" #define GL_FUNC(N,R,P) typedef R (CALL_CONVENTION N##_Function)P; N##_Function *N = 0; #include "mac_4ed_opengl_funcs.h" -f64 mac_get_time_diff_sec(u64 begin, u64 end){ - f64 result = ((end - begin) / 1000000.0); - return result; -} +//////////////////////////////// #include "opengl/4ed_opengl_render.cpp" -@interface OpenGLView : NSOpenGLView -- (void)initGL; +//////////////////////////////// + +@interface OpenGL_View : NSOpenGLView +- (void)init_gl; - (void)render:(Render_Target*)target; @end -@implementation OpenGLView{ - b32 glIsInitialized; +//////////////////////////////// + +struct Mac_OpenGL_Renderer{ + Mac_Renderer base; + OpenGL_View *opengl_view; +}; + +//////////////////////////////// + +@implementation OpenGL_View{ + b32 gl_is_initialized; } - (id)init{ @@ -27,8 +41,8 @@ f64 mac_get_time_diff_sec(u64 begin, u64 end){ return nil; } - glIsInitialized = false; - [self initGL]; + gl_is_initialized = false; + [self init_gl]; return self; } @@ -43,13 +57,13 @@ f64 mac_get_time_diff_sec(u64 begin, u64 end){ [[self openGLContext] makeCurrentContext]; // NOTE(yuval): Setup vsync - GLint swapInt = 1; - printf("Using vsync: %d\n", swapInt); - [[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval]; + GLint swap_int = 1; + printf("Using vsync: %d\n", swap_int); + [[self openGLContext] setValues:&swap_int forParameter:NSOpenGLCPSwapInterval]; } - (void)awakeFromNib{ - [self initGL]; + [self init_gl]; } - (void)reshape{ @@ -59,8 +73,8 @@ f64 mac_get_time_diff_sec(u64 begin, u64 end){ [[self openGLContext] update]; } -- (void)initGL{ - if (glIsInitialized){ +- (void)init_gl{ + if (gl_is_initialized){ return; } @@ -92,65 +106,78 @@ f64 mac_get_time_diff_sec(u64 begin, u64 end){ [pixel_format release]; - glIsInitialized = true; + gl_is_initialized = true; } - (void)render:(Render_Target*)target{ - Assert(glIsInitialized); + Assert(gl_is_initialized); - u64 context_lock_begin = system_now_time(); CGLLockContext([[self openGLContext] CGLContextObj]); - u64 context_lock_end = system_now_time(); - printf("Context lock time: %fs\n", mac_get_time_diff_sec(context_lock_begin, context_lock_end)); - - u64 make_current_context_begin = system_now_time(); [[self openGLContext] makeCurrentContext]; - u64 make_current_context_end = system_now_time(); - printf("Make current context time: %fs\n", mac_get_time_diff_sec(make_current_context_begin, make_current_context_end)); - u64 gl_render_begin = system_now_time(); gl_render(target); - u64 gl_render_end = system_now_time(); - printf("GL render time: %fs\n", mac_get_time_diff_sec(gl_render_begin, gl_render_end)); - u64 gl_flush_buffer_begin = system_now_time(); [[self openGLContext] flushBuffer]; - u64 gl_flush_buffer_end = system_now_time(); - printf("GL flush buffer time: %fs\n", mac_get_time_diff_sec(gl_flush_buffer_begin, gl_flush_buffer_end)); - - u64 context_unlock_begin = system_now_time(); CGLUnlockContext([[self openGLContext] CGLContextObj]); - u64 context_unlock_end = system_now_time(); - printf("Context unlock time: %fs\n", mac_get_time_diff_sec(context_unlock_begin, context_unlock_end)); } @end -global OpenGLView *opengl_view; +//////////////////////////////// -function void -mac_gl_init(NSWindow *window){ - // NOTE(yuval): Create OpenGLView +function +mac_render_sig(mac_gl_render){ + printf("Rendering using OpenGL!\n"); + + Mac_OpenGL_Renderer *gl = (Mac_OpenGL_Renderer*)renderer; + [gl->opengl_view render:target]; +} + +function +mac_get_texture_sig(mac_gl_get_texture){ + u32 result = gl__get_texture(dim, texture_kind); + return(result); +} + +function +mac_fill_texture_sig(mac_gl_fill_texture){ + b32 result = gl__fill_texture(texture_kind, texture, p, dim, data); + return(result); +} + +function Mac_OpenGL_Renderer* +mac_gl__init(NSWindow *window, Render_Target *target){ + // NOTE(yuval): Create the Mac Renderer + Mac_OpenGL_Renderer *gl = (Mac_OpenGL_Renderer*)system_memory_allocate(sizeof(Mac_OpenGL_Renderer), + file_name_line_number_lit_u8); + gl->base.render = mac_gl_render; + gl->base.get_texture = mac_gl_get_texture; + gl->base.fill_texture = mac_gl_fill_texture; + + // NOTE(yuval): Create the OpenGL view NSView *content_view = [window contentView]; - opengl_view = [[OpenGLView alloc] init]; - [opengl_view setFrame:[content_view bounds]]; - [opengl_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - [opengl_view setWantsBestResolutionOpenGLSurface:YES]; + gl->opengl_view = [[OpenGL_View alloc] init]; + [gl->opengl_view setFrame:[content_view bounds]]; + [gl->opengl_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [gl->opengl_view setWantsBestResolutionOpenGLSurface:YES]; // NOTE(yuval): Add the OpenGL view as a subview of the window - [content_view addSubview:opengl_view]; + [content_view addSubview:gl->opengl_view]; // NOTE(yuval): Load gl functions void *gl_image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY); #define GL_FUNC(f,R,P) ((f) = (f##_Function*)dlsym(gl_image, #f)); #include "mac_4ed_opengl_funcs.h" + + return(gl); } -function void -mac_gl_render(Render_Target* target){ - u64 begin_time = system_now_time(); - [opengl_view render:target]; - u64 end_time = system_now_time(); - printf("Render Time: %fs\n\n", mac_get_time_diff_sec(begin_time, end_time)); -} \ No newline at end of file +// TODO(yuval): This function should be exported to a DLL +function +mac_load_renderer_sig(mac_load_opengl_renderer){ + printf("Initializing The OpenGL Renderer!\n"); + + Mac_Renderer *renderer = (Mac_Renderer*)mac_gl__init(window, target); + return(renderer); +} diff --git a/platform_mac/mac_4ed_renderer.h b/platform_mac/mac_4ed_renderer.h new file mode 100644 index 00000000..0d1d4caf --- /dev/null +++ b/platform_mac/mac_4ed_renderer.h @@ -0,0 +1,42 @@ +/* Mac Renderer Abstraction */ + +#if !defined(FRED_MAC_RENDERER_H) +#define FRED_MAC_RENDERER_H + +//////////////////////////////// + +// TODO(yuval): This should be refactored into a platform independent renderer + +struct Mac_Renderer; + +#define mac_render_sig(name) void name(Mac_Renderer *renderer, Render_Target *target) +typedef mac_render_sig(mac_render_type); + +#define mac_get_texture_sig(name) u32 name(Mac_Renderer *renderer, Vec3_i32 dim, Texture_Kind texture_kind) +typedef mac_get_texture_sig(mac_get_texture_type); + +#define mac_fill_texture_sig(name) b32 name(Mac_Renderer *renderer, Texture_Kind texture_kind, u32 texture, Vec3_i32 p, Vec3_i32 dim, void* data) +typedef mac_fill_texture_sig(mac_fill_texture_type); + +typedef i32 Mac_Renderer_Kind; +enum{ + MacRenderer_OpenGL, + MacRenderer_Metal +}; + +struct Mac_Renderer{ + mac_render_type *render; + + mac_get_texture_type *get_texture; + mac_fill_texture_type *fill_texture; +}; + +//////////////////////////////// + +// NOTE(yuval): This is the actual platform dependent function that each renderer implementation implements and should be exported into a DLL +#define mac_load_renderer_sig(name) Mac_Renderer* name(NSWindow *window, Render_Target *target) +typedef mac_load_renderer_sig(mac_load_renderer_type); + +//////////////////////////////// + +#endif \ No newline at end of file diff --git a/platform_mac/mac_4ed_renderer.mm b/platform_mac/mac_4ed_renderer.mm new file mode 100644 index 00000000..f1b18967 --- /dev/null +++ b/platform_mac/mac_4ed_renderer.mm @@ -0,0 +1,33 @@ +/* Mac Renderer Abstraction Implementation */ + +// TODO(yuval): This should NOT be included here once the renderer is exported to a DLL +#import "mac_4ed_opengl.mm" +#import "mac_4ed_metal.mm" + +function Mac_Renderer* +mac_init_renderer(Mac_Renderer_Kind kind, NSWindow *window, Render_Target *target){ + // TODO(yuval): Import renderer load function from a DLL instead of using a switch statement and a renderer kind. This would allow us to switch the renderer backend and implemented new backends with ease. + + Mac_Renderer *result = 0; + + switch (kind){ + case MacRenderer_OpenGL: + { + result = mac_load_opengl_renderer(window, target); + } break; + + case MacRenderer_Metal: + { + //result = mac_load_metal_renderer(window, target); + } break; + + default: InvalidPath; + } + + if (!result){ + mac_error_box("Unable to initialize the renderer!"); + } + + return result; +} + From 88c933acd2d3ca548bbc40057952f9ea2fd5a866 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 9 Jan 2020 02:36:37 +0200 Subject: [PATCH 059/128] Implemented the renderer abstraction for both OpenGL and Metal. --- metal/4ed_metal_render.mm | 2 - platform_mac/mac_4ed.mm | 8 +-- platform_mac/mac_4ed_metal.mm | 101 +++++++++++++++++++++---------- platform_mac/mac_4ed_opengl.mm | 43 +++++++------ platform_mac/mac_4ed_renderer.mm | 2 +- 5 files changed, 94 insertions(+), 62 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index d5126396..3209e53e 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -259,8 +259,6 @@ metal__make_buffer(u32 size, id device){ } - (void)drawInMTKView:(nonnull MTKView*)view{ - printf("Metal Renderer Draw!\n"); - [capture_scope beginScope]; // HACK(yuval): This is the best way I found to force valid width and height without drawing on the next drawing cycle (1 frame delay). diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 33f645f7..29465700 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -447,8 +447,6 @@ this only gets called for window creation and other extraordinary events. [NSApp terminate:nil]; } - //mac_gl_render(&target); - //mac_metal_render(&target); renderer->render(renderer, &target); mac_vars.first = false; @@ -663,7 +661,7 @@ main(int arg_count, char **args){ } // - // Window and GL View Initialization + // Window and Renderer Initialization // // NOTE(yuval): Create Window & Window Delegate @@ -707,9 +705,7 @@ main(int arg_count, char **args){ [mac_vars.window makeKeyAndOrderFront:nil]; // NOTE(yuval): Initialize the renderer - //mac_gl_init(mac_vars.window); - //mac_metal_init(mac_vars.window, &target); - renderer = mac_init_renderer(MacRenderer_OpenGL, mac_vars.window, &target); + renderer = mac_init_renderer(MacRenderer_Metal, mac_vars.window, &target); mac_resize(w, h); diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm index ba44930b..117eec2d 100644 --- a/platform_mac/mac_4ed_metal.mm +++ b/platform_mac/mac_4ed_metal.mm @@ -1,50 +1,85 @@ +/* Mac Metal layer for 4coder */ + #import "metal/4ed_metal_render.mm" -global Metal_Renderer *metal_renderer; -global MTKView *metal_view; +//////////////////////////////// -function void -mac_metal_init(NSWindow *window, Render_Target *target){ - // NOTE(yuval): Create Metal view - NSView *content_view = [window contentView]; +struct Mac_Metal{ + Mac_Renderer base; - metal_view = [[MTKView alloc] initWithFrame:[content_view bounds]]; - [metal_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - [metal_view setPaused:YES]; - [metal_view setEnableSetNeedsDisplay:NO]; - [metal_view setSampleCount:4]; + Metal_Renderer *renderer; + MTKView *view; +}; + +//////////////////////////////// + +function +mac_render_sig(mac_metal__render){ + printf("Rendering using Metal!\n"); - metal_view.device = MTLCreateSystemDefaultDevice(); - - // NOTE(yuval): Add the Metal view as a subview of the window - [content_view addSubview:metal_view]; - - // NOTE(yuval): Create the Metal renderer and set it as the Metal view's delegate - metal_renderer = [[Metal_Renderer alloc] initWithMetalKitView:metal_view]; - metal_view.delegate = metal_renderer; + Mac_Metal *metal = (Mac_Metal*)renderer; + metal->renderer.target = target; + [metal->view draw]; } -function void -mac_metal_render(Render_Target* target){ - metal_renderer.target = target; - [metal_view draw]; -} - -function u32 -mac_metal_get_texture(Vec3_i32 dim, Texture_Kind texture_kind){ - u32 result = [metal_renderer get_texture_of_dim:dim +function +mac_get_texture_sig(mac_metal__get_texture){ + Mac_Metal *metal = (Mac_Metal*)renderer; + u32 result = [metal->renderer get_texture_of_dim:dim kind:texture_kind]; - return result; + return(result); } -function b32 -mac_metal_fill_texture(Texture_Kind texture_kind, u32 texture, Vec3_i32 p, Vec3_i32 dim, void *data){ - b32 result = [metal_renderer fill_texture:texture +function +mac_fill_texture_sig(mac_metal__fill_texture){ + Mac_Metal *metal = (Mac_Metal*)renderer; + b32 result = [metal->renderer fill_texture:texture kind:texture_kind pos:p dim:dim data:data]; - return result; + return(result); +} + +function Mac_Metal* +mac_metal__init(NSWindow *window, Render_Target *target){ + // NOTE(yuval): Create the Mac Metal rendere + Mac_Metal *metal = (Mac_Metal*)system_memory_allocate(sizeof(Mac_Metal), + file_name_line_number_lit_u8); + metal->base.render = mac_metal__render; + metal->base.get_texture = mac_metal__get_texture; + metal->base.fill_texture = mac_metal__fill_texture; + + // NOTE(yuval): Create the Metal view + NSView *content_view = [window contentView]; + + metal->view = [[MTKView alloc] initWithFrame:[content_view bounds]]; + [metal->view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [metal->view setPaused:YES]; + [metal->view setEnableSetNeedsDisplay:NO]; + [metal->view setSampleCount:4]; + + metal->view.device = MTLCreateSystemDefaultDevice(); + + // NOTE(yuval): Add the Metal view as a subview of the window + [content_view addSubview:metal->view]; + + // NOTE(yuval): Create the Metal renderer and set it as the Metal view's delegate + metal->renderer = [[Metal_Renderer alloc] initWithMetalKitView:metal->view]; + metal->view.delegate = metal->renderer; + + return(metal); +} + +//////////////////////////////// + +// TODO(yuval): This function should be exported to a DLL +function +mac_load_renderer_sig(mac_load_metal_renderer){ + printf("Loding The Metal Renderer!\n"); + + Mac_Renderer *renderer = (Mac_Renderer*)mac_metal__init(window, target); + return(renderer); } diff --git a/platform_mac/mac_4ed_opengl.mm b/platform_mac/mac_4ed_opengl.mm index 0a73c9c9..57dd3348 100644 --- a/platform_mac/mac_4ed_opengl.mm +++ b/platform_mac/mac_4ed_opengl.mm @@ -24,9 +24,10 @@ //////////////////////////////// -struct Mac_OpenGL_Renderer{ +struct Mac_OpenGL{ Mac_Renderer base; - OpenGL_View *opengl_view; + + OpenGL_View *view; }; //////////////////////////////// @@ -125,44 +126,44 @@ struct Mac_OpenGL_Renderer{ //////////////////////////////// function -mac_render_sig(mac_gl_render){ +mac_render_sig(mac_gl__render){ printf("Rendering using OpenGL!\n"); - Mac_OpenGL_Renderer *gl = (Mac_OpenGL_Renderer*)renderer; - [gl->opengl_view render:target]; + Mac_OpenGL *gl = (Mac_OpenGL*)renderer; + [gl->view render:target]; } function -mac_get_texture_sig(mac_gl_get_texture){ +mac_get_texture_sig(mac_gl__get_texture){ u32 result = gl__get_texture(dim, texture_kind); return(result); } function -mac_fill_texture_sig(mac_gl_fill_texture){ +mac_fill_texture_sig(mac_gl__fill_texture){ b32 result = gl__fill_texture(texture_kind, texture, p, dim, data); return(result); } -function Mac_OpenGL_Renderer* +function Mac_OpenGL* mac_gl__init(NSWindow *window, Render_Target *target){ - // NOTE(yuval): Create the Mac Renderer - Mac_OpenGL_Renderer *gl = (Mac_OpenGL_Renderer*)system_memory_allocate(sizeof(Mac_OpenGL_Renderer), - file_name_line_number_lit_u8); - gl->base.render = mac_gl_render; - gl->base.get_texture = mac_gl_get_texture; - gl->base.fill_texture = mac_gl_fill_texture; + // NOTE(yuval): Create the Mac OpenGL Renderer + Mac_OpenGL *gl = (Mac_OpenGL*)system_memory_allocate(sizeof(Mac_OpenGL), + file_name_line_number_lit_u8); + gl->base.render = mac_gl__render; + gl->base.get_texture = mac_gl__get_texture; + gl->base.fill_texture = mac_gl__fill_texture; // NOTE(yuval): Create the OpenGL view NSView *content_view = [window contentView]; - gl->opengl_view = [[OpenGL_View alloc] init]; - [gl->opengl_view setFrame:[content_view bounds]]; - [gl->opengl_view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; - [gl->opengl_view setWantsBestResolutionOpenGLSurface:YES]; + gl->view = [[OpenGL_View alloc] init]; + [gl->view setFrame:[content_view bounds]]; + [gl->view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + [gl->view setWantsBestResolutionOpenGLSurface:YES]; // NOTE(yuval): Add the OpenGL view as a subview of the window - [content_view addSubview:gl->opengl_view]; + [content_view addSubview:gl->view]; // NOTE(yuval): Load gl functions void *gl_image = dlopen("/System/Library/Frameworks/OpenGL.framework/Versions/Current/OpenGL", RTLD_LAZY); @@ -173,10 +174,12 @@ mac_gl__init(NSWindow *window, Render_Target *target){ return(gl); } +//////////////////////////////// + // TODO(yuval): This function should be exported to a DLL function mac_load_renderer_sig(mac_load_opengl_renderer){ - printf("Initializing The OpenGL Renderer!\n"); + printf("Loding The OpenGL Renderer!\n"); Mac_Renderer *renderer = (Mac_Renderer*)mac_gl__init(window, target); return(renderer); diff --git a/platform_mac/mac_4ed_renderer.mm b/platform_mac/mac_4ed_renderer.mm index f1b18967..5b4e4015 100644 --- a/platform_mac/mac_4ed_renderer.mm +++ b/platform_mac/mac_4ed_renderer.mm @@ -18,7 +18,7 @@ mac_init_renderer(Mac_Renderer_Kind kind, NSWindow *window, Render_Target *targe case MacRenderer_Metal: { - //result = mac_load_metal_renderer(window, target); + result = mac_load_metal_renderer(window, target); } break; default: InvalidPath; From 533819c7d4550f6f716b5ce4fa3e5b43c0a31c63 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 9 Jan 2020 20:52:39 +0200 Subject: [PATCH 060/128] Added mouse input. --- platform_mac/mac_4ed.mm | 63 +++++++++++++++++++++++++++++++++++++---- 1 file changed, 58 insertions(+), 5 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 29465700..62dc3390 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -128,6 +128,7 @@ struct Mac_Input_Chunk{ @interface FCoderView : NSView - (void)requestDisplay; +- (void)process_mouse_move_event:(NSEvent*)event; @end //////////////////////////////// @@ -394,6 +395,9 @@ mac_resize(NSWindow *window){ } - (void)drawRect:(NSRect)bounds{ + // NOTE(yuval): Read comment in win32_4ed.cpp's main loop + system_mutex_acquire(mac_vars.global_frame_mutex); + /* NOTE(yuval): Force the graphics context to clear to black so we don't get a flash of white until the app is ready to draw. In practice on modern macOS, this only gets called for window creation and other extraordinary events. @@ -401,9 +405,6 @@ this only gets called for window creation and other extraordinary events. [[NSColor blackColor] setFill]; NSRectFill(bounds); - // NOTE(yuval): Read comment in win32_4ed.cpp's main loop - system_mutex_release(mac_vars.global_frame_mutex); - // NOTE(yuval): Prepare the Frame Input Mac_Input_Chunk input_chunk = mac_vars.input_chunk; Application_Step_Input input = {}; @@ -452,6 +453,8 @@ this only gets called for window creation and other extraordinary events. mac_vars.first = false; linalloc_clear(mac_vars.frame_arena); + + system_mutex_release(mac_vars.global_frame_mutex); } - (BOOL)acceptsFirstResponder{ @@ -488,9 +491,50 @@ this only gets called for window creation and other extraordinary events. } - (void)mouseMoved:(NSEvent*)event{ + [self process_mouse_move_event:event]; +} + +- (void)mouseDragged:(NSEvent*)event{ + [self process_mouse_move_event:event]; +} + +- (void)scrollWheel:(NSEvent *)event{ + float dx = event.scrollingDeltaX; + float dy = event.scrollingDeltaY; + + mac_vars.input_chunk.trans.mouse_wheel = -((int32_t)dy); + + system_signal_step(0); } - (void)mouseDown:(NSEvent*)event{ + mac_vars.input_chunk.trans.mouse_l_press = true; + mac_vars.input_chunk.pers.mouse_l = true; + + system_signal_step(0); +} + +- (void)mouseUp:(NSEvent*)event{ + mac_vars.input_chunk.trans.mouse_l_release = true; + mac_vars.input_chunk.pers.mouse_l = false; + + system_signal_step(0); +} + +- (void)rightMouseDown:(NSEvent*)event{ + [super rightMouseDown:event]; + + mac_vars.input_chunk.trans.mouse_r_press = true; + mac_vars.input_chunk.pers.mouse_r = true; + + system_signal_step(0); +} + +- (void)rightMouseUp:(NSEvent*)event{ + mac_vars.input_chunk.trans.mouse_r_release = true; + mac_vars.input_chunk.pers.mouse_r = false; + + system_signal_step(0); } - (void)requestDisplay{ @@ -498,6 +542,16 @@ this only gets called for window creation and other extraordinary events. NSRect rect = NSRectFromCGRect(cg_rect); [self setNeedsDisplayInRect:rect]; } + +- (void)process_mouse_move_event:(NSEvent*)event{ + NSPoint location = [event locationInWindow]; + Vec2_i32 new_m = V2i32(location.x, mac_vars.height - location.y); + if (new_m != mac_vars.input_chunk.pers.mouse){ + mac_vars.input_chunk.pers.mouse = new_m; + } + + system_signal_step(0); +} @end //////////////////////////////// @@ -728,13 +782,12 @@ main(int arg_count, char **args){ } // - // Main loop + // Start Main Loop // mac_vars.first = true; mac_vars.global_frame_mutex = system_mutex_make(); - system_mutex_acquire(mac_vars.global_frame_mutex); mac_vars.timer_start = system_now_time(); From 520ab3dd27875d3302b4030f80808ba62314eae4 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Fri, 10 Jan 2020 01:04:55 +0200 Subject: [PATCH 061/128] Fixed animations. --- platform_mac/mac_4ed.mm | 29 +++++++++++++++++++++++------ 1 file changed, 23 insertions(+), 6 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 62dc3390..31ff96ef 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -430,6 +430,8 @@ this only gets called for window creation and other extraordinary events. block_zero_struct(&mac_vars.input_chunk.trans); + printf("Step scroll wheel: %d\n", input.mouse.wheel); + // NOTE(yuval): See comment in win32_4ed.cpp's main loop if (mac_vars.send_exit_signal){ input.trying_to_kill = true; @@ -448,7 +450,16 @@ this only gets called for window creation and other extraordinary events. [NSApp terminate:nil]; } + // NOTE(yuval): Render + u64 begin_render = system_now_time(); renderer->render(renderer, &target); + u64 end_render = system_now_time(); + printf("Render Time: %fs\n\n", (end_render - begin_render) / 1000000.0f); + + // NOTE(yuval): Schedule another step if needed + if (result.animating){ + system_signal_step(0); + } mac_vars.first = false; @@ -480,10 +491,9 @@ this only gets called for window creation and other extraordinary events. String_Const_u32 str_32 = SCu32(&character_code, 1); String_Const_u8 str_8 = string_u8_from_string_u32(mac_vars.frame_arena, str_32).string; - Input_Event event = {}; - event.kind = InputEventKind_TextInsert; - event.text.string = str_8; - push_input_event(mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list, &event); + Input_Event *event = push_input_event(mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list); + event->kind = InputEventKind_TextInsert; + event->text.string = str_8; system_signal_step(0); } @@ -502,7 +512,14 @@ this only gets called for window creation and other extraordinary events. float dx = event.scrollingDeltaX; float dy = event.scrollingDeltaY; - mac_vars.input_chunk.trans.mouse_wheel = -((int32_t)dy); + printf("Mouse scroll - dx:%f dy:%f\n", dx, dy); + + //mac_vars.input_chunk.trans.mouse_wheel = -((int32_t)dy); + i8 scroll_speed = 100; + if (dy > 0){ + scroll_speed *= -1; + } + mac_vars.input_chunk.trans.mouse_wheel = scroll_speed; system_signal_step(0); } @@ -759,7 +776,7 @@ main(int arg_count, char **args){ [mac_vars.window makeKeyAndOrderFront:nil]; // NOTE(yuval): Initialize the renderer - renderer = mac_init_renderer(MacRenderer_Metal, mac_vars.window, &target); + renderer = mac_init_renderer(MacRenderer_OpenGL, mac_vars.window, &target); mac_resize(w, h); From 76735e6f0183adaefd6d459d6802c40442d656c2 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 9 Jan 2020 17:56:01 -0800 Subject: [PATCH 062/128] Change file name bug fixed --- custom/4coder_base_commands.cpp | 7 ++---- custom/generated/command_metadata.h | 36 ++++++++++++++--------------- 2 files changed, 20 insertions(+), 23 deletions(-) diff --git a/custom/4coder_base_commands.cpp b/custom/4coder_base_commands.cpp index b5877959..b80e646f 100644 --- a/custom/4coder_base_commands.cpp +++ b/custom/4coder_base_commands.cpp @@ -1311,11 +1311,10 @@ CUSTOM_DOC("Queries the user for a new name and renames the file of the current bar.prompt = push_u8_stringf(scratch, "Rename '%.*s' to: ", string_expand(front)); bar.string = SCu8(name_space, (u64)0); bar.string_capacity = sizeof(name_space); - if (query_user_string(app, &bar)){ - if (bar.string.size != 0){ + if (query_user_string(app, &bar) && bar.string.size != 0){ // TODO(allen): There should be a way to say, "detach a buffer's file" and "attach this file to a buffer" List_String_Const_u8 new_file_name_list = {}; - string_list_push(scratch, &new_file_name_list, file_name); + string_list_push(scratch, &new_file_name_list, string_remove_front_of_path(file_name)); string_list_push(scratch, &new_file_name_list, bar.string); String_Const_u8 new_file_name = string_list_flatten(scratch, new_file_name_list, StringFill_NullTerminate); if (buffer_save(app, buffer, new_file_name, BufferSave_IgnoreDirtyFlag)){ @@ -1325,9 +1324,7 @@ CUSTOM_DOC("Queries the user for a new name and renames the file of the current view_set_buffer(app, view, new_buffer, 0); } } - } } - } } diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 38218855..b4831970 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -282,7 +282,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 682 }, -{ 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, 1796 }, +{ 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, 1793 }, { 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, 51 }, @@ -290,9 +290,9 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 1219 }, -{ 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, 1394 }, +{ 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, 1391 }, { 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, 1380 }, +{ 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, 1377 }, { 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, 738 }, @@ -323,7 +323,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 54 }, { 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, 77 }, { 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, 41 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1540 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1537 }, { 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, 296 }, @@ -343,7 +343,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 1334 }, +{ 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, 1331 }, { 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 }, @@ -364,8 +364,8 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 486 }, { 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, 471 }, { 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, 500 }, -{ 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, 1374 }, -{ 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, 1368 }, +{ 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, 1371 }, +{ 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, 1365 }, { 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, 445 }, { 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, 507 }, { 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, 521 }, @@ -379,12 +379,12 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 413 }, { 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, 1459 }, -{ 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, 1790 }, +{ 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, 1456 }, +{ 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, 1787 }, { 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, 1491 }, +{ 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, 1488 }, { 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, 372 }, @@ -404,16 +404,16 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 1147 }, { 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, 1168 }, { 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, 1184 }, -{ 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, 1629 }, -{ 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, 1714 }, +{ 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, 1626 }, +{ 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, 1711 }, { 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, 1296 }, -{ 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, 1558 }, +{ 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, 1555 }, { 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, 1057 }, { 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, 1048 }, { 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, 1039 }, { 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, 980 }, { 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, 992 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1548 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1545 }, { 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, 1263 }, { 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, 974 }, @@ -447,7 +447,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 1516 }, +{ 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, 1513 }, { 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, 563 }, { 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, 550 }, @@ -465,9 +465,9 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 1616 }, -{ 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, 1643 }, -{ 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, 1504 }, +{ 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, 1613 }, +{ 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, 1640 }, +{ 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, 1501 }, { 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 }, From d143a0e6d52f9ff1543d9b1eeff3e777e248fff2 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 9 Jan 2020 18:12:20 -0800 Subject: [PATCH 063/128] Fix indent on save bug --- custom/4coder_default_hooks.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom/4coder_default_hooks.cpp b/custom/4coder_default_hooks.cpp index c898d3bf..3824ca00 100644 --- a/custom/4coder_default_hooks.cpp +++ b/custom/4coder_default_hooks.cpp @@ -970,7 +970,7 @@ BUFFER_HOOK_SIG(default_new_file){ BUFFER_HOOK_SIG(default_file_save){ // buffer_id ProfileScope(app, "default file save"); - b32 is_virtual = false; + b32 is_virtual = global_config.enable_virtual_whitespace; if (global_config.automatically_indent_text_on_save && is_virtual){ auto_indent_buffer(app, buffer_id, buffer_range(app, buffer_id)); } From 65bfe172c4c640ca6f2754e7bcb97a7b2b18cc3a Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 9 Jan 2020 18:15:37 -0800 Subject: [PATCH 064/128] 4.1.1 --- custom/4coder_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom/4coder_version.h b/custom/4coder_version.h index 98596a84..0b0c6500 100644 --- a/custom/4coder_version.h +++ b/custom/4coder_version.h @@ -1,6 +1,6 @@ #define MAJOR 4 #define MINOR 1 -#define PATCH 0 +#define PATCH 1 // string #define VN__(a,b,c) #a "." #b "." #c From 2e21156e664f4b5407c9b5b36f462159192bcb80 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 9 Jan 2020 18:52:53 -0800 Subject: [PATCH 065/128] Add call convention for wgl functions --- bin/4ed_build.cpp | 1226 +++++++++++++++++----------------- platform_win32/win32_4ed.cpp | 18 +- 2 files changed, 622 insertions(+), 622 deletions(-) diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index 4362da1a..41ad2d55 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 = DEBUG_INFO | SUPER; + u32 arch = Arch_X64; +#if defined(DEV_BUILD) || defined(DEV_BUILD_X86) + flags |= 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) || defined(OPT_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/platform_win32/win32_4ed.cpp b/platform_win32/win32_4ed.cpp index 432d9b3a..737167ff 100644 --- a/platform_win32/win32_4ed.cpp +++ b/platform_win32/win32_4ed.cpp @@ -1241,10 +1241,10 @@ win32_wgl_good(Void_Func *f){ f != (Void_Func*)-1); } -typedef HGLRC (wglCreateContextAttribsARB_Function)(HDC,HGLRC,i32*); -typedef BOOL (wglChoosePixelFormatARB_Function)(HDC,i32*,f32*,u32,i32*,u32*); -typedef char* (wglGetExtensionsStringEXT_Function)(); -typedef VOID (wglSwapIntervalEXT_Function)(i32); +typedef HGLRC (CALL_CONVENTION wglCreateContextAttribsARB_Function)(HDC,HGLRC,i32*); +typedef BOOL (CALL_CONVENTION wglChoosePixelFormatARB_Function)(HDC,i32*,f32*,u32,i32*,u32*); +typedef char* (CALL_CONVENTION wglGetExtensionsStringEXT_Function)(); +typedef VOID (CALL_CONVENTION wglSwapIntervalEXT_Function)(i32); global wglCreateContextAttribsARB_Function *wglCreateContextAttribsARB = 0; global wglChoosePixelFormatARB_Function *wglChoosePixelFormatARB = 0; @@ -1309,7 +1309,7 @@ win32_gl_create_window(HWND *wnd_out, HGLRC *context_out, DWORD style, RECT rect // NOTE(allen): Load wgl extensions #define LoadWGL(f,l) Stmnt((f) = (f##_Function*)wglGetProcAddress(#f); \ - (l) = (l) && win32_wgl_good((Void_Func*)(f));) +(l) = (l) && win32_wgl_good((Void_Func*)(f));) b32 load_success = true; LoadWGL(wglCreateContextAttribsARB, load_success); @@ -1414,10 +1414,10 @@ win32_gl_create_window(HWND *wnd_out, HGLRC *context_out, DWORD style, RECT rect /*0*/WGL_CONTEXT_MAJOR_VERSION_ARB, 3, /*2*/WGL_CONTEXT_MINOR_VERSION_ARB, 2, /*4*/WGL_CONTEXT_FLAGS_ARB, WGL_CONTEXT_FORWARD_COMPATIBLE_BIT_ARB -#if GL_DEBUG_MODE - |WGL_CONTEXT_DEBUG_BIT_ARB -#endif - , + #if GL_DEBUG_MODE + |WGL_CONTEXT_DEBUG_BIT_ARB + #endif + , /*6*/WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB, /*8*/0 }; From 13970744b485aacc9ee1ba118f7d347cf64fc0b0 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Fri, 10 Jan 2020 18:57:08 +0200 Subject: [PATCH 066/128] Fixed blending bug in the Metal renderer where the destination alpha was not updated which caused problems while rendering the program in full screen mode. --- metal/4ed_metal_render.mm | 50 ++++++++++++++++++++++++----------- platform_mac/mac_4ed.mm | 31 ++++++++++++++-------- platform_mac/mac_4ed_metal.mm | 2 +- 3 files changed, 55 insertions(+), 28 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index 3209e53e..c7452e02 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -25,9 +25,12 @@ struct Metal_Buffer{ @interface Metal_Renderer : NSObject @property (nonatomic) Render_Target *target; -- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtkView; +- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtkView target:(Render_Target*)target; + - (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind; - (b32)fill_texture:(u32)texture kind:(Texture_Kind)kind pos:(Vec3_i32)p dim:(Vec3_i32)dim data:(void*)data; +- (void)bind_texture:(u32)handle encoder:(id)render_encoder; + - (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size; - (void)add_reusable_buffer:(Metal_Buffer*)buffer; @end @@ -127,8 +130,8 @@ sd = (abs(sd + in.half_thickness) - in.half_thickness); float shape_value = (1.0 - smoothstep(-1.0, 0.0, sd)); shape_value *= has_thickness; -// TOOD(yuval): Add sample_value to alpha float4 out_color = float4(in.color.xyz, in.color.a * (sample_value + shape_value)); +//float4 out_color = float4(1, 1, 1, shape_value); return(out_color); } )"; @@ -165,7 +168,7 @@ metal__make_buffer(u32 size, id device){ u32 next_texture_handle_index; } -- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtk_view{ +- (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtk_view target:(Render_Target*)target{ self = [super init]; if (self == nil){ return(nil); @@ -226,8 +229,8 @@ metal__make_buffer(u32 size, id device){ pipeline_state_descriptor.colorAttachments[0].rgbBlendOperation = MTLBlendOperationAdd; pipeline_state_descriptor.colorAttachments[0].sourceRGBBlendFactor = MTLBlendFactorSourceAlpha; pipeline_state_descriptor.colorAttachments[0].destinationRGBBlendFactor = MTLBlendFactorOneMinusSourceAlpha; - /*pipeline_state_descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; - pipeline_state_descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha;*/ + pipeline_state_descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; + pipeline_state_descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; pipeline_state = [device newRenderPipelineStateWithDescriptor:pipeline_state_descriptor error:&error]; @@ -246,6 +249,16 @@ metal__make_buffer(u32 size, id device){ textures = (Metal_Texture*)system_memory_allocate(metal__max_textures * sizeof(Metal_Texture), file_name_line_number_lit_u8); next_texture_handle_index = 0; + // NOTE(yuval): Create the fallback texture + target->fallback_texture_id = [self get_texture_of_dim:V3i32(2, 2, 1) + kind:TextureKind_Mono]; + u8 white_block[] = {0xFF, 0xFF, 0xFF, 0xFF}; + [self fill_texture:target->fallback_texture_id + kind:TextureKind_Mono + pos:V3i32(0, 0, 0) + dim:V3i32(2, 2, 1) + data:white_block]; + // NOTE(yuval): Create a capture scope for gpu frame capture capture_scope = [[MTLCaptureManager sharedCaptureManager] newCaptureScopeWithDevice:device]; @@ -324,10 +337,9 @@ metal__make_buffer(u32 size, id device){ atIndex:1]; u32 buffer_offset = 0; - i32 count = 0; for (Render_Group *group = _target->group_first; group; - group = group->next, ++count){ + group = group->next){ // NOTE(yuval): Set scissor rect { Rect_i32 box = Ri32(group->clip_box); @@ -349,19 +361,17 @@ metal__make_buffer(u32 size, id device){ i32 vertex_count = group->vertex_list.vertex_count; if (vertex_count > 0){ - // TODO(yuval): Bind a texture + // NOTE(yuval): Bind a texture { Face* face = font_set_face_from_id(font_set, group->face_id); if (face != 0){ - // TODO(yuval): Bind face texture - u32 texture_handle = face->texture; - Metal_Texture texture = textures[texture_handle]; - if (texture != 0){ - [render_encoder setFragmentTexture:texture - atIndex:0]; - } + // NOTE(yuval): Bind face texture + [self bind_texture:face->texture + encoder:render_encoder]; } else{ - // TODO(yuval): Bind default texture + // NOTE(yuval): Bind fallback texture + [self bind_texture:_target->fallback_texture_id + encoder:render_encoder]; } } @@ -458,6 +468,14 @@ metal__make_buffer(u32 size, id device){ return result; } +- (void)bind_texture:(u32)handle encoder:(id)render_encoder{ + Metal_Texture texture = textures[handle]; + if (texture != 0){ + [render_encoder setFragmentTexture:texture + atIndex:0]; + } +} + - (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size{ // NOTE(yuval): This routine is a modified version of Dear ImGui's MetalContext::dequeueReusableBufferOfLength in imgui_impl_metal.mm diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 31ff96ef..f8ad5a20 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -360,21 +360,35 @@ mac_resize(NSWindow *window){ @end @implementation FCoderWindowDelegate -- (BOOL)windowShouldClose:(id)sender { +- (BOOL)windowShouldClose:(id)sender{ mac_vars.input_chunk.trans.trying_to_kill = true; system_signal_step(0); return(NO); } -- (void)windowDidResize:(NSNotification*)notification { +- (void)windowDidResize:(NSNotification*)notification{ mac_resize(mac_vars.window); } -- (void)windowDidMiniaturize:(NSNotification*)notification { +- (void)windowDidMiniaturize:(NSNotification*)notification{ } -- (void)windowDidDeminiaturize:(NSNotification*)notification { +- (void)windowDidDeminiaturize:(NSNotification*)notification{ +} + +- (void)windowDidBecomeKey:(NSNotification *)notification{ + printf("Focus\n"); + system_signal_step(0); +} + +- (void)windowDidResignKey:(NSNotification *)notification{ + printf("Lost Focus\n"); + system_signal_step(0); +} + +- (void)windowDidEnterFullScreen:(NSNotification *)notification{ + system_signal_step(0); } @end @@ -430,8 +444,6 @@ this only gets called for window creation and other extraordinary events. block_zero_struct(&mac_vars.input_chunk.trans); - printf("Step scroll wheel: %d\n", input.mouse.wheel); - // NOTE(yuval): See comment in win32_4ed.cpp's main loop if (mac_vars.send_exit_signal){ input.trying_to_kill = true; @@ -512,9 +524,6 @@ this only gets called for window creation and other extraordinary events. float dx = event.scrollingDeltaX; float dy = event.scrollingDeltaY; - printf("Mouse scroll - dx:%f dy:%f\n", dx, dy); - - //mac_vars.input_chunk.trans.mouse_wheel = -((int32_t)dy); i8 scroll_speed = 100; if (dy > 0){ scroll_speed *= -1; @@ -567,7 +576,7 @@ this only gets called for window creation and other extraordinary events. mac_vars.input_chunk.pers.mouse = new_m; } - system_signal_step(0); + //system_signal_step(0); } @end @@ -776,7 +785,7 @@ main(int arg_count, char **args){ [mac_vars.window makeKeyAndOrderFront:nil]; // NOTE(yuval): Initialize the renderer - renderer = mac_init_renderer(MacRenderer_OpenGL, mac_vars.window, &target); + renderer = mac_init_renderer(MacRenderer_Metal, mac_vars.window, &target); mac_resize(w, h); diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm index 117eec2d..60b754d9 100644 --- a/platform_mac/mac_4ed_metal.mm +++ b/platform_mac/mac_4ed_metal.mm @@ -67,7 +67,7 @@ mac_metal__init(NSWindow *window, Render_Target *target){ [content_view addSubview:metal->view]; // NOTE(yuval): Create the Metal renderer and set it as the Metal view's delegate - metal->renderer = [[Metal_Renderer alloc] initWithMetalKitView:metal->view]; + metal->renderer = [[Metal_Renderer alloc] initWithMetalKitView:metal->view target:target]; metal->view.delegate = metal->renderer; return(metal); From 8e4ec5215f94a6a4544c3bbeb1ec1421d93520f7 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sat, 11 Jan 2020 22:19:43 +0200 Subject: [PATCH 067/128] Added KeyStoke and KeyRelease events and fixed TextInput events. --- metal/4ed_metal_render.mm | 6 +- platform_mac/mac_4ed.mm | 245 ++++++++++++++++++++++++++---- platform_mac/mac_4ed_functions.mm | 4 +- platform_mac/mac_4ed_metal.mm | 1 - 4 files changed, 219 insertions(+), 37 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index c7452e02..6f8b1a20 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -174,6 +174,8 @@ metal__make_buffer(u32 size, id device){ return(nil); } + _target = target; + NSError *error = nil; device = mtk_view.device; @@ -250,10 +252,10 @@ metal__make_buffer(u32 size, id device){ next_texture_handle_index = 0; // NOTE(yuval): Create the fallback texture - target->fallback_texture_id = [self get_texture_of_dim:V3i32(2, 2, 1) + _target->fallback_texture_id = [self get_texture_of_dim:V3i32(2, 2, 1) kind:TextureKind_Mono]; u8 white_block[] = {0xFF, 0xFF, 0xFF, 0xFF}; - [self fill_texture:target->fallback_texture_id + [self fill_texture:_target->fallback_texture_id kind:TextureKind_Mono pos:V3i32(0, 0, 0) dim:V3i32(2, 2, 1) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index f8ad5a20..c5dc43fb 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -55,6 +55,7 @@ #import #include // NOTE(yuval): Used for proc_pidpath +#include // NOTE(yuval): Used for virtual key codes #include // NOTE(yuval): Used for mach_absolute_time, mach_timebase_info, mach_timebase_info_data_t #include // NOTE(yuval): Used for opendir, readdir @@ -120,14 +121,15 @@ struct Mac_Input_Chunk{ //////////////////////////////// -@interface FCoderAppDelegate : NSObject +@interface FCoder_App_Delegate : NSObject @end -@interface FCoderWindowDelegate : NSObject +@interface FCoder_Window_Delegate : NSObject @end -@interface FCoderView : NSView -- (void)requestDisplay; +@interface FCoder_View : NSView +- (void)request_display; +- (void)process_keyboard_event:(NSEvent*)event; - (void)process_mouse_move_event:(NSEvent*)event; @end @@ -166,7 +168,10 @@ struct Mac_Vars { Thread_Context *tctx; Arena *frame_arena; + Input_Event *active_key_stroke; + Input_Event *active_text_input; Mac_Input_Chunk input_chunk; + b8 lctrl_lalt_is_altgr; b8 full_screen; b8 do_toggle; @@ -180,7 +185,7 @@ struct Mac_Vars { String_Const_u8 clipboard_contents; NSWindow *window; - FCoderView *view; + FCoder_View *view; f32 screen_scale_factor; mach_timebase_info_data_t timebase_info; @@ -300,11 +305,101 @@ mac_error_box(char *msg, b32 shutdown = true){ //////////////////////////////// -global Key_Code keycode_lookup_table[255]; +global Key_Code keycode_lookup_table[255] = {}; function void -mac_key_code_init(void){ +mac_keycode_init(void){ + keycode_lookup_table[kVK_ANSI_A] = KeyCode_A; + keycode_lookup_table[kVK_ANSI_B] = KeyCode_B; + keycode_lookup_table[kVK_ANSI_C] = KeyCode_C; + keycode_lookup_table[kVK_ANSI_D] = KeyCode_D; + keycode_lookup_table[kVK_ANSI_E] = KeyCode_E; + keycode_lookup_table[kVK_ANSI_F] = KeyCode_F; + keycode_lookup_table[kVK_ANSI_G] = KeyCode_G; + keycode_lookup_table[kVK_ANSI_H] = KeyCode_H; + keycode_lookup_table[kVK_ANSI_I] = KeyCode_I; + keycode_lookup_table[kVK_ANSI_J] = KeyCode_J; + keycode_lookup_table[kVK_ANSI_K] = KeyCode_K; + keycode_lookup_table[kVK_ANSI_L] = KeyCode_L; + keycode_lookup_table[kVK_ANSI_M] = KeyCode_M; + keycode_lookup_table[kVK_ANSI_N] = KeyCode_N; + keycode_lookup_table[kVK_ANSI_O] = KeyCode_O; + keycode_lookup_table[kVK_ANSI_P] = KeyCode_P; + keycode_lookup_table[kVK_ANSI_Q] = KeyCode_Q; + keycode_lookup_table[kVK_ANSI_R] = KeyCode_R; + keycode_lookup_table[kVK_ANSI_S] = KeyCode_S; + keycode_lookup_table[kVK_ANSI_T] = KeyCode_T; + keycode_lookup_table[kVK_ANSI_U] = KeyCode_U; + keycode_lookup_table[kVK_ANSI_V] = KeyCode_V; + keycode_lookup_table[kVK_ANSI_W] = KeyCode_W; + keycode_lookup_table[kVK_ANSI_X] = KeyCode_X; + keycode_lookup_table[kVK_ANSI_Y] = KeyCode_Y; + keycode_lookup_table[kVK_ANSI_Z] = KeyCode_Z; + keycode_lookup_table[kVK_ANSI_0] = KeyCode_0; + keycode_lookup_table[kVK_ANSI_1] = KeyCode_1; + keycode_lookup_table[kVK_ANSI_2] = KeyCode_2; + keycode_lookup_table[kVK_ANSI_3] = KeyCode_3; + keycode_lookup_table[kVK_ANSI_4] = KeyCode_4; + keycode_lookup_table[kVK_ANSI_5] = KeyCode_5; + keycode_lookup_table[kVK_ANSI_6] = KeyCode_6; + keycode_lookup_table[kVK_ANSI_7] = KeyCode_7; + keycode_lookup_table[kVK_ANSI_8] = KeyCode_8; + keycode_lookup_table[kVK_ANSI_9] = KeyCode_9; + + keycode_lookup_table[kVK_Space] = KeyCode_Space; + keycode_lookup_table[kVK_ANSI_Grave] = KeyCode_Tick; + keycode_lookup_table[kVK_ANSI_Minus] = KeyCode_Minus; + keycode_lookup_table[kVK_ANSI_LeftBracket] = KeyCode_LeftBracket; + keycode_lookup_table[kVK_ANSI_RightBracket] = KeyCode_RightBracket; + keycode_lookup_table[kVK_ANSI_Semicolon] = KeyCode_Semicolon; + keycode_lookup_table[kVK_ANSI_Quote] = KeyCode_Quote; + keycode_lookup_table[kVK_ANSI_Comma] = KeyCode_Comma; + keycode_lookup_table[kVK_ANSI_Period] = KeyCode_Period; + keycode_lookup_table[kVK_ANSI_Slash] = KeyCode_ForwardSlash; + keycode_lookup_table[kVK_ANSI_Backslash] = KeyCode_BackwardSlash; + + keycode_lookup_table[kVK_Tab] = KeyCode_Tab; + // NOTE(yuval): No Pause key on macOS! + keycode_lookup_table[kVK_Escape] = KeyCode_Escape; + + keycode_lookup_table[kVK_UpArrow] = KeyCode_Up; + keycode_lookup_table[kVK_DownArrow] = KeyCode_Down; + keycode_lookup_table[kVK_LeftArrow] = KeyCode_Left; + keycode_lookup_table[kVK_RightArrow] = KeyCode_Right; + + keycode_lookup_table[kVK_Delete] = KeyCode_Backspace; + keycode_lookup_table[kVK_Return] = KeyCode_Return; + + keycode_lookup_table[kVK_ForwardDelete] = KeyCode_Delete; + //keycode_lookup_table[] = KeyCode_Insert; // TODO(yuval): Figure how to get keyDown events for the insert key + keycode_lookup_table[kVK_Home] = KeyCode_Home; + keycode_lookup_table[kVK_End] = KeyCode_End; + keycode_lookup_table[kVK_PageUp] = KeyCode_PageUp; + keycode_lookup_table[kVK_PageDown] = KeyCode_PageDown; + + keycode_lookup_table[kVK_CapsLock] = KeyCode_CapsLock; + keycode_lookup_table[kVK_ANSI_KeypadClear] = KeyCode_NumLock; + // NOTE(yuval): No Scroll Lock key on macOS! + keycode_lookup_table[0x6E] = KeyCode_Menu; + + keycode_lookup_table[kVK_F1] = KeyCode_F1; + keycode_lookup_table[kVK_F2] = KeyCode_F2; + keycode_lookup_table[kVK_F3] = KeyCode_F3; + keycode_lookup_table[kVK_F4] = KeyCode_F4; + keycode_lookup_table[kVK_F5] = KeyCode_F5; + keycode_lookup_table[kVK_F6] = KeyCode_F6; + keycode_lookup_table[kVK_F7] = KeyCode_F7; + keycode_lookup_table[kVK_F8] = KeyCode_F8; + keycode_lookup_table[kVK_F9] = KeyCode_F9; + + keycode_lookup_table[kVK_F10] = KeyCode_F10; + keycode_lookup_table[kVK_F11] = KeyCode_F11; + keycode_lookup_table[kVK_F12] = KeyCode_F12; + keycode_lookup_table[kVK_F13] = KeyCode_F13; + keycode_lookup_table[kVK_F14] = KeyCode_F14; + keycode_lookup_table[kVK_F15] = KeyCode_F15; + keycode_lookup_table[kVK_F16] = KeyCode_F16; } //////////////////////////////// @@ -347,7 +442,7 @@ mac_resize(NSWindow *window){ //////////////////////////////// -@implementation FCoderAppDelegate +@implementation FCoder_App_Delegate - (void)applicationDidFinishLaunching:(id)sender{ } @@ -359,7 +454,7 @@ mac_resize(NSWindow *window){ } @end -@implementation FCoderWindowDelegate +@implementation FCoder_Window_Delegate - (BOOL)windowShouldClose:(id)sender{ mac_vars.input_chunk.trans.trying_to_kill = true; system_signal_step(0); @@ -392,7 +487,7 @@ mac_resize(NSWindow *window){ } @end -@implementation FCoderView +@implementation FCoder_View - (id)init{ self = [super init]; return(self); @@ -493,23 +588,17 @@ this only gets called for window creation and other extraordinary events. } - (void)keyDown:(NSEvent*)event{ - NSString *characters = [event characters]; - if ([characters length] != 0) { - u32 character_code = [characters characterAtIndex:0]; - - // NOTE(yuval): Control characters generate character_codes < 32 - if (character_code > 31) { - // TODO(yuval): This is actually in utf16!!! - String_Const_u32 str_32 = SCu32(&character_code, 1); - String_Const_u8 str_8 = string_u8_from_string_u32(mac_vars.frame_arena, str_32).string; - - Input_Event *event = push_input_event(mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list); - event->kind = InputEventKind_TextInsert; - event->text.string = str_8; - - system_signal_step(0); - } - } + printf("Key Down: %#X\n", [event keyCode]); + [self process_keyboard_event:event]; +} + +- (void)keyUp:(NSEvent*)event{ + printf("Key Up: %#X\n", [event keyCode]); + [self process_keyboard_event:event]; +} + +- (void)flagsChanged:(NSEvent *)event{ + NSEventModifierFlags flags = [event modifierFlags]; } - (void)mouseMoved:(NSEvent*)event{ @@ -563,12 +652,102 @@ this only gets called for window creation and other extraordinary events. system_signal_step(0); } -- (void)requestDisplay{ +- (void)request_display{ CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height); NSRect rect = NSRectFromCGRect(cg_rect); [self setNeedsDisplayInRect:rect]; } +- (void)process_keyboard_event:(NSEvent*)event{ + b8 release = ([event type] == NSEventTypeKeyUp); + b8 down = !release; + + Input_Modifier_Set_Fixed *mods = &mac_vars.input_chunk.pers.modifiers; + + // NOTE(yuval): Set control modifiers + { + Control_Keys *controls = &mac_vars.input_chunk.pers.controls; + b8 ctrl = (controls->r_ctrl || (controls->l_ctrl && !controls->r_alt)); + b8 alt = (controls->l_alt || (controls->r_alt && !controls->l_ctrl)); + if (mac_vars.lctrl_lalt_is_altgr && controls->l_alt && controls->l_ctrl){ + ctrl = false; + alt = false; + } + + set_modifier(mods, KeyCode_Control, ctrl); + set_modifier(mods, KeyCode_Alt, alt); + } + + // NOTE(yuval): Process KeyStroke / KeyRelease event + { + u16 event_key_code = [event keyCode]; + Key_Code key = keycode_lookup_table[(u8)event_key_code]; + if (down){ + if (key != 0){ + add_modifier(mods, key); + + Input_Event *event = push_input_event(mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list); + event->kind = InputEventKind_KeyStroke; + event->key.code = key; + event->key.modifiers = copy_modifier_set(mac_vars.frame_arena, mods); + + mac_vars.active_key_stroke = event; + + system_signal_step(0); + } + } else{ + mac_vars.active_key_stroke = 0; + mac_vars.active_text_input = 0; + + if (key != 0){ + Input_Event *event = push_input_event(mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list); + event->kind = InputEventKind_KeyRelease; + event->key.code = key; + event->key.modifiers = copy_modifier_set(mac_vars.frame_arena, mods); + + remove_modifier(mods, key); + } + + system_signal_step(0); + } + } + + // NOTE(yuval): Process TextInput event + { + if (down){ + NSString *characters = [event characters]; + if ([characters length] > 0){ + // NOTE(yuval): Get the first utf-16 character + u32 c = [characters characterAtIndex:0]; + if (c == '\r'){ + c = '\n'; + } + + // NOTE(yuval): Check for a valid text input + if ((c > 127) || ((' ' <= c) && (c <= '~')) || (c == '\t') || (c == '\n') || (c == '\r')){ + String_Const_u16 str_16 = SCu16((u16*)&c, 1); + String_Const_u8 str_8 = string_u8_from_string_u16(mac_vars.frame_arena, str_16).string; + + Input_Event *event = push_input_event(mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list); + event->kind = InputEventKind_TextInsert; + event->text.string = str_8; + event->text.next_text = 0; + event->text.blocked = false; + if (mac_vars.active_text_input){ + mac_vars.active_text_input->text.next_text = event; + } else if (mac_vars.active_key_stroke){ + mac_vars.active_key_stroke->key.first_dependent_text = event; + } + + mac_vars.active_text_input = event; + + system_signal_step(0); + } + } + } + } +} + - (void)process_mouse_move_event:(NSEvent*)event{ NSPoint location = [event locationInWindow]; Vec2_i32 new_m = V2i32(location.x, mac_vars.height - location.y); @@ -576,7 +755,7 @@ this only gets called for window creation and other extraordinary events. mac_vars.input_chunk.pers.mouse = new_m; } - //system_signal_step(0); + system_signal_step(0); } @end @@ -591,7 +770,7 @@ main(int arg_count, char **args){ [NSApp setActivationPolicy:NSApplicationActivationPolicyRegular]; - FCoderAppDelegate *app_delegate = [[FCoderAppDelegate alloc] init]; + FCoder_App_Delegate *app_delegate = [[FCoder_App_Delegate alloc] init]; [NSApp setDelegate:app_delegate]; pthread_mutex_init(&memory_tracker_mutex, 0); @@ -765,7 +944,7 @@ main(int arg_count, char **args){ backing:NSBackingStoreBuffered defer:NO]; - FCoderWindowDelegate *window_delegate = [[FCoderWindowDelegate alloc] init]; + FCoder_Window_Delegate *window_delegate = [[FCoder_Window_Delegate alloc] init]; [mac_vars.window setDelegate:window_delegate]; [mac_vars.window setMinSize:NSMakeSize(100, 100)]; @@ -776,7 +955,7 @@ main(int arg_count, char **args){ NSView* content_view = [mac_vars.window contentView]; // NOTE(yuval): Create the 4coder view - mac_vars.view = [[FCoderView alloc] init]; + mac_vars.view = [[FCoder_View alloc] init]; [mac_vars.view setFrame:[content_view bounds]]; [mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; @@ -793,6 +972,8 @@ main(int arg_count, char **args){ // TODO(yuval): Misc System Initializations // + mac_keycode_init(); + // NOTE(yuval): Get the timebase info mach_timebase_info(&mac_vars.timebase_info); diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index c1c37bae..b62b4bb3 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -399,7 +399,7 @@ system_wake_up_timer_set_sig(){ f64 time_seconds = ((f64)time_milliseconds / 1000.0); object->timer = [NSTimer scheduledTimerWithTimeInterval:time_seconds target:mac_vars.view - selector:@selector(requestDisplay) + selector:@selector(request_display) userInfo:nil repeats:NO]; } } @@ -408,7 +408,7 @@ function system_signal_step_sig(){ [NSTimer scheduledTimerWithTimeInterval:0.0 target:mac_vars.view - selector:@selector(requestDisplay) + selector:@selector(request_display) userInfo:nil repeats:NO]; } diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm index 60b754d9..34fbbeca 100644 --- a/platform_mac/mac_4ed_metal.mm +++ b/platform_mac/mac_4ed_metal.mm @@ -18,7 +18,6 @@ mac_render_sig(mac_metal__render){ printf("Rendering using Metal!\n"); Mac_Metal *metal = (Mac_Metal*)renderer; - metal->renderer.target = target; [metal->view draw]; } From 7f00ead99c7b9be31dfcb7093a0d3325d68aabf3 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sat, 11 Jan 2020 23:12:41 +0200 Subject: [PATCH 068/128] Added support for control keys. --- platform_mac/mac_4ed.mm | 139 ++++++++++++++++++++++++++++------------ 1 file changed, 97 insertions(+), 42 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index c5dc43fb..ec191dab 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -80,6 +80,10 @@ struct Control_Keys{ b8 r_ctrl; b8 l_alt; b8 r_alt; + b8 l_shift; + b8 r_shift; + b8 l_command; + b8 r_command; }; struct Mac_Input_Chunk_Transient{ @@ -129,7 +133,7 @@ struct Mac_Input_Chunk{ @interface FCoder_View : NSView - (void)request_display; -- (void)process_keyboard_event:(NSEvent*)event; +- (void)process_keyboard_event:(NSEvent*)event down:(b8)down; - (void)process_mouse_move_event:(NSEvent*)event; @end @@ -305,6 +309,8 @@ mac_error_box(char *msg, b32 shutdown = true){ //////////////////////////////// +global_const u8 kVK_Menu = 0x6E; + global Key_Code keycode_lookup_table[255] = {}; function void @@ -381,7 +387,19 @@ mac_keycode_init(void){ keycode_lookup_table[kVK_CapsLock] = KeyCode_CapsLock; keycode_lookup_table[kVK_ANSI_KeypadClear] = KeyCode_NumLock; // NOTE(yuval): No Scroll Lock key on macOS! - keycode_lookup_table[0x6E] = KeyCode_Menu; + keycode_lookup_table[kVK_Menu] = KeyCode_Menu; + + keycode_lookup_table[kVK_Shift] = KeyCode_Shift; + keycode_lookup_table[kVK_RightShift] = KeyCode_Shift; + + keycode_lookup_table[kVK_Control] = KeyCode_Control; + keycode_lookup_table[kVK_RightControl] = KeyCode_Control; + + keycode_lookup_table[kVK_Option] = KeyCode_Alt; + keycode_lookup_table[kVK_RightOption] = KeyCode_Alt; + + keycode_lookup_table[kVK_Command] = KeyCode_Command; + keycode_lookup_table[kVK_RightCommand] = KeyCode_Command; // NOTE(yuval): Right Command keycode_lookup_table[kVK_F1] = KeyCode_F1; keycode_lookup_table[kVK_F2] = KeyCode_F2; @@ -589,16 +607,83 @@ this only gets called for window creation and other extraordinary events. - (void)keyDown:(NSEvent*)event{ printf("Key Down: %#X\n", [event keyCode]); - [self process_keyboard_event:event]; + + // NOTE(yuval): Process keyboard event + [self process_keyboard_event:event down:true]; + + // NOTE(yuval): Process TextInsert event + { + NSString *characters = [event characters]; + if ([characters length] > 0){ + // NOTE(yuval): Get the first utf-16 character + u32 c = [characters characterAtIndex:0]; + if (c == '\r'){ + c = '\n'; + } + + // NOTE(yuval): Check for a valid text input + if ((c > 127) || ((' ' <= c) && (c <= '~')) || (c == '\t') || (c == '\n') || (c == '\r')){ + String_Const_u16 str_16 = SCu16((u16*)&c, 1); + String_Const_u8 str_8 = string_u8_from_string_u16(mac_vars.frame_arena, str_16).string; + + Input_Event *event = push_input_event(mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list); + event->kind = InputEventKind_TextInsert; + event->text.string = str_8; + event->text.next_text = 0; + event->text.blocked = false; + if (mac_vars.active_text_input){ + mac_vars.active_text_input->text.next_text = event; + } else if (mac_vars.active_key_stroke){ + mac_vars.active_key_stroke->key.first_dependent_text = event; + } + + mac_vars.active_text_input = event; + + system_signal_step(0); + } + } + } } - (void)keyUp:(NSEvent*)event{ printf("Key Up: %#X\n", [event keyCode]); - [self process_keyboard_event:event]; + [self process_keyboard_event:event down:false]; } - (void)flagsChanged:(NSEvent *)event{ NSEventModifierFlags flags = [event modifierFlags]; + b8 ctrl_pressed = ((flags & NSEventModifierFlagControl) != 0); + b8 alt_pressed = ((flags & NSEventModifierFlagOption) != 0); + b8 shift_pressed = ((flags & NSEventModifierFlagShift) != 0); + b8 command_pressed = ((flags & NSEventModifierFlagCommand) != 0); + + Control_Keys *controls = &mac_vars.input_chunk.pers.controls; + u16 event_key_code = [event keyCode]; + if (event_key_code == kVK_Control){ + controls->l_ctrl = ctrl_pressed; + [self process_keyboard_event:event down:ctrl_pressed]; + } else if (event_key_code == kVK_RightControl){ + controls->r_ctrl = ctrl_pressed; + [self process_keyboard_event:event down:ctrl_pressed]; + } else if (event_key_code == kVK_Option){ + controls->l_alt = alt_pressed; + [self process_keyboard_event:event down:alt_pressed]; + } else if (event_key_code == kVK_RightOption){ + controls->r_alt = alt_pressed; + [self process_keyboard_event:event down:alt_pressed]; + } else if (event_key_code == kVK_Shift){ + controls->l_shift = shift_pressed; + [self process_keyboard_event:event down:shift_pressed]; + } else if (event_key_code == kVK_RightShift){ + controls->r_shift = shift_pressed; + [self process_keyboard_event:event down:shift_pressed]; + } else if (event_key_code == kVK_Command){ + controls->l_command = command_pressed; + [self process_keyboard_event:event down:command_pressed]; + } else if (event_key_code == kVK_RightCommand){ + controls->r_command = command_pressed; + [self process_keyboard_event:event down:command_pressed]; + } } - (void)mouseMoved:(NSEvent*)event{ @@ -658,15 +743,15 @@ this only gets called for window creation and other extraordinary events. [self setNeedsDisplayInRect:rect]; } -- (void)process_keyboard_event:(NSEvent*)event{ - b8 release = ([event type] == NSEventTypeKeyUp); - b8 down = !release; +- (void)process_keyboard_event:(NSEvent*)event down:(b8)down{ + b8 release = !down; Input_Modifier_Set_Fixed *mods = &mac_vars.input_chunk.pers.modifiers; // NOTE(yuval): Set control modifiers { Control_Keys *controls = &mac_vars.input_chunk.pers.controls; + b8 ctrl = (controls->r_ctrl || (controls->l_ctrl && !controls->r_alt)); b8 alt = (controls->l_alt || (controls->r_alt && !controls->l_ctrl)); if (mac_vars.lctrl_lalt_is_altgr && controls->l_alt && controls->l_ctrl){ @@ -674,8 +759,13 @@ this only gets called for window creation and other extraordinary events. alt = false; } + b8 shift = (controls->r_shift || controls->l_shift); + b8 command = (controls->r_command || controls->l_command); + set_modifier(mods, KeyCode_Control, ctrl); set_modifier(mods, KeyCode_Alt, alt); + set_modifier(mods, KeyCode_Shift, shift); + set_modifier(mods, KeyCode_Command, command); } // NOTE(yuval): Process KeyStroke / KeyRelease event @@ -711,41 +801,6 @@ this only gets called for window creation and other extraordinary events. system_signal_step(0); } } - - // NOTE(yuval): Process TextInput event - { - if (down){ - NSString *characters = [event characters]; - if ([characters length] > 0){ - // NOTE(yuval): Get the first utf-16 character - u32 c = [characters characterAtIndex:0]; - if (c == '\r'){ - c = '\n'; - } - - // NOTE(yuval): Check for a valid text input - if ((c > 127) || ((' ' <= c) && (c <= '~')) || (c == '\t') || (c == '\n') || (c == '\r')){ - String_Const_u16 str_16 = SCu16((u16*)&c, 1); - String_Const_u8 str_8 = string_u8_from_string_u16(mac_vars.frame_arena, str_16).string; - - Input_Event *event = push_input_event(mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list); - event->kind = InputEventKind_TextInsert; - event->text.string = str_8; - event->text.next_text = 0; - event->text.blocked = false; - if (mac_vars.active_text_input){ - mac_vars.active_text_input->text.next_text = event; - } else if (mac_vars.active_key_stroke){ - mac_vars.active_key_stroke->key.first_dependent_text = event; - } - - mac_vars.active_text_input = event; - - system_signal_step(0); - } - } - } - } } - (void)process_mouse_move_event:(NSEvent*)event{ From f1dd78f32a52b35a20a754165a902dfa141c1edc Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sat, 11 Jan 2020 15:45:28 -0800 Subject: [PATCH 069/128] Only compute line indentation info at necessary points in the auto-indent routine --- 4ed.cpp | 2 +- custom/4coder_auto_indent.cpp | 39 +- custom/4coder_helper.cpp | 24 +- custom/generated/command_metadata.h | 8 +- custom/generated/lexer_cpp.cpp | 9964 ++++++++++----------- custom/languages/4coder_cpp_lexer_gen.cpp | 1 - 6 files changed, 5030 insertions(+), 5008 deletions(-) diff --git a/4ed.cpp b/4ed.cpp index 7f10ef54..155c53a5 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -730,7 +730,7 @@ App_Step_Sig(app_step){ // NOTE(allen): if the exit signal has been sent, run the exit hook. if (!models->keep_playing || input->trying_to_kill){ co_send_core_event(tctx, models, CoreCode_TryExit); - models->keep_playing = true; + models->keep_playing = true; } // NOTE(allen): rendering diff --git a/custom/4coder_auto_indent.cpp b/custom/4coder_auto_indent.cpp index d05d98f8..b672edd4 100644 --- a/custom/4coder_auto_indent.cpp +++ b/custom/4coder_auto_indent.cpp @@ -15,7 +15,7 @@ make_batch_from_indentations(Application_Links *app, Arena *arena, Buffer_ID buf line_number <= lines.max; ++line_number){ i64 line_start_pos = get_line_start_pos(app, buffer, line_number); - Indent_Info indent_info = get_indent_info_line_start(app, buffer, line_start_pos, tab_width); + Indent_Info indent_info = get_indent_info_line_number_and_start(app, buffer, line_number, line_start_pos, tab_width); i64 correct_indentation = shifted_indentations[line_number]; if (indent_info.is_blank && HasFlag(flags, Indent_ClearLine)){ @@ -63,6 +63,7 @@ set_line_indents(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i internal Token* find_anchor_token(Application_Links *app, Buffer_ID buffer, Token_Array *tokens, i64 invalid_line){ + ProfileScope(app, "find anchor token"); Token *result = 0; if (tokens != 0 && tokens->tokens != 0){ @@ -148,6 +149,7 @@ indent__unfinished_statement(Token *token, Nest *current_nest){ internal i64* get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 lines, Indent_Flag flags, i32 tab_width, i32 indent_width){ + ProfileScope(app, "get indentation array"); i64 count = lines.max - lines.min + 1; i64 *indentations = push_array(arena, i64, count); i64 *shifted_indentations = indentations - lines.first; @@ -174,11 +176,31 @@ get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Ra i64 actual_indent = 0; b32 in_unfinished_statement = false; + i64 line_where_token_starts = 0; + i64 line_start_pos = 0; + i64 line_one_past_last_pos = 0; + Indent_Info line_indent_info = {}; + for (;;){ Token *token = token_it_read(&token_it); - i64 line_where_token_starts = get_line_number_from_pos(app, buffer, token->pos); - i64 line_start_pos = get_line_start_pos(app, buffer, line_where_token_starts); - Indent_Info line_indent_info = get_indent_info_line_start(app, buffer, line_start_pos, tab_width); + + if (line_where_token_starts == 0 || + token->pos >= line_one_past_last_pos){ + + { + line_where_token_starts = get_line_number_from_pos(app, buffer, token->pos); + } + { + line_start_pos = get_line_start_pos(app, buffer, line_where_token_starts); + } + { + line_one_past_last_pos = get_line_end_pos(app, buffer, line_where_token_starts); + } + { + Range_i64 range = Ii64(line_start_pos, line_one_past_last_pos); + line_indent_info = get_indent_info_range(app, buffer, range, tab_width); + } + } i64 current_indent = 0; if (nest != 0){ @@ -255,9 +277,9 @@ get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Ra } #define EMIT(N) \ - Stmnt(if (lines.first <= line_it){shifted_indentations[line_it]=N;} \ - if (line_it == lines.end){goto finished;} \ - actual_indent = N; ) +Stmnt(if (lines.first <= line_it){shifted_indentations[line_it]=N;} \ +if (line_it == lines.end){goto finished;} \ +actual_indent = N; ) i64 line_it = line_last_indented; for (;line_it < line_where_token_starts;){ @@ -275,7 +297,7 @@ get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Ra for (;line_it < line_where_token_ends;){ line_it += 1; i64 line_it_start_pos = get_line_start_pos(app, buffer, line_it); - Indent_Info line_it_indent_info = get_indent_info_line_start(app, buffer, line_it_start_pos, tab_width); + Indent_Info line_it_indent_info = get_indent_info_line_number_and_start(app, buffer, line_it, line_it_start_pos, tab_width); i64 new_indent = line_it_indent_info.indent_pos + line_where_token_starts_shift; new_indent = clamp_bot(0, new_indent); EMIT(new_indent); @@ -395,6 +417,7 @@ CUSTOM_DOC("Auto-indents the range between the cursor and the mark.") CUSTOM_COMMAND_SIG(write_text_and_auto_indent) CUSTOM_DOC("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.") { + ProfileScope(app, "write and auto indent"); User_Input in = get_current_input(app); String_Const_u8 insert = to_writable(&in); if (insert.str != 0 && insert.size > 0){ diff --git a/custom/4coder_helper.cpp b/custom/4coder_helper.cpp index d074e891..c4246f52 100644 --- a/custom/4coder_helper.cpp +++ b/custom/4coder_helper.cpp @@ -68,15 +68,15 @@ character_predicate_from_function(Character_Predicate_Function *func){ v[bit_index] = func((u8)i); } predicate.b[byte_index] = ( - (v[0] << 0) | - (v[1] << 1) | - (v[2] << 2) | - (v[3] << 3) | - (v[4] << 4) | - (v[5] << 5) | - (v[6] << 6) | - (v[7] << 7) - ); + (v[0] << 0) | + (v[1] << 1) | + (v[2] << 2) | + (v[3] << 3) | + (v[4] << 4) | + (v[5] << 5) | + (v[6] << 6) | + (v[7] << 7) + ); byte_index += 1; } return(predicate); @@ -797,7 +797,7 @@ enclose_boundary(Application_Links *app, Buffer_ID buffer, Range_i64 range, internal Range_i64 left_enclose_boundary(Application_Links *app, Buffer_ID buffer, Range_i64 range, - Boundary_Function *func){ + Boundary_Function *func){ i64 new_min = func(app, buffer, Side_Min, Scan_Backward, range.min + 1); i64 new_min_check = func(app, buffer, Side_Max, Scan_Backward, range.min + 1); if (new_min_check <= new_min && new_min < range.min){ @@ -1227,8 +1227,8 @@ get_indent_info_range(Application_Links *app, Buffer_ID buffer, Range_i64 range, } internal Indent_Info -get_indent_info_line_start(Application_Links *app, Buffer_ID buffer, i64 line_start, i32 tab_width){ - i64 end = get_line_side_pos_from_pos(app, buffer, line_start, Side_Max); +get_indent_info_line_number_and_start(Application_Links *app, Buffer_ID buffer, i64 line_number, i64 line_start, i32 tab_width){ + i64 end = get_line_side_pos(app, buffer, line_number, Side_Max); return(get_indent_info_range(app, buffer, Ii64(line_start, end), tab_width)); } diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index b4831970..7064e503 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -252,9 +252,9 @@ 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(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, 397 }, +{ 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, 407 }, +{ 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, 388 }, { 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, 611 }, @@ -475,7 +475,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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 a space.", 16, "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_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, 417 }, { 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 }, diff --git a/custom/generated/lexer_cpp.cpp b/custom/generated/lexer_cpp.cpp index 150e5fbf..77bf3f7b 100644 --- a/custom/generated/lexer_cpp.cpp +++ b/custom/generated/lexer_cpp.cpp @@ -44,37 +44,37 @@ lexeme_table_lookup(u64 *hash_array, String_Const_u8 *key_array, #endif u64 main_keys_hash_array[121] = { -0x3165da52e461ac3f,0x0000000000000000,0x3165da52f92661bd,0x0000000000000000, -0x0000000000000000,0x0000000000000000,0x3165da52f9fa6ddb,0xbfc3c777d05a650b, -0x3165da52ea1d2cb3,0x0000000000000000,0x0000000000000000,0x0000000000000000, -0x0000000000000000,0xa47e4b3347ca768b,0xa47e4b0d60643265,0xf9ddaa09147bac4d, -0x95351611c4501ef3,0x0000000000000000,0x0000000000000000,0xa47e4b33693ada65, -0x0000000000000000,0xdb05013ca08bb8f1,0xf9ddaa091485019b,0xbfc3dfcbf5462bb3, -0x0000000000000000,0x3165da52f85e6961,0x0000000000000000,0xdb0563922ce5394d, -0x0000000000000000,0xa47e4b334bfc993f,0xdb02e2748a4d7e43,0x0000000000000000, -0xb4c81ca554c806f3,0x0000000000000000,0x3165da52e0f88b5b,0x501eeeb814fbf821, -0x0000000000000000,0xdb0503951fae6cc1,0x0000000000000000,0x0000000000000000, -0xbfc3de349dfab331,0x0000000000000000,0x0000000000000000,0x3165da52f092830f, -0xa47e4b300b3f05d3,0xbfc3dfcbf546362d,0xdb05125809d1c12f,0x0000000000000000, -0xed66c2eeb45a9c73,0x0000000000000000,0xf9ddaa0914eaa03f,0x77f5a2bcd06af3a3, -0xa47e4b0cab3b440f,0x0000000000000000,0x0000000000000000,0x3165da52ebde8871, -0xa47e4b0cab0869b5,0x3165da52e5b576b7,0x0000000000000000,0x0000000000000000, -0xa47e4b336935d383,0x0000000000000000,0x0000000000000000,0xa47e4b30efc0220b, -0x0000000000000000,0x0000000000000000,0x501eeeb814fabe67,0xbfc3dfefa2fc3a77, -0x0000000000000000,0x0000000000000000,0x0000000000000000,0xf9ddaa0914bb0bf9, -0x0000000000000000,0xf9ddaa09148a58bb,0x0000000000000000,0xdb02e323971f6e8d, -0x501eeeb814fa0161,0xa9cef01e4d45a29b,0x501eeeb814fb939f,0x0000000000000000, -0xdb0517ba16b3ab83,0xbfc3dfb0ab021849,0xdb0541265bb691e9,0xbfc3df66cacb41a5, -0xa47e4b325526bb31,0x0000000000000000,0xeca54fbddbbe35d5,0xa47e4b3347a263d3, -0x0000000000000000,0x77e3dcb62d4753c1,0xdb05aa39286523b1,0x0000000000000000, -0xf9ddaa0914b809a1,0x0000000000000000,0xc6f60bbdf7c8c073,0x3165da52e44f8393, -0x0000000000000000,0x0000000000000000,0xa47e4b32f4f66927,0x0000000000000000, -0xf9ddaa0914dd4631,0x0000000000000000,0xa47e4b322642ad51,0x0000000000000000, -0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000, -0xa47e4b335ea331b5,0x0000000000000000,0x0000000000000000,0x0000000000000000, -0xdb0545d45d35a161,0xeca54fbddbbe34ff,0x44a0daa872c59baf,0x0000000000000000, -0xf9ddaa0914c5876b,0x0000000000000000,0x501eeeb814fa0b79,0xf9ddaa0914df8d85, -0xf9ddaa0914b167f3, + 0x3165da52e461ac3f,0x0000000000000000,0x3165da52f92661bd,0x0000000000000000, + 0x0000000000000000,0x0000000000000000,0x3165da52f9fa6ddb,0xbfc3c777d05a650b, + 0x3165da52ea1d2cb3,0x0000000000000000,0x0000000000000000,0x0000000000000000, + 0x0000000000000000,0xa47e4b3347ca768b,0xa47e4b0d60643265,0xf9ddaa09147bac4d, + 0x95351611c4501ef3,0x0000000000000000,0x0000000000000000,0xa47e4b33693ada65, + 0x0000000000000000,0xdb05013ca08bb8f1,0xf9ddaa091485019b,0xbfc3dfcbf5462bb3, + 0x0000000000000000,0x3165da52f85e6961,0x0000000000000000,0xdb0563922ce5394d, + 0x0000000000000000,0xa47e4b334bfc993f,0xdb02e2748a4d7e43,0x0000000000000000, + 0xb4c81ca554c806f3,0x0000000000000000,0x3165da52e0f88b5b,0x501eeeb814fbf821, + 0x0000000000000000,0xdb0503951fae6cc1,0x0000000000000000,0x0000000000000000, + 0xbfc3de349dfab331,0x0000000000000000,0x0000000000000000,0x3165da52f092830f, + 0xa47e4b300b3f05d3,0xbfc3dfcbf546362d,0xdb05125809d1c12f,0x0000000000000000, + 0xed66c2eeb45a9c73,0x0000000000000000,0xf9ddaa0914eaa03f,0x77f5a2bcd06af3a3, + 0xa47e4b0cab3b440f,0x0000000000000000,0x0000000000000000,0x3165da52ebde8871, + 0xa47e4b0cab0869b5,0x3165da52e5b576b7,0x0000000000000000,0x0000000000000000, + 0xa47e4b336935d383,0x0000000000000000,0x0000000000000000,0xa47e4b30efc0220b, + 0x0000000000000000,0x0000000000000000,0x501eeeb814fabe67,0xbfc3dfefa2fc3a77, + 0x0000000000000000,0x0000000000000000,0x0000000000000000,0xf9ddaa0914bb0bf9, + 0x0000000000000000,0xf9ddaa09148a58bb,0x0000000000000000,0xdb02e323971f6e8d, + 0x501eeeb814fa0161,0xa9cef01e4d45a29b,0x501eeeb814fb939f,0x0000000000000000, + 0xdb0517ba16b3ab83,0xbfc3dfb0ab021849,0xdb0541265bb691e9,0xbfc3df66cacb41a5, + 0xa47e4b325526bb31,0x0000000000000000,0xeca54fbddbbe35d5,0xa47e4b3347a263d3, + 0x0000000000000000,0x77e3dcb62d4753c1,0xdb05aa39286523b1,0x0000000000000000, + 0xf9ddaa0914b809a1,0x0000000000000000,0xc6f60bbdf7c8c073,0x3165da52e44f8393, + 0x0000000000000000,0x0000000000000000,0xa47e4b32f4f66927,0x0000000000000000, + 0xf9ddaa0914dd4631,0x0000000000000000,0xa47e4b322642ad51,0x0000000000000000, + 0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000, + 0xa47e4b335ea331b5,0x0000000000000000,0x0000000000000000,0x0000000000000000, + 0xdb0545d45d35a161,0xeca54fbddbbe34ff,0x44a0daa872c59baf,0x0000000000000000, + 0xf9ddaa0914c5876b,0x0000000000000000,0x501eeeb814fa0b79,0xf9ddaa0914df8d85, + 0xf9ddaa0914b167f3, }; u8 main_keys_key_array_0[] = {0x63,0x61,0x74,0x63,0x68,}; u8 main_keys_key_array_2[] = {0x75,0x6e,0x69,0x6f,0x6e,}; @@ -143,261 +143,261 @@ u8 main_keys_key_array_118[] = {0x61,0x73,0x6d,}; u8 main_keys_key_array_119[] = {0x65,0x6e,0x75,0x6d,}; u8 main_keys_key_array_120[] = {0x76,0x6f,0x69,0x64,}; String_Const_u8 main_keys_key_array[121] = { -{main_keys_key_array_0, 5}, -{0, 0}, -{main_keys_key_array_2, 5}, -{0, 0}, -{0, 0}, -{0, 0}, -{main_keys_key_array_6, 5}, -{main_keys_key_array_7, 7}, -{main_keys_key_array_8, 5}, -{0, 0}, -{0, 0}, -{0, 0}, -{0, 0}, -{main_keys_key_array_13, 6}, -{main_keys_key_array_14, 6}, -{main_keys_key_array_15, 4}, -{main_keys_key_array_16, 12}, -{0, 0}, -{0, 0}, -{main_keys_key_array_19, 6}, -{0, 0}, -{main_keys_key_array_21, 8}, -{main_keys_key_array_22, 4}, -{main_keys_key_array_23, 7}, -{0, 0}, -{main_keys_key_array_25, 5}, -{0, 0}, -{main_keys_key_array_27, 8}, -{0, 0}, -{main_keys_key_array_29, 6}, -{main_keys_key_array_30, 8}, -{0, 0}, -{main_keys_key_array_32, 11}, -{0, 0}, -{main_keys_key_array_34, 5}, -{main_keys_key_array_35, 3}, -{0, 0}, -{main_keys_key_array_37, 8}, -{0, 0}, -{0, 0}, -{main_keys_key_array_40, 7}, -{0, 0}, -{0, 0}, -{main_keys_key_array_43, 5}, -{main_keys_key_array_44, 6}, -{main_keys_key_array_45, 7}, -{main_keys_key_array_46, 8}, -{0, 0}, -{main_keys_key_array_48, 16}, -{0, 0}, -{main_keys_key_array_50, 4}, -{main_keys_key_array_51, 9}, -{main_keys_key_array_52, 6}, -{0, 0}, -{0, 0}, -{main_keys_key_array_55, 5}, -{main_keys_key_array_56, 6}, -{main_keys_key_array_57, 5}, -{0, 0}, -{0, 0}, -{main_keys_key_array_60, 6}, -{0, 0}, -{0, 0}, -{main_keys_key_array_63, 6}, -{0, 0}, -{0, 0}, -{main_keys_key_array_66, 3}, -{main_keys_key_array_67, 7}, -{0, 0}, -{0, 0}, -{0, 0}, -{main_keys_key_array_71, 4}, -{0, 0}, -{main_keys_key_array_73, 4}, -{0, 0}, -{main_keys_key_array_75, 8}, -{main_keys_key_array_76, 3}, -{main_keys_key_array_77, 12}, -{main_keys_key_array_78, 3}, -{0, 0}, -{main_keys_key_array_80, 8}, -{main_keys_key_array_81, 7}, -{main_keys_key_array_82, 8}, -{main_keys_key_array_83, 7}, -{main_keys_key_array_84, 6}, -{0, 0}, -{main_keys_key_array_86, 2}, -{main_keys_key_array_87, 6}, -{0, 0}, -{main_keys_key_array_89, 9}, -{main_keys_key_array_90, 8}, -{0, 0}, -{main_keys_key_array_92, 4}, -{0, 0}, -{main_keys_key_array_94, 10}, -{main_keys_key_array_95, 5}, -{0, 0}, -{0, 0}, -{main_keys_key_array_98, 6}, -{0, 0}, -{main_keys_key_array_100, 4}, -{0, 0}, -{main_keys_key_array_102, 6}, -{0, 0}, -{0, 0}, -{0, 0}, -{0, 0}, -{0, 0}, -{main_keys_key_array_108, 6}, -{0, 0}, -{0, 0}, -{0, 0}, -{main_keys_key_array_112, 8}, -{main_keys_key_array_113, 2}, -{main_keys_key_array_114, 13}, -{0, 0}, -{main_keys_key_array_116, 4}, -{0, 0}, -{main_keys_key_array_118, 3}, -{main_keys_key_array_119, 4}, -{main_keys_key_array_120, 4}, + {main_keys_key_array_0, 5}, + {0, 0}, + {main_keys_key_array_2, 5}, + {0, 0}, + {0, 0}, + {0, 0}, + {main_keys_key_array_6, 5}, + {main_keys_key_array_7, 7}, + {main_keys_key_array_8, 5}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {main_keys_key_array_13, 6}, + {main_keys_key_array_14, 6}, + {main_keys_key_array_15, 4}, + {main_keys_key_array_16, 12}, + {0, 0}, + {0, 0}, + {main_keys_key_array_19, 6}, + {0, 0}, + {main_keys_key_array_21, 8}, + {main_keys_key_array_22, 4}, + {main_keys_key_array_23, 7}, + {0, 0}, + {main_keys_key_array_25, 5}, + {0, 0}, + {main_keys_key_array_27, 8}, + {0, 0}, + {main_keys_key_array_29, 6}, + {main_keys_key_array_30, 8}, + {0, 0}, + {main_keys_key_array_32, 11}, + {0, 0}, + {main_keys_key_array_34, 5}, + {main_keys_key_array_35, 3}, + {0, 0}, + {main_keys_key_array_37, 8}, + {0, 0}, + {0, 0}, + {main_keys_key_array_40, 7}, + {0, 0}, + {0, 0}, + {main_keys_key_array_43, 5}, + {main_keys_key_array_44, 6}, + {main_keys_key_array_45, 7}, + {main_keys_key_array_46, 8}, + {0, 0}, + {main_keys_key_array_48, 16}, + {0, 0}, + {main_keys_key_array_50, 4}, + {main_keys_key_array_51, 9}, + {main_keys_key_array_52, 6}, + {0, 0}, + {0, 0}, + {main_keys_key_array_55, 5}, + {main_keys_key_array_56, 6}, + {main_keys_key_array_57, 5}, + {0, 0}, + {0, 0}, + {main_keys_key_array_60, 6}, + {0, 0}, + {0, 0}, + {main_keys_key_array_63, 6}, + {0, 0}, + {0, 0}, + {main_keys_key_array_66, 3}, + {main_keys_key_array_67, 7}, + {0, 0}, + {0, 0}, + {0, 0}, + {main_keys_key_array_71, 4}, + {0, 0}, + {main_keys_key_array_73, 4}, + {0, 0}, + {main_keys_key_array_75, 8}, + {main_keys_key_array_76, 3}, + {main_keys_key_array_77, 12}, + {main_keys_key_array_78, 3}, + {0, 0}, + {main_keys_key_array_80, 8}, + {main_keys_key_array_81, 7}, + {main_keys_key_array_82, 8}, + {main_keys_key_array_83, 7}, + {main_keys_key_array_84, 6}, + {0, 0}, + {main_keys_key_array_86, 2}, + {main_keys_key_array_87, 6}, + {0, 0}, + {main_keys_key_array_89, 9}, + {main_keys_key_array_90, 8}, + {0, 0}, + {main_keys_key_array_92, 4}, + {0, 0}, + {main_keys_key_array_94, 10}, + {main_keys_key_array_95, 5}, + {0, 0}, + {0, 0}, + {main_keys_key_array_98, 6}, + {0, 0}, + {main_keys_key_array_100, 4}, + {0, 0}, + {main_keys_key_array_102, 6}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {main_keys_key_array_108, 6}, + {0, 0}, + {0, 0}, + {0, 0}, + {main_keys_key_array_112, 8}, + {main_keys_key_array_113, 2}, + {main_keys_key_array_114, 13}, + {0, 0}, + {main_keys_key_array_116, 4}, + {0, 0}, + {main_keys_key_array_118, 3}, + {main_keys_key_array_119, 4}, + {main_keys_key_array_120, 4}, }; Lexeme_Table_Value main_keys_value_array[121] = { -{4, TokenCppKind_Catch}, -{0, 0}, -{4, TokenCppKind_Union}, -{0, 0}, -{0, 0}, -{0, 0}, -{4, TokenCppKind_Using}, -{4, TokenCppKind_Virtual}, -{4, TokenCppKind_Float}, -{0, 0}, -{0, 0}, -{0, 0}, -{0, 0}, -{4, TokenCppKind_Static}, -{4, TokenCppKind_Inline}, -{8, TokenCppKind_LiteralTrue}, -{4, TokenCppKind_DynamicCast}, -{0, 0}, -{0, 0}, -{4, TokenCppKind_SizeOf}, -{0, 0}, -{4, TokenCppKind_Template}, -{4, TokenCppKind_This}, -{4, TokenCppKind_AlignAs}, -{0, 0}, -{4, TokenCppKind_While}, -{0, 0}, -{4, TokenCppKind_Typename}, -{0, 0}, -{4, TokenCppKind_Switch}, -{4, TokenCppKind_Explicit}, -{0, 0}, -{4, TokenCppKind_StaticCast}, -{0, 0}, -{4, TokenCppKind_Break}, -{4, TokenCppKind_Try}, -{0, 0}, -{4, TokenCppKind_DeclType}, -{0, 0}, -{0, 0}, -{4, TokenCppKind_Private}, -{0, 0}, -{0, 0}, -{4, TokenCppKind_Short}, -{4, TokenCppKind_TypeID}, -{4, TokenCppKind_AlignOf}, -{4, TokenCppKind_NoExcept}, -{0, 0}, -{4, TokenCppKind_ReinterpretCast}, -{0, 0}, -{4, TokenCppKind_Goto}, -{4, TokenCppKind_Protected}, -{4, TokenCppKind_Export}, -{0, 0}, -{0, 0}, -{8, TokenCppKind_LiteralFalse}, -{4, TokenCppKind_Extern}, -{4, TokenCppKind_Class}, -{0, 0}, -{0, 0}, -{4, TokenCppKind_Signed}, -{0, 0}, -{0, 0}, -{4, TokenCppKind_Public}, -{0, 0}, -{0, 0}, -{4, TokenCppKind_Int}, -{4, TokenCppKind_Default}, -{0, 0}, -{0, 0}, -{0, 0}, -{4, TokenCppKind_Char}, -{0, 0}, -{4, TokenCppKind_Long}, -{0, 0}, -{4, TokenCppKind_Continue}, -{4, TokenCppKind_For}, -{4, TokenCppKind_ThreadLocal}, -{4, TokenCppKind_New}, -{0, 0}, -{4, TokenCppKind_Unsigned}, -{4, TokenCppKind_NullPtr}, -{4, TokenCppKind_Operator}, -{4, TokenCppKind_Typedef}, -{4, TokenCppKind_Delete}, -{0, 0}, -{4, TokenCppKind_If}, -{4, TokenCppKind_Struct}, -{0, 0}, -{4, TokenCppKind_Namespace}, -{4, TokenCppKind_Register}, -{0, 0}, -{4, TokenCppKind_Case}, -{0, 0}, -{4, TokenCppKind_ConstCast}, -{4, TokenCppKind_Const}, -{0, 0}, -{0, 0}, -{4, TokenCppKind_Friend}, -{0, 0}, -{4, TokenCppKind_Else}, -{0, 0}, -{4, TokenCppKind_Double}, -{0, 0}, -{0, 0}, -{0, 0}, -{0, 0}, -{0, 0}, -{4, TokenCppKind_Return}, -{0, 0}, -{0, 0}, -{0, 0}, -{4, TokenCppKind_Volatile}, -{4, TokenCppKind_Do}, -{4, TokenCppKind_StaticAssert}, -{0, 0}, -{4, TokenCppKind_Bool}, -{0, 0}, -{4, TokenCppKind_Asm}, -{4, TokenCppKind_Enum}, -{4, TokenCppKind_Void}, + {4, TokenCppKind_Catch}, + {0, 0}, + {4, TokenCppKind_Union}, + {0, 0}, + {0, 0}, + {0, 0}, + {4, TokenCppKind_Using}, + {4, TokenCppKind_Virtual}, + {4, TokenCppKind_Float}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {4, TokenCppKind_Static}, + {4, TokenCppKind_Inline}, + {8, TokenCppKind_LiteralTrue}, + {4, TokenCppKind_DynamicCast}, + {0, 0}, + {0, 0}, + {4, TokenCppKind_SizeOf}, + {0, 0}, + {4, TokenCppKind_Template}, + {4, TokenCppKind_This}, + {4, TokenCppKind_AlignAs}, + {0, 0}, + {4, TokenCppKind_While}, + {0, 0}, + {4, TokenCppKind_Typename}, + {0, 0}, + {4, TokenCppKind_Switch}, + {4, TokenCppKind_Explicit}, + {0, 0}, + {4, TokenCppKind_StaticCast}, + {0, 0}, + {4, TokenCppKind_Break}, + {4, TokenCppKind_Try}, + {0, 0}, + {4, TokenCppKind_DeclType}, + {0, 0}, + {0, 0}, + {4, TokenCppKind_Private}, + {0, 0}, + {0, 0}, + {4, TokenCppKind_Short}, + {4, TokenCppKind_TypeID}, + {4, TokenCppKind_AlignOf}, + {4, TokenCppKind_NoExcept}, + {0, 0}, + {4, TokenCppKind_ReinterpretCast}, + {0, 0}, + {4, TokenCppKind_Goto}, + {4, TokenCppKind_Protected}, + {4, TokenCppKind_Export}, + {0, 0}, + {0, 0}, + {8, TokenCppKind_LiteralFalse}, + {4, TokenCppKind_Extern}, + {4, TokenCppKind_Class}, + {0, 0}, + {0, 0}, + {4, TokenCppKind_Signed}, + {0, 0}, + {0, 0}, + {4, TokenCppKind_Public}, + {0, 0}, + {0, 0}, + {4, TokenCppKind_Int}, + {4, TokenCppKind_Default}, + {0, 0}, + {0, 0}, + {0, 0}, + {4, TokenCppKind_Char}, + {0, 0}, + {4, TokenCppKind_Long}, + {0, 0}, + {4, TokenCppKind_Continue}, + {4, TokenCppKind_For}, + {4, TokenCppKind_ThreadLocal}, + {4, TokenCppKind_New}, + {0, 0}, + {4, TokenCppKind_Unsigned}, + {4, TokenCppKind_NullPtr}, + {4, TokenCppKind_Operator}, + {4, TokenCppKind_Typedef}, + {4, TokenCppKind_Delete}, + {0, 0}, + {4, TokenCppKind_If}, + {4, TokenCppKind_Struct}, + {0, 0}, + {4, TokenCppKind_Namespace}, + {4, TokenCppKind_Register}, + {0, 0}, + {4, TokenCppKind_Case}, + {0, 0}, + {4, TokenCppKind_ConstCast}, + {4, TokenCppKind_Const}, + {0, 0}, + {0, 0}, + {4, TokenCppKind_Friend}, + {0, 0}, + {4, TokenCppKind_Else}, + {0, 0}, + {4, TokenCppKind_Double}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {0, 0}, + {4, TokenCppKind_Return}, + {0, 0}, + {0, 0}, + {0, 0}, + {4, TokenCppKind_Volatile}, + {4, TokenCppKind_Do}, + {4, TokenCppKind_StaticAssert}, + {0, 0}, + {4, TokenCppKind_Bool}, + {0, 0}, + {4, TokenCppKind_Asm}, + {4, TokenCppKind_Enum}, + {4, TokenCppKind_Void}, }; i32 main_keys_slot_count = 121; u64 main_keys_seed = 0x32a240442a6e221f; u64 pp_directives_hash_array[25] = { -0xa8f3b0d79807b793,0x808ba552d670368f,0x0000000000000000,0x808ba54dc047d94b, -0x3b97f7088cbf95df,0x7fd91d3d238e04c9,0x0000000000000000,0x7fd91d3dac09e067, -0x0000000000000000,0x0000000000000000,0xa8f3beab5b880ad3,0x0000000000000000, -0x3b97f7088cbffd3b,0x3b97f7088cdab44b,0x79521904bb682f3f,0x0000000000000000, -0x0000000000000000,0x7fd91d3d978c615f,0x808ba553ad911e19,0x0000000000000000, -0x808ba54ef8496067,0x7fd91d3d2fe85067,0x7fd91d3d97a21607,0x0000000000000000, -0x0000000000000000, + 0xa8f3b0d79807b793,0x808ba552d670368f,0x0000000000000000,0x808ba54dc047d94b, + 0x3b97f7088cbf95df,0x7fd91d3d238e04c9,0x0000000000000000,0x7fd91d3dac09e067, + 0x0000000000000000,0x0000000000000000,0xa8f3beab5b880ad3,0x0000000000000000, + 0x3b97f7088cbffd3b,0x3b97f7088cdab44b,0x79521904bb682f3f,0x0000000000000000, + 0x0000000000000000,0x7fd91d3d978c615f,0x808ba553ad911e19,0x0000000000000000, + 0x808ba54ef8496067,0x7fd91d3d2fe85067,0x7fd91d3d97a21607,0x0000000000000000, + 0x0000000000000000, }; u8 pp_directives_key_array_0[] = {0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,}; u8 pp_directives_key_array_1[] = {0x70,0x72,0x61,0x67,0x6d,0x61,}; @@ -415,4730 +415,4730 @@ u8 pp_directives_key_array_20[] = {0x69,0x66,0x6e,0x64,0x65,0x66,}; u8 pp_directives_key_array_21[] = {0x75,0x6e,0x64,0x65,0x66,}; u8 pp_directives_key_array_22[] = {0x65,0x72,0x72,0x6f,0x72,}; String_Const_u8 pp_directives_key_array[25] = { -{pp_directives_key_array_0, 7}, -{pp_directives_key_array_1, 6}, -{0, 0}, -{pp_directives_key_array_3, 6}, -{pp_directives_key_array_4, 4}, -{pp_directives_key_array_5, 5}, -{0, 0}, -{pp_directives_key_array_7, 5}, -{0, 0}, -{0, 0}, -{pp_directives_key_array_10, 7}, -{0, 0}, -{pp_directives_key_array_12, 4}, -{pp_directives_key_array_13, 4}, -{pp_directives_key_array_14, 2}, -{0, 0}, -{0, 0}, -{pp_directives_key_array_17, 5}, -{pp_directives_key_array_18, 6}, -{0, 0}, -{pp_directives_key_array_20, 6}, -{pp_directives_key_array_21, 5}, -{pp_directives_key_array_22, 5}, -{0, 0}, -{0, 0}, + {pp_directives_key_array_0, 7}, + {pp_directives_key_array_1, 6}, + {0, 0}, + {pp_directives_key_array_3, 6}, + {pp_directives_key_array_4, 4}, + {pp_directives_key_array_5, 5}, + {0, 0}, + {pp_directives_key_array_7, 5}, + {0, 0}, + {0, 0}, + {pp_directives_key_array_10, 7}, + {0, 0}, + {pp_directives_key_array_12, 4}, + {pp_directives_key_array_13, 4}, + {pp_directives_key_array_14, 2}, + {0, 0}, + {0, 0}, + {pp_directives_key_array_17, 5}, + {pp_directives_key_array_18, 6}, + {0, 0}, + {pp_directives_key_array_20, 6}, + {pp_directives_key_array_21, 5}, + {pp_directives_key_array_22, 5}, + {0, 0}, + {0, 0}, }; Lexeme_Table_Value pp_directives_value_array[25] = { -{5, TokenCppKind_PPInclude}, -{5, TokenCppKind_PPPragma}, -{0, 0}, -{5, TokenCppKind_PPDefine}, -{5, TokenCppKind_PPElIf}, -{5, TokenCppKind_PPUsing}, -{0, 0}, -{5, TokenCppKind_PPIfDef}, -{0, 0}, -{0, 0}, -{5, TokenCppKind_PPVersion}, -{0, 0}, -{5, TokenCppKind_PPElse}, -{5, TokenCppKind_PPLine}, -{5, TokenCppKind_PPIf}, -{0, 0}, -{0, 0}, -{5, TokenCppKind_PPEndIf}, -{5, TokenCppKind_PPImport}, -{0, 0}, -{5, TokenCppKind_PPIfNDef}, -{5, TokenCppKind_PPUndef}, -{5, TokenCppKind_PPError}, -{0, 0}, -{0, 0}, + {5, TokenCppKind_PPInclude}, + {5, TokenCppKind_PPPragma}, + {0, 0}, + {5, TokenCppKind_PPDefine}, + {5, TokenCppKind_PPElIf}, + {5, TokenCppKind_PPUsing}, + {0, 0}, + {5, TokenCppKind_PPIfDef}, + {0, 0}, + {0, 0}, + {5, TokenCppKind_PPVersion}, + {0, 0}, + {5, TokenCppKind_PPElse}, + {5, TokenCppKind_PPLine}, + {5, TokenCppKind_PPIf}, + {0, 0}, + {0, 0}, + {5, TokenCppKind_PPEndIf}, + {5, TokenCppKind_PPImport}, + {0, 0}, + {5, TokenCppKind_PPIfNDef}, + {5, TokenCppKind_PPUndef}, + {5, TokenCppKind_PPError}, + {0, 0}, + {0, 0}, }; i32 pp_directives_slot_count = 25; u64 pp_directives_seed = 0x8848fb3caaf5d4d5; u64 pp_keys_hash_array[2] = { -0x0000000000000000,0x72743f437c9f847d, + 0x0000000000000000,0x72743f437c9f847d, }; u8 pp_keys_key_array_1[] = {0x64,0x65,0x66,0x69,0x6e,0x65,0x64,}; String_Const_u8 pp_keys_key_array[2] = { -{0, 0}, -{pp_keys_key_array_1, 7}, + {0, 0}, + {pp_keys_key_array_1, 7}, }; Lexeme_Table_Value pp_keys_value_array[2] = { -{0, 0}, -{4, TokenCppKind_PPDefined}, + {0, 0}, + {4, TokenCppKind_PPDefined}, }; i32 pp_keys_slot_count = 2; u64 pp_keys_seed = 0x71428d58f01a7eed; struct Lex_State_Cpp{ -u32 flags_ZF0; -u32 flags_KF0; -u16 flags_KB0; -u8 *base; -u8 *delim_first; -u8 *delim_one_past_last; -u8 *emit_ptr; -u8 *ptr; -u8 *opl_ptr; + u32 flags_ZF0; + u32 flags_KF0; + u16 flags_KB0; + u8 *base; + u8 *delim_first; + u8 *delim_one_past_last; + u8 *emit_ptr; + u8 *ptr; + u8 *opl_ptr; }; internal void lex_full_input_cpp_init(Lex_State_Cpp *state_ptr, String_Const_u8 input){ -state_ptr->flags_ZF0 = 0; -state_ptr->flags_KF0 = 0; -state_ptr->flags_KB0 = 0; -state_ptr->base = input.str; -state_ptr->delim_first = input.str; -state_ptr->delim_one_past_last = input.str; -state_ptr->emit_ptr = input.str; -state_ptr->ptr = input.str; -state_ptr->opl_ptr = input.str + input.size; + state_ptr->flags_ZF0 = 0; + state_ptr->flags_KF0 = 0; + state_ptr->flags_KB0 = 0; + state_ptr->base = input.str; + state_ptr->delim_first = input.str; + state_ptr->delim_one_past_last = input.str; + state_ptr->emit_ptr = input.str; + state_ptr->ptr = input.str; + state_ptr->opl_ptr = input.str + input.size; } internal b32 lex_full_input_cpp_breaks(Arena *arena, Token_List *list, Lex_State_Cpp *state_ptr, u64 max){ -b32 result = false; -u64 emit_counter = 0; -Lex_State_Cpp state; -block_copy_struct(&state, state_ptr); -{ -state_label_1: // root -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_EOF; -token.kind = 0; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -result = true; -goto end; -} -} -switch (*state.ptr){ -case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06: -case 0x07:case 0x08:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12: -case 0x13:case 0x14:case 0x15:case 0x16:case 0x17:case 0x18:case 0x19: -case 0x1a:case 0x1b:case 0x1c:case 0x1d:case 0x1e:case 0x1f:case 0x40: -case 0x60:case 0x7f: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x09:case 0x0b:case 0x0c:case 0x0d:case 0x20: -{ -if ((HasFlag(state.flags_KF0, 0x2))){ -state.ptr += 1; -goto state_label_4; // error_body -} -state.ptr += 1; -goto state_label_3; // whitespace -}break; -case 0x0a: -{ -state.ptr += 1; -state.flags_KB0 &= ~(0x1); -state.flags_KF0 &= ~(0x1); -state.flags_KF0 &= ~(0x2); -goto state_label_3; // whitespace -}break; -case 0x21: -{ -state.ptr += 1; -goto state_label_60; // op stage -}break; -case 0x22: -{ -if ((HasFlag(state.flags_KF0, 0x1))){ -state.ptr += 1; -goto state_label_26; // include_quotes -} -state.ptr += 1; -goto state_label_32; // string -}break; -case 0x23: -{ -if ((!HasFlag(state.flags_KB0, 0x1))){ -state.ptr += 1; -goto state_label_23; // pp_directive_whitespace -} -state.ptr += 1; -goto state_label_67; // op stage -}break; -default: -{ -state.ptr += 1; -goto state_label_2; // identifier -}break; -case 0x25: -{ -state.ptr += 1; -goto state_label_64; // op stage -}break; -case 0x26: -{ -state.ptr += 1; -goto state_label_61; // op stage -}break; -case 0x27: -{ -state.ptr += 1; -state.flags_ZF0 |= 0x40; -goto state_label_32; // string -}break; -case 0x28: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_ParenOp; -token.kind = 13; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x29: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_ParenCl; -token.kind = 14; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x2a: -{ -state.ptr += 1; -goto state_label_63; // op stage -}break; -case 0x2b: -{ -state.ptr += 1; -goto state_label_53; // op stage -}break; -case 0x2c: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Comma; -token.kind = 15; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x2d: -{ -state.ptr += 1; -goto state_label_54; // op stage -}break; -case 0x2e: -{ -state.ptr += 1; -goto state_label_6; // operator_or_fnumber_dot -}break; -case 0x2f: -{ -state.ptr += 1; -goto state_label_7; // operator_or_comment_slash -}break; -case 0x30: -{ -state.ptr += 1; -goto state_label_9; // znumber -}break; -case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36:case 0x37: -case 0x38:case 0x39: -{ -state.ptr += 1; -goto state_label_8; // number -}break; -case 0x3a: -{ -state.ptr += 1; -goto state_label_52; // op stage -}break; -case 0x3b: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Semicolon; -token.kind = 15; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3c: -{ -if ((!HasFlag(state.flags_KF0, 0x1))){ -state.ptr += 1; -goto state_label_56; // op stage -} -state.ptr += 1; -goto state_label_25; // include_pointy -}break; -case 0x3d: -{ -state.ptr += 1; -goto state_label_59; // op stage -}break; -case 0x3e: -{ -state.ptr += 1; -goto state_label_57; // op stage -}break; -case 0x3f: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Ternary; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x4c: -{ -state.ptr += 1; -state.flags_ZF0 |= 0x4; -goto state_label_27; // pre_L -}break; -case 0x52: -{ -state.ptr += 1; -goto state_label_31; // pre_R -}break; -case 0x55: -{ -state.ptr += 1; -state.flags_ZF0 |= 0x20; -goto state_label_29; // pre_U -}break; -case 0x5b: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_BrackOp; -token.kind = 13; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x5c: -{ -state.ptr += 1; -goto state_label_5; // backslash -}break; -case 0x5d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_BrackCl; -token.kind = 14; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x5e: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Xor; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x75: -{ -state.ptr += 1; -state.flags_ZF0 |= 0x10; -goto state_label_28; // pre_u -}break; -case 0x7b: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_BraceOp; -token.kind = 11; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x7c: -{ -state.ptr += 1; -goto state_label_62; // op stage -}break; -case 0x7d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_BraceCl; -token.kind = 12; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x7e: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Tilde; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_2: // identifier -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_KB0, 0x1)){ -Lexeme_Table_Lookup lookup = lexeme_table_lookup(pp_keys_hash_array, pp_keys_key_array, pp_keys_value_array, pp_keys_slot_count, pp_keys_seed, state.emit_ptr, token.size); -if (lookup.found_match){ -token.kind = lookup.base_kind; -token.sub_kind = lookup.sub_kind; -break; -} -} -Lexeme_Table_Lookup lookup = lexeme_table_lookup(main_keys_hash_array, main_keys_key_array, main_keys_value_array, main_keys_slot_count, main_keys_seed, state.emit_ptr, token.size); -if (lookup.found_match){ -token.kind = lookup.base_kind; -token.sub_kind = lookup.sub_kind; -break; -} -token.sub_kind = TokenCppKind_Identifier; -token.kind = 6; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06: -case 0x07:case 0x08:case 0x09:case 0x0a:case 0x0b:case 0x0c:case 0x0d: -case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14: -case 0x15:case 0x16:case 0x17:case 0x18:case 0x19:case 0x1a:case 0x1b: -case 0x1c:case 0x1d:case 0x1e:case 0x1f:case 0x20:case 0x21:case 0x22: -case 0x23:case 0x25:case 0x26:case 0x27:case 0x28:case 0x29:case 0x2a: -case 0x2b:case 0x2c:case 0x2d:case 0x2e:case 0x2f:case 0x3a:case 0x3b: -case 0x3c:case 0x3d:case 0x3e:case 0x3f:case 0x40:case 0x5b:case 0x5c: -case 0x5d:case 0x5e:case 0x60:case 0x7b:case 0x7c:case 0x7d:case 0x7e: -case 0x7f: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_KB0, 0x1)){ -Lexeme_Table_Lookup lookup = lexeme_table_lookup(pp_keys_hash_array, pp_keys_key_array, pp_keys_value_array, pp_keys_slot_count, pp_keys_seed, state.emit_ptr, token.size); -if (lookup.found_match){ -token.kind = lookup.base_kind; -token.sub_kind = lookup.sub_kind; -break; -} -} -Lexeme_Table_Lookup lookup = lexeme_table_lookup(main_keys_hash_array, main_keys_key_array, main_keys_value_array, main_keys_slot_count, main_keys_seed, state.emit_ptr, token.size); -if (lookup.found_match){ -token.kind = lookup.base_kind; -token.sub_kind = lookup.sub_kind; -break; -} -token.sub_kind = TokenCppKind_Identifier; -token.kind = 6; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -default: -{ -state.ptr += 1; -goto state_label_2; // identifier -}break; -} -} -{ -state_label_3: // whitespace -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Whitespace; -token.kind = 1; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Whitespace; -token.kind = 1; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x09:case 0x0b:case 0x0c:case 0x0d:case 0x20: -{ -state.ptr += 1; -goto state_label_3; // whitespace -}break; -case 0x0a: -{ -state.ptr += 1; -state.flags_KB0 &= ~(0x1); -state.flags_KF0 &= ~(0x1); -state.flags_KF0 &= ~(0x2); -goto state_label_3; // whitespace -}break; -} -} -{ -state_label_4: // error_body -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_PPErrorMessage; -token.kind = 10; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -state.ptr += 1; -goto state_label_4; // error_body -}break; -case 0x0a: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_PPErrorMessage; -token.kind = 10; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_5: // backslash -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Backslash; -token.kind = 1; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Backslash; -token.kind = 1; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x0a: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Backslash; -token.kind = 1; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_6: // operator_or_fnumber_dot -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Dot; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Dot; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x2a: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_DotStar; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x2e: -{ -state.ptr += 1; -goto state_label_68; // op stage -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39: -{ -state.ptr += 1; -goto state_label_10; // fnumber_decimal -}break; -} -} -{ -state_label_7: // operator_or_comment_slash -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Div; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Div; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x2a: -{ -state.ptr += 1; -goto state_label_49; // comment_block -}break; -case 0x2f: -{ -state.ptr += 1; -goto state_label_51; // comment_line -}break; -case 0x3d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_DivEq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_8: // number -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralInteger; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralInteger; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x2e: -{ -state.ptr += 1; -goto state_label_10; // fnumber_decimal -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39: -{ -state.ptr += 1; -goto state_label_8; // number -}break; -case 0x45:case 0x65: -{ -state.ptr += 1; -goto state_label_11; // fnumber_exponent -}break; -case 0x4c: -{ -state.ptr += 1; -goto state_label_18; // L_number -}break; -case 0x55:case 0x75: -{ -state.ptr += 1; -goto state_label_17; // U_number -}break; -case 0x6c: -{ -state.ptr += 1; -goto state_label_20; // l_number -}break; -} -} -{ -state_label_9: // znumber -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralInteger; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralInteger; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x2e: -{ -state.ptr += 1; -goto state_label_10; // fnumber_decimal -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37: -{ -state.ptr += 1; -state.flags_ZF0 |= 0x2; -goto state_label_16; // number_oct -}break; -case 0x45:case 0x65: -{ -state.ptr += 1; -goto state_label_11; // fnumber_exponent -}break; -case 0x4c: -{ -state.ptr += 1; -goto state_label_18; // L_number -}break; -case 0x55:case 0x75: -{ -state.ptr += 1; -goto state_label_17; // U_number -}break; -case 0x58:case 0x78: -{ -state.ptr += 1; -state.flags_ZF0 |= 0x1; -goto state_label_14; // number_hex_first -}break; -case 0x6c: -{ -state.ptr += 1; -goto state_label_20; // l_number -}break; -} -} -{ -state_label_10: // fnumber_decimal -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat64; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat64; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39: -{ -state.ptr += 1; -goto state_label_10; // fnumber_decimal -}break; -case 0x45:case 0x65: -{ -state.ptr += 1; -goto state_label_11; // fnumber_exponent -}break; -case 0x46:case 0x66: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat32; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x4c:case 0x6c: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat64; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_11: // fnumber_exponent -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat64; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat64; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x2b:case 0x2d: -{ -state.ptr += 1; -goto state_label_12; // fnumber_exponent_sign -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39: -{ -state.ptr += 1; -goto state_label_13; // fnumber_exponent_digits -}break; -case 0x46:case 0x66: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat32; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x4c:case 0x6c: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat64; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_12: // fnumber_exponent_sign -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat64; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat64; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39: -{ -state.ptr += 1; -goto state_label_13; // fnumber_exponent_digits -}break; -case 0x46:case 0x66: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat32; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x4c:case 0x6c: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat64; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_13: // fnumber_exponent_digits -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat64; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat64; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39: -{ -state.ptr += 1; -goto state_label_13; // fnumber_exponent_digits -}break; -case 0x46:case 0x66: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat32; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x4c:case 0x6c: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralFloat64; -token.kind = 9; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_14: // number_hex_first -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66: -{ -state.ptr += 1; -goto state_label_15; // number_hex -}break; -} -} -{ -state_label_15: // number_hex -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralIntegerHex; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralIntegerHex; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66: -{ -state.ptr += 1; -goto state_label_15; // number_hex -}break; -case 0x4c: -{ -state.ptr += 1; -goto state_label_18; // L_number -}break; -case 0x55:case 0x75: -{ -state.ptr += 1; -goto state_label_17; // U_number -}break; -case 0x6c: -{ -state.ptr += 1; -goto state_label_20; // l_number -}break; -} -} -{ -state_label_16: // number_oct -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralIntegerOct; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LiteralIntegerOct; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37: -{ -state.ptr += 1; -state.flags_ZF0 |= 0x2; -goto state_label_16; // number_oct -}break; -case 0x4c: -{ -state.ptr += 1; -goto state_label_18; // L_number -}break; -case 0x55:case 0x75: -{ -state.ptr += 1; -goto state_label_17; // U_number -}break; -case 0x6c: -{ -state.ptr += 1; -goto state_label_20; // l_number -}break; -} -} -{ -state_label_17: // U_number -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexU; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctU; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerU; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexU; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctU; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerU; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x4c: -{ -state.ptr += 1; -goto state_label_19; // UL_number -}break; -case 0x6c: -{ -state.ptr += 1; -goto state_label_21; // Ul_number -}break; -} -} -{ -state_label_18: // L_number -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x4c: -{ -state.ptr += 1; -goto state_label_22; // LL_number -}break; -case 0x55:case 0x75: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexUL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctUL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerUL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_19: // UL_number -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexUL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctUL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerUL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexUL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctUL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerUL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x4c: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexULL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctULL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerULL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_20: // l_number -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x55:case 0x75: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexUL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctUL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerUL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x6c: -{ -state.ptr += 1; -goto state_label_22; // LL_number -}break; -} -} -{ -state_label_21: // Ul_number -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexUL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctUL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerUL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexUL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctUL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerUL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x6c: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexULL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctULL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerULL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_22: // LL_number -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexLL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctLL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerLL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexLL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctLL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerLL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x55:case 0x75: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x1)){ -token.sub_kind = TokenCppKind_LiteralIntegerHexULL; -token.kind = 8; -break; -} -if (HasFlag(state.flags_ZF0, 0x2)){ -token.sub_kind = TokenCppKind_LiteralIntegerOctULL; -token.kind = 8; -break; -} -token.sub_kind = TokenCppKind_LiteralIntegerULL; -token.kind = 8; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_23: // pp_directive_whitespace -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x09:case 0x0b:case 0x0c:case 0x20: -{ -state.ptr += 1; -goto state_label_23; // pp_directive_whitespace -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x47:case 0x48:case 0x49:case 0x4a:case 0x4b: -case 0x4c:case 0x4d:case 0x4e:case 0x4f:case 0x50:case 0x51:case 0x52: -case 0x53:case 0x54:case 0x55:case 0x56:case 0x57:case 0x58:case 0x59: -case 0x5a:case 0x5f:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66:case 0x67:case 0x68:case 0x69:case 0x6a:case 0x6b:case 0x6c: -case 0x6d:case 0x6e:case 0x6f:case 0x70:case 0x71:case 0x72:case 0x73: -case 0x74:case 0x75:case 0x76:case 0x77:case 0x78:case 0x79:case 0x7a: -{ -state.delim_first = state.ptr; -state.flags_KB0 |= 0x1; -state.ptr += 1; -goto state_label_24; // pp_directive -}break; -} -} -{ -state_label_24: // pp_directive -if (state.ptr == state.opl_ptr){ -if ((true)){ -state.delim_one_past_last = state.ptr; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -Lexeme_Table_Lookup lookup = lexeme_table_lookup(pp_directives_hash_array, pp_directives_key_array, pp_directives_value_array, pp_directives_slot_count, pp_directives_seed, state.delim_first, (state.delim_one_past_last - state.delim_first)); -if (lookup.found_match){ -token.kind = lookup.base_kind; -token.sub_kind = lookup.sub_kind; -break; -} -token.sub_kind = TokenCppKind_PPUnknown; -token.kind = 2; -}while(0); -switch (token.sub_kind){ -case TokenCppKind_PPInclude: -{ -state.flags_KF0 |= 0x1; -}break; -case TokenCppKind_PPError: -{ -state.flags_KF0 |= 0x2; -}break; -} -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -state.delim_one_past_last = state.ptr; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -Lexeme_Table_Lookup lookup = lexeme_table_lookup(pp_directives_hash_array, pp_directives_key_array, pp_directives_value_array, pp_directives_slot_count, pp_directives_seed, state.delim_first, (state.delim_one_past_last - state.delim_first)); -if (lookup.found_match){ -token.kind = lookup.base_kind; -token.sub_kind = lookup.sub_kind; -break; -} -token.sub_kind = TokenCppKind_PPUnknown; -token.kind = 2; -}while(0); -switch (token.sub_kind){ -case TokenCppKind_PPInclude: -{ -state.flags_KF0 |= 0x1; -}break; -case TokenCppKind_PPError: -{ -state.flags_KF0 |= 0x2; -}break; -} -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x47:case 0x48:case 0x49:case 0x4a:case 0x4b: -case 0x4c:case 0x4d:case 0x4e:case 0x4f:case 0x50:case 0x51:case 0x52: -case 0x53:case 0x54:case 0x55:case 0x56:case 0x57:case 0x58:case 0x59: -case 0x5a:case 0x5f:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66:case 0x67:case 0x68:case 0x69:case 0x6a:case 0x6b:case 0x6c: -case 0x6d:case 0x6e:case 0x6f:case 0x70:case 0x71:case 0x72:case 0x73: -case 0x74:case 0x75:case 0x76:case 0x77:case 0x78:case 0x79:case 0x7a: -{ -state.ptr += 1; -goto state_label_24; // pp_directive -}break; -} -} -{ -state_label_25: // include_pointy -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x20:case 0x2e:case 0x2f:case 0x30:case 0x31:case 0x32:case 0x33: -case 0x34:case 0x35:case 0x36:case 0x37:case 0x38:case 0x39:case 0x41: -case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:case 0x48: -case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f: -case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56: -case 0x57:case 0x58:case 0x59:case 0x5a:case 0x5c:case 0x5f:case 0x61: -case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67:case 0x68: -case 0x69:case 0x6a:case 0x6b:case 0x6c:case 0x6d:case 0x6e:case 0x6f: -case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76: -case 0x77:case 0x78:case 0x79:case 0x7a: -{ -state.ptr += 1; -goto state_label_25; // include_pointy -}break; -case 0x3e: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_PPIncludeFile; -token.kind = 10; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_26: // include_quotes -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x20:case 0x2e:case 0x2f:case 0x30:case 0x31:case 0x32:case 0x33: -case 0x34:case 0x35:case 0x36:case 0x37:case 0x38:case 0x39:case 0x41: -case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:case 0x48: -case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f: -case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56: -case 0x57:case 0x58:case 0x59:case 0x5a:case 0x5c:case 0x5f:case 0x61: -case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67:case 0x68: -case 0x69:case 0x6a:case 0x6b:case 0x6c:case 0x6d:case 0x6e:case 0x6f: -case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76: -case 0x77:case 0x78:case 0x79:case 0x7a: -{ -state.ptr += 1; -goto state_label_26; // include_quotes -}break; -case 0x22: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_PPIncludeFile; -token.kind = 10; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_27: // pre_L -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_2; // identifier -} -} -switch (*state.ptr){ -default: -{ -goto state_label_2; // identifier -}break; -case 0x22: -{ -state.ptr += 1; -goto state_label_32; // string -}break; -case 0x52: -{ -state.ptr += 1; -goto state_label_31; // pre_R -}break; -} -} -{ -state_label_28: // pre_u -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_2; // identifier -} -} -switch (*state.ptr){ -default: -{ -goto state_label_2; // identifier -}break; -case 0x22: -{ -state.ptr += 1; -goto state_label_32; // string -}break; -case 0x38: -{ -state.ptr += 1; -state.flags_ZF0 |= 0x8; -goto state_label_30; // pre_u8 -}break; -case 0x52: -{ -state.ptr += 1; -goto state_label_31; // pre_R -}break; -} -} -{ -state_label_29: // pre_U -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_2; // identifier -} -} -switch (*state.ptr){ -default: -{ -goto state_label_2; // identifier -}break; -case 0x22: -{ -state.ptr += 1; -goto state_label_32; // string -}break; -case 0x52: -{ -state.ptr += 1; -goto state_label_31; // pre_R -}break; -} -} -{ -state_label_30: // pre_u8 -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_2; // identifier -} -} -switch (*state.ptr){ -default: -{ -goto state_label_2; // identifier -}break; -case 0x22: -{ -state.ptr += 1; -goto state_label_32; // string -}break; -case 0x52: -{ -state.ptr += 1; -goto state_label_31; // pre_R -}break; -} -} -{ -state_label_31: // pre_R -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_2; // identifier -} -} -switch (*state.ptr){ -default: -{ -goto state_label_2; // identifier -}break; -case 0x22: -{ -state.ptr += 1; -state.delim_first = state.ptr; -goto state_label_45; // raw_string_get_delim -}break; -} -} -{ -state_label_32: // string -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -state.ptr += 1; -goto state_label_32; // string -}break; -case 0x0a: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x22: -{ -if ((!HasFlag(state.flags_ZF0, 0x40))){ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x4)){ -token.sub_kind = TokenCppKind_LiteralStringWide; -token.kind = 10; -break; -} -if (HasFlag(state.flags_ZF0, 0x8)){ -token.sub_kind = TokenCppKind_LiteralStringUTF8; -token.kind = 10; -break; -} -if (HasFlag(state.flags_ZF0, 0x10)){ -token.sub_kind = TokenCppKind_LiteralStringUTF16; -token.kind = 10; -break; -} -if (HasFlag(state.flags_ZF0, 0x20)){ -token.sub_kind = TokenCppKind_LiteralStringUTF32; -token.kind = 10; -break; -} -token.sub_kind = TokenCppKind_LiteralString; -token.kind = 10; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -state.ptr += 1; -goto state_label_32; // string -}break; -case 0x27: -{ -if ((HasFlag(state.flags_ZF0, 0x40))){ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x4)){ -token.sub_kind = TokenCppKind_LiteralCharacterWide; -token.kind = 10; -break; -} -if (HasFlag(state.flags_ZF0, 0x8)){ -token.sub_kind = TokenCppKind_LiteralCharacterUTF8; -token.kind = 10; -break; -} -if (HasFlag(state.flags_ZF0, 0x10)){ -token.sub_kind = TokenCppKind_LiteralCharacterUTF16; -token.kind = 10; -break; -} -if (HasFlag(state.flags_ZF0, 0x20)){ -token.sub_kind = TokenCppKind_LiteralCharacterUTF32; -token.kind = 10; -break; -} -token.sub_kind = TokenCppKind_LiteralCharacter; -token.kind = 10; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -state.ptr += 1; -goto state_label_32; // string -}break; -case 0x5c: -{ -state.ptr += 1; -goto state_label_33; // string_esc -}break; -} -} -{ -state_label_33: // string_esc -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_EOF; -token.kind = 0; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -result = true; -goto end; -} -} -switch (*state.ptr){ -default: -{ -state.ptr += 1; -goto state_label_32; // string -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37: -{ -state.ptr += 1; -goto state_label_34; // string_esc_oct2 -}break; -case 0x55: -{ -state.ptr += 1; -goto state_label_37; // string_esc_universal_8 -}break; -case 0x75: -{ -state.ptr += 1; -goto state_label_41; // string_esc_universal_4 -}break; -case 0x78: -{ -state.ptr += 1; -goto state_label_36; // string_esc_hex -}break; -} -} -{ -state_label_34: // string_esc_oct2 -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_32; // string -} -} -switch (*state.ptr){ -default: -{ -goto state_label_32; // string -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37: -{ -state.ptr += 1; -goto state_label_35; // string_esc_oct1 -}break; -} -} -{ -state_label_35: // string_esc_oct1 -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_32; // string -} -} -switch (*state.ptr){ -default: -{ -goto state_label_32; // string -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37: -{ -state.ptr += 1; -goto state_label_32; // string -}break; -} -} -{ -state_label_36: // string_esc_hex -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_32; // string -} -} -switch (*state.ptr){ -default: -{ -goto state_label_32; // string -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66: -{ -state.ptr += 1; -goto state_label_36; // string_esc_hex -}break; -} -} -{ -state_label_37: // string_esc_universal_8 -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_32; // string -} -} -switch (*state.ptr){ -default: -{ -goto state_label_32; // string -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66: -{ -state.ptr += 1; -goto state_label_38; // string_esc_universal_7 -}break; -} -} -{ -state_label_38: // string_esc_universal_7 -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_32; // string -} -} -switch (*state.ptr){ -default: -{ -goto state_label_32; // string -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66: -{ -state.ptr += 1; -goto state_label_39; // string_esc_universal_6 -}break; -} -} -{ -state_label_39: // string_esc_universal_6 -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_32; // string -} -} -switch (*state.ptr){ -default: -{ -goto state_label_32; // string -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66: -{ -state.ptr += 1; -goto state_label_40; // string_esc_universal_5 -}break; -} -} -{ -state_label_40: // string_esc_universal_5 -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_32; // string -} -} -switch (*state.ptr){ -default: -{ -goto state_label_32; // string -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66: -{ -state.ptr += 1; -goto state_label_41; // string_esc_universal_4 -}break; -} -} -{ -state_label_41: // string_esc_universal_4 -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_32; // string -} -} -switch (*state.ptr){ -default: -{ -goto state_label_32; // string -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66: -{ -state.ptr += 1; -goto state_label_42; // string_esc_universal_3 -}break; -} -} -{ -state_label_42: // string_esc_universal_3 -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_32; // string -} -} -switch (*state.ptr){ -default: -{ -goto state_label_32; // string -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66: -{ -state.ptr += 1; -goto state_label_43; // string_esc_universal_2 -}break; -} -} -{ -state_label_43: // string_esc_universal_2 -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_32; // string -} -} -switch (*state.ptr){ -default: -{ -goto state_label_32; // string -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66: -{ -state.ptr += 1; -goto state_label_44; // string_esc_universal_1 -}break; -} -} -{ -state_label_44: // string_esc_universal_1 -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_32; // string -} -} -switch (*state.ptr){ -default: -{ -goto state_label_32; // string -}break; -case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: -case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: -case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: -case 0x66: -{ -state.ptr += 1; -goto state_label_32; // string -}break; -} -} -{ -state_label_45: // raw_string_get_delim -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_EOF; -token.kind = 0; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -result = true; -goto end; -} -} -switch (*state.ptr){ -default: -{ -state.ptr += 1; -goto state_label_45; // raw_string_get_delim -}break; -case 0x20:case 0x29:case 0x5c: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x28: -{ -state.delim_one_past_last = state.ptr; -state.ptr += 1; -goto state_label_46; // raw_string_find_close -}break; -} -} -{ -state_label_46: // raw_string_find_close -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_EOF; -token.kind = 0; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -result = true; -goto end; -} -} -switch (*state.ptr){ -default: -{ -state.ptr += 1; -goto state_label_46; // raw_string_find_close -}break; -case 0x29: -{ -state.ptr += 1; -goto state_label_47; // raw_string_try_delim -}break; -} -} -{ -state_label_47: // raw_string_try_delim -u64 delim_length = state.delim_one_past_last - state.delim_first; -u64 parse_length = 0; -for (;;){ -if (parse_length == delim_length){ -goto state_label_48; // raw_string_try_quote -} -if (state.ptr == state.opl_ptr){ -goto state_label_48; // raw_string_try_quote -} -if (*state.ptr == state.delim_first[parse_length]){ -state.ptr += 1; -parse_length += 1; -} -else{ -goto state_label_46; // raw_string_find_close -} -} -} -{ -state_label_48: // raw_string_try_quote -if (state.ptr == state.opl_ptr){ -if ((true)){ -goto state_label_46; // raw_string_find_close -} -} -switch (*state.ptr){ -default: -{ -goto state_label_46; // raw_string_find_close -}break; -case 0x22: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -if (HasFlag(state.flags_ZF0, 0x4)){ -token.sub_kind = TokenCppKind_LiteralStringWideRaw; -token.kind = 10; -break; -} -if (HasFlag(state.flags_ZF0, 0x8)){ -token.sub_kind = TokenCppKind_LiteralStringUTF8Raw; -token.kind = 10; -break; -} -if (HasFlag(state.flags_ZF0, 0x10)){ -token.sub_kind = TokenCppKind_LiteralStringUTF16Raw; -token.kind = 10; -break; -} -if (HasFlag(state.flags_ZF0, 0x20)){ -token.sub_kind = TokenCppKind_LiteralStringUTF32Raw; -token.kind = 10; -break; -} -token.sub_kind = TokenCppKind_LiteralStringRaw; -token.kind = 10; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_49: // comment_block -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_BlockComment; -token.kind = 3; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_EOF; -token.kind = 0; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -result = true; -goto end; -} -} -switch (*state.ptr){ -default: -{ -state.ptr += 1; -goto state_label_49; // comment_block -}break; -case 0x0a: -{ -state.ptr += 1; -state.flags_KB0 &= ~(0x1); -state.flags_KF0 &= ~(0x1); -goto state_label_49; // comment_block -}break; -case 0x2a: -{ -state.ptr += 1; -goto state_label_50; // comment_block_try_close -}break; -} -} -{ -state_label_50: // comment_block_try_close -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_BlockComment; -token.kind = 3; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_EOF; -token.kind = 0; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -result = true; -goto end; -} -} -switch (*state.ptr){ -default: -{ -state.ptr += 1; -goto state_label_49; // comment_block -}break; -case 0x2a: -{ -state.ptr += 1; -goto state_label_50; // comment_block_try_close -}break; -case 0x2f: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_BlockComment; -token.kind = 3; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_51: // comment_line -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LineComment; -token.kind = 3; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -state.ptr += 1; -goto state_label_51; // comment_line -}break; -case 0x0a: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LineComment; -token.kind = 3; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_52: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Colon; -token.kind = 15; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Colon; -token.kind = 15; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3a: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_ColonColon; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_53: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Plus; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Plus; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x2b: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_PlusPlus; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_PlusEq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_54: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Minus; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Minus; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x2d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_MinusMinus; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_MinusEq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3e: -{ -state.ptr += 1; -goto state_label_55; // op stage -}break; -} -} -{ -state_label_55: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Arrow; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Arrow; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x2a: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_ArrowStar; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_56: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Less; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Less; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3c: -{ -state.ptr += 1; -goto state_label_65; // op stage -}break; -case 0x3d: -{ -state.ptr += 1; -goto state_label_58; // op stage -}break; -} -} -{ -state_label_57: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Grtr; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Grtr; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_GrtrEq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3e: -{ -state.ptr += 1; -goto state_label_66; // op stage -}break; -} -} -{ -state_label_58: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LessEq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LessEq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3e: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Compare; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_59: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Eq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Eq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_EqEq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_60: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Not; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Not; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_NotEq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_61: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_And; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_And; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x26: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_AndAnd; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_62: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Or; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Or; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x7c: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_OrOr; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_63: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Star; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Star; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_StarEq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_64: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Mod; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_Mod; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_ModEq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_65: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LeftLeft; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LeftLeft; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LeftLeftEq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_66: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_RightRight; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_RightRight; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x3d: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_RightRightEq; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_67: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_PPStringify; -token.kind = 15; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_PPStringify; -token.kind = 15; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x23: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_PPConcat; -token.kind = 15; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -{ -state_label_68: // op stage -if (state.ptr == state.opl_ptr){ -if ((true)){ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -} -} -switch (*state.ptr){ -default: -{ -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_LexError; -token.kind = 2; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -case 0x2e: -{ -state.ptr += 1; -{ -Token token = {}; -token.pos = (i64)(state.emit_ptr - state.base); -token.size = (i64)(state.ptr - state.emit_ptr); -token.flags = state.flags_KB0; -do{ -token.sub_kind = TokenCppKind_DotDotDot; -token.kind = 7; -}while(0); -token_list_push(arena, list, &token); -emit_counter += 1; -if (emit_counter == max){ -goto end; -} -state.emit_ptr = state.ptr; -} -state.flags_ZF0 = 0; -goto state_label_1; // root -}break; -} -} -end:; -block_copy_struct(state_ptr, &state); -return(result); + b32 result = false; + u64 emit_counter = 0; + Lex_State_Cpp state; + block_copy_struct(&state, state_ptr); + { + state_label_1: // root + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_EOF; + token.kind = 0; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + result = true; + goto end; + } + } + switch (*state.ptr){ + case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06: + case 0x07:case 0x08:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12: + case 0x13:case 0x14:case 0x15:case 0x16:case 0x17:case 0x18:case 0x19: + case 0x1a:case 0x1b:case 0x1c:case 0x1d:case 0x1e:case 0x1f:case 0x40: + case 0x60:case 0x7f: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x09:case 0x0b:case 0x0c:case 0x0d:case 0x20: + { + if ((HasFlag(state.flags_KF0, 0x2))){ + state.ptr += 1; + goto state_label_4; // error_body + } + state.ptr += 1; + goto state_label_3; // whitespace + }break; + case 0x0a: + { + state.ptr += 1; + state.flags_KB0 &= ~(0x1); + state.flags_KF0 &= ~(0x1); + state.flags_KF0 &= ~(0x2); + goto state_label_3; // whitespace + }break; + case 0x21: + { + state.ptr += 1; + goto state_label_60; // op stage + }break; + case 0x22: + { + if ((HasFlag(state.flags_KF0, 0x1))){ + state.ptr += 1; + goto state_label_26; // include_quotes + } + state.ptr += 1; + goto state_label_32; // string + }break; + case 0x23: + { + if ((!HasFlag(state.flags_KB0, 0x1))){ + state.ptr += 1; + goto state_label_23; // pp_directive_whitespace + } + state.ptr += 1; + goto state_label_67; // op stage + }break; + default: + { + state.ptr += 1; + goto state_label_2; // identifier + }break; + case 0x25: + { + state.ptr += 1; + goto state_label_64; // op stage + }break; + case 0x26: + { + state.ptr += 1; + goto state_label_61; // op stage + }break; + case 0x27: + { + state.ptr += 1; + state.flags_ZF0 |= 0x40; + goto state_label_32; // string + }break; + case 0x28: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_ParenOp; + token.kind = 13; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x29: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_ParenCl; + token.kind = 14; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x2a: + { + state.ptr += 1; + goto state_label_63; // op stage + }break; + case 0x2b: + { + state.ptr += 1; + goto state_label_53; // op stage + }break; + case 0x2c: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Comma; + token.kind = 15; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x2d: + { + state.ptr += 1; + goto state_label_54; // op stage + }break; + case 0x2e: + { + state.ptr += 1; + goto state_label_6; // operator_or_fnumber_dot + }break; + case 0x2f: + { + state.ptr += 1; + goto state_label_7; // operator_or_comment_slash + }break; + case 0x30: + { + state.ptr += 1; + goto state_label_9; // znumber + }break; + case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36:case 0x37: + case 0x38:case 0x39: + { + state.ptr += 1; + goto state_label_8; // number + }break; + case 0x3a: + { + state.ptr += 1; + goto state_label_52; // op stage + }break; + case 0x3b: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Semicolon; + token.kind = 15; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3c: + { + if ((!HasFlag(state.flags_KF0, 0x1))){ + state.ptr += 1; + goto state_label_56; // op stage + } + state.ptr += 1; + goto state_label_25; // include_pointy + }break; + case 0x3d: + { + state.ptr += 1; + goto state_label_59; // op stage + }break; + case 0x3e: + { + state.ptr += 1; + goto state_label_57; // op stage + }break; + case 0x3f: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Ternary; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x4c: + { + state.ptr += 1; + state.flags_ZF0 |= 0x4; + goto state_label_27; // pre_L + }break; + case 0x52: + { + state.ptr += 1; + goto state_label_31; // pre_R + }break; + case 0x55: + { + state.ptr += 1; + state.flags_ZF0 |= 0x20; + goto state_label_29; // pre_U + }break; + case 0x5b: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_BrackOp; + token.kind = 13; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x5c: + { + state.ptr += 1; + goto state_label_5; // backslash + }break; + case 0x5d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_BrackCl; + token.kind = 14; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x5e: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Xor; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x75: + { + state.ptr += 1; + state.flags_ZF0 |= 0x10; + goto state_label_28; // pre_u + }break; + case 0x7b: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_BraceOp; + token.kind = 11; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x7c: + { + state.ptr += 1; + goto state_label_62; // op stage + }break; + case 0x7d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_BraceCl; + token.kind = 12; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x7e: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Tilde; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_2: // identifier + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_KB0, 0x1)){ + Lexeme_Table_Lookup lookup = lexeme_table_lookup(pp_keys_hash_array, pp_keys_key_array, pp_keys_value_array, pp_keys_slot_count, pp_keys_seed, state.emit_ptr, token.size); + if (lookup.found_match){ + token.kind = lookup.base_kind; + token.sub_kind = lookup.sub_kind; + break; + } + } + Lexeme_Table_Lookup lookup = lexeme_table_lookup(main_keys_hash_array, main_keys_key_array, main_keys_value_array, main_keys_slot_count, main_keys_seed, state.emit_ptr, token.size); + if (lookup.found_match){ + token.kind = lookup.base_kind; + token.sub_kind = lookup.sub_kind; + break; + } + token.sub_kind = TokenCppKind_Identifier; + token.kind = 6; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06: + case 0x07:case 0x08:case 0x09:case 0x0a:case 0x0b:case 0x0c:case 0x0d: + case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14: + case 0x15:case 0x16:case 0x17:case 0x18:case 0x19:case 0x1a:case 0x1b: + case 0x1c:case 0x1d:case 0x1e:case 0x1f:case 0x20:case 0x21:case 0x22: + case 0x23:case 0x25:case 0x26:case 0x27:case 0x28:case 0x29:case 0x2a: + case 0x2b:case 0x2c:case 0x2d:case 0x2e:case 0x2f:case 0x3a:case 0x3b: + case 0x3c:case 0x3d:case 0x3e:case 0x3f:case 0x40:case 0x5b:case 0x5c: + case 0x5d:case 0x5e:case 0x60:case 0x7b:case 0x7c:case 0x7d:case 0x7e: + case 0x7f: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_KB0, 0x1)){ + Lexeme_Table_Lookup lookup = lexeme_table_lookup(pp_keys_hash_array, pp_keys_key_array, pp_keys_value_array, pp_keys_slot_count, pp_keys_seed, state.emit_ptr, token.size); + if (lookup.found_match){ + token.kind = lookup.base_kind; + token.sub_kind = lookup.sub_kind; + break; + } + } + Lexeme_Table_Lookup lookup = lexeme_table_lookup(main_keys_hash_array, main_keys_key_array, main_keys_value_array, main_keys_slot_count, main_keys_seed, state.emit_ptr, token.size); + if (lookup.found_match){ + token.kind = lookup.base_kind; + token.sub_kind = lookup.sub_kind; + break; + } + token.sub_kind = TokenCppKind_Identifier; + token.kind = 6; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + default: + { + state.ptr += 1; + goto state_label_2; // identifier + }break; + } + } + { + state_label_3: // whitespace + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Whitespace; + token.kind = 1; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Whitespace; + token.kind = 1; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x09:case 0x0b:case 0x0c:case 0x0d:case 0x20: + { + state.ptr += 1; + goto state_label_3; // whitespace + }break; + case 0x0a: + { + state.ptr += 1; + state.flags_KB0 &= ~(0x1); + state.flags_KF0 &= ~(0x1); + state.flags_KF0 &= ~(0x2); + goto state_label_3; // whitespace + }break; + } + } + { + state_label_4: // error_body + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_PPErrorMessage; + token.kind = 10; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + state.ptr += 1; + goto state_label_4; // error_body + }break; + case 0x0a: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_PPErrorMessage; + token.kind = 10; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_5: // backslash + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Backslash; + token.kind = 1; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Backslash; + token.kind = 1; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x0a: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Backslash; + token.kind = 1; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_6: // operator_or_fnumber_dot + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Dot; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Dot; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x2a: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_DotStar; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x2e: + { + state.ptr += 1; + goto state_label_68; // op stage + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39: + { + state.ptr += 1; + goto state_label_10; // fnumber_decimal + }break; + } + } + { + state_label_7: // operator_or_comment_slash + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Div; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Div; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x2a: + { + state.ptr += 1; + goto state_label_49; // comment_block + }break; + case 0x2f: + { + state.ptr += 1; + goto state_label_51; // comment_line + }break; + case 0x3d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_DivEq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_8: // number + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralInteger; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralInteger; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x2e: + { + state.ptr += 1; + goto state_label_10; // fnumber_decimal + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39: + { + state.ptr += 1; + goto state_label_8; // number + }break; + case 0x45:case 0x65: + { + state.ptr += 1; + goto state_label_11; // fnumber_exponent + }break; + case 0x4c: + { + state.ptr += 1; + goto state_label_18; // L_number + }break; + case 0x55:case 0x75: + { + state.ptr += 1; + goto state_label_17; // U_number + }break; + case 0x6c: + { + state.ptr += 1; + goto state_label_20; // l_number + }break; + } + } + { + state_label_9: // znumber + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralInteger; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralInteger; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x2e: + { + state.ptr += 1; + goto state_label_10; // fnumber_decimal + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37: + { + state.ptr += 1; + state.flags_ZF0 |= 0x2; + goto state_label_16; // number_oct + }break; + case 0x45:case 0x65: + { + state.ptr += 1; + goto state_label_11; // fnumber_exponent + }break; + case 0x4c: + { + state.ptr += 1; + goto state_label_18; // L_number + }break; + case 0x55:case 0x75: + { + state.ptr += 1; + goto state_label_17; // U_number + }break; + case 0x58:case 0x78: + { + state.ptr += 1; + state.flags_ZF0 |= 0x1; + goto state_label_14; // number_hex_first + }break; + case 0x6c: + { + state.ptr += 1; + goto state_label_20; // l_number + }break; + } + } + { + state_label_10: // fnumber_decimal + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat64; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat64; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39: + { + state.ptr += 1; + goto state_label_10; // fnumber_decimal + }break; + case 0x45:case 0x65: + { + state.ptr += 1; + goto state_label_11; // fnumber_exponent + }break; + case 0x46:case 0x66: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat32; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x4c:case 0x6c: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat64; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_11: // fnumber_exponent + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat64; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat64; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x2b:case 0x2d: + { + state.ptr += 1; + goto state_label_12; // fnumber_exponent_sign + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39: + { + state.ptr += 1; + goto state_label_13; // fnumber_exponent_digits + }break; + case 0x46:case 0x66: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat32; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x4c:case 0x6c: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat64; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_12: // fnumber_exponent_sign + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat64; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat64; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39: + { + state.ptr += 1; + goto state_label_13; // fnumber_exponent_digits + }break; + case 0x46:case 0x66: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat32; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x4c:case 0x6c: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat64; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_13: // fnumber_exponent_digits + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat64; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat64; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39: + { + state.ptr += 1; + goto state_label_13; // fnumber_exponent_digits + }break; + case 0x46:case 0x66: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat32; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x4c:case 0x6c: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralFloat64; + token.kind = 9; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_14: // number_hex_first + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66: + { + state.ptr += 1; + goto state_label_15; // number_hex + }break; + } + } + { + state_label_15: // number_hex + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralIntegerHex; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralIntegerHex; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66: + { + state.ptr += 1; + goto state_label_15; // number_hex + }break; + case 0x4c: + { + state.ptr += 1; + goto state_label_18; // L_number + }break; + case 0x55:case 0x75: + { + state.ptr += 1; + goto state_label_17; // U_number + }break; + case 0x6c: + { + state.ptr += 1; + goto state_label_20; // l_number + }break; + } + } + { + state_label_16: // number_oct + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralIntegerOct; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LiteralIntegerOct; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37: + { + state.ptr += 1; + state.flags_ZF0 |= 0x2; + goto state_label_16; // number_oct + }break; + case 0x4c: + { + state.ptr += 1; + goto state_label_18; // L_number + }break; + case 0x55:case 0x75: + { + state.ptr += 1; + goto state_label_17; // U_number + }break; + case 0x6c: + { + state.ptr += 1; + goto state_label_20; // l_number + }break; + } + } + { + state_label_17: // U_number + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexU; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctU; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerU; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexU; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctU; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerU; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x4c: + { + state.ptr += 1; + goto state_label_19; // UL_number + }break; + case 0x6c: + { + state.ptr += 1; + goto state_label_21; // Ul_number + }break; + } + } + { + state_label_18: // L_number + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x4c: + { + state.ptr += 1; + goto state_label_22; // LL_number + }break; + case 0x55:case 0x75: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexUL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctUL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerUL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_19: // UL_number + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexUL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctUL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerUL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexUL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctUL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerUL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x4c: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexULL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctULL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerULL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_20: // l_number + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x55:case 0x75: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexUL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctUL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerUL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x6c: + { + state.ptr += 1; + goto state_label_22; // LL_number + }break; + } + } + { + state_label_21: // Ul_number + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexUL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctUL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerUL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexUL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctUL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerUL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x6c: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexULL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctULL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerULL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_22: // LL_number + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexLL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctLL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerLL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexLL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctLL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerLL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x55:case 0x75: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x1)){ + token.sub_kind = TokenCppKind_LiteralIntegerHexULL; + token.kind = 8; + break; + } + if (HasFlag(state.flags_ZF0, 0x2)){ + token.sub_kind = TokenCppKind_LiteralIntegerOctULL; + token.kind = 8; + break; + } + token.sub_kind = TokenCppKind_LiteralIntegerULL; + token.kind = 8; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_23: // pp_directive_whitespace + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x09:case 0x0b:case 0x0c:case 0x20: + { + state.ptr += 1; + goto state_label_23; // pp_directive_whitespace + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x47:case 0x48:case 0x49:case 0x4a:case 0x4b: + case 0x4c:case 0x4d:case 0x4e:case 0x4f:case 0x50:case 0x51:case 0x52: + case 0x53:case 0x54:case 0x55:case 0x56:case 0x57:case 0x58:case 0x59: + case 0x5a:case 0x5f:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66:case 0x67:case 0x68:case 0x69:case 0x6a:case 0x6b:case 0x6c: + case 0x6d:case 0x6e:case 0x6f:case 0x70:case 0x71:case 0x72:case 0x73: + case 0x74:case 0x75:case 0x76:case 0x77:case 0x78:case 0x79:case 0x7a: + { + state.delim_first = state.ptr; + state.flags_KB0 |= 0x1; + state.ptr += 1; + goto state_label_24; // pp_directive + }break; + } + } + { + state_label_24: // pp_directive + if (state.ptr == state.opl_ptr){ + if ((true)){ + state.delim_one_past_last = state.ptr; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + Lexeme_Table_Lookup lookup = lexeme_table_lookup(pp_directives_hash_array, pp_directives_key_array, pp_directives_value_array, pp_directives_slot_count, pp_directives_seed, state.delim_first, (state.delim_one_past_last - state.delim_first)); + if (lookup.found_match){ + token.kind = lookup.base_kind; + token.sub_kind = lookup.sub_kind; + break; + } + token.sub_kind = TokenCppKind_PPUnknown; + token.kind = 2; + }while(0); + switch (token.sub_kind){ + case TokenCppKind_PPInclude: + { + state.flags_KF0 |= 0x1; + }break; + case TokenCppKind_PPError: + { + state.flags_KF0 |= 0x2; + }break; + } + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + state.delim_one_past_last = state.ptr; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + Lexeme_Table_Lookup lookup = lexeme_table_lookup(pp_directives_hash_array, pp_directives_key_array, pp_directives_value_array, pp_directives_slot_count, pp_directives_seed, state.delim_first, (state.delim_one_past_last - state.delim_first)); + if (lookup.found_match){ + token.kind = lookup.base_kind; + token.sub_kind = lookup.sub_kind; + break; + } + token.sub_kind = TokenCppKind_PPUnknown; + token.kind = 2; + }while(0); + switch (token.sub_kind){ + case TokenCppKind_PPInclude: + { + state.flags_KF0 |= 0x1; + }break; + case TokenCppKind_PPError: + { + state.flags_KF0 |= 0x2; + }break; + } + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x47:case 0x48:case 0x49:case 0x4a:case 0x4b: + case 0x4c:case 0x4d:case 0x4e:case 0x4f:case 0x50:case 0x51:case 0x52: + case 0x53:case 0x54:case 0x55:case 0x56:case 0x57:case 0x58:case 0x59: + case 0x5a:case 0x5f:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66:case 0x67:case 0x68:case 0x69:case 0x6a:case 0x6b:case 0x6c: + case 0x6d:case 0x6e:case 0x6f:case 0x70:case 0x71:case 0x72:case 0x73: + case 0x74:case 0x75:case 0x76:case 0x77:case 0x78:case 0x79:case 0x7a: + { + state.ptr += 1; + goto state_label_24; // pp_directive + }break; + } + } + { + state_label_25: // include_pointy + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x20:case 0x2e:case 0x2f:case 0x30:case 0x31:case 0x32:case 0x33: + case 0x34:case 0x35:case 0x36:case 0x37:case 0x38:case 0x39:case 0x41: + case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:case 0x48: + case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f: + case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56: + case 0x57:case 0x58:case 0x59:case 0x5a:case 0x5c:case 0x5f:case 0x61: + case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67:case 0x68: + case 0x69:case 0x6a:case 0x6b:case 0x6c:case 0x6d:case 0x6e:case 0x6f: + case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76: + case 0x77:case 0x78:case 0x79:case 0x7a: + { + state.ptr += 1; + goto state_label_25; // include_pointy + }break; + case 0x3e: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_PPIncludeFile; + token.kind = 10; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_26: // include_quotes + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x20:case 0x2e:case 0x2f:case 0x30:case 0x31:case 0x32:case 0x33: + case 0x34:case 0x35:case 0x36:case 0x37:case 0x38:case 0x39:case 0x41: + case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:case 0x48: + case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f: + case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56: + case 0x57:case 0x58:case 0x59:case 0x5a:case 0x5c:case 0x5f:case 0x61: + case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67:case 0x68: + case 0x69:case 0x6a:case 0x6b:case 0x6c:case 0x6d:case 0x6e:case 0x6f: + case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76: + case 0x77:case 0x78:case 0x79:case 0x7a: + { + state.ptr += 1; + goto state_label_26; // include_quotes + }break; + case 0x22: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_PPIncludeFile; + token.kind = 10; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_27: // pre_L + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_2; // identifier + } + } + switch (*state.ptr){ + default: + { + goto state_label_2; // identifier + }break; + case 0x22: + { + state.ptr += 1; + goto state_label_32; // string + }break; + case 0x52: + { + state.ptr += 1; + goto state_label_31; // pre_R + }break; + } + } + { + state_label_28: // pre_u + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_2; // identifier + } + } + switch (*state.ptr){ + default: + { + goto state_label_2; // identifier + }break; + case 0x22: + { + state.ptr += 1; + goto state_label_32; // string + }break; + case 0x38: + { + state.ptr += 1; + state.flags_ZF0 |= 0x8; + goto state_label_30; // pre_u8 + }break; + case 0x52: + { + state.ptr += 1; + goto state_label_31; // pre_R + }break; + } + } + { + state_label_29: // pre_U + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_2; // identifier + } + } + switch (*state.ptr){ + default: + { + goto state_label_2; // identifier + }break; + case 0x22: + { + state.ptr += 1; + goto state_label_32; // string + }break; + case 0x52: + { + state.ptr += 1; + goto state_label_31; // pre_R + }break; + } + } + { + state_label_30: // pre_u8 + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_2; // identifier + } + } + switch (*state.ptr){ + default: + { + goto state_label_2; // identifier + }break; + case 0x22: + { + state.ptr += 1; + goto state_label_32; // string + }break; + case 0x52: + { + state.ptr += 1; + goto state_label_31; // pre_R + }break; + } + } + { + state_label_31: // pre_R + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_2; // identifier + } + } + switch (*state.ptr){ + default: + { + goto state_label_2; // identifier + }break; + case 0x22: + { + state.ptr += 1; + state.delim_first = state.ptr; + goto state_label_45; // raw_string_get_delim + }break; + } + } + { + state_label_32: // string + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + state.ptr += 1; + goto state_label_32; // string + }break; + case 0x0a: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x22: + { + if ((!HasFlag(state.flags_ZF0, 0x40))){ + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x4)){ + token.sub_kind = TokenCppKind_LiteralStringWide; + token.kind = 10; + break; + } + if (HasFlag(state.flags_ZF0, 0x8)){ + token.sub_kind = TokenCppKind_LiteralStringUTF8; + token.kind = 10; + break; + } + if (HasFlag(state.flags_ZF0, 0x10)){ + token.sub_kind = TokenCppKind_LiteralStringUTF16; + token.kind = 10; + break; + } + if (HasFlag(state.flags_ZF0, 0x20)){ + token.sub_kind = TokenCppKind_LiteralStringUTF32; + token.kind = 10; + break; + } + token.sub_kind = TokenCppKind_LiteralString; + token.kind = 10; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + state.ptr += 1; + goto state_label_32; // string + }break; + case 0x27: + { + if ((HasFlag(state.flags_ZF0, 0x40))){ + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x4)){ + token.sub_kind = TokenCppKind_LiteralCharacterWide; + token.kind = 10; + break; + } + if (HasFlag(state.flags_ZF0, 0x8)){ + token.sub_kind = TokenCppKind_LiteralCharacterUTF8; + token.kind = 10; + break; + } + if (HasFlag(state.flags_ZF0, 0x10)){ + token.sub_kind = TokenCppKind_LiteralCharacterUTF16; + token.kind = 10; + break; + } + if (HasFlag(state.flags_ZF0, 0x20)){ + token.sub_kind = TokenCppKind_LiteralCharacterUTF32; + token.kind = 10; + break; + } + token.sub_kind = TokenCppKind_LiteralCharacter; + token.kind = 10; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + state.ptr += 1; + goto state_label_32; // string + }break; + case 0x5c: + { + state.ptr += 1; + goto state_label_33; // string_esc + }break; + } + } + { + state_label_33: // string_esc + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_EOF; + token.kind = 0; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + result = true; + goto end; + } + } + switch (*state.ptr){ + default: + { + state.ptr += 1; + goto state_label_32; // string + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37: + { + state.ptr += 1; + goto state_label_34; // string_esc_oct2 + }break; + case 0x55: + { + state.ptr += 1; + goto state_label_37; // string_esc_universal_8 + }break; + case 0x75: + { + state.ptr += 1; + goto state_label_41; // string_esc_universal_4 + }break; + case 0x78: + { + state.ptr += 1; + goto state_label_36; // string_esc_hex + }break; + } + } + { + state_label_34: // string_esc_oct2 + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_32; // string + } + } + switch (*state.ptr){ + default: + { + goto state_label_32; // string + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37: + { + state.ptr += 1; + goto state_label_35; // string_esc_oct1 + }break; + } + } + { + state_label_35: // string_esc_oct1 + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_32; // string + } + } + switch (*state.ptr){ + default: + { + goto state_label_32; // string + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37: + { + state.ptr += 1; + goto state_label_32; // string + }break; + } + } + { + state_label_36: // string_esc_hex + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_32; // string + } + } + switch (*state.ptr){ + default: + { + goto state_label_32; // string + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66: + { + state.ptr += 1; + goto state_label_36; // string_esc_hex + }break; + } + } + { + state_label_37: // string_esc_universal_8 + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_32; // string + } + } + switch (*state.ptr){ + default: + { + goto state_label_32; // string + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66: + { + state.ptr += 1; + goto state_label_38; // string_esc_universal_7 + }break; + } + } + { + state_label_38: // string_esc_universal_7 + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_32; // string + } + } + switch (*state.ptr){ + default: + { + goto state_label_32; // string + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66: + { + state.ptr += 1; + goto state_label_39; // string_esc_universal_6 + }break; + } + } + { + state_label_39: // string_esc_universal_6 + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_32; // string + } + } + switch (*state.ptr){ + default: + { + goto state_label_32; // string + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66: + { + state.ptr += 1; + goto state_label_40; // string_esc_universal_5 + }break; + } + } + { + state_label_40: // string_esc_universal_5 + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_32; // string + } + } + switch (*state.ptr){ + default: + { + goto state_label_32; // string + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66: + { + state.ptr += 1; + goto state_label_41; // string_esc_universal_4 + }break; + } + } + { + state_label_41: // string_esc_universal_4 + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_32; // string + } + } + switch (*state.ptr){ + default: + { + goto state_label_32; // string + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66: + { + state.ptr += 1; + goto state_label_42; // string_esc_universal_3 + }break; + } + } + { + state_label_42: // string_esc_universal_3 + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_32; // string + } + } + switch (*state.ptr){ + default: + { + goto state_label_32; // string + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66: + { + state.ptr += 1; + goto state_label_43; // string_esc_universal_2 + }break; + } + } + { + state_label_43: // string_esc_universal_2 + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_32; // string + } + } + switch (*state.ptr){ + default: + { + goto state_label_32; // string + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66: + { + state.ptr += 1; + goto state_label_44; // string_esc_universal_1 + }break; + } + } + { + state_label_44: // string_esc_universal_1 + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_32; // string + } + } + switch (*state.ptr){ + default: + { + goto state_label_32; // string + }break; + case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: + case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: + case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: + case 0x66: + { + state.ptr += 1; + goto state_label_32; // string + }break; + } + } + { + state_label_45: // raw_string_get_delim + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_EOF; + token.kind = 0; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + result = true; + goto end; + } + } + switch (*state.ptr){ + default: + { + state.ptr += 1; + goto state_label_45; // raw_string_get_delim + }break; + case 0x20:case 0x29:case 0x5c: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x28: + { + state.delim_one_past_last = state.ptr; + state.ptr += 1; + goto state_label_46; // raw_string_find_close + }break; + } + } + { + state_label_46: // raw_string_find_close + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_EOF; + token.kind = 0; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + result = true; + goto end; + } + } + switch (*state.ptr){ + default: + { + state.ptr += 1; + goto state_label_46; // raw_string_find_close + }break; + case 0x29: + { + state.ptr += 1; + goto state_label_47; // raw_string_try_delim + }break; + } + } + { + state_label_47: // raw_string_try_delim + u64 delim_length = state.delim_one_past_last - state.delim_first; + u64 parse_length = 0; + for (;;){ + if (parse_length == delim_length){ + goto state_label_48; // raw_string_try_quote + } + if (state.ptr == state.opl_ptr){ + goto state_label_48; // raw_string_try_quote + } + if (*state.ptr == state.delim_first[parse_length]){ + state.ptr += 1; + parse_length += 1; + } + else{ + goto state_label_46; // raw_string_find_close + } + } + } + { + state_label_48: // raw_string_try_quote + if (state.ptr == state.opl_ptr){ + if ((true)){ + goto state_label_46; // raw_string_find_close + } + } + switch (*state.ptr){ + default: + { + goto state_label_46; // raw_string_find_close + }break; + case 0x22: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + if (HasFlag(state.flags_ZF0, 0x4)){ + token.sub_kind = TokenCppKind_LiteralStringWideRaw; + token.kind = 10; + break; + } + if (HasFlag(state.flags_ZF0, 0x8)){ + token.sub_kind = TokenCppKind_LiteralStringUTF8Raw; + token.kind = 10; + break; + } + if (HasFlag(state.flags_ZF0, 0x10)){ + token.sub_kind = TokenCppKind_LiteralStringUTF16Raw; + token.kind = 10; + break; + } + if (HasFlag(state.flags_ZF0, 0x20)){ + token.sub_kind = TokenCppKind_LiteralStringUTF32Raw; + token.kind = 10; + break; + } + token.sub_kind = TokenCppKind_LiteralStringRaw; + token.kind = 10; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_49: // comment_block + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_BlockComment; + token.kind = 3; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_EOF; + token.kind = 0; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + result = true; + goto end; + } + } + switch (*state.ptr){ + default: + { + state.ptr += 1; + goto state_label_49; // comment_block + }break; + case 0x0a: + { + state.ptr += 1; + state.flags_KB0 &= ~(0x1); + state.flags_KF0 &= ~(0x1); + goto state_label_49; // comment_block + }break; + case 0x2a: + { + state.ptr += 1; + goto state_label_50; // comment_block_try_close + }break; + } + } + { + state_label_50: // comment_block_try_close + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_BlockComment; + token.kind = 3; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_EOF; + token.kind = 0; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + result = true; + goto end; + } + } + switch (*state.ptr){ + default: + { + state.ptr += 1; + goto state_label_49; // comment_block + }break; + case 0x2a: + { + state.ptr += 1; + goto state_label_50; // comment_block_try_close + }break; + case 0x2f: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_BlockComment; + token.kind = 3; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_51: // comment_line + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LineComment; + token.kind = 3; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + state.ptr += 1; + goto state_label_51; // comment_line + }break; + case 0x0a: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LineComment; + token.kind = 3; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_52: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Colon; + token.kind = 15; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Colon; + token.kind = 15; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3a: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_ColonColon; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_53: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Plus; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Plus; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x2b: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_PlusPlus; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_PlusEq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_54: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Minus; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Minus; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x2d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_MinusMinus; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_MinusEq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3e: + { + state.ptr += 1; + goto state_label_55; // op stage + }break; + } + } + { + state_label_55: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Arrow; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Arrow; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x2a: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_ArrowStar; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_56: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Less; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Less; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3c: + { + state.ptr += 1; + goto state_label_65; // op stage + }break; + case 0x3d: + { + state.ptr += 1; + goto state_label_58; // op stage + }break; + } + } + { + state_label_57: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Grtr; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Grtr; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_GrtrEq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3e: + { + state.ptr += 1; + goto state_label_66; // op stage + }break; + } + } + { + state_label_58: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LessEq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LessEq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3e: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Compare; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_59: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Eq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Eq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_EqEq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_60: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Not; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Not; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_NotEq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_61: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_And; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_And; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x26: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_AndAnd; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_62: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Or; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Or; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x7c: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_OrOr; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_63: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Star; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Star; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_StarEq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_64: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Mod; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_Mod; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_ModEq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_65: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LeftLeft; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LeftLeft; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LeftLeftEq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_66: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_RightRight; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_RightRight; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x3d: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_RightRightEq; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_67: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_PPStringify; + token.kind = 15; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_PPStringify; + token.kind = 15; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x23: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_PPConcat; + token.kind = 15; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + { + state_label_68: // op stage + if (state.ptr == state.opl_ptr){ + if ((true)){ + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + } + } + switch (*state.ptr){ + default: + { + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_LexError; + token.kind = 2; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + case 0x2e: + { + state.ptr += 1; + { + Token token = {}; + token.pos = (i64)(state.emit_ptr - state.base); + token.size = (i64)(state.ptr - state.emit_ptr); + token.flags = state.flags_KB0; + do{ + token.sub_kind = TokenCppKind_DotDotDot; + token.kind = 7; + }while(0); + token_list_push(arena, list, &token); + emit_counter += 1; + if (emit_counter == max){ + goto end; + } + state.emit_ptr = state.ptr; + } + state.flags_ZF0 = 0; + goto state_label_1; // root + }break; + } + } + end:; + block_copy_struct(state_ptr, &state); + return(result); } internal Token_List lex_full_input_cpp(Arena *arena, String_Const_u8 input){ -Lex_State_Cpp state = {}; -lex_full_input_cpp_init(&state, input); -Token_List list = {}; -lex_full_input_cpp_breaks(arena, &list, &state, max_u64); -return(list); + Lex_State_Cpp state = {}; + lex_full_input_cpp_init(&state, input); + Token_List list = {}; + lex_full_input_cpp_breaks(arena, &list, &state, max_u64); + return(list); } diff --git a/custom/languages/4coder_cpp_lexer_gen.cpp b/custom/languages/4coder_cpp_lexer_gen.cpp index 8832d60c..84c3eb90 100644 --- a/custom/languages/4coder_cpp_lexer_gen.cpp +++ b/custom/languages/4coder_cpp_lexer_gen.cpp @@ -1130,7 +1130,6 @@ build_language_model(void){ sm_case_eof_peek(emit); } sm_fallback(comment_line); - } // BOTTOM From 8e390db03c1594dfb6d7bc991e0c6a4b930734d2 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sat, 11 Jan 2020 16:27:34 -0800 Subject: [PATCH 070/128] Optimizing auto-indent scanning logic --- custom/4coder_auto_indent.cpp | 82 ++++++++++++++++------------- custom/4coder_auto_indent.h | 8 +++ custom/generated/command_metadata.h | 8 +-- 3 files changed, 58 insertions(+), 40 deletions(-) diff --git a/custom/4coder_auto_indent.cpp b/custom/4coder_auto_indent.cpp index b672edd4..e34efdb1 100644 --- a/custom/4coder_auto_indent.cpp +++ b/custom/4coder_auto_indent.cpp @@ -147,6 +147,17 @@ indent__unfinished_statement(Token *token, Nest *current_nest){ return(result); } +function void +line_indent_cache_update(Application_Links *app, Buffer_ID buffer, i32 tab_width, Indent_Line_Cache *line_cache){ + if (line_cache->line_number_for_cached_indent != line_cache->where_token_starts){ + ProfileScope(app, "get indent info"); + line_cache->line_number_for_cached_indent = line_cache->where_token_starts; + line_cache->start_pos = get_line_start_pos(app, buffer, line_cache->where_token_starts); + Range_i64 range = Ii64(line_cache->start_pos, line_cache->one_past_last_pos); + line_cache->indent_info = get_indent_info_range(app, buffer, range, tab_width); + } +} + internal i64* get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Range_i64 lines, Indent_Flag flags, i32 tab_width, i32 indent_width){ ProfileScope(app, "get indentation array"); @@ -176,30 +187,16 @@ get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Ra i64 actual_indent = 0; b32 in_unfinished_statement = false; - i64 line_where_token_starts = 0; - i64 line_start_pos = 0; - i64 line_one_past_last_pos = 0; - Indent_Info line_indent_info = {}; + Indent_Line_Cache line_cache = {}; for (;;){ Token *token = token_it_read(&token_it); - if (line_where_token_starts == 0 || - token->pos >= line_one_past_last_pos){ - - { - line_where_token_starts = get_line_number_from_pos(app, buffer, token->pos); - } - { - line_start_pos = get_line_start_pos(app, buffer, line_where_token_starts); - } - { - line_one_past_last_pos = get_line_end_pos(app, buffer, line_where_token_starts); - } - { - Range_i64 range = Ii64(line_start_pos, line_one_past_last_pos); - line_indent_info = get_indent_info_range(app, buffer, range, tab_width); - } + if (line_cache.where_token_starts == 0 || + token->pos >= line_cache.one_past_last_pos){ + ProfileScope(app, "get line number"); + line_cache.where_token_starts = get_line_number_from_pos(app, buffer, token->pos); + line_cache.one_past_last_pos = get_line_end_pos(app, buffer, line_cache.where_token_starts); } i64 current_indent = 0; @@ -251,7 +248,8 @@ get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Ra Nest *new_nest = indent__new_nest(arena, &nest_alloc); sll_stack_push(nest, new_nest); nest->kind = TokenBaseKind_ParentheticalOpen; - nest->indent = (token->pos - line_indent_info.first_char_pos) + 1; + line_indent_cache_update(app, buffer, tab_width, &line_cache); + nest->indent = (token->pos - line_cache.indent_info.first_char_pos) + 1; following_indent = nest->indent; shift_by_actual_indent = true; }break; @@ -282,25 +280,37 @@ if (line_it == lines.end){goto finished;} \ actual_indent = N; ) i64 line_it = line_last_indented; - for (;line_it < line_where_token_starts;){ - line_it += 1; - if (line_it == line_where_token_starts){ - EMIT(this_indent); - } - else{ - EMIT(last_indent); + if (lines.first <= line_cache.where_token_starts){ + for (;line_it < line_cache.where_token_starts;){ + line_it += 1; + if (line_it == line_cache.where_token_starts){ + EMIT(this_indent); + } + else{ + EMIT(last_indent); + } } } + else{ + actual_indent = this_indent; + line_it = line_cache.where_token_starts; + } - i64 line_where_token_starts_shift = this_indent - line_indent_info.indent_pos; i64 line_where_token_ends = get_line_number_from_pos(app, buffer, token->pos + token->size); - for (;line_it < line_where_token_ends;){ - line_it += 1; - i64 line_it_start_pos = get_line_start_pos(app, buffer, line_it); - Indent_Info line_it_indent_info = get_indent_info_line_number_and_start(app, buffer, line_it, line_it_start_pos, tab_width); - i64 new_indent = line_it_indent_info.indent_pos + line_where_token_starts_shift; - new_indent = clamp_bot(0, new_indent); - EMIT(new_indent); + if (lines.first <= line_where_token_ends){ + line_indent_cache_update(app, buffer, tab_width, &line_cache); + i64 line_where_token_starts_shift = this_indent - line_cache.indent_info.indent_pos; + for (;line_it < line_where_token_ends;){ + line_it += 1; + i64 line_it_start_pos = get_line_start_pos(app, buffer, line_it); + Indent_Info line_it_indent_info = get_indent_info_line_number_and_start(app, buffer, line_it, line_it_start_pos, tab_width); + i64 new_indent = line_it_indent_info.indent_pos + line_where_token_starts_shift; + new_indent = clamp_bot(0, new_indent); + EMIT(new_indent); + } + } + else{ + line_it = line_where_token_ends; } #undef EMIT diff --git a/custom/4coder_auto_indent.h b/custom/4coder_auto_indent.h index 214cc8b8..79e2fa05 100644 --- a/custom/4coder_auto_indent.h +++ b/custom/4coder_auto_indent.h @@ -24,6 +24,14 @@ struct Nest_Alloc{ Nest *free_nest; }; +struct Indent_Line_Cache{ + i64 where_token_starts; + i64 line_number_for_cached_indent; + i64 start_pos; + i64 one_past_last_pos; + Indent_Info indent_info; +}; + #endif // BOTTOM diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 7064e503..cc473ae3 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -252,9 +252,9 @@ 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, 397 }, -{ 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, 407 }, -{ 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, 388 }, +{ 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, 407 }, +{ 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, 417 }, +{ 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, 398 }, { 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, 611 }, @@ -475,7 +475,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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 a space.", 16, "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, 417 }, +{ 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, 427 }, { 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 }, From 020e2789d7e5f59e01862a9e9f636013148f29f7 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 12 Jan 2020 03:08:07 +0200 Subject: [PATCH 071/128] Fixed input bug where the input was not zeroed at the end of each frame. --- platform_mac/mac_4ed.mm | 170 +++++++++++++++++------------- platform_mac/mac_4ed_functions.mm | 18 ++-- 2 files changed, 106 insertions(+), 82 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index ec191dab..470c7365 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -129,6 +129,7 @@ struct Mac_Input_Chunk{ @end @interface FCoder_Window_Delegate : NSObject +- (void)process_focus_event; @end @interface FCoder_View : NSView @@ -458,6 +459,15 @@ mac_resize(NSWindow *window){ mac_resize(bounds.size.width, bounds.size.height); } +function inline void +mac_profile(char *name, u64 begin, u64 end){ + printf("%s Time: %fs\n", name, ((end - begin) / 1000000.0f)); +} + +#define MacProfileScope(name) for (u64 i = 0, begin = system_now_time();\ +i < 1;\ +++i, mac_profile(name, begin, system_now_time())) + //////////////////////////////// @implementation FCoder_App_Delegate @@ -491,16 +501,23 @@ mac_resize(NSWindow *window){ } - (void)windowDidBecomeKey:(NSNotification *)notification{ - printf("Focus\n"); - system_signal_step(0); + // NOTE(yuval): The window is the focused window + [self process_focus_event]; } - (void)windowDidResignKey:(NSNotification *)notification{ - printf("Lost Focus\n"); - system_signal_step(0); + // NOTE(yuval): The window has lost focus + [self process_focus_event]; } -- (void)windowDidEnterFullScreen:(NSNotification *)notification{ +- (void)process_focus_event{ + mac_vars.input_chunk.pers.mouse_l = false; + mac_vars.input_chunk.pers.mouse_r = false; + block_zero_struct(&mac_vars.input_chunk.pers.controls); + block_zero_struct(&mac_vars.input_chunk.pers.modifiers); + mac_vars.active_key_stroke = 0; + mac_vars.active_text_input = 0; + system_signal_step(0); } @end @@ -522,75 +539,82 @@ mac_resize(NSWindow *window){ } - (void)drawRect:(NSRect)bounds{ - // NOTE(yuval): Read comment in win32_4ed.cpp's main loop - system_mutex_acquire(mac_vars.global_frame_mutex); - - /* NOTE(yuval): Force the graphics context to clear to black so we don't -get a flash of white until the app is ready to draw. In practice on modern macOS, -this only gets called for window creation and other extraordinary events. -(Taken From SDL) */ - [[NSColor blackColor] setFill]; - NSRectFill(bounds); - - // NOTE(yuval): Prepare the Frame Input - Mac_Input_Chunk input_chunk = mac_vars.input_chunk; - Application_Step_Input input = {}; - - input.first_step = mac_vars.first; - input.dt = frame_useconds / 1000000.0f; - input.events = input_chunk.trans.event_list; - - input.mouse.out_of_window = input_chunk.trans.out_of_window; - - input.mouse.l = input_chunk.pers.mouse_l; - input.mouse.press_l = input_chunk.trans.mouse_l_press; - input.mouse.release_l = input_chunk.trans.mouse_l_release; - - input.mouse.r = input_chunk.pers.mouse_r; - input.mouse.press_r = input_chunk.trans.mouse_r_press; - input.mouse.release_r = input_chunk.trans.mouse_r_release; - - input.mouse.wheel = input_chunk.trans.mouse_wheel; - input.mouse.p = input_chunk.pers.mouse; - - input.trying_to_kill = input_chunk.trans.trying_to_kill; - - block_zero_struct(&mac_vars.input_chunk.trans); - - // NOTE(yuval): See comment in win32_4ed.cpp's main loop - if (mac_vars.send_exit_signal){ - input.trying_to_kill = true; - mac_vars.send_exit_signal = false; + MacProfileScope("Frame"){ + MacProfileScope("Acquire System Mutex"){ + // NOTE(yuval): Read comment in win32_4ed.cpp's main loop + system_mutex_acquire(mac_vars.global_frame_mutex); + } + + Mac_Input_Chunk input_chunk = mac_vars.input_chunk; + Application_Step_Input input = {}; + + // NOTE(yuval): Prepare the Frame Input + MacProfileScope("Prepare Input"){ + input.first_step = mac_vars.first; + input.dt = frame_useconds / 1000000.0f; + input.events = input_chunk.trans.event_list; + + input.mouse.out_of_window = input_chunk.trans.out_of_window; + + input.mouse.l = input_chunk.pers.mouse_l; + input.mouse.press_l = input_chunk.trans.mouse_l_press; + input.mouse.release_l = input_chunk.trans.mouse_l_release; + + input.mouse.r = input_chunk.pers.mouse_r; + input.mouse.press_r = input_chunk.trans.mouse_r_press; + input.mouse.release_r = input_chunk.trans.mouse_r_release; + + input.mouse.wheel = input_chunk.trans.mouse_wheel; + input.mouse.p = input_chunk.pers.mouse; + + input.trying_to_kill = input_chunk.trans.trying_to_kill; + + block_zero_struct(&mac_vars.input_chunk.trans); + mac_vars.active_key_stroke = 0; + mac_vars.active_text_input = 0; + + // NOTE(yuval): See comment in win32_4ed.cpp's main loop + if (mac_vars.send_exit_signal){ + input.trying_to_kill = true; + mac_vars.send_exit_signal = false; + } + } + + Application_Step_Result result = {}; + MacProfileScope("Step"){ + // NOTE(yuval): Application Core Update + if (app.step != 0){ + result = app.step(mac_vars.tctx, &target, mac_vars.base_ptr, &input); + } + } + + MacProfileScope("Perform Kill"){ + // NOTE(yuval): Quit the app + if (result.perform_kill){ + printf("Terminating 4coder!\n"); + [NSApp terminate:nil]; + } + } + + MacProfileScope("Render"){ + // NOTE(yuval): Render + renderer->render(renderer, &target); + + // NOTE(yuval): Schedule another step if needed + if (result.animating){ + system_signal_step(0); + } + } + + MacProfileScope("Cleanup"){ + mac_vars.first = false; + + linalloc_clear(mac_vars.frame_arena); + + system_mutex_release(mac_vars.global_frame_mutex); + } } - - // NOTE(yuval): Application Core Update - Application_Step_Result result = {}; - if (app.step != 0){ - result = app.step(mac_vars.tctx, &target, mac_vars.base_ptr, &input); - } - - // NOTE(yuval): Quit the app - if (result.perform_kill){ - printf("Terminating 4coder!\n"); - [NSApp terminate:nil]; - } - - // NOTE(yuval): Render - u64 begin_render = system_now_time(); - renderer->render(renderer, &target); - u64 end_render = system_now_time(); - printf("Render Time: %fs\n\n", (end_render - begin_render) / 1000000.0f); - - // NOTE(yuval): Schedule another step if needed - if (result.animating){ - system_signal_step(0); - } - - mac_vars.first = false; - - linalloc_clear(mac_vars.frame_arena); - - system_mutex_release(mac_vars.global_frame_mutex); + printf("\n"); } - (BOOL)acceptsFirstResponder{ diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index b62b4bb3..a39faae5 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -1,8 +1,8 @@ /* macOS System/Graphics/Font API Implementations */ -////////////////////// -// System API // -////////////////////// +/********************/ +/* System API */ +/********************/ //////////////////////////////// @@ -796,9 +796,9 @@ system_get_keyboard_modifiers_sig(){ //////////////////////////////// -//////////////////////// -// Graphics API // -//////////////////////// +/**********************/ +/* Graphics API */ +/**********************/ //////////////////////////////// @@ -816,9 +816,9 @@ graphics_fill_texture_sig(){ //////////////////////////////// -//////////////////// -// Font API // -//////////////////// +/******************/ +/* Font API */ +/******************/ //////////////////////////////// From f8297dc036e7aec99751ba71db9708a097e1c957 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sat, 11 Jan 2020 17:20:40 -0800 Subject: [PATCH 072/128] Fixed paren-statement interaction in indentation logic --- custom/4coder_auto_indent.cpp | 2 +- custom/4coder_code_index.cpp | 40 ++++++++++++++++++----------- custom/generated/command_metadata.h | 2 +- 3 files changed, 27 insertions(+), 17 deletions(-) diff --git a/custom/4coder_auto_indent.cpp b/custom/4coder_auto_indent.cpp index e34efdb1..f6460cd0 100644 --- a/custom/4coder_auto_indent.cpp +++ b/custom/4coder_auto_indent.cpp @@ -265,7 +265,7 @@ get_indentation_array(Application_Links *app, Arena *arena, Buffer_ID buffer, Ra if (nest != 0){ following_indent = nest->indent; } - ignore_unfinished_statement = true; + //ignore_unfinished_statement = true; }break; } } diff --git a/custom/4coder_code_index.cpp b/custom/4coder_code_index.cpp index 2e7d0fcc..ff9c6731 100644 --- a/custom/4coder_code_index.cpp +++ b/custom/4coder_code_index.cpp @@ -266,7 +266,7 @@ struct: "struct" $(";" | "{") union: "union" $(";" | "{") enum: "enum" $(";" | "{") typedef: "typedef" [* - ( (";" | "("))] $(";" | "(") -function: >"(" [* - ("(" | ")" | "{" | "}" | ";")] ")" ("{" | ";") +function: >"(" ["(" ")" | * - ("(" | ")")] ")" ("{" | ";") #endif @@ -359,6 +359,7 @@ cpp_parse_function(Code_Index_File *index, Generic_Parse_State *state, Code_Inde Token *reset_point = peek; if (peek != 0 && peek->sub_kind == TokenCppKind_ParenOp){ b32 at_paren_close = false; + i32 paren_nest_level = 0; for (; peek != 0;){ generic_parse_inc(state); generic_parse_skip_soft_tokens(index, state); @@ -367,15 +368,17 @@ cpp_parse_function(Code_Index_File *index, Generic_Parse_State *state, Code_Inde break; } - if (peek->kind == TokenBaseKind_ParentheticalOpen || - peek->kind == TokenBaseKind_ScopeOpen || - peek->kind == TokenBaseKind_ScopeClose || - peek->kind == TokenBaseKind_StatementClose){ - break; + if (peek->kind == TokenBaseKind_ParentheticalOpen){ + paren_nest_level += 1; } - if (peek->kind == TokenBaseKind_ParentheticalClose){ - at_paren_close = true; - break; + else if (peek->kind == TokenBaseKind_ParentheticalClose){ + if (paren_nest_level > 0){ + paren_nest_level -= 1; + } + else{ + at_paren_close = true; + break; + } } } @@ -386,7 +389,7 @@ cpp_parse_function(Code_Index_File *index, Generic_Parse_State *state, Code_Inde if (peek != 0 && peek->kind == TokenBaseKind_ScopeOpen || peek->kind == TokenBaseKind_StatementClose){ - index_new_note(index, state, Ii64(token), CodeIndexNote_Function, parent); + index_new_note(index, state, Ii64(token), CodeIndexNote_Function, parent); } } } @@ -573,15 +576,22 @@ generic_parse_scope(Code_Index_File *index, Generic_Parse_State *state){ continue; } + if (token->kind == TokenBaseKind_ParentheticalClose){ + generic_parse_inc(state); + 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); + + // NOTE(allen): after a parenthetical group we consider ourselves immediately + // transitioning into a statement + nest = generic_parse_statement(index, state); + nest->parent = result; + code_index_push_nest(&result->nest_list, nest); + continue; } diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index cc473ae3..a1d0cdde 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -461,7 +461,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 710 }, -{ 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(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, 1170 }, { 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 }, From 8c6335afb4b58a26b4a57ec305296a9be7294450 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sat, 11 Jan 2020 18:00:38 -0800 Subject: [PATCH 073/128] Stabilized scrolling in side-by-side single buffer editing --- 4ed_edit.cpp | 23 +++++++++++++------ .../lexer_generator/4coder_lex_gen_main.cpp | 4 ++-- 2 files changed, 18 insertions(+), 9 deletions(-) diff --git a/4ed_edit.cpp b/4ed_edit.cpp index 73d4ca81..d05097e3 100644 --- a/4ed_edit.cpp +++ b/4ed_edit.cpp @@ -90,8 +90,7 @@ edit_fix_markers__compute_scroll_y(i32 line_height, i32 old_y_val, f32 new_y_val } function void -edit_fix_markers(Thread_Context *tctx, Models *models, Editing_File *file, - Batch_Edit *batch){ +edit_fix_markers(Thread_Context *tctx, Models *models, Editing_File *file, Batch_Edit *batch){ Layout *layout = &models->layout; Lifetime_Object *file_lifetime_object = file->lifetime_object; @@ -135,7 +134,10 @@ edit_fix_markers(Thread_Context *tctx, Models *models, Editing_File *file, File_Edit_Positions edit_pos = view_get_edit_pos(view); write_cursor_with_index(cursors, &cursor_count, (i32)edit_pos.cursor_pos); write_cursor_with_index(cursors, &cursor_count, (i32)view->mark); - // TODO(allen): write a cursor for the current scroll line + Buffer_Cursor pos_cursor = file_compute_cursor(file, seek_line_col(edit_pos.scroll.position.line_number, 1)); + Buffer_Cursor targ_cursor = file_compute_cursor(file, seek_line_col(edit_pos.scroll.target.line_number, 1)); + write_cursor_with_index(cursors, &cursor_count, pos_cursor.pos); + write_cursor_with_index(cursors, &cursor_count, targ_cursor.pos); } } @@ -156,6 +158,8 @@ edit_fix_markers(Thread_Context *tctx, Models *models, Editing_File *file, } } + buffer_remeasure_starts(tctx, &file->state.buffer, batch); + if (cursor_count > 0 || r_cursor_count > 0){ buffer_sort_cursors( cursors, cursor_count); buffer_sort_cursors(r_cursors, r_cursor_count); @@ -178,8 +182,15 @@ edit_fix_markers(Thread_Context *tctx, Models *models, Editing_File *file, i64 cursor_pos = cursors[cursor_count++].pos; view->mark = cursors[cursor_count++].pos; File_Edit_Positions edit_pos = view_get_edit_pos(view); + + i64 scroll_pos = cursors[cursor_count++].pos; + i64 scroll_targ = cursors[cursor_count++].pos; + Buffer_Cursor pos_cursor = file_compute_cursor(file, seek_pos(scroll_pos)); + Buffer_Cursor targ_cursor = file_compute_cursor(file, seek_pos(scroll_targ)); + edit_pos.scroll.position.line_number = pos_cursor.line; + edit_pos.scroll.target.line_number = targ_cursor.line; + view_set_cursor_and_scroll(tctx, models, view, cursor_pos, edit_pos.scroll); - // TODO(allen): read a cursor for the current scroll line } } @@ -254,7 +265,6 @@ edit_single(Thread_Context *tctx, Models *models, Editing_File *file, batch.edit.text = string; batch.edit.range = range; - buffer_remeasure_starts(tctx, &file->state.buffer, &batch); edit_fix_markers(tctx, models, file, &batch); post_edit_call_hook(tctx, models, file, Ii64_size(range.first, string.size), range_size(range)); @@ -489,7 +499,6 @@ edit_batch(Thread_Context *tctx, Models *models, Editing_File *file, file_clear_layout_cache(file); - buffer_remeasure_starts(tctx, buffer, batch); edit_fix_markers(tctx, models, file, batch); post_edit_call_hook(tctx, models, file, new_range, range_size(old_range)); @@ -501,7 +510,7 @@ edit_batch(Thread_Context *tctx, Models *models, Editing_File *file, //////////////////////////////// - function Editing_File* +function Editing_File* create_file(Thread_Context *tctx, Models *models, String_Const_u8 file_name, Buffer_Create_Flag flags){ Editing_File *result = 0; diff --git a/custom/lexer_generator/4coder_lex_gen_main.cpp b/custom/lexer_generator/4coder_lex_gen_main.cpp index 357c7273..0974cd26 100644 --- a/custom/lexer_generator/4coder_lex_gen_main.cpp +++ b/custom/lexer_generator/4coder_lex_gen_main.cpp @@ -2700,7 +2700,7 @@ opt_key_layout(Arena *arena, Keyword_Set keywords, i32 slot_count, u64 seed){ else{ run_length += 1; layout.error_score += run_length; - max_run_length = max(max_run_length, run_length); + max_run_length = Max(max_run_length, run_length); } } i32 total_run_length = run_length; @@ -2711,7 +2711,7 @@ opt_key_layout(Arena *arena, Keyword_Set keywords, i32 slot_count, u64 seed){ else{ layout.error_score += run_length; total_run_length += 1; - max_run_length = max(max_run_length, total_run_length); + max_run_length = Max(max_run_length, total_run_length); } } layout.max_single_error_score = max_run_length; From dbcb05d2d1eee11d53eec3fe22776dc5fe1ead87 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 12 Jan 2020 23:16:03 +0200 Subject: [PATCH 074/128] Fixed a performance issue regarding timers. Now we can start a single timer per step request. --- metal/4ed_metal_render.mm | 2 +- platform_mac/mac_4ed.mm | 58 ++++++++++++++++++++++++++----- platform_mac/mac_4ed_functions.mm | 13 ++++--- platform_mac/mac_4ed_renderer.h | 4 ++- platform_mac/mac_4ed_renderer.mm | 25 +++++-------- 5 files changed, 72 insertions(+), 30 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index 6f8b1a20..9aab846a 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -290,7 +290,7 @@ metal__make_buffer(u32 size, id device){ // NOTE(yuval): Obtain the render pass descriptor from the renderer's view MTLRenderPassDescriptor *render_pass_descriptor = view.currentRenderPassDescriptor; if (render_pass_descriptor != nil){ - render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(1.0f, 0.0f, 1.0f, 1.0f); + render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0f, 0.0f, 0.0f, 1.0f); // NOTE(yuval): Create the render command encoder id render_encoder diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 470c7365..047086de 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -195,6 +195,7 @@ struct Mac_Vars { mach_timebase_info_data_t timebase_info; b32 first; + b32 step_requested; void *base_ptr; u64 timer_start; @@ -459,15 +460,18 @@ mac_resize(NSWindow *window){ mac_resize(bounds.size.width, bounds.size.height); } +#if defined(FRED_INTERNAL) function inline void mac_profile(char *name, u64 begin, u64 end){ printf("%s Time: %fs\n", name, ((end - begin) / 1000000.0f)); } #define MacProfileScope(name) for (u64 i = 0, begin = system_now_time();\ -i < 1;\ -++i, mac_profile(name, begin, system_now_time())) - +i == 0;\ +i = 1, mac_profile(name, begin, system_now_time())) +#else +# define MacProfileScope(...) +#endif //////////////////////////////// @implementation FCoder_App_Delegate @@ -539,8 +543,10 @@ i < 1;\ } - (void)drawRect:(NSRect)bounds{ - MacProfileScope("Frame"){ - MacProfileScope("Acquire System Mutex"){ + u64 prev_timer_start; + + MacProfileScope("Draw Rect"){ + MacProfileScope("Acquire Frame Mutex"){ // NOTE(yuval): Read comment in win32_4ed.cpp's main loop system_mutex_acquire(mac_vars.global_frame_mutex); } @@ -606,14 +612,44 @@ i < 1;\ } } + // NOTE(yuval): Sleep a bit to cool off + MacProfileScope("Cool Down"){ + system_mutex_release(mac_vars.global_frame_mutex); + { + u64 timer_end = system_now_time(); + u64 end_target = (mac_vars.timer_start + frame_useconds); + + if (timer_end < end_target){ + if ((end_target - timer_end) > 1000){ + // NOTE(yuval): Sleep until the end target minus a millisecond (to allow the scheduler to wake the process in time) + system_sleep(end_target - timer_end - 1000); + } + + // NOTE(yuval): Iterate through the rest of the time that's left using a regular for loop to make sure that we hit the end target + u64 now = system_now_time(); + while (now < end_target){ + now = system_now_time(); + } + } + + prev_timer_start = mac_vars.timer_start; + mac_vars.timer_start = system_now_time(); + } + system_mutex_acquire(mac_vars.global_frame_mutex); + } + MacProfileScope("Cleanup"){ mac_vars.first = false; + mac_vars.step_requested = false; linalloc_clear(mac_vars.frame_arena); + // NOTE(yuval): Release the global frame mutex until the next drawRect call system_mutex_release(mac_vars.global_frame_mutex); } } + + mac_profile("Frame", prev_timer_start, mac_vars.timer_start); printf("\n"); } @@ -762,6 +798,7 @@ i < 1;\ } - (void)request_display{ + printf("Display Requested!\n"); CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height); NSRect rect = NSRectFromCGRect(cg_rect); [self setNeedsDisplayInRect:rect]; @@ -829,7 +866,9 @@ i < 1;\ - (void)process_mouse_move_event:(NSEvent*)event{ NSPoint location = [event locationInWindow]; - Vec2_i32 new_m = V2i32(location.x, mac_vars.height - location.y); + NSPoint backing_location = [self convertPointToBacking:location]; + + Vec2_i32 new_m = V2i32(backing_location.x, mac_vars.height - backing_location.y); if (new_m != mac_vars.input_chunk.pers.mouse){ mac_vars.input_chunk.pers.mouse = new_m; } @@ -854,7 +893,7 @@ main(int arg_count, char **args){ pthread_mutex_init(&memory_tracker_mutex, 0); - // NOTE(yuval): Context Setup + // NOTE(yuval): Context setup Thread_Context _tctx = {}; thread_ctx_init(&_tctx, ThreadKind_Main, get_base_allocator_system(), @@ -1048,9 +1087,11 @@ main(int arg_count, char **args){ mac_resize(w, h); // - // TODO(yuval): Misc System Initializations + // NOTE(yuval): Misc System Initializations // + // TODO(yuval): Initialize clipboard buffer + mac_keycode_init(); // NOTE(yuval): Get the timebase info @@ -1072,6 +1113,7 @@ main(int arg_count, char **args){ // mac_vars.first = true; + mac_vars.step_requested = false; mac_vars.global_frame_mutex = system_mutex_make(); diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index a39faae5..69275512 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -406,10 +406,15 @@ system_wake_up_timer_set_sig(){ function system_signal_step_sig(){ - [NSTimer scheduledTimerWithTimeInterval:0.0 - target:mac_vars.view - selector:@selector(request_display) - userInfo:nil repeats:NO]; + printf("Signal Step!\n"); + if (!mac_vars.step_requested){ + [NSTimer scheduledTimerWithTimeInterval:0.0 + target:mac_vars.view + selector:@selector(request_display) + userInfo:nil repeats:NO]; + + mac_vars.step_requested = true; + } } function diff --git a/platform_mac/mac_4ed_renderer.h b/platform_mac/mac_4ed_renderer.h index 0d1d4caf..ecc11ff2 100644 --- a/platform_mac/mac_4ed_renderer.h +++ b/platform_mac/mac_4ed_renderer.h @@ -21,7 +21,9 @@ typedef mac_fill_texture_sig(mac_fill_texture_type); typedef i32 Mac_Renderer_Kind; enum{ MacRenderer_OpenGL, - MacRenderer_Metal + MacRenderer_Metal, + // + MacRenderer_COUNT }; struct Mac_Renderer{ diff --git a/platform_mac/mac_4ed_renderer.mm b/platform_mac/mac_4ed_renderer.mm index 5b4e4015..7ad171b6 100644 --- a/platform_mac/mac_4ed_renderer.mm +++ b/platform_mac/mac_4ed_renderer.mm @@ -4,25 +4,18 @@ #import "mac_4ed_opengl.mm" #import "mac_4ed_metal.mm" +// TODO(yuval): Replace this array with an array of the paths to the renderer dlls +global mac_load_renderer_type *mac_renderer_load_functions[MacRenderer_COUNT] = { + mac_load_opengl_renderer, + mac_load_metal_renderer +}; + function Mac_Renderer* mac_init_renderer(Mac_Renderer_Kind kind, NSWindow *window, Render_Target *target){ - // TODO(yuval): Import renderer load function from a DLL instead of using a switch statement and a renderer kind. This would allow us to switch the renderer backend and implemented new backends with ease. + // TODO(yuval): Import renderer load function from a DLL instead of using an array of the load functions. This would allow us to switch the renderer backend and implemented new backends with ease. - Mac_Renderer *result = 0; - - switch (kind){ - case MacRenderer_OpenGL: - { - result = mac_load_opengl_renderer(window, target); - } break; - - case MacRenderer_Metal: - { - result = mac_load_metal_renderer(window, target); - } break; - - default: InvalidPath; - } + mac_load_renderer_type *load_renderer = mac_renderer_load_functions[kind]; + Mac_Renderer *result = load_renderer(window, target); if (!result){ mac_error_box("Unable to initialize the renderer!"); From 7d2a91805b7a953bef66bbbd533d339fc694cbe8 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Mon, 13 Jan 2020 03:05:44 +0200 Subject: [PATCH 075/128] The clipboard is now read is frame and on changes and sent to the core. We're using polling to get the clipboard contents on macOS using a timer because there is no way to get a clipboard change notification on macOS (sigh...) --- platform_mac/mac_4ed.mm | 103 +++++++++++++++++++++++++++++- platform_mac/mac_4ed_functions.mm | 1 - 2 files changed, 100 insertions(+), 4 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 047086de..564d3cd5 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -134,6 +134,7 @@ struct Mac_Input_Chunk{ @interface FCoder_View : NSView - (void)request_display; +- (void)check_clipboard; - (void)process_keyboard_event:(NSEvent*)event down:(b8)down; - (void)process_mouse_move_event:(NSEvent*)event; @end @@ -187,7 +188,10 @@ struct Mac_Vars { String_Const_u8 binary_path; + Arena *clipboard_arena; String_Const_u8 clipboard_contents; + u32 clipboard_change_count; + b32 next_clipboard_is_self; NSWindow *window; FCoder_View *view; @@ -460,6 +464,46 @@ mac_resize(NSWindow *window){ mac_resize(bounds.size.width, bounds.size.height); } +function u32 +mac_get_clipboard_change_count(void){ + NSPasteboard *board = [NSPasteboard generalPasteboard]; + u32 result = board.changeCount; + + return(result); +} + +function b32 +mac_read_clipboard_contents(Arena *scratch){ + b32 result = false; + + Temp_Memory temp = begin_temp(scratch); + { + NSPasteboard *board = [NSPasteboard generalPasteboard]; + NSString *utf8_type = @"public.utf8-plain-text"; + NSArray *array = [NSArray arrayWithObjects:utf8_type, nil]; + NSString *has_string = [board availableTypeFromArray:array]; + if (has_string != nil){ + NSData *data = [board dataForType:utf8_type]; + if (data != nil){ + u32 copy_length = data.length; + if (copy_length > 0){ + Arena *clip_arena = mac_vars.clipboard_arena; + linalloc_clear(clip_arena); + + mac_vars.clipboard_contents = string_const_u8_push(clip_arena, copy_length); + [data getBytes:mac_vars.clipboard_contents.str + length:mac_vars.clipboard_contents.size]; + + result = true; + } + } + } + } + end_temp(temp); + + return(result); +} + #if defined(FRED_INTERNAL) function inline void mac_profile(char *name, u64 begin, u64 end){ @@ -551,11 +595,12 @@ i = 1, mac_profile(name, begin, system_now_time())) system_mutex_acquire(mac_vars.global_frame_mutex); } - Mac_Input_Chunk input_chunk = mac_vars.input_chunk; Application_Step_Input input = {}; // NOTE(yuval): Prepare the Frame Input MacProfileScope("Prepare Input"){ + Mac_Input_Chunk input_chunk = mac_vars.input_chunk; + input.first_step = mac_vars.first; input.dt = frame_useconds / 1000000.0f; input.events = input_chunk.trans.event_list; @@ -586,6 +631,34 @@ i = 1, mac_profile(name, begin, system_now_time())) } } + // NOTE(yuval): Frame clipboard input + MacProfileScope("Frame Clipboard Input"){ + block_zero_struct(&mac_vars.clipboard_contents); + input.clipboard_changed = false; + + if (mac_vars.clipboard_change_count != 0){ + u32 change_count = mac_get_clipboard_change_count(); + if (change_count != mac_vars.clipboard_change_count){ + if (mac_vars.next_clipboard_is_self){ + mac_vars.next_clipboard_is_self = false; + } else{ + for (i32 r = 0; r < 4; ++r){ + Scratch_Block scratch(mac_vars.tctx, Scratch_Share); + + if (mac_read_clipboard_contents(scratch)){ + input.clipboard_changed = true; + break; + } + } + } + + mac_vars.clipboard_change_count = change_count; + } + } + + input.clipboard = mac_vars.clipboard_contents; + } + Application_Step_Result result = {}; MacProfileScope("Step"){ // NOTE(yuval): Application Core Update @@ -798,12 +871,18 @@ i = 1, mac_profile(name, begin, system_now_time())) } - (void)request_display{ - printf("Display Requested!\n"); CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height); NSRect rect = NSRectFromCGRect(cg_rect); [self setNeedsDisplayInRect:rect]; } +- (void)check_clipboard{ + u32 change_count = mac_get_clipboard_change_count(); + if (change_count != mac_vars.clipboard_change_count){ + system_signal_step(0); + } +} + - (void)process_keyboard_event:(NSEvent*)event down:(b8)down{ b8 release = !down; @@ -1090,8 +1169,26 @@ main(int arg_count, char **args){ // NOTE(yuval): Misc System Initializations // - // TODO(yuval): Initialize clipboard buffer + // NOTE(yuval): Initialize clipboard + { + mac_vars.clipboard_arena = reserve_arena(mac_vars.tctx); + mac_vars.clipboard_change_count = mac_get_clipboard_change_count(); + mac_vars.next_clipboard_is_self = false; + + // NOTE(yuval): Read the current clipboard + { + Scratch_Block scratch(mac_vars.tctx, Scratch_Share); + mac_read_clipboard_contents(scratch); + } + + // NOTE(yuval): Start the clipboard polling timer + [NSTimer scheduledTimerWithTimeInterval: 0.5 + target:mac_vars.view + selector:@selector(check_clipboard) + userInfo:nil repeats:YES]; + } + // NOTE(yuval): Initialize the virtul keycodes table mac_keycode_init(); // NOTE(yuval): Get the timebase info diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 69275512..aeeaab27 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -406,7 +406,6 @@ system_wake_up_timer_set_sig(){ function system_signal_step_sig(){ - printf("Signal Step!\n"); if (!mac_vars.step_requested){ [NSTimer scheduledTimerWithTimeInterval:0.0 target:mac_vars.view From f7b0b05426b539cebd041607f6ab4c72dbcd0013 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Mon, 13 Jan 2020 03:20:58 +0200 Subject: [PATCH 076/128] Posting to clipboard now works. --- platform_mac/mac_4ed.mm | 36 +++++++++++++++++++++++++++++-- platform_mac/mac_4ed_functions.mm | 16 +++++++++++++- 2 files changed, 49 insertions(+), 3 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 564d3cd5..ba62017d 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -193,6 +193,9 @@ struct Mac_Vars { u32 clipboard_change_count; b32 next_clipboard_is_self; + Arena clip_post_arena; + String_Const_u8 clip_post; + NSWindow *window; FCoder_View *view; f32 screen_scale_factor; @@ -480,8 +483,8 @@ mac_read_clipboard_contents(Arena *scratch){ { NSPasteboard *board = [NSPasteboard generalPasteboard]; NSString *utf8_type = @"public.utf8-plain-text"; - NSArray *array = [NSArray arrayWithObjects:utf8_type, nil]; - NSString *has_string = [board availableTypeFromArray:array]; + NSArray *types_array = [NSArray arrayWithObjects:utf8_type, nil]; + NSString *has_string = [board availableTypeFromArray:types_array]; if (has_string != nil){ NSData *data = [board dataForType:utf8_type]; if (data != nil){ @@ -504,6 +507,25 @@ mac_read_clipboard_contents(Arena *scratch){ return(result); } +function void +mac_post_clipboard(Arena *scratch, char *text, i32 len){ + NSPasteboard *board = [NSPasteboard generalPasteboard]; + + NSString *utf8_type = @"public.utf8-plain-text"; + NSArray *types_array = [NSArray arrayWithObjects:utf8_type, nil]; + [board declareTypes:types_array + owner:nil]; + + NSString *paste_string = [[NSString alloc] initWithBytes:text + length:len + encoding:NSUTF8StringEncoding]; + [board setString:paste_string + forType:utf8_type]; + [paste_string release]; + + mac_vars.next_clipboard_is_self = true; +} + #if defined(FRED_INTERNAL) function inline void mac_profile(char *name, u64 begin, u64 end){ @@ -659,6 +681,8 @@ i = 1, mac_profile(name, begin, system_now_time())) input.clipboard = mac_vars.clipboard_contents; } + mac_vars.clip_post.size = 0; + Application_Step_Result result = {}; MacProfileScope("Step"){ // NOTE(yuval): Application Core Update @@ -675,6 +699,14 @@ i = 1, mac_profile(name, begin, system_now_time())) } } + // NOTE(yuval): Post new clipboard content + MacProfileScope("Post Clipboard"){ + if (mac_vars.clip_post.size > 0){ + Scratch_Block scratch(mac_vars.tctx, Scratch_Share); + mac_post_clipboard(scratch, (char*)mac_vars.clip_post.str, (i32)mac_vars.clip_post.size); + } + } + MacProfileScope("Render"){ // NOTE(yuval): Render renderer->render(renderer, &target); diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index aeeaab27..9076a100 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -431,7 +431,21 @@ system_sleep_sig(){ function system_post_clipboard_sig(){ - NotImplemented; + Arena *arena = &mac_vars.clip_post_arena; + if (arena->base_allocator == 0){ + *arena = make_arena_system(); + } else{ + linalloc_clear(arena); + } + + mac_vars.clip_post.str = push_array(arena, u8, str.size + 1); + if (mac_vars.clip_post.str != 0){ + block_copy(mac_vars.clip_post.str, str.str, str.size); + mac_vars.clip_post.str[str.size] = 0; + mac_vars.clip_post.size = str.size; + } else{ + // NOTE(yuval): Failed to allocate buffer for clipboard post + } } //////////////////////////////// From fd1c41bab48483ee48c58c60796c2eeccc572c0c Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Mon, 13 Jan 2020 04:06:10 +0200 Subject: [PATCH 077/128] Finished implementing the run loop. --- platform_mac/mac_4ed.mm | 120 +++++++++++++++++++++++++++++++++++----- 1 file changed, 107 insertions(+), 13 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index ba62017d..e8b58a63 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -185,6 +185,10 @@ struct Mac_Vars { i32 cursor_show; i32 prev_cursor_show; + NSCursor *cursor_ibeam; + NSCursor *cursor_arrow; + NSCursor *cursor_leftright; + NSCursor *cursor_updown; String_Const_u8 binary_path; @@ -437,6 +441,8 @@ mac_file_can_be_made(u8* filename){ return(result); } +//////////////////////////////// + function void mac_resize(float width, float height){ if ((width > 0.0f) && (height > 0.0f)){ @@ -467,6 +473,8 @@ mac_resize(NSWindow *window){ mac_resize(bounds.size.width, bounds.size.height); } +//////////////////////////////// + function u32 mac_get_clipboard_change_count(void){ NSPasteboard *board = [NSPasteboard generalPasteboard]; @@ -526,18 +534,28 @@ mac_post_clipboard(Arena *scratch, char *text, i32 len){ mac_vars.next_clipboard_is_self = true; } +//////////////////////////////// + +function void +mac_toggle_fullscreen(void){ + [mac_vars.window toggleFullScreen:nil]; +} + +//////////////////////////////// + #if defined(FRED_INTERNAL) function inline void mac_profile(char *name, u64 begin, u64 end){ printf("%s Time: %fs\n", name, ((end - begin) / 1000000.0f)); } -#define MacProfileScope(name) for (u64 i = 0, begin = system_now_time();\ -i == 0;\ -i = 1, mac_profile(name, begin, system_now_time())) +#define MacProfileScope(name) for (u64 glue(_i_, __LINE__) = 0, glue(_begin_, __LINE__) = system_now_time();\ +glue(_i_, __LINE__) == 0;\ +glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_time())) #else # define MacProfileScope(...) #endif + //////////////////////////////// @implementation FCoder_App_Delegate @@ -683,16 +701,16 @@ i = 1, mac_profile(name, begin, system_now_time())) mac_vars.clip_post.size = 0; + // NOTE(yuval): Application Core Update Application_Step_Result result = {}; MacProfileScope("Step"){ - // NOTE(yuval): Application Core Update if (app.step != 0){ result = app.step(mac_vars.tctx, &target, mac_vars.base_ptr, &input); } } + // NOTE(yuval): Quit the app if requested by the application core MacProfileScope("Perform Kill"){ - // NOTE(yuval): Quit the app if (result.perform_kill){ printf("Terminating 4coder!\n"); [NSApp terminate:nil]; @@ -707,11 +725,75 @@ i = 1, mac_profile(name, begin, system_now_time())) } } - MacProfileScope("Render"){ - // NOTE(yuval): Render - renderer->render(renderer, &target); + // NOTE(yuval): Switch to a new title + MacProfileScope("Switch Title"){ + if (result.has_new_title){ + NSString *str = [NSString stringWithUTF8String:result.title_string]; + [mac_vars.window setTitle:str]; + } + } + + // NOTE(yuval): Switch to new cursor + MacProfileScope("Switch Cursor"){ + // NOTE(yuval): Switch cursor type + switch (result.mouse_cursor_type){ + case APP_MOUSE_CURSOR_ARROW: + { + [mac_vars.cursor_arrow set]; + } break; + + case APP_MOUSE_CURSOR_IBEAM: + { + [mac_vars.cursor_ibeam set]; + } break; + + case APP_MOUSE_CURSOR_LEFTRIGHT: + { + [mac_vars.cursor_leftright set]; + } break; + + case APP_MOUSE_CURSOR_UPDOWN: + { + [mac_vars.cursor_updown set]; + } break; + } - // NOTE(yuval): Schedule another step if needed + // NOTE(yuval): Show or hide cursor + if (mac_vars.cursor_show != mac_vars.prev_cursor_show){ + switch (mac_vars.cursor_show){ + case MouseCursorShow_Never: + { + [NSCursor hide]; + } break; + + case MouseCursorShow_Always: + { + [NSCursor unhide]; + } break; + } + + mac_vars.prev_cursor_show = mac_vars.cursor_show; + } + } + + // NOTE(yuval): Update lctrl_lalt_is_altgr status + mac_vars.lctrl_lalt_is_altgr = (b8)result.lctrl_lalt_is_altgr; + + // NOTE(yuval): Render + MacProfileScope("Render"){ + renderer->render(renderer, &target); + } + + // NOTE(yuval): Toggle full screen + MacProfileScope("Toggle Full Screen"){ + if (mac_vars.do_toggle){ + mac_toggle_fullscreen(); + mac_vars.do_toggle = false; + } + } + + // NOTE(yuval): Schedule another step if needed + MacProfileScope("Schedule Animations"){ if (result.animating){ system_signal_step(0); } @@ -1026,9 +1108,6 @@ main(int arg_count, char **args){ mac_vars.frame_arena = reserve_arena(mac_vars.tctx); target.arena = make_arena_system(KB(256)); - mac_vars.cursor_show = MouseCursorShow_Always; - mac_vars.prev_cursor_show = MouseCursorShow_Always; - dll_init_sentinel(&mac_vars.free_mac_objects); dll_init_sentinel(&mac_vars.timer_objects); @@ -1178,7 +1257,7 @@ main(int arg_count, char **args){ [mac_vars.window setMinSize:NSMakeSize(100, 100)]; [mac_vars.window setBackgroundColor:NSColor.blackColor]; - [mac_vars.window setTitle:@WINDOW_NAME]; + [mac_vars.window setTitle:@"GRAPHICS"]; [mac_vars.window setAcceptsMouseMovedEvents:YES]; NSView* content_view = [mac_vars.window contentView]; @@ -1223,6 +1302,17 @@ main(int arg_count, char **args){ // NOTE(yuval): Initialize the virtul keycodes table mac_keycode_init(); + // NOTE(yuval): Initialize cursors + { + mac_vars.cursor_show = MouseCursorShow_Always; + mac_vars.prev_cursor_show = MouseCursorShow_Always; + + mac_vars.cursor_arrow = [NSCursor arrowCursor]; + mac_vars.cursor_ibeam = [NSCursor IBeamCursor]; + mac_vars.cursor_leftright = [NSCursor resizeLeftRightCursor]; + mac_vars.cursor_updown = [NSCursor resizeUpDownCursor]; + } + // NOTE(yuval): Get the timebase info mach_timebase_info(&mac_vars.timebase_info); @@ -1244,6 +1334,10 @@ main(int arg_count, char **args){ mac_vars.first = true; mac_vars.step_requested = false; + if (plat_settings.fullscreen_window){ + mac_toggle_fullscreen(); + } + mac_vars.global_frame_mutex = system_mutex_make(); mac_vars.timer_start = system_now_time(); From 585978982e37623249e65d2334fd0715af0e8a93 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Mon, 13 Jan 2020 04:20:10 +0200 Subject: [PATCH 078/128] Updates to the step scheduling to improve animations. --- platform_mac/mac_4ed.mm | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index e8b58a63..5f444f51 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -630,6 +630,8 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t u64 prev_timer_start; MacProfileScope("Draw Rect"){ + mac_vars.step_requested = false; + MacProfileScope("Acquire Frame Mutex"){ // NOTE(yuval): Read comment in win32_4ed.cpp's main loop system_mutex_acquire(mac_vars.global_frame_mutex); @@ -827,7 +829,6 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t MacProfileScope("Cleanup"){ mac_vars.first = false; - mac_vars.step_requested = false; linalloc_clear(mac_vars.frame_arena); @@ -985,6 +986,7 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t } - (void)request_display{ + printf("Display Requested!\n"); CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height); NSRect rect = NSRectFromCGRect(cg_rect); [self setNeedsDisplayInRect:rect]; From a737a5409ac117f3df77f559aa64a6463c89731e Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Mon, 13 Jan 2020 16:15:25 +0200 Subject: [PATCH 079/128] Implemented all system cli handling functions. --- platform_mac/mac_4ed.mm | 9 ++- platform_mac/mac_4ed_functions.mm | 92 ++++++++++++++++++++++++++++--- 2 files changed, 90 insertions(+), 11 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 5f444f51..00735e43 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -206,9 +206,11 @@ struct Mac_Vars { mach_timebase_info_data_t timebase_info; b32 first; - b32 step_requested; void *base_ptr; + u64 timer_start; + b32 step_requested; + i32 running_cli; Node free_mac_objects; Node timer_objects; @@ -795,8 +797,8 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t } // NOTE(yuval): Schedule another step if needed - MacProfileScope("Schedule Animations"){ - if (result.animating){ + MacProfileScope("Schedule Step"){ + if (result.animating || (mac_vars.running_cli > 0)){ system_signal_step(0); } } @@ -1335,6 +1337,7 @@ main(int arg_count, char **args){ mac_vars.first = true; mac_vars.step_requested = false; + mac_vars.running_cli = 0; if (plat_settings.fullscreen_window){ mac_toggle_fullscreen(); diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 9076a100..1502a441 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -454,32 +454,108 @@ function system_cli_call_sig(){ b32 result = false; - NotImplemented; + int pipe_fds[2]; + if (pipe(pipe_fds) == -1){ + perror("system_cli_call: pipe"); + return(false); + } - return(result); + pid_t child_pid = fork(); + if (child_pid == -1){ + perror("system_cli_call: fork"); + return(false); + } + + enum { PIPE_FD_READ, PIPE_FD_WRITE }; + + if (child_pid == 0){ + // NOTE(yuval): Child Process + close(pipe_fds[PIPE_FD_READ]); + dup2(pipe_fds[PIPE_FD_WRITE], STDOUT_FILENO); + dup2(pipe_fds[PIPE_FD_WRITE], STDERR_FILENO); + + if (chdir(path) == -1){ + perror("system_cli_call: chdir"); + exit(1); + } + + char* argv[] = {"sh", "-c", script, 0}; + + if (execv("/bin/sh", argv) == -1){ + perror("system_cli_call: execv"); + } + + exit(1); + } else{ + // NOTE(yuval): Parent Process + close(pipe_fds[PIPE_FD_WRITE]); + + *(pid_t*)&cli_out->proc = child_pid; + *(int*)&cli_out->out_read = pipe_fds[PIPE_FD_READ]; + *(int*)&cli_out->out_write = pipe_fds[PIPE_FD_WRITE]; + + mac_vars.running_cli += 1; + } + + return(true); } function system_cli_begin_update_sig(){ - NotImplemented; + // NOTE(yuval): Nothing to do here. } function system_cli_update_step_sig(){ - b32 result = false; + int pipe_read_fd = *(int*)&cli->out_read; - NotImplemented; + fd_set fds; + FD_ZERO(&fds); + FD_SET(pipe_read_fd, &fds); + struct timeval tv = {}; + + size_t space_left = max; + char* ptr = dest; + + while (space_left > 0 && (select(pipe_read_fd + 1, &fds, NULL, NULL, &tv) == 1)){ + ssize_t num = read(pipe_read_fd, ptr, space_left); + if (num == -1){ + perror("system_cli_update_step: read"); + } else if (num == 0){ + // NOTE(inso): EOF + break; + } else{ + ptr += num; + space_left -= num; + } + } + + *amount = (ptr - dest); + + b32 result = ((ptr - dest) > 0); return(result); } function system_cli_end_update_sig(){ - b32 result = false; + b32 close_me = false; - NotImplemented; + pid_t pid = *(pid_t*)&cli->proc; - return(result); + int status; + if (pid && (waitpid(pid, &status, WNOHANG) > 0)){ + cli->exit = WEXITSTATUS(status); + + close(*(int*)&cli->out_read); + close(*(int*)&cli->out_write); + + mac_vars.running_cli -= 1; + + close_me = true; + } + + return(close_me); } //////////////////////////////// From de9fc34c3e25f70dacb930bcfcb753390a0813ed Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 14 Jan 2020 03:22:29 +0200 Subject: [PATCH 080/128] Added a hack to fix DeadLock problem regrading the system_memory_annotation function. Also started working on fixing the performance issues that I discovered in the graphics renderer on retina displays (for now I changed to FCoder_View to be layer backed which is faster for rendering animations, this seems to improve performance by a little margin but rendering on high dpi displays is not closed to being smooth yet...). --- 4ed.cpp | 1684 ++++++++++++++--------------- custom/4coder_fancy.cpp | 48 +- metal/4ed_metal_render.mm | 23 +- platform_mac/mac_4ed.mm | 50 +- platform_mac/mac_4ed_functions.mm | 4 +- platform_mac/mac_4ed_metal.mm | 4 - 6 files changed, 916 insertions(+), 897 deletions(-) diff --git a/4ed.cpp b/4ed.cpp index 8059d581..60b9f849 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -1,842 +1,842 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * 12.12.2014 - * - * Application layer for project codename "4ed" - * - */ - -// TOP - -internal void -init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, i32 argc, char **argv){ - char *arg = 0; - Command_Line_Mode mode = CLMode_App; - Command_Line_Action action = CLAct_Nothing; - b32 strict = false; - - settings->init_files_max = ArrayCount(settings->init_files); - for (i32 i = 1; i <= argc; ++i){ - if (i == argc){ - arg = ""; - } - else{ - arg = argv[i]; - } - - if (arg[0] == '-' && arg[1] == '-'){ - char *long_arg_name = arg+2; - if (string_match(SCu8(long_arg_name), string_u8_litexpr("custom"))){ - mode = CLMode_Custom; - continue; - } - } - - switch (mode){ - case CLMode_App: - { - switch (action){ - case CLAct_Nothing: - { - if (arg[0] == '-'){ - action = CLAct_Ignore; - switch (arg[1]){ - case 'd': action = CLAct_CustomDLL; strict = false; break; - case 'D': action = CLAct_CustomDLL; strict = true; break; - - case 'i': action = CLAct_InitialFilePosition; break; - - case 'w': action = CLAct_WindowSize; break; - case 'W': action = CLAct_WindowMaximize; break; - case 'p': action = CLAct_WindowPosition; break; - case 'F': action = CLAct_WindowFullscreen; break; - - case 'f': action = CLAct_FontSize; break; - case 'h': action = CLAct_FontUseHinting; --i; break; - } - } - else if (arg[0] != 0){ - if (settings->init_files_count < settings->init_files_max){ - i32 index = settings->init_files_count++; - settings->init_files[index] = arg; - } - } - }break; - - case CLAct_CustomDLL: - { - plat_settings->custom_dll_is_strict = (b8)strict; - if (i < argc){ - plat_settings->custom_dll = argv[i]; - } - action = CLAct_Nothing; - }break; - - case CLAct_InitialFilePosition: - { - if (i < argc){ - settings->initial_line = (i32)string_to_integer(SCu8(argv[i]), 10); - } - action = CLAct_Nothing; - }break; - - case CLAct_WindowSize: - { - if (i + 1 < argc){ - plat_settings->set_window_size = true; - - i32 w = (i32)string_to_integer(SCu8(argv[i]), 10); - i32 h = (i32)string_to_integer(SCu8(argv[i + 1]), 10); - if (w > 0){ - plat_settings->window_w = w; - } - if (h > 0){ - plat_settings->window_h = h; - } - - ++i; - } - action = CLAct_Nothing; - }break; - - case CLAct_WindowMaximize: - { - --i; - plat_settings->maximize_window = true; - action = CLAct_Nothing; - }break; - - case CLAct_WindowPosition: - { - if (i + 1 < argc){ - plat_settings->set_window_pos = true; - - i32 x = (i32)string_to_integer(SCu8(argv[i]), 10); - i32 y = (i32)string_to_integer(SCu8(argv[i + 1]), 10); - if (x > 0){ - plat_settings->window_x = x; - } - if (y > 0){ - plat_settings->window_y = y; - } - - ++i; - } - action = CLAct_Nothing; - }break; - - case CLAct_WindowFullscreen: - { - --i; - plat_settings->fullscreen_window = true; - action = CLAct_Nothing; - }break; - - case CLAct_FontSize: - { - if (i < argc){ - settings->font_size = (i32)string_to_integer(SCu8(argv[i]), 10); - } - action = CLAct_Nothing; - }break; - - case CLAct_FontUseHinting: - { - plat_settings->use_hinting = true; - settings->use_hinting = plat_settings->use_hinting; - action = CLAct_Nothing; - }break; - } - }break; - - case CLMode_Custom: - { - settings->custom_flags = argv + i; - settings->custom_flags_count = argc - i; - i = argc; - mode = CLMode_App; - }break; - } - } -} - -//////////////////////////////// - -internal Models* -models_init(void){ - Arena arena = make_arena_system(); - Models *models = push_array_zero(&arena, Models, 1); - models->arena_ = arena; - models->arena = &models->arena_; - heap_init(&models->heap, get_base_allocator_system()); - return(models); -} - -internal void -app_load_vtables(API_VTable_system *vtable_system, API_VTable_font *vtable_font, API_VTable_graphics *vtable_graphics){ - system_api_read_vtable(vtable_system); - font_api_read_vtable(vtable_font); - graphics_api_read_vtable(vtable_graphics); -} - -internal Log_Function* -app_get_logger(void){ - log_init(); - return(log_string); -} - -App_Read_Command_Line_Sig(app_read_command_line){ - Models *models = models_init(); - App_Settings *settings = &models->settings; - block_zero_struct(settings); - if (argc > 1){ - init_command_line_settings(&models->settings, plat_settings, argc, argv); - } - *files = models->settings.init_files; - *file_count = &models->settings.init_files_count; - return(models); -} - -App_Init_Sig(app_init){ - Models *models = (Models*)base_ptr; - models->keep_playing = true; - - models->config_api = api; - models->virtual_event_arena = reserve_arena(tctx); - - profile_init(&models->profile_list); - - managed_ids_init(tctx->allocator, &models->managed_id_set); - - API_VTable_custom custom_vtable = {}; - custom_api_fill_vtable(&custom_vtable); - API_VTable_system system_vtable = {}; - system_api_fill_vtable(&system_vtable); - Custom_Layer_Init_Type *custom_init = api.init_apis(&custom_vtable, &system_vtable); - Assert(custom_init != 0); - - // NOTE(allen): coroutines - coroutine_system_init(&models->coroutines); - - // NOTE(allen): font set - font_set_init(&models->font_set); - - // NOTE(allen): live set - Arena *arena = models->arena; - { - models->view_set.count = 0; - models->view_set.max = MAX_VIEWS; - models->view_set.views = push_array(arena, View, models->view_set.max); - - //dll_init_sentinel - models->view_set.free_sentinel.next = &models->view_set.free_sentinel; - models->view_set.free_sentinel.prev = &models->view_set.free_sentinel; - - i32 max = models->view_set.max; - View *view = models->view_set.views; - for (i32 i = 0; i < max; ++i, ++view){ - //dll_insert(&models->view_set.free_sentinel, view); - view->next = models->view_set.free_sentinel.next; - view->prev = &models->view_set.free_sentinel; - models->view_set.free_sentinel.next = view; - view->next->prev = view; - } - } - - lifetime_allocator_init(tctx->allocator, &models->lifetime_allocator); - dynamic_workspace_init(&models->lifetime_allocator, DynamicWorkspace_Global, 0, &models->dynamic_workspace); - - // NOTE(allen): file setup - working_set_init(models, &models->working_set); - Mutex_Lock file_order_lock(models->working_set.mutex); - - // NOTE(allen): - global_history_init(&models->global_history); - text_layout_init(tctx, &models->text_layouts); - - // NOTE(allen): clipboard setup - models->working_set.clipboard_max_size = ArrayCount(models->working_set.clipboards); - models->working_set.clipboard_size = 0; - models->working_set.clipboard_current = 0; - models->working_set.clipboard_rolling = 0; - - // TODO(allen): do(better clipboard allocation) - if (clipboard.str != 0){ - String_Const_u8 *dest = working_set_next_clipboard_string(&models->heap, &models->working_set, clipboard.size); - block_copy(dest->str, clipboard.str, clipboard.size); - } - - // NOTE(allen): style setup - { - Scratch_Block scratch(tctx); - Face_Description description = {}; - description.font.file_name = get_file_path_in_fonts_folder(scratch, string_u8_litexpr("liberation-mono.ttf")); - description.parameters.pt_size = 12; - Face *new_face = font_set_new_face(&models->font_set, &description); - models->global_face_id = new_face->id; - } - - // NOTE(allen): title space - models->has_new_title = true; - models->title_capacity = KB(4); - models->title_space = push_array(arena, char, models->title_capacity); - block_copy(models->title_space, WINDOW_NAME, sizeof(WINDOW_NAME)); - - // NOTE(allen): miscellaneous init - hot_directory_init(arena, &models->hot_directory, current_directory); - child_process_container_init(tctx->allocator, &models->child_processes); - models->period_wakeup_timer = system_wake_up_timer_create(); - - // NOTE(allen): custom layer init - Application_Links app = {}; - app.tctx = tctx; - app.cmd_context = models; - custom_init(&app); - - // NOTE(allen): init baked in buffers - File_Init init_files[] = { - { string_u8_litinit("*messages*"), &models->message_buffer , true , }, - { string_u8_litinit("*scratch*") , &models->scratch_buffer , false, }, - { string_u8_litinit("*log*") , &models->log_buffer , true , }, - { string_u8_litinit("*keyboard*"), &models->keyboard_buffer, true , }, - }; - - Heap *heap = &models->heap; - for (i32 i = 0; i < ArrayCount(init_files); ++i){ - Editing_File *file = working_set_allocate_file(&models->working_set, &models->lifetime_allocator); - buffer_bind_name(tctx, models, arena, &models->working_set, file, init_files[i].name); - - if (init_files[i].ptr != 0){ - *init_files[i].ptr = file; - } - - File_Attributes attributes = {}; - file_create_from_string(tctx, models, file, SCu8(), attributes); - if (init_files[i].read_only){ - file->settings.read_only = true; - history_free(tctx, &file->state.history); - } - - file->settings.never_kill = true; - file_set_unimportant(file, true); - } - - // NOTE(allen): setup first panel - { - Panel *panel = layout_initialize(arena, &models->layout); - View *new_view = live_set_alloc_view(&models->lifetime_allocator, &models->view_set, panel); - view_init(tctx, models, new_view, models->scratch_buffer, models->view_event_handler); - } -} - -App_Step_Sig(app_step){ - Models *models = (Models*)base_ptr; - - Mutex_Lock file_order_lock(models->working_set.mutex); - Scratch_Block scratch(tctx, Scratch_Share); - - models->next_animate_delay = max_u32; - models->animate_next_frame = false; - - // NOTE(allen): per-frame update of models state - begin_frame(target, &models->font_set); - models->target = target; - models->input = input; - - // NOTE(allen): OS clipboard event handling - String_Const_u8 clipboard = input->clipboard; - if (clipboard.str != 0){ - String_Const_u8 *dest = working_set_next_clipboard_string(&models->heap, &models->working_set, clipboard.size); - dest->size = eol_convert_in((char*)dest->str, (char*)clipboard.str, (i32)clipboard.size); - if (input->clipboard_changed){ - co_send_core_event(tctx, models, CoreCode_NewClipboardContents, *dest); - } - } - - // NOTE(allen): reorganizing panels on screen - Vec2_i32 prev_dim = layout_get_root_size(&models->layout); - Vec2_i32 current_dim = V2i32(target->width, target->height); - layout_set_root_size(&models->layout, current_dim); - - // NOTE(allen): update child processes - f32 dt = input->dt; - if (dt > 0){ - Temp_Memory_Block temp(scratch); - - Child_Process_Container *child_processes = &models->child_processes; - Child_Process **processes_to_free = push_array(scratch, Child_Process*, child_processes->active_child_process_count); - i32 processes_to_free_count = 0; - - u32 max = KB(128); - char *dest = push_array(scratch, char, max); - - for (Node *node = child_processes->child_process_active_list.next; - node != &child_processes->child_process_active_list; - node = node->next){ - Child_Process *child_process = CastFromMember(Child_Process, node, node); - - Editing_File *file = child_process->out_file; - CLI_Handles *cli = &child_process->cli; - - // TODO(allen): do(call a 'child process updated hook' let that hook populate the buffer if it so chooses) - - b32 edited_file = false; - u32 amount = 0; - system_cli_begin_update(cli); - if (system_cli_update_step(cli, dest, max, &amount)){ - if (file != 0 && amount > 0){ - amount = eol_in_place_convert_in(dest, amount); - output_file_append(tctx, models, file, SCu8(dest, amount)); - edited_file = true; - } - } - - if (system_cli_end_update(cli)){ - if (file != 0){ - String_Const_u8 str = push_u8_stringf(scratch, "exited with code %d", cli->exit); - output_file_append(tctx, models, file, str); - edited_file = true; - } - processes_to_free[processes_to_free_count++] = child_process; - child_process_set_return_code(models, child_processes, child_process->id, cli->exit); - } - - if (child_process->cursor_at_end && file != 0){ - file_cursor_to_end(tctx, models, file); - } - } - - for (i32 i = 0; i < processes_to_free_count; ++i){ - child_process_free(child_processes, processes_to_free[i]->id); - } - } - - // NOTE(allen): simulated events - Input_List input_list = input->events; - Input_Modifier_Set modifiers = system_get_keyboard_modifiers(scratch); - if (input->mouse.press_l){ - Input_Event event = {}; - event.kind = InputEventKind_MouseButton; - event.mouse.code = MouseCode_Left; - event.mouse.p = input->mouse.p; - event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); - push_input_event(scratch, &input_list, &event); - } - else if (input->mouse.release_l){ - Input_Event event = {}; - event.kind = InputEventKind_MouseButtonRelease; - event.mouse.code = MouseCode_Left; - event.mouse.p = input->mouse.p; - event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); - push_input_event(scratch, &input_list, &event); - } - if (input->mouse.press_r){ - Input_Event event = {}; - event.kind = InputEventKind_MouseButton; - event.mouse.code = MouseCode_Right; - event.mouse.p = input->mouse.p; - event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); - push_input_event(scratch, &input_list, &event); - } - else if (input->mouse.release_r){ - Input_Event event = {}; - event.kind = InputEventKind_MouseButtonRelease; - event.mouse.code = MouseCode_Right; - event.mouse.p = input->mouse.p; - event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); - push_input_event(scratch, &input_list, &event); - } - if (input->mouse.wheel != 0){ - Input_Event event = {}; - event.kind = InputEventKind_MouseWheel; - event.mouse_wheel.value = (f32)(input->mouse.wheel); - event.mouse_wheel.p = input->mouse.p; - event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); - push_input_event(scratch, &input_list, &event); - } - if (input->mouse.p != models->prev_p){ - b32 was_in_window = rect_contains_point(Ri32(0, 0, prev_dim.x, prev_dim.y), models->prev_p); - b32 is_in_window = rect_contains_point(Ri32(0, 0, current_dim.x, current_dim.y), input->mouse.p); - if (is_in_window || was_in_window){ - Input_Event event = {}; - event.kind = InputEventKind_MouseMove; - event.mouse_move.p = input->mouse.p; - event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); - push_input_event(scratch, &input_list, &event); - } - } - if (models->animated_last_frame){ - Input_Event event = {}; - event.kind = InputEventKind_Core; - event.core.code = CoreCode_Animate; - push_input_event(scratch, &input_list, &event); - } - - // NOTE(allen): expose layout - Layout *layout = &models->layout; - - // NOTE(allen): mouse hover status - Panel *mouse_panel = 0; - Panel *divider_panel = 0; - b32 mouse_in_margin = false; - Vec2_i32 mouse = input->mouse.p; - { - for (Panel *panel = layout_get_first_open_panel(layout); - panel != 0; - panel = layout_get_next_open_panel(layout, panel)){ - if (rect_contains_point(panel->rect_full, mouse)){ - mouse_panel = panel; - if (!rect_contains_point(panel->rect_inner, mouse)){ - mouse_in_margin = true; - for (divider_panel = mouse_panel->parent; - divider_panel != 0; - divider_panel = divider_panel->parent){ - if (rect_contains_point(divider_panel->rect_inner, mouse)){ - break; - } - } - } - } - if (mouse_panel != 0){ - break; - } - } - } - - // NOTE(allen): First frame initialization - if (input->first_step){ - Temp_Memory_Block temp(scratch); - - String_Const_u8_Array file_names = {}; - file_names.count = models->settings.init_files_count; - file_names.vals = push_array(scratch, String_Const_u8, file_names.count); - for (i32 i = 0; i < file_names.count; i += 1){ - file_names.vals[i] = SCu8(models->settings.init_files[i]); - } - - String_Const_u8_Array flags = {}; - flags.count = models->settings.custom_flags_count; - flags.vals = push_array(scratch, String_Const_u8, flags.count); - for (i32 i = 0; i < flags.count; i += 1){ - flags.vals[i] = SCu8(models->settings.custom_flags[i]); - } - - Input_Event event = {}; - event.kind = InputEventKind_Core; - event.core.code = CoreCode_Startup; - event.core.flag_strings = flags; - event.core.file_names = file_names; - co_send_event(tctx, models, &event); - } - - // NOTE(allen): consume event stream - Input_Event_Node *input_node = input_list.first; - Input_Event_Node *input_node_next = 0; - for (;; input_node = input_node_next){ - // NOTE(allen): first handle any events coming from the view command - // function queue - Model_View_Command_Function cmd_func = models_pop_view_command_function(models); - if (cmd_func.custom_func != 0){ - View *view = imp_get_view(models, cmd_func.view_id); - if (view != 0){ - input_node_next = input_node; - Input_Event cmd_func_event = {}; - cmd_func_event.kind = InputEventKind_CustomFunction; - cmd_func_event.custom_func = cmd_func.custom_func; - co_send_event(tctx, models, view, &cmd_func_event); - continue; - } - } - - Temp_Memory_Block temp(scratch); - Input_Event *simulated_input = 0; - Input_Event virtual_event = models_pop_virtual_event(scratch, models); - if (virtual_event.kind != InputEventKind_None){ - virtual_event.virtual_event = true; - simulated_input = &virtual_event; - } - else{ - if (input_node == 0){ - break; - } - input_node_next = input_node->next; - simulated_input = &input_node->event; - - if (simulated_input->kind == InputEventKind_TextInsert && simulated_input->text.blocked){ - continue; - } - - // NOTE(allen): record to keyboard history - if (simulated_input->kind == InputEventKind_KeyStroke || - simulated_input->kind == InputEventKind_KeyRelease || - simulated_input->kind == InputEventKind_TextInsert){ - Temp_Memory_Block temp_key_line(scratch); - String_Const_u8 key_line = stringize_keyboard_event(scratch, simulated_input); - output_file_append(tctx, models, models->keyboard_buffer, key_line); - } - } - - b32 event_was_handled = false; - Input_Event *event = simulated_input; - - Panel *active_panel = layout_get_active_panel(layout); - View *view = active_panel->view; - Assert(view != 0); - - switch (models->state){ - case APP_STATE_EDIT: - { - typedef i32 Event_Consume_Rule; - enum{ - EventConsume_None, - EventConsume_BeginResize, - EventConsume_ClickChangeView, - EventConsume_CustomCommand, - }; - - Event_Consume_Rule consume_rule = EventConsume_CustomCommand; - if (match_mouse_code(event, MouseCode_Left) && (divider_panel != 0)){ - consume_rule = EventConsume_BeginResize; - } - else if (match_mouse_code(event, MouseCode_Left) && - mouse_panel != 0 && mouse_panel != active_panel){ - consume_rule = EventConsume_ClickChangeView; - } - - switch (consume_rule){ - case EventConsume_BeginResize: - { - models->state = APP_STATE_RESIZING; - models->resizing_intermediate_panel = divider_panel; - event_was_handled = true; - }break; - - case EventConsume_ClickChangeView: - { - // NOTE(allen): run deactivate command - co_send_core_event(tctx, models, view, CoreCode_ClickDeactivateView); - - layout->active_panel = mouse_panel; - models->animate_next_frame = true; - active_panel = mouse_panel; - view = active_panel->view; - - // NOTE(allen): run activate command - co_send_core_event(tctx, models, view, CoreCode_ClickActivateView); - - event_was_handled = true; - }break; - - case EventConsume_CustomCommand: - { - event_was_handled = co_send_event(tctx, models, view, event); - }break; - } - }break; - - case APP_STATE_RESIZING: - { - Event_Property event_flags = get_event_properties(event); - if (HasFlag(event_flags, EventProperty_AnyKey) || - match_mouse_code_release(event, MouseCode_Left)){ - models->state = APP_STATE_EDIT; - } - else if (event->kind == InputEventKind_MouseMove){ - if (input->mouse.l){ - Panel *split = models->resizing_intermediate_panel; - Range_i32 limits = layout_get_limiting_range_on_split(layout, split); - i32 mouse_position = (split->vertical_split)?(mouse.x):(mouse.y); - mouse_position = clamp(limits.min, mouse_position, limits.max); - layout_set_split_absolute_position(layout, split, mouse_position); - } - else{ - models->state = APP_STATE_EDIT; - } - } - }break; - } - - if (event_was_handled && event->kind == InputEventKind_KeyStroke){ - for (Input_Event *dependent_text = event->key.first_dependent_text; - dependent_text != 0; - dependent_text = dependent_text->text.next_text){ - Assert(dependent_text->kind == InputEventKind_TextInsert); - dependent_text->text.blocked = true; - } - } - } - - linalloc_clear(models->virtual_event_arena); - models->free_virtual_event = 0; - models->first_virtual_event = 0; - models->last_virtual_event = 0; - - // NOTE(allen): send panel size update - if (models->layout.panel_state_dirty){ - models->layout.panel_state_dirty = false; - if (models->buffer_viewer_update != 0){ - Application_Links app = {}; - app.tctx = tctx; - app.cmd_context = models; - models->buffer_viewer_update(&app); - } - } - - // NOTE(allen): dt - f32 literal_dt = 0.f; - u64 now_usecond_stamp = system_now_time(); - if (!input->first_step){ - u64 elapsed_useconds = now_usecond_stamp - models->last_render_usecond_stamp; - literal_dt = (f32)((f64)(elapsed_useconds)/1000000.f); - } - models->last_render_usecond_stamp = now_usecond_stamp; - f32 animation_dt = 0.f; - if (models->animated_last_frame){ - animation_dt = literal_dt; - } - - // NOTE(allen): on the first frame there should be no scrolling - if (input->first_step){ - for (Panel *panel = layout_get_first_open_panel(layout); - panel != 0; - panel = layout_get_next_open_panel(layout, panel)){ - View *view = panel->view; - File_Edit_Positions edit_pos = view_get_edit_pos(view); - edit_pos.scroll.position = view_normalize_buffer_point(tctx, models, view, edit_pos.scroll.target); - block_zero_struct(&edit_pos.scroll.target); - view_set_edit_pos(view, edit_pos); - } - } - - // NOTE(allen): hook for files reloaded - { - Working_Set *working_set = &models->working_set; - Assert(working_set->has_external_mod_sentinel.next != 0); - if (working_set->has_external_mod_sentinel.next != &working_set->has_external_mod_sentinel){ - for (Node *node = working_set->has_external_mod_sentinel.next, *next = 0; - node != &working_set->has_external_mod_sentinel; - node = next){ - next = node->next; - Editing_File *file = CastFromMember(Editing_File, external_mod_node, node); - dll_remove(node); - block_zero_struct(node); - co_send_core_event(tctx, models, CoreCode_FileExternallyModified, file->id); - } - } - } - - // NOTE(allen): if the exit signal has been sent, run the exit hook. - if (input->trying_to_kill){ - models->keep_playing = false; - } - if (!models->keep_playing){ - if (co_send_core_event(tctx, models, CoreCode_TryExit)){ - models->keep_playing = true; - } - } - - // NOTE(allen): rendering - { - Frame_Info frame = {}; - frame.index = models->frame_counter; - frame.literal_dt = literal_dt; - frame.animation_dt = animation_dt; - - Application_Links app = {}; - app.tctx = tctx; - app.cmd_context = models; - - if (models->tick != 0){ - models->tick(&app, frame); - } - - begin_render_section(target, models->frame_counter, literal_dt, animation_dt); - models->in_render_mode = true; - - Live_Views *live_views = &models->view_set; - for (Node *node = layout->open_panels.next; - node != &layout->open_panels; - node = node->next){ - Panel *panel = CastFromMember(Panel, node, node); - View *view = panel->view; - View_Context_Node *ctx = view->ctx; - if (ctx != 0){ - Render_Caller_Function *render_caller = ctx->ctx.render_caller; - if (render_caller != 0){ - render_caller(&app, frame, view_get_id(live_views, view)); - } - } - } - - models->in_render_mode = false; - end_render_section(target); - } - - // NOTE(allen): flush the log - log_flush(tctx, models); - - // NOTE(allen): set the app_result - Application_Step_Result app_result = {}; - app_result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; - app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr; - - // NOTE(allen): get new window title - if (models->has_new_title){ - models->has_new_title = false; - app_result.has_new_title = true; - app_result.title_string = models->title_space; - } - - // NOTE(allen): get cursor type - if (mouse_panel != 0 && !mouse_in_margin){ - app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; - } - else if (divider_panel != 0){ - if (divider_panel->vertical_split){ - app_result.mouse_cursor_type = APP_MOUSE_CURSOR_LEFTRIGHT; - } - else{ - app_result.mouse_cursor_type = APP_MOUSE_CURSOR_UPDOWN; - } - } - else{ - app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; - } - - models->prev_mouse_panel = mouse_panel; - app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr; - app_result.perform_kill = !models->keep_playing; - app_result.animating = models->animate_next_frame; - if (models->animate_next_frame){ - // NOTE(allen): Silence the timer, because we're going to do another frame right away anyways. - system_wake_up_timer_set(models->period_wakeup_timer, max_u32); - } - else{ - // NOTE(allen): Set the timer's wakeup period, possibly to max_u32 thus effectively silencing it. - system_wake_up_timer_set(models->period_wakeup_timer, models->next_animate_delay); - } - - // NOTE(allen): Update Frame to Frame States - models->prev_p = input->mouse.p; - models->animated_last_frame = app_result.animating; - models->frame_counter += 1; - - // end-of-app_step - return(app_result); -} - -extern "C" App_Get_Functions_Sig(app_get_functions){ - App_Functions result = {}; - - result.load_vtables = app_load_vtables; - result.get_logger = app_get_logger; - result.read_command_line = app_read_command_line; - result.init = app_init; - result.step = app_step; - - return(result); -} - -// BOTTOM - +/* + * Mr. 4th Dimention - Allen Webster + * + * 12.12.2014 + * + * Application layer for project codename "4ed" + * + */ + +// TOP + +internal void +init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, i32 argc, char **argv){ + char *arg = 0; + Command_Line_Mode mode = CLMode_App; + Command_Line_Action action = CLAct_Nothing; + b32 strict = false; + + settings->init_files_max = ArrayCount(settings->init_files); + for (i32 i = 1; i <= argc; ++i){ + if (i == argc){ + arg = ""; + } + else{ + arg = argv[i]; + } + + if (arg[0] == '-' && arg[1] == '-'){ + char *long_arg_name = arg+2; + if (string_match(SCu8(long_arg_name), string_u8_litexpr("custom"))){ + mode = CLMode_Custom; + continue; + } + } + + switch (mode){ + case CLMode_App: + { + switch (action){ + case CLAct_Nothing: + { + if (arg[0] == '-'){ + action = CLAct_Ignore; + switch (arg[1]){ + case 'd': action = CLAct_CustomDLL; strict = false; break; + case 'D': action = CLAct_CustomDLL; strict = true; break; + + case 'i': action = CLAct_InitialFilePosition; break; + + case 'w': action = CLAct_WindowSize; break; + case 'W': action = CLAct_WindowMaximize; break; + case 'p': action = CLAct_WindowPosition; break; + case 'F': action = CLAct_WindowFullscreen; break; + + case 'f': action = CLAct_FontSize; break; + case 'h': action = CLAct_FontUseHinting; --i; break; + } + } + else if (arg[0] != 0){ + if (settings->init_files_count < settings->init_files_max){ + i32 index = settings->init_files_count++; + settings->init_files[index] = arg; + } + } + }break; + + case CLAct_CustomDLL: + { + plat_settings->custom_dll_is_strict = (b8)strict; + if (i < argc){ + plat_settings->custom_dll = argv[i]; + } + action = CLAct_Nothing; + }break; + + case CLAct_InitialFilePosition: + { + if (i < argc){ + settings->initial_line = (i32)string_to_integer(SCu8(argv[i]), 10); + } + action = CLAct_Nothing; + }break; + + case CLAct_WindowSize: + { + if (i + 1 < argc){ + plat_settings->set_window_size = true; + + i32 w = (i32)string_to_integer(SCu8(argv[i]), 10); + i32 h = (i32)string_to_integer(SCu8(argv[i + 1]), 10); + if (w > 0){ + plat_settings->window_w = w; + } + if (h > 0){ + plat_settings->window_h = h; + } + + ++i; + } + action = CLAct_Nothing; + }break; + + case CLAct_WindowMaximize: + { + --i; + plat_settings->maximize_window = true; + action = CLAct_Nothing; + }break; + + case CLAct_WindowPosition: + { + if (i + 1 < argc){ + plat_settings->set_window_pos = true; + + i32 x = (i32)string_to_integer(SCu8(argv[i]), 10); + i32 y = (i32)string_to_integer(SCu8(argv[i + 1]), 10); + if (x > 0){ + plat_settings->window_x = x; + } + if (y > 0){ + plat_settings->window_y = y; + } + + ++i; + } + action = CLAct_Nothing; + }break; + + case CLAct_WindowFullscreen: + { + --i; + plat_settings->fullscreen_window = true; + action = CLAct_Nothing; + }break; + + case CLAct_FontSize: + { + if (i < argc){ + settings->font_size = (i32)string_to_integer(SCu8(argv[i]), 10); + } + action = CLAct_Nothing; + }break; + + case CLAct_FontUseHinting: + { + plat_settings->use_hinting = true; + settings->use_hinting = plat_settings->use_hinting; + action = CLAct_Nothing; + }break; + } + }break; + + case CLMode_Custom: + { + settings->custom_flags = argv + i; + settings->custom_flags_count = argc - i; + i = argc; + mode = CLMode_App; + }break; + } + } +} + +//////////////////////////////// + +internal Models* +models_init(void){ + Arena arena = make_arena_system(); + Models *models = push_array_zero(&arena, Models, 1); + models->arena_ = arena; + models->arena = &models->arena_; + heap_init(&models->heap, get_base_allocator_system()); + return(models); +} + +internal void +app_load_vtables(API_VTable_system *vtable_system, API_VTable_font *vtable_font, API_VTable_graphics *vtable_graphics){ + system_api_read_vtable(vtable_system); + font_api_read_vtable(vtable_font); + graphics_api_read_vtable(vtable_graphics); +} + +internal Log_Function* +app_get_logger(void){ + log_init(); + return(log_string); +} + +App_Read_Command_Line_Sig(app_read_command_line){ + Models *models = models_init(); + App_Settings *settings = &models->settings; + block_zero_struct(settings); + if (argc > 1){ + init_command_line_settings(&models->settings, plat_settings, argc, argv); + } + *files = models->settings.init_files; + *file_count = &models->settings.init_files_count; + return(models); +} + +App_Init_Sig(app_init){ + Models *models = (Models*)base_ptr; + models->keep_playing = true; + + models->config_api = api; + models->virtual_event_arena = reserve_arena(tctx); + + profile_init(&models->profile_list); + + managed_ids_init(tctx->allocator, &models->managed_id_set); + + API_VTable_custom custom_vtable = {}; + custom_api_fill_vtable(&custom_vtable); + API_VTable_system system_vtable = {}; + system_api_fill_vtable(&system_vtable); + Custom_Layer_Init_Type *custom_init = api.init_apis(&custom_vtable, &system_vtable); + Assert(custom_init != 0); + + // NOTE(allen): coroutines + coroutine_system_init(&models->coroutines); + + // NOTE(allen): font set + font_set_init(&models->font_set); + + // NOTE(allen): live set + Arena *arena = models->arena; + { + models->view_set.count = 0; + models->view_set.max = MAX_VIEWS; + models->view_set.views = push_array(arena, View, models->view_set.max); + + //dll_init_sentinel + models->view_set.free_sentinel.next = &models->view_set.free_sentinel; + models->view_set.free_sentinel.prev = &models->view_set.free_sentinel; + + i32 max = models->view_set.max; + View *view = models->view_set.views; + for (i32 i = 0; i < max; ++i, ++view){ + //dll_insert(&models->view_set.free_sentinel, view); + view->next = models->view_set.free_sentinel.next; + view->prev = &models->view_set.free_sentinel; + models->view_set.free_sentinel.next = view; + view->next->prev = view; + } + } + + lifetime_allocator_init(tctx->allocator, &models->lifetime_allocator); + dynamic_workspace_init(&models->lifetime_allocator, DynamicWorkspace_Global, 0, &models->dynamic_workspace); + + // NOTE(allen): file setup + working_set_init(models, &models->working_set); + Mutex_Lock file_order_lock(models->working_set.mutex); + + // NOTE(allen): + global_history_init(&models->global_history); + text_layout_init(tctx, &models->text_layouts); + + // NOTE(allen): clipboard setup + models->working_set.clipboard_max_size = ArrayCount(models->working_set.clipboards); + models->working_set.clipboard_size = 0; + models->working_set.clipboard_current = 0; + models->working_set.clipboard_rolling = 0; + + // TODO(allen): do(better clipboard allocation) + if (clipboard.str != 0){ + String_Const_u8 *dest = working_set_next_clipboard_string(&models->heap, &models->working_set, clipboard.size); + block_copy(dest->str, clipboard.str, clipboard.size); + } + + // NOTE(allen): style setup + { + Scratch_Block scratch(tctx); + Face_Description description = {}; + description.font.file_name = get_file_path_in_fonts_folder(scratch, string_u8_litexpr("liberation-mono.ttf")); + description.parameters.pt_size = 12; + Face *new_face = font_set_new_face(&models->font_set, &description); + models->global_face_id = new_face->id; + } + + // NOTE(allen): title space + models->has_new_title = true; + models->title_capacity = KB(4); + models->title_space = push_array(arena, char, models->title_capacity); + block_copy(models->title_space, WINDOW_NAME, sizeof(WINDOW_NAME)); + + // NOTE(allen): miscellaneous init + hot_directory_init(arena, &models->hot_directory, current_directory); + child_process_container_init(tctx->allocator, &models->child_processes); + models->period_wakeup_timer = system_wake_up_timer_create(); + + // NOTE(allen): custom layer init + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + custom_init(&app); + + // NOTE(allen): init baked in buffers + File_Init init_files[] = { + { string_u8_litinit("*messages*"), &models->message_buffer , true , }, + { string_u8_litinit("*scratch*") , &models->scratch_buffer , false, }, + { string_u8_litinit("*log*") , &models->log_buffer , true , }, + { string_u8_litinit("*keyboard*"), &models->keyboard_buffer, true , }, + }; + + Heap *heap = &models->heap; + for (i32 i = 0; i < ArrayCount(init_files); ++i){ + Editing_File *file = working_set_allocate_file(&models->working_set, &models->lifetime_allocator); + buffer_bind_name(tctx, models, arena, &models->working_set, file, init_files[i].name); + + if (init_files[i].ptr != 0){ + *init_files[i].ptr = file; + } + + File_Attributes attributes = {}; + file_create_from_string(tctx, models, file, SCu8(), attributes); + if (init_files[i].read_only){ + file->settings.read_only = true; + history_free(tctx, &file->state.history); + } + + file->settings.never_kill = true; + file_set_unimportant(file, true); + } + + // NOTE(allen): setup first panel + { + Panel *panel = layout_initialize(arena, &models->layout); + View *new_view = live_set_alloc_view(&models->lifetime_allocator, &models->view_set, panel); + view_init(tctx, models, new_view, models->scratch_buffer, models->view_event_handler); + } +} + +App_Step_Sig(app_step){ + Models *models = (Models*)base_ptr; + + Mutex_Lock file_order_lock(models->working_set.mutex); + Scratch_Block scratch(tctx, Scratch_Share); + + models->next_animate_delay = max_u32; + models->animate_next_frame = false; + + // NOTE(allen): per-frame update of models state + begin_frame(target, &models->font_set); + models->target = target; + models->input = input; + + // NOTE(allen): OS clipboard event handling + String_Const_u8 clipboard = input->clipboard; + if (clipboard.str != 0){ + String_Const_u8 *dest = working_set_next_clipboard_string(&models->heap, &models->working_set, clipboard.size); + dest->size = eol_convert_in((char*)dest->str, (char*)clipboard.str, (i32)clipboard.size); + if (input->clipboard_changed){ + co_send_core_event(tctx, models, CoreCode_NewClipboardContents, *dest); + } + } + + // NOTE(allen): reorganizing panels on screen + Vec2_i32 prev_dim = layout_get_root_size(&models->layout); + Vec2_i32 current_dim = V2i32(target->width, target->height); + layout_set_root_size(&models->layout, current_dim); + + // NOTE(allen): update child processes + f32 dt = input->dt; + if (dt > 0){ + Temp_Memory_Block temp(scratch); + + Child_Process_Container *child_processes = &models->child_processes; + Child_Process **processes_to_free = push_array(scratch, Child_Process*, child_processes->active_child_process_count); + i32 processes_to_free_count = 0; + + u32 max = KB(128); + char *dest = push_array(scratch, char, max); + + for (Node *node = child_processes->child_process_active_list.next; + node != &child_processes->child_process_active_list; + node = node->next){ + Child_Process *child_process = CastFromMember(Child_Process, node, node); + + Editing_File *file = child_process->out_file; + CLI_Handles *cli = &child_process->cli; + + // TODO(allen): do(call a 'child process updated hook' let that hook populate the buffer if it so chooses) + + b32 edited_file = false; + u32 amount = 0; + system_cli_begin_update(cli); + if (system_cli_update_step(cli, dest, max, &amount)){ + if (file != 0 && amount > 0){ + amount = eol_in_place_convert_in(dest, amount); + output_file_append(tctx, models, file, SCu8(dest, amount)); + edited_file = true; + } + } + + if (system_cli_end_update(cli)){ + if (file != 0){ + String_Const_u8 str = push_u8_stringf(scratch, "exited with code %d", cli->exit); + output_file_append(tctx, models, file, str); + edited_file = true; + } + processes_to_free[processes_to_free_count++] = child_process; + child_process_set_return_code(models, child_processes, child_process->id, cli->exit); + } + + if (child_process->cursor_at_end && file != 0){ + file_cursor_to_end(tctx, models, file); + } + } + + for (i32 i = 0; i < processes_to_free_count; ++i){ + child_process_free(child_processes, processes_to_free[i]->id); + } + } + + // NOTE(allen): simulated events + Input_List input_list = input->events; + Input_Modifier_Set modifiers = system_get_keyboard_modifiers(scratch); + if (input->mouse.press_l){ + Input_Event event = {}; + event.kind = InputEventKind_MouseButton; + event.mouse.code = MouseCode_Left; + event.mouse.p = input->mouse.p; + event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); + push_input_event(scratch, &input_list, &event); + } + else if (input->mouse.release_l){ + Input_Event event = {}; + event.kind = InputEventKind_MouseButtonRelease; + event.mouse.code = MouseCode_Left; + event.mouse.p = input->mouse.p; + event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); + push_input_event(scratch, &input_list, &event); + } + if (input->mouse.press_r){ + Input_Event event = {}; + event.kind = InputEventKind_MouseButton; + event.mouse.code = MouseCode_Right; + event.mouse.p = input->mouse.p; + event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); + push_input_event(scratch, &input_list, &event); + } + else if (input->mouse.release_r){ + Input_Event event = {}; + event.kind = InputEventKind_MouseButtonRelease; + event.mouse.code = MouseCode_Right; + event.mouse.p = input->mouse.p; + event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); + push_input_event(scratch, &input_list, &event); + } + if (input->mouse.wheel != 0){ + Input_Event event = {}; + event.kind = InputEventKind_MouseWheel; + event.mouse_wheel.value = (f32)(input->mouse.wheel); + event.mouse_wheel.p = input->mouse.p; + event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); + push_input_event(scratch, &input_list, &event); + } + if (input->mouse.p != models->prev_p){ + b32 was_in_window = rect_contains_point(Ri32(0, 0, prev_dim.x, prev_dim.y), models->prev_p); + b32 is_in_window = rect_contains_point(Ri32(0, 0, current_dim.x, current_dim.y), input->mouse.p); + if (is_in_window || was_in_window){ + Input_Event event = {}; + event.kind = InputEventKind_MouseMove; + event.mouse_move.p = input->mouse.p; + event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); + push_input_event(scratch, &input_list, &event); + } + } + if (models->animated_last_frame){ + Input_Event event = {}; + event.kind = InputEventKind_Core; + event.core.code = CoreCode_Animate; + push_input_event(scratch, &input_list, &event); + } + + // NOTE(allen): expose layout + Layout *layout = &models->layout; + + // NOTE(allen): mouse hover status + Panel *mouse_panel = 0; + Panel *divider_panel = 0; + b32 mouse_in_margin = false; + Vec2_i32 mouse = input->mouse.p; + { + for (Panel *panel = layout_get_first_open_panel(layout); + panel != 0; + panel = layout_get_next_open_panel(layout, panel)){ + if (rect_contains_point(panel->rect_full, mouse)){ + mouse_panel = panel; + if (!rect_contains_point(panel->rect_inner, mouse)){ + mouse_in_margin = true; + for (divider_panel = mouse_panel->parent; + divider_panel != 0; + divider_panel = divider_panel->parent){ + if (rect_contains_point(divider_panel->rect_inner, mouse)){ + break; + } + } + } + } + if (mouse_panel != 0){ + break; + } + } + } + + // NOTE(allen): First frame initialization + if (input->first_step){ + Temp_Memory_Block temp(scratch); + + String_Const_u8_Array file_names = {}; + file_names.count = models->settings.init_files_count; + file_names.vals = push_array(scratch, String_Const_u8, file_names.count); + for (i32 i = 0; i < file_names.count; i += 1){ + file_names.vals[i] = SCu8(models->settings.init_files[i]); + } + + String_Const_u8_Array flags = {}; + flags.count = models->settings.custom_flags_count; + flags.vals = push_array(scratch, String_Const_u8, flags.count); + for (i32 i = 0; i < flags.count; i += 1){ + flags.vals[i] = SCu8(models->settings.custom_flags[i]); + } + + Input_Event event = {}; + event.kind = InputEventKind_Core; + event.core.code = CoreCode_Startup; + event.core.flag_strings = flags; + event.core.file_names = file_names; + co_send_event(tctx, models, &event); + } + + // NOTE(allen): consume event stream + Input_Event_Node *input_node = input_list.first; + Input_Event_Node *input_node_next = 0; + for (;; input_node = input_node_next){ + // NOTE(allen): first handle any events coming from the view command + // function queue + Model_View_Command_Function cmd_func = models_pop_view_command_function(models); + if (cmd_func.custom_func != 0){ + View *view = imp_get_view(models, cmd_func.view_id); + if (view != 0){ + input_node_next = input_node; + Input_Event cmd_func_event = {}; + cmd_func_event.kind = InputEventKind_CustomFunction; + cmd_func_event.custom_func = cmd_func.custom_func; + co_send_event(tctx, models, view, &cmd_func_event); + continue; + } + } + + Temp_Memory_Block temp(scratch); + Input_Event *simulated_input = 0; + Input_Event virtual_event = models_pop_virtual_event(scratch, models); + if (virtual_event.kind != InputEventKind_None){ + virtual_event.virtual_event = true; + simulated_input = &virtual_event; + } + else{ + if (input_node == 0){ + break; + } + input_node_next = input_node->next; + simulated_input = &input_node->event; + + if (simulated_input->kind == InputEventKind_TextInsert && simulated_input->text.blocked){ + continue; + } + + // NOTE(allen): record to keyboard history + if (simulated_input->kind == InputEventKind_KeyStroke || + simulated_input->kind == InputEventKind_KeyRelease || + simulated_input->kind == InputEventKind_TextInsert){ + Temp_Memory_Block temp_key_line(scratch); + String_Const_u8 key_line = stringize_keyboard_event(scratch, simulated_input); + output_file_append(tctx, models, models->keyboard_buffer, key_line); + } + } + + b32 event_was_handled = false; + Input_Event *event = simulated_input; + + Panel *active_panel = layout_get_active_panel(layout); + View *view = active_panel->view; + Assert(view != 0); + + switch (models->state){ + case APP_STATE_EDIT: + { + typedef i32 Event_Consume_Rule; + enum{ + EventConsume_None, + EventConsume_BeginResize, + EventConsume_ClickChangeView, + EventConsume_CustomCommand, + }; + + Event_Consume_Rule consume_rule = EventConsume_CustomCommand; + if (match_mouse_code(event, MouseCode_Left) && (divider_panel != 0)){ + consume_rule = EventConsume_BeginResize; + } + else if (match_mouse_code(event, MouseCode_Left) && + mouse_panel != 0 && mouse_panel != active_panel){ + consume_rule = EventConsume_ClickChangeView; + } + + switch (consume_rule){ + case EventConsume_BeginResize: + { + models->state = APP_STATE_RESIZING; + models->resizing_intermediate_panel = divider_panel; + event_was_handled = true; + }break; + + case EventConsume_ClickChangeView: + { + // NOTE(allen): run deactivate command + co_send_core_event(tctx, models, view, CoreCode_ClickDeactivateView); + + layout->active_panel = mouse_panel; + models->animate_next_frame = true; + active_panel = mouse_panel; + view = active_panel->view; + + // NOTE(allen): run activate command + co_send_core_event(tctx, models, view, CoreCode_ClickActivateView); + + event_was_handled = true; + }break; + + case EventConsume_CustomCommand: + { + event_was_handled = co_send_event(tctx, models, view, event); + }break; + } + }break; + + case APP_STATE_RESIZING: + { + Event_Property event_flags = get_event_properties(event); + if (HasFlag(event_flags, EventProperty_AnyKey) || + match_mouse_code_release(event, MouseCode_Left)){ + models->state = APP_STATE_EDIT; + } + else if (event->kind == InputEventKind_MouseMove){ + if (input->mouse.l){ + Panel *split = models->resizing_intermediate_panel; + Range_i32 limits = layout_get_limiting_range_on_split(layout, split); + i32 mouse_position = (split->vertical_split)?(mouse.x):(mouse.y); + mouse_position = clamp(limits.min, mouse_position, limits.max); + layout_set_split_absolute_position(layout, split, mouse_position); + } + else{ + models->state = APP_STATE_EDIT; + } + } + }break; + } + + if (event_was_handled && event->kind == InputEventKind_KeyStroke){ + for (Input_Event *dependent_text = event->key.first_dependent_text; + dependent_text != 0; + dependent_text = dependent_text->text.next_text){ + Assert(dependent_text->kind == InputEventKind_TextInsert); + dependent_text->text.blocked = true; + } + } + } + + linalloc_clear(models->virtual_event_arena); + models->free_virtual_event = 0; + models->first_virtual_event = 0; + models->last_virtual_event = 0; + + // NOTE(allen): send panel size update + if (models->layout.panel_state_dirty){ + models->layout.panel_state_dirty = false; + if (models->buffer_viewer_update != 0){ + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + models->buffer_viewer_update(&app); + } + } + + // NOTE(allen): dt + f32 literal_dt = 0.f; + u64 now_usecond_stamp = system_now_time(); + if (!input->first_step){ + u64 elapsed_useconds = now_usecond_stamp - models->last_render_usecond_stamp; + literal_dt = (f32)((f64)(elapsed_useconds)/1000000.f); + } + models->last_render_usecond_stamp = now_usecond_stamp; + f32 animation_dt = 0.f; + if (models->animated_last_frame){ + animation_dt = literal_dt; + } + + // NOTE(allen): on the first frame there should be no scrolling + if (input->first_step){ + for (Panel *panel = layout_get_first_open_panel(layout); + panel != 0; + panel = layout_get_next_open_panel(layout, panel)){ + View *view = panel->view; + File_Edit_Positions edit_pos = view_get_edit_pos(view); + edit_pos.scroll.position = view_normalize_buffer_point(tctx, models, view, edit_pos.scroll.target); + block_zero_struct(&edit_pos.scroll.target); + view_set_edit_pos(view, edit_pos); + } + } + + // NOTE(allen): hook for files reloaded + { + Working_Set *working_set = &models->working_set; + Assert(working_set->has_external_mod_sentinel.next != 0); + if (working_set->has_external_mod_sentinel.next != &working_set->has_external_mod_sentinel){ + for (Node *node = working_set->has_external_mod_sentinel.next, *next = 0; + node != &working_set->has_external_mod_sentinel; + node = next){ + next = node->next; + Editing_File *file = CastFromMember(Editing_File, external_mod_node, node); + dll_remove(node); + block_zero_struct(node); + co_send_core_event(tctx, models, CoreCode_FileExternallyModified, file->id); + } + } + } + + // NOTE(allen): if the exit signal has been sent, run the exit hook. + if (input->trying_to_kill){ + models->keep_playing = false; + } + if (!models->keep_playing){ + if (co_send_core_event(tctx, models, CoreCode_TryExit)){ + models->keep_playing = true; + } + } + + // NOTE(allen): rendering + { + Frame_Info frame = {}; + frame.index = models->frame_counter; + frame.literal_dt = literal_dt; + frame.animation_dt = animation_dt; + + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + + if (models->tick != 0){ + models->tick(&app, frame); + } + + begin_render_section(target, models->frame_counter, literal_dt, animation_dt); + models->in_render_mode = true; + + Live_Views *live_views = &models->view_set; + for (Node *node = layout->open_panels.next; + node != &layout->open_panels; + node = node->next){ + Panel *panel = CastFromMember(Panel, node, node); + View *view = panel->view; + View_Context_Node *ctx = view->ctx; + if (ctx != 0){ + Render_Caller_Function *render_caller = ctx->ctx.render_caller; + if (render_caller != 0){ + render_caller(&app, frame, view_get_id(live_views, view)); + } + } + } + + models->in_render_mode = false; + end_render_section(target); + } + + // NOTE(allen): flush the log + log_flush(tctx, models); + + // NOTE(allen): set the app_result + Application_Step_Result app_result = {}; + app_result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; + app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr; + + // NOTE(allen): get new window title + if (models->has_new_title){ + models->has_new_title = false; + app_result.has_new_title = true; + app_result.title_string = models->title_space; + } + + // NOTE(allen): get cursor type + if (mouse_panel != 0 && !mouse_in_margin){ + app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; + } + else if (divider_panel != 0){ + if (divider_panel->vertical_split){ + app_result.mouse_cursor_type = APP_MOUSE_CURSOR_LEFTRIGHT; + } + else{ + app_result.mouse_cursor_type = APP_MOUSE_CURSOR_UPDOWN; + } + } + else{ + app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; + } + + models->prev_mouse_panel = mouse_panel; + app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr; + app_result.perform_kill = !models->keep_playing; + app_result.animating = models->animate_next_frame; + if (models->animate_next_frame){ + // NOTE(allen): Silence the timer, because we're going to do another frame right away anyways. + system_wake_up_timer_set(models->period_wakeup_timer, max_u32); + } + else{ + // NOTE(allen): Set the timer's wakeup period, possibly to max_u32 thus effectively silencing it. + system_wake_up_timer_set(models->period_wakeup_timer, models->next_animate_delay); + } + + // NOTE(allen): Update Frame to Frame States + models->prev_p = input->mouse.p; + models->animated_last_frame = app_result.animating; + models->frame_counter += 1; + + // end-of-app_step + return(app_result); +} + +extern "C" App_Get_Functions_Sig(app_get_functions){ + App_Functions result = {}; + + result.load_vtables = app_load_vtables; + result.get_logger = app_get_logger; + result.read_command_line = app_read_command_line; + result.init = app_init; + result.step = app_step; + + return(result); +} + +// BOTTOM + diff --git a/custom/4coder_fancy.cpp b/custom/4coder_fancy.cpp index 9b840962..4364db02 100644 --- a/custom/4coder_fancy.cpp +++ b/custom/4coder_fancy.cpp @@ -347,11 +347,11 @@ function Fancy_String* push_fancy_string_fixed(Arena *arena, Fancy_Line *line, FColor fore, String_Const_u8 value, i32 max){ if (value.size <= max){ - return(push_fancy_stringf(arena, line, 0, fore, 0.f, 0.f, + return(push_fancy_stringf(arena, line, (Face_ID)0, fore, 0.f, 0.f, "%-*.*s", max, string_expand(value))); } else{ - return(push_fancy_stringf(arena, line, 0, fore, 0.f, 0.f, + return(push_fancy_stringf(arena, line, (Face_ID)0, fore, 0.f, 0.f, "%-*.*s...", max - 3, string_expand(value))); } } @@ -360,12 +360,12 @@ push_fancy_string_fixed(Arena *arena, Fancy_Line *line, f32 pre_margin, f32 post_margin, String_Const_u8 value, i32 max){ if (value.size <= max){ - return(push_fancy_stringf(arena, line, 0, fcolor_zero(), + return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), pre_margin, post_margin, "%-*.*s", max, string_expand(value))); } else{ - return(push_fancy_stringf(arena, line, 0, fcolor_zero(), + return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), pre_margin, post_margin, "%-*.*s...", max - 3, string_expand(value))); } @@ -374,11 +374,11 @@ function Fancy_String* push_fancy_string_fixed(Arena *arena, Fancy_Line *line, String_Const_u8 value, i32 max){ if (value.size <= max){ - return(push_fancy_stringf(arena, line, 0, fcolor_zero(), 0.f, 0.f, + return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), 0.f, 0.f, "%-*.*s", max, string_expand(value))); } else{ - return(push_fancy_stringf(arena, line, 0, fcolor_zero(), 0.f, 0.f, + return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), 0.f, 0.f, "%-*.*s...", max - 3, string_expand(value))); } } @@ -452,11 +452,11 @@ function Fancy_String* push_fancy_string_trunc(Arena *arena, Fancy_Line *line, FColor fore, String_Const_u8 value, i32 max){ if (value.size <= max){ - return(push_fancy_stringf(arena, line, 0, fore, 0.f, 0.f, + return(push_fancy_stringf(arena, line, (Face_ID)0, fore, 0.f, 0.f, "%.*s", string_expand(value))); } else{ - return(push_fancy_stringf(arena, line, 0, fore, 0.f, 0.f, + return(push_fancy_stringf(arena, line, (Face_ID)0, fore, 0.f, 0.f, "%.*s...", max - 3, value.str)); } } @@ -465,12 +465,12 @@ push_fancy_string_trunc(Arena *arena, Fancy_Line *line, f32 pre_margin, f32 post_margin, String_Const_u8 value, i32 max){ if (value.size <= max){ - return(push_fancy_stringf(arena, line, 0, fcolor_zero(), + return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), pre_margin, post_margin, "%.*s", string_expand(value))); } else{ - return(push_fancy_stringf(arena, line, 0, fcolor_zero(), + return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), pre_margin, post_margin, "%.*s...", max - 3, value.str)); } @@ -479,11 +479,11 @@ function Fancy_String* push_fancy_string_trunc(Arena *arena, Fancy_Line *line, String_Const_u8 value, i32 max){ if (value.size <= max){ - return(push_fancy_stringf(arena, line, 0, fcolor_zero(), 0.f, 0.f, + return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), 0.f, 0.f, "%.*s", string_expand(value))); } else{ - return(push_fancy_stringf(arena, line, 0, fcolor_zero(), 0.f, 0.f, + return(push_fancy_stringf(arena, line, (Face_ID)0, fcolor_zero(), 0.f, 0.f, "%.*s...", max - 3, value.str)); } } @@ -620,7 +620,7 @@ draw_fancy_string__inner(Application_Links *app, Face_ID face, FColor fore, Fanc use_fore = string->fore; } if (use_face != 0){ - ARGB_Color use_argb = fcolor_resolve(use_fore); + ARGB_Color use_argb = fcolor_resolve(use_fore); Face_Metrics metrics = get_face_metrics(app, use_face); f32 down_shift = (base_line - metrics.ascent); down_shift = clamp_bot(0.f, down_shift); @@ -668,7 +668,7 @@ get_fancy_string_height(Application_Links *app, Face_ID face, function f32 get_fancy_string_text_height(Application_Links *app, Face_ID face, - Fancy_String *string){ + Fancy_String *string){ Fancy_String *next = string->next; string->next = 0; f32 result = get_fancy_string_text_height__inner(app, face, string); @@ -700,10 +700,10 @@ function f32 get_fancy_line_width(Application_Links *app, Face_ID face, Fancy_Line *line){ f32 result = 0.f; if (line != 0){ - if (line->face != 0){ - face = line->face; - } - result = get_fancy_string_width__inner(app, face, line->first); + if (line->face != 0){ + face = line->face; + } + result = get_fancy_string_width__inner(app, face, line->first); } return(result); } @@ -749,12 +749,12 @@ draw_fancy_line(Application_Links *app, Face_ID face, FColor fore, Fancy_Line *line, Vec2_f32 p, u32 flags, Vec2_f32 delta){ Vec2_f32 result = {}; if (line != 0){ - if (line->face != 0){ - face = line->face; - } - if (fcolor_is_valid(line->fore)){ - fore = line->fore; - } + if (line->face != 0){ + face = line->face; + } + if (fcolor_is_valid(line->fore)){ + fore = line->fore; + } result = draw_fancy_string__inner(app, face, fore, line->first, p, flags, delta); } return(result); diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index 9aab846a..5cace252 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -131,7 +131,6 @@ float shape_value = (1.0 - smoothstep(-1.0, 0.0, sd)); shape_value *= has_thickness; float4 out_color = float4(in.color.xyz, in.color.a * (sample_value + shape_value)); -//float4 out_color = float4(1, 1, 1, shape_value); return(out_color); } )"; @@ -274,9 +273,12 @@ metal__make_buffer(u32 size, id device){ } - (void)drawInMTKView:(nonnull MTKView*)view{ +#if FRED_INTERNAL [capture_scope beginScope]; +#endif + + // HACK(yuval): This is the best way I found to force valid width and height without drawing on the next draw cycle (1 frame delay). - // HACK(yuval): This is the best way I found to force valid width and height without drawing on the next drawing cycle (1 frame delay). CGSize drawable_size = [view drawableSize]; i32 width = (i32)Min(_target->width, drawable_size.width); i32 height = (i32)Min(_target->height, drawable_size.height); @@ -293,8 +295,8 @@ metal__make_buffer(u32 size, id device){ render_pass_descriptor.colorAttachments[0].clearColor = MTLClearColorMake(0.0f, 0.0f, 0.0f, 1.0f); // NOTE(yuval): Create the render command encoder - id render_encoder - = [command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor]; + id render_encoder = + [command_buffer renderCommandEncoderWithDescriptor:render_pass_descriptor]; render_encoder.label = @"4coder Render Encoder"; // NOTE(yuval): Set the region of the drawable to draw into @@ -303,7 +305,7 @@ metal__make_buffer(u32 size, id device){ // NOTE(yuval): Set the render pipeline to use for drawing [render_encoder setRenderPipelineState:pipeline_state]; - // NOTE(yuval): Calculate and pass in the projection matrix + // NOTE(yuval): Calculate the projection matrix float left = 0, right = (float)width; float bottom = (float)height, top = 0; float near_depth = -1.0f, far_depth = 1.0f; @@ -325,6 +327,8 @@ metal__make_buffer(u32 size, id device){ u32 vertex_buffer_size = (all_vertex_count * sizeof(Render_Vertex)); + printf("Vertices to render: %d\n", all_vertex_count); + // NOTE(yuval): Find & Get a vertex buffer matching the required size Metal_Buffer *buffer = [self get_reusable_buffer_with_size:vertex_buffer_size]; @@ -338,6 +342,8 @@ metal__make_buffer(u32 size, id device){ length:sizeof(proj) atIndex:1]; + u32 group_count = 0; + u32 buffer_offset = 0; for (Render_Group *group = _target->group_first; group; @@ -346,7 +352,6 @@ metal__make_buffer(u32 size, id device){ { Rect_i32 box = Ri32(group->clip_box); - NSUInteger x0 = (NSUInteger)Min(Max(0, box.x0), width - 1); NSUInteger x1 = (NSUInteger)Min(Max(0, box.x1), width); NSUInteger y0 = (NSUInteger)Min(Max(0, box.y0), height - 1); @@ -405,8 +410,12 @@ metal__make_buffer(u32 size, id device){ buffer_offset += (vertex_count * sizeof(Render_Vertex)); } + + ++group_count; } + printf("Group Count: %u\n", group_count); + [render_encoder endEncoding]; // NOTE(yuval): Schedule a present once the framebuffer is complete using the current drawable @@ -422,7 +431,9 @@ metal__make_buffer(u32 size, id device){ // NOTE(yuval): Finalize rendering here and push the command buffer to the GPU [command_buffer commit]; +#if FRED_INTERNAL [capture_scope endScope]; +#endif } - (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind{ diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 00735e43..0925f962 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -315,6 +315,22 @@ mac_error_box(char *msg, b32 shutdown = true){ //////////////////////////////// +#if defined(FRED_INTERNAL) +function inline void +mac_profile(char *name, u64 begin, u64 end){ + printf("%s Time: %fs\n", name, ((end - begin) / 1000000.0f)); +} + +#define MacProfileScope(name) for (u64 glue(_i_, __LINE__) = 0, glue(_begin_, __LINE__) = system_now_time();\ +glue(_i_, __LINE__) == 0;\ +glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_time())) +#else +# define mac_profile(...) +# define MacProfileScope(...) +#endif + +//////////////////////////////// + #import "mac_4ed_renderer.mm" #include "4ed_font_provider_freetype.h" @@ -545,21 +561,6 @@ mac_toggle_fullscreen(void){ //////////////////////////////// -#if defined(FRED_INTERNAL) -function inline void -mac_profile(char *name, u64 begin, u64 end){ - printf("%s Time: %fs\n", name, ((end - begin) / 1000000.0f)); -} - -#define MacProfileScope(name) for (u64 glue(_i_, __LINE__) = 0, glue(_begin_, __LINE__) = system_now_time();\ -glue(_i_, __LINE__) == 0;\ -glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_time())) -#else -# define MacProfileScope(...) -#endif - -//////////////////////////////// - @implementation FCoder_App_Delegate - (void)applicationDidFinishLaunching:(id)sender{ } @@ -628,7 +629,12 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t mac_resize(mac_vars.window); } -- (void)drawRect:(NSRect)bounds{ +- (BOOL)wantsUpdateLayer +{ + return YES; +} + +- (void)updateLayer{ u64 prev_timer_start; MacProfileScope("Draw Rect"){ @@ -840,7 +846,9 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t } mac_profile("Frame", prev_timer_start, mac_vars.timer_start); +#if FRED_INTERNAL printf("\n"); +#endif } - (BOOL)acceptsFirstResponder{ @@ -856,8 +864,6 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t } - (void)keyDown:(NSEvent*)event{ - printf("Key Down: %#X\n", [event keyCode]); - // NOTE(yuval): Process keyboard event [self process_keyboard_event:event down:true]; @@ -896,7 +902,6 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t } - (void)keyUp:(NSEvent*)event{ - printf("Key Up: %#X\n", [event keyCode]); [self process_keyboard_event:event down:false]; } @@ -988,7 +993,7 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t } - (void)request_display{ - printf("Display Requested!\n"); + //printf("Display Requested!\n"); CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height); NSRect rect = NSRectFromCGRect(cg_rect); [self setNeedsDisplayInRect:rect]; @@ -1068,6 +1073,10 @@ glue(_i_, __LINE__) = 1, mac_profile(name, glue(_begin_, __LINE__), system_now_t Vec2_i32 new_m = V2i32(backing_location.x, mac_vars.height - backing_location.y); if (new_m != mac_vars.input_chunk.pers.mouse){ mac_vars.input_chunk.pers.mouse = new_m; + + Rect_i32 screen = Ri32(0, 0, target.width, target.height); + mac_vars.input_chunk.trans.out_of_window = !rect_contains_point(screen, new_m); + } system_signal_step(0); @@ -1270,6 +1279,7 @@ main(int arg_count, char **args){ mac_vars.view = [[FCoder_View alloc] init]; [mac_vars.view setFrame:[content_view bounds]]; [mac_vars.view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; + mac_vars.view.wantsLayer = true; // NOTE(yuval): Display window and view [content_view addSubview:mac_vars.view]; diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 1502a441..85a6c0f4 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -844,7 +844,9 @@ system_memory_annotation_sig(){ for (Memory_Annotation_Tracker_Node *node = memory_tracker.first; node != 0; node = node->next){ - Memory_Annotation_Node *r_node = push_array(arena, Memory_Annotation_Node, 1); + // TODO(yuval): Fix the API so that annotations would not mess with the system memory. + // Memory_Annotation_Node *r_node = push_array(arena, Memory_Annotation_Node, 1); + Memory_Annotation_Node *r_node = (Memory_Annotation_Node*)malloc(sizeof(Memory_Annotation_Node)); sll_queue_push(result.first, result.last, r_node); result.count += 1; diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm index 34fbbeca..19ea4459 100644 --- a/platform_mac/mac_4ed_metal.mm +++ b/platform_mac/mac_4ed_metal.mm @@ -15,8 +15,6 @@ struct Mac_Metal{ function mac_render_sig(mac_metal__render){ - printf("Rendering using Metal!\n"); - Mac_Metal *metal = (Mac_Metal*)renderer; [metal->view draw]; } @@ -77,8 +75,6 @@ mac_metal__init(NSWindow *window, Render_Target *target){ // TODO(yuval): This function should be exported to a DLL function mac_load_renderer_sig(mac_load_metal_renderer){ - printf("Loding The Metal Renderer!\n"); - Mac_Renderer *renderer = (Mac_Renderer*)mac_metal__init(window, target); return(renderer); } From 1ab40ff5b96bd8acfdb4821ed00b000adb041cad Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 14 Jan 2020 17:21:03 +0200 Subject: [PATCH 081/128] Lowered view sample count to improve the rendering speed on high dpi displays. --- metal/4ed_metal_render.mm | 1 - platform_mac/mac_4ed_metal.mm | 1 - 2 files changed, 2 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index 5cace252..7ac6f35e 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -223,7 +223,6 @@ metal__make_buffer(u32 size, id device){ pipeline_state_descriptor.vertexFunction = vertex_function; pipeline_state_descriptor.fragmentFunction = fragment_function; pipeline_state_descriptor.vertexDescriptor = vertexDescriptor; - pipeline_state_descriptor.sampleCount = mtk_view.sampleCount; pipeline_state_descriptor.colorAttachments[0].pixelFormat = mtk_view.colorPixelFormat; pipeline_state_descriptor.colorAttachments[0].blendingEnabled = YES; pipeline_state_descriptor.colorAttachments[0].alphaBlendOperation = MTLBlendOperationAdd; diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm index 19ea4459..0ce3397d 100644 --- a/platform_mac/mac_4ed_metal.mm +++ b/platform_mac/mac_4ed_metal.mm @@ -56,7 +56,6 @@ mac_metal__init(NSWindow *window, Render_Target *target){ [metal->view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable]; [metal->view setPaused:YES]; [metal->view setEnableSetNeedsDisplay:NO]; - [metal->view setSampleCount:4]; metal->view.device = MTLCreateSystemDefaultDevice(); From 93494bd3984c1675bf3c33b936404208e5ac16d6 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 14 Jan 2020 17:25:13 +0200 Subject: [PATCH 082/128] Cleanup to the macOS platform layer. --- metal/4ed_metal_render.mm | 8 -------- platform_mac/mac_4ed.mm | 2 +- platform_mac/mac_4ed_opengl.mm | 2 -- 3 files changed, 1 insertion(+), 11 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index 7ac6f35e..6f029cc7 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -326,8 +326,6 @@ metal__make_buffer(u32 size, id device){ u32 vertex_buffer_size = (all_vertex_count * sizeof(Render_Vertex)); - printf("Vertices to render: %d\n", all_vertex_count); - // NOTE(yuval): Find & Get a vertex buffer matching the required size Metal_Buffer *buffer = [self get_reusable_buffer_with_size:vertex_buffer_size]; @@ -341,8 +339,6 @@ metal__make_buffer(u32 size, id device){ length:sizeof(proj) atIndex:1]; - u32 group_count = 0; - u32 buffer_offset = 0; for (Render_Group *group = _target->group_first; group; @@ -409,12 +405,8 @@ metal__make_buffer(u32 size, id device){ buffer_offset += (vertex_count * sizeof(Render_Vertex)); } - - ++group_count; } - printf("Group Count: %u\n", group_count); - [render_encoder endEncoding]; // NOTE(yuval): Schedule a present once the framebuffer is complete using the current drawable diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 0925f962..2318c698 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -1286,7 +1286,7 @@ main(int arg_count, char **args){ [mac_vars.window makeKeyAndOrderFront:nil]; // NOTE(yuval): Initialize the renderer - renderer = mac_init_renderer(MacRenderer_Metal, mac_vars.window, &target); + renderer = mac_init_renderer(MacRenderer_OpenGL, mac_vars.window, &target); mac_resize(w, h); diff --git a/platform_mac/mac_4ed_opengl.mm b/platform_mac/mac_4ed_opengl.mm index 57dd3348..7efb31c0 100644 --- a/platform_mac/mac_4ed_opengl.mm +++ b/platform_mac/mac_4ed_opengl.mm @@ -87,8 +87,6 @@ struct Mac_OpenGL{ NSOpenGLPFAColorSize, 32, NSOpenGLPFAAlphaSize, 8, NSOpenGLPFADepthSize, 24, - NSOpenGLPFASampleBuffers, 1, - NSOpenGLPFASamples, 16, 0 }; From 2865860b24adf1547f4866747db02f32e760f491 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Tue, 14 Jan 2020 15:35:14 -0800 Subject: [PATCH 083/128] Create folders from interactive_open_or_new --- custom/4coder_base_types.cpp | 30 +++++- custom/4coder_lister_base.cpp | 8 +- custom/4coder_lister_base.h | 3 +- custom/4coder_lists.cpp | 136 ++++++++++++++++++++-------- custom/generated/command_metadata.h | 14 +-- 5 files changed, 137 insertions(+), 54 deletions(-) diff --git a/custom/4coder_base_types.cpp b/custom/4coder_base_types.cpp index 09717a43..677029a2 100644 --- a/custom/4coder_base_types.cpp +++ b/custom/4coder_base_types.cpp @@ -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)); @@ -4399,6 +4399,26 @@ string_front_of_path(String_Const_u32 str){ return(str); } +function String_Const_u8 +string_remove_front_folder_of_path(String_Const_u8 str){ + i64 slash_pos = string_find_last_slash(string_chop(str, 1)); + if (slash_pos < 0){ + str.size = 0; + } + else{ + str.size = slash_pos + 1; + } + return(str); +} +function String_Const_u8 +string_front_folder_of_path(String_Const_u8 str){ + i64 slash_pos = string_find_last_slash(string_chop(str, 1)); + if (slash_pos >= 0){ + str = string_skip(str, slash_pos + 1); + } + return(str); +} + function String_Const_char string_file_extension(String_Const_char string){ return(string_skip(string, string_find_last(string, '.') + 1)); @@ -4752,7 +4772,7 @@ string_find_first(String_Const_u8 str, String_Const_u8 needle, String_Match_Rule i = str.size; if (str.size >= needle.size){ i = 0; - u8 c = character_to_upper(needle.str[0]); + u8 c = character_to_upper(needle.str[0]); u64 one_past_last = str.size - needle.size + 1; for (;i < one_past_last; i += 1){ if (character_to_upper(str.str[i]) == c){ @@ -4776,7 +4796,7 @@ string_find_first(String_Const_u16 str, String_Const_u16 needle, String_Match_Ru i = str.size; if (str.size >= needle.size){ i = 0; - u16 c = character_to_upper(needle.str[0]); + u16 c = character_to_upper(needle.str[0]); u64 one_past_last = str.size - needle.size + 1; for (;i < one_past_last; i += 1){ if (character_to_upper(str.str[i]) == c){ @@ -4800,7 +4820,7 @@ string_find_first(String_Const_u32 str, String_Const_u32 needle, String_Match_Ru i = str.size; if (str.size >= needle.size){ i = 0; - u32 c = character_to_upper(needle.str[0]); + u32 c = character_to_upper(needle.str[0]); u64 one_past_last = str.size - needle.size + 1; for (;i < one_past_last; i += 1){ if (character_to_upper(str.str[i]) == c){ @@ -5285,7 +5305,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); diff --git a/custom/4coder_lister_base.cpp b/custom/4coder_lister_base.cpp index 315ad374..06341b16 100644 --- a/custom/4coder_lister_base.cpp +++ b/custom/4coder_lister_base.cpp @@ -472,7 +472,7 @@ run_lister(Application_Links *app, Lister *lister){ case InputEventKind_TextInsert: { if (lister->handlers.write_character != 0){ - lister->handlers.write_character(app); + result = lister->handlers.write_character(app); } }break; @@ -627,7 +627,7 @@ run_lister(Application_Links *app, Lister *lister){ switch (in.event.core.code){ case CoreCode_Animate: { - lister_update_filtered_list(app, lister); + lister_update_filtered_list(app, lister); }break; default: @@ -716,8 +716,9 @@ lister_add_item(Lister *lister, String_Const_u8 string, String_Const_u8 status, user_data, extra_space)); } -function void +function Lister_Activation_Code lister__write_string__default(Application_Links *app){ + Lister_Activation_Code result = ListerActivation_Continue; View_ID view = get_active_view(app, Access_Always); Lister *lister = view_get_lister(view); if (lister != 0){ @@ -731,6 +732,7 @@ lister__write_string__default(Application_Links *app){ lister_update_filtered_list(app, lister); } } + return(result); } function void diff --git a/custom/4coder_lister_base.h b/custom/4coder_lister_base.h index c38cc666..aa6fae80 100644 --- a/custom/4coder_lister_base.h +++ b/custom/4coder_lister_base.h @@ -39,6 +39,7 @@ struct Lister_Node_Ptr_Array{ i32 count; }; +typedef Lister_Activation_Code Lister_Write_Character_Function(Application_Links *app); typedef Lister_Activation_Code Lister_Key_Stroke_Function(Application_Links *app); typedef void Lister_Navigate_Function(Application_Links *app, View_ID view, struct Lister *lister, @@ -46,7 +47,7 @@ typedef void Lister_Navigate_Function(Application_Links *app, struct Lister_Handlers{ Lister_Regenerate_List_Function_Type *refresh; - Custom_Command_Function *write_character; + Lister_Write_Character_Function *write_character; Custom_Command_Function *backspace; Lister_Navigate_Function *navigate; Lister_Key_Stroke_Function *key_stroke; diff --git a/custom/4coder_lists.cpp b/custom/4coder_lists.cpp index 7438a50f..bc27d363 100644 --- a/custom/4coder_lists.cpp +++ b/custom/4coder_lists.cpp @@ -222,7 +222,7 @@ get_color_table_from_user(Application_Links *app, String_Const_u8 query, Color_T Lister_Result l_result = run_lister(app, lister); - Color_Table *result = 0; + Color_Table *result = 0; if (!l_result.canceled){ result = (Color_Table*)l_result.user_data; } @@ -236,8 +236,9 @@ get_color_table_from_user(Application_Links *app){ //////////////////////////////// -function void +function Lister_Activation_Code lister__write_character__file_path(Application_Links *app){ + Lister_Activation_Code result = ListerActivation_Continue; View_ID view = get_this_ctx_view(app, Access_Always); Lister *lister = view_get_lister(view); if (lister != 0){ @@ -245,18 +246,20 @@ lister__write_character__file_path(Application_Links *app){ String_Const_u8 string = to_writable(&in); if (string.str != 0 && string.size > 0){ lister_append_text_field(lister, string); - String_Const_u8 front_name = string_front_of_path(lister->text_field.string); - lister_set_key(lister, front_name); if (character_is_slash(string.str[0])){ - String_Const_u8 new_hot = lister->text_field.string; - set_hot_directory(app, new_hot); - lister_call_refresh_handler(app, lister); + lister->out.text_field = lister->text_field.string; + result = ListerActivation_Finished; + } + else{ + String_Const_u8 front_name = string_front_of_path(lister->text_field.string); + lister_set_key(lister, front_name); } lister->item_index = 0; lister_zero_scroll(lister); lister_update_filtered_list(app, lister); } } + return(result); } function void @@ -374,15 +377,13 @@ struct File_Name_Result{ }; function File_Name_Result -get_file_name_from_user(Application_Links *app, Arena *arena, String_Const_u8 query, - View_ID view){ +get_file_name_from_user(Application_Links *app, Arena *arena, String_Const_u8 query, View_ID view){ Lister_Handlers handlers = lister_get_default_handlers(); handlers.refresh = generate_hot_directory_file_list; handlers.write_character = lister__write_character__file_path; handlers.backspace = lister__backspace_text_field__file_path; - Lister_Result l_result = - run_lister_with_refresh_handler(app, arena, query, handlers); + Lister_Result l_result = run_lister_with_refresh_handler(app, arena, query, handlers); File_Name_Result result = {}; result.canceled = l_result.canceled; @@ -391,12 +392,18 @@ get_file_name_from_user(Application_Links *app, Arena *arena, String_Const_u8 qu if (l_result.user_data != 0){ String_Const_u8 name = SCu8((u8*)l_result.user_data); result.file_name_activated = name; - result.is_folder = - character_is_slash(string_get_character(name, name.size -1 )); + result.is_folder = character_is_slash(string_get_character(name, name.size - 1)); } result.file_name_in_text_field = string_front_of_path(l_result.text_field); - String_Const_u8 path = string_remove_front_of_path(l_result.text_field); + String_Const_u8 path = {}; + if (result.file_name_in_text_field.size == 0 && l_result.text_field.size > 0){ + result.file_name_in_text_field = string_front_folder_of_path(l_result.text_field); + path = string_remove_front_folder_of_path(l_result.text_field); + } + else{ + path = string_remove_front_of_path(l_result.text_field); + } if (character_is_slash(string_get_character(path, path.size - 1))){ path = string_chop(path, 1); } @@ -407,8 +414,7 @@ get_file_name_from_user(Application_Links *app, Arena *arena, String_Const_u8 qu } function File_Name_Result -get_file_name_from_user(Application_Links *app, Arena *arena, char *query, - View_ID view){ +get_file_name_from_user(Application_Links *app, Arena *arena, char *query, View_ID view){ return(get_file_name_from_user(app, arena, SCu8(query), view)); } @@ -429,8 +435,7 @@ do_buffer_kill_user_check(Application_Links *app, Buffer_ID buffer, View_ID view lister_choice(scratch, &list, "(Y)es" , "", KeyCode_Y, SureToKill_Yes); lister_choice(scratch, &list, "(S)ave", "", KeyCode_S, SureToKill_Save); - Lister_Choice *choice = - get_choice_from_user(app, "There are unsaved changes, close anyway?", list); + Lister_Choice *choice = get_choice_from_user(app, "There are unsaved changes, close anyway?", list); b32 do_kill = false; if (choice != 0){ @@ -507,7 +512,7 @@ CUSTOM_DOC("Interactively switch to an open buffer.") { Buffer_ID buffer = get_buffer_from_user(app, "Switch:"); if (buffer != 0){ - View_ID view = get_this_ctx_view(app, Access_Always); + View_ID view = get_this_ctx_view(app, Access_Always); view_set_buffer(app, view, buffer, 0); } } @@ -524,6 +529,50 @@ CUSTOM_DOC("Interactively kill an open buffer.") //////////////////////////////// +enum{ + SureToCreateFolder_NULL = 0, + SureToCreateFolder_No = 1, + SureToCreateFolder_Yes = 2, +}; + +function b32 +query_create_folder(Application_Links *app, String_Const_u8 folder_name){ + Scratch_Block scratch(app); + Lister_Choice_List list = {}; + lister_choice(scratch, &list, "(N)o" , "", KeyCode_N, SureToKill_No); + lister_choice(scratch, &list, "(Y)es" , "", KeyCode_Y, SureToKill_Yes); + + String_Const_u8 message = push_u8_stringf(scratch, "Create the folder %.*s?", string_expand(folder_name)); + Lister_Choice *choice = get_choice_from_user(app, message, list); + + b32 did_create_folder = false; + if (choice != 0){ + switch (choice->user_data){ + case SureToCreateFolder_No: + {}break; + + case SureToCreateFolder_Yes: + { + String_Const_u8 hot = push_hot_directory(app, scratch); + String_Const_u8 fixed_folder_name = folder_name; + for (;fixed_folder_name.size > 0 && + character_is_slash(fixed_folder_name.str[fixed_folder_name.size - 1]);){ + fixed_folder_name = string_chop(fixed_folder_name, 1); + } + if (fixed_folder_name.size > 0){ + String_Const_u8 cmd = push_u8_stringf(scratch, "mkdir %.*s", string_expand(fixed_folder_name)); + exec_system_command(app, 0, buffer_identifier(0), hot, cmd, 0); + did_create_folder = true; + } + }break; + } + } + + return(did_create_folder); +} + +//////////////////////////////// + function Lister_Activation_Code activate_open_or_new__generic(Application_Links *app, View_ID view, String_Const_u8 path, String_Const_u8 file_name, @@ -566,8 +615,7 @@ CUSTOM_DOC("Interactively open a file out of the file system.") for (;;){ Scratch_Block scratch(app); View_ID view = get_this_ctx_view(app, Access_Always); - File_Name_Result result = get_file_name_from_user(app, scratch, "Open:", - view); + File_Name_Result result = get_file_name_from_user(app, scratch, "Open:", view); if (result.canceled) break; String_Const_u8 file_name = result.file_name_activated; @@ -577,15 +625,27 @@ CUSTOM_DOC("Interactively open a file out of the file system.") if (file_name.size == 0) break; String_Const_u8 path = result.path_in_text_field; - String_Const_u8 full_file_name = - push_u8_stringf(scratch, "%.*s/%.*s", - string_expand(path), string_expand(file_name)); + String_Const_u8 full_file_name = push_u8_stringf(scratch, "%.*s/%.*s", + string_expand(path), string_expand(file_name)); if (result.is_folder){ set_hot_directory(app, full_file_name); continue; } + if (character_is_slash(file_name.str[file_name.size - 1])){ + File_Attributes attribs = system_quick_file_attributes(scratch, full_file_name); + if (HasFlag(attribs.flags, FileAttribute_IsDirectory)){ + set_hot_directory(app, full_file_name); + continue; + } + if (query_create_folder(app, file_name)){ + set_hot_directory(app, full_file_name); + continue; + } + break; + } + Buffer_ID buffer = create_buffer(app, full_file_name, 0); if (buffer != 0){ view_set_buffer(app, view, buffer, 0); @@ -670,20 +730,20 @@ CUSTOM_DOC("Opens an interactive list of all registered commands.") { View_ID view = get_this_ctx_view(app, Access_Always); if (view != 0){ - Command_Lister_Status_Rule rule = {}; - Buffer_ID buffer = view_get_buffer(app, view, Access_Visible); - Managed_Scope buffer_scope = buffer_get_managed_scope(app, buffer); - Command_Map_ID *map_id_ptr = scope_attachment(app, buffer_scope, buffer_map_id, Command_Map_ID); - if (map_id_ptr != 0){ - rule = command_lister_status_bindings(&framework_mapping, *map_id_ptr); - } - else{ - rule = command_lister_status_descriptions(); - } - Custom_Command_Function *func = get_command_from_user(app, "Command:", &rule); - if (func != 0){ - view_enqueue_command_function(app, view, func); - } + Command_Lister_Status_Rule rule = {}; + Buffer_ID buffer = view_get_buffer(app, view, Access_Visible); + Managed_Scope buffer_scope = buffer_get_managed_scope(app, buffer); + Command_Map_ID *map_id_ptr = scope_attachment(app, buffer_scope, buffer_map_id, Command_Map_ID); + if (map_id_ptr != 0){ + rule = command_lister_status_bindings(&framework_mapping, *map_id_ptr); + } + else{ + rule = command_lister_status_descriptions(); + } + Custom_Command_Function *func = get_command_from_user(app, "Command:", &rule); + if (func != 0){ + view_enqueue_command_function(app, view, func); + } } } diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index a1d0cdde..8e9958d0 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -274,7 +274,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 619 }, { 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(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 728 }, { 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 }, @@ -314,11 +314,11 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 671 }, -{ 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(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 520 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 657 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 694 }, +{ 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, 612 }, +{ 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, 510 }, { 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, 54 }, { 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, 77 }, @@ -448,7 +448,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 1513 }, -{ 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(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 752 }, { 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, 563 }, { 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, 550 }, { 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, 656 }, From e0920123acefcb85683dc292dd978e8b13390855 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Tue, 14 Jan 2020 15:38:29 -0800 Subject: [PATCH 084/128] Sticky jump crash fixed --- custom/4coder_jump_sticky.cpp | 12 +++++++----- 1 file changed, 7 insertions(+), 5 deletions(-) diff --git a/custom/4coder_jump_sticky.cpp b/custom/4coder_jump_sticky.cpp index 2188af7a..b39acd49 100644 --- a/custom/4coder_jump_sticky.cpp +++ b/custom/4coder_jump_sticky.cpp @@ -114,9 +114,9 @@ init_marker_list(Application_Links *app, Heap *heap, Buffer_ID buffer, Marker_Li } sort_pairs_by_key(range_index_buffer_id_pairs, buffer_ranges.count); Range_i32_Array scoped_buffer_ranges = get_ranges_of_duplicate_keys(scratch, - &range_index_buffer_id_pairs->key, - sizeof(*range_index_buffer_id_pairs), - buffer_ranges.count); + &range_index_buffer_id_pairs->key, + sizeof(*range_index_buffer_id_pairs), + buffer_ranges.count); Sticky_Jump_Stored *stored = push_array(scratch, Sticky_Jump_Stored, jumps.count); @@ -171,7 +171,9 @@ init_marker_list(Application_Links *app, Heap *heap, Buffer_ID buffer, Marker_Li Assert(managed_object_get_type(app, marker_handle) == ManagedObjectType_Markers); Managed_Object *marker_handle_ptr = scope_attachment(app, scope, sticky_jump_marker_handle, Managed_Object); - *marker_handle_ptr = marker_handle; + if (marker_handle_ptr != 0){ + *marker_handle_ptr = marker_handle; + } } Managed_Object stored_jump_array = alloc_managed_memory_in_scope(app, scope_array[0], sizeof(Sticky_Jump_Stored), jumps.count); @@ -279,7 +281,7 @@ get_jump_from_list(Application_Links *app, Marker_List *list, i32 index, ID_Pos_ Managed_Scope scope = get_managed_scope_with_multiple_dependencies(app, scope_array, ArrayCount(scope_array)); Managed_Object *marker_array = scope_attachment(app, scope, sticky_jump_marker_handle, Managed_Object); - if (*marker_array != 0){ + if (marker_array != 0 && *marker_array != 0){ Marker marker = {}; managed_object_load_data(app, *marker_array, stored.index_into_marker_array, 1, &marker); location->buffer_id = target_buffer_id; From d0937976d7b8a2d7f1d5acb3127c30197a0f3fae Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Tue, 14 Jan 2020 15:39:32 -0800 Subject: [PATCH 085/128] Added folder creation logic to interactive_new and interactive_open --- custom/4coder_lists.cpp | 26 ++++++++++++++++++++++++++ custom/generated/command_metadata.h | 26 +++++++++++++------------- 2 files changed, 39 insertions(+), 13 deletions(-) diff --git a/custom/4coder_lists.cpp b/custom/4coder_lists.cpp index bc27d363..27a15d89 100644 --- a/custom/4coder_lists.cpp +++ b/custom/4coder_lists.cpp @@ -682,6 +682,19 @@ CUSTOM_DOC("Interactively creates a new file.") continue; } + if (character_is_slash(file_name.str[file_name.size - 1])){ + File_Attributes attribs = system_quick_file_attributes(scratch, full_file_name); + if (HasFlag(attribs.flags, FileAttribute_IsDirectory)){ + set_hot_directory(app, full_file_name); + continue; + } + if (query_create_folder(app, file_name)){ + set_hot_directory(app, full_file_name); + continue; + } + break; + } + Buffer_Create_Flag flags = BufferCreate_AlwaysNew; Buffer_ID buffer = create_buffer(app, full_file_name, flags); if (buffer != 0){ @@ -714,6 +727,19 @@ CUSTOM_DOC("Interactively opens a file.") continue; } + if (character_is_slash(file_name.str[file_name.size - 1])){ + File_Attributes attribs = system_quick_file_attributes(scratch, full_file_name); + if (HasFlag(attribs.flags, FileAttribute_IsDirectory)){ + set_hot_directory(app, full_file_name); + continue; + } + if (query_create_folder(app, file_name)){ + set_hot_directory(app, full_file_name); + continue; + } + break; + } + Buffer_Create_Flag flags = BufferCreate_NeverNew; Buffer_ID buffer = create_buffer(app, full_file_name, flags); if (buffer != 0){ diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 8e9958d0..ebda7adb 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -274,7 +274,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 619 }, { 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, 728 }, +{ 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, 754 }, { 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 }, @@ -298,25 +298,25 @@ static Command_Metadata fcoder_metacmd_table[229] = { { PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 738 }, { 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_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, 525 }, +{ 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, 542 }, +{ 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, 348 }, +{ 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, 375 }, { 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, 746 }, -{ 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(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, 464 }, +{ 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, 494 }, +{ 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, 481 }, +{ 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, 511 }, { 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, 649 }, { 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, 635 }, { 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(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, 564 }, +{ 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, 581 }, { 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, 671 }, { 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, 520 }, { PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 657 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 694 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 707 }, { 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, 612 }, { 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, 510 }, { 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 }, @@ -448,7 +448,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 1513 }, -{ 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, 752 }, +{ 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, 778 }, { 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, 563 }, { 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, 550 }, { 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, 656 }, From ab486eb22947ea3566db8bee94897aa9951f2e12 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Wed, 15 Jan 2020 02:21:02 +0200 Subject: [PATCH 086/128] Removed some debug prints. --- custom/bin/buildsuper_x64-mac.sh | 2 +- platform_mac/mac_4ed.mm | 24 +----------------------- 2 files changed, 2 insertions(+), 24 deletions(-) diff --git a/custom/bin/buildsuper_x64-mac.sh b/custom/bin/buildsuper_x64-mac.sh index 9f6bce10..ff3699a8 100755 --- a/custom/bin/buildsuper_x64-mac.sh +++ b/custom/bin/buildsuper_x64-mac.sh @@ -24,7 +24,7 @@ clang++ -I"$CODE_HOME" $meta_macros $arch $opts $debug -std=gnu++0x "$SOURCE" -E clang++ -I"$CODE_HOME" $opts $debug -std=gnu++0x "$CODE_HOME/4coder_metadata_generator.cpp" -o "$CODE_HOME/metadata_generator" "$CODE_HOME/metadata_generator" -R "$CODE_HOME" "$PWD/$preproc_file" -clang++ -I"$CODE_HOME" $arch $opts $debug -std=gnu++0x "$SOURCE" -shared -o custom_4coder.so -fPIC +clang++ -I"$CODE_HOME" $arch $opts $debug -std=c++11 "$SOURCE" -shared -o custom_4coder.so -fPIC rm "$CODE_HOME/metadata_generator" rm $preproc_file diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 2318c698..228d87bc 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -624,8 +624,7 @@ mac_toggle_fullscreen(void){ } - (void)viewDidChangeBackingProperties{ - // TODO(yuval): Screen scale factor calculation - printf("Backing changed!\n"); + // TODO(yuval): If the screen scale factor changed, modify the current face to use the new screen scale factor. mac_resize(mac_vars.window); } @@ -722,7 +721,6 @@ mac_toggle_fullscreen(void){ // NOTE(yuval): Quit the app if requested by the application core MacProfileScope("Perform Kill"){ if (result.perform_kill){ - printf("Terminating 4coder!\n"); [NSApp terminate:nil]; } } @@ -993,7 +991,6 @@ mac_toggle_fullscreen(void){ } - (void)request_display{ - //printf("Display Requested!\n"); CGRect cg_rect = CGRectMake(0, 0, mac_vars.width, mac_vars.height); NSRect rect = NSRectFromCGRect(cg_rect); [self setNeedsDisplayInRect:rect]; @@ -1358,25 +1355,6 @@ main(int arg_count, char **args){ mac_vars.timer_start = system_now_time(); // NOTE(yuval): Start the app's run loop -#if 1 - printf("Running using NSApp run\n"); [NSApp run]; -#else - printf("Running using manual event loop\n"); - - for (;;) { - u64 count = 0; - - NSEvent* event; - do { - event = [NSApp nextEventMatchingMask:NSEventMaskAny - untilDate:[NSDate distantFuture] - inMode:NSDefaultRunLoopMode - dequeue:YES]; - - [NSApp sendEvent:event]; - } while (event != nil); - } -#endif } } \ No newline at end of file From 4a8febcdde9c5668531cb3b87d130cb7f6998f25 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Wed, 15 Jan 2020 10:14:17 -0800 Subject: [PATCH 087/128] Fade ranges added to default rendering rules; fixed crash on bad font path --- 4ed.cpp | 1678 ++++++------ 4ed_api_implementation.cpp | 53 +- 4ed_file.h | 11 - 4ed_layout.cpp | 2 +- 4ed_view.cpp | 16 +- custom/4coder_clipboard.cpp | 14 +- custom/4coder_default_bindings.cpp | 4 + custom/4coder_default_framework.cpp | 115 +- custom/4coder_default_framework.h | 20 + custom/4coder_default_framework_variables.cpp | 7 + custom/4coder_default_hooks.cpp | 2311 +++++++++-------- custom/4coder_default_include.cpp | 2 - custom/4coder_draw.cpp | 1703 ++++++------ custom/4coder_lists.cpp | 3 +- custom/generated/command_metadata.h | 10 +- custom/generated/custom_api.cpp | 4 +- custom/generated/custom_api.h | 10 +- custom/generated/custom_api_master_list.h | 2 +- docs/4ed_doc_custom_api_view.cpp | 7 - 19 files changed, 3037 insertions(+), 2935 deletions(-) diff --git a/4ed.cpp b/4ed.cpp index 155c53a5..78818d9c 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -1,839 +1,839 @@ -/* - * Mr. 4th Dimention - Allen Webster - * - * 12.12.2014 - * - * Application layer for project codename "4ed" - * - */ - -// TOP - -internal void -init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, i32 argc, char **argv){ - char *arg = 0; - Command_Line_Mode mode = CLMode_App; - Command_Line_Action action = CLAct_Nothing; - b32 strict = false; - - settings->init_files_max = ArrayCount(settings->init_files); - for (i32 i = 1; i <= argc; ++i){ - if (i == argc){ - arg = ""; - } - else{ - arg = argv[i]; - } - - if (arg[0] == '-' && arg[1] == '-'){ - char *long_arg_name = arg+2; - if (string_match(SCu8(long_arg_name), string_u8_litexpr("custom"))){ - mode = CLMode_Custom; - continue; - } - } - - switch (mode){ - case CLMode_App: - { - switch (action){ - case CLAct_Nothing: - { - if (arg[0] == '-'){ - action = CLAct_Ignore; - switch (arg[1]){ - case 'd': action = CLAct_CustomDLL; strict = false; break; - case 'D': action = CLAct_CustomDLL; strict = true; break; - - case 'i': action = CLAct_InitialFilePosition; break; - - case 'w': action = CLAct_WindowSize; break; - case 'W': action = CLAct_WindowMaximize; break; - case 'p': action = CLAct_WindowPosition; break; - case 'F': action = CLAct_WindowFullscreen; break; - - case 'f': action = CLAct_FontSize; break; - case 'h': action = CLAct_FontUseHinting; --i; break; - } - } - else if (arg[0] != 0){ - if (settings->init_files_count < settings->init_files_max){ - i32 index = settings->init_files_count++; - settings->init_files[index] = arg; - } - } - }break; - - case CLAct_CustomDLL: - { - plat_settings->custom_dll_is_strict = (b8)strict; - if (i < argc){ - plat_settings->custom_dll = argv[i]; - } - action = CLAct_Nothing; - }break; - - case CLAct_InitialFilePosition: - { - if (i < argc){ - settings->initial_line = (i32)string_to_integer(SCu8(argv[i]), 10); - } - action = CLAct_Nothing; - }break; - - case CLAct_WindowSize: - { - if (i + 1 < argc){ - plat_settings->set_window_size = true; - - i32 w = (i32)string_to_integer(SCu8(argv[i]), 10); - i32 h = (i32)string_to_integer(SCu8(argv[i + 1]), 10); - if (w > 0){ - plat_settings->window_w = w; - } - if (h > 0){ - plat_settings->window_h = h; - } - - ++i; - } - action = CLAct_Nothing; - }break; - - case CLAct_WindowMaximize: - { - --i; - plat_settings->maximize_window = true; - action = CLAct_Nothing; - }break; - - case CLAct_WindowPosition: - { - if (i + 1 < argc){ - plat_settings->set_window_pos = true; - - i32 x = (i32)string_to_integer(SCu8(argv[i]), 10); - i32 y = (i32)string_to_integer(SCu8(argv[i + 1]), 10); - if (x > 0){ - plat_settings->window_x = x; - } - if (y > 0){ - plat_settings->window_y = y; - } - - ++i; - } - action = CLAct_Nothing; - }break; - - case CLAct_WindowFullscreen: - { - --i; - plat_settings->fullscreen_window = true; - action = CLAct_Nothing; - }break; - - case CLAct_FontSize: - { - if (i < argc){ - settings->font_size = (i32)string_to_integer(SCu8(argv[i]), 10); - } - action = CLAct_Nothing; - }break; - - case CLAct_FontUseHinting: - { - plat_settings->use_hinting = true; - settings->use_hinting = plat_settings->use_hinting; - action = CLAct_Nothing; - }break; - } - }break; - - case CLMode_Custom: - { - settings->custom_flags = argv + i; - settings->custom_flags_count = argc - i; - i = argc; - mode = CLMode_App; - }break; - } - } -} - -//////////////////////////////// - -internal Models* -models_init(void){ - Arena arena = make_arena_system(); - Models *models = push_array_zero(&arena, Models, 1); - models->arena_ = arena; - models->arena = &models->arena_; - heap_init(&models->heap, get_base_allocator_system()); - return(models); -} - -internal void -app_load_vtables(API_VTable_system *vtable_system, API_VTable_font *vtable_font, API_VTable_graphics *vtable_graphics){ - system_api_read_vtable(vtable_system); - font_api_read_vtable(vtable_font); - graphics_api_read_vtable(vtable_graphics); -} - -internal Log_Function* -app_get_logger(void){ - log_init(); - return(log_string); -} - -App_Read_Command_Line_Sig(app_read_command_line){ - Models *models = models_init(); - App_Settings *settings = &models->settings; - block_zero_struct(settings); - if (argc > 1){ - init_command_line_settings(&models->settings, plat_settings, argc, argv); - } - *files = models->settings.init_files; - *file_count = &models->settings.init_files_count; - return(models); -} - -App_Init_Sig(app_init){ - Models *models = (Models*)base_ptr; - models->keep_playing = true; - models->hard_exit = false; - - models->config_api = api; - models->virtual_event_arena = reserve_arena(tctx); - - profile_init(&models->profile_list); - - managed_ids_init(tctx->allocator, &models->managed_id_set); - - API_VTable_custom custom_vtable = {}; - custom_api_fill_vtable(&custom_vtable); - API_VTable_system system_vtable = {}; - system_api_fill_vtable(&system_vtable); - Custom_Layer_Init_Type *custom_init = api.init_apis(&custom_vtable, &system_vtable); - Assert(custom_init != 0); - - // NOTE(allen): coroutines - coroutine_system_init(&models->coroutines); - - // NOTE(allen): font set - font_set_init(&models->font_set); - - // NOTE(allen): live set - Arena *arena = models->arena; - { - models->view_set.count = 0; - models->view_set.max = MAX_VIEWS; - models->view_set.views = push_array(arena, View, models->view_set.max); - - //dll_init_sentinel - models->view_set.free_sentinel.next = &models->view_set.free_sentinel; - models->view_set.free_sentinel.prev = &models->view_set.free_sentinel; - - i32 max = models->view_set.max; - View *view = models->view_set.views; - for (i32 i = 0; i < max; ++i, ++view){ - //dll_insert(&models->view_set.free_sentinel, view); - view->next = models->view_set.free_sentinel.next; - view->prev = &models->view_set.free_sentinel; - models->view_set.free_sentinel.next = view; - view->next->prev = view; - } - } - - lifetime_allocator_init(tctx->allocator, &models->lifetime_allocator); - dynamic_workspace_init(&models->lifetime_allocator, DynamicWorkspace_Global, 0, &models->dynamic_workspace); - - // NOTE(allen): file setup - working_set_init(models, &models->working_set); - Mutex_Lock file_order_lock(models->working_set.mutex); - - // NOTE(allen): - global_history_init(&models->global_history); - text_layout_init(tctx, &models->text_layouts); - - // NOTE(allen): clipboard setup - models->working_set.clipboard_max_size = ArrayCount(models->working_set.clipboards); - models->working_set.clipboard_size = 0; - models->working_set.clipboard_current = 0; - models->working_set.clipboard_rolling = 0; - - // TODO(allen): do(better clipboard allocation) - if (clipboard.str != 0){ - String_Const_u8 *dest = working_set_next_clipboard_string(&models->heap, &models->working_set, clipboard.size); - block_copy(dest->str, clipboard.str, clipboard.size); - } - - // NOTE(allen): style setup - { - Scratch_Block scratch(tctx); - Face_Description description = {}; - description.font.file_name = get_file_path_in_fonts_folder(scratch, string_u8_litexpr("liberation-mono.ttf")); - description.parameters.pt_size = 12; - Face *new_face = font_set_new_face(&models->font_set, &description); - models->global_face_id = new_face->id; - } - - // NOTE(allen): title space - models->has_new_title = true; - models->title_capacity = KB(4); - models->title_space = push_array(arena, char, models->title_capacity); - block_copy(models->title_space, WINDOW_NAME, sizeof(WINDOW_NAME)); - - // NOTE(allen): miscellaneous init - hot_directory_init(arena, &models->hot_directory, current_directory); - child_process_container_init(tctx->allocator, &models->child_processes); - models->period_wakeup_timer = system_wake_up_timer_create(); - - // NOTE(allen): custom layer init - Application_Links app = {}; - app.tctx = tctx; - app.cmd_context = models; - custom_init(&app); - - // NOTE(allen): init baked in buffers - File_Init init_files[] = { - { string_u8_litinit("*messages*"), &models->message_buffer , true , }, - { string_u8_litinit("*scratch*") , &models->scratch_buffer , false, }, - { string_u8_litinit("*log*") , &models->log_buffer , true , }, - { string_u8_litinit("*keyboard*"), &models->keyboard_buffer, true , }, - }; - - Heap *heap = &models->heap; - for (i32 i = 0; i < ArrayCount(init_files); ++i){ - Editing_File *file = working_set_allocate_file(&models->working_set, &models->lifetime_allocator); - buffer_bind_name(tctx, models, arena, &models->working_set, file, init_files[i].name); - - if (init_files[i].ptr != 0){ - *init_files[i].ptr = file; - } - - File_Attributes attributes = {}; - file_create_from_string(tctx, models, file, SCu8(), attributes); - if (init_files[i].read_only){ - file->settings.read_only = true; - history_free(tctx, &file->state.history); - } - - file->settings.never_kill = true; - file_set_unimportant(file, true); - } - - // NOTE(allen): setup first panel - { - Panel *panel = layout_initialize(arena, &models->layout); - View *new_view = live_set_alloc_view(&models->lifetime_allocator, &models->view_set, panel); - view_init(tctx, models, new_view, models->scratch_buffer, models->view_event_handler); - } -} - -App_Step_Sig(app_step){ - Models *models = (Models*)base_ptr; - - Mutex_Lock file_order_lock(models->working_set.mutex); - Scratch_Block scratch(tctx, Scratch_Share); - - models->next_animate_delay = max_u32; - models->animate_next_frame = false; - - // NOTE(allen): per-frame update of models state - begin_frame(target, &models->font_set); - models->target = target; - models->input = input; - - // NOTE(allen): OS clipboard event handling - String_Const_u8 clipboard = input->clipboard; - if (clipboard.str != 0){ - String_Const_u8 *dest = working_set_next_clipboard_string(&models->heap, &models->working_set, clipboard.size); - dest->size = eol_convert_in((char*)dest->str, (char*)clipboard.str, (i32)clipboard.size); - if (input->clipboard_changed){ - co_send_core_event(tctx, models, CoreCode_NewClipboardContents, *dest); - } - } - - // NOTE(allen): reorganizing panels on screen - Vec2_i32 prev_dim = layout_get_root_size(&models->layout); - Vec2_i32 current_dim = V2i32(target->width, target->height); - layout_set_root_size(&models->layout, current_dim); - - // NOTE(allen): update child processes - f32 dt = input->dt; - if (dt > 0){ - Temp_Memory_Block temp(scratch); - - Child_Process_Container *child_processes = &models->child_processes; - Child_Process **processes_to_free = push_array(scratch, Child_Process*, child_processes->active_child_process_count); - i32 processes_to_free_count = 0; - - u32 max = KB(128); - char *dest = push_array(scratch, char, max); - - for (Node *node = child_processes->child_process_active_list.next; - node != &child_processes->child_process_active_list; - node = node->next){ - Child_Process *child_process = CastFromMember(Child_Process, node, node); - - Editing_File *file = child_process->out_file; - CLI_Handles *cli = &child_process->cli; - - // TODO(allen): do(call a 'child process updated hook' let that hook populate the buffer if it so chooses) - - b32 edited_file = false; - u32 amount = 0; - system_cli_begin_update(cli); - if (system_cli_update_step(cli, dest, max, &amount)){ - if (file != 0 && amount > 0){ - amount = eol_in_place_convert_in(dest, amount); - output_file_append(tctx, models, file, SCu8(dest, amount)); - edited_file = true; - } - } - - if (system_cli_end_update(cli)){ - if (file != 0){ - String_Const_u8 str = push_u8_stringf(scratch, "exited with code %d", cli->exit); - output_file_append(tctx, models, file, str); - edited_file = true; - } - processes_to_free[processes_to_free_count++] = child_process; - child_process_set_return_code(models, child_processes, child_process->id, cli->exit); - } - - if (child_process->cursor_at_end && file != 0){ - file_cursor_to_end(tctx, models, file); - } - } - - for (i32 i = 0; i < processes_to_free_count; ++i){ - child_process_free(child_processes, processes_to_free[i]->id); - } - } - - // NOTE(allen): simulated events - Input_List input_list = input->events; - Input_Modifier_Set modifiers = system_get_keyboard_modifiers(scratch); - if (input->mouse.press_l){ - Input_Event event = {}; - event.kind = InputEventKind_MouseButton; - event.mouse.code = MouseCode_Left; - event.mouse.p = input->mouse.p; - event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); - push_input_event(scratch, &input_list, &event); - } - else if (input->mouse.release_l){ - Input_Event event = {}; - event.kind = InputEventKind_MouseButtonRelease; - event.mouse.code = MouseCode_Left; - event.mouse.p = input->mouse.p; - event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); - push_input_event(scratch, &input_list, &event); - } - if (input->mouse.press_r){ - Input_Event event = {}; - event.kind = InputEventKind_MouseButton; - event.mouse.code = MouseCode_Right; - event.mouse.p = input->mouse.p; - event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); - push_input_event(scratch, &input_list, &event); - } - else if (input->mouse.release_r){ - Input_Event event = {}; - event.kind = InputEventKind_MouseButtonRelease; - event.mouse.code = MouseCode_Right; - event.mouse.p = input->mouse.p; - event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); - push_input_event(scratch, &input_list, &event); - } - if (input->mouse.wheel != 0){ - Input_Event event = {}; - event.kind = InputEventKind_MouseWheel; - event.mouse_wheel.value = (f32)(input->mouse.wheel); - event.mouse_wheel.p = input->mouse.p; - event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); - push_input_event(scratch, &input_list, &event); - } - if (input->mouse.p != models->prev_p){ - b32 was_in_window = rect_contains_point(Ri32(0, 0, prev_dim.x, prev_dim.y), models->prev_p); - b32 is_in_window = rect_contains_point(Ri32(0, 0, current_dim.x, current_dim.y), input->mouse.p); - if (is_in_window || was_in_window){ - Input_Event event = {}; - event.kind = InputEventKind_MouseMove; - event.mouse_move.p = input->mouse.p; - event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); - push_input_event(scratch, &input_list, &event); - } - } - if (models->animated_last_frame){ - Input_Event event = {}; - event.kind = InputEventKind_Core; - event.core.code = CoreCode_Animate; - push_input_event(scratch, &input_list, &event); - } - - // NOTE(allen): expose layout - Layout *layout = &models->layout; - - // NOTE(allen): mouse hover status - Panel *mouse_panel = 0; - Panel *divider_panel = 0; - b32 mouse_in_margin = false; - Vec2_i32 mouse = input->mouse.p; - { - for (Panel *panel = layout_get_first_open_panel(layout); - panel != 0; - panel = layout_get_next_open_panel(layout, panel)){ - if (rect_contains_point(panel->rect_full, mouse)){ - mouse_panel = panel; - if (!rect_contains_point(panel->rect_inner, mouse)){ - mouse_in_margin = true; - for (divider_panel = mouse_panel->parent; - divider_panel != 0; - divider_panel = divider_panel->parent){ - if (rect_contains_point(divider_panel->rect_inner, mouse)){ - break; - } - } - } - } - if (mouse_panel != 0){ - break; - } - } - } - - // NOTE(allen): First frame initialization - if (input->first_step){ - Temp_Memory_Block temp(scratch); - - String_Const_u8_Array file_names = {}; - file_names.count = models->settings.init_files_count; - file_names.vals = push_array(scratch, String_Const_u8, file_names.count); - for (i32 i = 0; i < file_names.count; i += 1){ - file_names.vals[i] = SCu8(models->settings.init_files[i]); - } - - String_Const_u8_Array flags = {}; - flags.count = models->settings.custom_flags_count; - flags.vals = push_array(scratch, String_Const_u8, flags.count); - for (i32 i = 0; i < flags.count; i += 1){ - flags.vals[i] = SCu8(models->settings.custom_flags[i]); - } - - Input_Event event = {}; - event.kind = InputEventKind_Core; - event.core.code = CoreCode_Startup; - event.core.flag_strings = flags; - event.core.file_names = file_names; - co_send_event(tctx, models, &event); - } - - // NOTE(allen): consume event stream - Input_Event_Node *input_node = input_list.first; - Input_Event_Node *input_node_next = 0; - for (;; input_node = input_node_next){ - // NOTE(allen): first handle any events coming from the view command - // function queue - Model_View_Command_Function cmd_func = models_pop_view_command_function(models); - if (cmd_func.custom_func != 0){ - View *view = imp_get_view(models, cmd_func.view_id); - if (view != 0){ - input_node_next = input_node; - Input_Event cmd_func_event = {}; - cmd_func_event.kind = InputEventKind_CustomFunction; - cmd_func_event.custom_func = cmd_func.custom_func; - co_send_event(tctx, models, view, &cmd_func_event); - continue; - } - } - - Temp_Memory_Block temp(scratch); - Input_Event *simulated_input = 0; - Input_Event virtual_event = models_pop_virtual_event(scratch, models); - if (virtual_event.kind != InputEventKind_None){ - virtual_event.virtual_event = true; - simulated_input = &virtual_event; - } - else{ - if (input_node == 0){ - break; - } - input_node_next = input_node->next; - simulated_input = &input_node->event; - - if (simulated_input->kind == InputEventKind_TextInsert && simulated_input->text.blocked){ - continue; - } - - // NOTE(allen): record to keyboard history - if (simulated_input->kind == InputEventKind_KeyStroke || - simulated_input->kind == InputEventKind_KeyRelease || - simulated_input->kind == InputEventKind_TextInsert){ - Temp_Memory_Block temp_key_line(scratch); - String_Const_u8 key_line = stringize_keyboard_event(scratch, simulated_input); - output_file_append(tctx, models, models->keyboard_buffer, key_line); - } - } - - b32 event_was_handled = false; - Input_Event *event = simulated_input; - - Panel *active_panel = layout_get_active_panel(layout); - View *view = active_panel->view; - Assert(view != 0); - - switch (models->state){ - case APP_STATE_EDIT: - { - typedef i32 Event_Consume_Rule; - enum{ - EventConsume_None, - EventConsume_BeginResize, - EventConsume_ClickChangeView, - EventConsume_CustomCommand, - }; - - Event_Consume_Rule consume_rule = EventConsume_CustomCommand; - if (match_mouse_code(event, MouseCode_Left) && (divider_panel != 0)){ - consume_rule = EventConsume_BeginResize; - } - else if (match_mouse_code(event, MouseCode_Left) && - mouse_panel != 0 && mouse_panel != active_panel){ - consume_rule = EventConsume_ClickChangeView; - } - - switch (consume_rule){ - case EventConsume_BeginResize: - { - models->state = APP_STATE_RESIZING; - models->resizing_intermediate_panel = divider_panel; - event_was_handled = true; - }break; - - case EventConsume_ClickChangeView: - { - // NOTE(allen): run deactivate command - co_send_core_event(tctx, models, view, CoreCode_ClickDeactivateView); - - layout->active_panel = mouse_panel; - models->animate_next_frame = true; - active_panel = mouse_panel; - view = active_panel->view; - - // NOTE(allen): run activate command - co_send_core_event(tctx, models, view, CoreCode_ClickActivateView); - - event_was_handled = true; - }break; - - case EventConsume_CustomCommand: - { - event_was_handled = co_send_event(tctx, models, view, event); - }break; - } - }break; - - case APP_STATE_RESIZING: - { - Event_Property event_flags = get_event_properties(event); - if (HasFlag(event_flags, EventProperty_AnyKey) || - match_mouse_code_release(event, MouseCode_Left)){ - models->state = APP_STATE_EDIT; - } - else if (event->kind == InputEventKind_MouseMove){ - if (input->mouse.l){ - Panel *split = models->resizing_intermediate_panel; - Range_i32 limits = layout_get_limiting_range_on_split(layout, split); - i32 mouse_position = (split->vertical_split)?(mouse.x):(mouse.y); - mouse_position = clamp(limits.min, mouse_position, limits.max); - layout_set_split_absolute_position(layout, split, mouse_position); - } - else{ - models->state = APP_STATE_EDIT; - } - } - }break; - } - - if (event_was_handled && event->kind == InputEventKind_KeyStroke){ - for (Input_Event *dependent_text = event->key.first_dependent_text; - dependent_text != 0; - dependent_text = dependent_text->text.next_text){ - Assert(dependent_text->kind == InputEventKind_TextInsert); - dependent_text->text.blocked = true; - } - } - } - - linalloc_clear(models->virtual_event_arena); - models->free_virtual_event = 0; - models->first_virtual_event = 0; - models->last_virtual_event = 0; - - // NOTE(allen): send panel size update - if (models->layout.panel_state_dirty){ - models->layout.panel_state_dirty = false; - if (models->buffer_viewer_update != 0){ - Application_Links app = {}; - app.tctx = tctx; - app.cmd_context = models; - models->buffer_viewer_update(&app); - } - } - - // NOTE(allen): dt - f32 literal_dt = 0.f; - u64 now_usecond_stamp = system_now_time(); - if (!input->first_step){ - u64 elapsed_useconds = now_usecond_stamp - models->last_render_usecond_stamp; - literal_dt = (f32)((f64)(elapsed_useconds)/1000000.f); - } - models->last_render_usecond_stamp = now_usecond_stamp; - f32 animation_dt = 0.f; - if (models->animated_last_frame){ - animation_dt = literal_dt; - } - - // NOTE(allen): on the first frame there should be no scrolling - if (input->first_step){ - for (Panel *panel = layout_get_first_open_panel(layout); - panel != 0; - panel = layout_get_next_open_panel(layout, panel)){ - View *view = panel->view; - File_Edit_Positions edit_pos = view_get_edit_pos(view); - edit_pos.scroll.position = view_normalize_buffer_point(tctx, models, view, edit_pos.scroll.target); - block_zero_struct(&edit_pos.scroll.target); - view_set_edit_pos(view, edit_pos); - } - } - - // NOTE(allen): hook for files reloaded - { - Working_Set *working_set = &models->working_set; - Assert(working_set->has_external_mod_sentinel.next != 0); - if (working_set->has_external_mod_sentinel.next != &working_set->has_external_mod_sentinel){ - for (Node *node = working_set->has_external_mod_sentinel.next, *next = 0; - node != &working_set->has_external_mod_sentinel; - node = next){ - next = node->next; - Editing_File *file = CastFromMember(Editing_File, external_mod_node, node); - dll_remove(node); - block_zero_struct(node); - co_send_core_event(tctx, models, CoreCode_FileExternallyModified, file->id); - } - } - } - - // NOTE(allen): if the exit signal has been sent, run the exit hook. - if (!models->keep_playing || input->trying_to_kill){ - co_send_core_event(tctx, models, CoreCode_TryExit); - models->keep_playing = true; - } - - // NOTE(allen): rendering - { - Frame_Info frame = {}; - frame.index = models->frame_counter; - frame.literal_dt = literal_dt; - frame.animation_dt = animation_dt; - - Application_Links app = {}; - app.tctx = tctx; - app.cmd_context = models; - - if (models->tick != 0){ - models->tick(&app, frame); - } - - begin_render_section(target, models->frame_counter, literal_dt, animation_dt); - models->in_render_mode = true; - - Live_Views *live_views = &models->view_set; - for (Node *node = layout->open_panels.next; - node != &layout->open_panels; - node = node->next){ - Panel *panel = CastFromMember(Panel, node, node); - View *view = panel->view; - View_Context_Node *ctx = view->ctx; - if (ctx != 0){ - Render_Caller_Function *render_caller = ctx->ctx.render_caller; - if (render_caller != 0){ - render_caller(&app, frame, view_get_id(live_views, view)); - } - } - } - - models->in_render_mode = false; - end_render_section(target); - } - - // NOTE(allen): flush the log - log_flush(tctx, models); - - // NOTE(allen): set the app_result - Application_Step_Result app_result = {}; - app_result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; - app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr; - - // NOTE(allen): get new window title - if (models->has_new_title){ - models->has_new_title = false; - app_result.has_new_title = true; - app_result.title_string = models->title_space; - } - - // NOTE(allen): get cursor type - if (mouse_panel != 0 && !mouse_in_margin){ - app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; - } - else if (divider_panel != 0){ - if (divider_panel->vertical_split){ - app_result.mouse_cursor_type = APP_MOUSE_CURSOR_LEFTRIGHT; - } - else{ - app_result.mouse_cursor_type = APP_MOUSE_CURSOR_UPDOWN; - } - } - else{ - app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; - } - - models->prev_mouse_panel = mouse_panel; - app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr; - app_result.perform_kill = models->hard_exit; - app_result.animating = models->animate_next_frame; - if (models->animate_next_frame){ - // NOTE(allen): Silence the timer, because we're going to do another frame right away anyways. - system_wake_up_timer_set(models->period_wakeup_timer, max_u32); - } - else{ - // NOTE(allen): Set the timer's wakeup period, possibly to max_u32 thus effectively silencing it. - system_wake_up_timer_set(models->period_wakeup_timer, models->next_animate_delay); - } - - // NOTE(allen): Update Frame to Frame States - models->prev_p = input->mouse.p; - models->animated_last_frame = app_result.animating; - models->frame_counter += 1; - - // end-of-app_step - return(app_result); -} - -extern "C" App_Get_Functions_Sig(app_get_functions){ - App_Functions result = {}; - - result.load_vtables = app_load_vtables; - result.get_logger = app_get_logger; - result.read_command_line = app_read_command_line; - result.init = app_init; - result.step = app_step; - - return(result); -} - -// BOTTOM - +/* + * Mr. 4th Dimention - Allen Webster + * + * 12.12.2014 + * + * Application layer for project codename "4ed" + * + */ + +// TOP + +internal void +init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings, i32 argc, char **argv){ + char *arg = 0; + Command_Line_Mode mode = CLMode_App; + Command_Line_Action action = CLAct_Nothing; + b32 strict = false; + + settings->init_files_max = ArrayCount(settings->init_files); + for (i32 i = 1; i <= argc; ++i){ + if (i == argc){ + arg = ""; + } + else{ + arg = argv[i]; + } + + if (arg[0] == '-' && arg[1] == '-'){ + char *long_arg_name = arg+2; + if (string_match(SCu8(long_arg_name), string_u8_litexpr("custom"))){ + mode = CLMode_Custom; + continue; + } + } + + switch (mode){ + case CLMode_App: + { + switch (action){ + case CLAct_Nothing: + { + if (arg[0] == '-'){ + action = CLAct_Ignore; + switch (arg[1]){ + case 'd': action = CLAct_CustomDLL; strict = false; break; + case 'D': action = CLAct_CustomDLL; strict = true; break; + + case 'i': action = CLAct_InitialFilePosition; break; + + case 'w': action = CLAct_WindowSize; break; + case 'W': action = CLAct_WindowMaximize; break; + case 'p': action = CLAct_WindowPosition; break; + case 'F': action = CLAct_WindowFullscreen; break; + + case 'f': action = CLAct_FontSize; break; + case 'h': action = CLAct_FontUseHinting; --i; break; + } + } + else if (arg[0] != 0){ + if (settings->init_files_count < settings->init_files_max){ + i32 index = settings->init_files_count++; + settings->init_files[index] = arg; + } + } + }break; + + case CLAct_CustomDLL: + { + plat_settings->custom_dll_is_strict = (b8)strict; + if (i < argc){ + plat_settings->custom_dll = argv[i]; + } + action = CLAct_Nothing; + }break; + + case CLAct_InitialFilePosition: + { + if (i < argc){ + settings->initial_line = (i32)string_to_integer(SCu8(argv[i]), 10); + } + action = CLAct_Nothing; + }break; + + case CLAct_WindowSize: + { + if (i + 1 < argc){ + plat_settings->set_window_size = true; + + i32 w = (i32)string_to_integer(SCu8(argv[i]), 10); + i32 h = (i32)string_to_integer(SCu8(argv[i + 1]), 10); + if (w > 0){ + plat_settings->window_w = w; + } + if (h > 0){ + plat_settings->window_h = h; + } + + ++i; + } + action = CLAct_Nothing; + }break; + + case CLAct_WindowMaximize: + { + --i; + plat_settings->maximize_window = true; + action = CLAct_Nothing; + }break; + + case CLAct_WindowPosition: + { + if (i + 1 < argc){ + plat_settings->set_window_pos = true; + + i32 x = (i32)string_to_integer(SCu8(argv[i]), 10); + i32 y = (i32)string_to_integer(SCu8(argv[i + 1]), 10); + if (x > 0){ + plat_settings->window_x = x; + } + if (y > 0){ + plat_settings->window_y = y; + } + + ++i; + } + action = CLAct_Nothing; + }break; + + case CLAct_WindowFullscreen: + { + --i; + plat_settings->fullscreen_window = true; + action = CLAct_Nothing; + }break; + + case CLAct_FontSize: + { + if (i < argc){ + settings->font_size = (i32)string_to_integer(SCu8(argv[i]), 10); + } + action = CLAct_Nothing; + }break; + + case CLAct_FontUseHinting: + { + plat_settings->use_hinting = true; + settings->use_hinting = plat_settings->use_hinting; + action = CLAct_Nothing; + }break; + } + }break; + + case CLMode_Custom: + { + settings->custom_flags = argv + i; + settings->custom_flags_count = argc - i; + i = argc; + mode = CLMode_App; + }break; + } + } +} + +//////////////////////////////// + +internal Models* +models_init(void){ + Arena arena = make_arena_system(); + Models *models = push_array_zero(&arena, Models, 1); + models->arena_ = arena; + models->arena = &models->arena_; + heap_init(&models->heap, get_base_allocator_system()); + return(models); +} + +internal void +app_load_vtables(API_VTable_system *vtable_system, API_VTable_font *vtable_font, API_VTable_graphics *vtable_graphics){ + system_api_read_vtable(vtable_system); + font_api_read_vtable(vtable_font); + graphics_api_read_vtable(vtable_graphics); +} + +internal Log_Function* +app_get_logger(void){ + log_init(); + return(log_string); +} + +App_Read_Command_Line_Sig(app_read_command_line){ + Models *models = models_init(); + App_Settings *settings = &models->settings; + block_zero_struct(settings); + if (argc > 1){ + init_command_line_settings(&models->settings, plat_settings, argc, argv); + } + *files = models->settings.init_files; + *file_count = &models->settings.init_files_count; + return(models); +} + +App_Init_Sig(app_init){ + Models *models = (Models*)base_ptr; + models->keep_playing = true; + models->hard_exit = false; + + models->config_api = api; + models->virtual_event_arena = reserve_arena(tctx); + + profile_init(&models->profile_list); + + managed_ids_init(tctx->allocator, &models->managed_id_set); + + API_VTable_custom custom_vtable = {}; + custom_api_fill_vtable(&custom_vtable); + API_VTable_system system_vtable = {}; + system_api_fill_vtable(&system_vtable); + Custom_Layer_Init_Type *custom_init = api.init_apis(&custom_vtable, &system_vtable); + Assert(custom_init != 0); + + // NOTE(allen): coroutines + coroutine_system_init(&models->coroutines); + + // NOTE(allen): font set + font_set_init(&models->font_set); + + // NOTE(allen): live set + Arena *arena = models->arena; + { + models->view_set.count = 0; + models->view_set.max = MAX_VIEWS; + models->view_set.views = push_array(arena, View, models->view_set.max); + + //dll_init_sentinel + models->view_set.free_sentinel.next = &models->view_set.free_sentinel; + models->view_set.free_sentinel.prev = &models->view_set.free_sentinel; + + i32 max = models->view_set.max; + View *view = models->view_set.views; + for (i32 i = 0; i < max; ++i, ++view){ + //dll_insert(&models->view_set.free_sentinel, view); + view->next = models->view_set.free_sentinel.next; + view->prev = &models->view_set.free_sentinel; + models->view_set.free_sentinel.next = view; + view->next->prev = view; + } + } + + lifetime_allocator_init(tctx->allocator, &models->lifetime_allocator); + dynamic_workspace_init(&models->lifetime_allocator, DynamicWorkspace_Global, 0, &models->dynamic_workspace); + + // NOTE(allen): file setup + working_set_init(models, &models->working_set); + Mutex_Lock file_order_lock(models->working_set.mutex); + + // NOTE(allen): + global_history_init(&models->global_history); + text_layout_init(tctx, &models->text_layouts); + + // NOTE(allen): clipboard setup + models->working_set.clipboard_max_size = ArrayCount(models->working_set.clipboards); + models->working_set.clipboard_size = 0; + models->working_set.clipboard_current = 0; + models->working_set.clipboard_rolling = 0; + + // TODO(allen): do(better clipboard allocation) + if (clipboard.str != 0){ + String_Const_u8 *dest = working_set_next_clipboard_string(&models->heap, &models->working_set, clipboard.size); + block_copy(dest->str, clipboard.str, clipboard.size); + } + + // NOTE(allen): style setup + { + Scratch_Block scratch(tctx); + Face_Description description = {}; + description.font.file_name = get_file_path_in_fonts_folder(scratch, string_u8_litexpr("liberation-mono.ttf")); + description.parameters.pt_size = 12; + Face *new_face = font_set_new_face(&models->font_set, &description); + models->global_face_id = new_face->id; + } + + // NOTE(allen): title space + models->has_new_title = true; + models->title_capacity = KB(4); + models->title_space = push_array(arena, char, models->title_capacity); + block_copy(models->title_space, WINDOW_NAME, sizeof(WINDOW_NAME)); + + // NOTE(allen): miscellaneous init + hot_directory_init(arena, &models->hot_directory, current_directory); + child_process_container_init(tctx->allocator, &models->child_processes); + models->period_wakeup_timer = system_wake_up_timer_create(); + + // NOTE(allen): custom layer init + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + custom_init(&app); + + // NOTE(allen): init baked in buffers + File_Init init_files[] = { + { string_u8_litinit("*messages*"), &models->message_buffer , true , }, + { string_u8_litinit("*scratch*") , &models->scratch_buffer , false, }, + { string_u8_litinit("*log*") , &models->log_buffer , true , }, + { string_u8_litinit("*keyboard*"), &models->keyboard_buffer, true , }, + }; + + Heap *heap = &models->heap; + for (i32 i = 0; i < ArrayCount(init_files); ++i){ + Editing_File *file = working_set_allocate_file(&models->working_set, &models->lifetime_allocator); + buffer_bind_name(tctx, models, arena, &models->working_set, file, init_files[i].name); + + if (init_files[i].ptr != 0){ + *init_files[i].ptr = file; + } + + File_Attributes attributes = {}; + file_create_from_string(tctx, models, file, SCu8(), attributes); + if (init_files[i].read_only){ + file->settings.read_only = true; + history_free(tctx, &file->state.history); + } + + file->settings.never_kill = true; + file_set_unimportant(file, true); + } + + // NOTE(allen): setup first panel + { + Panel *panel = layout_initialize(arena, &models->layout); + View *new_view = live_set_alloc_view(&models->lifetime_allocator, &models->view_set, panel); + view_init(tctx, models, new_view, models->scratch_buffer, models->view_event_handler); + } +} + +App_Step_Sig(app_step){ + Models *models = (Models*)base_ptr; + + Mutex_Lock file_order_lock(models->working_set.mutex); + Scratch_Block scratch(tctx, Scratch_Share); + + models->next_animate_delay = max_u32; + models->animate_next_frame = false; + + // NOTE(allen): per-frame update of models state + begin_frame(target, &models->font_set); + models->target = target; + models->input = input; + + // NOTE(allen): OS clipboard event handling + String_Const_u8 clipboard = input->clipboard; + if (clipboard.str != 0){ + String_Const_u8 *dest = working_set_next_clipboard_string(&models->heap, &models->working_set, clipboard.size); + dest->size = eol_convert_in((char*)dest->str, (char*)clipboard.str, (i32)clipboard.size); + if (input->clipboard_changed){ + co_send_core_event(tctx, models, CoreCode_NewClipboardContents, *dest); + } + } + + // NOTE(allen): reorganizing panels on screen + Vec2_i32 prev_dim = layout_get_root_size(&models->layout); + Vec2_i32 current_dim = V2i32(target->width, target->height); + layout_set_root_size(&models->layout, current_dim); + + // NOTE(allen): update child processes + f32 dt = input->dt; + if (dt > 0){ + Temp_Memory_Block temp(scratch); + + Child_Process_Container *child_processes = &models->child_processes; + Child_Process **processes_to_free = push_array(scratch, Child_Process*, child_processes->active_child_process_count); + i32 processes_to_free_count = 0; + + u32 max = KB(128); + char *dest = push_array(scratch, char, max); + + for (Node *node = child_processes->child_process_active_list.next; + node != &child_processes->child_process_active_list; + node = node->next){ + Child_Process *child_process = CastFromMember(Child_Process, node, node); + + Editing_File *file = child_process->out_file; + CLI_Handles *cli = &child_process->cli; + + // TODO(allen): do(call a 'child process updated hook' let that hook populate the buffer if it so chooses) + + b32 edited_file = false; + u32 amount = 0; + system_cli_begin_update(cli); + if (system_cli_update_step(cli, dest, max, &amount)){ + if (file != 0 && amount > 0){ + amount = eol_in_place_convert_in(dest, amount); + output_file_append(tctx, models, file, SCu8(dest, amount)); + edited_file = true; + } + } + + if (system_cli_end_update(cli)){ + if (file != 0){ + String_Const_u8 str = push_u8_stringf(scratch, "exited with code %d", cli->exit); + output_file_append(tctx, models, file, str); + edited_file = true; + } + processes_to_free[processes_to_free_count++] = child_process; + child_process_set_return_code(models, child_processes, child_process->id, cli->exit); + } + + if (child_process->cursor_at_end && file != 0){ + file_cursor_to_end(tctx, models, file); + } + } + + for (i32 i = 0; i < processes_to_free_count; ++i){ + child_process_free(child_processes, processes_to_free[i]->id); + } + } + + // NOTE(allen): simulated events + Input_List input_list = input->events; + Input_Modifier_Set modifiers = system_get_keyboard_modifiers(scratch); + if (input->mouse.press_l){ + Input_Event event = {}; + event.kind = InputEventKind_MouseButton; + event.mouse.code = MouseCode_Left; + event.mouse.p = input->mouse.p; + event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); + push_input_event(scratch, &input_list, &event); + } + else if (input->mouse.release_l){ + Input_Event event = {}; + event.kind = InputEventKind_MouseButtonRelease; + event.mouse.code = MouseCode_Left; + event.mouse.p = input->mouse.p; + event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); + push_input_event(scratch, &input_list, &event); + } + if (input->mouse.press_r){ + Input_Event event = {}; + event.kind = InputEventKind_MouseButton; + event.mouse.code = MouseCode_Right; + event.mouse.p = input->mouse.p; + event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); + push_input_event(scratch, &input_list, &event); + } + else if (input->mouse.release_r){ + Input_Event event = {}; + event.kind = InputEventKind_MouseButtonRelease; + event.mouse.code = MouseCode_Right; + event.mouse.p = input->mouse.p; + event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); + push_input_event(scratch, &input_list, &event); + } + if (input->mouse.wheel != 0){ + Input_Event event = {}; + event.kind = InputEventKind_MouseWheel; + event.mouse_wheel.value = (f32)(input->mouse.wheel); + event.mouse_wheel.p = input->mouse.p; + event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); + push_input_event(scratch, &input_list, &event); + } + if (input->mouse.p != models->prev_p){ + b32 was_in_window = rect_contains_point(Ri32(0, 0, prev_dim.x, prev_dim.y), models->prev_p); + b32 is_in_window = rect_contains_point(Ri32(0, 0, current_dim.x, current_dim.y), input->mouse.p); + if (is_in_window || was_in_window){ + Input_Event event = {}; + event.kind = InputEventKind_MouseMove; + event.mouse_move.p = input->mouse.p; + event.mouse.modifiers = copy_modifier_set(scratch, &modifiers); + push_input_event(scratch, &input_list, &event); + } + } + if (models->animated_last_frame){ + Input_Event event = {}; + event.kind = InputEventKind_Core; + event.core.code = CoreCode_Animate; + push_input_event(scratch, &input_list, &event); + } + + // NOTE(allen): expose layout + Layout *layout = &models->layout; + + // NOTE(allen): mouse hover status + Panel *mouse_panel = 0; + Panel *divider_panel = 0; + b32 mouse_in_margin = false; + Vec2_i32 mouse = input->mouse.p; + { + for (Panel *panel = layout_get_first_open_panel(layout); + panel != 0; + panel = layout_get_next_open_panel(layout, panel)){ + if (rect_contains_point(panel->rect_full, mouse)){ + mouse_panel = panel; + if (!rect_contains_point(panel->rect_inner, mouse)){ + mouse_in_margin = true; + for (divider_panel = mouse_panel->parent; + divider_panel != 0; + divider_panel = divider_panel->parent){ + if (rect_contains_point(divider_panel->rect_inner, mouse)){ + break; + } + } + } + } + if (mouse_panel != 0){ + break; + } + } + } + + // NOTE(allen): First frame initialization + if (input->first_step){ + Temp_Memory_Block temp(scratch); + + String_Const_u8_Array file_names = {}; + file_names.count = models->settings.init_files_count; + file_names.vals = push_array(scratch, String_Const_u8, file_names.count); + for (i32 i = 0; i < file_names.count; i += 1){ + file_names.vals[i] = SCu8(models->settings.init_files[i]); + } + + String_Const_u8_Array flags = {}; + flags.count = models->settings.custom_flags_count; + flags.vals = push_array(scratch, String_Const_u8, flags.count); + for (i32 i = 0; i < flags.count; i += 1){ + flags.vals[i] = SCu8(models->settings.custom_flags[i]); + } + + Input_Event event = {}; + event.kind = InputEventKind_Core; + event.core.code = CoreCode_Startup; + event.core.flag_strings = flags; + event.core.file_names = file_names; + co_send_event(tctx, models, &event); + } + + // NOTE(allen): consume event stream + Input_Event_Node *input_node = input_list.first; + Input_Event_Node *input_node_next = 0; + for (;; input_node = input_node_next){ + // NOTE(allen): first handle any events coming from the view command + // function queue + Model_View_Command_Function cmd_func = models_pop_view_command_function(models); + if (cmd_func.custom_func != 0){ + View *view = imp_get_view(models, cmd_func.view_id); + if (view != 0){ + input_node_next = input_node; + Input_Event cmd_func_event = {}; + cmd_func_event.kind = InputEventKind_CustomFunction; + cmd_func_event.custom_func = cmd_func.custom_func; + co_send_event(tctx, models, view, &cmd_func_event); + continue; + } + } + + Temp_Memory_Block temp(scratch); + Input_Event *simulated_input = 0; + Input_Event virtual_event = models_pop_virtual_event(scratch, models); + if (virtual_event.kind != InputEventKind_None){ + virtual_event.virtual_event = true; + simulated_input = &virtual_event; + } + else{ + if (input_node == 0){ + break; + } + input_node_next = input_node->next; + simulated_input = &input_node->event; + + if (simulated_input->kind == InputEventKind_TextInsert && simulated_input->text.blocked){ + continue; + } + + // NOTE(allen): record to keyboard history + if (simulated_input->kind == InputEventKind_KeyStroke || + simulated_input->kind == InputEventKind_KeyRelease || + simulated_input->kind == InputEventKind_TextInsert){ + Temp_Memory_Block temp_key_line(scratch); + String_Const_u8 key_line = stringize_keyboard_event(scratch, simulated_input); + output_file_append(tctx, models, models->keyboard_buffer, key_line); + } + } + + b32 event_was_handled = false; + Input_Event *event = simulated_input; + + Panel *active_panel = layout_get_active_panel(layout); + View *view = active_panel->view; + Assert(view != 0); + + switch (models->state){ + case APP_STATE_EDIT: + { + typedef i32 Event_Consume_Rule; + enum{ + EventConsume_None, + EventConsume_BeginResize, + EventConsume_ClickChangeView, + EventConsume_CustomCommand, + }; + + Event_Consume_Rule consume_rule = EventConsume_CustomCommand; + if (match_mouse_code(event, MouseCode_Left) && (divider_panel != 0)){ + consume_rule = EventConsume_BeginResize; + } + else if (match_mouse_code(event, MouseCode_Left) && + mouse_panel != 0 && mouse_panel != active_panel){ + consume_rule = EventConsume_ClickChangeView; + } + + switch (consume_rule){ + case EventConsume_BeginResize: + { + models->state = APP_STATE_RESIZING; + models->resizing_intermediate_panel = divider_panel; + event_was_handled = true; + }break; + + case EventConsume_ClickChangeView: + { + // NOTE(allen): run deactivate command + co_send_core_event(tctx, models, view, CoreCode_ClickDeactivateView); + + layout->active_panel = mouse_panel; + models->animate_next_frame = true; + active_panel = mouse_panel; + view = active_panel->view; + + // NOTE(allen): run activate command + co_send_core_event(tctx, models, view, CoreCode_ClickActivateView); + + event_was_handled = true; + }break; + + case EventConsume_CustomCommand: + { + event_was_handled = co_send_event(tctx, models, view, event); + }break; + } + }break; + + case APP_STATE_RESIZING: + { + Event_Property event_flags = get_event_properties(event); + if (HasFlag(event_flags, EventProperty_AnyKey) || + match_mouse_code_release(event, MouseCode_Left)){ + models->state = APP_STATE_EDIT; + } + else if (event->kind == InputEventKind_MouseMove){ + if (input->mouse.l){ + Panel *split = models->resizing_intermediate_panel; + Range_i32 limits = layout_get_limiting_range_on_split(layout, split); + i32 mouse_position = (split->vertical_split)?(mouse.x):(mouse.y); + mouse_position = clamp(limits.min, mouse_position, limits.max); + layout_set_split_absolute_position(layout, split, mouse_position); + } + else{ + models->state = APP_STATE_EDIT; + } + } + }break; + } + + if (event_was_handled && event->kind == InputEventKind_KeyStroke){ + for (Input_Event *dependent_text = event->key.first_dependent_text; + dependent_text != 0; + dependent_text = dependent_text->text.next_text){ + Assert(dependent_text->kind == InputEventKind_TextInsert); + dependent_text->text.blocked = true; + } + } + } + + linalloc_clear(models->virtual_event_arena); + models->free_virtual_event = 0; + models->first_virtual_event = 0; + models->last_virtual_event = 0; + + // NOTE(allen): send panel size update + if (models->layout.panel_state_dirty){ + models->layout.panel_state_dirty = false; + if (models->buffer_viewer_update != 0){ + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + models->buffer_viewer_update(&app); + } + } + + // NOTE(allen): dt + f32 literal_dt = 0.f; + u64 now_usecond_stamp = system_now_time(); + if (!input->first_step){ + u64 elapsed_useconds = now_usecond_stamp - models->last_render_usecond_stamp; + literal_dt = (f32)((f64)(elapsed_useconds)/1000000.f); + } + models->last_render_usecond_stamp = now_usecond_stamp; + f32 animation_dt = 0.f; + if (models->animated_last_frame){ + animation_dt = literal_dt; + } + + // NOTE(allen): on the first frame there should be no scrolling + if (input->first_step){ + for (Panel *panel = layout_get_first_open_panel(layout); + panel != 0; + panel = layout_get_next_open_panel(layout, panel)){ + View *view = panel->view; + File_Edit_Positions edit_pos = view_get_edit_pos(view); + edit_pos.scroll.position = view_normalize_buffer_point(tctx, models, view, edit_pos.scroll.target); + block_zero_struct(&edit_pos.scroll.target); + view_set_edit_pos(view, edit_pos); + } + } + + // NOTE(allen): hook for files reloaded + { + Working_Set *working_set = &models->working_set; + Assert(working_set->has_external_mod_sentinel.next != 0); + if (working_set->has_external_mod_sentinel.next != &working_set->has_external_mod_sentinel){ + for (Node *node = working_set->has_external_mod_sentinel.next, *next = 0; + node != &working_set->has_external_mod_sentinel; + node = next){ + next = node->next; + Editing_File *file = CastFromMember(Editing_File, external_mod_node, node); + dll_remove(node); + block_zero_struct(node); + co_send_core_event(tctx, models, CoreCode_FileExternallyModified, file->id); + } + } + } + + // NOTE(allen): if the exit signal has been sent, run the exit hook. + if (!models->keep_playing || input->trying_to_kill){ + co_send_core_event(tctx, models, CoreCode_TryExit); + models->keep_playing = true; + } + + // NOTE(allen): rendering + { + Frame_Info frame = {}; + frame.index = models->frame_counter; + frame.literal_dt = literal_dt; + frame.animation_dt = animation_dt; + + Application_Links app = {}; + app.tctx = tctx; + app.cmd_context = models; + + if (models->tick != 0){ + models->tick(&app, frame); + } + + begin_render_section(target, models->frame_counter, literal_dt, animation_dt); + models->in_render_mode = true; + + Live_Views *live_views = &models->view_set; + for (Node *node = layout->open_panels.next; + node != &layout->open_panels; + node = node->next){ + Panel *panel = CastFromMember(Panel, node, node); + View *view = panel->view; + View_Context_Node *ctx = view->ctx; + if (ctx != 0){ + Render_Caller_Function *render_caller = ctx->ctx.render_caller; + if (render_caller != 0){ + render_caller(&app, frame, view_get_id(live_views, view)); + } + } + } + + models->in_render_mode = false; + end_render_section(target); + } + + // NOTE(allen): flush the log + log_flush(tctx, models); + + // NOTE(allen): set the app_result + Application_Step_Result app_result = {}; + app_result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT; + app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr; + + // NOTE(allen): get new window title + if (models->has_new_title){ + models->has_new_title = false; + app_result.has_new_title = true; + app_result.title_string = models->title_space; + } + + // NOTE(allen): get cursor type + if (mouse_panel != 0 && !mouse_in_margin){ + app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; + } + else if (divider_panel != 0){ + if (divider_panel->vertical_split){ + app_result.mouse_cursor_type = APP_MOUSE_CURSOR_LEFTRIGHT; + } + else{ + app_result.mouse_cursor_type = APP_MOUSE_CURSOR_UPDOWN; + } + } + else{ + app_result.mouse_cursor_type = APP_MOUSE_CURSOR_ARROW; + } + + models->prev_mouse_panel = mouse_panel; + app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr; + app_result.perform_kill = models->hard_exit; + app_result.animating = models->animate_next_frame; + if (models->animate_next_frame){ + // NOTE(allen): Silence the timer, because we're going to do another frame right away anyways. + system_wake_up_timer_set(models->period_wakeup_timer, max_u32); + } + else{ + // NOTE(allen): Set the timer's wakeup period, possibly to max_u32 thus effectively silencing it. + system_wake_up_timer_set(models->period_wakeup_timer, models->next_animate_delay); + } + + // NOTE(allen): Update Frame to Frame States + models->prev_p = input->mouse.p; + models->animated_last_frame = app_result.animating; + models->frame_counter += 1; + + // end-of-app_step + return(app_result); +} + +extern "C" App_Get_Functions_Sig(app_get_functions){ + App_Functions result = {}; + + result.load_vtables = app_load_vtables; + result.get_logger = app_get_logger; + result.read_command_line = app_read_command_line; + result.init = app_init; + result.step = app_step; + + return(result); +} + +// BOTTOM + diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 5829cd27..5cbb28de 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -531,8 +531,8 @@ buffer_padded_box_of_pos(Application_Links *app, Buffer_ID buffer_id, f32 width, if (face != 0){ Layout_Function *layout_func = file_get_layout_func(file); result = file_padded_box_of_pos(app->tctx, models, file, - layout_func, width, face, - base_line, pos); + layout_func, width, face, + base_line, pos); } } return(result); @@ -1706,23 +1706,6 @@ view_set_buffer(Application_Links *app, View_ID view_id, Buffer_ID buffer_id, Se return(result); } -// TODO(allen): remove this! -api(custom) function b32 -view_post_fade(Application_Links *app, View_ID view_id, f32 seconds, Range_i64 range, - ARGB_Color color){ - Models *models = (Models*)app->cmd_context; - View *view = imp_get_view(models, view_id); - b32 result = false; - if (api_check_view(view)){ - i64 size = range_size(range); - if (size > 0){ - view_post_paste_effect(view, seconds, (i32)range.start, (i32)size, color); - result = true; - } - } - return(result); -} - api(custom) function b32 view_push_context(Application_Links *app, View_ID view_id, View_Context *ctx){ Models *models = (Models*)app->cmd_context; @@ -2019,7 +2002,7 @@ managed_scope_get_attachment(Application_Links *app, Managed_Scope scope, Manage } else{ #define M \ - "ERROR: scope attachment already exists with a size smaller than the requested size; no attachment pointer can be returned." +"ERROR: scope attachment already exists with a size smaller than the requested size; no attachment pointer can be returned." print_message(app, string_u8_litexpr(M)); #undef M } @@ -2418,7 +2401,7 @@ set_global_face(Application_Links *app, Face_ID id) b32 result = false; Face *face = font_set_face_from_id(&models->font_set, id); if (face != 0){ - models->global_face_id = face->id; + models->global_face_id = face->id; result = true; } return(result); @@ -2861,10 +2844,10 @@ text_layout_create(Application_Links *app, Buffer_ID buffer_id, Rect_f32 rect, B Range_i64 visible_line_number_range = Ii64(buffer_point.line_number, line_number); Range_i64 visible_range = Ii64(buffer_get_first_pos_from_line_number(buffer, visible_line_number_range.min), - buffer_get_last_pos_from_line_number(buffer, visible_line_number_range.max)); + buffer_get_last_pos_from_line_number(buffer, visible_line_number_range.max)); i64 item_count = range_size_inclusive(visible_range); - ARGB_Color *colors_array = push_array_zero(arena, ARGB_Color, item_count); + ARGB_Color *colors_array = push_array_zero(arena, ARGB_Color, item_count); result = text_layout_new(&models->text_layouts, arena, buffer_id, buffer_point, visible_range, visible_line_number_range, rect, colors_array, layout_func); @@ -3022,13 +3005,35 @@ paint_text_color(Application_Links *app, Text_Layout_ID layout_id, Range_i64 ran range.max = clamp_top(range.max, layout->visible_range.max); range.min -= layout->visible_range.min; range.max -= layout->visible_range.min; - ARGB_Color *color_ptr = layout->item_colors + range.min; + ARGB_Color *color_ptr = layout->item_colors + range.min; for (i64 i = range.min; i < range.max; i += 1, color_ptr += 1){ *color_ptr = color; } } } +api(custom) function void +paint_text_color_blend(Application_Links *app, Text_Layout_ID layout_id, Range_i64 range, ARGB_Color color, f32 blend){ + Models *models = (Models*)app->cmd_context; + Rect_f32 result = {}; + Text_Layout *layout = text_layout_get(&models->text_layouts, layout_id); + if (layout != 0){ + range.min = clamp_bot(layout->visible_range.min, range.min); + range.max = clamp_top(range.max, layout->visible_range.max); + range.min -= layout->visible_range.min; + range.max -= layout->visible_range.min; + Vec4_f32 color_v4f32 = unpack_color(color); + Vec4_f32 color_pm_v4f32 = color_v4f32*blend; + f32 neg_blend = 1.f - blend; + ARGB_Color *color_ptr = layout->item_colors + range.min; + for (i64 i = range.min; i < range.max; i += 1, color_ptr += 1){ + Vec4_f32 color_ptr_v4f32 = unpack_color(*color_ptr); + Vec4_f32 blended_v4f32 = color_ptr_v4f32*neg_blend + color_pm_v4f32; + *color_ptr = pack_color(blended_v4f32); + } + } +} + api(custom) function b32 text_layout_free(Application_Links *app, Text_Layout_ID text_layout_id){ Models *models = (Models*)app->cmd_context; diff --git a/4ed_file.h b/4ed_file.h index 1eb82013..8844aad7 100644 --- a/4ed_file.h +++ b/4ed_file.h @@ -24,15 +24,6 @@ struct File_Edit_Positions{ i64 cursor_pos; }; -// TODO(allen): do(replace Text_Effect with IM rendering over time) -struct Text_Effect{ - i64 start; - i64 end; - u32 color; - f32 seconds_down; - f32 seconds_max; -}; - struct Editing_File_Settings{ Layout_Function *layout_func; Face_ID face_id; @@ -62,8 +53,6 @@ struct Editing_File_State{ History history; i32 current_record_index; - Text_Effect paste_effect; - Dirty_State dirty; File_Save_State save_state; diff --git a/4ed_layout.cpp b/4ed_layout.cpp index e64c12da..fd493dee 100644 --- a/4ed_layout.cpp +++ b/4ed_layout.cpp @@ -289,7 +289,7 @@ layout_initialize(Arena *arena, Layout *layout){ Panel *panel = panels; layout->free_panels.next = &panel->node; panel->node.prev = &layout->free_panels; - for (i32 i = 1; i < MAX_VIEWS; i += 1, panel += 1){ + for (i32 i = 1; i < panel_alloc_count; i += 1, panel += 1){ panel[1].node.prev = &panel[0].node; panel[0].node.next = &panel[1].node; } diff --git a/4ed_view.cpp b/4ed_view.cpp index 1d5a2e0b..3a25ea21 100644 --- a/4ed_view.cpp +++ b/4ed_view.cpp @@ -236,13 +236,13 @@ view_relative_xy_of_pos(Thread_Context *tctx, Models *models, View *view, function Rect_f32 view_padded_box_of_pos(Thread_Context *tctx, Models *models, View *view, - i64 base_line, i64 pos){ + i64 base_line, i64 pos){ Editing_File *file = view->file; Face *face = file_get_face(models, file); f32 width = view_width(tctx, models, view); Layout_Function *layout_func = file_get_layout_func(file); return(file_padded_box_of_pos(tctx, models, file, - layout_func, width, face, base_line, pos)); + layout_func, width, face, base_line, pos)); } internal Buffer_Point @@ -441,16 +441,6 @@ view_set_cursor_and_scroll(Thread_Context *tctx, Models *models, View *view, i64 view_set_edit_pos(view, edit_pos); } -internal void -view_post_paste_effect(View *view, f32 seconds, i64 start, i64 size, ARGB_Color color){ - Editing_File *file = view->file; - file->state.paste_effect.start = start; - file->state.paste_effect.end = start + size; - file->state.paste_effect.color = color; - file->state.paste_effect.seconds_down = seconds; - file->state.paste_effect.seconds_max = seconds; -} - //////////////////////////////// internal void @@ -529,7 +519,7 @@ co_handle_request(Models *models, Coroutine *co, Co_Out *out){ Face_Description *description = out->face_description; Face *face = font_set_new_face(&models->font_set, description); Co_In in = {}; - in.face_id = face->id; + in.face_id = (face != 0)?face->id:0; result = coroutine_run(&models->coroutines, co, &in, out); }break; diff --git a/custom/4coder_clipboard.cpp b/custom/4coder_clipboard.cpp index fdb44353..ba37ad61 100644 --- a/custom/4coder_clipboard.cpp +++ b/custom/4coder_clipboard.cpp @@ -4,7 +4,7 @@ // TOP - function b32 +function b32 clipboard_post_buffer_range(Application_Links *app, i32 clipboard_index, Buffer_ID buffer, Range_i64 range){ b32 success = false; Scratch_Block scratch(app); @@ -61,9 +61,8 @@ CUSTOM_DOC("At the cursor, insert the text at the top of the clipboard.") view_set_mark(app, view, seek_pos(pos)); view_set_cursor_and_preferred_x(app, view, seek_pos(pos + (i32)string.size)); - // TODO(allen): Send this to all views. ARGB_Color argb = fcolor_resolve(fcolor_id(defcolor_paste)); - view_post_fade(app, view, 0.667f, Ii64_size(pos, string.size), argb); + buffer_post_fade(app, buffer, 0.667f, Ii64_size(pos, string.size), argb); } } } @@ -99,7 +98,7 @@ CUSTOM_DOC("If the previous command was paste or paste_next, replaces the paste view_set_cursor_and_preferred_x(app, view, seek_pos(pos + string.size)); ARGB_Color argb = fcolor_resolve(fcolor_id(defcolor_paste)); - view_post_fade(app, view, 0.667f, Ii64_size(pos, string.size), argb); + buffer_post_fade(app, buffer, 0.667f, Ii64_size(pos, string.size), argb); } else{ paste(app); @@ -150,9 +149,7 @@ CUSTOM_COMMAND_SIG(multi_paste){ view_set_cursor_and_preferred_x(app, view, seek_pos(range.max + insert_string.size)); ARGB_Color argb = fcolor_resolve(fcolor_id(defcolor_paste)); - view_post_fade(app, view, 0.667f, - Ii64(range.max + 1, range.max + insert_string.size), - argb); + view_post_fade(app, buffer, 0.667f, Ii64(range.max + 1, range.max + insert_string.size), argb); } else{ paste(app); @@ -207,9 +204,8 @@ multi_paste_range(Application_Links *app, View_ID view, Range_i64 range, i32 pas view_set_mark(app, view, seek_pos(finish_range.min)); view_set_cursor_and_preferred_x(app, view, seek_pos(finish_range.max)); - // TODO(allen): Send this to all views. ARGB_Color argb = fcolor_resolve(fcolor_id(defcolor_paste)); - view_post_fade(app, view, 0.667f, finish_range, argb); + buffer_post_fade(app, buffer, 0.667f, finish_range, argb); } } return(finish_range); diff --git a/custom/4coder_default_bindings.cpp b/custom/4coder_default_bindings.cpp index 8d926fa4..fb2f4a03 100644 --- a/custom/4coder_default_bindings.cpp +++ b/custom/4coder_default_bindings.cpp @@ -8,7 +8,11 @@ #define FCODER_DEFAULT_BINDINGS_CPP #include "4coder_default_include.cpp" + +// NOTE(allen): Users can declare their own managed IDs here. + #include "4coder_default_map.cpp" +#include "generated/managed_id_metadata.cpp" void custom_layer_init(Application_Links *app){ diff --git a/custom/4coder_default_framework.cpp b/custom/4coder_default_framework.cpp index c4acc753..28588d3a 100644 --- a/custom/4coder_default_framework.cpp +++ b/custom/4coder_default_framework.cpp @@ -484,7 +484,7 @@ CUSTOM_DOC("Clear the theme list") global_theme_arena = make_arena_system(); } else{ - linalloc_clear(&global_theme_arena); + linalloc_clear(&global_theme_arena); } block_zero_struct(&global_theme_list); @@ -500,13 +500,13 @@ default_4coder_initialize(Application_Links *app, String_Const_u8_Array file_nam heap_init(&global_heap, tctx->allocator); #define M \ - "Welcome to " VERSION "\n" \ - "If you're new to 4coder there are some tutorials at http://4coder.net/tutorials.html\n" \ - "Direct bug reports and feature requests to https://github.com/4coder-editor/4coder/issues\n" \ - "Other questions and discussion can be directed to editor@4coder.net or 4coder.handmade.network\n" \ - "The change log can be found in CHANGES.txt\n" \ - "\n" - print_message(app, string_u8_litexpr(M)); +"Welcome to " VERSION "\n" \ +"If you're new to 4coder there are some tutorials at http://4coder.net/tutorials.html\n" \ +"Direct bug reports and feature requests to https://github.com/4coder-editor/4coder/issues\n" \ +"Other questions and discussion can be directed to editor@4coder.net or 4coder.handmade.network\n" \ +"The change log can be found in CHANGES.txt\n" \ +"\n" + print_message(app, string_u8_litexpr(M)); #undef M #if 0 @@ -529,6 +529,8 @@ default_4coder_initialize(Application_Links *app, String_Const_u8_Array file_nam create_buffer(app, input_name, 0); } } + + fade_range_arena = make_arena_system(KB(8)); } function void @@ -687,5 +689,102 @@ buffer_modified_set_clear(void){ } } +//////////////////////////////// + +function Fade_Range* +alloc_fade_range(void){ + Fade_Range *result = free_fade_ranges; + if (result == 0){ + result = push_array(&fade_range_arena, Fade_Range, 1); + } + else{ + sll_stack_pop(free_fade_ranges); + } + return(result); +} + +function void +free_fade_range(Fade_Range *range){ + sll_stack_push(free_fade_ranges, range); +} + +function void +buffer_post_fade(Application_Links *app, Buffer_ID buffer_id, f32 seconds, Range_i64 range, ARGB_Color color){ + Fade_Range *fade_range = alloc_fade_range(); + sll_queue_push(buffer_fade_ranges.first, buffer_fade_ranges.last, fade_range); + buffer_fade_ranges.count += 1; + fade_range->buffer_id = buffer_id; + fade_range->t = seconds; + fade_range->full_t = seconds; + fade_range->range = range; + fade_range->color= color; +} + +function void +view_post_fade(Application_Links *app, View_ID view_id, f32 seconds, Range_i64 range, ARGB_Color color){ + Fade_Range *fade_range = alloc_fade_range(); + sll_queue_push(view_fade_ranges.first, view_fade_ranges.last, fade_range); + view_fade_ranges.count += 1; + fade_range->view_id = view_id; + fade_range->t = seconds; + fade_range->full_t = seconds; + fade_range->range = range; + fade_range->color= color; +} + +function b32 +tick_all_fade_ranges(f32 t){ + Fade_Range **prev_next = &buffer_fade_ranges.first; + for (Fade_Range *node = buffer_fade_ranges.first, *next = 0; + node != 0; + node = next){ + next = node->next; + node->t -= t; + if (node->t <= 0.f){ + *prev_next = next; + buffer_fade_ranges.count -= 1; + } + else{ + prev_next = &node->next; + } + } + + prev_next = &view_fade_ranges.first; + for (Fade_Range *node = view_fade_ranges.first, *next = 0; + node != 0; + node = next){ + next = node->next; + node->t -= t; + if (node->t <= 0.f){ + *prev_next = next; + view_fade_ranges.count -= 1; + } + else{ + prev_next = &node->next; + } + } + + return(buffer_fade_ranges.count > 0 || view_fade_ranges.count > 0); +} + +function void +paint_fade_ranges(Application_Links *app, Text_Layout_ID layout, Buffer_ID buffer, View_ID view){ + for (Fade_Range *node = buffer_fade_ranges.first; + node != 0; + node = node->next){ + if (node->buffer_id == buffer){ + paint_text_color_blend(app, layout, node->range, node->color, node->t/node->full_t); + } + } + + for (Fade_Range *node = view_fade_ranges.first; + node != 0; + node = node->next){ + if (node->view_id == view){ + paint_text_color_blend(app, layout, node->range, node->color, node->t/node->full_t); + } + } +} + // BOTTOM diff --git a/custom/4coder_default_framework.h b/custom/4coder_default_framework.h index 703a88ad..b1daa3e2 100644 --- a/custom/4coder_default_framework.h +++ b/custom/4coder_default_framework.h @@ -94,6 +94,26 @@ struct Buffer_Modified_Set{ Table_u64_u64 id_to_node; }; +//////////////////////////////// + +struct Fade_Range{ + Fade_Range *next; + union{ + Buffer_ID buffer_id; + View_ID view_id; + }; + f32 t; + f32 full_t; + Range_i64 range; + ARGB_Color color; +}; + +struct Fade_Range_List{ + Fade_Range *first; + Fade_Range *last; + i32 count; +}; + #endif // BOTTOM diff --git a/custom/4coder_default_framework_variables.cpp b/custom/4coder_default_framework_variables.cpp index 859143ff..eebdbfb6 100644 --- a/custom/4coder_default_framework_variables.cpp +++ b/custom/4coder_default_framework_variables.cpp @@ -91,5 +91,12 @@ global Buffer_Modified_Set global_buffer_modified_set = {}; global b32 global_keyboard_macro_is_recording = false; global Range_i64 global_keyboard_macro_range = {}; +//////////////////////////////// + +global Fade_Range_List buffer_fade_ranges = {}; +global Fade_Range_List view_fade_ranges = {}; +global Arena fade_range_arena = {}; +global Fade_Range *free_fade_ranges = 0; + // BOTTOM diff --git a/custom/4coder_default_hooks.cpp b/custom/4coder_default_hooks.cpp index 3824ca00..2444afe1 100644 --- a/custom/4coder_default_hooks.cpp +++ b/custom/4coder_default_hooks.cpp @@ -1,1152 +1,1159 @@ -/* -4coder_default_hooks.cpp - Sets up the hooks for the default framework. -*/ - -// TOP - -CUSTOM_COMMAND_SIG(default_startup) -CUSTOM_DOC("Default command for responding to a startup event") -{ - ProfileScope(app, "default startup"); - User_Input input = get_current_input(app); - if (match_core_code(&input, CoreCode_Startup)){ - String_Const_u8_Array file_names = input.event.core.file_names; - load_themes_default_folder(app); - default_4coder_initialize(app, file_names); - default_4coder_side_by_side_panels(app, file_names); - if (global_config.automatically_load_project){ - load_project(app); - } - } -} - -CUSTOM_COMMAND_SIG(default_try_exit) -CUSTOM_DOC("Default command for responding to a try-exit event") -{ - User_Input input = get_current_input(app); - if (match_core_code(&input, CoreCode_TryExit)){ - b32 do_exit = true; - if (!allow_immediate_close_without_checking_for_changes){ - b32 has_unsaved_changes = false; - for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always); - buffer != 0; - buffer = get_buffer_next(app, buffer, Access_Always)){ - Dirty_State dirty = buffer_get_dirty_state(app, buffer); - if (HasFlag(dirty, DirtyState_UnsavedChanges)){ - has_unsaved_changes = true; - break; - } - } - if (has_unsaved_changes){ - View_ID view = get_active_view(app, Access_Always); - do_exit = do_4coder_close_user_check(app, view); - } - } - if (do_exit){ - hard_exit(app); - } - } -} - -CUSTOM_COMMAND_SIG(default_view_input_handler) -CUSTOM_DOC("Input consumption loop for default view behavior") -{ - Thread_Context *tctx = get_thread_context(app); - Scratch_Block scratch(tctx); - - { - View_ID view = get_this_ctx_view(app, Access_Always); - String_Const_u8 name = push_u8_stringf(scratch, "view %d", view); - - Profile_Global_List *list = get_core_profile_list(app); - ProfileThreadName(tctx, list, name); - - View_Context ctx = view_current_context(app, view); - ctx.mapping = &framework_mapping; - ctx.map_id = mapid_global; - view_alter_context(app, view, &ctx); - } - - for (;;){ - // NOTE(allen): Get the binding from the buffer's current map - User_Input input = get_next_input(app, EventPropertyGroup_Any, 0); - ProfileScopeNamed(app, "before view input", view_input_profile); - if (input.abort){ - break; - } - - Event_Property event_properties = get_event_properties(&input.event); - - if (suppressing_mouse && (event_properties & EventPropertyGroup_AnyMouseEvent) != 0){ - continue; - } - - View_ID view = get_this_ctx_view(app, Access_Always); - - Buffer_ID buffer = view_get_buffer(app, view, Access_Always); - Managed_Scope buffer_scope = buffer_get_managed_scope(app, buffer); - Command_Map_ID *map_id_ptr = scope_attachment(app, buffer_scope, buffer_map_id, Command_Map_ID); - if (*map_id_ptr == 0){ - *map_id_ptr = mapid_file; - } - Command_Map_ID map_id = *map_id_ptr; - - Command_Binding binding = map_get_binding_recursive(&framework_mapping, map_id, &input.event); - - Managed_Scope scope = view_get_managed_scope(app, view); - - if (binding.custom == 0){ - // NOTE(allen): we don't have anything to do with this input, - // leave it marked unhandled so that if there's a follow up - // event it is not blocked. - leave_current_input_unhandled(app); - } - else{ - // NOTE(allen): before the command is called do some book keeping - Rewrite_Type *next_rewrite = - scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); - *next_rewrite = Rewrite_None; - if (fcoder_mode == FCoderMode_NotepadLike){ - for (View_ID view_it = get_view_next(app, 0, Access_Always); - view_it != 0; - view_it = get_view_next(app, view_it, Access_Always)){ - Managed_Scope scope_it = view_get_managed_scope(app, view_it); - b32 *snap_mark_to_cursor = - scope_attachment(app, scope_it, view_snap_mark_to_cursor, - b32); - *snap_mark_to_cursor = true; - } - } - - ProfileCloseNow(view_input_profile); - - // NOTE(allen): call the command - binding.custom(app); - - // NOTE(allen): after the command is called do some book keeping - ProfileScope(app, "after view input"); - - next_rewrite = scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); - if (next_rewrite != 0){ - Rewrite_Type *rewrite = - scope_attachment(app, scope, view_rewrite_loc, Rewrite_Type); - *rewrite = *next_rewrite; - if (fcoder_mode == FCoderMode_NotepadLike){ - for (View_ID view_it = get_view_next(app, 0, Access_Always); - view_it != 0; - view_it = get_view_next(app, view_it, Access_Always)){ - Managed_Scope scope_it = view_get_managed_scope(app, view_it); - b32 *snap_mark_to_cursor = - scope_attachment(app, scope_it, view_snap_mark_to_cursor, b32); - if (*snap_mark_to_cursor){ - i64 pos = view_get_cursor_pos(app, view_it); - view_set_mark(app, view_it, seek_pos(pos)); - } - } - } - } - } - } -} - -function void -default_tick(Application_Links *app, Frame_Info frame_info){ - Scratch_Block scratch(app); - - for (Buffer_Modified_Node *node = global_buffer_modified_set.first; - node != 0; - node = node->next){ - Temp_Memory_Block temp(scratch); - Buffer_ID buffer_id = node->buffer; - - Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); - - String_Const_u8 contents = push_whole_buffer(app, scratch, buffer_id); - Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array); - if (tokens_ptr == 0){ - continue; - } - if (tokens_ptr->count == 0){ - continue; - } - Token_Array tokens = *tokens_ptr; - - Arena arena = make_arena_system(KB(16)); - Code_Index_File *index = push_array_zero(&arena, Code_Index_File, 1); - index->buffer = buffer_id; - - Generic_Parse_State state = {}; - generic_parse_init(app, &arena, contents, &tokens, &state); - // TODO(allen): Actually determine this in a fair way. - // Maybe switch to an enum. - state.do_cpp_parse = true; - generic_parse_full_input_breaks(index, &state, max_i32); - - code_index_lock(); - code_index_set_file(buffer_id, arena, index); - code_index_unlock(); - buffer_clear_layout_cache(app, buffer_id); - } - - buffer_modified_set_clear(); -} - -function Rect_f32 -default_buffer_region(Application_Links *app, View_ID view_id, Rect_f32 region){ - Buffer_ID buffer = view_get_buffer(app, view_id, Access_Always); - Face_ID face_id = get_face_id(app, buffer); - Face_Metrics metrics = get_face_metrics(app, face_id); - f32 line_height = metrics.line_height; - f32 digit_advance = metrics.decimal_digit_advance; - - // NOTE(allen): margins - region = rect_inner(region, 3.f); - - // NOTE(allen): file bar - b64 showing_file_bar = false; - if (view_get_setting(app, view_id, ViewSetting_ShowFileBar, &showing_file_bar) && - showing_file_bar){ - Rect_f32_Pair pair = layout_file_bar_on_top(region, line_height); - region = pair.max; - } - - // NOTE(allen): query bars - { - Query_Bar *space[32]; - Query_Bar_Ptr_Array query_bars = {}; - query_bars.ptrs = space; - if (get_active_query_bars(app, view_id, ArrayCount(space), &query_bars)){ - Rect_f32_Pair pair = layout_query_bar_on_top(region, line_height, query_bars.count); - region = pair.max; - } - } - - // NOTE(allen): FPS hud - if (show_fps_hud){ - Rect_f32_Pair pair = layout_fps_hud_on_bottom(region, line_height); - region = pair.min; - } - - // NOTE(allen): line numbers - if (global_config.show_line_number_margins){ - Rect_f32_Pair pair = layout_line_number_margin(app, buffer, region, digit_advance); - region = pair.max; - } - - return(region); -} - -function void -recursive_nest_highlight(Application_Links *app, Text_Layout_ID layout_id, Range_i64 range, - Code_Index_Nest_Ptr_Array *array, i32 counter){ - Code_Index_Nest **ptr = array->ptrs; - Code_Index_Nest **ptr_end = ptr + array->count; - - for (;ptr < ptr_end; ptr += 1){ - Code_Index_Nest *nest = *ptr; - if (!nest->is_closed){ - break; - } - if (range.first <= nest->close.max){ - break; - } - } - - ARGB_Color argb = finalize_color(defcolor_text_cycle, counter); - - for (;ptr < ptr_end; ptr += 1){ - Code_Index_Nest *nest = *ptr; - if (range.max <= nest->open.min){ - break; - } - - paint_text_color(app, layout_id, nest->open, argb); - if (nest->is_closed){ - paint_text_color(app, layout_id, nest->close, argb); - } - recursive_nest_highlight(app, layout_id, range, &nest->nest_array, counter + 1); - } -} - -function void -recursive_nest_highlight(Application_Links *app, Text_Layout_ID layout_id, Range_i64 range, - Code_Index_File *file){ - recursive_nest_highlight(app, layout_id, range, &file->nest_array, 0); -} - -function void -default_render_buffer(Application_Links *app, View_ID view_id, Face_ID face_id, - Buffer_ID buffer, Text_Layout_ID text_layout_id, - Rect_f32 rect){ - ProfileScope(app, "render buffer"); - - View_ID active_view = get_active_view(app, Access_Always); - b32 is_active_view = (active_view == view_id); - Rect_f32 prev_clip = draw_set_clip(app, rect); - - // NOTE(allen): Token colorizing - Token_Array token_array = get_token_array_from_buffer(app, buffer); - if (token_array.tokens != 0){ - draw_cpp_token_colors(app, text_layout_id, &token_array); - - // NOTE(allen): Scan for TODOs and NOTEs - if (global_config.use_comment_keyword){ - Comment_Highlight_Pair pairs[] = { - {string_u8_litexpr("NOTE"), finalize_color(defcolor_comment_pop, 0)}, - {string_u8_litexpr("TODO"), finalize_color(defcolor_comment_pop, 1)}, - }; - draw_comment_highlights(app, buffer, text_layout_id, - &token_array, pairs, ArrayCount(pairs)); - } - } - else{ - Range_i64 visible_range = text_layout_get_visible_range(app, text_layout_id); - paint_text_color_fcolor(app, text_layout_id, visible_range, fcolor_id(defcolor_text_default)); - } - - i64 cursor_pos = view_correct_cursor(app, view_id); - view_correct_mark(app, view_id); - - // NOTE(allen): Scope highlight - if (global_config.use_scope_highlight){ - Color_Array colors = finalize_color_array(defcolor_back_cycle); - draw_scope_highlight(app, buffer, text_layout_id, cursor_pos, colors.vals, colors.count); - } - - if (global_config.use_error_highlight || global_config.use_jump_highlight){ - // NOTE(allen): Error highlight - String_Const_u8 name = string_u8_litexpr("*compilation*"); - Buffer_ID compilation_buffer = get_buffer_by_name(app, name, Access_Always); - if (global_config.use_error_highlight){ - draw_jump_highlights(app, buffer, text_layout_id, compilation_buffer, - fcolor_id(defcolor_highlight_junk)); - } - - // NOTE(allen): Search highlight - if (global_config.use_jump_highlight){ - Buffer_ID jump_buffer = get_locked_jump_buffer(app); - if (jump_buffer != compilation_buffer){ - draw_jump_highlights(app, buffer, text_layout_id, jump_buffer, - fcolor_id(defcolor_highlight_white)); - } - } - } - - // NOTE(allen): Color parens - if (global_config.use_paren_helper){ - Color_Array colors = finalize_color_array(defcolor_text_cycle); - draw_paren_highlight(app, buffer, text_layout_id, cursor_pos, colors.vals, colors.count); - } - - // NOTE(allen): Line highlight - if (global_config.highlight_line_at_cursor && is_active_view){ - i64 line_number = get_line_number_from_pos(app, buffer, cursor_pos); - draw_line_highlight(app, text_layout_id, line_number, - fcolor_id(defcolor_highlight_cursor_line)); - } - - // NOTE(allen): Cursor shape - Face_Metrics metrics = get_face_metrics(app, face_id); - f32 cursor_roundness = (metrics.normal_advance*0.5f)*0.9f; - f32 mark_thickness = 2.f; - - // NOTE(allen): Cursor - switch (fcoder_mode){ - case FCoderMode_Original: - { - draw_original_4coder_style_cursor_mark_highlight(app, view_id, is_active_view, buffer, text_layout_id, cursor_roundness, mark_thickness); - }break; - case FCoderMode_NotepadLike: - { - draw_notepad_style_cursor_highlight(app, view_id, buffer, text_layout_id, cursor_roundness); - }break; - } - - // NOTE(allen): put the actual text on the actual screen - draw_text_layout_default(app, text_layout_id); - - draw_set_clip(app, prev_clip); -} - -function void -default_render_caller(Application_Links *app, Frame_Info frame_info, View_ID view_id){ - ProfileScope(app, "default render caller"); - View_ID active_view = get_active_view(app, Access_Always); - b32 is_active_view = (active_view == view_id); - - Rect_f32 region = draw_background_and_margin(app, view_id, is_active_view); - Rect_f32 prev_clip = draw_set_clip(app, region); - - Buffer_ID buffer = view_get_buffer(app, view_id, Access_Always); - Face_ID face_id = get_face_id(app, buffer); - Face_Metrics face_metrics = get_face_metrics(app, face_id); - f32 line_height = face_metrics.line_height; - f32 digit_advance = face_metrics.decimal_digit_advance; - - // NOTE(allen): file bar - b64 showing_file_bar = false; - if (view_get_setting(app, view_id, ViewSetting_ShowFileBar, &showing_file_bar) && showing_file_bar){ - Rect_f32_Pair pair = layout_file_bar_on_top(region, line_height); - draw_file_bar(app, view_id, buffer, face_id, pair.min); - region = pair.max; - } - - Buffer_Scroll scroll = view_get_buffer_scroll(app, view_id); - - Buffer_Point_Delta_Result delta = delta_apply(app, view_id, - frame_info.animation_dt, scroll); - if (!block_match_struct(&scroll.position, &delta.point)){ - block_copy_struct(&scroll.position, &delta.point); - view_set_buffer_scroll(app, view_id, scroll, SetBufferScroll_NoCursorChange); - } - if (delta.still_animating){ - animate_in_n_milliseconds(app, 0); - } - - // NOTE(allen): query bars - { - Query_Bar *space[32]; - Query_Bar_Ptr_Array query_bars = {}; - query_bars.ptrs = space; - if (get_active_query_bars(app, view_id, ArrayCount(space), &query_bars)){ - for (i32 i = 0; i < query_bars.count; i += 1){ - Rect_f32_Pair pair = layout_query_bar_on_top(region, line_height, 1); - draw_query_bar(app, query_bars.ptrs[i], face_id, pair.min); - region = pair.max; - } - } - } - - // NOTE(allen): FPS hud - if (show_fps_hud){ - Rect_f32_Pair pair = layout_fps_hud_on_bottom(region, line_height); - draw_fps_hud(app, frame_info, face_id, pair.max); - region = pair.min; - animate_in_n_milliseconds(app, 1000); - } - - // NOTE(allen): layout line numbers - Rect_f32 line_number_rect = {}; - if (global_config.show_line_number_margins){ - Rect_f32_Pair pair = layout_line_number_margin(app, buffer, region, digit_advance); - line_number_rect = pair.min; - region = pair.max; - } - - // NOTE(allen): begin buffer render - Buffer_Point buffer_point = scroll.position; - Text_Layout_ID text_layout_id = text_layout_create(app, buffer, region, buffer_point); - - // NOTE(allen): draw line numbers - if (global_config.show_line_number_margins){ - draw_line_number_margin(app, view_id, buffer, face_id, text_layout_id, line_number_rect); - } - - // NOTE(allen): draw the buffer - default_render_buffer(app, view_id, face_id, buffer, text_layout_id, region); - - text_layout_free(app, text_layout_id); - draw_set_clip(app, prev_clip); -} - -HOOK_SIG(default_view_adjust){ - // NOTE(allen): Called whenever the view layout/sizes have been modified, - // including by full window resize. - return(0); -} - -BUFFER_NAME_RESOLVER_SIG(default_buffer_name_resolution){ - ProfileScope(app, "default buffer name resolution"); - if (conflict_count > 1){ - // List of unresolved conflicts - Scratch_Block scratch(app); - - i32 *unresolved = push_array(scratch, i32, conflict_count); - i32 unresolved_count = conflict_count; - for (i32 i = 0; i < conflict_count; ++i){ - unresolved[i] = i; - } - - // Resolution Loop - i32 x = 0; - for (;;){ - // Resolution Pass - ++x; - for (i32 i = 0; i < unresolved_count; ++i){ - i32 conflict_index = unresolved[i]; - Buffer_Name_Conflict_Entry *conflict = &conflicts[conflict_index]; - - u64 size = conflict->base_name.size; - size = clamp_top(size, conflict->unique_name_capacity); - conflict->unique_name_len_in_out = size; - block_copy(conflict->unique_name_in_out, conflict->base_name.str, size); - - if (conflict->file_name.str != 0){ - Temp_Memory_Block temp(scratch); - String_Const_u8 uniqueifier = {}; - - String_Const_u8 file_name = string_remove_last_folder(conflict->file_name); - if (file_name.size > 0){ - file_name = string_chop(file_name, 1); - u8 *end = file_name.str + file_name.size; - b32 past_the_end = false; - for (i32 j = 0; j < x; ++j){ - file_name = string_remove_last_folder(file_name); - if (j + 1 < x){ - file_name = string_chop(file_name, 1); - } - if (file_name.size == 0){ - if (j + 1 < x){ - past_the_end = true; - } - break; - } - } - u8 *start = file_name.str + file_name.size; - - uniqueifier = SCu8(start, end); - if (past_the_end){ - uniqueifier = push_u8_stringf(scratch, "%.*s~%d", - string_expand(uniqueifier), i); - } - } - else{ - uniqueifier = push_u8_stringf(scratch, "%d", i); - } - - String_u8 builder = Su8(conflict->unique_name_in_out, - conflict->unique_name_len_in_out, - conflict->unique_name_capacity); - string_append(&builder, string_u8_litexpr(" <")); - string_append(&builder, uniqueifier); - string_append(&builder, string_u8_litexpr(">")); - conflict->unique_name_len_in_out = builder.size; - } - } - - // Conflict Check Pass - b32 has_conflicts = false; - for (i32 i = 0; i < unresolved_count; ++i){ - i32 conflict_index = unresolved[i]; - Buffer_Name_Conflict_Entry *conflict = &conflicts[conflict_index]; - String_Const_u8 conflict_name = SCu8(conflict->unique_name_in_out, - conflict->unique_name_len_in_out); - - b32 hit_conflict = false; - if (conflict->file_name.str != 0){ - for (i32 j = 0; j < unresolved_count; ++j){ - if (i == j) continue; - - i32 conflict_j_index = unresolved[j]; - Buffer_Name_Conflict_Entry *conflict_j = &conflicts[conflict_j_index]; - - String_Const_u8 conflict_name_j = SCu8(conflict_j->unique_name_in_out, - conflict_j->unique_name_len_in_out); - - if (string_match(conflict_name, conflict_name_j)){ - hit_conflict = true; - break; - } - } - } - - if (hit_conflict){ - has_conflicts = true; - } - else{ - --unresolved_count; - unresolved[i] = unresolved[unresolved_count]; - --i; - } - } - - if (!has_conflicts){ - break; - } - } - } -} - -function void -parse_async__inner(Async_Context *actx, Buffer_ID buffer_id, - String_Const_u8 contents, Token_Array *tokens, i32 limit_factor){ - Application_Links *app = actx->app; - ProfileBlock(app, "async parse"); - - Arena arena = make_arena_system(KB(16)); - Code_Index_File *index = push_array_zero(&arena, Code_Index_File, 1); - index->buffer = buffer_id; - - Generic_Parse_State state = {}; - generic_parse_init(app, &arena, contents, tokens, &state); - - b32 canceled = false; - - for (;;){ - if (generic_parse_full_input_breaks(index, &state, limit_factor)){ - break; - } - if (async_check_canceled(actx)){ - canceled = true; - break; - } - } - - if (!canceled){ - Thread_Context *tctx = get_thread_context(app); - system_acquire_global_frame_mutex(tctx); - code_index_lock(); - code_index_set_file(buffer_id, arena, index); - code_index_unlock(); - buffer_clear_layout_cache(app, buffer_id); - system_release_global_frame_mutex(tctx); - } - else{ - linalloc_clear(&arena); - } -} - -function void -do_full_lex_async__inner(Async_Context *actx, Buffer_ID buffer_id){ - Application_Links *app = actx->app; - ProfileScope(app, "async lex"); - Thread_Context *tctx = get_thread_context(app); - Scratch_Block scratch(tctx); - - String_Const_u8 contents = {}; - { - ProfileBlock(app, "async lex contents (before mutex)"); - system_acquire_global_frame_mutex(tctx); - ProfileBlock(app, "async lex contents (after mutex)"); - contents = push_whole_buffer(app, scratch, buffer_id); - system_release_global_frame_mutex(tctx); - } - - i32 limit_factor = 10000; - - Token_List list = {}; - b32 canceled = false; - - Lex_State_Cpp state = {}; - lex_full_input_cpp_init(&state, contents); - for (;;){ - ProfileBlock(app, "async lex block"); - if (lex_full_input_cpp_breaks(scratch, &list, &state, limit_factor)){ - break; - } - if (async_check_canceled(actx)){ - canceled = true; - break; - } - } - - if (!canceled){ - ProfileBlock(app, "async lex save results (before mutex)"); - system_acquire_global_frame_mutex(tctx); - ProfileBlock(app, "async lex save results (after mutex)"); - Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); - if (scope != 0){ - Base_Allocator *allocator = managed_scope_allocator(app, scope); - Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, - Token_Array); - base_free(allocator, tokens_ptr->tokens); - Token_Array tokens = {}; - tokens.tokens = base_array(allocator, Token, list.total_count); - tokens.count = list.total_count; - tokens.max = list.total_count; - token_fill_memory_from_list(tokens.tokens, &list); - block_copy_struct(tokens_ptr, &tokens); - } - buffer_mark_as_modified(buffer_id); - system_release_global_frame_mutex(tctx); - } -} - -function void -do_full_lex_async(Async_Context *actx, Data data){ - if (data.size == sizeof(Buffer_ID)){ - Buffer_ID buffer = *(Buffer_ID*)data.data; - do_full_lex_async__inner(actx, buffer); - } -} - -#if 0 -function void -do_full_lex_and_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){ - Application_Links *app = actx->app; - ProfileScope(app, "async lex"); - Thread_Context *tctx = get_thread_context(app); - Scratch_Block scratch(tctx); - - String_Const_u8 contents = {}; - { - ProfileBlock(app, "async lex contents (before mutex)"); - system_acquire_global_frame_mutex(tctx); - ProfileBlock(app, "async lex contents (after mutex)"); - - Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); - if (scope != 0){ - Base_Allocator *allocator = managed_scope_allocator(app, scope); - Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, - Token_Array); - base_free(allocator, tokens_ptr->tokens); - block_zero_struct(tokens_ptr); - } - - contents = push_whole_buffer(app, scratch, buffer_id); - system_release_global_frame_mutex(tctx); - } - - i32 limit_factor = 10000; - - Token_List list = {}; - b32 canceled = false; - - { - Lex_State_Cpp state = {}; - lex_full_input_cpp_init(&state, contents); - for (;;){ - ProfileBlock(app, "async lex block"); - if (lex_full_input_cpp_breaks(scratch, &list, &state, limit_factor)){ - break; - } - if (async_check_canceled(actx)){ - canceled = true; - break; - } - } - } - - Token_Array tokens = {}; - if (!canceled){ - ProfileBlock(app, "async lex save results (before mutex)"); - system_acquire_global_frame_mutex(tctx); - ProfileBlock(app, "async lex save results (after mutex)"); - Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); - if (scope != 0){ - Base_Allocator *allocator = managed_scope_allocator(app, scope); - Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, - Token_Array); - base_free(allocator, tokens_ptr->tokens); - tokens.tokens = base_array(allocator, Token, list.total_count); - tokens.count = list.total_count; - tokens.max = list.total_count; - token_fill_memory_from_list(tokens.tokens, &list); - block_copy_struct(tokens_ptr, &tokens); - } - system_release_global_frame_mutex(tctx); - } - - if (tokens.count > 0){ - parse_async__inner(actx, buffer_id, contents, &tokens, limit_factor); - } -} - -function void -do_full_lex_and_parse_async(Async_Context *actx, Data data){ - if (data.size == sizeof(Buffer_ID)){ - Buffer_ID buffer = *(Buffer_ID*)data.data; - do_full_lex_and_parse_async__inner(actx, buffer); - } -} -#endif - -#if 0 -function void -do_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){ - Application_Links *app = actx->app; - ProfileScope(app, "async lex"); - Thread_Context *tctx = get_thread_context(app); - Scratch_Block scratch(tctx); - - String_Const_u8 contents = {}; - Token_Array tokens = {}; - { - ProfileBlock(app, "async parse contents (before mutex)"); - system_acquire_global_frame_mutex(tctx); - ProfileBlock(app, "async parse contents (after mutex)"); - - Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); - if (scope != 0){ - Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, - Token_Array); - tokens.count = tokens_ptr->count; - tokens.tokens = push_array_write(scratch, Token, tokens.count, tokens_ptr->tokens); - if (tokens.count > 0){ - contents = push_whole_buffer(app, scratch, buffer_id); - } - } - - system_release_global_frame_mutex(tctx); - } - - i32 limit_factor = 10000; - - if (tokens.count > 0){ - parse_async__inner(actx, buffer_id, contents, &tokens, limit_factor); - } -} - -function void -do_parse_async(Async_Context *actx, Data data){ - if (data.size == sizeof(Buffer_ID)){ - Buffer_ID buffer = *(Buffer_ID*)data.data; - do_parse_async__inner(actx, buffer); - } -} -#endif - -BUFFER_HOOK_SIG(default_begin_buffer){ - ProfileScope(app, "begin buffer"); - - Scratch_Block scratch(app); - - b32 treat_as_code = false; - String_Const_u8 file_name = push_buffer_file_name(app, scratch, buffer_id); - if (file_name.size > 0){ - String_Const_u8_Array extensions = global_config.code_exts; - String_Const_u8 ext = string_file_extension(file_name); - for (i32 i = 0; i < extensions.count; ++i){ - if (string_match(ext, extensions.strings[i])){ - - if (string_match(ext, string_u8_litexpr("cpp")) || - string_match(ext, string_u8_litexpr("h")) || - string_match(ext, string_u8_litexpr("c")) || - string_match(ext, string_u8_litexpr("hpp")) || - string_match(ext, string_u8_litexpr("cc"))){ - treat_as_code = true; - } - -#if 0 - treat_as_code = true; - - if (string_match(ext, string_u8_litexpr("cs"))){ - if (parse_context_language_cs == 0){ - init_language_cs(app); - } - parse_context_id = parse_context_language_cs; - } - - if (string_match(ext, string_u8_litexpr("java"))){ - if (parse_context_language_java == 0){ - init_language_java(app); - } - parse_context_id = parse_context_language_java; - } - - if (string_match(ext, string_u8_litexpr("rs"))){ - if (parse_context_language_rust == 0){ - init_language_rust(app); - } - parse_context_id = parse_context_language_rust; - } - - if (string_match(ext, string_u8_litexpr("cpp")) || - string_match(ext, string_u8_litexpr("h")) || - string_match(ext, string_u8_litexpr("c")) || - string_match(ext, string_u8_litexpr("hpp")) || - string_match(ext, string_u8_litexpr("cc"))){ - if (parse_context_language_cpp == 0){ - init_language_cpp(app); - } - parse_context_id = parse_context_language_cpp; - } - - // TODO(NAME): Real GLSL highlighting - if (string_match(ext, string_u8_litexpr("glsl"))){ - if (parse_context_language_cpp == 0){ - init_language_cpp(app); - } - parse_context_id = parse_context_language_cpp; - } - - // TODO(NAME): Real Objective-C highlighting - if (string_match(ext, string_u8_litexpr("m"))){ - if (parse_context_language_cpp == 0){ - init_language_cpp(app); - } - parse_context_id = parse_context_language_cpp; - } -#endif - - break; - } - } - } - - Command_Map_ID map_id = (treat_as_code)?(mapid_code):(mapid_file); - Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); - Command_Map_ID *map_id_ptr = scope_attachment(app, scope, buffer_map_id, Command_Map_ID); - *map_id_ptr = map_id; - - Line_Ending_Kind setting = guess_line_ending_kind_from_buffer(app, buffer_id); - Line_Ending_Kind *eol_setting = scope_attachment(app, scope, buffer_eol_setting, Line_Ending_Kind); - *eol_setting = setting; - - // NOTE(allen): Decide buffer settings - b32 wrap_lines = true; - b32 use_virtual_whitespace = false; - b32 use_lexer = false; - if (treat_as_code){ - wrap_lines = global_config.enable_code_wrapping; - use_virtual_whitespace = global_config.enable_virtual_whitespace; - use_lexer = true; - } - - String_Const_u8 buffer_name = push_buffer_base_name(app, scratch, buffer_id); - if (string_match(buffer_name, string_u8_litexpr("*compilation*"))){ - wrap_lines = false; - } - - if (use_lexer){ - ProfileBlock(app, "begin buffer kick off lexer"); - Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task); - *lex_task_ptr = async_task_no_dep(&global_async_system, do_full_lex_async, make_data_struct(&buffer_id)); - } - - { - b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32); - *wrap_lines_ptr = wrap_lines; - } - - if (use_virtual_whitespace){ - if (use_lexer){ - buffer_set_layout(app, buffer_id, layout_virt_indent_index_generic); - } - else{ - buffer_set_layout(app, buffer_id, layout_virt_indent_literal_generic); - } - } - else{ - buffer_set_layout(app, buffer_id, layout_generic); - } - - // no meaning for return - return(0); -} - -BUFFER_HOOK_SIG(default_new_file){ - Scratch_Block scratch(app); - String_Const_u8 file_name = push_buffer_base_name(app, scratch, buffer_id); - if (!string_match(string_postfix(file_name, 2), string_u8_litexpr(".h"))) { - return(0); - } - - List_String_Const_u8 guard_list = {}; - for (u64 i = 0; i < file_name.size; ++i){ - u8 c[2] = {}; - u64 c_size = 1; - u8 ch = file_name.str[i]; - if (ch == '.'){ - c[0] = '_'; - } - else if (ch >= 'A' && ch <= 'Z'){ - c_size = 2; - c[0] = '_'; - c[1] = ch; - } - else if (ch >= 'a' && ch <= 'z'){ - c[0] = ch - ('a' - 'A'); - } - String_Const_u8 part = push_string_copy(scratch, SCu8(c, c_size)); - string_list_push(scratch, &guard_list, part); - } - String_Const_u8 guard = string_list_flatten(scratch, guard_list); - - Buffer_Insertion insert = begin_buffer_insertion_at_buffered(app, buffer_id, 0, scratch, KB(16)); - insertf(&insert, - "#ifndef %.*s\n" - "#define %.*s\n" - "\n" - "#endif //%.*s\n", - string_expand(guard), - string_expand(guard), - string_expand(guard)); - end_buffer_insertion(&insert); - - return(0); -} - -BUFFER_HOOK_SIG(default_file_save){ - // buffer_id - ProfileScope(app, "default file save"); - b32 is_virtual = global_config.enable_virtual_whitespace; - if (global_config.automatically_indent_text_on_save && is_virtual){ - auto_indent_buffer(app, buffer_id, buffer_range(app, buffer_id)); - } - - Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); - Line_Ending_Kind *eol = scope_attachment(app, scope, buffer_eol_setting, - Line_Ending_Kind); - switch (*eol){ - case LineEndingKind_LF: - { - rewrite_lines_to_lf(app, buffer_id); - }break; - case LineEndingKind_CRLF: - { - rewrite_lines_to_crlf(app, buffer_id); - }break; - } - - // no meaning for return - return(0); -} - -BUFFER_EDIT_RANGE_SIG(default_buffer_edit_range){ - // buffer_id, new_range, original_size - ProfileScope(app, "default edit range"); - - Range_i64 old_range = Ii64(new_range.first, new_range.first + original_size); - - { - code_index_lock(); - Code_Index_File *file = code_index_get_file(buffer_id); - if (file != 0){ - code_index_shift(file, old_range, range_size(new_range)); - } - code_index_unlock(); - } - - i64 insert_size = range_size(new_range); - i64 text_shift = replace_range_shift(old_range, insert_size); - - Scratch_Block scratch(app); - - Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); - Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task); - - Base_Allocator *allocator = managed_scope_allocator(app, scope); - b32 do_full_relex = false; - - if (async_task_is_running_or_pending(&global_async_system, *lex_task_ptr)){ - async_task_cancel(&global_async_system, *lex_task_ptr); - buffer_unmark_as_modified(buffer_id); - do_full_relex = true; - *lex_task_ptr = 0; - } - - Token_Array *ptr = scope_attachment(app, scope, attachment_tokens, Token_Array); - if (ptr != 0 && ptr->tokens != 0){ - ProfileBlockNamed(app, "attempt resync", profile_attempt_resync); - - i64 token_index_first = token_relex_first(ptr, old_range.first, 1); - i64 token_index_resync_guess = - token_relex_resync(ptr, old_range.one_past_last, 16); - - if (token_index_resync_guess - token_index_first >= 4000){ - do_full_relex = true; - } - else{ - Token *token_first = ptr->tokens + token_index_first; - Token *token_resync = ptr->tokens + token_index_resync_guess; - - Range_i64 relex_range = Ii64(token_first->pos, token_resync->pos + token_resync->size + text_shift); - String_Const_u8 partial_text = push_buffer_range(app, scratch, buffer_id, relex_range); - - Token_List relex_list = lex_full_input_cpp(scratch, partial_text); - if (relex_range.one_past_last < buffer_get_size(app, buffer_id)){ - token_drop_eof(&relex_list); - } - - Token_Relex relex = token_relex(relex_list, relex_range.first - text_shift, ptr->tokens, token_index_first, token_index_resync_guess); - - ProfileCloseNow(profile_attempt_resync); - - if (!relex.successful_resync){ - do_full_relex = true; - } - else{ - ProfileBlock(app, "apply resync"); - - i64 token_index_resync = relex.first_resync_index; - - Range_i64 head = Ii64(0, token_index_first); - Range_i64 replaced = Ii64(token_index_first, token_index_resync); - Range_i64 tail = Ii64(token_index_resync, ptr->count); - i64 resynced_count = (token_index_resync_guess + 1) - token_index_resync; - i64 relexed_count = relex_list.total_count - resynced_count; - i64 tail_shift = relexed_count - (token_index_resync - token_index_first); - - i64 new_tokens_count = ptr->count + tail_shift; - Token *new_tokens = base_array(allocator, Token, new_tokens_count); - - Token *old_tokens = ptr->tokens; - block_copy_array_shift(new_tokens, old_tokens, head, 0); - token_fill_memory_from_list(new_tokens + replaced.first, &relex_list, relexed_count); - for (i64 i = 0, index = replaced.first; i < relexed_count; i += 1, index += 1){ - new_tokens[index].pos += relex_range.first; - } - for (i64 i = tail.first; i < tail.one_past_last; i += 1){ - old_tokens[i].pos += text_shift; - } - block_copy_array_shift(new_tokens, ptr->tokens, tail, tail_shift); - - base_free(allocator, ptr->tokens); - - ptr->tokens = new_tokens; - ptr->count = new_tokens_count; - ptr->max = new_tokens_count; - - buffer_mark_as_modified(buffer_id); - } - } - } - - if (do_full_relex){ - *lex_task_ptr = async_task_no_dep(&global_async_system, do_full_lex_async, - make_data_struct(&buffer_id)); - } - - // no meaning for return - return(0); -} - -BUFFER_HOOK_SIG(default_end_buffer){ - Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); - Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task); - if (lex_task_ptr != 0){ - async_task_cancel(&global_async_system, *lex_task_ptr); - } - buffer_unmark_as_modified(buffer_id); - code_index_lock(); - code_index_erase_file(buffer_id); - code_index_unlock(); - // no meaning for return - return(0); -} - -internal void -set_all_default_hooks(Application_Links *app){ - set_custom_hook(app, HookID_BufferViewerUpdate, default_view_adjust); - - set_custom_hook(app, HookID_ViewEventHandler, default_view_input_handler); - set_custom_hook(app, HookID_Tick, default_tick); - set_custom_hook(app, HookID_RenderCaller, default_render_caller); -#if 0 - set_custom_hook(app, HookID_DeltaRule, original_delta); - set_custom_hook_memory_size(app, HookID_DeltaRule, - delta_ctx_size(original_delta_memory_size)); -#else - set_custom_hook(app, HookID_DeltaRule, fixed_time_cubic_delta); - set_custom_hook_memory_size(app, HookID_DeltaRule, - delta_ctx_size(fixed_time_cubic_delta_memory_size)); -#endif - set_custom_hook(app, HookID_BufferNameResolver, default_buffer_name_resolution); - - set_custom_hook(app, HookID_BeginBuffer, default_begin_buffer); - set_custom_hook(app, HookID_EndBuffer, end_buffer_close_jump_list); - set_custom_hook(app, HookID_NewFile, default_new_file); - set_custom_hook(app, HookID_SaveFile, default_file_save); - set_custom_hook(app, HookID_BufferEditRange, default_buffer_edit_range); - set_custom_hook(app, HookID_BufferRegion, default_buffer_region); - - set_custom_hook(app, HookID_Layout, layout_unwrapped); - //set_custom_hook(app, HookID_Layout, layout_wrap_anywhere); - //set_custom_hook(app, HookID_Layout, layout_wrap_whitespace); - //set_custom_hook(app, HookID_Layout, layout_virt_indent_unwrapped); - //set_custom_hook(app, HookID_Layout, layout_unwrapped_small_blank_lines); -} - -// BOTTOM - +/* +4coder_default_hooks.cpp - Sets up the hooks for the default framework. +*/ + +// TOP + +CUSTOM_COMMAND_SIG(default_startup) +CUSTOM_DOC("Default command for responding to a startup event") +{ + ProfileScope(app, "default startup"); + User_Input input = get_current_input(app); + if (match_core_code(&input, CoreCode_Startup)){ + String_Const_u8_Array file_names = input.event.core.file_names; + load_themes_default_folder(app); + default_4coder_initialize(app, file_names); + default_4coder_side_by_side_panels(app, file_names); + if (global_config.automatically_load_project){ + load_project(app); + } + } +} + +CUSTOM_COMMAND_SIG(default_try_exit) +CUSTOM_DOC("Default command for responding to a try-exit event") +{ + User_Input input = get_current_input(app); + if (match_core_code(&input, CoreCode_TryExit)){ + b32 do_exit = true; + if (!allow_immediate_close_without_checking_for_changes){ + b32 has_unsaved_changes = false; + for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always); + buffer != 0; + buffer = get_buffer_next(app, buffer, Access_Always)){ + Dirty_State dirty = buffer_get_dirty_state(app, buffer); + if (HasFlag(dirty, DirtyState_UnsavedChanges)){ + has_unsaved_changes = true; + break; + } + } + if (has_unsaved_changes){ + View_ID view = get_active_view(app, Access_Always); + do_exit = do_4coder_close_user_check(app, view); + } + } + if (do_exit){ + hard_exit(app); + } + } +} + +CUSTOM_COMMAND_SIG(default_view_input_handler) +CUSTOM_DOC("Input consumption loop for default view behavior") +{ + Thread_Context *tctx = get_thread_context(app); + Scratch_Block scratch(tctx); + + { + View_ID view = get_this_ctx_view(app, Access_Always); + String_Const_u8 name = push_u8_stringf(scratch, "view %d", view); + + Profile_Global_List *list = get_core_profile_list(app); + ProfileThreadName(tctx, list, name); + + View_Context ctx = view_current_context(app, view); + ctx.mapping = &framework_mapping; + ctx.map_id = mapid_global; + view_alter_context(app, view, &ctx); + } + + for (;;){ + // NOTE(allen): Get the binding from the buffer's current map + User_Input input = get_next_input(app, EventPropertyGroup_Any, 0); + ProfileScopeNamed(app, "before view input", view_input_profile); + if (input.abort){ + break; + } + + Event_Property event_properties = get_event_properties(&input.event); + + if (suppressing_mouse && (event_properties & EventPropertyGroup_AnyMouseEvent) != 0){ + continue; + } + + View_ID view = get_this_ctx_view(app, Access_Always); + + Buffer_ID buffer = view_get_buffer(app, view, Access_Always); + Managed_Scope buffer_scope = buffer_get_managed_scope(app, buffer); + Command_Map_ID *map_id_ptr = scope_attachment(app, buffer_scope, buffer_map_id, Command_Map_ID); + if (*map_id_ptr == 0){ + *map_id_ptr = mapid_file; + } + Command_Map_ID map_id = *map_id_ptr; + + Command_Binding binding = map_get_binding_recursive(&framework_mapping, map_id, &input.event); + + Managed_Scope scope = view_get_managed_scope(app, view); + + if (binding.custom == 0){ + // NOTE(allen): we don't have anything to do with this input, + // leave it marked unhandled so that if there's a follow up + // event it is not blocked. + leave_current_input_unhandled(app); + } + else{ + // NOTE(allen): before the command is called do some book keeping + Rewrite_Type *next_rewrite = + scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); + *next_rewrite = Rewrite_None; + if (fcoder_mode == FCoderMode_NotepadLike){ + for (View_ID view_it = get_view_next(app, 0, Access_Always); + view_it != 0; + view_it = get_view_next(app, view_it, Access_Always)){ + Managed_Scope scope_it = view_get_managed_scope(app, view_it); + b32 *snap_mark_to_cursor = + scope_attachment(app, scope_it, view_snap_mark_to_cursor, + b32); + *snap_mark_to_cursor = true; + } + } + + ProfileCloseNow(view_input_profile); + + // NOTE(allen): call the command + binding.custom(app); + + // NOTE(allen): after the command is called do some book keeping + ProfileScope(app, "after view input"); + + next_rewrite = scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); + if (next_rewrite != 0){ + Rewrite_Type *rewrite = + scope_attachment(app, scope, view_rewrite_loc, Rewrite_Type); + *rewrite = *next_rewrite; + if (fcoder_mode == FCoderMode_NotepadLike){ + for (View_ID view_it = get_view_next(app, 0, Access_Always); + view_it != 0; + view_it = get_view_next(app, view_it, Access_Always)){ + Managed_Scope scope_it = view_get_managed_scope(app, view_it); + b32 *snap_mark_to_cursor = + scope_attachment(app, scope_it, view_snap_mark_to_cursor, b32); + if (*snap_mark_to_cursor){ + i64 pos = view_get_cursor_pos(app, view_it); + view_set_mark(app, view_it, seek_pos(pos)); + } + } + } + } + } + } +} + +function void +default_tick(Application_Links *app, Frame_Info frame_info){ + Scratch_Block scratch(app); + + for (Buffer_Modified_Node *node = global_buffer_modified_set.first; + node != 0; + node = node->next){ + Temp_Memory_Block temp(scratch); + Buffer_ID buffer_id = node->buffer; + + Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); + + String_Const_u8 contents = push_whole_buffer(app, scratch, buffer_id); + Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, Token_Array); + if (tokens_ptr == 0){ + continue; + } + if (tokens_ptr->count == 0){ + continue; + } + Token_Array tokens = *tokens_ptr; + + Arena arena = make_arena_system(KB(16)); + Code_Index_File *index = push_array_zero(&arena, Code_Index_File, 1); + index->buffer = buffer_id; + + Generic_Parse_State state = {}; + generic_parse_init(app, &arena, contents, &tokens, &state); + // TODO(allen): Actually determine this in a fair way. + // Maybe switch to an enum. + state.do_cpp_parse = true; + generic_parse_full_input_breaks(index, &state, max_i32); + + code_index_lock(); + code_index_set_file(buffer_id, arena, index); + code_index_unlock(); + buffer_clear_layout_cache(app, buffer_id); + } + + buffer_modified_set_clear(); + + if (tick_all_fade_ranges(frame_info.animation_dt)){ + animate_in_n_milliseconds(app, 0); + } +} + +function Rect_f32 +default_buffer_region(Application_Links *app, View_ID view_id, Rect_f32 region){ + Buffer_ID buffer = view_get_buffer(app, view_id, Access_Always); + Face_ID face_id = get_face_id(app, buffer); + Face_Metrics metrics = get_face_metrics(app, face_id); + f32 line_height = metrics.line_height; + f32 digit_advance = metrics.decimal_digit_advance; + + // NOTE(allen): margins + region = rect_inner(region, 3.f); + + // NOTE(allen): file bar + b64 showing_file_bar = false; + if (view_get_setting(app, view_id, ViewSetting_ShowFileBar, &showing_file_bar) && + showing_file_bar){ + Rect_f32_Pair pair = layout_file_bar_on_top(region, line_height); + region = pair.max; + } + + // NOTE(allen): query bars + { + Query_Bar *space[32]; + Query_Bar_Ptr_Array query_bars = {}; + query_bars.ptrs = space; + if (get_active_query_bars(app, view_id, ArrayCount(space), &query_bars)){ + Rect_f32_Pair pair = layout_query_bar_on_top(region, line_height, query_bars.count); + region = pair.max; + } + } + + // NOTE(allen): FPS hud + if (show_fps_hud){ + Rect_f32_Pair pair = layout_fps_hud_on_bottom(region, line_height); + region = pair.min; + } + + // NOTE(allen): line numbers + if (global_config.show_line_number_margins){ + Rect_f32_Pair pair = layout_line_number_margin(app, buffer, region, digit_advance); + region = pair.max; + } + + return(region); +} + +function void +recursive_nest_highlight(Application_Links *app, Text_Layout_ID layout_id, Range_i64 range, + Code_Index_Nest_Ptr_Array *array, i32 counter){ + Code_Index_Nest **ptr = array->ptrs; + Code_Index_Nest **ptr_end = ptr + array->count; + + for (;ptr < ptr_end; ptr += 1){ + Code_Index_Nest *nest = *ptr; + if (!nest->is_closed){ + break; + } + if (range.first <= nest->close.max){ + break; + } + } + + ARGB_Color argb = finalize_color(defcolor_text_cycle, counter); + + for (;ptr < ptr_end; ptr += 1){ + Code_Index_Nest *nest = *ptr; + if (range.max <= nest->open.min){ + break; + } + + paint_text_color(app, layout_id, nest->open, argb); + if (nest->is_closed){ + paint_text_color(app, layout_id, nest->close, argb); + } + recursive_nest_highlight(app, layout_id, range, &nest->nest_array, counter + 1); + } +} + +function void +recursive_nest_highlight(Application_Links *app, Text_Layout_ID layout_id, Range_i64 range, + Code_Index_File *file){ + recursive_nest_highlight(app, layout_id, range, &file->nest_array, 0); +} + +function void +default_render_buffer(Application_Links *app, View_ID view_id, Face_ID face_id, + Buffer_ID buffer, Text_Layout_ID text_layout_id, + Rect_f32 rect){ + ProfileScope(app, "render buffer"); + + View_ID active_view = get_active_view(app, Access_Always); + b32 is_active_view = (active_view == view_id); + Rect_f32 prev_clip = draw_set_clip(app, rect); + + // NOTE(allen): Token colorizing + Token_Array token_array = get_token_array_from_buffer(app, buffer); + if (token_array.tokens != 0){ + draw_cpp_token_colors(app, text_layout_id, &token_array); + + // NOTE(allen): Scan for TODOs and NOTEs + if (global_config.use_comment_keyword){ + Comment_Highlight_Pair pairs[] = { + {string_u8_litexpr("NOTE"), finalize_color(defcolor_comment_pop, 0)}, + {string_u8_litexpr("TODO"), finalize_color(defcolor_comment_pop, 1)}, + }; + draw_comment_highlights(app, buffer, text_layout_id, + &token_array, pairs, ArrayCount(pairs)); + } + } + else{ + Range_i64 visible_range = text_layout_get_visible_range(app, text_layout_id); + paint_text_color_fcolor(app, text_layout_id, visible_range, fcolor_id(defcolor_text_default)); + } + + i64 cursor_pos = view_correct_cursor(app, view_id); + view_correct_mark(app, view_id); + + // NOTE(allen): Scope highlight + if (global_config.use_scope_highlight){ + Color_Array colors = finalize_color_array(defcolor_back_cycle); + draw_scope_highlight(app, buffer, text_layout_id, cursor_pos, colors.vals, colors.count); + } + + if (global_config.use_error_highlight || global_config.use_jump_highlight){ + // NOTE(allen): Error highlight + String_Const_u8 name = string_u8_litexpr("*compilation*"); + Buffer_ID compilation_buffer = get_buffer_by_name(app, name, Access_Always); + if (global_config.use_error_highlight){ + draw_jump_highlights(app, buffer, text_layout_id, compilation_buffer, + fcolor_id(defcolor_highlight_junk)); + } + + // NOTE(allen): Search highlight + if (global_config.use_jump_highlight){ + Buffer_ID jump_buffer = get_locked_jump_buffer(app); + if (jump_buffer != compilation_buffer){ + draw_jump_highlights(app, buffer, text_layout_id, jump_buffer, + fcolor_id(defcolor_highlight_white)); + } + } + } + + // NOTE(allen): Color parens + if (global_config.use_paren_helper){ + Color_Array colors = finalize_color_array(defcolor_text_cycle); + draw_paren_highlight(app, buffer, text_layout_id, cursor_pos, colors.vals, colors.count); + } + + // NOTE(allen): Line highlight + if (global_config.highlight_line_at_cursor && is_active_view){ + i64 line_number = get_line_number_from_pos(app, buffer, cursor_pos); + draw_line_highlight(app, text_layout_id, line_number, + fcolor_id(defcolor_highlight_cursor_line)); + } + + // NOTE(allen): Cursor shape + Face_Metrics metrics = get_face_metrics(app, face_id); + f32 cursor_roundness = (metrics.normal_advance*0.5f)*0.9f; + f32 mark_thickness = 2.f; + + // NOTE(allen): Cursor + switch (fcoder_mode){ + case FCoderMode_Original: + { + draw_original_4coder_style_cursor_mark_highlight(app, view_id, is_active_view, buffer, text_layout_id, cursor_roundness, mark_thickness); + }break; + case FCoderMode_NotepadLike: + { + draw_notepad_style_cursor_highlight(app, view_id, buffer, text_layout_id, cursor_roundness); + }break; + } + + // NOTE(allen): Fade ranges + paint_fade_ranges(app, text_layout_id, buffer, view_id); + + // NOTE(allen): put the actual text on the actual screen + draw_text_layout_default(app, text_layout_id); + + draw_set_clip(app, prev_clip); +} + +function void +default_render_caller(Application_Links *app, Frame_Info frame_info, View_ID view_id){ + ProfileScope(app, "default render caller"); + View_ID active_view = get_active_view(app, Access_Always); + b32 is_active_view = (active_view == view_id); + + Rect_f32 region = draw_background_and_margin(app, view_id, is_active_view); + Rect_f32 prev_clip = draw_set_clip(app, region); + + Buffer_ID buffer = view_get_buffer(app, view_id, Access_Always); + Face_ID face_id = get_face_id(app, buffer); + Face_Metrics face_metrics = get_face_metrics(app, face_id); + f32 line_height = face_metrics.line_height; + f32 digit_advance = face_metrics.decimal_digit_advance; + + // NOTE(allen): file bar + b64 showing_file_bar = false; + if (view_get_setting(app, view_id, ViewSetting_ShowFileBar, &showing_file_bar) && showing_file_bar){ + Rect_f32_Pair pair = layout_file_bar_on_top(region, line_height); + draw_file_bar(app, view_id, buffer, face_id, pair.min); + region = pair.max; + } + + Buffer_Scroll scroll = view_get_buffer_scroll(app, view_id); + + Buffer_Point_Delta_Result delta = delta_apply(app, view_id, + frame_info.animation_dt, scroll); + if (!block_match_struct(&scroll.position, &delta.point)){ + block_copy_struct(&scroll.position, &delta.point); + view_set_buffer_scroll(app, view_id, scroll, SetBufferScroll_NoCursorChange); + } + if (delta.still_animating){ + animate_in_n_milliseconds(app, 0); + } + + // NOTE(allen): query bars + { + Query_Bar *space[32]; + Query_Bar_Ptr_Array query_bars = {}; + query_bars.ptrs = space; + if (get_active_query_bars(app, view_id, ArrayCount(space), &query_bars)){ + for (i32 i = 0; i < query_bars.count; i += 1){ + Rect_f32_Pair pair = layout_query_bar_on_top(region, line_height, 1); + draw_query_bar(app, query_bars.ptrs[i], face_id, pair.min); + region = pair.max; + } + } + } + + // NOTE(allen): FPS hud + if (show_fps_hud){ + Rect_f32_Pair pair = layout_fps_hud_on_bottom(region, line_height); + draw_fps_hud(app, frame_info, face_id, pair.max); + region = pair.min; + animate_in_n_milliseconds(app, 1000); + } + + // NOTE(allen): layout line numbers + Rect_f32 line_number_rect = {}; + if (global_config.show_line_number_margins){ + Rect_f32_Pair pair = layout_line_number_margin(app, buffer, region, digit_advance); + line_number_rect = pair.min; + region = pair.max; + } + + // NOTE(allen): begin buffer render + Buffer_Point buffer_point = scroll.position; + Text_Layout_ID text_layout_id = text_layout_create(app, buffer, region, buffer_point); + + // NOTE(allen): draw line numbers + if (global_config.show_line_number_margins){ + draw_line_number_margin(app, view_id, buffer, face_id, text_layout_id, line_number_rect); + } + + // NOTE(allen): draw the buffer + default_render_buffer(app, view_id, face_id, buffer, text_layout_id, region); + + text_layout_free(app, text_layout_id); + draw_set_clip(app, prev_clip); +} + +HOOK_SIG(default_view_adjust){ + // NOTE(allen): Called whenever the view layout/sizes have been modified, + // including by full window resize. + return(0); +} + +BUFFER_NAME_RESOLVER_SIG(default_buffer_name_resolution){ + ProfileScope(app, "default buffer name resolution"); + if (conflict_count > 1){ + // List of unresolved conflicts + Scratch_Block scratch(app); + + i32 *unresolved = push_array(scratch, i32, conflict_count); + i32 unresolved_count = conflict_count; + for (i32 i = 0; i < conflict_count; ++i){ + unresolved[i] = i; + } + + // Resolution Loop + i32 x = 0; + for (;;){ + // Resolution Pass + ++x; + for (i32 i = 0; i < unresolved_count; ++i){ + i32 conflict_index = unresolved[i]; + Buffer_Name_Conflict_Entry *conflict = &conflicts[conflict_index]; + + u64 size = conflict->base_name.size; + size = clamp_top(size, conflict->unique_name_capacity); + conflict->unique_name_len_in_out = size; + block_copy(conflict->unique_name_in_out, conflict->base_name.str, size); + + if (conflict->file_name.str != 0){ + Temp_Memory_Block temp(scratch); + String_Const_u8 uniqueifier = {}; + + String_Const_u8 file_name = string_remove_last_folder(conflict->file_name); + if (file_name.size > 0){ + file_name = string_chop(file_name, 1); + u8 *end = file_name.str + file_name.size; + b32 past_the_end = false; + for (i32 j = 0; j < x; ++j){ + file_name = string_remove_last_folder(file_name); + if (j + 1 < x){ + file_name = string_chop(file_name, 1); + } + if (file_name.size == 0){ + if (j + 1 < x){ + past_the_end = true; + } + break; + } + } + u8 *start = file_name.str + file_name.size; + + uniqueifier = SCu8(start, end); + if (past_the_end){ + uniqueifier = push_u8_stringf(scratch, "%.*s~%d", + string_expand(uniqueifier), i); + } + } + else{ + uniqueifier = push_u8_stringf(scratch, "%d", i); + } + + String_u8 builder = Su8(conflict->unique_name_in_out, + conflict->unique_name_len_in_out, + conflict->unique_name_capacity); + string_append(&builder, string_u8_litexpr(" <")); + string_append(&builder, uniqueifier); + string_append(&builder, string_u8_litexpr(">")); + conflict->unique_name_len_in_out = builder.size; + } + } + + // Conflict Check Pass + b32 has_conflicts = false; + for (i32 i = 0; i < unresolved_count; ++i){ + i32 conflict_index = unresolved[i]; + Buffer_Name_Conflict_Entry *conflict = &conflicts[conflict_index]; + String_Const_u8 conflict_name = SCu8(conflict->unique_name_in_out, + conflict->unique_name_len_in_out); + + b32 hit_conflict = false; + if (conflict->file_name.str != 0){ + for (i32 j = 0; j < unresolved_count; ++j){ + if (i == j) continue; + + i32 conflict_j_index = unresolved[j]; + Buffer_Name_Conflict_Entry *conflict_j = &conflicts[conflict_j_index]; + + String_Const_u8 conflict_name_j = SCu8(conflict_j->unique_name_in_out, + conflict_j->unique_name_len_in_out); + + if (string_match(conflict_name, conflict_name_j)){ + hit_conflict = true; + break; + } + } + } + + if (hit_conflict){ + has_conflicts = true; + } + else{ + --unresolved_count; + unresolved[i] = unresolved[unresolved_count]; + --i; + } + } + + if (!has_conflicts){ + break; + } + } + } +} + +function void +parse_async__inner(Async_Context *actx, Buffer_ID buffer_id, + String_Const_u8 contents, Token_Array *tokens, i32 limit_factor){ + Application_Links *app = actx->app; + ProfileBlock(app, "async parse"); + + Arena arena = make_arena_system(KB(16)); + Code_Index_File *index = push_array_zero(&arena, Code_Index_File, 1); + index->buffer = buffer_id; + + Generic_Parse_State state = {}; + generic_parse_init(app, &arena, contents, tokens, &state); + + b32 canceled = false; + + for (;;){ + if (generic_parse_full_input_breaks(index, &state, limit_factor)){ + break; + } + if (async_check_canceled(actx)){ + canceled = true; + break; + } + } + + if (!canceled){ + Thread_Context *tctx = get_thread_context(app); + system_acquire_global_frame_mutex(tctx); + code_index_lock(); + code_index_set_file(buffer_id, arena, index); + code_index_unlock(); + buffer_clear_layout_cache(app, buffer_id); + system_release_global_frame_mutex(tctx); + } + else{ + linalloc_clear(&arena); + } +} + +function void +do_full_lex_async__inner(Async_Context *actx, Buffer_ID buffer_id){ + Application_Links *app = actx->app; + ProfileScope(app, "async lex"); + Thread_Context *tctx = get_thread_context(app); + Scratch_Block scratch(tctx); + + String_Const_u8 contents = {}; + { + ProfileBlock(app, "async lex contents (before mutex)"); + system_acquire_global_frame_mutex(tctx); + ProfileBlock(app, "async lex contents (after mutex)"); + contents = push_whole_buffer(app, scratch, buffer_id); + system_release_global_frame_mutex(tctx); + } + + i32 limit_factor = 10000; + + Token_List list = {}; + b32 canceled = false; + + Lex_State_Cpp state = {}; + lex_full_input_cpp_init(&state, contents); + for (;;){ + ProfileBlock(app, "async lex block"); + if (lex_full_input_cpp_breaks(scratch, &list, &state, limit_factor)){ + break; + } + if (async_check_canceled(actx)){ + canceled = true; + break; + } + } + + if (!canceled){ + ProfileBlock(app, "async lex save results (before mutex)"); + system_acquire_global_frame_mutex(tctx); + ProfileBlock(app, "async lex save results (after mutex)"); + Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); + if (scope != 0){ + Base_Allocator *allocator = managed_scope_allocator(app, scope); + Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, + Token_Array); + base_free(allocator, tokens_ptr->tokens); + Token_Array tokens = {}; + tokens.tokens = base_array(allocator, Token, list.total_count); + tokens.count = list.total_count; + tokens.max = list.total_count; + token_fill_memory_from_list(tokens.tokens, &list); + block_copy_struct(tokens_ptr, &tokens); + } + buffer_mark_as_modified(buffer_id); + system_release_global_frame_mutex(tctx); + } +} + +function void +do_full_lex_async(Async_Context *actx, Data data){ + if (data.size == sizeof(Buffer_ID)){ + Buffer_ID buffer = *(Buffer_ID*)data.data; + do_full_lex_async__inner(actx, buffer); + } +} + +#if 0 +function void +do_full_lex_and_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){ + Application_Links *app = actx->app; + ProfileScope(app, "async lex"); + Thread_Context *tctx = get_thread_context(app); + Scratch_Block scratch(tctx); + + String_Const_u8 contents = {}; + { + ProfileBlock(app, "async lex contents (before mutex)"); + system_acquire_global_frame_mutex(tctx); + ProfileBlock(app, "async lex contents (after mutex)"); + + Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); + if (scope != 0){ + Base_Allocator *allocator = managed_scope_allocator(app, scope); + Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, + Token_Array); + base_free(allocator, tokens_ptr->tokens); + block_zero_struct(tokens_ptr); + } + + contents = push_whole_buffer(app, scratch, buffer_id); + system_release_global_frame_mutex(tctx); + } + + i32 limit_factor = 10000; + + Token_List list = {}; + b32 canceled = false; + + { + Lex_State_Cpp state = {}; + lex_full_input_cpp_init(&state, contents); + for (;;){ + ProfileBlock(app, "async lex block"); + if (lex_full_input_cpp_breaks(scratch, &list, &state, limit_factor)){ + break; + } + if (async_check_canceled(actx)){ + canceled = true; + break; + } + } + } + + Token_Array tokens = {}; + if (!canceled){ + ProfileBlock(app, "async lex save results (before mutex)"); + system_acquire_global_frame_mutex(tctx); + ProfileBlock(app, "async lex save results (after mutex)"); + Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); + if (scope != 0){ + Base_Allocator *allocator = managed_scope_allocator(app, scope); + Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, + Token_Array); + base_free(allocator, tokens_ptr->tokens); + tokens.tokens = base_array(allocator, Token, list.total_count); + tokens.count = list.total_count; + tokens.max = list.total_count; + token_fill_memory_from_list(tokens.tokens, &list); + block_copy_struct(tokens_ptr, &tokens); + } + system_release_global_frame_mutex(tctx); + } + + if (tokens.count > 0){ + parse_async__inner(actx, buffer_id, contents, &tokens, limit_factor); + } +} + +function void +do_full_lex_and_parse_async(Async_Context *actx, Data data){ + if (data.size == sizeof(Buffer_ID)){ + Buffer_ID buffer = *(Buffer_ID*)data.data; + do_full_lex_and_parse_async__inner(actx, buffer); + } +} +#endif + +#if 0 +function void +do_parse_async__inner(Async_Context *actx, Buffer_ID buffer_id){ + Application_Links *app = actx->app; + ProfileScope(app, "async lex"); + Thread_Context *tctx = get_thread_context(app); + Scratch_Block scratch(tctx); + + String_Const_u8 contents = {}; + Token_Array tokens = {}; + { + ProfileBlock(app, "async parse contents (before mutex)"); + system_acquire_global_frame_mutex(tctx); + ProfileBlock(app, "async parse contents (after mutex)"); + + Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); + if (scope != 0){ + Token_Array *tokens_ptr = scope_attachment(app, scope, attachment_tokens, + Token_Array); + tokens.count = tokens_ptr->count; + tokens.tokens = push_array_write(scratch, Token, tokens.count, tokens_ptr->tokens); + if (tokens.count > 0){ + contents = push_whole_buffer(app, scratch, buffer_id); + } + } + + system_release_global_frame_mutex(tctx); + } + + i32 limit_factor = 10000; + + if (tokens.count > 0){ + parse_async__inner(actx, buffer_id, contents, &tokens, limit_factor); + } +} + +function void +do_parse_async(Async_Context *actx, Data data){ + if (data.size == sizeof(Buffer_ID)){ + Buffer_ID buffer = *(Buffer_ID*)data.data; + do_parse_async__inner(actx, buffer); + } +} +#endif + +BUFFER_HOOK_SIG(default_begin_buffer){ + ProfileScope(app, "begin buffer"); + + Scratch_Block scratch(app); + + b32 treat_as_code = false; + String_Const_u8 file_name = push_buffer_file_name(app, scratch, buffer_id); + if (file_name.size > 0){ + String_Const_u8_Array extensions = global_config.code_exts; + String_Const_u8 ext = string_file_extension(file_name); + for (i32 i = 0; i < extensions.count; ++i){ + if (string_match(ext, extensions.strings[i])){ + + if (string_match(ext, string_u8_litexpr("cpp")) || + string_match(ext, string_u8_litexpr("h")) || + string_match(ext, string_u8_litexpr("c")) || + string_match(ext, string_u8_litexpr("hpp")) || + string_match(ext, string_u8_litexpr("cc"))){ + treat_as_code = true; + } + +#if 0 + treat_as_code = true; + + if (string_match(ext, string_u8_litexpr("cs"))){ + if (parse_context_language_cs == 0){ + init_language_cs(app); + } + parse_context_id = parse_context_language_cs; + } + + if (string_match(ext, string_u8_litexpr("java"))){ + if (parse_context_language_java == 0){ + init_language_java(app); + } + parse_context_id = parse_context_language_java; + } + + if (string_match(ext, string_u8_litexpr("rs"))){ + if (parse_context_language_rust == 0){ + init_language_rust(app); + } + parse_context_id = parse_context_language_rust; + } + + if (string_match(ext, string_u8_litexpr("cpp")) || + string_match(ext, string_u8_litexpr("h")) || + string_match(ext, string_u8_litexpr("c")) || + string_match(ext, string_u8_litexpr("hpp")) || + string_match(ext, string_u8_litexpr("cc"))){ + if (parse_context_language_cpp == 0){ + init_language_cpp(app); + } + parse_context_id = parse_context_language_cpp; + } + + // TODO(NAME): Real GLSL highlighting + if (string_match(ext, string_u8_litexpr("glsl"))){ + if (parse_context_language_cpp == 0){ + init_language_cpp(app); + } + parse_context_id = parse_context_language_cpp; + } + + // TODO(NAME): Real Objective-C highlighting + if (string_match(ext, string_u8_litexpr("m"))){ + if (parse_context_language_cpp == 0){ + init_language_cpp(app); + } + parse_context_id = parse_context_language_cpp; + } +#endif + + break; + } + } + } + + Command_Map_ID map_id = (treat_as_code)?(mapid_code):(mapid_file); + Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); + Command_Map_ID *map_id_ptr = scope_attachment(app, scope, buffer_map_id, Command_Map_ID); + *map_id_ptr = map_id; + + Line_Ending_Kind setting = guess_line_ending_kind_from_buffer(app, buffer_id); + Line_Ending_Kind *eol_setting = scope_attachment(app, scope, buffer_eol_setting, Line_Ending_Kind); + *eol_setting = setting; + + // NOTE(allen): Decide buffer settings + b32 wrap_lines = true; + b32 use_virtual_whitespace = false; + b32 use_lexer = false; + if (treat_as_code){ + wrap_lines = global_config.enable_code_wrapping; + use_virtual_whitespace = global_config.enable_virtual_whitespace; + use_lexer = true; + } + + String_Const_u8 buffer_name = push_buffer_base_name(app, scratch, buffer_id); + if (string_match(buffer_name, string_u8_litexpr("*compilation*"))){ + wrap_lines = false; + } + + if (use_lexer){ + ProfileBlock(app, "begin buffer kick off lexer"); + Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task); + *lex_task_ptr = async_task_no_dep(&global_async_system, do_full_lex_async, make_data_struct(&buffer_id)); + } + + { + b32 *wrap_lines_ptr = scope_attachment(app, scope, buffer_wrap_lines, b32); + *wrap_lines_ptr = wrap_lines; + } + + if (use_virtual_whitespace){ + if (use_lexer){ + buffer_set_layout(app, buffer_id, layout_virt_indent_index_generic); + } + else{ + buffer_set_layout(app, buffer_id, layout_virt_indent_literal_generic); + } + } + else{ + buffer_set_layout(app, buffer_id, layout_generic); + } + + // no meaning for return + return(0); +} + +BUFFER_HOOK_SIG(default_new_file){ + Scratch_Block scratch(app); + String_Const_u8 file_name = push_buffer_base_name(app, scratch, buffer_id); + if (!string_match(string_postfix(file_name, 2), string_u8_litexpr(".h"))) { + return(0); + } + + List_String_Const_u8 guard_list = {}; + for (u64 i = 0; i < file_name.size; ++i){ + u8 c[2] = {}; + u64 c_size = 1; + u8 ch = file_name.str[i]; + if (ch == '.'){ + c[0] = '_'; + } + else if (ch >= 'A' && ch <= 'Z'){ + c_size = 2; + c[0] = '_'; + c[1] = ch; + } + else if (ch >= 'a' && ch <= 'z'){ + c[0] = ch - ('a' - 'A'); + } + String_Const_u8 part = push_string_copy(scratch, SCu8(c, c_size)); + string_list_push(scratch, &guard_list, part); + } + String_Const_u8 guard = string_list_flatten(scratch, guard_list); + + Buffer_Insertion insert = begin_buffer_insertion_at_buffered(app, buffer_id, 0, scratch, KB(16)); + insertf(&insert, + "#ifndef %.*s\n" + "#define %.*s\n" + "\n" + "#endif //%.*s\n", + string_expand(guard), + string_expand(guard), + string_expand(guard)); + end_buffer_insertion(&insert); + + return(0); +} + +BUFFER_HOOK_SIG(default_file_save){ + // buffer_id + ProfileScope(app, "default file save"); + b32 is_virtual = global_config.enable_virtual_whitespace; + if (global_config.automatically_indent_text_on_save && is_virtual){ + auto_indent_buffer(app, buffer_id, buffer_range(app, buffer_id)); + } + + Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); + Line_Ending_Kind *eol = scope_attachment(app, scope, buffer_eol_setting, + Line_Ending_Kind); + switch (*eol){ + case LineEndingKind_LF: + { + rewrite_lines_to_lf(app, buffer_id); + }break; + case LineEndingKind_CRLF: + { + rewrite_lines_to_crlf(app, buffer_id); + }break; + } + + // no meaning for return + return(0); +} + +BUFFER_EDIT_RANGE_SIG(default_buffer_edit_range){ + // buffer_id, new_range, original_size + ProfileScope(app, "default edit range"); + + Range_i64 old_range = Ii64(new_range.first, new_range.first + original_size); + + { + code_index_lock(); + Code_Index_File *file = code_index_get_file(buffer_id); + if (file != 0){ + code_index_shift(file, old_range, range_size(new_range)); + } + code_index_unlock(); + } + + i64 insert_size = range_size(new_range); + i64 text_shift = replace_range_shift(old_range, insert_size); + + Scratch_Block scratch(app); + + Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); + Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task); + + Base_Allocator *allocator = managed_scope_allocator(app, scope); + b32 do_full_relex = false; + + if (async_task_is_running_or_pending(&global_async_system, *lex_task_ptr)){ + async_task_cancel(&global_async_system, *lex_task_ptr); + buffer_unmark_as_modified(buffer_id); + do_full_relex = true; + *lex_task_ptr = 0; + } + + Token_Array *ptr = scope_attachment(app, scope, attachment_tokens, Token_Array); + if (ptr != 0 && ptr->tokens != 0){ + ProfileBlockNamed(app, "attempt resync", profile_attempt_resync); + + i64 token_index_first = token_relex_first(ptr, old_range.first, 1); + i64 token_index_resync_guess = + token_relex_resync(ptr, old_range.one_past_last, 16); + + if (token_index_resync_guess - token_index_first >= 4000){ + do_full_relex = true; + } + else{ + Token *token_first = ptr->tokens + token_index_first; + Token *token_resync = ptr->tokens + token_index_resync_guess; + + Range_i64 relex_range = Ii64(token_first->pos, token_resync->pos + token_resync->size + text_shift); + String_Const_u8 partial_text = push_buffer_range(app, scratch, buffer_id, relex_range); + + Token_List relex_list = lex_full_input_cpp(scratch, partial_text); + if (relex_range.one_past_last < buffer_get_size(app, buffer_id)){ + token_drop_eof(&relex_list); + } + + Token_Relex relex = token_relex(relex_list, relex_range.first - text_shift, ptr->tokens, token_index_first, token_index_resync_guess); + + ProfileCloseNow(profile_attempt_resync); + + if (!relex.successful_resync){ + do_full_relex = true; + } + else{ + ProfileBlock(app, "apply resync"); + + i64 token_index_resync = relex.first_resync_index; + + Range_i64 head = Ii64(0, token_index_first); + Range_i64 replaced = Ii64(token_index_first, token_index_resync); + Range_i64 tail = Ii64(token_index_resync, ptr->count); + i64 resynced_count = (token_index_resync_guess + 1) - token_index_resync; + i64 relexed_count = relex_list.total_count - resynced_count; + i64 tail_shift = relexed_count - (token_index_resync - token_index_first); + + i64 new_tokens_count = ptr->count + tail_shift; + Token *new_tokens = base_array(allocator, Token, new_tokens_count); + + Token *old_tokens = ptr->tokens; + block_copy_array_shift(new_tokens, old_tokens, head, 0); + token_fill_memory_from_list(new_tokens + replaced.first, &relex_list, relexed_count); + for (i64 i = 0, index = replaced.first; i < relexed_count; i += 1, index += 1){ + new_tokens[index].pos += relex_range.first; + } + for (i64 i = tail.first; i < tail.one_past_last; i += 1){ + old_tokens[i].pos += text_shift; + } + block_copy_array_shift(new_tokens, ptr->tokens, tail, tail_shift); + + base_free(allocator, ptr->tokens); + + ptr->tokens = new_tokens; + ptr->count = new_tokens_count; + ptr->max = new_tokens_count; + + buffer_mark_as_modified(buffer_id); + } + } + } + + if (do_full_relex){ + *lex_task_ptr = async_task_no_dep(&global_async_system, do_full_lex_async, + make_data_struct(&buffer_id)); + } + + // no meaning for return + return(0); +} + +BUFFER_HOOK_SIG(default_end_buffer){ + Managed_Scope scope = buffer_get_managed_scope(app, buffer_id); + Async_Task *lex_task_ptr = scope_attachment(app, scope, buffer_lex_task, Async_Task); + if (lex_task_ptr != 0){ + async_task_cancel(&global_async_system, *lex_task_ptr); + } + buffer_unmark_as_modified(buffer_id); + code_index_lock(); + code_index_erase_file(buffer_id); + code_index_unlock(); + // no meaning for return + return(0); +} + +internal void +set_all_default_hooks(Application_Links *app){ + set_custom_hook(app, HookID_BufferViewerUpdate, default_view_adjust); + + set_custom_hook(app, HookID_ViewEventHandler, default_view_input_handler); + set_custom_hook(app, HookID_Tick, default_tick); + set_custom_hook(app, HookID_RenderCaller, default_render_caller); +#if 0 + set_custom_hook(app, HookID_DeltaRule, original_delta); + set_custom_hook_memory_size(app, HookID_DeltaRule, + delta_ctx_size(original_delta_memory_size)); +#else + set_custom_hook(app, HookID_DeltaRule, fixed_time_cubic_delta); + set_custom_hook_memory_size(app, HookID_DeltaRule, + delta_ctx_size(fixed_time_cubic_delta_memory_size)); +#endif + set_custom_hook(app, HookID_BufferNameResolver, default_buffer_name_resolution); + + set_custom_hook(app, HookID_BeginBuffer, default_begin_buffer); + set_custom_hook(app, HookID_EndBuffer, end_buffer_close_jump_list); + set_custom_hook(app, HookID_NewFile, default_new_file); + set_custom_hook(app, HookID_SaveFile, default_file_save); + set_custom_hook(app, HookID_BufferEditRange, default_buffer_edit_range); + set_custom_hook(app, HookID_BufferRegion, default_buffer_region); + + set_custom_hook(app, HookID_Layout, layout_unwrapped); + //set_custom_hook(app, HookID_Layout, layout_wrap_anywhere); + //set_custom_hook(app, HookID_Layout, layout_wrap_whitespace); + //set_custom_hook(app, HookID_Layout, layout_virt_indent_unwrapped); + //set_custom_hook(app, HookID_Layout, layout_unwrapped_small_blank_lines); +} + +// BOTTOM + diff --git a/custom/4coder_default_include.cpp b/custom/4coder_default_include.cpp index 929af268..51ee72b2 100644 --- a/custom/4coder_default_include.cpp +++ b/custom/4coder_default_include.cpp @@ -118,8 +118,6 @@ #include "4coder_default_hooks.cpp" -#include "generated/managed_id_metadata.cpp" - #endif // BOTTOM diff --git a/custom/4coder_draw.cpp b/custom/4coder_draw.cpp index 006bbd31..2f719f74 100644 --- a/custom/4coder_draw.cpp +++ b/custom/4coder_draw.cpp @@ -1,854 +1,849 @@ -/* -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 i32 -default_cursor_sub_id(void){ - i32 result = 0; - if (global_keyboard_macro_is_recording){ - result = 1; - } - return(result); -} - -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){ - i32 cursor_sub_id = default_cursor_sub_id(); - 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, cursor_sub_id)); - 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, cursor_sub_id)); - } - } -} - -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){ - i32 cursor_sub_id = default_cursor_sub_id(); - 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, cursor_sub_id)); - } -} - -//////////////////////////////// - -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); + 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); + } +} + +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 i32 +default_cursor_sub_id(void){ + i32 result = 0; + if (global_keyboard_macro_is_recording){ + result = 1; + } + return(result); +} + +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){ + i32 cursor_sub_id = default_cursor_sub_id(); + 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, cursor_sub_id)); + 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, cursor_sub_id)); + } + } +} + +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){ + i32 cursor_sub_id = default_cursor_sub_id(); + 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, cursor_sub_id)); + } +} + +//////////////////////////////// + +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_lists.cpp b/custom/4coder_lists.cpp index 27a15d89..ab7593bf 100644 --- a/custom/4coder_lists.cpp +++ b/custom/4coder_lists.cpp @@ -710,8 +710,7 @@ CUSTOM_DOC("Interactively opens a file.") for (;;){ Scratch_Block scratch(app); View_ID view = get_this_ctx_view(app, Access_Always); - File_Name_Result result = get_file_name_from_user(app, scratch, "Open:", - view); + File_Name_Result result = get_file_name_from_user(app, scratch, "Open:", view); if (result.canceled) break; String_Const_u8 file_name = result.file_name_activated; diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index ebda7adb..1c461ef6 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -274,7 +274,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 619 }, { 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, 754 }, +{ 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, 753 }, { 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 }, @@ -390,9 +390,9 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 372 }, { 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, 364 }, { 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(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, 109 }, +{ 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, 70 }, +{ 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, 116 }, { 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 }, @@ -448,7 +448,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 1513 }, -{ 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, 778 }, +{ 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, 777 }, { 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, 563 }, { 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, 550 }, { 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, 656 }, diff --git a/custom/generated/custom_api.cpp b/custom/generated/custom_api.cpp index 0aef628d..653783c8 100644 --- a/custom/generated/custom_api.cpp +++ b/custom/generated/custom_api.cpp @@ -92,7 +92,6 @@ vtable->view_set_buffer_scroll = view_set_buffer_scroll; vtable->view_set_mark = view_set_mark; vtable->view_quit_ui = view_quit_ui; vtable->view_set_buffer = view_set_buffer; -vtable->view_post_fade = view_post_fade; vtable->view_push_context = view_push_context; vtable->view_pop_context = view_pop_context; vtable->view_alter_context = view_alter_context; @@ -170,6 +169,7 @@ vtable->text_layout_get_visible_range = text_layout_get_visible_range; vtable->text_layout_line_on_screen = text_layout_line_on_screen; vtable->text_layout_character_on_screen = text_layout_character_on_screen; vtable->paint_text_color = paint_text_color; +vtable->paint_text_color_blend = paint_text_color_blend; vtable->text_layout_free = text_layout_free; vtable->draw_text_layout = draw_text_layout; vtable->open_color_picker = open_color_picker; @@ -273,7 +273,6 @@ view_set_buffer_scroll = vtable->view_set_buffer_scroll; view_set_mark = vtable->view_set_mark; view_quit_ui = vtable->view_quit_ui; view_set_buffer = vtable->view_set_buffer; -view_post_fade = vtable->view_post_fade; view_push_context = vtable->view_push_context; view_pop_context = vtable->view_pop_context; view_alter_context = vtable->view_alter_context; @@ -351,6 +350,7 @@ text_layout_get_visible_range = vtable->text_layout_get_visible_range; text_layout_line_on_screen = vtable->text_layout_line_on_screen; text_layout_character_on_screen = vtable->text_layout_character_on_screen; paint_text_color = vtable->paint_text_color; +paint_text_color_blend = vtable->paint_text_color_blend; text_layout_free = vtable->text_layout_free; draw_text_layout = vtable->draw_text_layout; open_color_picker = vtable->open_color_picker; diff --git a/custom/generated/custom_api.h b/custom/generated/custom_api.h index 178479d4..7e65493a 100644 --- a/custom/generated/custom_api.h +++ b/custom/generated/custom_api.h @@ -90,7 +90,6 @@ #define custom_view_set_mark_sig() b32 custom_view_set_mark(Application_Links* app, View_ID view_id, Buffer_Seek seek) #define custom_view_quit_ui_sig() b32 custom_view_quit_ui(Application_Links* app, View_ID view_id) #define custom_view_set_buffer_sig() b32 custom_view_set_buffer(Application_Links* app, View_ID view_id, Buffer_ID buffer_id, Set_Buffer_Flag flags) -#define custom_view_post_fade_sig() b32 custom_view_post_fade(Application_Links* app, View_ID view_id, f32 seconds, Range_i64 range, ARGB_Color color) #define custom_view_push_context_sig() b32 custom_view_push_context(Application_Links* app, View_ID view_id, View_Context* ctx) #define custom_view_pop_context_sig() b32 custom_view_pop_context(Application_Links* app, View_ID view_id) #define custom_view_alter_context_sig() b32 custom_view_alter_context(Application_Links* app, View_ID view_id, View_Context* ctx) @@ -168,6 +167,7 @@ #define custom_text_layout_line_on_screen_sig() Range_f32 custom_text_layout_line_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 line_number) #define custom_text_layout_character_on_screen_sig() Rect_f32 custom_text_layout_character_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 pos) #define custom_paint_text_color_sig() void custom_paint_text_color(Application_Links* app, Text_Layout_ID layout_id, Range_i64 range, ARGB_Color color) +#define custom_paint_text_color_blend_sig() void custom_paint_text_color_blend(Application_Links* app, Text_Layout_ID layout_id, Range_i64 range, ARGB_Color color, f32 blend) #define custom_text_layout_free_sig() b32 custom_text_layout_free(Application_Links* app, Text_Layout_ID text_layout_id) #define custom_draw_text_layout_sig() void custom_draw_text_layout(Application_Links* app, Text_Layout_ID layout_id, ARGB_Color special_color, ARGB_Color ghost_color) #define custom_open_color_picker_sig() void custom_open_color_picker(Application_Links* app, Color_Picker* picker) @@ -267,7 +267,6 @@ typedef b32 custom_view_set_buffer_scroll_type(Application_Links* app, View_ID v typedef b32 custom_view_set_mark_type(Application_Links* app, View_ID view_id, Buffer_Seek seek); typedef b32 custom_view_quit_ui_type(Application_Links* app, View_ID view_id); typedef b32 custom_view_set_buffer_type(Application_Links* app, View_ID view_id, Buffer_ID buffer_id, Set_Buffer_Flag flags); -typedef b32 custom_view_post_fade_type(Application_Links* app, View_ID view_id, f32 seconds, Range_i64 range, ARGB_Color color); typedef b32 custom_view_push_context_type(Application_Links* app, View_ID view_id, View_Context* ctx); typedef b32 custom_view_pop_context_type(Application_Links* app, View_ID view_id); typedef b32 custom_view_alter_context_type(Application_Links* app, View_ID view_id, View_Context* ctx); @@ -345,6 +344,7 @@ typedef Range_i64 custom_text_layout_get_visible_range_type(Application_Links* a typedef Range_f32 custom_text_layout_line_on_screen_type(Application_Links* app, Text_Layout_ID layout_id, i64 line_number); typedef Rect_f32 custom_text_layout_character_on_screen_type(Application_Links* app, Text_Layout_ID layout_id, i64 pos); typedef void custom_paint_text_color_type(Application_Links* app, Text_Layout_ID layout_id, Range_i64 range, ARGB_Color color); +typedef void custom_paint_text_color_blend_type(Application_Links* app, Text_Layout_ID layout_id, Range_i64 range, ARGB_Color color, f32 blend); typedef b32 custom_text_layout_free_type(Application_Links* app, Text_Layout_ID text_layout_id); typedef void custom_draw_text_layout_type(Application_Links* app, Text_Layout_ID layout_id, ARGB_Color special_color, ARGB_Color ghost_color); typedef void custom_open_color_picker_type(Application_Links* app, Color_Picker* picker); @@ -445,7 +445,6 @@ custom_view_set_buffer_scroll_type *view_set_buffer_scroll; custom_view_set_mark_type *view_set_mark; custom_view_quit_ui_type *view_quit_ui; custom_view_set_buffer_type *view_set_buffer; -custom_view_post_fade_type *view_post_fade; custom_view_push_context_type *view_push_context; custom_view_pop_context_type *view_pop_context; custom_view_alter_context_type *view_alter_context; @@ -523,6 +522,7 @@ custom_text_layout_get_visible_range_type *text_layout_get_visible_range; custom_text_layout_line_on_screen_type *text_layout_line_on_screen; custom_text_layout_character_on_screen_type *text_layout_character_on_screen; custom_paint_text_color_type *paint_text_color; +custom_paint_text_color_blend_type *paint_text_color_blend; custom_text_layout_free_type *text_layout_free; custom_draw_text_layout_type *draw_text_layout; custom_open_color_picker_type *open_color_picker; @@ -624,7 +624,6 @@ internal b32 view_set_buffer_scroll(Application_Links* app, View_ID view_id, Buf internal b32 view_set_mark(Application_Links* app, View_ID view_id, Buffer_Seek seek); internal b32 view_quit_ui(Application_Links* app, View_ID view_id); internal b32 view_set_buffer(Application_Links* app, View_ID view_id, Buffer_ID buffer_id, Set_Buffer_Flag flags); -internal b32 view_post_fade(Application_Links* app, View_ID view_id, f32 seconds, Range_i64 range, ARGB_Color color); internal b32 view_push_context(Application_Links* app, View_ID view_id, View_Context* ctx); internal b32 view_pop_context(Application_Links* app, View_ID view_id); internal b32 view_alter_context(Application_Links* app, View_ID view_id, View_Context* ctx); @@ -702,6 +701,7 @@ internal Range_i64 text_layout_get_visible_range(Application_Links* app, Text_La internal Range_f32 text_layout_line_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 line_number); internal Rect_f32 text_layout_character_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 pos); internal void paint_text_color(Application_Links* app, Text_Layout_ID layout_id, Range_i64 range, ARGB_Color color); +internal void paint_text_color_blend(Application_Links* app, Text_Layout_ID layout_id, Range_i64 range, ARGB_Color color, f32 blend); internal b32 text_layout_free(Application_Links* app, Text_Layout_ID text_layout_id); internal void draw_text_layout(Application_Links* app, Text_Layout_ID layout_id, ARGB_Color special_color, ARGB_Color ghost_color); internal void open_color_picker(Application_Links* app, Color_Picker* picker); @@ -803,7 +803,6 @@ global custom_view_set_buffer_scroll_type *view_set_buffer_scroll = 0; global custom_view_set_mark_type *view_set_mark = 0; global custom_view_quit_ui_type *view_quit_ui = 0; global custom_view_set_buffer_type *view_set_buffer = 0; -global custom_view_post_fade_type *view_post_fade = 0; global custom_view_push_context_type *view_push_context = 0; global custom_view_pop_context_type *view_pop_context = 0; global custom_view_alter_context_type *view_alter_context = 0; @@ -881,6 +880,7 @@ global custom_text_layout_get_visible_range_type *text_layout_get_visible_range global custom_text_layout_line_on_screen_type *text_layout_line_on_screen = 0; global custom_text_layout_character_on_screen_type *text_layout_character_on_screen = 0; global custom_paint_text_color_type *paint_text_color = 0; +global custom_paint_text_color_blend_type *paint_text_color_blend = 0; global custom_text_layout_free_type *text_layout_free = 0; global custom_draw_text_layout_type *draw_text_layout = 0; global custom_open_color_picker_type *open_color_picker = 0; diff --git a/custom/generated/custom_api_master_list.h b/custom/generated/custom_api_master_list.h index 97617c5e..60e06631 100644 --- a/custom/generated/custom_api_master_list.h +++ b/custom/generated/custom_api_master_list.h @@ -90,7 +90,6 @@ api(custom) function b32 view_set_buffer_scroll(Application_Links* app, View_ID api(custom) function b32 view_set_mark(Application_Links* app, View_ID view_id, Buffer_Seek seek); api(custom) function b32 view_quit_ui(Application_Links* app, View_ID view_id); api(custom) function b32 view_set_buffer(Application_Links* app, View_ID view_id, Buffer_ID buffer_id, Set_Buffer_Flag flags); -api(custom) function b32 view_post_fade(Application_Links* app, View_ID view_id, f32 seconds, Range_i64 range, ARGB_Color color); api(custom) function b32 view_push_context(Application_Links* app, View_ID view_id, View_Context* ctx); api(custom) function b32 view_pop_context(Application_Links* app, View_ID view_id); api(custom) function b32 view_alter_context(Application_Links* app, View_ID view_id, View_Context* ctx); @@ -168,6 +167,7 @@ api(custom) function Range_i64 text_layout_get_visible_range(Application_Links* api(custom) function Range_f32 text_layout_line_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 line_number); api(custom) function Rect_f32 text_layout_character_on_screen(Application_Links* app, Text_Layout_ID layout_id, i64 pos); api(custom) function void paint_text_color(Application_Links* app, Text_Layout_ID layout_id, Range_i64 range, ARGB_Color color); +api(custom) function void paint_text_color_blend(Application_Links* app, Text_Layout_ID layout_id, Range_i64 range, ARGB_Color color, f32 blend); api(custom) function b32 text_layout_free(Application_Links* app, Text_Layout_ID text_layout_id); api(custom) function void draw_text_layout(Application_Links* app, Text_Layout_ID layout_id, ARGB_Color special_color, ARGB_Color ghost_color); api(custom) function void open_color_picker(Application_Links* app, Color_Picker* picker); diff --git a/docs/4ed_doc_custom_api_view.cpp b/docs/4ed_doc_custom_api_view.cpp index 37c3bde5..b34f867f 100644 --- a/docs/4ed_doc_custom_api_view.cpp +++ b/docs/4ed_doc_custom_api_view.cpp @@ -915,13 +915,6 @@ doc_custom_api__view(Arena *arena, API_Definition *api_def, Doc_Cluster *cluster //////////////////////////////// - // TODO(allen): remove view_post_fade - if (begin_doc_call(arena, cluster, api_def, "view_post_fade", &func)){ - doc_function_brief(arena, &func, "Plans to deprecate - do not rely on this call!"); - } - - //////////////////////////////// - if (begin_doc_call(arena, cluster, api_def, "view_push_context", &func)){ doc_function_brief(arena, &func, "Push a view's stack of context details with a pointer to the new values for the context"); From e977d1d312a5d3bbdaa404cd6f010ebf303dbd0b Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Wed, 15 Jan 2020 10:16:13 -0800 Subject: [PATCH 088/128] Fix crash when escaping command_documentation --- custom/4coder_docs.cpp | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/custom/4coder_docs.cpp b/custom/4coder_docs.cpp index 99a3e237..c3262b8e 100644 --- a/custom/4coder_docs.cpp +++ b/custom/4coder_docs.cpp @@ -195,8 +195,10 @@ CUSTOM_DOC("Prompts the user to select a command then loads a doc buffer for tha Scratch_Block scratch(app); Doc_Cluster *docs = doc_commands(scratch); Doc_Page *page = get_doc_page_from_user(app, docs, "Doc Page:"); - Buffer_ID buffer = render_doc_page(app, page); - view_set_buffer(app, view, buffer, 0); + if (page != 0){ + Buffer_ID buffer = render_doc_page(app, page); + view_set_buffer(app, view, buffer, 0); + } } } From 0bbafd636e92aa20d9877d64c4a9ee65f0860528 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Wed, 15 Jan 2020 10:42:02 -0800 Subject: [PATCH 089/128] Fixed random crashes and misbehaviors --- 4ed_api_implementation.cpp | 2 +- 4ed_layout.cpp | 10 + custom/4coder_base_commands.cpp | 22 +- custom/generated/lexer_cpp.cpp | 10158 ++++++++-------- .../lexer_generator/4coder_lex_gen_main.cpp | 30 +- 5 files changed, 5120 insertions(+), 5102 deletions(-) diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index 5cbb28de..73fbfcd4 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -1108,7 +1108,7 @@ get_view_prev__inner(Layout *layout, View *view){ } } else{ - Panel *panel = layout_get_first_open_panel(layout); + Panel *panel = layout_get_last_open_panel(layout); view = panel->view; } return(view); diff --git a/4ed_layout.cpp b/4ed_layout.cpp index fd493dee..3b81bdbd 100644 --- a/4ed_layout.cpp +++ b/4ed_layout.cpp @@ -123,6 +123,16 @@ layout_get_first_open_panel(Layout *layout){ return(panel); } +internal Panel* +layout_get_last_open_panel(Layout *layout){ + Panel *panel = CastFromMember(Panel, node, layout->open_panels.prev); + if (panel != 0 && &panel->node == &layout->open_panels){ + panel = 0; + } + AssertImplies(panel != 0, panel->kind == PanelKind_Final); + return(panel); +} + internal Panel* layout_get_next_open_panel(Layout *layout, Panel *panel){ panel = CastFromMember(Panel, node, panel->node.next); diff --git a/custom/4coder_base_commands.cpp b/custom/4coder_base_commands.cpp index b80e646f..45b100b4 100644 --- a/custom/4coder_base_commands.cpp +++ b/custom/4coder_base_commands.cpp @@ -1312,18 +1312,18 @@ CUSTOM_DOC("Queries the user for a new name and renames the file of the current bar.string = SCu8(name_space, (u64)0); bar.string_capacity = sizeof(name_space); if (query_user_string(app, &bar) && bar.string.size != 0){ - // TODO(allen): There should be a way to say, "detach a buffer's file" and "attach this file to a buffer" - List_String_Const_u8 new_file_name_list = {}; - string_list_push(scratch, &new_file_name_list, string_remove_front_of_path(file_name)); - string_list_push(scratch, &new_file_name_list, bar.string); - String_Const_u8 new_file_name = string_list_flatten(scratch, new_file_name_list, StringFill_NullTerminate); - if (buffer_save(app, buffer, new_file_name, BufferSave_IgnoreDirtyFlag)){ - Buffer_ID new_buffer = create_buffer(app, new_file_name, BufferCreate_NeverNew|BufferCreate_JustChangedFile); - if (new_buffer != 0 && new_buffer != buffer){ - delete_file_base(app, file_name, buffer); - view_set_buffer(app, view, new_buffer, 0); - } + // TODO(allen): There should be a way to say, "detach a buffer's file" and "attach this file to a buffer" + List_String_Const_u8 new_file_name_list = {}; + string_list_push(scratch, &new_file_name_list, string_remove_front_of_path(file_name)); + string_list_push(scratch, &new_file_name_list, bar.string); + String_Const_u8 new_file_name = string_list_flatten(scratch, new_file_name_list, StringFill_NullTerminate); + if (buffer_save(app, buffer, new_file_name, BufferSave_IgnoreDirtyFlag)){ + Buffer_ID new_buffer = create_buffer(app, new_file_name, BufferCreate_NeverNew|BufferCreate_JustChangedFile); + if (new_buffer != 0 && new_buffer != buffer){ + delete_file_base(app, file_name, buffer); + view_set_buffer(app, view, new_buffer, 0); } + } } } } diff --git a/custom/generated/lexer_cpp.cpp b/custom/generated/lexer_cpp.cpp index 77bf3f7b..a1a3ffae 100644 --- a/custom/generated/lexer_cpp.cpp +++ b/custom/generated/lexer_cpp.cpp @@ -43,5102 +43,5102 @@ lexeme_table_lookup(u64 *hash_array, String_Const_u8 *key_array, } #endif -u64 main_keys_hash_array[121] = { - 0x3165da52e461ac3f,0x0000000000000000,0x3165da52f92661bd,0x0000000000000000, - 0x0000000000000000,0x0000000000000000,0x3165da52f9fa6ddb,0xbfc3c777d05a650b, - 0x3165da52ea1d2cb3,0x0000000000000000,0x0000000000000000,0x0000000000000000, - 0x0000000000000000,0xa47e4b3347ca768b,0xa47e4b0d60643265,0xf9ddaa09147bac4d, - 0x95351611c4501ef3,0x0000000000000000,0x0000000000000000,0xa47e4b33693ada65, - 0x0000000000000000,0xdb05013ca08bb8f1,0xf9ddaa091485019b,0xbfc3dfcbf5462bb3, - 0x0000000000000000,0x3165da52f85e6961,0x0000000000000000,0xdb0563922ce5394d, - 0x0000000000000000,0xa47e4b334bfc993f,0xdb02e2748a4d7e43,0x0000000000000000, - 0xb4c81ca554c806f3,0x0000000000000000,0x3165da52e0f88b5b,0x501eeeb814fbf821, - 0x0000000000000000,0xdb0503951fae6cc1,0x0000000000000000,0x0000000000000000, - 0xbfc3de349dfab331,0x0000000000000000,0x0000000000000000,0x3165da52f092830f, - 0xa47e4b300b3f05d3,0xbfc3dfcbf546362d,0xdb05125809d1c12f,0x0000000000000000, - 0xed66c2eeb45a9c73,0x0000000000000000,0xf9ddaa0914eaa03f,0x77f5a2bcd06af3a3, - 0xa47e4b0cab3b440f,0x0000000000000000,0x0000000000000000,0x3165da52ebde8871, - 0xa47e4b0cab0869b5,0x3165da52e5b576b7,0x0000000000000000,0x0000000000000000, - 0xa47e4b336935d383,0x0000000000000000,0x0000000000000000,0xa47e4b30efc0220b, - 0x0000000000000000,0x0000000000000000,0x501eeeb814fabe67,0xbfc3dfefa2fc3a77, - 0x0000000000000000,0x0000000000000000,0x0000000000000000,0xf9ddaa0914bb0bf9, - 0x0000000000000000,0xf9ddaa09148a58bb,0x0000000000000000,0xdb02e323971f6e8d, - 0x501eeeb814fa0161,0xa9cef01e4d45a29b,0x501eeeb814fb939f,0x0000000000000000, - 0xdb0517ba16b3ab83,0xbfc3dfb0ab021849,0xdb0541265bb691e9,0xbfc3df66cacb41a5, - 0xa47e4b325526bb31,0x0000000000000000,0xeca54fbddbbe35d5,0xa47e4b3347a263d3, - 0x0000000000000000,0x77e3dcb62d4753c1,0xdb05aa39286523b1,0x0000000000000000, - 0xf9ddaa0914b809a1,0x0000000000000000,0xc6f60bbdf7c8c073,0x3165da52e44f8393, - 0x0000000000000000,0x0000000000000000,0xa47e4b32f4f66927,0x0000000000000000, - 0xf9ddaa0914dd4631,0x0000000000000000,0xa47e4b322642ad51,0x0000000000000000, - 0x0000000000000000,0x0000000000000000,0x0000000000000000,0x0000000000000000, - 0xa47e4b335ea331b5,0x0000000000000000,0x0000000000000000,0x0000000000000000, - 0xdb0545d45d35a161,0xeca54fbddbbe34ff,0x44a0daa872c59baf,0x0000000000000000, - 0xf9ddaa0914c5876b,0x0000000000000000,0x501eeeb814fa0b79,0xf9ddaa0914df8d85, - 0xf9ddaa0914b167f3, +u64 cpp_main_keys_hash_array[121] = { +0x0000000000000000,0x03cf3a59df2800d7,0x31804e296403b305,0x3b709b613539c371, +0x3b709aad95fb97b3,0x0000000000000000,0x14996033a5460d1b,0x3180604229f03e4d, +0x0000000000000000,0x0000000000000000,0x14996033a7e5b03b,0x0000000000000000, +0x03cf3a58ab580caf,0x0000000000000000,0x0000000000000000,0x1901b5d07bbd53e1, +0x3180496d6573ea51,0x0000000000000000,0x0000000000000000,0x0000000000000000, +0x0000000000000000,0x0000000000000000,0x3b709aaa9c896d6b,0xf11624614cefdacf, +0x3b709b7949044f87,0x0000000000000000,0x3b709aaa14b4549f,0xf114e97ba34018a3, +0x3180604229f29813,0x0000000000000000,0x1904509dbde2a353,0x03cf3a596f0f2511, +0x14996033a5507959,0x0000000000000000,0x5f3f9fc0d0a0c93f,0x03cf3a58b58c753b, +0x0000000000000000,0x0000000000000000,0xf10f7eff9095fb23,0x3b709aaa68405a55, +0x3b709b61a18cc255,0x3b709aaa7edd8723,0x0000000000000000,0xc8abc849dbd6ac9f, +0x0000000000000000,0x7e5f4ab862627b7b,0x0000000000000000,0x0000000000000000, +0xf114b8e386ce372d,0x14996033a5580e25,0x0000000000000000,0x14996033a7d21aed, +0x3b709b61a19e76af,0x0000000000000000,0x14996033ab0ae5d3,0x14996033a5509f41, +0x0000000000000000,0x0000000000000000,0x0000000000000000,0x03cf3a58b646fa01, +0xf10e5cfb2d0856c9,0x8d730a2abbb45b53,0x0000000000000000,0x3b709b4626a5db05, +0x0000000000000000,0x03cf3a59de20fa7b,0x0000000000000000,0x14996033a6b2b45f, +0xf10f17d125465a91,0x03cf3a59dfc04c9f,0x5f3f9fc0d0a0ba41,0x0000000000000000, +0x5f3f9fc0d0a6ec81,0x0000000000000000,0x3b709aaa4a86002b,0x0000000000000000, +0x0000000000000000,0x5f3f9fc0d0a00819,0x0000000000000000,0x0000000000000000, +0xc8abc849dbd6adb5,0x0000000000000000,0x0000000000000000,0x0000000000000000, +0x5f3f9fc0d0a0d087,0x0000000000000000,0x0000000000000000,0x31806cea0e7fbb29, +0x0000000000000000,0x0000000000000000,0x31806c8004d41f17,0x3b709b468ffbb151, +0x03cf3a59df3fc9f3,0x1744d2f34117d803,0x0000000000000000,0x0000000000000000, +0x0000000000000000,0x0000000000000000,0x03cf3a596ff8a353,0x0000000000000000, +0x0000000000000000,0x1a21e4856eaac353,0x3b709aaa7cdf92c5,0x0000000000000000, +0x14996033a553c5cb,0x03cf3a58b52cfddd,0x0000000000000000,0x31804dc503d40aab, +0x0a1c76541b3d4ccf,0x9721eca88effbb53,0xf10ea2bb4912c001,0x14996033a54db691, +0x0000000000000000,0xf1165cbc0c8e31e1,0xf10e41346ef0ed11,0x0000000000000000, +0x0000000000000000,0x0000000000000000,0x3b709aaa4b875f33,0xf10f7c240be83eed, +0x0000000000000000, }; -u8 main_keys_key_array_0[] = {0x63,0x61,0x74,0x63,0x68,}; -u8 main_keys_key_array_2[] = {0x75,0x6e,0x69,0x6f,0x6e,}; -u8 main_keys_key_array_6[] = {0x75,0x73,0x69,0x6e,0x67,}; -u8 main_keys_key_array_7[] = {0x76,0x69,0x72,0x74,0x75,0x61,0x6c,}; -u8 main_keys_key_array_8[] = {0x66,0x6c,0x6f,0x61,0x74,}; -u8 main_keys_key_array_13[] = {0x73,0x74,0x61,0x74,0x69,0x63,}; -u8 main_keys_key_array_14[] = {0x69,0x6e,0x6c,0x69,0x6e,0x65,}; -u8 main_keys_key_array_15[] = {0x74,0x72,0x75,0x65,}; -u8 main_keys_key_array_16[] = {0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x5f,0x63,0x61,0x73,0x74,}; -u8 main_keys_key_array_19[] = {0x73,0x69,0x7a,0x65,0x6f,0x66,}; -u8 main_keys_key_array_21[] = {0x74,0x65,0x6d,0x70,0x6c,0x61,0x74,0x65,}; -u8 main_keys_key_array_22[] = {0x74,0x68,0x69,0x73,}; -u8 main_keys_key_array_23[] = {0x61,0x6c,0x69,0x67,0x6e,0x61,0x73,}; -u8 main_keys_key_array_25[] = {0x77,0x68,0x69,0x6c,0x65,}; -u8 main_keys_key_array_27[] = {0x74,0x79,0x70,0x65,0x6e,0x61,0x6d,0x65,}; -u8 main_keys_key_array_29[] = {0x73,0x77,0x69,0x74,0x63,0x68,}; -u8 main_keys_key_array_30[] = {0x65,0x78,0x70,0x6c,0x69,0x63,0x69,0x74,}; -u8 main_keys_key_array_32[] = {0x73,0x74,0x61,0x74,0x69,0x63,0x5f,0x63,0x61,0x73,0x74,}; -u8 main_keys_key_array_34[] = {0x62,0x72,0x65,0x61,0x6b,}; -u8 main_keys_key_array_35[] = {0x74,0x72,0x79,}; -u8 main_keys_key_array_37[] = {0x64,0x65,0x63,0x6c,0x74,0x79,0x70,0x65,}; -u8 main_keys_key_array_40[] = {0x70,0x72,0x69,0x76,0x61,0x74,0x65,}; -u8 main_keys_key_array_43[] = {0x73,0x68,0x6f,0x72,0x74,}; -u8 main_keys_key_array_44[] = {0x74,0x79,0x70,0x65,0x69,0x64,}; -u8 main_keys_key_array_45[] = {0x61,0x6c,0x69,0x67,0x6e,0x6f,0x66,}; -u8 main_keys_key_array_46[] = {0x6e,0x6f,0x65,0x78,0x63,0x65,0x70,0x74,}; -u8 main_keys_key_array_48[] = {0x72,0x65,0x69,0x6e,0x74,0x65,0x72,0x70,0x72,0x65,0x74,0x5f,0x63,0x61,0x73,0x74,}; -u8 main_keys_key_array_50[] = {0x67,0x6f,0x74,0x6f,}; -u8 main_keys_key_array_51[] = {0x70,0x72,0x6f,0x74,0x65,0x63,0x74,0x65,0x64,}; -u8 main_keys_key_array_52[] = {0x65,0x78,0x70,0x6f,0x72,0x74,}; -u8 main_keys_key_array_55[] = {0x66,0x61,0x6c,0x73,0x65,}; -u8 main_keys_key_array_56[] = {0x65,0x78,0x74,0x65,0x72,0x6e,}; -u8 main_keys_key_array_57[] = {0x63,0x6c,0x61,0x73,0x73,}; -u8 main_keys_key_array_60[] = {0x73,0x69,0x67,0x6e,0x65,0x64,}; -u8 main_keys_key_array_63[] = {0x70,0x75,0x62,0x6c,0x69,0x63,}; -u8 main_keys_key_array_66[] = {0x69,0x6e,0x74,}; -u8 main_keys_key_array_67[] = {0x64,0x65,0x66,0x61,0x75,0x6c,0x74,}; -u8 main_keys_key_array_71[] = {0x63,0x68,0x61,0x72,}; -u8 main_keys_key_array_73[] = {0x6c,0x6f,0x6e,0x67,}; -u8 main_keys_key_array_75[] = {0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,}; -u8 main_keys_key_array_76[] = {0x66,0x6f,0x72,}; -u8 main_keys_key_array_77[] = {0x74,0x68,0x72,0x65,0x61,0x64,0x5f,0x6c,0x6f,0x63,0x61,0x6c,}; -u8 main_keys_key_array_78[] = {0x6e,0x65,0x77,}; -u8 main_keys_key_array_80[] = {0x75,0x6e,0x73,0x69,0x67,0x6e,0x65,0x64,}; -u8 main_keys_key_array_81[] = {0x6e,0x75,0x6c,0x6c,0x70,0x74,0x72,}; -u8 main_keys_key_array_82[] = {0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,}; -u8 main_keys_key_array_83[] = {0x74,0x79,0x70,0x65,0x64,0x65,0x66,}; -u8 main_keys_key_array_84[] = {0x64,0x65,0x6c,0x65,0x74,0x65,}; -u8 main_keys_key_array_86[] = {0x69,0x66,}; -u8 main_keys_key_array_87[] = {0x73,0x74,0x72,0x75,0x63,0x74,}; -u8 main_keys_key_array_89[] = {0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,}; -u8 main_keys_key_array_90[] = {0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,}; -u8 main_keys_key_array_92[] = {0x63,0x61,0x73,0x65,}; -u8 main_keys_key_array_94[] = {0x63,0x6f,0x6e,0x73,0x74,0x5f,0x63,0x61,0x73,0x74,}; -u8 main_keys_key_array_95[] = {0x63,0x6f,0x6e,0x73,0x74,}; -u8 main_keys_key_array_98[] = {0x66,0x72,0x69,0x65,0x6e,0x64,}; -u8 main_keys_key_array_100[] = {0x65,0x6c,0x73,0x65,}; -u8 main_keys_key_array_102[] = {0x64,0x6f,0x75,0x62,0x6c,0x65,}; -u8 main_keys_key_array_108[] = {0x72,0x65,0x74,0x75,0x72,0x6e,}; -u8 main_keys_key_array_112[] = {0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,}; -u8 main_keys_key_array_113[] = {0x64,0x6f,}; -u8 main_keys_key_array_114[] = {0x73,0x74,0x61,0x74,0x69,0x63,0x5f,0x61,0x73,0x73,0x65,0x72,0x74,}; -u8 main_keys_key_array_116[] = {0x62,0x6f,0x6f,0x6c,}; -u8 main_keys_key_array_118[] = {0x61,0x73,0x6d,}; -u8 main_keys_key_array_119[] = {0x65,0x6e,0x75,0x6d,}; -u8 main_keys_key_array_120[] = {0x76,0x6f,0x69,0x64,}; -String_Const_u8 main_keys_key_array[121] = { - {main_keys_key_array_0, 5}, - {0, 0}, - {main_keys_key_array_2, 5}, - {0, 0}, - {0, 0}, - {0, 0}, - {main_keys_key_array_6, 5}, - {main_keys_key_array_7, 7}, - {main_keys_key_array_8, 5}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {main_keys_key_array_13, 6}, - {main_keys_key_array_14, 6}, - {main_keys_key_array_15, 4}, - {main_keys_key_array_16, 12}, - {0, 0}, - {0, 0}, - {main_keys_key_array_19, 6}, - {0, 0}, - {main_keys_key_array_21, 8}, - {main_keys_key_array_22, 4}, - {main_keys_key_array_23, 7}, - {0, 0}, - {main_keys_key_array_25, 5}, - {0, 0}, - {main_keys_key_array_27, 8}, - {0, 0}, - {main_keys_key_array_29, 6}, - {main_keys_key_array_30, 8}, - {0, 0}, - {main_keys_key_array_32, 11}, - {0, 0}, - {main_keys_key_array_34, 5}, - {main_keys_key_array_35, 3}, - {0, 0}, - {main_keys_key_array_37, 8}, - {0, 0}, - {0, 0}, - {main_keys_key_array_40, 7}, - {0, 0}, - {0, 0}, - {main_keys_key_array_43, 5}, - {main_keys_key_array_44, 6}, - {main_keys_key_array_45, 7}, - {main_keys_key_array_46, 8}, - {0, 0}, - {main_keys_key_array_48, 16}, - {0, 0}, - {main_keys_key_array_50, 4}, - {main_keys_key_array_51, 9}, - {main_keys_key_array_52, 6}, - {0, 0}, - {0, 0}, - {main_keys_key_array_55, 5}, - {main_keys_key_array_56, 6}, - {main_keys_key_array_57, 5}, - {0, 0}, - {0, 0}, - {main_keys_key_array_60, 6}, - {0, 0}, - {0, 0}, - {main_keys_key_array_63, 6}, - {0, 0}, - {0, 0}, - {main_keys_key_array_66, 3}, - {main_keys_key_array_67, 7}, - {0, 0}, - {0, 0}, - {0, 0}, - {main_keys_key_array_71, 4}, - {0, 0}, - {main_keys_key_array_73, 4}, - {0, 0}, - {main_keys_key_array_75, 8}, - {main_keys_key_array_76, 3}, - {main_keys_key_array_77, 12}, - {main_keys_key_array_78, 3}, - {0, 0}, - {main_keys_key_array_80, 8}, - {main_keys_key_array_81, 7}, - {main_keys_key_array_82, 8}, - {main_keys_key_array_83, 7}, - {main_keys_key_array_84, 6}, - {0, 0}, - {main_keys_key_array_86, 2}, - {main_keys_key_array_87, 6}, - {0, 0}, - {main_keys_key_array_89, 9}, - {main_keys_key_array_90, 8}, - {0, 0}, - {main_keys_key_array_92, 4}, - {0, 0}, - {main_keys_key_array_94, 10}, - {main_keys_key_array_95, 5}, - {0, 0}, - {0, 0}, - {main_keys_key_array_98, 6}, - {0, 0}, - {main_keys_key_array_100, 4}, - {0, 0}, - {main_keys_key_array_102, 6}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {main_keys_key_array_108, 6}, - {0, 0}, - {0, 0}, - {0, 0}, - {main_keys_key_array_112, 8}, - {main_keys_key_array_113, 2}, - {main_keys_key_array_114, 13}, - {0, 0}, - {main_keys_key_array_116, 4}, - {0, 0}, - {main_keys_key_array_118, 3}, - {main_keys_key_array_119, 4}, - {main_keys_key_array_120, 4}, +u8 cpp_main_keys_key_array_1[] = {0x63,0x6c,0x61,0x73,0x73,}; +u8 cpp_main_keys_key_array_2[] = {0x74,0x79,0x70,0x65,0x64,0x65,0x66,}; +u8 cpp_main_keys_key_array_3[] = {0x64,0x6f,0x75,0x62,0x6c,0x65,}; +u8 cpp_main_keys_key_array_4[] = {0x74,0x79,0x70,0x65,0x69,0x64,}; +u8 cpp_main_keys_key_array_6[] = {0x6c,0x6f,0x6e,0x67,}; +u8 cpp_main_keys_key_array_7[] = {0x61,0x6c,0x69,0x67,0x6e,0x6f,0x66,}; +u8 cpp_main_keys_key_array_10[] = {0x74,0x68,0x69,0x73,}; +u8 cpp_main_keys_key_array_12[] = {0x73,0x68,0x6f,0x72,0x74,}; +u8 cpp_main_keys_key_array_15[] = {0x6e,0x61,0x6d,0x65,0x73,0x70,0x61,0x63,0x65,}; +u8 cpp_main_keys_key_array_16[] = {0x70,0x72,0x69,0x76,0x61,0x74,0x65,}; +u8 cpp_main_keys_key_array_22[] = {0x70,0x75,0x62,0x6c,0x69,0x63,}; +u8 cpp_main_keys_key_array_23[] = {0x6e,0x6f,0x65,0x78,0x63,0x65,0x70,0x74,}; +u8 cpp_main_keys_key_array_24[] = {0x66,0x72,0x69,0x65,0x6e,0x64,}; +u8 cpp_main_keys_key_array_26[] = {0x73,0x77,0x69,0x74,0x63,0x68,}; +u8 cpp_main_keys_key_array_27[] = {0x65,0x78,0x70,0x6c,0x69,0x63,0x69,0x74,}; +u8 cpp_main_keys_key_array_28[] = {0x61,0x6c,0x69,0x67,0x6e,0x61,0x73,}; +u8 cpp_main_keys_key_array_30[] = {0x73,0x74,0x61,0x74,0x69,0x63,0x5f,0x63,0x61,0x73,0x74,}; +u8 cpp_main_keys_key_array_31[] = {0x66,0x61,0x6c,0x73,0x65,}; +u8 cpp_main_keys_key_array_32[] = {0x63,0x68,0x61,0x72,}; +u8 cpp_main_keys_key_array_34[] = {0x6e,0x65,0x77,}; +u8 cpp_main_keys_key_array_35[] = {0x75,0x73,0x69,0x6e,0x67,}; +u8 cpp_main_keys_key_array_38[] = {0x75,0x6e,0x73,0x69,0x67,0x6e,0x65,0x64,}; +u8 cpp_main_keys_key_array_39[] = {0x72,0x65,0x74,0x75,0x72,0x6e,}; +u8 cpp_main_keys_key_array_40[] = {0x65,0x78,0x74,0x65,0x72,0x6e,}; +u8 cpp_main_keys_key_array_41[] = {0x73,0x69,0x67,0x6e,0x65,0x64,}; +u8 cpp_main_keys_key_array_43[] = {0x64,0x6f,}; +u8 cpp_main_keys_key_array_45[] = {0x74,0x68,0x72,0x65,0x61,0x64,0x5f,0x6c,0x6f,0x63,0x61,0x6c,}; +u8 cpp_main_keys_key_array_48[] = {0x63,0x6f,0x6e,0x74,0x69,0x6e,0x75,0x65,}; +u8 cpp_main_keys_key_array_49[] = {0x65,0x6e,0x75,0x6d,}; +u8 cpp_main_keys_key_array_51[] = {0x74,0x72,0x75,0x65,}; +u8 cpp_main_keys_key_array_52[] = {0x65,0x78,0x70,0x6f,0x72,0x74,}; +u8 cpp_main_keys_key_array_54[] = {0x76,0x6f,0x69,0x64,}; +u8 cpp_main_keys_key_array_55[] = {0x63,0x61,0x73,0x65,}; +u8 cpp_main_keys_key_array_59[] = {0x77,0x68,0x69,0x6c,0x65,}; +u8 cpp_main_keys_key_array_60[] = {0x6f,0x70,0x65,0x72,0x61,0x74,0x6f,0x72,}; +u8 cpp_main_keys_key_array_61[] = {0x63,0x6f,0x6e,0x73,0x74,0x5f,0x63,0x61,0x73,0x74,}; +u8 cpp_main_keys_key_array_63[] = {0x69,0x6e,0x6c,0x69,0x6e,0x65,}; +u8 cpp_main_keys_key_array_65[] = {0x62,0x72,0x65,0x61,0x6b,}; +u8 cpp_main_keys_key_array_67[] = {0x67,0x6f,0x74,0x6f,}; +u8 cpp_main_keys_key_array_68[] = {0x74,0x65,0x6d,0x70,0x6c,0x61,0x74,0x65,}; +u8 cpp_main_keys_key_array_69[] = {0x63,0x61,0x74,0x63,0x68,}; +u8 cpp_main_keys_key_array_70[] = {0x66,0x6f,0x72,}; +u8 cpp_main_keys_key_array_72[] = {0x74,0x72,0x79,}; +u8 cpp_main_keys_key_array_74[] = {0x73,0x74,0x61,0x74,0x69,0x63,}; +u8 cpp_main_keys_key_array_77[] = {0x61,0x73,0x6d,}; +u8 cpp_main_keys_key_array_80[] = {0x69,0x66,}; +u8 cpp_main_keys_key_array_84[] = {0x69,0x6e,0x74,}; +u8 cpp_main_keys_key_array_87[] = {0x6e,0x75,0x6c,0x6c,0x70,0x74,0x72,}; +u8 cpp_main_keys_key_array_90[] = {0x64,0x65,0x66,0x61,0x75,0x6c,0x74,}; +u8 cpp_main_keys_key_array_91[] = {0x64,0x65,0x6c,0x65,0x74,0x65,}; +u8 cpp_main_keys_key_array_92[] = {0x63,0x6f,0x6e,0x73,0x74,}; +u8 cpp_main_keys_key_array_93[] = {0x70,0x72,0x6f,0x74,0x65,0x63,0x74,0x65,0x64,}; +u8 cpp_main_keys_key_array_98[] = {0x66,0x6c,0x6f,0x61,0x74,}; +u8 cpp_main_keys_key_array_101[] = {0x64,0x79,0x6e,0x61,0x6d,0x69,0x63,0x5f,0x63,0x61,0x73,0x74,}; +u8 cpp_main_keys_key_array_102[] = {0x73,0x69,0x7a,0x65,0x6f,0x66,}; +u8 cpp_main_keys_key_array_104[] = {0x62,0x6f,0x6f,0x6c,}; +u8 cpp_main_keys_key_array_105[] = {0x75,0x6e,0x69,0x6f,0x6e,}; +u8 cpp_main_keys_key_array_107[] = {0x76,0x69,0x72,0x74,0x75,0x61,0x6c,}; +u8 cpp_main_keys_key_array_108[] = {0x73,0x74,0x61,0x74,0x69,0x63,0x5f,0x61,0x73,0x73,0x65,0x72,0x74,}; +u8 cpp_main_keys_key_array_109[] = {0x72,0x65,0x69,0x6e,0x74,0x65,0x72,0x70,0x72,0x65,0x74,0x5f,0x63,0x61,0x73,0x74,}; +u8 cpp_main_keys_key_array_110[] = {0x76,0x6f,0x6c,0x61,0x74,0x69,0x6c,0x65,}; +u8 cpp_main_keys_key_array_111[] = {0x65,0x6c,0x73,0x65,}; +u8 cpp_main_keys_key_array_113[] = {0x64,0x65,0x63,0x6c,0x74,0x79,0x70,0x65,}; +u8 cpp_main_keys_key_array_114[] = {0x72,0x65,0x67,0x69,0x73,0x74,0x65,0x72,}; +u8 cpp_main_keys_key_array_118[] = {0x73,0x74,0x72,0x75,0x63,0x74,}; +u8 cpp_main_keys_key_array_119[] = {0x74,0x79,0x70,0x65,0x6e,0x61,0x6d,0x65,}; +String_Const_u8 cpp_main_keys_key_array[121] = { +{0, 0}, +{cpp_main_keys_key_array_1, 5}, +{cpp_main_keys_key_array_2, 7}, +{cpp_main_keys_key_array_3, 6}, +{cpp_main_keys_key_array_4, 6}, +{0, 0}, +{cpp_main_keys_key_array_6, 4}, +{cpp_main_keys_key_array_7, 7}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_10, 4}, +{0, 0}, +{cpp_main_keys_key_array_12, 5}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_15, 9}, +{cpp_main_keys_key_array_16, 7}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_22, 6}, +{cpp_main_keys_key_array_23, 8}, +{cpp_main_keys_key_array_24, 6}, +{0, 0}, +{cpp_main_keys_key_array_26, 6}, +{cpp_main_keys_key_array_27, 8}, +{cpp_main_keys_key_array_28, 7}, +{0, 0}, +{cpp_main_keys_key_array_30, 11}, +{cpp_main_keys_key_array_31, 5}, +{cpp_main_keys_key_array_32, 4}, +{0, 0}, +{cpp_main_keys_key_array_34, 3}, +{cpp_main_keys_key_array_35, 5}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_38, 8}, +{cpp_main_keys_key_array_39, 6}, +{cpp_main_keys_key_array_40, 6}, +{cpp_main_keys_key_array_41, 6}, +{0, 0}, +{cpp_main_keys_key_array_43, 2}, +{0, 0}, +{cpp_main_keys_key_array_45, 12}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_48, 8}, +{cpp_main_keys_key_array_49, 4}, +{0, 0}, +{cpp_main_keys_key_array_51, 4}, +{cpp_main_keys_key_array_52, 6}, +{0, 0}, +{cpp_main_keys_key_array_54, 4}, +{cpp_main_keys_key_array_55, 4}, +{0, 0}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_59, 5}, +{cpp_main_keys_key_array_60, 8}, +{cpp_main_keys_key_array_61, 10}, +{0, 0}, +{cpp_main_keys_key_array_63, 6}, +{0, 0}, +{cpp_main_keys_key_array_65, 5}, +{0, 0}, +{cpp_main_keys_key_array_67, 4}, +{cpp_main_keys_key_array_68, 8}, +{cpp_main_keys_key_array_69, 5}, +{cpp_main_keys_key_array_70, 3}, +{0, 0}, +{cpp_main_keys_key_array_72, 3}, +{0, 0}, +{cpp_main_keys_key_array_74, 6}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_77, 3}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_80, 2}, +{0, 0}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_84, 3}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_87, 7}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_90, 7}, +{cpp_main_keys_key_array_91, 6}, +{cpp_main_keys_key_array_92, 5}, +{cpp_main_keys_key_array_93, 9}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_98, 5}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_101, 12}, +{cpp_main_keys_key_array_102, 6}, +{0, 0}, +{cpp_main_keys_key_array_104, 4}, +{cpp_main_keys_key_array_105, 5}, +{0, 0}, +{cpp_main_keys_key_array_107, 7}, +{cpp_main_keys_key_array_108, 13}, +{cpp_main_keys_key_array_109, 16}, +{cpp_main_keys_key_array_110, 8}, +{cpp_main_keys_key_array_111, 4}, +{0, 0}, +{cpp_main_keys_key_array_113, 8}, +{cpp_main_keys_key_array_114, 8}, +{0, 0}, +{0, 0}, +{0, 0}, +{cpp_main_keys_key_array_118, 6}, +{cpp_main_keys_key_array_119, 8}, +{0, 0}, }; -Lexeme_Table_Value main_keys_value_array[121] = { - {4, TokenCppKind_Catch}, - {0, 0}, - {4, TokenCppKind_Union}, - {0, 0}, - {0, 0}, - {0, 0}, - {4, TokenCppKind_Using}, - {4, TokenCppKind_Virtual}, - {4, TokenCppKind_Float}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {4, TokenCppKind_Static}, - {4, TokenCppKind_Inline}, - {8, TokenCppKind_LiteralTrue}, - {4, TokenCppKind_DynamicCast}, - {0, 0}, - {0, 0}, - {4, TokenCppKind_SizeOf}, - {0, 0}, - {4, TokenCppKind_Template}, - {4, TokenCppKind_This}, - {4, TokenCppKind_AlignAs}, - {0, 0}, - {4, TokenCppKind_While}, - {0, 0}, - {4, TokenCppKind_Typename}, - {0, 0}, - {4, TokenCppKind_Switch}, - {4, TokenCppKind_Explicit}, - {0, 0}, - {4, TokenCppKind_StaticCast}, - {0, 0}, - {4, TokenCppKind_Break}, - {4, TokenCppKind_Try}, - {0, 0}, - {4, TokenCppKind_DeclType}, - {0, 0}, - {0, 0}, - {4, TokenCppKind_Private}, - {0, 0}, - {0, 0}, - {4, TokenCppKind_Short}, - {4, TokenCppKind_TypeID}, - {4, TokenCppKind_AlignOf}, - {4, TokenCppKind_NoExcept}, - {0, 0}, - {4, TokenCppKind_ReinterpretCast}, - {0, 0}, - {4, TokenCppKind_Goto}, - {4, TokenCppKind_Protected}, - {4, TokenCppKind_Export}, - {0, 0}, - {0, 0}, - {8, TokenCppKind_LiteralFalse}, - {4, TokenCppKind_Extern}, - {4, TokenCppKind_Class}, - {0, 0}, - {0, 0}, - {4, TokenCppKind_Signed}, - {0, 0}, - {0, 0}, - {4, TokenCppKind_Public}, - {0, 0}, - {0, 0}, - {4, TokenCppKind_Int}, - {4, TokenCppKind_Default}, - {0, 0}, - {0, 0}, - {0, 0}, - {4, TokenCppKind_Char}, - {0, 0}, - {4, TokenCppKind_Long}, - {0, 0}, - {4, TokenCppKind_Continue}, - {4, TokenCppKind_For}, - {4, TokenCppKind_ThreadLocal}, - {4, TokenCppKind_New}, - {0, 0}, - {4, TokenCppKind_Unsigned}, - {4, TokenCppKind_NullPtr}, - {4, TokenCppKind_Operator}, - {4, TokenCppKind_Typedef}, - {4, TokenCppKind_Delete}, - {0, 0}, - {4, TokenCppKind_If}, - {4, TokenCppKind_Struct}, - {0, 0}, - {4, TokenCppKind_Namespace}, - {4, TokenCppKind_Register}, - {0, 0}, - {4, TokenCppKind_Case}, - {0, 0}, - {4, TokenCppKind_ConstCast}, - {4, TokenCppKind_Const}, - {0, 0}, - {0, 0}, - {4, TokenCppKind_Friend}, - {0, 0}, - {4, TokenCppKind_Else}, - {0, 0}, - {4, TokenCppKind_Double}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {0, 0}, - {4, TokenCppKind_Return}, - {0, 0}, - {0, 0}, - {0, 0}, - {4, TokenCppKind_Volatile}, - {4, TokenCppKind_Do}, - {4, TokenCppKind_StaticAssert}, - {0, 0}, - {4, TokenCppKind_Bool}, - {0, 0}, - {4, TokenCppKind_Asm}, - {4, TokenCppKind_Enum}, - {4, TokenCppKind_Void}, +Lexeme_Table_Value cpp_main_keys_value_array[121] = { +{0, 0}, +{4, TokenCppKind_Class}, +{4, TokenCppKind_Typedef}, +{4, TokenCppKind_Double}, +{4, TokenCppKind_TypeID}, +{0, 0}, +{4, TokenCppKind_Long}, +{4, TokenCppKind_AlignOf}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_This}, +{0, 0}, +{4, TokenCppKind_Short}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_Namespace}, +{4, TokenCppKind_Private}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_Public}, +{4, TokenCppKind_NoExcept}, +{4, TokenCppKind_Friend}, +{0, 0}, +{4, TokenCppKind_Switch}, +{4, TokenCppKind_Explicit}, +{4, TokenCppKind_AlignAs}, +{0, 0}, +{4, TokenCppKind_StaticCast}, +{8, TokenCppKind_LiteralFalse}, +{4, TokenCppKind_Char}, +{0, 0}, +{4, TokenCppKind_New}, +{4, TokenCppKind_Using}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_Unsigned}, +{4, TokenCppKind_Return}, +{4, TokenCppKind_Extern}, +{4, TokenCppKind_Signed}, +{0, 0}, +{4, TokenCppKind_Do}, +{0, 0}, +{4, TokenCppKind_ThreadLocal}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_Continue}, +{4, TokenCppKind_Enum}, +{0, 0}, +{8, TokenCppKind_LiteralTrue}, +{4, TokenCppKind_Export}, +{0, 0}, +{4, TokenCppKind_Void}, +{4, TokenCppKind_Case}, +{0, 0}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_While}, +{4, TokenCppKind_Operator}, +{4, TokenCppKind_ConstCast}, +{0, 0}, +{4, TokenCppKind_Inline}, +{0, 0}, +{4, TokenCppKind_Break}, +{0, 0}, +{4, TokenCppKind_Goto}, +{4, TokenCppKind_Template}, +{4, TokenCppKind_Catch}, +{4, TokenCppKind_For}, +{0, 0}, +{4, TokenCppKind_Try}, +{0, 0}, +{4, TokenCppKind_Static}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_Asm}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_If}, +{0, 0}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_Int}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_NullPtr}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_Default}, +{4, TokenCppKind_Delete}, +{4, TokenCppKind_Const}, +{4, TokenCppKind_Protected}, +{0, 0}, +{0, 0}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_Float}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_DynamicCast}, +{4, TokenCppKind_SizeOf}, +{0, 0}, +{4, TokenCppKind_Bool}, +{4, TokenCppKind_Union}, +{0, 0}, +{4, TokenCppKind_Virtual}, +{4, TokenCppKind_StaticAssert}, +{4, TokenCppKind_ReinterpretCast}, +{4, TokenCppKind_Volatile}, +{4, TokenCppKind_Else}, +{0, 0}, +{4, TokenCppKind_DeclType}, +{4, TokenCppKind_Register}, +{0, 0}, +{0, 0}, +{0, 0}, +{4, TokenCppKind_Struct}, +{4, TokenCppKind_Typename}, +{0, 0}, }; -i32 main_keys_slot_count = 121; -u64 main_keys_seed = 0x32a240442a6e221f; -u64 pp_directives_hash_array[25] = { - 0xa8f3b0d79807b793,0x808ba552d670368f,0x0000000000000000,0x808ba54dc047d94b, - 0x3b97f7088cbf95df,0x7fd91d3d238e04c9,0x0000000000000000,0x7fd91d3dac09e067, - 0x0000000000000000,0x0000000000000000,0xa8f3beab5b880ad3,0x0000000000000000, - 0x3b97f7088cbffd3b,0x3b97f7088cdab44b,0x79521904bb682f3f,0x0000000000000000, - 0x0000000000000000,0x7fd91d3d978c615f,0x808ba553ad911e19,0x0000000000000000, - 0x808ba54ef8496067,0x7fd91d3d2fe85067,0x7fd91d3d97a21607,0x0000000000000000, - 0x0000000000000000, +i32 cpp_main_keys_slot_count = 121; +u64 cpp_main_keys_seed = 0x57fd2e8360fc723f; +u64 cpp_pp_directives_hash_array[25] = { +0x0000000000000000,0x0000000000000000,0xfcbe0e69ab5f0ab5,0x0000000000000000, +0xdfa7f6eb98ca462d,0xdfa7f6ebae1c243d,0x26e6293f7c60a9d7,0x0000000000000000, +0xfcbe0e6b92eff62d,0x0000000000000000,0xdfa7f6604dbd1a65,0xfcbe0e69ab4edf49, +0x0000000000000000,0xdfa7f6ee4efdc3a3,0xfcbe0e6b014df297,0x26e6293f7c60632d, +0x0000000000000000,0xfcbe0e6b09dcce2d,0x0000000000000000,0x0000000000000000, +0x26e6293f722aa025,0xa6ba73c3a74f4285,0xb0a57847c3818ea9,0x0000000000000000, +0xb0a595ffc01d0bd5, }; -u8 pp_directives_key_array_0[] = {0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,}; -u8 pp_directives_key_array_1[] = {0x70,0x72,0x61,0x67,0x6d,0x61,}; -u8 pp_directives_key_array_3[] = {0x64,0x65,0x66,0x69,0x6e,0x65,}; -u8 pp_directives_key_array_4[] = {0x65,0x6c,0x69,0x66,}; -u8 pp_directives_key_array_5[] = {0x75,0x73,0x69,0x6e,0x67,}; -u8 pp_directives_key_array_7[] = {0x69,0x66,0x64,0x65,0x66,}; -u8 pp_directives_key_array_10[] = {0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,}; -u8 pp_directives_key_array_12[] = {0x65,0x6c,0x73,0x65,}; -u8 pp_directives_key_array_13[] = {0x6c,0x69,0x6e,0x65,}; -u8 pp_directives_key_array_14[] = {0x69,0x66,}; -u8 pp_directives_key_array_17[] = {0x65,0x6e,0x64,0x69,0x66,}; -u8 pp_directives_key_array_18[] = {0x69,0x6d,0x70,0x6f,0x72,0x74,}; -u8 pp_directives_key_array_20[] = {0x69,0x66,0x6e,0x64,0x65,0x66,}; -u8 pp_directives_key_array_21[] = {0x75,0x6e,0x64,0x65,0x66,}; -u8 pp_directives_key_array_22[] = {0x65,0x72,0x72,0x6f,0x72,}; -String_Const_u8 pp_directives_key_array[25] = { - {pp_directives_key_array_0, 7}, - {pp_directives_key_array_1, 6}, - {0, 0}, - {pp_directives_key_array_3, 6}, - {pp_directives_key_array_4, 4}, - {pp_directives_key_array_5, 5}, - {0, 0}, - {pp_directives_key_array_7, 5}, - {0, 0}, - {0, 0}, - {pp_directives_key_array_10, 7}, - {0, 0}, - {pp_directives_key_array_12, 4}, - {pp_directives_key_array_13, 4}, - {pp_directives_key_array_14, 2}, - {0, 0}, - {0, 0}, - {pp_directives_key_array_17, 5}, - {pp_directives_key_array_18, 6}, - {0, 0}, - {pp_directives_key_array_20, 6}, - {pp_directives_key_array_21, 5}, - {pp_directives_key_array_22, 5}, - {0, 0}, - {0, 0}, +u8 cpp_pp_directives_key_array_2[] = {0x65,0x6e,0x64,0x69,0x66,}; +u8 cpp_pp_directives_key_array_4[] = {0x69,0x66,0x6e,0x64,0x65,0x66,}; +u8 cpp_pp_directives_key_array_5[] = {0x69,0x6d,0x70,0x6f,0x72,0x74,}; +u8 cpp_pp_directives_key_array_6[] = {0x65,0x6c,0x73,0x65,}; +u8 cpp_pp_directives_key_array_8[] = {0x69,0x66,0x64,0x65,0x66,}; +u8 cpp_pp_directives_key_array_10[] = {0x64,0x65,0x66,0x69,0x6e,0x65,}; +u8 cpp_pp_directives_key_array_11[] = {0x65,0x72,0x72,0x6f,0x72,}; +u8 cpp_pp_directives_key_array_13[] = {0x70,0x72,0x61,0x67,0x6d,0x61,}; +u8 cpp_pp_directives_key_array_14[] = {0x75,0x73,0x69,0x6e,0x67,}; +u8 cpp_pp_directives_key_array_15[] = {0x65,0x6c,0x69,0x66,}; +u8 cpp_pp_directives_key_array_17[] = {0x75,0x6e,0x64,0x65,0x66,}; +u8 cpp_pp_directives_key_array_20[] = {0x6c,0x69,0x6e,0x65,}; +u8 cpp_pp_directives_key_array_21[] = {0x69,0x66,}; +u8 cpp_pp_directives_key_array_22[] = {0x69,0x6e,0x63,0x6c,0x75,0x64,0x65,}; +u8 cpp_pp_directives_key_array_24[] = {0x76,0x65,0x72,0x73,0x69,0x6f,0x6e,}; +String_Const_u8 cpp_pp_directives_key_array[25] = { +{0, 0}, +{0, 0}, +{cpp_pp_directives_key_array_2, 5}, +{0, 0}, +{cpp_pp_directives_key_array_4, 6}, +{cpp_pp_directives_key_array_5, 6}, +{cpp_pp_directives_key_array_6, 4}, +{0, 0}, +{cpp_pp_directives_key_array_8, 5}, +{0, 0}, +{cpp_pp_directives_key_array_10, 6}, +{cpp_pp_directives_key_array_11, 5}, +{0, 0}, +{cpp_pp_directives_key_array_13, 6}, +{cpp_pp_directives_key_array_14, 5}, +{cpp_pp_directives_key_array_15, 4}, +{0, 0}, +{cpp_pp_directives_key_array_17, 5}, +{0, 0}, +{0, 0}, +{cpp_pp_directives_key_array_20, 4}, +{cpp_pp_directives_key_array_21, 2}, +{cpp_pp_directives_key_array_22, 7}, +{0, 0}, +{cpp_pp_directives_key_array_24, 7}, }; -Lexeme_Table_Value pp_directives_value_array[25] = { - {5, TokenCppKind_PPInclude}, - {5, TokenCppKind_PPPragma}, - {0, 0}, - {5, TokenCppKind_PPDefine}, - {5, TokenCppKind_PPElIf}, - {5, TokenCppKind_PPUsing}, - {0, 0}, - {5, TokenCppKind_PPIfDef}, - {0, 0}, - {0, 0}, - {5, TokenCppKind_PPVersion}, - {0, 0}, - {5, TokenCppKind_PPElse}, - {5, TokenCppKind_PPLine}, - {5, TokenCppKind_PPIf}, - {0, 0}, - {0, 0}, - {5, TokenCppKind_PPEndIf}, - {5, TokenCppKind_PPImport}, - {0, 0}, - {5, TokenCppKind_PPIfNDef}, - {5, TokenCppKind_PPUndef}, - {5, TokenCppKind_PPError}, - {0, 0}, - {0, 0}, +Lexeme_Table_Value cpp_pp_directives_value_array[25] = { +{0, 0}, +{0, 0}, +{5, TokenCppKind_PPEndIf}, +{0, 0}, +{5, TokenCppKind_PPIfNDef}, +{5, TokenCppKind_PPImport}, +{5, TokenCppKind_PPElse}, +{0, 0}, +{5, TokenCppKind_PPIfDef}, +{0, 0}, +{5, TokenCppKind_PPDefine}, +{5, TokenCppKind_PPError}, +{0, 0}, +{5, TokenCppKind_PPPragma}, +{5, TokenCppKind_PPUsing}, +{5, TokenCppKind_PPElIf}, +{0, 0}, +{5, TokenCppKind_PPUndef}, +{0, 0}, +{0, 0}, +{5, TokenCppKind_PPLine}, +{5, TokenCppKind_PPIf}, +{5, TokenCppKind_PPInclude}, +{0, 0}, +{5, TokenCppKind_PPVersion}, }; -i32 pp_directives_slot_count = 25; -u64 pp_directives_seed = 0x8848fb3caaf5d4d5; -u64 pp_keys_hash_array[2] = { - 0x0000000000000000,0x72743f437c9f847d, +i32 cpp_pp_directives_slot_count = 25; +u64 cpp_pp_directives_seed = 0xe34ca5b52cfeb288; +u64 cpp_pp_keys_hash_array[2] = { +0x0000000000000000,0xbef27711d7aba2b5, }; -u8 pp_keys_key_array_1[] = {0x64,0x65,0x66,0x69,0x6e,0x65,0x64,}; -String_Const_u8 pp_keys_key_array[2] = { - {0, 0}, - {pp_keys_key_array_1, 7}, +u8 cpp_pp_keys_key_array_1[] = {0x64,0x65,0x66,0x69,0x6e,0x65,0x64,}; +String_Const_u8 cpp_pp_keys_key_array[2] = { +{0, 0}, +{cpp_pp_keys_key_array_1, 7}, }; -Lexeme_Table_Value pp_keys_value_array[2] = { - {0, 0}, - {4, TokenCppKind_PPDefined}, +Lexeme_Table_Value cpp_pp_keys_value_array[2] = { +{0, 0}, +{4, TokenCppKind_PPDefined}, }; -i32 pp_keys_slot_count = 2; -u64 pp_keys_seed = 0x71428d58f01a7eed; +i32 cpp_pp_keys_slot_count = 2; +u64 cpp_pp_keys_seed = 0x5c61314da2466695; struct Lex_State_Cpp{ - u32 flags_ZF0; - u32 flags_KF0; - u16 flags_KB0; - u8 *base; - u8 *delim_first; - u8 *delim_one_past_last; - u8 *emit_ptr; - u8 *ptr; - u8 *opl_ptr; +u32 flags_ZF0; +u32 flags_KF0; +u16 flags_KB0; +u8 *base; +u8 *delim_first; +u8 *delim_one_past_last; +u8 *emit_ptr; +u8 *ptr; +u8 *opl_ptr; }; internal void lex_full_input_cpp_init(Lex_State_Cpp *state_ptr, String_Const_u8 input){ - state_ptr->flags_ZF0 = 0; - state_ptr->flags_KF0 = 0; - state_ptr->flags_KB0 = 0; - state_ptr->base = input.str; - state_ptr->delim_first = input.str; - state_ptr->delim_one_past_last = input.str; - state_ptr->emit_ptr = input.str; - state_ptr->ptr = input.str; - state_ptr->opl_ptr = input.str + input.size; +state_ptr->flags_ZF0 = 0; +state_ptr->flags_KF0 = 0; +state_ptr->flags_KB0 = 0; +state_ptr->base = input.str; +state_ptr->delim_first = input.str; +state_ptr->delim_one_past_last = input.str; +state_ptr->emit_ptr = input.str; +state_ptr->ptr = input.str; +state_ptr->opl_ptr = input.str + input.size; } internal b32 lex_full_input_cpp_breaks(Arena *arena, Token_List *list, Lex_State_Cpp *state_ptr, u64 max){ - b32 result = false; - u64 emit_counter = 0; - Lex_State_Cpp state; - block_copy_struct(&state, state_ptr); - { - state_label_1: // root - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_EOF; - token.kind = 0; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - result = true; - goto end; - } - } - switch (*state.ptr){ - case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06: - case 0x07:case 0x08:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12: - case 0x13:case 0x14:case 0x15:case 0x16:case 0x17:case 0x18:case 0x19: - case 0x1a:case 0x1b:case 0x1c:case 0x1d:case 0x1e:case 0x1f:case 0x40: - case 0x60:case 0x7f: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x09:case 0x0b:case 0x0c:case 0x0d:case 0x20: - { - if ((HasFlag(state.flags_KF0, 0x2))){ - state.ptr += 1; - goto state_label_4; // error_body - } - state.ptr += 1; - goto state_label_3; // whitespace - }break; - case 0x0a: - { - state.ptr += 1; - state.flags_KB0 &= ~(0x1); - state.flags_KF0 &= ~(0x1); - state.flags_KF0 &= ~(0x2); - goto state_label_3; // whitespace - }break; - case 0x21: - { - state.ptr += 1; - goto state_label_60; // op stage - }break; - case 0x22: - { - if ((HasFlag(state.flags_KF0, 0x1))){ - state.ptr += 1; - goto state_label_26; // include_quotes - } - state.ptr += 1; - goto state_label_32; // string - }break; - case 0x23: - { - if ((!HasFlag(state.flags_KB0, 0x1))){ - state.ptr += 1; - goto state_label_23; // pp_directive_whitespace - } - state.ptr += 1; - goto state_label_67; // op stage - }break; - default: - { - state.ptr += 1; - goto state_label_2; // identifier - }break; - case 0x25: - { - state.ptr += 1; - goto state_label_64; // op stage - }break; - case 0x26: - { - state.ptr += 1; - goto state_label_61; // op stage - }break; - case 0x27: - { - state.ptr += 1; - state.flags_ZF0 |= 0x40; - goto state_label_32; // string - }break; - case 0x28: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_ParenOp; - token.kind = 13; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x29: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_ParenCl; - token.kind = 14; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x2a: - { - state.ptr += 1; - goto state_label_63; // op stage - }break; - case 0x2b: - { - state.ptr += 1; - goto state_label_53; // op stage - }break; - case 0x2c: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Comma; - token.kind = 15; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x2d: - { - state.ptr += 1; - goto state_label_54; // op stage - }break; - case 0x2e: - { - state.ptr += 1; - goto state_label_6; // operator_or_fnumber_dot - }break; - case 0x2f: - { - state.ptr += 1; - goto state_label_7; // operator_or_comment_slash - }break; - case 0x30: - { - state.ptr += 1; - goto state_label_9; // znumber - }break; - case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36:case 0x37: - case 0x38:case 0x39: - { - state.ptr += 1; - goto state_label_8; // number - }break; - case 0x3a: - { - state.ptr += 1; - goto state_label_52; // op stage - }break; - case 0x3b: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Semicolon; - token.kind = 15; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3c: - { - if ((!HasFlag(state.flags_KF0, 0x1))){ - state.ptr += 1; - goto state_label_56; // op stage - } - state.ptr += 1; - goto state_label_25; // include_pointy - }break; - case 0x3d: - { - state.ptr += 1; - goto state_label_59; // op stage - }break; - case 0x3e: - { - state.ptr += 1; - goto state_label_57; // op stage - }break; - case 0x3f: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Ternary; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x4c: - { - state.ptr += 1; - state.flags_ZF0 |= 0x4; - goto state_label_27; // pre_L - }break; - case 0x52: - { - state.ptr += 1; - goto state_label_31; // pre_R - }break; - case 0x55: - { - state.ptr += 1; - state.flags_ZF0 |= 0x20; - goto state_label_29; // pre_U - }break; - case 0x5b: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_BrackOp; - token.kind = 13; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x5c: - { - state.ptr += 1; - goto state_label_5; // backslash - }break; - case 0x5d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_BrackCl; - token.kind = 14; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x5e: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Xor; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x75: - { - state.ptr += 1; - state.flags_ZF0 |= 0x10; - goto state_label_28; // pre_u - }break; - case 0x7b: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_BraceOp; - token.kind = 11; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x7c: - { - state.ptr += 1; - goto state_label_62; // op stage - }break; - case 0x7d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_BraceCl; - token.kind = 12; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x7e: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Tilde; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_2: // identifier - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_KB0, 0x1)){ - Lexeme_Table_Lookup lookup = lexeme_table_lookup(pp_keys_hash_array, pp_keys_key_array, pp_keys_value_array, pp_keys_slot_count, pp_keys_seed, state.emit_ptr, token.size); - if (lookup.found_match){ - token.kind = lookup.base_kind; - token.sub_kind = lookup.sub_kind; - break; - } - } - Lexeme_Table_Lookup lookup = lexeme_table_lookup(main_keys_hash_array, main_keys_key_array, main_keys_value_array, main_keys_slot_count, main_keys_seed, state.emit_ptr, token.size); - if (lookup.found_match){ - token.kind = lookup.base_kind; - token.sub_kind = lookup.sub_kind; - break; - } - token.sub_kind = TokenCppKind_Identifier; - token.kind = 6; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06: - case 0x07:case 0x08:case 0x09:case 0x0a:case 0x0b:case 0x0c:case 0x0d: - case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14: - case 0x15:case 0x16:case 0x17:case 0x18:case 0x19:case 0x1a:case 0x1b: - case 0x1c:case 0x1d:case 0x1e:case 0x1f:case 0x20:case 0x21:case 0x22: - case 0x23:case 0x25:case 0x26:case 0x27:case 0x28:case 0x29:case 0x2a: - case 0x2b:case 0x2c:case 0x2d:case 0x2e:case 0x2f:case 0x3a:case 0x3b: - case 0x3c:case 0x3d:case 0x3e:case 0x3f:case 0x40:case 0x5b:case 0x5c: - case 0x5d:case 0x5e:case 0x60:case 0x7b:case 0x7c:case 0x7d:case 0x7e: - case 0x7f: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_KB0, 0x1)){ - Lexeme_Table_Lookup lookup = lexeme_table_lookup(pp_keys_hash_array, pp_keys_key_array, pp_keys_value_array, pp_keys_slot_count, pp_keys_seed, state.emit_ptr, token.size); - if (lookup.found_match){ - token.kind = lookup.base_kind; - token.sub_kind = lookup.sub_kind; - break; - } - } - Lexeme_Table_Lookup lookup = lexeme_table_lookup(main_keys_hash_array, main_keys_key_array, main_keys_value_array, main_keys_slot_count, main_keys_seed, state.emit_ptr, token.size); - if (lookup.found_match){ - token.kind = lookup.base_kind; - token.sub_kind = lookup.sub_kind; - break; - } - token.sub_kind = TokenCppKind_Identifier; - token.kind = 6; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - default: - { - state.ptr += 1; - goto state_label_2; // identifier - }break; - } - } - { - state_label_3: // whitespace - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Whitespace; - token.kind = 1; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Whitespace; - token.kind = 1; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x09:case 0x0b:case 0x0c:case 0x0d:case 0x20: - { - state.ptr += 1; - goto state_label_3; // whitespace - }break; - case 0x0a: - { - state.ptr += 1; - state.flags_KB0 &= ~(0x1); - state.flags_KF0 &= ~(0x1); - state.flags_KF0 &= ~(0x2); - goto state_label_3; // whitespace - }break; - } - } - { - state_label_4: // error_body - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_PPErrorMessage; - token.kind = 10; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - state.ptr += 1; - goto state_label_4; // error_body - }break; - case 0x0a: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_PPErrorMessage; - token.kind = 10; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_5: // backslash - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Backslash; - token.kind = 1; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Backslash; - token.kind = 1; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x0a: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Backslash; - token.kind = 1; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_6: // operator_or_fnumber_dot - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Dot; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Dot; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x2a: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_DotStar; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x2e: - { - state.ptr += 1; - goto state_label_68; // op stage - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39: - { - state.ptr += 1; - goto state_label_10; // fnumber_decimal - }break; - } - } - { - state_label_7: // operator_or_comment_slash - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Div; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Div; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x2a: - { - state.ptr += 1; - goto state_label_49; // comment_block - }break; - case 0x2f: - { - state.ptr += 1; - goto state_label_51; // comment_line - }break; - case 0x3d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_DivEq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_8: // number - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralInteger; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralInteger; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x2e: - { - state.ptr += 1; - goto state_label_10; // fnumber_decimal - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39: - { - state.ptr += 1; - goto state_label_8; // number - }break; - case 0x45:case 0x65: - { - state.ptr += 1; - goto state_label_11; // fnumber_exponent - }break; - case 0x4c: - { - state.ptr += 1; - goto state_label_18; // L_number - }break; - case 0x55:case 0x75: - { - state.ptr += 1; - goto state_label_17; // U_number - }break; - case 0x6c: - { - state.ptr += 1; - goto state_label_20; // l_number - }break; - } - } - { - state_label_9: // znumber - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralInteger; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralInteger; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x2e: - { - state.ptr += 1; - goto state_label_10; // fnumber_decimal - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37: - { - state.ptr += 1; - state.flags_ZF0 |= 0x2; - goto state_label_16; // number_oct - }break; - case 0x45:case 0x65: - { - state.ptr += 1; - goto state_label_11; // fnumber_exponent - }break; - case 0x4c: - { - state.ptr += 1; - goto state_label_18; // L_number - }break; - case 0x55:case 0x75: - { - state.ptr += 1; - goto state_label_17; // U_number - }break; - case 0x58:case 0x78: - { - state.ptr += 1; - state.flags_ZF0 |= 0x1; - goto state_label_14; // number_hex_first - }break; - case 0x6c: - { - state.ptr += 1; - goto state_label_20; // l_number - }break; - } - } - { - state_label_10: // fnumber_decimal - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat64; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat64; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39: - { - state.ptr += 1; - goto state_label_10; // fnumber_decimal - }break; - case 0x45:case 0x65: - { - state.ptr += 1; - goto state_label_11; // fnumber_exponent - }break; - case 0x46:case 0x66: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat32; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x4c:case 0x6c: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat64; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_11: // fnumber_exponent - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat64; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat64; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x2b:case 0x2d: - { - state.ptr += 1; - goto state_label_12; // fnumber_exponent_sign - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39: - { - state.ptr += 1; - goto state_label_13; // fnumber_exponent_digits - }break; - case 0x46:case 0x66: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat32; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x4c:case 0x6c: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat64; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_12: // fnumber_exponent_sign - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat64; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat64; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39: - { - state.ptr += 1; - goto state_label_13; // fnumber_exponent_digits - }break; - case 0x46:case 0x66: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat32; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x4c:case 0x6c: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat64; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_13: // fnumber_exponent_digits - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat64; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat64; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39: - { - state.ptr += 1; - goto state_label_13; // fnumber_exponent_digits - }break; - case 0x46:case 0x66: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat32; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x4c:case 0x6c: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralFloat64; - token.kind = 9; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_14: // number_hex_first - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66: - { - state.ptr += 1; - goto state_label_15; // number_hex - }break; - } - } - { - state_label_15: // number_hex - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralIntegerHex; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralIntegerHex; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66: - { - state.ptr += 1; - goto state_label_15; // number_hex - }break; - case 0x4c: - { - state.ptr += 1; - goto state_label_18; // L_number - }break; - case 0x55:case 0x75: - { - state.ptr += 1; - goto state_label_17; // U_number - }break; - case 0x6c: - { - state.ptr += 1; - goto state_label_20; // l_number - }break; - } - } - { - state_label_16: // number_oct - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralIntegerOct; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LiteralIntegerOct; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37: - { - state.ptr += 1; - state.flags_ZF0 |= 0x2; - goto state_label_16; // number_oct - }break; - case 0x4c: - { - state.ptr += 1; - goto state_label_18; // L_number - }break; - case 0x55:case 0x75: - { - state.ptr += 1; - goto state_label_17; // U_number - }break; - case 0x6c: - { - state.ptr += 1; - goto state_label_20; // l_number - }break; - } - } - { - state_label_17: // U_number - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexU; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctU; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerU; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexU; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctU; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerU; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x4c: - { - state.ptr += 1; - goto state_label_19; // UL_number - }break; - case 0x6c: - { - state.ptr += 1; - goto state_label_21; // Ul_number - }break; - } - } - { - state_label_18: // L_number - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x4c: - { - state.ptr += 1; - goto state_label_22; // LL_number - }break; - case 0x55:case 0x75: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexUL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctUL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerUL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_19: // UL_number - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexUL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctUL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerUL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexUL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctUL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerUL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x4c: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexULL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctULL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerULL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_20: // l_number - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x55:case 0x75: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexUL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctUL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerUL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x6c: - { - state.ptr += 1; - goto state_label_22; // LL_number - }break; - } - } - { - state_label_21: // Ul_number - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexUL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctUL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerUL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexUL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctUL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerUL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x6c: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexULL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctULL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerULL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_22: // LL_number - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexLL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctLL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerLL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexLL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctLL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerLL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x55:case 0x75: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x1)){ - token.sub_kind = TokenCppKind_LiteralIntegerHexULL; - token.kind = 8; - break; - } - if (HasFlag(state.flags_ZF0, 0x2)){ - token.sub_kind = TokenCppKind_LiteralIntegerOctULL; - token.kind = 8; - break; - } - token.sub_kind = TokenCppKind_LiteralIntegerULL; - token.kind = 8; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_23: // pp_directive_whitespace - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x09:case 0x0b:case 0x0c:case 0x20: - { - state.ptr += 1; - goto state_label_23; // pp_directive_whitespace - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x47:case 0x48:case 0x49:case 0x4a:case 0x4b: - case 0x4c:case 0x4d:case 0x4e:case 0x4f:case 0x50:case 0x51:case 0x52: - case 0x53:case 0x54:case 0x55:case 0x56:case 0x57:case 0x58:case 0x59: - case 0x5a:case 0x5f:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66:case 0x67:case 0x68:case 0x69:case 0x6a:case 0x6b:case 0x6c: - case 0x6d:case 0x6e:case 0x6f:case 0x70:case 0x71:case 0x72:case 0x73: - case 0x74:case 0x75:case 0x76:case 0x77:case 0x78:case 0x79:case 0x7a: - { - state.delim_first = state.ptr; - state.flags_KB0 |= 0x1; - state.ptr += 1; - goto state_label_24; // pp_directive - }break; - } - } - { - state_label_24: // pp_directive - if (state.ptr == state.opl_ptr){ - if ((true)){ - state.delim_one_past_last = state.ptr; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - Lexeme_Table_Lookup lookup = lexeme_table_lookup(pp_directives_hash_array, pp_directives_key_array, pp_directives_value_array, pp_directives_slot_count, pp_directives_seed, state.delim_first, (state.delim_one_past_last - state.delim_first)); - if (lookup.found_match){ - token.kind = lookup.base_kind; - token.sub_kind = lookup.sub_kind; - break; - } - token.sub_kind = TokenCppKind_PPUnknown; - token.kind = 2; - }while(0); - switch (token.sub_kind){ - case TokenCppKind_PPInclude: - { - state.flags_KF0 |= 0x1; - }break; - case TokenCppKind_PPError: - { - state.flags_KF0 |= 0x2; - }break; - } - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - state.delim_one_past_last = state.ptr; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - Lexeme_Table_Lookup lookup = lexeme_table_lookup(pp_directives_hash_array, pp_directives_key_array, pp_directives_value_array, pp_directives_slot_count, pp_directives_seed, state.delim_first, (state.delim_one_past_last - state.delim_first)); - if (lookup.found_match){ - token.kind = lookup.base_kind; - token.sub_kind = lookup.sub_kind; - break; - } - token.sub_kind = TokenCppKind_PPUnknown; - token.kind = 2; - }while(0); - switch (token.sub_kind){ - case TokenCppKind_PPInclude: - { - state.flags_KF0 |= 0x1; - }break; - case TokenCppKind_PPError: - { - state.flags_KF0 |= 0x2; - }break; - } - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x47:case 0x48:case 0x49:case 0x4a:case 0x4b: - case 0x4c:case 0x4d:case 0x4e:case 0x4f:case 0x50:case 0x51:case 0x52: - case 0x53:case 0x54:case 0x55:case 0x56:case 0x57:case 0x58:case 0x59: - case 0x5a:case 0x5f:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66:case 0x67:case 0x68:case 0x69:case 0x6a:case 0x6b:case 0x6c: - case 0x6d:case 0x6e:case 0x6f:case 0x70:case 0x71:case 0x72:case 0x73: - case 0x74:case 0x75:case 0x76:case 0x77:case 0x78:case 0x79:case 0x7a: - { - state.ptr += 1; - goto state_label_24; // pp_directive - }break; - } - } - { - state_label_25: // include_pointy - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x20:case 0x2e:case 0x2f:case 0x30:case 0x31:case 0x32:case 0x33: - case 0x34:case 0x35:case 0x36:case 0x37:case 0x38:case 0x39:case 0x41: - case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:case 0x48: - case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f: - case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56: - case 0x57:case 0x58:case 0x59:case 0x5a:case 0x5c:case 0x5f:case 0x61: - case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67:case 0x68: - case 0x69:case 0x6a:case 0x6b:case 0x6c:case 0x6d:case 0x6e:case 0x6f: - case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76: - case 0x77:case 0x78:case 0x79:case 0x7a: - { - state.ptr += 1; - goto state_label_25; // include_pointy - }break; - case 0x3e: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_PPIncludeFile; - token.kind = 10; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_26: // include_quotes - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x20:case 0x2e:case 0x2f:case 0x30:case 0x31:case 0x32:case 0x33: - case 0x34:case 0x35:case 0x36:case 0x37:case 0x38:case 0x39:case 0x41: - case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:case 0x48: - case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f: - case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56: - case 0x57:case 0x58:case 0x59:case 0x5a:case 0x5c:case 0x5f:case 0x61: - case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67:case 0x68: - case 0x69:case 0x6a:case 0x6b:case 0x6c:case 0x6d:case 0x6e:case 0x6f: - case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76: - case 0x77:case 0x78:case 0x79:case 0x7a: - { - state.ptr += 1; - goto state_label_26; // include_quotes - }break; - case 0x22: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_PPIncludeFile; - token.kind = 10; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_27: // pre_L - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_2; // identifier - } - } - switch (*state.ptr){ - default: - { - goto state_label_2; // identifier - }break; - case 0x22: - { - state.ptr += 1; - goto state_label_32; // string - }break; - case 0x52: - { - state.ptr += 1; - goto state_label_31; // pre_R - }break; - } - } - { - state_label_28: // pre_u - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_2; // identifier - } - } - switch (*state.ptr){ - default: - { - goto state_label_2; // identifier - }break; - case 0x22: - { - state.ptr += 1; - goto state_label_32; // string - }break; - case 0x38: - { - state.ptr += 1; - state.flags_ZF0 |= 0x8; - goto state_label_30; // pre_u8 - }break; - case 0x52: - { - state.ptr += 1; - goto state_label_31; // pre_R - }break; - } - } - { - state_label_29: // pre_U - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_2; // identifier - } - } - switch (*state.ptr){ - default: - { - goto state_label_2; // identifier - }break; - case 0x22: - { - state.ptr += 1; - goto state_label_32; // string - }break; - case 0x52: - { - state.ptr += 1; - goto state_label_31; // pre_R - }break; - } - } - { - state_label_30: // pre_u8 - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_2; // identifier - } - } - switch (*state.ptr){ - default: - { - goto state_label_2; // identifier - }break; - case 0x22: - { - state.ptr += 1; - goto state_label_32; // string - }break; - case 0x52: - { - state.ptr += 1; - goto state_label_31; // pre_R - }break; - } - } - { - state_label_31: // pre_R - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_2; // identifier - } - } - switch (*state.ptr){ - default: - { - goto state_label_2; // identifier - }break; - case 0x22: - { - state.ptr += 1; - state.delim_first = state.ptr; - goto state_label_45; // raw_string_get_delim - }break; - } - } - { - state_label_32: // string - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - state.ptr += 1; - goto state_label_32; // string - }break; - case 0x0a: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x22: - { - if ((!HasFlag(state.flags_ZF0, 0x40))){ - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x4)){ - token.sub_kind = TokenCppKind_LiteralStringWide; - token.kind = 10; - break; - } - if (HasFlag(state.flags_ZF0, 0x8)){ - token.sub_kind = TokenCppKind_LiteralStringUTF8; - token.kind = 10; - break; - } - if (HasFlag(state.flags_ZF0, 0x10)){ - token.sub_kind = TokenCppKind_LiteralStringUTF16; - token.kind = 10; - break; - } - if (HasFlag(state.flags_ZF0, 0x20)){ - token.sub_kind = TokenCppKind_LiteralStringUTF32; - token.kind = 10; - break; - } - token.sub_kind = TokenCppKind_LiteralString; - token.kind = 10; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - state.ptr += 1; - goto state_label_32; // string - }break; - case 0x27: - { - if ((HasFlag(state.flags_ZF0, 0x40))){ - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x4)){ - token.sub_kind = TokenCppKind_LiteralCharacterWide; - token.kind = 10; - break; - } - if (HasFlag(state.flags_ZF0, 0x8)){ - token.sub_kind = TokenCppKind_LiteralCharacterUTF8; - token.kind = 10; - break; - } - if (HasFlag(state.flags_ZF0, 0x10)){ - token.sub_kind = TokenCppKind_LiteralCharacterUTF16; - token.kind = 10; - break; - } - if (HasFlag(state.flags_ZF0, 0x20)){ - token.sub_kind = TokenCppKind_LiteralCharacterUTF32; - token.kind = 10; - break; - } - token.sub_kind = TokenCppKind_LiteralCharacter; - token.kind = 10; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - state.ptr += 1; - goto state_label_32; // string - }break; - case 0x5c: - { - state.ptr += 1; - goto state_label_33; // string_esc - }break; - } - } - { - state_label_33: // string_esc - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_EOF; - token.kind = 0; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - result = true; - goto end; - } - } - switch (*state.ptr){ - default: - { - state.ptr += 1; - goto state_label_32; // string - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37: - { - state.ptr += 1; - goto state_label_34; // string_esc_oct2 - }break; - case 0x55: - { - state.ptr += 1; - goto state_label_37; // string_esc_universal_8 - }break; - case 0x75: - { - state.ptr += 1; - goto state_label_41; // string_esc_universal_4 - }break; - case 0x78: - { - state.ptr += 1; - goto state_label_36; // string_esc_hex - }break; - } - } - { - state_label_34: // string_esc_oct2 - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_32; // string - } - } - switch (*state.ptr){ - default: - { - goto state_label_32; // string - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37: - { - state.ptr += 1; - goto state_label_35; // string_esc_oct1 - }break; - } - } - { - state_label_35: // string_esc_oct1 - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_32; // string - } - } - switch (*state.ptr){ - default: - { - goto state_label_32; // string - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37: - { - state.ptr += 1; - goto state_label_32; // string - }break; - } - } - { - state_label_36: // string_esc_hex - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_32; // string - } - } - switch (*state.ptr){ - default: - { - goto state_label_32; // string - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66: - { - state.ptr += 1; - goto state_label_36; // string_esc_hex - }break; - } - } - { - state_label_37: // string_esc_universal_8 - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_32; // string - } - } - switch (*state.ptr){ - default: - { - goto state_label_32; // string - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66: - { - state.ptr += 1; - goto state_label_38; // string_esc_universal_7 - }break; - } - } - { - state_label_38: // string_esc_universal_7 - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_32; // string - } - } - switch (*state.ptr){ - default: - { - goto state_label_32; // string - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66: - { - state.ptr += 1; - goto state_label_39; // string_esc_universal_6 - }break; - } - } - { - state_label_39: // string_esc_universal_6 - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_32; // string - } - } - switch (*state.ptr){ - default: - { - goto state_label_32; // string - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66: - { - state.ptr += 1; - goto state_label_40; // string_esc_universal_5 - }break; - } - } - { - state_label_40: // string_esc_universal_5 - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_32; // string - } - } - switch (*state.ptr){ - default: - { - goto state_label_32; // string - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66: - { - state.ptr += 1; - goto state_label_41; // string_esc_universal_4 - }break; - } - } - { - state_label_41: // string_esc_universal_4 - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_32; // string - } - } - switch (*state.ptr){ - default: - { - goto state_label_32; // string - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66: - { - state.ptr += 1; - goto state_label_42; // string_esc_universal_3 - }break; - } - } - { - state_label_42: // string_esc_universal_3 - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_32; // string - } - } - switch (*state.ptr){ - default: - { - goto state_label_32; // string - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66: - { - state.ptr += 1; - goto state_label_43; // string_esc_universal_2 - }break; - } - } - { - state_label_43: // string_esc_universal_2 - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_32; // string - } - } - switch (*state.ptr){ - default: - { - goto state_label_32; // string - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66: - { - state.ptr += 1; - goto state_label_44; // string_esc_universal_1 - }break; - } - } - { - state_label_44: // string_esc_universal_1 - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_32; // string - } - } - switch (*state.ptr){ - default: - { - goto state_label_32; // string - }break; - case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: - case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: - case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: - case 0x66: - { - state.ptr += 1; - goto state_label_32; // string - }break; - } - } - { - state_label_45: // raw_string_get_delim - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_EOF; - token.kind = 0; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - result = true; - goto end; - } - } - switch (*state.ptr){ - default: - { - state.ptr += 1; - goto state_label_45; // raw_string_get_delim - }break; - case 0x20:case 0x29:case 0x5c: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x28: - { - state.delim_one_past_last = state.ptr; - state.ptr += 1; - goto state_label_46; // raw_string_find_close - }break; - } - } - { - state_label_46: // raw_string_find_close - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_EOF; - token.kind = 0; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - result = true; - goto end; - } - } - switch (*state.ptr){ - default: - { - state.ptr += 1; - goto state_label_46; // raw_string_find_close - }break; - case 0x29: - { - state.ptr += 1; - goto state_label_47; // raw_string_try_delim - }break; - } - } - { - state_label_47: // raw_string_try_delim - u64 delim_length = state.delim_one_past_last - state.delim_first; - u64 parse_length = 0; - for (;;){ - if (parse_length == delim_length){ - goto state_label_48; // raw_string_try_quote - } - if (state.ptr == state.opl_ptr){ - goto state_label_48; // raw_string_try_quote - } - if (*state.ptr == state.delim_first[parse_length]){ - state.ptr += 1; - parse_length += 1; - } - else{ - goto state_label_46; // raw_string_find_close - } - } - } - { - state_label_48: // raw_string_try_quote - if (state.ptr == state.opl_ptr){ - if ((true)){ - goto state_label_46; // raw_string_find_close - } - } - switch (*state.ptr){ - default: - { - goto state_label_46; // raw_string_find_close - }break; - case 0x22: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - if (HasFlag(state.flags_ZF0, 0x4)){ - token.sub_kind = TokenCppKind_LiteralStringWideRaw; - token.kind = 10; - break; - } - if (HasFlag(state.flags_ZF0, 0x8)){ - token.sub_kind = TokenCppKind_LiteralStringUTF8Raw; - token.kind = 10; - break; - } - if (HasFlag(state.flags_ZF0, 0x10)){ - token.sub_kind = TokenCppKind_LiteralStringUTF16Raw; - token.kind = 10; - break; - } - if (HasFlag(state.flags_ZF0, 0x20)){ - token.sub_kind = TokenCppKind_LiteralStringUTF32Raw; - token.kind = 10; - break; - } - token.sub_kind = TokenCppKind_LiteralStringRaw; - token.kind = 10; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_49: // comment_block - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_BlockComment; - token.kind = 3; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_EOF; - token.kind = 0; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - result = true; - goto end; - } - } - switch (*state.ptr){ - default: - { - state.ptr += 1; - goto state_label_49; // comment_block - }break; - case 0x0a: - { - state.ptr += 1; - state.flags_KB0 &= ~(0x1); - state.flags_KF0 &= ~(0x1); - goto state_label_49; // comment_block - }break; - case 0x2a: - { - state.ptr += 1; - goto state_label_50; // comment_block_try_close - }break; - } - } - { - state_label_50: // comment_block_try_close - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_BlockComment; - token.kind = 3; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_EOF; - token.kind = 0; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - result = true; - goto end; - } - } - switch (*state.ptr){ - default: - { - state.ptr += 1; - goto state_label_49; // comment_block - }break; - case 0x2a: - { - state.ptr += 1; - goto state_label_50; // comment_block_try_close - }break; - case 0x2f: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_BlockComment; - token.kind = 3; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_51: // comment_line - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LineComment; - token.kind = 3; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - state.ptr += 1; - goto state_label_51; // comment_line - }break; - case 0x0a: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LineComment; - token.kind = 3; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_52: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Colon; - token.kind = 15; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Colon; - token.kind = 15; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3a: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_ColonColon; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_53: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Plus; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Plus; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x2b: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_PlusPlus; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_PlusEq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_54: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Minus; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Minus; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x2d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_MinusMinus; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_MinusEq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3e: - { - state.ptr += 1; - goto state_label_55; // op stage - }break; - } - } - { - state_label_55: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Arrow; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Arrow; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x2a: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_ArrowStar; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_56: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Less; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Less; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3c: - { - state.ptr += 1; - goto state_label_65; // op stage - }break; - case 0x3d: - { - state.ptr += 1; - goto state_label_58; // op stage - }break; - } - } - { - state_label_57: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Grtr; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Grtr; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_GrtrEq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3e: - { - state.ptr += 1; - goto state_label_66; // op stage - }break; - } - } - { - state_label_58: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LessEq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LessEq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3e: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Compare; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_59: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Eq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Eq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_EqEq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_60: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Not; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Not; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_NotEq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_61: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_And; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_And; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x26: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_AndAnd; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_62: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Or; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Or; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x7c: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_OrOr; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_63: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Star; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Star; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_StarEq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_64: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Mod; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_Mod; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_ModEq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_65: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LeftLeft; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LeftLeft; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LeftLeftEq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_66: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_RightRight; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_RightRight; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x3d: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_RightRightEq; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_67: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_PPStringify; - token.kind = 15; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_PPStringify; - token.kind = 15; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x23: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_PPConcat; - token.kind = 15; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - { - state_label_68: // op stage - if (state.ptr == state.opl_ptr){ - if ((true)){ - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - } - } - switch (*state.ptr){ - default: - { - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_LexError; - token.kind = 2; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - case 0x2e: - { - state.ptr += 1; - { - Token token = {}; - token.pos = (i64)(state.emit_ptr - state.base); - token.size = (i64)(state.ptr - state.emit_ptr); - token.flags = state.flags_KB0; - do{ - token.sub_kind = TokenCppKind_DotDotDot; - token.kind = 7; - }while(0); - token_list_push(arena, list, &token); - emit_counter += 1; - if (emit_counter == max){ - goto end; - } - state.emit_ptr = state.ptr; - } - state.flags_ZF0 = 0; - goto state_label_1; // root - }break; - } - } - end:; - block_copy_struct(state_ptr, &state); - return(result); +b32 result = false; +u64 emit_counter = 0; +Lex_State_Cpp state; +block_copy_struct(&state, state_ptr); +{ +state_label_1: // root +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_EOF; +token.kind = 0; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +result = true; +goto end; +} +} +switch (*state.ptr){ +case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06: +case 0x07:case 0x08:case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12: +case 0x13:case 0x14:case 0x15:case 0x16:case 0x17:case 0x18:case 0x19: +case 0x1a:case 0x1b:case 0x1c:case 0x1d:case 0x1e:case 0x1f:case 0x40: +case 0x60:case 0x7f: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x09:case 0x0b:case 0x0c:case 0x0d:case 0x20: +{ +if ((HasFlag(state.flags_KF0, 0x2))){ +state.ptr += 1; +goto state_label_4; // error_body +} +state.ptr += 1; +goto state_label_3; // whitespace +}break; +case 0x0a: +{ +state.ptr += 1; +state.flags_KB0 &= ~(0x1); +state.flags_KF0 &= ~(0x1); +state.flags_KF0 &= ~(0x2); +goto state_label_3; // whitespace +}break; +case 0x21: +{ +state.ptr += 1; +goto state_label_60; // op stage +}break; +case 0x22: +{ +if ((HasFlag(state.flags_KF0, 0x1))){ +state.ptr += 1; +goto state_label_26; // include_quotes +} +state.ptr += 1; +goto state_label_32; // string +}break; +case 0x23: +{ +if ((!HasFlag(state.flags_KB0, 0x1))){ +state.ptr += 1; +goto state_label_23; // pp_directive_whitespace +} +state.ptr += 1; +goto state_label_67; // op stage +}break; +default: +{ +state.ptr += 1; +goto state_label_2; // identifier +}break; +case 0x25: +{ +state.ptr += 1; +goto state_label_64; // op stage +}break; +case 0x26: +{ +state.ptr += 1; +goto state_label_61; // op stage +}break; +case 0x27: +{ +state.ptr += 1; +state.flags_ZF0 |= 0x40; +goto state_label_32; // string +}break; +case 0x28: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_ParenOp; +token.kind = 13; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x29: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_ParenCl; +token.kind = 14; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x2a: +{ +state.ptr += 1; +goto state_label_63; // op stage +}break; +case 0x2b: +{ +state.ptr += 1; +goto state_label_53; // op stage +}break; +case 0x2c: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Comma; +token.kind = 15; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x2d: +{ +state.ptr += 1; +goto state_label_54; // op stage +}break; +case 0x2e: +{ +state.ptr += 1; +goto state_label_6; // operator_or_fnumber_dot +}break; +case 0x2f: +{ +state.ptr += 1; +goto state_label_7; // operator_or_comment_slash +}break; +case 0x30: +{ +state.ptr += 1; +goto state_label_9; // znumber +}break; +case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36:case 0x37: +case 0x38:case 0x39: +{ +state.ptr += 1; +goto state_label_8; // number +}break; +case 0x3a: +{ +state.ptr += 1; +goto state_label_52; // op stage +}break; +case 0x3b: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Semicolon; +token.kind = 15; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3c: +{ +if ((!HasFlag(state.flags_KF0, 0x1))){ +state.ptr += 1; +goto state_label_56; // op stage +} +state.ptr += 1; +goto state_label_25; // include_pointy +}break; +case 0x3d: +{ +state.ptr += 1; +goto state_label_59; // op stage +}break; +case 0x3e: +{ +state.ptr += 1; +goto state_label_57; // op stage +}break; +case 0x3f: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Ternary; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x4c: +{ +state.ptr += 1; +state.flags_ZF0 |= 0x4; +goto state_label_27; // pre_L +}break; +case 0x52: +{ +state.ptr += 1; +goto state_label_31; // pre_R +}break; +case 0x55: +{ +state.ptr += 1; +state.flags_ZF0 |= 0x20; +goto state_label_29; // pre_U +}break; +case 0x5b: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_BrackOp; +token.kind = 13; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x5c: +{ +state.ptr += 1; +goto state_label_5; // backslash +}break; +case 0x5d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_BrackCl; +token.kind = 14; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x5e: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Xor; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x75: +{ +state.ptr += 1; +state.flags_ZF0 |= 0x10; +goto state_label_28; // pre_u +}break; +case 0x7b: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_BraceOp; +token.kind = 11; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x7c: +{ +state.ptr += 1; +goto state_label_62; // op stage +}break; +case 0x7d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_BraceCl; +token.kind = 12; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x7e: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Tilde; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_2: // identifier +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_KB0, 0x1)){ +Lexeme_Table_Lookup lookup = lexeme_table_lookup(cpp_pp_keys_hash_array, cpp_pp_keys_key_array, cpp_pp_keys_value_array, cpp_pp_keys_slot_count, cpp_pp_keys_seed, state.emit_ptr, token.size); +if (lookup.found_match){ +token.kind = lookup.base_kind; +token.sub_kind = lookup.sub_kind; +break; +} +} +Lexeme_Table_Lookup lookup = lexeme_table_lookup(cpp_main_keys_hash_array, cpp_main_keys_key_array, cpp_main_keys_value_array, cpp_main_keys_slot_count, cpp_main_keys_seed, state.emit_ptr, token.size); +if (lookup.found_match){ +token.kind = lookup.base_kind; +token.sub_kind = lookup.sub_kind; +break; +} +token.sub_kind = TokenCppKind_Identifier; +token.kind = 6; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +case 0x00:case 0x01:case 0x02:case 0x03:case 0x04:case 0x05:case 0x06: +case 0x07:case 0x08:case 0x09:case 0x0a:case 0x0b:case 0x0c:case 0x0d: +case 0x0e:case 0x0f:case 0x10:case 0x11:case 0x12:case 0x13:case 0x14: +case 0x15:case 0x16:case 0x17:case 0x18:case 0x19:case 0x1a:case 0x1b: +case 0x1c:case 0x1d:case 0x1e:case 0x1f:case 0x20:case 0x21:case 0x22: +case 0x23:case 0x25:case 0x26:case 0x27:case 0x28:case 0x29:case 0x2a: +case 0x2b:case 0x2c:case 0x2d:case 0x2e:case 0x2f:case 0x3a:case 0x3b: +case 0x3c:case 0x3d:case 0x3e:case 0x3f:case 0x40:case 0x5b:case 0x5c: +case 0x5d:case 0x5e:case 0x60:case 0x7b:case 0x7c:case 0x7d:case 0x7e: +case 0x7f: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_KB0, 0x1)){ +Lexeme_Table_Lookup lookup = lexeme_table_lookup(cpp_pp_keys_hash_array, cpp_pp_keys_key_array, cpp_pp_keys_value_array, cpp_pp_keys_slot_count, cpp_pp_keys_seed, state.emit_ptr, token.size); +if (lookup.found_match){ +token.kind = lookup.base_kind; +token.sub_kind = lookup.sub_kind; +break; +} +} +Lexeme_Table_Lookup lookup = lexeme_table_lookup(cpp_main_keys_hash_array, cpp_main_keys_key_array, cpp_main_keys_value_array, cpp_main_keys_slot_count, cpp_main_keys_seed, state.emit_ptr, token.size); +if (lookup.found_match){ +token.kind = lookup.base_kind; +token.sub_kind = lookup.sub_kind; +break; +} +token.sub_kind = TokenCppKind_Identifier; +token.kind = 6; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +default: +{ +state.ptr += 1; +goto state_label_2; // identifier +}break; +} +} +{ +state_label_3: // whitespace +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Whitespace; +token.kind = 1; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Whitespace; +token.kind = 1; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x09:case 0x0b:case 0x0c:case 0x0d:case 0x20: +{ +state.ptr += 1; +goto state_label_3; // whitespace +}break; +case 0x0a: +{ +state.ptr += 1; +state.flags_KB0 &= ~(0x1); +state.flags_KF0 &= ~(0x1); +state.flags_KF0 &= ~(0x2); +goto state_label_3; // whitespace +}break; +} +} +{ +state_label_4: // error_body +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_PPErrorMessage; +token.kind = 10; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +state.ptr += 1; +goto state_label_4; // error_body +}break; +case 0x0a: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_PPErrorMessage; +token.kind = 10; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_5: // backslash +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Backslash; +token.kind = 1; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Backslash; +token.kind = 1; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x0a: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Backslash; +token.kind = 1; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_6: // operator_or_fnumber_dot +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Dot; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Dot; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x2a: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_DotStar; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x2e: +{ +state.ptr += 1; +goto state_label_68; // op stage +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39: +{ +state.ptr += 1; +goto state_label_10; // fnumber_decimal +}break; +} +} +{ +state_label_7: // operator_or_comment_slash +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Div; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Div; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x2a: +{ +state.ptr += 1; +goto state_label_49; // comment_block +}break; +case 0x2f: +{ +state.ptr += 1; +goto state_label_51; // comment_line +}break; +case 0x3d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_DivEq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_8: // number +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralInteger; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralInteger; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x2e: +{ +state.ptr += 1; +goto state_label_10; // fnumber_decimal +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39: +{ +state.ptr += 1; +goto state_label_8; // number +}break; +case 0x45:case 0x65: +{ +state.ptr += 1; +goto state_label_11; // fnumber_exponent +}break; +case 0x4c: +{ +state.ptr += 1; +goto state_label_18; // L_number +}break; +case 0x55:case 0x75: +{ +state.ptr += 1; +goto state_label_17; // U_number +}break; +case 0x6c: +{ +state.ptr += 1; +goto state_label_20; // l_number +}break; +} +} +{ +state_label_9: // znumber +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralInteger; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralInteger; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x2e: +{ +state.ptr += 1; +goto state_label_10; // fnumber_decimal +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37: +{ +state.ptr += 1; +state.flags_ZF0 |= 0x2; +goto state_label_16; // number_oct +}break; +case 0x45:case 0x65: +{ +state.ptr += 1; +goto state_label_11; // fnumber_exponent +}break; +case 0x4c: +{ +state.ptr += 1; +goto state_label_18; // L_number +}break; +case 0x55:case 0x75: +{ +state.ptr += 1; +goto state_label_17; // U_number +}break; +case 0x58:case 0x78: +{ +state.ptr += 1; +state.flags_ZF0 |= 0x1; +goto state_label_14; // number_hex_first +}break; +case 0x6c: +{ +state.ptr += 1; +goto state_label_20; // l_number +}break; +} +} +{ +state_label_10: // fnumber_decimal +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat64; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat64; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39: +{ +state.ptr += 1; +goto state_label_10; // fnumber_decimal +}break; +case 0x45:case 0x65: +{ +state.ptr += 1; +goto state_label_11; // fnumber_exponent +}break; +case 0x46:case 0x66: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat32; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x4c:case 0x6c: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat64; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_11: // fnumber_exponent +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat64; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat64; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x2b:case 0x2d: +{ +state.ptr += 1; +goto state_label_12; // fnumber_exponent_sign +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39: +{ +state.ptr += 1; +goto state_label_13; // fnumber_exponent_digits +}break; +case 0x46:case 0x66: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat32; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x4c:case 0x6c: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat64; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_12: // fnumber_exponent_sign +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat64; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat64; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39: +{ +state.ptr += 1; +goto state_label_13; // fnumber_exponent_digits +}break; +case 0x46:case 0x66: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat32; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x4c:case 0x6c: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat64; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_13: // fnumber_exponent_digits +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat64; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat64; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39: +{ +state.ptr += 1; +goto state_label_13; // fnumber_exponent_digits +}break; +case 0x46:case 0x66: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat32; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x4c:case 0x6c: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralFloat64; +token.kind = 9; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_14: // number_hex_first +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66: +{ +state.ptr += 1; +goto state_label_15; // number_hex +}break; +} +} +{ +state_label_15: // number_hex +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralIntegerHex; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralIntegerHex; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66: +{ +state.ptr += 1; +goto state_label_15; // number_hex +}break; +case 0x4c: +{ +state.ptr += 1; +goto state_label_18; // L_number +}break; +case 0x55:case 0x75: +{ +state.ptr += 1; +goto state_label_17; // U_number +}break; +case 0x6c: +{ +state.ptr += 1; +goto state_label_20; // l_number +}break; +} +} +{ +state_label_16: // number_oct +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralIntegerOct; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LiteralIntegerOct; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37: +{ +state.ptr += 1; +state.flags_ZF0 |= 0x2; +goto state_label_16; // number_oct +}break; +case 0x4c: +{ +state.ptr += 1; +goto state_label_18; // L_number +}break; +case 0x55:case 0x75: +{ +state.ptr += 1; +goto state_label_17; // U_number +}break; +case 0x6c: +{ +state.ptr += 1; +goto state_label_20; // l_number +}break; +} +} +{ +state_label_17: // U_number +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexU; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctU; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerU; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexU; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctU; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerU; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x4c: +{ +state.ptr += 1; +goto state_label_19; // UL_number +}break; +case 0x6c: +{ +state.ptr += 1; +goto state_label_21; // Ul_number +}break; +} +} +{ +state_label_18: // L_number +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x4c: +{ +state.ptr += 1; +goto state_label_22; // LL_number +}break; +case 0x55:case 0x75: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexUL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctUL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerUL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_19: // UL_number +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexUL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctUL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerUL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexUL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctUL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerUL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x4c: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexULL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctULL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerULL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_20: // l_number +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x55:case 0x75: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexUL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctUL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerUL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x6c: +{ +state.ptr += 1; +goto state_label_22; // LL_number +}break; +} +} +{ +state_label_21: // Ul_number +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexUL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctUL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerUL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexUL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctUL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerUL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x6c: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexULL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctULL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerULL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_22: // LL_number +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexLL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctLL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerLL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexLL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctLL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerLL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x55:case 0x75: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x1)){ +token.sub_kind = TokenCppKind_LiteralIntegerHexULL; +token.kind = 8; +break; +} +if (HasFlag(state.flags_ZF0, 0x2)){ +token.sub_kind = TokenCppKind_LiteralIntegerOctULL; +token.kind = 8; +break; +} +token.sub_kind = TokenCppKind_LiteralIntegerULL; +token.kind = 8; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_23: // pp_directive_whitespace +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x09:case 0x0b:case 0x0c:case 0x20: +{ +state.ptr += 1; +goto state_label_23; // pp_directive_whitespace +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x47:case 0x48:case 0x49:case 0x4a:case 0x4b: +case 0x4c:case 0x4d:case 0x4e:case 0x4f:case 0x50:case 0x51:case 0x52: +case 0x53:case 0x54:case 0x55:case 0x56:case 0x57:case 0x58:case 0x59: +case 0x5a:case 0x5f:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66:case 0x67:case 0x68:case 0x69:case 0x6a:case 0x6b:case 0x6c: +case 0x6d:case 0x6e:case 0x6f:case 0x70:case 0x71:case 0x72:case 0x73: +case 0x74:case 0x75:case 0x76:case 0x77:case 0x78:case 0x79:case 0x7a: +{ +state.delim_first = state.ptr; +state.flags_KB0 |= 0x1; +state.ptr += 1; +goto state_label_24; // pp_directive +}break; +} +} +{ +state_label_24: // pp_directive +if (state.ptr == state.opl_ptr){ +if ((true)){ +state.delim_one_past_last = state.ptr; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +Lexeme_Table_Lookup lookup = lexeme_table_lookup(cpp_pp_directives_hash_array, cpp_pp_directives_key_array, cpp_pp_directives_value_array, cpp_pp_directives_slot_count, cpp_pp_directives_seed, state.delim_first, (state.delim_one_past_last - state.delim_first)); +if (lookup.found_match){ +token.kind = lookup.base_kind; +token.sub_kind = lookup.sub_kind; +break; +} +token.sub_kind = TokenCppKind_PPUnknown; +token.kind = 2; +}while(0); +switch (token.sub_kind){ +case TokenCppKind_PPInclude: +{ +state.flags_KF0 |= 0x1; +}break; +case TokenCppKind_PPError: +{ +state.flags_KF0 |= 0x2; +}break; +} +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +state.delim_one_past_last = state.ptr; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +Lexeme_Table_Lookup lookup = lexeme_table_lookup(cpp_pp_directives_hash_array, cpp_pp_directives_key_array, cpp_pp_directives_value_array, cpp_pp_directives_slot_count, cpp_pp_directives_seed, state.delim_first, (state.delim_one_past_last - state.delim_first)); +if (lookup.found_match){ +token.kind = lookup.base_kind; +token.sub_kind = lookup.sub_kind; +break; +} +token.sub_kind = TokenCppKind_PPUnknown; +token.kind = 2; +}while(0); +switch (token.sub_kind){ +case TokenCppKind_PPInclude: +{ +state.flags_KF0 |= 0x1; +}break; +case TokenCppKind_PPError: +{ +state.flags_KF0 |= 0x2; +}break; +} +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x47:case 0x48:case 0x49:case 0x4a:case 0x4b: +case 0x4c:case 0x4d:case 0x4e:case 0x4f:case 0x50:case 0x51:case 0x52: +case 0x53:case 0x54:case 0x55:case 0x56:case 0x57:case 0x58:case 0x59: +case 0x5a:case 0x5f:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66:case 0x67:case 0x68:case 0x69:case 0x6a:case 0x6b:case 0x6c: +case 0x6d:case 0x6e:case 0x6f:case 0x70:case 0x71:case 0x72:case 0x73: +case 0x74:case 0x75:case 0x76:case 0x77:case 0x78:case 0x79:case 0x7a: +{ +state.ptr += 1; +goto state_label_24; // pp_directive +}break; +} +} +{ +state_label_25: // include_pointy +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x20:case 0x2e:case 0x2f:case 0x30:case 0x31:case 0x32:case 0x33: +case 0x34:case 0x35:case 0x36:case 0x37:case 0x38:case 0x39:case 0x41: +case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:case 0x48: +case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f: +case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56: +case 0x57:case 0x58:case 0x59:case 0x5a:case 0x5c:case 0x5f:case 0x61: +case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67:case 0x68: +case 0x69:case 0x6a:case 0x6b:case 0x6c:case 0x6d:case 0x6e:case 0x6f: +case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76: +case 0x77:case 0x78:case 0x79:case 0x7a: +{ +state.ptr += 1; +goto state_label_25; // include_pointy +}break; +case 0x3e: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_PPIncludeFile; +token.kind = 10; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_26: // include_quotes +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x20:case 0x2e:case 0x2f:case 0x30:case 0x31:case 0x32:case 0x33: +case 0x34:case 0x35:case 0x36:case 0x37:case 0x38:case 0x39:case 0x41: +case 0x42:case 0x43:case 0x44:case 0x45:case 0x46:case 0x47:case 0x48: +case 0x49:case 0x4a:case 0x4b:case 0x4c:case 0x4d:case 0x4e:case 0x4f: +case 0x50:case 0x51:case 0x52:case 0x53:case 0x54:case 0x55:case 0x56: +case 0x57:case 0x58:case 0x59:case 0x5a:case 0x5c:case 0x5f:case 0x61: +case 0x62:case 0x63:case 0x64:case 0x65:case 0x66:case 0x67:case 0x68: +case 0x69:case 0x6a:case 0x6b:case 0x6c:case 0x6d:case 0x6e:case 0x6f: +case 0x70:case 0x71:case 0x72:case 0x73:case 0x74:case 0x75:case 0x76: +case 0x77:case 0x78:case 0x79:case 0x7a: +{ +state.ptr += 1; +goto state_label_26; // include_quotes +}break; +case 0x22: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_PPIncludeFile; +token.kind = 10; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_27: // pre_L +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_2; // identifier +} +} +switch (*state.ptr){ +default: +{ +goto state_label_2; // identifier +}break; +case 0x22: +{ +state.ptr += 1; +goto state_label_32; // string +}break; +case 0x52: +{ +state.ptr += 1; +goto state_label_31; // pre_R +}break; +} +} +{ +state_label_28: // pre_u +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_2; // identifier +} +} +switch (*state.ptr){ +default: +{ +goto state_label_2; // identifier +}break; +case 0x22: +{ +state.ptr += 1; +goto state_label_32; // string +}break; +case 0x38: +{ +state.ptr += 1; +state.flags_ZF0 |= 0x8; +goto state_label_30; // pre_u8 +}break; +case 0x52: +{ +state.ptr += 1; +goto state_label_31; // pre_R +}break; +} +} +{ +state_label_29: // pre_U +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_2; // identifier +} +} +switch (*state.ptr){ +default: +{ +goto state_label_2; // identifier +}break; +case 0x22: +{ +state.ptr += 1; +goto state_label_32; // string +}break; +case 0x52: +{ +state.ptr += 1; +goto state_label_31; // pre_R +}break; +} +} +{ +state_label_30: // pre_u8 +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_2; // identifier +} +} +switch (*state.ptr){ +default: +{ +goto state_label_2; // identifier +}break; +case 0x22: +{ +state.ptr += 1; +goto state_label_32; // string +}break; +case 0x52: +{ +state.ptr += 1; +goto state_label_31; // pre_R +}break; +} +} +{ +state_label_31: // pre_R +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_2; // identifier +} +} +switch (*state.ptr){ +default: +{ +goto state_label_2; // identifier +}break; +case 0x22: +{ +state.ptr += 1; +state.delim_first = state.ptr; +goto state_label_45; // raw_string_get_delim +}break; +} +} +{ +state_label_32: // string +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +state.ptr += 1; +goto state_label_32; // string +}break; +case 0x0a: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x22: +{ +if ((!HasFlag(state.flags_ZF0, 0x40))){ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x4)){ +token.sub_kind = TokenCppKind_LiteralStringWide; +token.kind = 10; +break; +} +if (HasFlag(state.flags_ZF0, 0x8)){ +token.sub_kind = TokenCppKind_LiteralStringUTF8; +token.kind = 10; +break; +} +if (HasFlag(state.flags_ZF0, 0x10)){ +token.sub_kind = TokenCppKind_LiteralStringUTF16; +token.kind = 10; +break; +} +if (HasFlag(state.flags_ZF0, 0x20)){ +token.sub_kind = TokenCppKind_LiteralStringUTF32; +token.kind = 10; +break; +} +token.sub_kind = TokenCppKind_LiteralString; +token.kind = 10; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +state.ptr += 1; +goto state_label_32; // string +}break; +case 0x27: +{ +if ((HasFlag(state.flags_ZF0, 0x40))){ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x4)){ +token.sub_kind = TokenCppKind_LiteralCharacterWide; +token.kind = 10; +break; +} +if (HasFlag(state.flags_ZF0, 0x8)){ +token.sub_kind = TokenCppKind_LiteralCharacterUTF8; +token.kind = 10; +break; +} +if (HasFlag(state.flags_ZF0, 0x10)){ +token.sub_kind = TokenCppKind_LiteralCharacterUTF16; +token.kind = 10; +break; +} +if (HasFlag(state.flags_ZF0, 0x20)){ +token.sub_kind = TokenCppKind_LiteralCharacterUTF32; +token.kind = 10; +break; +} +token.sub_kind = TokenCppKind_LiteralCharacter; +token.kind = 10; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +state.ptr += 1; +goto state_label_32; // string +}break; +case 0x5c: +{ +state.ptr += 1; +goto state_label_33; // string_esc +}break; +} +} +{ +state_label_33: // string_esc +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_EOF; +token.kind = 0; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +result = true; +goto end; +} +} +switch (*state.ptr){ +default: +{ +state.ptr += 1; +goto state_label_32; // string +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37: +{ +state.ptr += 1; +goto state_label_34; // string_esc_oct2 +}break; +case 0x55: +{ +state.ptr += 1; +goto state_label_37; // string_esc_universal_8 +}break; +case 0x75: +{ +state.ptr += 1; +goto state_label_41; // string_esc_universal_4 +}break; +case 0x78: +{ +state.ptr += 1; +goto state_label_36; // string_esc_hex +}break; +} +} +{ +state_label_34: // string_esc_oct2 +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_32; // string +} +} +switch (*state.ptr){ +default: +{ +goto state_label_32; // string +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37: +{ +state.ptr += 1; +goto state_label_35; // string_esc_oct1 +}break; +} +} +{ +state_label_35: // string_esc_oct1 +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_32; // string +} +} +switch (*state.ptr){ +default: +{ +goto state_label_32; // string +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37: +{ +state.ptr += 1; +goto state_label_32; // string +}break; +} +} +{ +state_label_36: // string_esc_hex +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_32; // string +} +} +switch (*state.ptr){ +default: +{ +goto state_label_32; // string +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66: +{ +state.ptr += 1; +goto state_label_36; // string_esc_hex +}break; +} +} +{ +state_label_37: // string_esc_universal_8 +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_32; // string +} +} +switch (*state.ptr){ +default: +{ +goto state_label_32; // string +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66: +{ +state.ptr += 1; +goto state_label_38; // string_esc_universal_7 +}break; +} +} +{ +state_label_38: // string_esc_universal_7 +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_32; // string +} +} +switch (*state.ptr){ +default: +{ +goto state_label_32; // string +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66: +{ +state.ptr += 1; +goto state_label_39; // string_esc_universal_6 +}break; +} +} +{ +state_label_39: // string_esc_universal_6 +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_32; // string +} +} +switch (*state.ptr){ +default: +{ +goto state_label_32; // string +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66: +{ +state.ptr += 1; +goto state_label_40; // string_esc_universal_5 +}break; +} +} +{ +state_label_40: // string_esc_universal_5 +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_32; // string +} +} +switch (*state.ptr){ +default: +{ +goto state_label_32; // string +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66: +{ +state.ptr += 1; +goto state_label_41; // string_esc_universal_4 +}break; +} +} +{ +state_label_41: // string_esc_universal_4 +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_32; // string +} +} +switch (*state.ptr){ +default: +{ +goto state_label_32; // string +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66: +{ +state.ptr += 1; +goto state_label_42; // string_esc_universal_3 +}break; +} +} +{ +state_label_42: // string_esc_universal_3 +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_32; // string +} +} +switch (*state.ptr){ +default: +{ +goto state_label_32; // string +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66: +{ +state.ptr += 1; +goto state_label_43; // string_esc_universal_2 +}break; +} +} +{ +state_label_43: // string_esc_universal_2 +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_32; // string +} +} +switch (*state.ptr){ +default: +{ +goto state_label_32; // string +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66: +{ +state.ptr += 1; +goto state_label_44; // string_esc_universal_1 +}break; +} +} +{ +state_label_44: // string_esc_universal_1 +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_32; // string +} +} +switch (*state.ptr){ +default: +{ +goto state_label_32; // string +}break; +case 0x30:case 0x31:case 0x32:case 0x33:case 0x34:case 0x35:case 0x36: +case 0x37:case 0x38:case 0x39:case 0x41:case 0x42:case 0x43:case 0x44: +case 0x45:case 0x46:case 0x61:case 0x62:case 0x63:case 0x64:case 0x65: +case 0x66: +{ +state.ptr += 1; +goto state_label_32; // string +}break; +} +} +{ +state_label_45: // raw_string_get_delim +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_EOF; +token.kind = 0; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +result = true; +goto end; +} +} +switch (*state.ptr){ +default: +{ +state.ptr += 1; +goto state_label_45; // raw_string_get_delim +}break; +case 0x20:case 0x29:case 0x5c: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x28: +{ +state.delim_one_past_last = state.ptr; +state.ptr += 1; +goto state_label_46; // raw_string_find_close +}break; +} +} +{ +state_label_46: // raw_string_find_close +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_EOF; +token.kind = 0; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +result = true; +goto end; +} +} +switch (*state.ptr){ +default: +{ +state.ptr += 1; +goto state_label_46; // raw_string_find_close +}break; +case 0x29: +{ +state.ptr += 1; +goto state_label_47; // raw_string_try_delim +}break; +} +} +{ +state_label_47: // raw_string_try_delim +u64 delim_length = state.delim_one_past_last - state.delim_first; +u64 parse_length = 0; +for (;;){ +if (parse_length == delim_length){ +goto state_label_48; // raw_string_try_quote +} +if (state.ptr == state.opl_ptr){ +goto state_label_48; // raw_string_try_quote +} +if (*state.ptr == state.delim_first[parse_length]){ +state.ptr += 1; +parse_length += 1; +} +else{ +goto state_label_46; // raw_string_find_close +} +} +} +{ +state_label_48: // raw_string_try_quote +if (state.ptr == state.opl_ptr){ +if ((true)){ +goto state_label_46; // raw_string_find_close +} +} +switch (*state.ptr){ +default: +{ +goto state_label_46; // raw_string_find_close +}break; +case 0x22: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +if (HasFlag(state.flags_ZF0, 0x4)){ +token.sub_kind = TokenCppKind_LiteralStringWideRaw; +token.kind = 10; +break; +} +if (HasFlag(state.flags_ZF0, 0x8)){ +token.sub_kind = TokenCppKind_LiteralStringUTF8Raw; +token.kind = 10; +break; +} +if (HasFlag(state.flags_ZF0, 0x10)){ +token.sub_kind = TokenCppKind_LiteralStringUTF16Raw; +token.kind = 10; +break; +} +if (HasFlag(state.flags_ZF0, 0x20)){ +token.sub_kind = TokenCppKind_LiteralStringUTF32Raw; +token.kind = 10; +break; +} +token.sub_kind = TokenCppKind_LiteralStringRaw; +token.kind = 10; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_49: // comment_block +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_BlockComment; +token.kind = 3; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_EOF; +token.kind = 0; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +result = true; +goto end; +} +} +switch (*state.ptr){ +default: +{ +state.ptr += 1; +goto state_label_49; // comment_block +}break; +case 0x0a: +{ +state.ptr += 1; +state.flags_KB0 &= ~(0x1); +state.flags_KF0 &= ~(0x1); +goto state_label_49; // comment_block +}break; +case 0x2a: +{ +state.ptr += 1; +goto state_label_50; // comment_block_try_close +}break; +} +} +{ +state_label_50: // comment_block_try_close +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_BlockComment; +token.kind = 3; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_EOF; +token.kind = 0; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +result = true; +goto end; +} +} +switch (*state.ptr){ +default: +{ +state.ptr += 1; +goto state_label_49; // comment_block +}break; +case 0x2a: +{ +state.ptr += 1; +goto state_label_50; // comment_block_try_close +}break; +case 0x2f: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_BlockComment; +token.kind = 3; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_51: // comment_line +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LineComment; +token.kind = 3; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +state.ptr += 1; +goto state_label_51; // comment_line +}break; +case 0x0a: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LineComment; +token.kind = 3; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_52: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Colon; +token.kind = 15; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Colon; +token.kind = 15; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3a: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_ColonColon; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_53: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Plus; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Plus; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x2b: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_PlusPlus; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_PlusEq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_54: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Minus; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Minus; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x2d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_MinusMinus; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_MinusEq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3e: +{ +state.ptr += 1; +goto state_label_55; // op stage +}break; +} +} +{ +state_label_55: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Arrow; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Arrow; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x2a: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_ArrowStar; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_56: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Less; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Less; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3c: +{ +state.ptr += 1; +goto state_label_65; // op stage +}break; +case 0x3d: +{ +state.ptr += 1; +goto state_label_58; // op stage +}break; +} +} +{ +state_label_57: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Grtr; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Grtr; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_GrtrEq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3e: +{ +state.ptr += 1; +goto state_label_66; // op stage +}break; +} +} +{ +state_label_58: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LessEq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LessEq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3e: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Compare; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_59: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Eq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Eq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_EqEq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_60: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Not; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Not; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_NotEq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_61: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_And; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_And; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x26: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_AndAnd; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_62: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Or; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Or; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x7c: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_OrOr; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_63: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Star; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Star; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_StarEq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_64: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Mod; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_Mod; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_ModEq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_65: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LeftLeft; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LeftLeft; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LeftLeftEq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_66: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_RightRight; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_RightRight; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x3d: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_RightRightEq; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_67: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_PPStringify; +token.kind = 15; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_PPStringify; +token.kind = 15; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x23: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_PPConcat; +token.kind = 15; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +{ +state_label_68: // op stage +if (state.ptr == state.opl_ptr){ +if ((true)){ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +} +} +switch (*state.ptr){ +default: +{ +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_LexError; +token.kind = 2; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +case 0x2e: +{ +state.ptr += 1; +{ +Token token = {}; +token.pos = (i64)(state.emit_ptr - state.base); +token.size = (i64)(state.ptr - state.emit_ptr); +token.flags = state.flags_KB0; +do{ +token.sub_kind = TokenCppKind_DotDotDot; +token.kind = 7; +}while(0); +token_list_push(arena, list, &token); +emit_counter += 1; +if (emit_counter == max){ +goto end; +} +state.emit_ptr = state.ptr; +} +state.flags_ZF0 = 0; +goto state_label_1; // root +}break; +} +} +end:; +block_copy_struct(state_ptr, &state); +return(result); } internal Token_List lex_full_input_cpp(Arena *arena, String_Const_u8 input){ - Lex_State_Cpp state = {}; - lex_full_input_cpp_init(&state, input); - Token_List list = {}; - lex_full_input_cpp_breaks(arena, &list, &state, max_u64); - return(list); +Lex_State_Cpp state = {}; +lex_full_input_cpp_init(&state, input); +Token_List list = {}; +lex_full_input_cpp_breaks(arena, &list, &state, max_u64); +return(list); } diff --git a/custom/lexer_generator/4coder_lex_gen_main.cpp b/custom/lexer_generator/4coder_lex_gen_main.cpp index 0974cd26..ec02a67b 100644 --- a/custom/lexer_generator/4coder_lex_gen_main.cpp +++ b/custom/lexer_generator/4coder_lex_gen_main.cpp @@ -3181,7 +3181,7 @@ gen_keyword_table(Arena *scratch, Token_Kind_Set tokens, Keyword_Set keywords, F Temp_Memory temp = begin_temp(scratch); Keyword_Layout key_layout = opt_key_layout(scratch, keywords); - fprintf(out, "u64 %.*s_hash_array[%d] = {\n", + fprintf(out, "u64 " LANG_NAME_LOWER_STR "_%.*s_hash_array[%d] = {\n", string_expand(keywords.pretty_name), key_layout.slot_count); for (i32 i = 0; i < key_layout.slot_count; i += 1){ if (key_layout.slots[i] == 0){ @@ -3198,7 +3198,7 @@ gen_keyword_table(Arena *scratch, Token_Kind_Set tokens, Keyword_Set keywords, F for (i32 i = 0; i < key_layout.slot_count; i += 1){ if (key_layout.slots[i] != 0){ - fprintf(out, "u8 %.*s_key_array_%d[] = {", + fprintf(out, "u8 " LANG_NAME_LOWER_STR "_%.*s_key_array_%d[] = {", string_expand(keywords.pretty_name), i); String_Const_u8 lexeme = key_layout.slots[i]->lexeme; for (u64 j = 0; j < lexeme.size; j += 1){ @@ -3208,20 +3208,20 @@ gen_keyword_table(Arena *scratch, Token_Kind_Set tokens, Keyword_Set keywords, F } } - fprintf(out, "String_Const_u8 %.*s_key_array[%d] = {\n", + fprintf(out, "String_Const_u8 " LANG_NAME_LOWER_STR "_%.*s_key_array[%d] = {\n", string_expand(keywords.pretty_name), key_layout.slot_count); for (i32 i = 0; i < key_layout.slot_count; i += 1){ if (key_layout.slots[i] == 0){ fprintf(out, "{0, 0},\n"); } else{ - fprintf(out, "{%.*s_key_array_%d, %llu},\n", + fprintf(out, "{" LANG_NAME_LOWER_STR "_%.*s_key_array_%d, %llu},\n", string_expand(keywords.pretty_name), i, key_layout.slots[i]->lexeme.size); } } fprintf(out, "};\n"); - fprintf(out, "Lexeme_Table_Value %.*s_value_array[%d] = {\n", + fprintf(out, "Lexeme_Table_Value " LANG_NAME_LOWER_STR "_%.*s_value_array[%d] = {\n", string_expand(keywords.pretty_name), key_layout.slot_count); for (i32 i = 0; i < key_layout.slot_count; i += 1){ if (key_layout.slots[i] == 0){ @@ -3245,9 +3245,9 @@ gen_keyword_table(Arena *scratch, Token_Kind_Set tokens, Keyword_Set keywords, F } fprintf(out, "};\n"); - fprintf(out, "i32 %.*s_slot_count = %d;\n", + fprintf(out, "i32 " LANG_NAME_LOWER_STR "_%.*s_slot_count = %d;\n", string_expand(keywords.pretty_name), key_layout.slot_count); - fprintf(out, "u64 %.*s_seed = 0x%016llx;\n", + fprintf(out, "u64 " LANG_NAME_LOWER_STR "_%.*s_seed = 0x%016llx;\n", string_expand(keywords.pretty_name), key_layout.seed); end_temp(temp); @@ -3453,8 +3453,12 @@ gen_SLOW_action_list__cont_flow(Arena *scratch, Token_Kind_Set tokens, Flag_Set { Keyword_Set *keywords = handler->keywords; fprintf(out, "Lexeme_Table_Lookup lookup = " - "lexeme_table_lookup(%.*s_hash_array, %.*s_key_array, " - "%.*s_value_array, %.*s_slot_count, %.*s_seed, " + "lexeme_table_lookup(" + LANG_NAME_LOWER_STR "_%.*s_hash_array, " + LANG_NAME_LOWER_STR "_%.*s_key_array, " + LANG_NAME_LOWER_STR "_%.*s_value_array, " + LANG_NAME_LOWER_STR "_%.*s_slot_count, " + LANG_NAME_LOWER_STR "_%.*s_seed, " "state.emit_ptr, token.size);\n", string_expand(keywords->pretty_name), string_expand(keywords->pretty_name), @@ -3477,8 +3481,12 @@ gen_SLOW_action_list__cont_flow(Arena *scratch, Token_Kind_Set tokens, Flag_Set { Keyword_Set *keywords = handler->keywords; fprintf(out, "Lexeme_Table_Lookup lookup = " - "lexeme_table_lookup(%.*s_hash_array, %.*s_key_array, " - "%.*s_value_array, %.*s_slot_count, %.*s_seed, " + "lexeme_table_lookup(" + LANG_NAME_LOWER_STR "_%.*s_hash_array, " + LANG_NAME_LOWER_STR "_%.*s_key_array, " + LANG_NAME_LOWER_STR "_%.*s_value_array, " + LANG_NAME_LOWER_STR "_%.*s_slot_count, " + LANG_NAME_LOWER_STR "_%.*s_seed, " "state.delim_first, (state.delim_one_past_last - state.delim_first));\n", string_expand(keywords->pretty_name), string_expand(keywords->pretty_name), From 2375a40b29b5b24a1e4c979afb94bc9fc468b40d Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Thu, 16 Jan 2020 01:07:49 +0200 Subject: [PATCH 090/128] Ifdefed some debug prints to work only on internal builds. --- platform_mac/mac_4ed.mm | 2 +- platform_mac/mac_4ed_metal.mm | 4 ++++ platform_mac/mac_4ed_opengl.mm | 7 +++---- 3 files changed, 8 insertions(+), 5 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 228d87bc..7e792f4f 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -1283,7 +1283,7 @@ main(int arg_count, char **args){ [mac_vars.window makeKeyAndOrderFront:nil]; // NOTE(yuval): Initialize the renderer - renderer = mac_init_renderer(MacRenderer_OpenGL, mac_vars.window, &target); + renderer = mac_init_renderer(MacRenderer_Metal, mac_vars.window, &target); mac_resize(w, h); diff --git a/platform_mac/mac_4ed_metal.mm b/platform_mac/mac_4ed_metal.mm index 0ce3397d..3b03423b 100644 --- a/platform_mac/mac_4ed_metal.mm +++ b/platform_mac/mac_4ed_metal.mm @@ -15,6 +15,10 @@ struct Mac_Metal{ function mac_render_sig(mac_metal__render){ +#if defined(FRED_INTERNAL) + printf("Redering using Metal!\n"); +#endif + Mac_Metal *metal = (Mac_Metal*)renderer; [metal->view draw]; } diff --git a/platform_mac/mac_4ed_opengl.mm b/platform_mac/mac_4ed_opengl.mm index 7efb31c0..dcfe3715 100644 --- a/platform_mac/mac_4ed_opengl.mm +++ b/platform_mac/mac_4ed_opengl.mm @@ -59,7 +59,6 @@ struct Mac_OpenGL{ // NOTE(yuval): Setup vsync GLint swap_int = 1; - printf("Using vsync: %d\n", swap_int); [[self openGLContext] setValues:&swap_int forParameter:NSOpenGLCPSwapInterval]; } @@ -125,7 +124,9 @@ struct Mac_OpenGL{ function mac_render_sig(mac_gl__render){ - printf("Rendering using OpenGL!\n"); +#if defined(FRED_INTERNAL) + printf("Redering using OpenGL!\n"); +#endif Mac_OpenGL *gl = (Mac_OpenGL*)renderer; [gl->view render:target]; @@ -177,8 +178,6 @@ mac_gl__init(NSWindow *window, Render_Target *target){ // TODO(yuval): This function should be exported to a DLL function mac_load_renderer_sig(mac_load_opengl_renderer){ - printf("Loding The OpenGL Renderer!\n"); - Mac_Renderer *renderer = (Mac_Renderer*)mac_gl__init(window, target); return(renderer); } From b6f6663727b88bc5b8fbbdf7720dd56e9cc974cc Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Fri, 17 Jan 2020 00:49:08 +0200 Subject: [PATCH 091/128] Added a key mapping for the equal key. --- custom/generated/4coder_event_codes.h | 400 +++++++++++++------------- platform_mac/mac_4ed.mm | 1 + 2 files changed, 201 insertions(+), 200 deletions(-) diff --git a/custom/generated/4coder_event_codes.h b/custom/generated/4coder_event_codes.h index 8358d6a2..633caf07 100644 --- a/custom/generated/4coder_event_codes.h +++ b/custom/generated/4coder_event_codes.h @@ -1,212 +1,212 @@ enum{ -KeyCode_A = 1, -KeyCode_B = 2, -KeyCode_C = 3, -KeyCode_D = 4, -KeyCode_E = 5, -KeyCode_F = 6, -KeyCode_G = 7, -KeyCode_H = 8, -KeyCode_I = 9, -KeyCode_J = 10, -KeyCode_K = 11, -KeyCode_L = 12, -KeyCode_M = 13, -KeyCode_N = 14, -KeyCode_O = 15, -KeyCode_P = 16, -KeyCode_Q = 17, -KeyCode_R = 18, -KeyCode_S = 19, -KeyCode_T = 20, -KeyCode_U = 21, -KeyCode_V = 22, -KeyCode_W = 23, -KeyCode_X = 24, -KeyCode_Y = 25, -KeyCode_Z = 26, -KeyCode_0 = 27, -KeyCode_1 = 28, -KeyCode_2 = 29, -KeyCode_3 = 30, -KeyCode_4 = 31, -KeyCode_5 = 32, -KeyCode_6 = 33, -KeyCode_7 = 34, -KeyCode_8 = 35, -KeyCode_9 = 36, -KeyCode_Space = 37, -KeyCode_Tick = 38, -KeyCode_Minus = 39, -KeyCode_Equal = 40, -KeyCode_LeftBracket = 41, -KeyCode_RightBracket = 42, -KeyCode_Semicolon = 43, -KeyCode_Quote = 44, -KeyCode_Comma = 45, -KeyCode_Period = 46, -KeyCode_ForwardSlash = 47, -KeyCode_BackwardSlash = 48, -KeyCode_Tab = 49, -KeyCode_Escape = 50, -KeyCode_Pause = 51, -KeyCode_Up = 52, -KeyCode_Down = 53, -KeyCode_Left = 54, -KeyCode_Right = 55, -KeyCode_Backspace = 56, -KeyCode_Return = 57, -KeyCode_Delete = 58, -KeyCode_Insert = 59, -KeyCode_Home = 60, -KeyCode_End = 61, -KeyCode_PageUp = 62, -KeyCode_PageDown = 63, -KeyCode_CapsLock = 64, -KeyCode_NumLock = 65, -KeyCode_ScrollLock = 66, -KeyCode_Menu = 67, -KeyCode_Shift = 68, -KeyCode_Control = 69, -KeyCode_Alt = 70, -KeyCode_Command = 71, -KeyCode_F1 = 72, -KeyCode_F2 = 73, -KeyCode_F3 = 74, -KeyCode_F4 = 75, -KeyCode_F5 = 76, -KeyCode_F6 = 77, -KeyCode_F7 = 78, -KeyCode_F8 = 79, -KeyCode_F9 = 80, -KeyCode_F10 = 81, -KeyCode_F11 = 82, -KeyCode_F12 = 83, -KeyCode_F13 = 84, -KeyCode_F14 = 85, -KeyCode_F15 = 86, -KeyCode_F16 = 87, -KeyCode_COUNT = 88, + KeyCode_A = 1, + KeyCode_B = 2, + KeyCode_C = 3, + KeyCode_D = 4, + KeyCode_E = 5, + KeyCode_F = 6, + KeyCode_G = 7, + KeyCode_H = 8, + KeyCode_I = 9, + KeyCode_J = 10, + KeyCode_K = 11, + KeyCode_L = 12, + KeyCode_M = 13, + KeyCode_N = 14, + KeyCode_O = 15, + KeyCode_P = 16, + KeyCode_Q = 17, + KeyCode_R = 18, + KeyCode_S = 19, + KeyCode_T = 20, + KeyCode_U = 21, + KeyCode_V = 22, + KeyCode_W = 23, + KeyCode_X = 24, + KeyCode_Y = 25, + KeyCode_Z = 26, + KeyCode_0 = 27, + KeyCode_1 = 28, + KeyCode_2 = 29, + KeyCode_3 = 30, + KeyCode_4 = 31, + KeyCode_5 = 32, + KeyCode_6 = 33, + KeyCode_7 = 34, + KeyCode_8 = 35, + KeyCode_9 = 36, + KeyCode_Space = 37, + KeyCode_Tick = 38, + KeyCode_Minus = 39, + KeyCode_Equal = 40, + KeyCode_LeftBracket = 41, + KeyCode_RightBracket = 42, + KeyCode_Semicolon = 43, + KeyCode_Quote = 44, + KeyCode_Comma = 45, + KeyCode_Period = 46, + KeyCode_ForwardSlash = 47, + KeyCode_BackwardSlash = 48, + KeyCode_Tab = 49, + KeyCode_Escape = 50, + KeyCode_Pause = 51, + KeyCode_Up = 52, + KeyCode_Down = 53, + KeyCode_Left = 54, + KeyCode_Right = 55, + KeyCode_Backspace = 56, + KeyCode_Return = 57, + KeyCode_Delete = 58, + KeyCode_Insert = 59, + KeyCode_Home = 60, + KeyCode_End = 61, + KeyCode_PageUp = 62, + KeyCode_PageDown = 63, + KeyCode_CapsLock = 64, + KeyCode_NumLock = 65, + KeyCode_ScrollLock = 66, + KeyCode_Menu = 67, + KeyCode_Shift = 68, + KeyCode_Control = 69, + KeyCode_Alt = 70, + KeyCode_Command = 71, + KeyCode_F1 = 72, + KeyCode_F2 = 73, + KeyCode_F3 = 74, + KeyCode_F4 = 75, + KeyCode_F5 = 76, + KeyCode_F6 = 77, + KeyCode_F7 = 78, + KeyCode_F8 = 79, + KeyCode_F9 = 80, + KeyCode_F10 = 81, + KeyCode_F11 = 82, + KeyCode_F12 = 83, + KeyCode_F13 = 84, + KeyCode_F14 = 85, + KeyCode_F15 = 86, + KeyCode_F16 = 87, + KeyCode_COUNT = 88, }; global char* key_code_name[KeyCode_COUNT] = { -"None", -"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", -"0", -"1", -"2", -"3", -"4", -"5", -"6", -"7", -"8", -"9", -"Space", -"Tick", -"Minus", -"Equal", -"LeftBracket", -"RightBracket", -"Semicolon", -"Quote", -"Comma", -"Period", -"ForwardSlash", -"BackwardSlash", -"Tab", -"Escape", -"Pause", -"Up", -"Down", -"Left", -"Right", -"Backspace", -"Return", -"Delete", -"Insert", -"Home", -"End", -"PageUp", -"PageDown", -"CapsLock", -"NumLock", -"ScrollLock", -"Menu", -"Shift", -"Control", -"Alt", -"Command", -"F1", -"F2", -"F3", -"F4", -"F5", -"F6", -"F7", -"F8", -"F9", -"F10", -"F11", -"F12", -"F13", -"F14", -"F15", -"F16", + "None", + "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", + "0", + "1", + "2", + "3", + "4", + "5", + "6", + "7", + "8", + "9", + "Space", + "Tick", + "Minus", + "Equal", + "LeftBracket", + "RightBracket", + "Semicolon", + "Quote", + "Comma", + "Period", + "ForwardSlash", + "BackwardSlash", + "Tab", + "Escape", + "Pause", + "Up", + "Down", + "Left", + "Right", + "Backspace", + "Return", + "Delete", + "Insert", + "Home", + "End", + "PageUp", + "PageDown", + "CapsLock", + "NumLock", + "ScrollLock", + "Menu", + "Shift", + "Control", + "Alt", + "Command", + "F1", + "F2", + "F3", + "F4", + "F5", + "F6", + "F7", + "F8", + "F9", + "F10", + "F11", + "F12", + "F13", + "F14", + "F15", + "F16", }; enum{ -MouseCode_Left = 1, -MouseCode_Middle = 2, -MouseCode_Right = 3, -MouseCode_COUNT = 4, + MouseCode_Left = 1, + MouseCode_Middle = 2, + MouseCode_Right = 3, + MouseCode_COUNT = 4, }; global char* mouse_code_name[MouseCode_COUNT] = { -"None", -"Left", -"Middle", -"Right", + "None", + "Left", + "Middle", + "Right", }; enum{ -CoreCode_Startup = 1, -CoreCode_Animate = 2, -CoreCode_ClickActivateView = 3, -CoreCode_ClickDeactivateView = 4, -CoreCode_TryExit = 5, -CoreCode_FileExternallyModified = 6, -CoreCode_NewClipboardContents = 7, -CoreCode_COUNT = 8, + CoreCode_Startup = 1, + CoreCode_Animate = 2, + CoreCode_ClickActivateView = 3, + CoreCode_ClickDeactivateView = 4, + CoreCode_TryExit = 5, + CoreCode_FileExternallyModified = 6, + CoreCode_NewClipboardContents = 7, + CoreCode_COUNT = 8, }; global char* core_code_name[CoreCode_COUNT] = { -"None", -"Startup", -"Animate", -"ClickActivateView", -"ClickDeactivateView", -"TryExit", -"FileExternallyModified", -"NewClipboardContents", + "None", + "Startup", + "Animate", + "ClickActivateView", + "ClickDeactivateView", + "TryExit", + "FileExternallyModified", + "NewClipboardContents", }; diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 7e792f4f..e4ca5ec1 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -387,6 +387,7 @@ mac_keycode_init(void){ keycode_lookup_table[kVK_Space] = KeyCode_Space; keycode_lookup_table[kVK_ANSI_Grave] = KeyCode_Tick; keycode_lookup_table[kVK_ANSI_Minus] = KeyCode_Minus; + keycode_lookup_table[kVK_ANSI_Equal] = KeyCode_Equal; keycode_lookup_table[kVK_ANSI_LeftBracket] = KeyCode_LeftBracket; keycode_lookup_table[kVK_ANSI_RightBracket] = KeyCode_RightBracket; keycode_lookup_table[kVK_ANSI_Semicolon] = KeyCode_Semicolon; From 939c568285891ff38244b0e7744563899faac1c5 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 16 Jan 2020 18:08:51 -0800 Subject: [PATCH 092/128] Some random change I want to keep --- custom/4coder_lists.cpp | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom/4coder_lists.cpp b/custom/4coder_lists.cpp index ab7593bf..1c3a5f13 100644 --- a/custom/4coder_lists.cpp +++ b/custom/4coder_lists.cpp @@ -397,7 +397,7 @@ get_file_name_from_user(Application_Links *app, Arena *arena, String_Const_u8 qu result.file_name_in_text_field = string_front_of_path(l_result.text_field); String_Const_u8 path = {}; - if (result.file_name_in_text_field.size == 0 && l_result.text_field.size > 0){ + if (!result.is_folder && result.file_name_in_text_field.size == 0 && l_result.text_field.size > 0){ result.file_name_in_text_field = string_front_folder_of_path(l_result.text_field); path = string_remove_front_folder_of_path(l_result.text_field); } From 99f30cfe771e2694a86ce02ad3368b89ccf2f566 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 16 Jan 2020 18:33:00 -0800 Subject: [PATCH 093/128] Merge other things that didn't come up on windows build --- bin/4ed_build.cpp | 54 ++++++----------------------------------------- 1 file changed, 6 insertions(+), 48 deletions(-) diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index 3bce85f6..ed5b07db 100644 --- a/bin/4ed_build.cpp +++ b/bin/4ed_build.cpp @@ -69,11 +69,8 @@ char *compiler_names[] = { # define This_Compiler Compiler_CL #elif COMPILER_GCC # define This_Compiler Compiler_GCC -<<<<<<< HEAD -======= #elif COMPILER_CLANG # define This_Compiler Compiler_Clang ->>>>>>> yuval_macos_platform_layer #else # error This compilers is not enumerated. #endif @@ -306,29 +303,6 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha #define GCC_LIBS_X64 GCC_LIBS_COMMON #define GCC_LIBS_X86 GCC_LIBS_COMMON -<<<<<<< HEAD -#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 -======= #else # error gcc options not set for this platform #endif @@ -427,7 +401,6 @@ FOREIGN "/x86/libfreetype-mac.a" #else # error clang options not set for this platform ->>>>>>> yuval_macos_platform_layer #endif internal void @@ -448,11 +421,7 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha } if (flags & OPTS){ - <<<<<<< HEAD - fm_add_to_line(line, GCC_OPTS); - ======= - fm_add_to_line(line, CLANG_OPTS); - >>>>>>> yuval_macos_platform_layer + fm_add_to_line(line, CLANG_OPTS); } fm_add_to_line(line, "-I%s", code_path); @@ -489,32 +458,21 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha if (flags & LIBS){ if (arch == Arch_X64){ - <<<<<<< HEAD - fm_add_to_line(line, GCC_LIBS_X64); - } - else if (arch == Arch_X86) - { - fm_add_to_line(line, GCC_LIBS_X86); - ======= - fm_add_to_line(line, CLANG_LIBS_X64); + fm_add_to_line(line, CLANG_LIBS_X64); } else if (arch == Arch_X86) { fm_add_to_line(line, CLANG_LIBS_X86); - >>>>>>> yuval_macos_platform_layer } } fm_finish_build_line(&line); Temp_Dir temp = fm_pushdir(out_path); - <<<<<<< HEAD - systemf("g++ %s -o %s", line.build_options, out_file); - ======= - // systemf("clang++ %s -E -o %s", line.build_options, "4ed.i"); - systemf("clang++ %s -o %s", line.build_options, out_file); - >>>>>>> yuval_macos_platform_layer - fm_popdir(temp); + + // systemf("clang++ %s -E -o %s", line.build_options, "4ed.i"); + systemf("clang++ %s -o %s", line.build_options, out_file); + fm_popdir(temp); } #else From e9a0aa9c1beaa0267ab8be3714e1c13ec004916c Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 16 Jan 2020 19:58:24 -0800 Subject: [PATCH 094/128] Fixed file opening bug; deleted dSYM file --- custom/4coder_lists.cpp | 2 +- .../Contents/Info.plist | 20 ------------------ .../Resources/DWARF/metadata_generator | Bin 136740 -> 0 bytes project.4coder | 1 + ship_files/config.4coder | 2 +- ship_files_super/project.4coder | 1 + 6 files changed, 4 insertions(+), 22 deletions(-) delete mode 100644 custom/metadata_generator.dSYM/Contents/Info.plist delete mode 100644 custom/metadata_generator.dSYM/Contents/Resources/DWARF/metadata_generator diff --git a/custom/4coder_lists.cpp b/custom/4coder_lists.cpp index 1c3a5f13..443c5f74 100644 --- a/custom/4coder_lists.cpp +++ b/custom/4coder_lists.cpp @@ -397,7 +397,7 @@ get_file_name_from_user(Application_Links *app, Arena *arena, String_Const_u8 qu result.file_name_in_text_field = string_front_of_path(l_result.text_field); String_Const_u8 path = {}; - if (!result.is_folder && result.file_name_in_text_field.size == 0 && l_result.text_field.size > 0){ + if (l_result.user_data == 0 && result.file_name_in_text_field.size == 0 && l_result.text_field.size > 0){ result.file_name_in_text_field = string_front_folder_of_path(l_result.text_field); path = string_remove_front_folder_of_path(l_result.text_field); } diff --git a/custom/metadata_generator.dSYM/Contents/Info.plist b/custom/metadata_generator.dSYM/Contents/Info.plist deleted file mode 100644 index a05ad97b..00000000 --- a/custom/metadata_generator.dSYM/Contents/Info.plist +++ /dev/null @@ -1,20 +0,0 @@ - - - - - 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 deleted file mode 100644 index 815fd87182819f59da407a6ef16a81b7f4629669..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 136740 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
    BESjpXtDu25#xOK5VZ~ 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 diff --git a/project.4coder b/project.4coder index a4a31ba8..a61663bb 100644 --- a/project.4coder +++ b/project.4coder @@ -6,6 +6,7 @@ patterns = { "*.cpp", "*.h", "*.m", +"*.mm", "*.bat", "*.sh", "*.4coder", diff --git a/ship_files/config.4coder b/ship_files/config.4coder index bfe0fc32..b59a01cc 100644 --- a/ship_files/config.4coder +++ b/ship_files/config.4coder @@ -23,7 +23,7 @@ lister_whole_word_backspace_when_modified = false; show_line_number_margins = false; // Code Wrapping -treat_as_code = ".cpp.c.hpp.h.cc.cs.java.rs.glsl.m"; +treat_as_code = ".cpp.c.hpp.h.cc.cs.java.rs.glsl.m.mm"; enable_virtual_whitespace = true; enable_code_wrapping = true; automatically_adjust_wrapping = true; diff --git a/ship_files_super/project.4coder b/ship_files_super/project.4coder index b976c45d..261a97f0 100644 --- a/ship_files_super/project.4coder +++ b/ship_files_super/project.4coder @@ -6,6 +6,7 @@ patterns = { "*.cpp", "*.h", "*.m", +"*.mm", "*.bat", "*.sh", "*.4coder", From 3afa6debb7847e7bf302877dabebcb6d09b39ec0 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 16 Jan 2020 20:01:37 -0800 Subject: [PATCH 095/128] added .dSYM to gitignore --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 47f4eb31..0872785b 100644 --- a/.gitignore +++ b/.gitignore @@ -1,3 +1,4 @@ vc120.pdb 4ed_data.ctm .DS_Store +*.dSYM \ No newline at end of file From 0335a1a7189ceeacc837f16d1aa35875f4309199 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 19 Jan 2020 02:47:43 +0200 Subject: [PATCH 096/128] Implemented a texture slot batch allocating system for the Metal renderer. --- custom/generated/command_metadata.h | 458 ++++++++++++++-------------- metal/4ed_metal_render.mm | 183 ++++++++--- metal/AAPLShaderTypes.h | 25 -- metal/AAPLShaders.metal | 64 ---- platform_mac/mac_4ed.mm | 1 + 5 files changed, 368 insertions(+), 363 deletions(-) delete mode 100644 metal/AAPLShaderTypes.h delete mode 100644 metal/AAPLShaders.metal diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 1c461ef6..f1f6a3f3 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, 407 }, -{ 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, 417 }, -{ 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, 398 }, -{ 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, 611 }, -{ 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, 576 }, -{ 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, 619 }, -{ 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, 753 }, -{ 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, 682 }, -{ 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, 1793 }, -{ 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, 51 }, -{ 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, 1219 }, -{ 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, 1391 }, -{ 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, 1377 }, -{ 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, 738 }, -{ 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, 525 }, -{ 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, 542 }, -{ 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, 348 }, -{ 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, 375 }, -{ 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, 746 }, -{ 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, 464 }, -{ 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, 494 }, -{ 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, 481 }, -{ 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, 511 }, -{ 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, 649 }, -{ 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, 635 }, -{ 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, 564 }, -{ 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, 581 }, -{ 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, 671 }, -{ 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, 520 }, -{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 657 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 707 }, -{ 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, 612 }, -{ 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, 510 }, -{ 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, 54 }, -{ 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, 77 }, -{ 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, 41 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1537 }, -{ 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, 296 }, -{ 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, 302 }, -{ 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, 1331 }, -{ 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, 693 }, -{ 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, 336 }, -{ 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, 348 }, -{ 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, 354 }, -{ 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, 407 }, -{ 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, 431 }, -{ 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, 419 }, -{ 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, 437 }, -{ 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, 514 }, -{ 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, 528 }, -{ 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, 486 }, -{ 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, 471 }, -{ 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, 500 }, -{ 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, 1371 }, -{ 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, 1365 }, -{ 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, 445 }, -{ 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, 507 }, -{ 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, 521 }, -{ 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, 479 }, -{ 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, 463 }, -{ 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, 493 }, -{ 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, 330 }, -{ 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, 342 }, -{ 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, 401 }, -{ 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, 425 }, -{ 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, 413 }, -{ 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, 1456 }, -{ 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, 1787 }, -{ 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, 1488 }, -{ 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, 372 }, -{ 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, 364 }, -{ 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, 109 }, -{ 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, 70 }, -{ 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, 116 }, -{ 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, 1147 }, -{ 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, 1168 }, -{ 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, 1184 }, -{ 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, 1626 }, -{ 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, 1711 }, -{ 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, 1296 }, -{ 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, 1555 }, -{ 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, 1057 }, -{ 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, 1048 }, -{ 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, 1039 }, -{ 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, 980 }, -{ 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, 992 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1545 }, -{ 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, 1263 }, -{ 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, 974 }, -{ 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, 986 }, -{ 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, 537 }, -{ 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, 642 }, -{ 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, 628 }, -{ 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, 1513 }, -{ 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, 777 }, -{ 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, 563 }, -{ 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, 550 }, -{ 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, 656 }, -{ 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, 665 }, -{ 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, 719 }, -{ 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, 725 }, -{ 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, 710 }, -{ 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, 1170 }, -{ 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, 1613 }, -{ 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, 1640 }, -{ 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, 1501 }, -{ 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 a space.", 16, "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, 427 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 407 }, +{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 417 }, +{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 398 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 154 }, +{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 611 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 128 }, +{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 186 }, +{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 576 }, +{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 480 }, +{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 243 }, +{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 842 }, +{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 180 }, +{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 619 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_docs.cpp", 49, 190 }, +{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 753 }, +{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 149 }, +{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 19 }, +{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_docs.cpp", 49, 175 }, +{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 28 }, +{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 682 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1793 }, +{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 7 }, +{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 23 }, +{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 51 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 162 }, +{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1219 }, +{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1391 }, +{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 134 }, +{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1377 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_cli_command.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_cli_command.cpp", 56, 7 }, +{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 738 }, +{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 2184 }, +{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 525 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 542 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 348 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 375 }, +{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 746 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 464 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 494 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 481 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 511 }, +{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 649 }, +{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 635 }, +{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 564 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 581 }, +{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 671 }, +{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 520 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 657 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 707 }, +{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 612 }, +{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 510 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_code_index_listers.cpp", 63, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 54 }, +{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 77 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 41 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1537 }, +{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 296 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 302 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1331 }, +{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 249 }, +{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 693 }, +{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 265 }, +{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 336 }, +{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 348 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 354 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 407 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 431 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 419 }, +{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 437 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 514 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 528 }, +{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 486 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 471 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 500 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1371 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1365 }, +{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 445 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 507 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 521 }, +{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 479 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 463 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 493 }, +{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 330 }, +{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 342 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 401 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 425 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 413 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1456 }, +{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1787 }, +{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1488 }, +{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 310 }, +{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 372 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 364 }, +{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 109 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 70 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 116 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 106 }, +{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 226 }, +{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 219 }, +{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 212 }, +{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "/Users/yuvaldolev/4ed/code/custom/4coder_profile_inspect.cpp", 60, 886 }, +{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1147 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1168 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1184 }, +{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1626 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1711 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1296 }, +{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1555 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1057 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1048 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1039 }, +{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 980 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 992 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1545 }, +{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1263 }, +{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 974 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 986 }, +{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 537 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 27 }, +{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 99 }, +{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 115 }, +{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 427 }, +{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 1230 }, +{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 642 }, +{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 628 }, +{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_log_parser.cpp", 55, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 187 }, +{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 403 }, +{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1513 }, +{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 777 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 563 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 550 }, +{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 656 }, +{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 665 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 439 }, +{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 433 }, +{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 719 }, +{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 725 }, +{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 445 }, +{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 710 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_code_index.cpp", 55, 1170 }, +{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 20 }, +{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 34 }, +{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 137 }, +{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1613 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1640 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1501 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_lister.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 392 }, +{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 639 }, +{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 88 }, +{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 427 }, +{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 76 }, +{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 73 }, +{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 100 }, }; static i32 fcoder_metacmd_ID_allow_mouse = 0; static i32 fcoder_metacmd_ID_auto_indent_line_at_cursor = 1; diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index 6f029cc7..c19c4df3 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -4,14 +4,10 @@ #undef function #import #import - -#include "AAPLShaderTypes.h" #define function static //////////////////////////////// -typedef id Metal_Texture; - struct Metal_Buffer{ Node node; @@ -22,6 +18,47 @@ struct Metal_Buffer{ //////////////////////////////// +typedef id Metal_Texture; + +global_const u32 metal__texture_slots_per_bucket = 256; + +// NOTE(yuval): This a bucket of ACTUAL texture slots. +struct Metal_Texture_Slot_Bucket{ + Metal_Texture_Slot_Bucket *next; + Metal_Texture textures[metal__texture_slots_per_bucket]; +}; + +// NOTE(yuval): This is a locator used to describe where a specific slot is located. +union Metal_Texture_Slot_Locator{ + u32 packed; + + struct{ + u16 bucket_index; + u16 slot_index; + }; +}; + +// NOTE(yuval): This is a node containing the locator inside the free slot list. +// This is a separate struct from the Texture_Slot_Locator because the locator's size has to be exactly 32 bits (to support returning the packed slot from get_texture_of_dim). +struct Metal_Texture_Slot_Locator_Node{ + Metal_Texture_Slot_Locator_Node *next; + Metal_Texture_Slot_Locator locator; +}; + +// NOTE(yuval): This a struct contaning all texture slot buckets and the texture slot free list (a list of free texture slots described by their locators). +struct Metal_Texture_Slot_List{ + Metal_Texture_Slot_Bucket *first_bucket; + Metal_Texture_Slot_Bucket *last_bucket; + u16 bucket_count; + + Metal_Texture_Slot_Locator_Node *first_free_slot; + Metal_Texture_Slot_Locator_Node *last_free_slot; +}; + +global_const u32 metal__invalid_texture_slot_locator = (u32)-1; + +//////////////////////////////// + @interface Metal_Renderer : NSObject @property (nonatomic) Render_Target *target; @@ -30,6 +67,8 @@ struct Metal_Buffer{ - (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind; - (b32)fill_texture:(u32)texture kind:(Texture_Kind)kind pos:(Vec3_i32)p dim:(Vec3_i32)dim data:(void*)data; - (void)bind_texture:(u32)handle encoder:(id)render_encoder; +- (Metal_Texture*)get_texture_slot_at_locator:(Metal_Texture_Slot_Locator)locator; +- (Metal_Texture*)get_texture_slot_at_handle:(u32)handle; - (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size; - (void)add_reusable_buffer:(Metal_Buffer*)buffer; @@ -37,10 +76,6 @@ struct Metal_Buffer{ //////////////////////////////// -global_const u32 metal__max_textures = 256; - -//////////////////////////////// - global_const char *metal__shaders_source = R"( #include #include @@ -163,8 +198,7 @@ metal__make_buffer(u32 size, id device){ Node buffer_cache; u64 last_buffer_cache_purge_time; - Metal_Texture *textures; - u32 next_texture_handle_index; + Metal_Texture_Slot_List texture_slots; } - (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtk_view target:(Render_Target*)target{ @@ -245,9 +279,8 @@ metal__make_buffer(u32 size, id device){ dll_init_sentinel(&buffer_cache); last_buffer_cache_purge_time = system_now_time(); - // NOTE(yuval): Initialize the textures array - textures = (Metal_Texture*)system_memory_allocate(metal__max_textures * sizeof(Metal_Texture), file_name_line_number_lit_u8); - next_texture_handle_index = 0; + // NOTE(yuval): Initialize the texture slot list + block_zero_struct(&texture_slots); // NOTE(yuval): Create the fallback texture _target->fallback_texture_id = [self get_texture_of_dim:V3i32(2, 2, 1) @@ -428,21 +461,50 @@ metal__make_buffer(u32 size, id device){ } - (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind{ - u32 handle = next_texture_handle_index; + u32 handle = metal__invalid_texture_slot_locator; - // NOTE(yuval): Create a texture descriptor - MTLTextureDescriptor *texture_descriptor = [[MTLTextureDescriptor alloc] init]; - texture_descriptor.textureType = MTLTextureType2DArray; - texture_descriptor.pixelFormat = MTLPixelFormatR8Unorm; - texture_descriptor.width = dim.x; - texture_descriptor.height = dim.y; - texture_descriptor.depth = dim.z; + // NOTE(yuval): Check for a free texture slot and allocate another slot bucket if no free slot has been found + if (!texture_slots.first_free_slot){ + Metal_Texture_Slot_Bucket *bucket = + (Metal_Texture_Slot_Bucket*)system_memory_allocate(sizeof(Metal_Texture_Slot_Bucket) + (sizeof(Metal_Texture_Slot_Locator_Node) * metal__texture_slots_per_bucket), file_name_line_number_lit_u8); + + Metal_Texture_Slot_Locator_Node *locator_array = (Metal_Texture_Slot_Locator_Node*)(bucket + 1); + for (u32 locator_index = 0; + locator_index < metal__texture_slots_per_bucket; + ++locator_index){ + Metal_Texture_Slot_Locator_Node *node = &locator_array[locator_index]; + node->locator.bucket_index = texture_slots.bucket_count; + node->locator.slot_index = locator_index; + + sll_queue_push(texture_slots.first_free_slot, texture_slots.last_free_slot, node); + } + + sll_queue_push(texture_slots.first_bucket, texture_slots.last_bucket, bucket); + ++texture_slots.bucket_count; + } + Assert(texture_slots.first_free_slot); - // NOTE(yuval): Create the texture from the device using the descriptor and add it to the textures array - Metal_Texture texture = [device newTextureWithDescriptor:texture_descriptor]; - textures[handle] = texture; + // NOTE(yuval): Get the first free texture slot's locator and remove it from the free list + Metal_Texture_Slot_Locator locator = texture_slots.first_free_slot->locator; + sll_queue_pop(texture_slots.first_free_slot, texture_slots.last_free_slot); - next_texture_handle_index += 1; + Metal_Texture *texture_slot = + [self get_texture_slot_at_locator:locator]; + if (texture_slot){ + // NOTE(yuval): Create a texture descriptor + MTLTextureDescriptor *texture_descriptor = [[MTLTextureDescriptor alloc] init]; + texture_descriptor.textureType = MTLTextureType2DArray; + texture_descriptor.pixelFormat = MTLPixelFormatR8Unorm; + texture_descriptor.width = dim.x; + texture_descriptor.height = dim.y; + texture_descriptor.depth = dim.z; + + // NOTE(yuval): Create the texture from the device using the descriptor and add it to the textures array + Metal_Texture texture = [device newTextureWithDescriptor:texture_descriptor]; + *texture_slot = texture; + + handle = locator.packed; + } return handle; } @@ -451,35 +513,66 @@ metal__make_buffer(u32 size, id device){ b32 result = false; if (data){ - Metal_Texture texture = textures[handle]; - - if (texture != 0){ - MTLRegion replace_region = { - {(NSUInteger)p.x, (NSUInteger)p.y, (NSUInteger)p.z}, - {(NSUInteger)dim.x, (NSUInteger)dim.y, (NSUInteger)dim.z} - }; + Metal_Texture *texture_slot = [self get_texture_slot_at_handle:handle]; + if (texture_slot){ + Metal_Texture texture = *texture_slot; - // NOTE(yuval): Fill the texture with data - [texture replaceRegion:replace_region - mipmapLevel:0 - withBytes:data - bytesPerRow:dim.x]; - - result = true; + if (texture != 0){ + MTLRegion replace_region = { + {(NSUInteger)p.x, (NSUInteger)p.y, (NSUInteger)p.z}, + {(NSUInteger)dim.x, (NSUInteger)dim.y, (NSUInteger)dim.z} + }; + + // NOTE(yuval): Fill the texture with data + [texture replaceRegion:replace_region + mipmapLevel:0 + withBytes:data + bytesPerRow:dim.x]; + + result = true; + } } } - return result; + return(result); } - (void)bind_texture:(u32)handle encoder:(id)render_encoder{ - Metal_Texture texture = textures[handle]; - if (texture != 0){ - [render_encoder setFragmentTexture:texture - atIndex:0]; + Metal_Texture *texture_slot = [self get_texture_slot_at_handle:handle]; + if (texture_slot){ + Metal_Texture texture = *texture_slot; + if (texture != 0){ + [render_encoder setFragmentTexture:texture + atIndex:0]; + } } } +- (Metal_Texture*)get_texture_slot_at_locator:(Metal_Texture_Slot_Locator)locator{ + Metal_Texture *result = 0; + + if (locator.packed != metal__invalid_texture_slot_locator){ + Metal_Texture_Slot_Bucket *bucket = texture_slots.first_bucket; + for (u16 bucket_index = 0; + (bucket_index < locator.bucket_index) && bucket; + ++bucket_index, bucket = bucket->next); + + if (bucket && (locator.slot_index < metal__texture_slots_per_bucket)){ + result = &bucket->textures[locator.slot_index]; + } + } + + return(result); +} + +- (Metal_Texture*)get_texture_slot_at_handle:(u32)handle{ + Metal_Texture_Slot_Locator locator; + locator.packed = handle; + + Metal_Texture *texture_slot = [self get_texture_slot_at_locator:locator]; + return(texture_slot); +} + - (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size{ // NOTE(yuval): This routine is a modified version of Dear ImGui's MetalContext::dequeueReusableBufferOfLength in imgui_impl_metal.mm @@ -524,7 +617,7 @@ metal__make_buffer(u32 size, id device){ result = metal__make_buffer(size, device); } - return result; + return(result); } - (void)add_reusable_buffer:(Metal_Buffer*)buffer{ diff --git a/metal/AAPLShaderTypes.h b/metal/AAPLShaderTypes.h deleted file mode 100644 index a464b446..00000000 --- a/metal/AAPLShaderTypes.h +++ /dev/null @@ -1,25 +0,0 @@ -/* -See LICENSE folder for this sample’s licensing information. - -Abstract: -Header containing types and enum constants shared between Metal shaders and C/ObjC source -*/ - -#ifndef AAPLShaderTypes_h -#define AAPLShaderTypes_h - -#undef clamp -#include -#define clamp(a,x,b) clamp_((a),(x),(b)) - -// This structure defines the layout of vertices sent to the vertex -// shader. This header is shared between the .metal shader and C code, to guarantee that -// the layout of the vertex array in the C code matches the layout that the .metal -// vertex shader expects. -typedef struct -{ - vector_float2 position; - vector_float4 color; -} AAPLVertex; - -#endif /* AAPLShaderTypes_h */ diff --git a/metal/AAPLShaders.metal b/metal/AAPLShaders.metal deleted file mode 100644 index 60c3736b..00000000 --- a/metal/AAPLShaders.metal +++ /dev/null @@ -1,64 +0,0 @@ -/* -See LICENSE folder for this sample’s licensing information. - -Abstract: -Metal shaders used for this sample -*/ - -#include -#include - -using namespace metal; - -// Include header shared between this Metal shader code and C code executing Metal API commands. -#import "AAPLShaderTypes.h" - -// Vertex shader outputs and fragment shader inputs -typedef struct -{ - // The [[position]] attribute of this member indicates that this value - // is the clip space position of the vertex when this structure is - // returned from the vertex function. - float4 position [[position]]; - - // Since this member does not have a special attribute, the rasterizer - // interpolates its value with the values of the other triangle vertices - // and then passes the interpolated value to the fragment shader for each - // fragment in the triangle. - float4 color; - -} RasterizerData; - -vertex RasterizerData -vertexShader(uint vertexID [[vertex_id]], - constant AAPLVertex *vertices [[buffer(AAPLVertexInputIndexVertices)]], - constant vector_uint2 *viewportSizePointer [[buffer(AAPLVertexInputIndexViewportSize)]]) -{ - RasterizerData out; - - // Index into the array of positions to get the current vertex. - // The positions are specified in pixel dimensions (i.e. a value of 100 - // is 100 pixels from the origin). - float2 pixelSpacePosition = vertices[vertexID].position.xy; - - // Get the viewport size and cast to float. - vector_float2 viewportSize = vector_float2(*viewportSizePointer); - - - // To convert from positions in pixel space to positions in clip-space, - // divide the pixel coordinates by half the size of the viewport. - out.position = vector_float4(0.0, 0.0, 0.0, 1.0); - out.position.xy = pixelSpacePosition / (viewportSize / 2.0); - - // Pass the input color directly to the rasterizer. - out.color = vertices[vertexID].color; - - return out; -} - -fragment float4 fragmentShader(RasterizerData in [[stage_in]]) -{ - // Return the interpolated color. - return in.color; -} - diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index e4ca5ec1..37897dfd 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -583,6 +583,7 @@ mac_toggle_fullscreen(void){ } - (void)windowDidResize:(NSNotification*)notification{ + printf("Resize!\n"); mac_resize(mac_vars.window); } From 00d8206ad237929ab33fc125efad19fb62479e66 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 19 Jan 2020 03:05:56 +0200 Subject: [PATCH 097/128] Fixed live resizing bug with the layer based view. --- metal/4ed_metal_render.mm | 5 ++++- platform_mac/mac_4ed.mm | 5 ++--- 2 files changed, 6 insertions(+), 4 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index c19c4df3..fc789cb9 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -465,6 +465,9 @@ metal__make_buffer(u32 size, id device){ // NOTE(yuval): Check for a free texture slot and allocate another slot bucket if no free slot has been found if (!texture_slots.first_free_slot){ + // NOTE(yuval): Assert that the next bucket's index can fit in a u16 + Assert(texture_slots.bucket_count < ((u16)-1)); + Metal_Texture_Slot_Bucket *bucket = (Metal_Texture_Slot_Bucket*)system_memory_allocate(sizeof(Metal_Texture_Slot_Bucket) + (sizeof(Metal_Texture_Slot_Locator_Node) * metal__texture_slots_per_bucket), file_name_line_number_lit_u8); @@ -480,7 +483,7 @@ metal__make_buffer(u32 size, id device){ } sll_queue_push(texture_slots.first_bucket, texture_slots.last_bucket, bucket); - ++texture_slots.bucket_count; + texture_slots.bucket_count += 1; } Assert(texture_slots.first_free_slot); diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 37897dfd..09dcc170 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -583,8 +583,8 @@ mac_toggle_fullscreen(void){ } - (void)windowDidResize:(NSNotification*)notification{ - printf("Resize!\n"); mac_resize(mac_vars.window); + [mac_vars.view display]; } - (void)windowDidMiniaturize:(NSNotification*)notification{ @@ -630,8 +630,7 @@ mac_toggle_fullscreen(void){ mac_resize(mac_vars.window); } -- (BOOL)wantsUpdateLayer -{ +- (BOOL)wantsUpdateLayer{ return YES; } From 63b964f1c51408c9b8a87e28cd576dd941207501 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 19 Jan 2020 04:44:52 +0200 Subject: [PATCH 098/128] Fixed wrong trackpad scrolling. --- metal/4ed_metal_render.mm | 12 +++++++++++- opengl/4ed_opengl_render.cpp | 3 +-- platform_mac/mac_4ed.mm | 6 ++++-- 3 files changed, 16 insertions(+), 5 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index fc789cb9..ad902b27 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -310,13 +310,23 @@ metal__make_buffer(u32 size, id device){ #endif // HACK(yuval): This is the best way I found to force valid width and height without drawing on the next draw cycle (1 frame delay). - CGSize drawable_size = [view drawableSize]; i32 width = (i32)Min(_target->width, drawable_size.width); i32 height = (i32)Min(_target->height, drawable_size.height); Font_Set *font_set = (Font_Set*)_target->font_set; + // TODO(yuval): Free any textures in the target's texture free list +#if 0 + for (Render_Free_Texture *free_texture = _target->free_texture_first; + free_texture; + free_texture = free_texture->next){ + /*sll_queue_push(texture_slots.first_free_slot, texture_slots.last_free_slot, free_texture)*/ + } + _target->free_texture_first = 0; + _taget->free_texture_last = 0; +#endif + // NOTE(yuval): Create the command buffer id command_buffer = [command_queue commandBuffer]; command_buffer.label = @"4coder Metal Render Command"; diff --git a/opengl/4ed_opengl_render.cpp b/opengl/4ed_opengl_render.cpp index 9daddb2d..0d1ad918 100644 --- a/opengl/4ed_opengl_render.cpp +++ b/opengl/4ed_opengl_render.cpp @@ -285,12 +285,11 @@ gl_render(Render_Target *t){ t->free_texture_first = 0; t->free_texture_last = 0; - u64 begin_draw = system_now_time(); for (Render_Group *group = t->group_first; group != 0; group = group->next){ Rect_i32 box = Ri32(group->clip_box); - + Rect_i32 scissor_box = { box.x0, height - box.y1, box.x1 - box.x0, box.y1 - box.y0, }; diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 09dcc170..3239cca2 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -952,9 +952,11 @@ mac_toggle_fullscreen(void){ float dx = event.scrollingDeltaX; float dy = event.scrollingDeltaY; - i8 scroll_speed = 100; + i8 scroll_speed = 0; if (dy > 0){ - scroll_speed *= -1; + scroll_speed = -100; + } else if (dy < 0){ + scroll_speed = 100; } mac_vars.input_chunk.trans.mouse_wheel = scroll_speed; From b255da9d0036aa7d88804bb048a30ccf461b028e Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 19 Jan 2020 05:30:04 +0200 Subject: [PATCH 099/128] Fixed path length sent to proc_pidpath because it seems to expect a maximum path length which was previously exceeded. Opening 4coder now works from anywhere. --- platform_mac/mac_4ed.mm | 8 ++++---- platform_mac/mac_4ed_functions.mm | 5 +++-- 2 files changed, 7 insertions(+), 6 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 3239cca2..6275f6d9 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -952,13 +952,13 @@ mac_toggle_fullscreen(void){ float dx = event.scrollingDeltaX; float dy = event.scrollingDeltaY; - i8 scroll_speed = 0; + i8 wheel_delta = 0; if (dy > 0){ - scroll_speed = -100; + wheel_delta = -100; } else if (dy < 0){ - scroll_speed = 100; + wheel_delta = 100; } - mac_vars.input_chunk.trans.mouse_wheel = scroll_speed; + mac_vars.input_chunk.trans.mouse_wheel = wheel_delta; system_signal_step(0); } diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 85a6c0f4..dbfc11b0 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -29,12 +29,12 @@ system_get_path_sig(){ { local_persist b32 has_stashed_4ed_path = false; if (!has_stashed_4ed_path){ - local_const i32 binary_path_capacity = KB(32); + local_const u32 binary_path_capacity = PATH_MAX; u8 *memory = (u8*)system_memory_allocate(binary_path_capacity, file_name_line_number_lit_u8); pid_t pid = getpid(); i32 size = proc_pidpath(pid, memory, binary_path_capacity); - Assert(size <= binary_path_capacity - 1); + Assert(size < binary_path_capacity); mac_vars.binary_path = SCu8(memory, size); mac_vars.binary_path = string_remove_last_folder(mac_vars.binary_path); @@ -742,6 +742,7 @@ function void* mac_memory_allocate_extended(void *base, u64 size, String_Const_u8 location){ u64 adjusted_size = size + ALLOCATION_SIZE_ADJUSTMENT; void *memory = mmap(base, adjusted_size, PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, -1, 0); + Assert(memory != MAP_FAILED); Memory_Annotation_Tracker_Node *node = (Memory_Annotation_Tracker_Node*)memory; From 354b4fe6dc0d0867800a44606c5e1aba79873ced Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 19 Jan 2020 05:47:01 +0200 Subject: [PATCH 100/128] All mutexes are now refrence counted. This solves a lot of the crashes caused by deadlocks in situations where the same thread locks its own mutex multiple times before unlocking it. --- platform_mac/mac_4ed.mm | 14 ++++++++++++-- platform_mac/mac_4ed_functions.mm | 6 +++--- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 6275f6d9..2033dc50 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -67,6 +67,7 @@ #include // NOTE(yuval): Used for mmap, munmap, mprotect #include // NOTE(yuval): Used for stat #include // NOTE(yuval): Used for struct stat, pid_t +#include // NOTE(yuval): Used for PATH_MAX #include // NOTE(yuval): Used for free @@ -297,6 +298,15 @@ mac_to_object(Plat_Handle handle){ //////////////////////////////// +function void +mac_init_recursive_mutex(pthread_mutex_t *mutex){ + pthread_mutexattr_t attr; + pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); + pthread_mutex_init(mutex, &attr); +} + +//////////////////////////////// + function void mac_error_box(char *msg, b32 shutdown = true){ NSAlert *alert = [[[NSAlert alloc] init] autorelease]; @@ -1097,7 +1107,7 @@ main(int arg_count, char **args){ FCoder_App_Delegate *app_delegate = [[FCoder_App_Delegate alloc] init]; [NSApp setDelegate:app_delegate]; - pthread_mutex_init(&memory_tracker_mutex, 0); + mac_init_recursive_mutex(&memory_tracker_mutex); // NOTE(yuval): Context setup Thread_Context _tctx = {}; @@ -1124,7 +1134,7 @@ main(int arg_count, char **args){ dll_init_sentinel(&mac_vars.free_mac_objects); dll_init_sentinel(&mac_vars.timer_objects); - pthread_mutex_init(&mac_vars.thread_launch_mutex, 0); + mac_init_recursive_mutex(&mac_vars.thread_launch_mutex); pthread_cond_init(&mac_vars.thread_launch_cv, 0); // NOTE(yuval): Screen scale factor calculation diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index dbfc11b0..9a211136 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -638,7 +638,7 @@ system_thread_get_id_sig(){ function system_mutex_make_sig(){ Mac_Object *object = mac_alloc_object(MacObjectKind_Mutex); - pthread_mutex_init(&object->mutex, 0); + mac_init_recursive_mutex(&object->mutex); System_Mutex result = mac_to_plat_handle(object); return(result); @@ -846,8 +846,8 @@ system_memory_annotation_sig(){ node != 0; node = node->next){ // TODO(yuval): Fix the API so that annotations would not mess with the system memory. - // Memory_Annotation_Node *r_node = push_array(arena, Memory_Annotation_Node, 1); - Memory_Annotation_Node *r_node = (Memory_Annotation_Node*)malloc(sizeof(Memory_Annotation_Node)); + Memory_Annotation_Node *r_node = push_array(arena, Memory_Annotation_Node, 1); + //Memory_Annotation_Node *r_node = (Memory_Annotation_Node*)malloc(sizeof(Memory_Annotation_Node)); sll_queue_push(result.first, result.last, r_node); result.count += 1; From eea989aa731ce22c7f068a430714aebaeea1bffe Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 19 Jan 2020 05:48:28 +0200 Subject: [PATCH 101/128] Removed the todo comment regrading fixing the mutex issue. --- platform_mac/mac_4ed_functions.mm | 2 -- 1 file changed, 2 deletions(-) diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 9a211136..a0ab70ea 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -845,9 +845,7 @@ system_memory_annotation_sig(){ for (Memory_Annotation_Tracker_Node *node = memory_tracker.first; node != 0; node = node->next){ - // TODO(yuval): Fix the API so that annotations would not mess with the system memory. Memory_Annotation_Node *r_node = push_array(arena, Memory_Annotation_Node, 1); - //Memory_Annotation_Node *r_node = (Memory_Annotation_Node*)malloc(sizeof(Memory_Annotation_Node)); sll_queue_push(result.first, result.last, r_node); result.count += 1; From a6fde84a3ca43dc7ff2ad566f874872361e794d4 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 19 Jan 2020 18:17:57 +0200 Subject: [PATCH 102/128] Improved the Metal renderer's texture handling system to handle texture freeing. --- metal/4ed_metal_render.mm | 108 +++++++++++++++++++------------------- 1 file changed, 54 insertions(+), 54 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index ad902b27..aefe7760 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -20,14 +20,6 @@ struct Metal_Buffer{ typedef id Metal_Texture; -global_const u32 metal__texture_slots_per_bucket = 256; - -// NOTE(yuval): This a bucket of ACTUAL texture slots. -struct Metal_Texture_Slot_Bucket{ - Metal_Texture_Slot_Bucket *next; - Metal_Texture textures[metal__texture_slots_per_bucket]; -}; - // NOTE(yuval): This is a locator used to describe where a specific slot is located. union Metal_Texture_Slot_Locator{ u32 packed; @@ -38,21 +30,31 @@ union Metal_Texture_Slot_Locator{ }; }; -// NOTE(yuval): This is a node containing the locator inside the free slot list. -// This is a separate struct from the Texture_Slot_Locator because the locator's size has to be exactly 32 bits (to support returning the packed slot from get_texture_of_dim). -struct Metal_Texture_Slot_Locator_Node{ - Metal_Texture_Slot_Locator_Node *next; +// NOTE(yuval): This is the ACTUAL texture slot. Each slot contains the texture handle, the slot locator, and a pointer to the next slot in the free list (in case the slot if not occupied). +struct Metal_Texture_Slot{ + // NOTE(yuval): This is a pointer to the next texture in the free texture slots list + Metal_Texture_Slot *next; + + Metal_Texture texture; Metal_Texture_Slot_Locator locator; }; -// NOTE(yuval): This a struct contaning all texture slot buckets and the texture slot free list (a list of free texture slots described by their locators). +global_const u32 metal__texture_slots_per_bucket = 256; + +// NOTE(yuval): This a bucket of ACTUAL texture slots. +struct Metal_Texture_Slot_Bucket{ + Metal_Texture_Slot_Bucket *next; + Metal_Texture_Slot slots[metal__texture_slots_per_bucket]; +}; + +// NOTE(yuval): This a struct contaning all texture slot buckets and a list of the currently free slots. struct Metal_Texture_Slot_List{ Metal_Texture_Slot_Bucket *first_bucket; Metal_Texture_Slot_Bucket *last_bucket; u16 bucket_count; - Metal_Texture_Slot_Locator_Node *first_free_slot; - Metal_Texture_Slot_Locator_Node *last_free_slot; + Metal_Texture_Slot *first_free_slot; + Metal_Texture_Slot *last_free_slot; }; global_const u32 metal__invalid_texture_slot_locator = (u32)-1; @@ -67,8 +69,8 @@ global_const u32 metal__invalid_texture_slot_locator = (u32)-1; - (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind; - (b32)fill_texture:(u32)texture kind:(Texture_Kind)kind pos:(Vec3_i32)p dim:(Vec3_i32)dim data:(void*)data; - (void)bind_texture:(u32)handle encoder:(id)render_encoder; -- (Metal_Texture*)get_texture_slot_at_locator:(Metal_Texture_Slot_Locator)locator; -- (Metal_Texture*)get_texture_slot_at_handle:(u32)handle; +- (Metal_Texture_Slot*)get_texture_slot_at_locator:(Metal_Texture_Slot_Locator)locator; +- (Metal_Texture_Slot*)get_texture_slot_at_handle:(u32)handle; - (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size; - (void)add_reusable_buffer:(Metal_Buffer*)buffer; @@ -316,16 +318,17 @@ metal__make_buffer(u32 size, id device){ Font_Set *font_set = (Font_Set*)_target->font_set; - // TODO(yuval): Free any textures in the target's texture free list -#if 0 + // NOTE(yuval): Free any textures in the target's texture free list for (Render_Free_Texture *free_texture = _target->free_texture_first; free_texture; free_texture = free_texture->next){ - /*sll_queue_push(texture_slots.first_free_slot, texture_slots.last_free_slot, free_texture)*/ + Metal_Texture_Slot *texture_slot = [self get_texture_slot_at_handle:free_texture->tex_id]; + if (texture_slot){ + sll_queue_push(texture_slots.first_free_slot, texture_slots.last_free_slot, texture_slot); + } } _target->free_texture_first = 0; - _taget->free_texture_last = 0; -#endif + _target->free_texture_last = 0; // NOTE(yuval): Create the command buffer id command_buffer = [command_queue commandBuffer]; @@ -478,33 +481,30 @@ metal__make_buffer(u32 size, id device){ // NOTE(yuval): Assert that the next bucket's index can fit in a u16 Assert(texture_slots.bucket_count < ((u16)-1)); - Metal_Texture_Slot_Bucket *bucket = - (Metal_Texture_Slot_Bucket*)system_memory_allocate(sizeof(Metal_Texture_Slot_Bucket) + (sizeof(Metal_Texture_Slot_Locator_Node) * metal__texture_slots_per_bucket), file_name_line_number_lit_u8); + Metal_Texture_Slot_Bucket *bucket = (Metal_Texture_Slot_Bucket*)system_memory_allocate(sizeof(Metal_Texture_Slot_Bucket), file_name_line_number_lit_u8); - Metal_Texture_Slot_Locator_Node *locator_array = (Metal_Texture_Slot_Locator_Node*)(bucket + 1); - for (u32 locator_index = 0; - locator_index < metal__texture_slots_per_bucket; - ++locator_index){ - Metal_Texture_Slot_Locator_Node *node = &locator_array[locator_index]; - node->locator.bucket_index = texture_slots.bucket_count; - node->locator.slot_index = locator_index; + for (u16 slot_index = 0; + slot_index < ArrayCount(bucket->slots); + ++slot_index){ + Metal_Texture_Slot *slot = &bucket->slots[slot_index]; + block_zero_struct(slot); + slot->locator.bucket_index = texture_slots.bucket_count; + slot->locator.slot_index = slot_index; - sll_queue_push(texture_slots.first_free_slot, texture_slots.last_free_slot, node); + sll_queue_push(texture_slots.first_free_slot, texture_slots.last_free_slot, slot); } sll_queue_push(texture_slots.first_bucket, texture_slots.last_bucket, bucket); texture_slots.bucket_count += 1; } - Assert(texture_slots.first_free_slot); - // NOTE(yuval): Get the first free texture slot's locator and remove it from the free list - Metal_Texture_Slot_Locator locator = texture_slots.first_free_slot->locator; - sll_queue_pop(texture_slots.first_free_slot, texture_slots.last_free_slot); - - Metal_Texture *texture_slot = - [self get_texture_slot_at_locator:locator]; - if (texture_slot){ - // NOTE(yuval): Create a texture descriptor + // NOTE(yuval): Get the first free texture slot and remove it from the free list (a slot is guarenteed to exist because we assert that above). + if (texture_slots.first_free_slot){ + Metal_Texture_Slot *texture_slot = texture_slots.first_free_slot; + sll_queue_pop(texture_slots.first_free_slot, texture_slots.last_free_slot); + texture_slot->next = 0; + + // NOTE(yuval): Create a texture descriptor. MTLTextureDescriptor *texture_descriptor = [[MTLTextureDescriptor alloc] init]; texture_descriptor.textureType = MTLTextureType2DArray; texture_descriptor.pixelFormat = MTLPixelFormatR8Unorm; @@ -512,11 +512,11 @@ metal__make_buffer(u32 size, id device){ texture_descriptor.height = dim.y; texture_descriptor.depth = dim.z; - // NOTE(yuval): Create the texture from the device using the descriptor and add it to the textures array + // NOTE(yuval): Create the texture from the device using the descriptor and add it to the textures array. Metal_Texture texture = [device newTextureWithDescriptor:texture_descriptor]; - *texture_slot = texture; + texture_slot->texture = texture; - handle = locator.packed; + handle = texture_slot->locator.packed; } return handle; @@ -526,9 +526,9 @@ metal__make_buffer(u32 size, id device){ b32 result = false; if (data){ - Metal_Texture *texture_slot = [self get_texture_slot_at_handle:handle]; + Metal_Texture_Slot *texture_slot = [self get_texture_slot_at_handle:handle]; if (texture_slot){ - Metal_Texture texture = *texture_slot; + Metal_Texture texture = texture_slot->texture; if (texture != 0){ MTLRegion replace_region = { @@ -551,9 +551,9 @@ metal__make_buffer(u32 size, id device){ } - (void)bind_texture:(u32)handle encoder:(id)render_encoder{ - Metal_Texture *texture_slot = [self get_texture_slot_at_handle:handle]; + Metal_Texture_Slot *texture_slot = [self get_texture_slot_at_handle:handle]; if (texture_slot){ - Metal_Texture texture = *texture_slot; + Metal_Texture texture = texture_slot->texture; if (texture != 0){ [render_encoder setFragmentTexture:texture atIndex:0]; @@ -561,8 +561,8 @@ metal__make_buffer(u32 size, id device){ } } -- (Metal_Texture*)get_texture_slot_at_locator:(Metal_Texture_Slot_Locator)locator{ - Metal_Texture *result = 0; +- (Metal_Texture_Slot*)get_texture_slot_at_locator:(Metal_Texture_Slot_Locator)locator{ + Metal_Texture_Slot *result = 0; if (locator.packed != metal__invalid_texture_slot_locator){ Metal_Texture_Slot_Bucket *bucket = texture_slots.first_bucket; @@ -571,19 +571,19 @@ metal__make_buffer(u32 size, id device){ ++bucket_index, bucket = bucket->next); if (bucket && (locator.slot_index < metal__texture_slots_per_bucket)){ - result = &bucket->textures[locator.slot_index]; + result = &bucket->slots[locator.slot_index]; } } return(result); } -- (Metal_Texture*)get_texture_slot_at_handle:(u32)handle{ +- (Metal_Texture_Slot*)get_texture_slot_at_handle:(u32)handle{ Metal_Texture_Slot_Locator locator; locator.packed = handle; - Metal_Texture *texture_slot = [self get_texture_slot_at_locator:locator]; - return(texture_slot); + Metal_Texture_Slot *result = [self get_texture_slot_at_locator:locator]; + return(result); } - (Metal_Buffer*)get_reusable_buffer_with_size:(NSUInteger)size{ From 3f83e67a89b23da038668b94ebd87afc5a63af44 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Sun, 19 Jan 2020 20:11:39 +0200 Subject: [PATCH 103/128] Changed the render target from a property to a regular field, also changed the instance variable names to use Apple's conventions. --- metal/4ed_metal_render.mm | 92 +++++++++++++++++++-------------------- 1 file changed, 46 insertions(+), 46 deletions(-) diff --git a/metal/4ed_metal_render.mm b/metal/4ed_metal_render.mm index aefe7760..ec9c2643 100644 --- a/metal/4ed_metal_render.mm +++ b/metal/4ed_metal_render.mm @@ -62,8 +62,6 @@ global_const u32 metal__invalid_texture_slot_locator = (u32)-1; //////////////////////////////// @interface Metal_Renderer : NSObject -@property (nonatomic) Render_Target *target; - - (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtkView target:(Render_Target*)target; - (u32)get_texture_of_dim:(Vec3_i32)dim kind:(Texture_Kind)kind; @@ -192,15 +190,17 @@ metal__make_buffer(u32 size, id device){ //////////////////////////////// @implementation Metal_Renderer{ - id device; - id pipeline_state; - id command_queue; - id capture_scope; + Render_Target *_target; - Node buffer_cache; - u64 last_buffer_cache_purge_time; + id _device; + id _pipeline_state; + id _command_queue; + id _capture_scope; - Metal_Texture_Slot_List texture_slots; + Node _buffer_cache; + u64 _last_buffer_cache_purge_time; + + Metal_Texture_Slot_List _texture_slots; } - (nonnull instancetype)initWithMetalKitView:(nonnull MTKView*)mtk_view target:(Render_Target*)target{ @@ -213,7 +213,7 @@ metal__make_buffer(u32 size, id device){ NSError *error = nil; - device = mtk_view.device; + _device = mtk_view.device; // NOTE(yuval): Compile the shaders id vertex_function = nil; @@ -224,7 +224,7 @@ metal__make_buffer(u32 size, id device){ MTLCompileOptions *options = [[MTLCompileOptions alloc] init]; options.fastMathEnabled = YES; - id shader_library = [device newLibraryWithSource:shaders_source_str + id shader_library = [_device newLibraryWithSource:shaders_source_str options:options error:&error]; vertex_function = [shader_library newFunctionWithName:@"vertex_shader"]; fragment_function = [shader_library newFunctionWithName:@"fragment_shader"]; @@ -268,21 +268,21 @@ metal__make_buffer(u32 size, id device){ pipeline_state_descriptor.colorAttachments[0].sourceAlphaBlendFactor = MTLBlendFactorOne; pipeline_state_descriptor.colorAttachments[0].destinationAlphaBlendFactor = MTLBlendFactorOneMinusSourceAlpha; - pipeline_state = [device newRenderPipelineStateWithDescriptor:pipeline_state_descriptor + _pipeline_state = [_device newRenderPipelineStateWithDescriptor:pipeline_state_descriptor error:&error]; } Assert(error == nil); // NOTE(yuval): Create the command queue - command_queue = [device newCommandQueue]; + _command_queue = [_device newCommandQueue]; // NOTE(yuval): Initialize buffer caching - dll_init_sentinel(&buffer_cache); - last_buffer_cache_purge_time = system_now_time(); + dll_init_sentinel(&_buffer_cache); + _last_buffer_cache_purge_time = system_now_time(); // NOTE(yuval): Initialize the texture slot list - block_zero_struct(&texture_slots); + block_zero_struct(&_texture_slots); // NOTE(yuval): Create the fallback texture _target->fallback_texture_id = [self get_texture_of_dim:V3i32(2, 2, 1) @@ -295,9 +295,9 @@ metal__make_buffer(u32 size, id device){ data:white_block]; // NOTE(yuval): Create a capture scope for gpu frame capture - capture_scope = [[MTLCaptureManager sharedCaptureManager] - newCaptureScopeWithDevice:device]; - capture_scope.label = @"4coder Metal Capture Scope"; + _capture_scope = [[MTLCaptureManager sharedCaptureManager] + newCaptureScopeWithDevice:_device]; + _capture_scope.label = @"4coder Metal Capture Scope"; return(self); } @@ -308,7 +308,7 @@ metal__make_buffer(u32 size, id device){ - (void)drawInMTKView:(nonnull MTKView*)view{ #if FRED_INTERNAL - [capture_scope beginScope]; + [_capture_scope beginScope]; #endif // HACK(yuval): This is the best way I found to force valid width and height without drawing on the next draw cycle (1 frame delay). @@ -324,14 +324,14 @@ metal__make_buffer(u32 size, id device){ free_texture = free_texture->next){ Metal_Texture_Slot *texture_slot = [self get_texture_slot_at_handle:free_texture->tex_id]; if (texture_slot){ - sll_queue_push(texture_slots.first_free_slot, texture_slots.last_free_slot, texture_slot); + sll_queue_push(_texture_slots.first_free_slot, _texture_slots.last_free_slot, texture_slot); } } _target->free_texture_first = 0; _target->free_texture_last = 0; // NOTE(yuval): Create the command buffer - id command_buffer = [command_queue commandBuffer]; + id command_buffer = [_command_queue commandBuffer]; command_buffer.label = @"4coder Metal Render Command"; // NOTE(yuval): Obtain the render pass descriptor from the renderer's view @@ -348,7 +348,7 @@ metal__make_buffer(u32 size, id device){ [render_encoder setViewport:(MTLViewport){0.0, 0.0, (double)width, (double)height, 0.0, 1.0}]; // NOTE(yuval): Set the render pipeline to use for drawing - [render_encoder setRenderPipelineState:pipeline_state]; + [render_encoder setRenderPipelineState:_pipeline_state]; // NOTE(yuval): Calculate the projection matrix float left = 0, right = (float)width; @@ -469,7 +469,7 @@ metal__make_buffer(u32 size, id device){ [command_buffer commit]; #if FRED_INTERNAL - [capture_scope endScope]; + [_capture_scope endScope]; #endif } @@ -477,9 +477,9 @@ metal__make_buffer(u32 size, id device){ u32 handle = metal__invalid_texture_slot_locator; // NOTE(yuval): Check for a free texture slot and allocate another slot bucket if no free slot has been found - if (!texture_slots.first_free_slot){ + if (!_texture_slots.first_free_slot){ // NOTE(yuval): Assert that the next bucket's index can fit in a u16 - Assert(texture_slots.bucket_count < ((u16)-1)); + Assert(_texture_slots.bucket_count < ((u16)-1)); Metal_Texture_Slot_Bucket *bucket = (Metal_Texture_Slot_Bucket*)system_memory_allocate(sizeof(Metal_Texture_Slot_Bucket), file_name_line_number_lit_u8); @@ -488,20 +488,20 @@ metal__make_buffer(u32 size, id device){ ++slot_index){ Metal_Texture_Slot *slot = &bucket->slots[slot_index]; block_zero_struct(slot); - slot->locator.bucket_index = texture_slots.bucket_count; + slot->locator.bucket_index = _texture_slots.bucket_count; slot->locator.slot_index = slot_index; - sll_queue_push(texture_slots.first_free_slot, texture_slots.last_free_slot, slot); + sll_queue_push(_texture_slots.first_free_slot, _texture_slots.last_free_slot, slot); } - sll_queue_push(texture_slots.first_bucket, texture_slots.last_bucket, bucket); - texture_slots.bucket_count += 1; + sll_queue_push(_texture_slots.first_bucket, _texture_slots.last_bucket, bucket); + _texture_slots.bucket_count += 1; } // NOTE(yuval): Get the first free texture slot and remove it from the free list (a slot is guarenteed to exist because we assert that above). - if (texture_slots.first_free_slot){ - Metal_Texture_Slot *texture_slot = texture_slots.first_free_slot; - sll_queue_pop(texture_slots.first_free_slot, texture_slots.last_free_slot); + if (_texture_slots.first_free_slot){ + Metal_Texture_Slot *texture_slot = _texture_slots.first_free_slot; + sll_queue_pop(_texture_slots.first_free_slot, _texture_slots.last_free_slot); texture_slot->next = 0; // NOTE(yuval): Create a texture descriptor. @@ -513,7 +513,7 @@ metal__make_buffer(u32 size, id device){ texture_descriptor.depth = dim.z; // NOTE(yuval): Create the texture from the device using the descriptor and add it to the textures array. - Metal_Texture texture = [device newTextureWithDescriptor:texture_descriptor]; + Metal_Texture texture = [_device newTextureWithDescriptor:texture_descriptor]; texture_slot->texture = texture; handle = texture_slot->locator.packed; @@ -565,7 +565,7 @@ metal__make_buffer(u32 size, id device){ Metal_Texture_Slot *result = 0; if (locator.packed != metal__invalid_texture_slot_locator){ - Metal_Texture_Slot_Bucket *bucket = texture_slots.first_bucket; + Metal_Texture_Slot_Bucket *bucket = _texture_slots.first_bucket; for (u16 bucket_index = 0; (bucket_index < locator.bucket_index) && bucket; ++bucket_index, bucket = bucket->next); @@ -592,26 +592,26 @@ metal__make_buffer(u32 size, id device){ u64 now = system_now_time(); // NOTE(yuval): Purge old buffers that haven't been useful for a while - if ((now - last_buffer_cache_purge_time) > 1000000){ - Node prev_buffer_cache = buffer_cache; - dll_init_sentinel(&buffer_cache); + if ((now - _last_buffer_cache_purge_time) > 1000000){ + Node prev_buffer_cache = _buffer_cache; + dll_init_sentinel(&_buffer_cache); for (Node *node = prev_buffer_cache.next; - node != &buffer_cache; + node != &_buffer_cache; node = node->next){ Metal_Buffer *candidate = CastFromMember(Metal_Buffer, node, node); - if (candidate->last_reuse_time > last_buffer_cache_purge_time){ - dll_insert(&buffer_cache, node); + if (candidate->last_reuse_time > _last_buffer_cache_purge_time){ + dll_insert(&_buffer_cache, node); } } - last_buffer_cache_purge_time = now; + _last_buffer_cache_purge_time = now; } // NOTE(yuval): See if we have a buffer we can reuse Metal_Buffer *best_candidate = 0; - for (Node *node = buffer_cache.next; - node != &buffer_cache; + for (Node *node = _buffer_cache.next; + node != &_buffer_cache; node = node->next){ Metal_Buffer *candidate = CastFromMember(Metal_Buffer, node, node); if ((candidate->size >= size) && ((!best_candidate) || (best_candidate->last_reuse_time > candidate->last_reuse_time))){ @@ -627,7 +627,7 @@ metal__make_buffer(u32 size, id device){ result = best_candidate; } else{ // NOTE(yuval): No luck; make a new buffer. - result = metal__make_buffer(size, device); + result = metal__make_buffer(size, _device); } return(result); @@ -636,6 +636,6 @@ metal__make_buffer(u32 size, id device){ - (void)add_reusable_buffer:(Metal_Buffer*)buffer{ // NOTE(yuval): This routine is a modified version of Dear ImGui's MetalContext::enqueueReusableBuffer in imgui_impl_metal.mm - dll_insert(&buffer_cache, &buffer->node); + dll_insert(&_buffer_cache, &buffer->node); } @end From 73da715644a01f3b9a350f27c29025349184d1ca Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 19 Jan 2020 10:30:37 -0800 Subject: [PATCH 104/128] Working on new Mac bindings; binding map written, but config switch not ready yet --- custom/4coder_default_bindings.cpp | 1 + custom/4coder_mac_map.cpp | 159 ++++++++++ custom/generated/command_metadata.h | 458 ++++++++++++++-------------- project.4coder | 20 +- ship_files/config.4coder | 3 +- 5 files changed, 402 insertions(+), 239 deletions(-) create mode 100644 custom/4coder_mac_map.cpp diff --git a/custom/4coder_default_bindings.cpp b/custom/4coder_default_bindings.cpp index fb2f4a03..2dc315cd 100644 --- a/custom/4coder_default_bindings.cpp +++ b/custom/4coder_default_bindings.cpp @@ -12,6 +12,7 @@ // NOTE(allen): Users can declare their own managed IDs here. #include "4coder_default_map.cpp" +#include "4coder_mac_map.cpp" #include "generated/managed_id_metadata.cpp" void diff --git a/custom/4coder_mac_map.cpp b/custom/4coder_mac_map.cpp new file mode 100644 index 00000000..26844ee2 --- /dev/null +++ b/custom/4coder_mac_map.cpp @@ -0,0 +1,159 @@ +/* +4coder_mac_map.cpp - Instantiate mac keyboard bindings. +*/ + +// TOP + +function void +setup_mac_mapping(Mapping *mapping, i64 global_id, i64 file_id, i64 code_id){ + MappingScope(); + SelectMapping(mapping); + + SelectMap(global_id); + BindCore(default_startup, CoreCode_Startup); + BindCore(default_try_exit, CoreCode_TryExit); + Bind(keyboard_macro_start_recording , KeyCode_U, KeyCode_Command); + Bind(keyboard_macro_finish_recording, KeyCode_U, KeyCode_Command, KeyCode_Shift); + Bind(keyboard_macro_replay, KeyCode_U, KeyCode_Control); + Bind(change_active_panel, KeyCode_Comma, KeyCode_Command); + Bind(change_active_panel_backwards, KeyCode_Comma, KeyCode_Command, KeyCode_Shift); + Bind(interactive_new, KeyCode_N, KeyCode_Command); + Bind(interactive_open_or_new, KeyCode_O, KeyCode_Command); + Bind(open_in_other, KeyCode_O, KeyCode_Control); + Bind(interactive_kill_buffer, KeyCode_K, KeyCode_Command); + Bind(interactive_switch_buffer, KeyCode_I, KeyCode_Command); + Bind(project_go_to_root_directory, KeyCode_H, KeyCode_Command); + Bind(save_all_dirty_buffers, KeyCode_S, KeyCode_Command, KeyCode_Shift); + Bind(change_to_build_panel, KeyCode_Period, KeyCode_Control); + Bind(close_build_panel, KeyCode_Comma, KeyCode_Control); + Bind(goto_next_jump, KeyCode_N, KeyCode_Control); + Bind(goto_prev_jump, KeyCode_N, KeyCode_Control, KeyCode_Shift); + Bind(build_in_build_panel, KeyCode_M, KeyCode_Control); + Bind(goto_first_jump, KeyCode_M, KeyCode_Control, KeyCode_Shift); + Bind(toggle_filebar, KeyCode_B, KeyCode_Control); + Bind(execute_any_cli, KeyCode_Z, KeyCode_Control); + Bind(execute_previous_cli, KeyCode_Z, KeyCode_Control, KeyCode_Shift); + Bind(command_lister, KeyCode_X, KeyCode_Control); + Bind(project_command_lister, KeyCode_X, KeyCode_Control, KeyCode_Shift); + Bind(list_all_functions_current_buffer, KeyCode_I, KeyCode_Command, KeyCode_Shift); + Bind(project_fkey_command, KeyCode_F1); + Bind(project_fkey_command, KeyCode_F2); + Bind(project_fkey_command, KeyCode_F3); + Bind(project_fkey_command, KeyCode_F4); + Bind(project_fkey_command, KeyCode_F5); + Bind(project_fkey_command, KeyCode_F6); + Bind(project_fkey_command, KeyCode_F7); + Bind(project_fkey_command, KeyCode_F8); + Bind(project_fkey_command, KeyCode_F9); + Bind(project_fkey_command, KeyCode_F10); + Bind(project_fkey_command, KeyCode_F11); + Bind(project_fkey_command, KeyCode_F12); + Bind(project_fkey_command, KeyCode_F13); + Bind(project_fkey_command, KeyCode_F14); + Bind(project_fkey_command, KeyCode_F15); + Bind(project_fkey_command, KeyCode_F16); + Bind(exit_4coder, KeyCode_F4, KeyCode_Control); + BindMouseWheel(mouse_wheel_scroll); + BindMouseWheel(mouse_wheel_change_face_size, KeyCode_Command); + + SelectMap(file_id); + ParentMap(global_id); + BindTextInput(write_text_input); + BindMouse(click_set_cursor_and_mark, MouseCode_Left); + BindMouseRelease(click_set_cursor, MouseCode_Left); + BindCore(click_set_cursor_and_mark, CoreCode_ClickActivateView); + BindMouseMove(click_set_cursor_if_lbutton); + Bind(delete_char, KeyCode_Delete); + Bind(backspace_char, KeyCode_Backspace); + Bind(move_up, KeyCode_Up); + Bind(move_down, KeyCode_Down); + Bind(move_left, KeyCode_Left); + Bind(move_right, KeyCode_Right); + Bind(seek_end_of_line, KeyCode_End); + Bind(seek_beginning_of_line, KeyCode_Home); + Bind(page_up, KeyCode_PageUp); + Bind(page_down, KeyCode_PageDown); + Bind(goto_beginning_of_file, KeyCode_PageUp, KeyCode_Command); + Bind(goto_end_of_file, KeyCode_PageDown, KeyCode_Command); + Bind(move_up_to_blank_line_end, KeyCode_Up, KeyCode_Command); + Bind(move_down_to_blank_line_end, KeyCode_Down, KeyCode_Command); + Bind(move_left_whitespace_boundary, KeyCode_Left, KeyCode_Command); + Bind(move_right_whitespace_boundary, KeyCode_Right, KeyCode_Command); + Bind(move_line_up, KeyCode_Up, KeyCode_Control); + Bind(move_line_down, KeyCode_Down, KeyCode_Control); + Bind(backspace_alpha_numeric_boundary, KeyCode_Backspace, KeyCode_Command); + Bind(delete_alpha_numeric_boundary, KeyCode_Delete, KeyCode_Command); + Bind(snipe_backward_whitespace_or_token_boundary, KeyCode_Backspace, KeyCode_Control); + Bind(snipe_forward_whitespace_or_token_boundary, KeyCode_Delete, KeyCode_Control); + Bind(set_mark, KeyCode_Space, KeyCode_Command); + Bind(replace_in_range, KeyCode_A, KeyCode_Command); + Bind(copy, KeyCode_C, KeyCode_Command); + Bind(delete_range, KeyCode_D, KeyCode_Command); + Bind(delete_line, KeyCode_D, KeyCode_Command, KeyCode_Shift); + Bind(center_view, KeyCode_E, KeyCode_Command); + Bind(left_adjust_view, KeyCode_E, KeyCode_Command, KeyCode_Shift); + Bind(search, KeyCode_F, KeyCode_Command); + Bind(list_all_locations, KeyCode_F, KeyCode_Command, KeyCode_Shift); + Bind(list_all_substring_locations_case_insensitive, KeyCode_F, KeyCode_Control); + Bind(goto_line, KeyCode_G, KeyCode_Command); + Bind(list_all_locations_of_selection, KeyCode_G, KeyCode_Command, KeyCode_Shift); + Bind(snippet_lister, KeyCode_J, KeyCode_Command); + Bind(kill_buffer, KeyCode_K, KeyCode_Command, KeyCode_Shift); + Bind(duplicate_line, KeyCode_L, KeyCode_Command); + Bind(cursor_mark_swap, KeyCode_M, KeyCode_Command); + Bind(reopen, KeyCode_O, KeyCode_Command, KeyCode_Shift); + Bind(query_replace, KeyCode_Q, KeyCode_Command); + Bind(query_replace_identifier, KeyCode_Q, KeyCode_Command, KeyCode_Shift); + Bind(query_replace_selection, KeyCode_Q, KeyCode_Control); + Bind(reverse_search, KeyCode_R, KeyCode_Command); + Bind(save, KeyCode_S, KeyCode_Command); + Bind(save_all_dirty_buffers, KeyCode_S, KeyCode_Command, KeyCode_Shift); + Bind(search_identifier, KeyCode_T, KeyCode_Command); + Bind(list_all_locations_of_identifier, KeyCode_T, KeyCode_Command, KeyCode_Shift); + Bind(paste_and_indent, KeyCode_V, KeyCode_Command); + Bind(paste_next_and_indent, KeyCode_V, KeyCode_Command, KeyCode_Shift); + Bind(cut, KeyCode_X, KeyCode_Command); + Bind(redo, KeyCode_Y, KeyCode_Command); + Bind(undo, KeyCode_Z, KeyCode_Command); + Bind(view_buffer_other_panel, KeyCode_1, KeyCode_Command); + Bind(swap_panels, KeyCode_2, KeyCode_Command); + Bind(if_read_only_goto_position, KeyCode_Return); + Bind(if_read_only_goto_position_same_panel, KeyCode_Return, KeyCode_Shift); + Bind(view_jump_list_with_lister, KeyCode_Period, KeyCode_Command, KeyCode_Shift); + + SelectMap(code_id); + ParentMap(file_id); + BindTextInput(write_text_and_auto_indent); + Bind(move_left_alpha_numeric_boundary, KeyCode_Left, KeyCode_Command); + Bind(move_right_alpha_numeric_boundary, KeyCode_Right, KeyCode_Command); + Bind(move_left_alpha_numeric_or_camel_boundary, KeyCode_Left, KeyCode_Control); + Bind(move_right_alpha_numeric_or_camel_boundary, KeyCode_Right, KeyCode_Control); + Bind(comment_line_toggle, KeyCode_Semicolon, KeyCode_Command); + Bind(word_complete, KeyCode_Tab); + Bind(auto_indent_range, KeyCode_Tab, KeyCode_Command); + Bind(auto_indent_line_at_cursor, KeyCode_Tab, KeyCode_Shift); + Bind(word_complete_drop_down, KeyCode_Tab, KeyCode_Shift, KeyCode_Command); + Bind(write_block, KeyCode_R, KeyCode_Control); + Bind(write_todo, KeyCode_T, KeyCode_Control); + Bind(write_note, KeyCode_Y, KeyCode_Control); + Bind(list_all_locations_of_type_definition, KeyCode_D, KeyCode_Control); + Bind(list_all_locations_of_type_definition_of_identifier, KeyCode_T, KeyCode_Control, KeyCode_Shift); + Bind(open_long_braces, KeyCode_LeftBracket, KeyCode_Command); + Bind(open_long_braces_semicolon, KeyCode_LeftBracket, KeyCode_Command, KeyCode_Shift); + Bind(open_long_braces_break, KeyCode_RightBracket, KeyCode_Command, KeyCode_Shift); + Bind(select_surrounding_scope, KeyCode_LeftBracket, KeyCode_Control); + Bind(select_surrounding_scope_maximal, KeyCode_LeftBracket, KeyCode_Control, KeyCode_Shift); + Bind(select_prev_scope_absolute, KeyCode_RightBracket, KeyCode_Control); + Bind(select_prev_top_most_scope, KeyCode_RightBracket, KeyCode_Control, KeyCode_Shift); + Bind(select_next_scope_absolute, KeyCode_Quote, KeyCode_Control); + Bind(select_next_scope_after_current, KeyCode_Quote, KeyCode_Control, KeyCode_Shift); + Bind(place_in_scope, KeyCode_ForwardSlash, KeyCode_Control); + Bind(delete_current_scope, KeyCode_Minus, KeyCode_Control); + Bind(if0_off, KeyCode_I, KeyCode_Control); + Bind(open_file_in_quotes, KeyCode_1, KeyCode_Control); + Bind(open_matching_file_cpp, KeyCode_2, KeyCode_Control); + Bind(write_zero_struct, KeyCode_0, KeyCode_Command); +} + +// BOTTOM + diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 1c461ef6..4b514631 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, 407 }, -{ 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, 417 }, -{ 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, 398 }, -{ 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, 611 }, -{ 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, 576 }, -{ 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, 619 }, -{ 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, 753 }, -{ 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, 682 }, -{ 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, 1793 }, -{ 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, 51 }, -{ 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, 1219 }, -{ 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, 1391 }, -{ 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, 1377 }, -{ 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, 738 }, -{ 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, 525 }, -{ 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, 542 }, -{ 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, 348 }, -{ 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, 375 }, -{ 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, 746 }, -{ 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, 464 }, -{ 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, 494 }, -{ 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, 481 }, -{ 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, 511 }, -{ 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, 649 }, -{ 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, 635 }, -{ 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, 564 }, -{ 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, 581 }, -{ 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, 671 }, -{ 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, 520 }, -{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 657 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 707 }, -{ 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, 612 }, -{ 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, 510 }, -{ 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, 54 }, -{ 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, 77 }, -{ 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, 41 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1537 }, -{ 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, 296 }, -{ 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, 302 }, -{ 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, 1331 }, -{ 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, 693 }, -{ 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, 336 }, -{ 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, 348 }, -{ 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, 354 }, -{ 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, 407 }, -{ 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, 431 }, -{ 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, 419 }, -{ 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, 437 }, -{ 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, 514 }, -{ 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, 528 }, -{ 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, 486 }, -{ 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, 471 }, -{ 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, 500 }, -{ 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, 1371 }, -{ 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, 1365 }, -{ 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, 445 }, -{ 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, 507 }, -{ 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, 521 }, -{ 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, 479 }, -{ 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, 463 }, -{ 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, 493 }, -{ 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, 330 }, -{ 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, 342 }, -{ 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, 401 }, -{ 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, 425 }, -{ 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, 413 }, -{ 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, 1456 }, -{ 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, 1787 }, -{ 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, 1488 }, -{ 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, 372 }, -{ 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, 364 }, -{ 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, 109 }, -{ 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, 70 }, -{ 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, 116 }, -{ 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, 1147 }, -{ 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, 1168 }, -{ 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, 1184 }, -{ 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, 1626 }, -{ 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, 1711 }, -{ 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, 1296 }, -{ 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, 1555 }, -{ 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, 1057 }, -{ 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, 1048 }, -{ 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, 1039 }, -{ 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, 980 }, -{ 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, 992 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1545 }, -{ 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, 1263 }, -{ 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, 974 }, -{ 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, 986 }, -{ 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, 537 }, -{ 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, 642 }, -{ 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, 628 }, -{ 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, 1513 }, -{ 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, 777 }, -{ 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, 563 }, -{ 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, 550 }, -{ 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, 656 }, -{ 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, 665 }, -{ 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, 719 }, -{ 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, 725 }, -{ 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, 710 }, -{ 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, 1170 }, -{ 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, 1613 }, -{ 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, 1640 }, -{ 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, 1501 }, -{ 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 a space.", 16, "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, 427 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 407 }, +{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 417 }, +{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 398 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 154 }, +{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 611 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 128 }, +{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 186 }, +{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 576 }, +{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 480 }, +{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 243 }, +{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 842 }, +{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 180 }, +{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 619 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 190 }, +{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 753 }, +{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 149 }, +{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 19 }, +{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 175 }, +{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 28 }, +{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 682 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1793 }, +{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 7 }, +{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 23 }, +{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 51 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 162 }, +{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1219 }, +{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1391 }, +{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 134 }, +{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1377 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 7 }, +{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 738 }, +{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 2184 }, +{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 525 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 542 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 348 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 375 }, +{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 746 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 464 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 494 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 481 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 511 }, +{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 649 }, +{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 635 }, +{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 564 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 581 }, +{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 671 }, +{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 520 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 657 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 707 }, +{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 612 }, +{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 510 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_code_index_listers.cpp", 65, 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 54 }, +{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 77 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 41 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1537 }, +{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 296 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 302 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1331 }, +{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 249 }, +{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 693 }, +{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 265 }, +{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 336 }, +{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 348 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 354 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 407 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 431 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 419 }, +{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 437 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 514 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 528 }, +{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 486 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 471 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 500 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1371 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1365 }, +{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 445 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 507 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 521 }, +{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 479 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 463 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 493 }, +{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 330 }, +{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 342 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 401 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 425 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 413 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1456 }, +{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1787 }, +{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1488 }, +{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 310 }, +{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 372 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 364 }, +{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 109 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 70 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 116 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 106 }, +{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 226 }, +{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 219 }, +{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 212 }, +{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "/Users/allenwebster/4ed/code/custom/4coder_profile_inspect.cpp", 62, 886 }, +{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1147 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1168 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1184 }, +{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1626 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1711 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1296 }, +{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1555 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1057 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1048 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1039 }, +{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 980 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 992 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1545 }, +{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1263 }, +{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 974 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 986 }, +{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 537 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 27 }, +{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 99 }, +{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 115 }, +{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 427 }, +{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 1230 }, +{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 642 }, +{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 628 }, +{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "/Users/allenwebster/4ed/code/custom/4coder_log_parser.cpp", 57, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 187 }, +{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 403 }, +{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1513 }, +{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 777 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 563 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 550 }, +{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 656 }, +{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 665 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 439 }, +{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 433 }, +{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 719 }, +{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 725 }, +{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 445 }, +{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 710 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "/Users/allenwebster/4ed/code/custom/4coder_code_index.cpp", 57, 1170 }, +{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 20 }, +{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 34 }, +{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 137 }, +{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1613 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1640 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1501 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_lister.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 392 }, +{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 639 }, +{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 88 }, +{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 427 }, +{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 76 }, +{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 73 }, +{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 100 }, }; static i32 fcoder_metacmd_ID_allow_mouse = 0; static i32 fcoder_metacmd_ID_auto_indent_line_at_cursor = 1; diff --git a/project.4coder b/project.4coder index a61663bb..c5484349 100644 --- a/project.4coder +++ b/project.4coder @@ -26,21 +26,23 @@ load_paths = { build_x64_win32 = "echo build: x64 & bin\\build.bat"; build_x86_win32 = "echo build: x86 & bin\\build.bat /DDEV_BUILD_X86"; -build_x64_unix = "echo build: x64 & bin/build.sh"; -build_x86_unix = "echo build: x86 & bin/build.sh -DDEV_BUILD_X86"; +build_x64_linux = "echo build: x64 & bin/build.sh"; +build_x86_linux = "echo build: x86 & bin/build.sh -DDEV_BUILD_X86"; +build_x64_mac = "echo build: x64 & bin/build-mac.sh"; +build_x86_mac = "echo build: x86 & bin/build-mac.sh -DDEV_BUILD_X86"; command_list = { { .name = "build x64", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cmd = { {build_x64_win32, .os = "win" }, - {build_x64_unix , .os = "linux"}, - {build_x64_unix , .os = "mac" }, }, }, + {build_x64_linux, .os = "linux"}, + {build_x64_mac , .os = "mac" }, }, }, { .name = "build x86", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, .cmd = { {build_x86_win32, .os = "win" }, - {build_x86_unix , .os = "linux"}, - {build_x86_unix , .os = "mac" }, }, }, + {build_x86_linux, .os = "linux"}, + {build_x86_mac , .os = "mac" }, }, }, { .name = "package", .out = "*compilation*", .footer_panel = false, .save_dirty_files = true, @@ -50,11 +52,13 @@ command_list = { { .name = "run one time", .out = "*run*", .footer_panel = false, .save_dirty_files = false, - .cmd = { { "pushd ..\\build & one_time", .os = "win" }, }, }, + .cmd = { { "pushd ..\\build & one_time", .os = "win" }, + { "pushd ../build & one_time", .os = "mac" }, }, }, { .name = "build custom api docs", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, - .cmd = { { "custom\\bin\\build_one_time docs\\4ed_doc_custom_api_main.cpp ..\\build", .os = "win" }, }, }, + .cmd = { { "custom\\bin\\build_one_time docs\\4ed_doc_custom_api_main.cpp ..\\build", .os = "win" }, + { "custom/bin/build_one_time.sh docs/4ed_doc_custom_api_main.cpp ../build", .os = "mac" }, }, }, { .name = "build C++ lexer generator", .out = "*compilation*", .footer_panel = true, .save_dirty_files = true, diff --git a/ship_files/config.4coder b/ship_files/config.4coder index b59a01cc..a2846415 100644 --- a/ship_files/config.4coder +++ b/ship_files/config.4coder @@ -3,8 +3,7 @@ // "choose" - Ask 4coder to choose based on platform. // "default" - Use the default keybindings 4coder has always had. // "mac-default" - Use keybindings similar to those found in other Mac applications. -// - If you use the custom layer to make a named mapping you can use that here too. -mapping = ""; +mapping = "choose"; // MODE // "4coder" - The default 4coder mode that has been around since the beginning of time (2015) From 7817f8412d251d4a3abb72d4b706b60977a8a93b Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 19 Jan 2020 12:00:58 -0800 Subject: [PATCH 105/128] Trying to debug weird allocator crash bug; switching to windows --- custom/4coder_base_types.h | 3 +++ platform_mac/mac_4ed_functions.mm | 6 +++++- 2 files changed, 8 insertions(+), 1 deletion(-) diff --git a/custom/4coder_base_types.h b/custom/4coder_base_types.h index 715ccbf9..31f29195 100644 --- a/custom/4coder_base_types.h +++ b/custom/4coder_base_types.h @@ -531,6 +531,9 @@ union SNode{ #define zdll_remove_front(f,l) zdll_remove_back_NP_((l),(f),prev,next) #define zdll_remove(f,l,n) zdll_remove_NP_((f),(l),(n),next,prev) +#define zdll_assert_good(T,f) Stmnt( if (f != 0){ Assert(f->prev == 0); \ +for(T *p_ = f; p_ != 0; p_ = p_->next){ Assert(p_->prev == 0 || p_->prev->next == p_); Assert(p_->next == 0 || p_->next->prev == p_); } } ) + //////////////////////////////// union Vec2_i8{ diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index a0ab70ea..98ce3121 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -748,8 +748,10 @@ mac_memory_allocate_extended(void *base, u64 size, String_Const_u8 location){ pthread_mutex_lock(&memory_tracker_mutex); { + zdll_assert_good(Memory_Annotation_Tracker_Node, memory_tracker.first); zdll_push_back(memory_tracker.first, memory_tracker.last, node); memory_tracker.count += 1; + zdll_assert_good(Memory_Annotation_Tracker_Node, memory_tracker.first); } pthread_mutex_unlock(&memory_tracker_mutex); @@ -767,8 +769,10 @@ mac_memory_free_extended(void *ptr){ pthread_mutex_lock(&memory_tracker_mutex); { + zdll_assert_good(Memory_Annotation_Tracker_Node, memory_tracker.first); zdll_remove(memory_tracker.first, memory_tracker.last, node); memory_tracker.count -= 1; + zdll_assert_good(Memory_Annotation_Tracker_Node, memory_tracker.first); } pthread_mutex_unlock(&memory_tracker_mutex); @@ -923,4 +927,4 @@ font_make_face_sig(){ return(result); } -//////////////////////////////// \ No newline at end of file +//////////////////////////////// From 33aa987589cc28f079a8f539299ad6f91fa45582 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 19 Jan 2020 12:16:54 -0800 Subject: [PATCH 106/128] Fixed the mutex problem --- platform_mac/mac_4ed.mm | 3 ++- platform_mac/mac_4ed_functions.mm | 4 ---- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 2033dc50..87e1f0d0 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -301,6 +301,7 @@ mac_to_object(Plat_Handle handle){ function void mac_init_recursive_mutex(pthread_mutex_t *mutex){ pthread_mutexattr_t attr; + pthread_mutexattr_init(&attr); pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE); pthread_mutex_init(mutex, &attr); } @@ -1370,4 +1371,4 @@ main(int arg_count, char **args){ // NOTE(yuval): Start the app's run loop [NSApp run]; } -} \ No newline at end of file +} diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 98ce3121..93b19ce6 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -748,10 +748,8 @@ mac_memory_allocate_extended(void *base, u64 size, String_Const_u8 location){ pthread_mutex_lock(&memory_tracker_mutex); { - zdll_assert_good(Memory_Annotation_Tracker_Node, memory_tracker.first); zdll_push_back(memory_tracker.first, memory_tracker.last, node); memory_tracker.count += 1; - zdll_assert_good(Memory_Annotation_Tracker_Node, memory_tracker.first); } pthread_mutex_unlock(&memory_tracker_mutex); @@ -769,10 +767,8 @@ mac_memory_free_extended(void *ptr){ pthread_mutex_lock(&memory_tracker_mutex); { - zdll_assert_good(Memory_Annotation_Tracker_Node, memory_tracker.first); zdll_remove(memory_tracker.first, memory_tracker.last, node); memory_tracker.count -= 1; - zdll_assert_good(Memory_Annotation_Tracker_Node, memory_tracker.first); } pthread_mutex_unlock(&memory_tracker_mutex); From bd3417e83643744ab8f590c031d3517110b99bc8 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 19 Jan 2020 13:30:28 -0800 Subject: [PATCH 107/128] Bindings favorable to mac keyboard now working --- custom/4coder_config.cpp | 3221 ++++++++++++++-------------- custom/4coder_config.h | 7 +- custom/4coder_default_bindings.cpp | 24 + custom/4coder_default_framework.h | 5 + custom/4coder_mac_map.cpp | 8 +- ship_files/config.4coder | 5 +- 6 files changed, 1643 insertions(+), 1627 deletions(-) diff --git a/custom/4coder_config.cpp b/custom/4coder_config.cpp index 7cff6e52..3b5f429d 100644 --- a/custom/4coder_config.cpp +++ b/custom/4coder_config.cpp @@ -1,1615 +1,1606 @@ -/* -4coder_config.cpp - Parsing *.4coder files. -*/ - -// TOP - -function String_Const_u8_Array -parse_extension_line_to_extension_list(Application_Links *app, - Arena *arena, String_Const_u8 str){ - ProfileScope(app, "parse extension line to extension list"); - i32 count = 0; - for (u64 i = 0; i < str.size; i += 1){ - if (str.str[i] == '.'){ - count += 1; - } - } - - String_Const_u8_Array array = {}; - array.count = count; - array.strings = push_array(arena, String_Const_u8, count); - - push_align(arena, 1); - str = string_skip(str, string_find_first(str, '.') + 1); - for (i32 i = 0; i < count; i += 1){ - u64 next_period = string_find_first(str, '.'); - String_Const_u8 extension = string_prefix(str, next_period); - str = string_skip(str, next_period + 1); - array.strings[i] = push_string_copy(arena, extension); - } - push_align(arena, 8); - - return(array); -} - -//////////////////////////////// - -function Error_Location -get_error_location(Application_Links *app, u8 *base, u8 *pos){ - ProfileScope(app, "get error location"); - Error_Location location = {}; - location.line_number = 1; - location.column_number = 1; - for (u8 *ptr = base; - ptr < pos; - ptr += 1){ - if (*ptr == '\n'){ - location.line_number += 1; - location.column_number = 1; - } - else{ - location.column_number += 1; - } - } - return(location); -} - -function String_Const_u8 -config_stringize_errors(Application_Links *app, Arena *arena, Config *parsed){ - ProfileScope(app, "stringize errors"); - String_Const_u8 result = {}; - if (parsed->errors.first != 0){ - List_String_Const_u8 list = {}; - for (Config_Error *error = parsed->errors.first; - error != 0; - error = error->next){ - Error_Location location = get_error_location(app, parsed->data.str, error->pos); - string_list_pushf(arena, &list, "%.*s:%d:%d: %.*s\n", - string_expand(error->file_name), location.line_number, location.column_number, string_expand(error->text)); - } - result = string_list_flatten(arena, list); - } - return(result); -} - -//////////////////////////////// - -function void -config_parser__advance_to_next(Config_Parser *ctx){ - Token *t = ctx->token; - Token *e = ctx->end; - for (t += 1; - t < e && (t->kind == TokenBaseKind_Comment || - t->kind == TokenBaseKind_Whitespace); - t += 1); - ctx->token = t; -} - -function Config_Parser -make_config_parser(Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Token_Array array){ - Config_Parser ctx = {}; - ctx.start = array.tokens; - ctx.token = ctx.start - 1; - ctx.end = ctx.start + array.count; - ctx.file_name = file_name; - ctx.data = data; - ctx.arena = arena; - config_parser__advance_to_next(&ctx); - return(ctx); -} - -function b32 -config_parser__recognize_base_token(Config_Parser *ctx, Token_Base_Kind kind){ - b32 result = false; - if (ctx->start <= ctx->token && ctx->token < ctx->end){ - result = (ctx->token->kind == kind); - } - else if (kind == TokenBaseKind_EOF){ - result = true; - } - return(result); -} - -function b32 -config_parser__recognize_token(Config_Parser *ctx, Token_Cpp_Kind kind){ - b32 result = false; - if (ctx->start <= ctx->token && ctx->token < ctx->end){ - result = (ctx->token->sub_kind == kind); - } - else if (kind == TokenCppKind_EOF){ - result = true; - } - return(result); -} - -function b32 -config_parser__recognize_boolean(Config_Parser *ctx){ - b32 result = false; - Token *token = ctx->token; - if (ctx->start <= ctx->token && ctx->token < ctx->end){ - result = (token->sub_kind == TokenCppKind_LiteralTrue || - token->sub_kind == TokenCppKind_LiteralFalse); - } - return(result); -} - -function String_Const_u8 -config_parser__get_lexeme(Config_Parser *ctx){ - String_Const_u8 lexeme = {}; - Token *token = ctx->token; - if (ctx->start <= token && token < ctx->end){ - lexeme = SCu8(ctx->data.str + token->pos, token->size); - } - return(lexeme); -} - -function Config_Integer -config_parser__get_int(Config_Parser *ctx){ - Config_Integer config_integer = {}; - String_Const_u8 str = config_parser__get_lexeme(ctx); - if (string_match(string_prefix(str, 2), string_u8_litexpr("0x"))){ - config_integer.is_signed = false; - config_integer.uinteger = (u32)(string_to_integer(string_skip(str, 2), 16)); - } - else{ - b32 is_negative = (string_get_character(str, 0) == '-'); - if (is_negative){ - str = string_skip(str, 1); - } - config_integer.is_signed = true; - config_integer.integer = (i32)(string_to_integer(str, 10)); - if (is_negative){ - config_integer.integer *= -1; - } - } - return(config_integer); -} - -function b32 -config_parser__get_boolean(Config_Parser *ctx){ - String_Const_u8 str = config_parser__get_lexeme(ctx); - return(string_match(str, string_u8_litexpr("true"))); -} - -function b32 -config_parser__recognize_text(Config_Parser *ctx, String_Const_u8 text){ - String_Const_u8 lexeme = config_parser__get_lexeme(ctx); - return(lexeme.str != 0 && string_match(lexeme, text)); -} - -function b32 -config_parser__match_token(Config_Parser *ctx, Token_Cpp_Kind kind){ - b32 result = config_parser__recognize_token(ctx, kind); - if (result){ - config_parser__advance_to_next(ctx); - } - return(result); -} - -function b32 -config_parser__match_text(Config_Parser *ctx, String_Const_u8 text){ - b32 result = config_parser__recognize_text(ctx, text); - if (result){ - config_parser__advance_to_next(ctx); - } - return(result); -} - -#define config_parser__match_text_lit(c,s) config_parser__match_text((c), string_u8_litexpr(s)) - -function Config *config_parser__config (Config_Parser *ctx); -function i32 *config_parser__version (Config_Parser *ctx); -function Config_Assignment *config_parser__assignment(Config_Parser *ctx); -function Config_LValue *config_parser__lvalue (Config_Parser *ctx); -function Config_RValue *config_parser__rvalue (Config_Parser *ctx); -function Config_Compound *config_parser__compound (Config_Parser *ctx); -function Config_Compound_Element *config_parser__element (Config_Parser *ctx); - -function Config* -config_parse(Application_Links *app, Arena *arena, String_Const_u8 file_name, - String_Const_u8 data, Token_Array array){ - ProfileScope(app, "config parse"); - Temp_Memory restore_point = begin_temp(arena); - Config_Parser ctx = make_config_parser(arena, file_name, data, array); - Config *config = config_parser__config(&ctx); - if (config == 0){ - end_temp(restore_point); - } - return(config); -} - -// TODO(allen): Move to string library -function Config_Error* -config_error_push(Arena *arena, Config_Error_List *list, String_Const_u8 file_name, - u8 *pos, char *error_text){ - Config_Error *error = push_array(arena, Config_Error, 1); - zdll_push_back(list->first, list->last, error); - list->count += 1; - error->file_name = file_name; - error->pos = pos; - error->text = push_string_copy(arena, SCu8(error_text)); - return(error); -} - -function u8* -config_parser__get_pos(Config_Parser *ctx){ - return(ctx->data.str + ctx->token->pos); -} - -function void -config_parser__log_error_pos(Config_Parser *ctx, u8 *pos, char *error_text){ - config_error_push(ctx->arena, &ctx->errors, ctx->file_name, pos, error_text); -} - -function void -config_parser__log_error(Config_Parser *ctx, char *error_text){ - config_parser__log_error_pos(ctx, config_parser__get_pos(ctx), error_text); -} - -function Config* -config_parser__config(Config_Parser *ctx){ - i32 *version = config_parser__version(ctx); - - Config_Assignment *first = 0; - Config_Assignment *last = 0; - i32 count = 0; - for (;!config_parser__recognize_token(ctx, TokenCppKind_EOF);){ - Config_Assignment *assignment = config_parser__assignment(ctx); - if (assignment != 0){ - zdll_push_back(first, last, assignment); - count += 1; - } - } - - Config *config = push_array(ctx->arena, Config, 1); - block_zero_struct(config); - config->version = version; - config->first = first; - config->last = last; - config->count = count; - config->errors = ctx->errors; - config->file_name = ctx->file_name; - config->data = ctx->data; - return(config); -} - -function void -config_parser__recover_parse(Config_Parser *ctx){ - for (;;){ - if (config_parser__match_token(ctx, TokenCppKind_Semicolon)){ - break; - } - if (config_parser__recognize_token(ctx, TokenCppKind_EOF)){ - break; - } - config_parser__advance_to_next(ctx); - } -} - -function i32* -config_parser__version(Config_Parser *ctx){ - require(config_parser__match_text_lit(ctx, "version")); - - if (!config_parser__match_token(ctx, TokenCppKind_ParenOp)){ - config_parser__log_error(ctx, "expected token '(' for version specifier: 'version(#)'"); - config_parser__recover_parse(ctx); - return(0); - } - - if (!config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ - config_parser__log_error(ctx, "expected an integer constant for version specifier: 'version(#)'"); - config_parser__recover_parse(ctx); - return(0); - } - - Config_Integer value = config_parser__get_int(ctx); - config_parser__advance_to_next(ctx); - - if (!config_parser__match_token(ctx, TokenCppKind_ParenCl)){ - config_parser__log_error(ctx, "expected token ')' for version specifier: 'version(#)'"); - config_parser__recover_parse(ctx); - return(0); - } - - if (!config_parser__match_token(ctx, TokenCppKind_Semicolon)){ - config_parser__log_error(ctx, "expected token ';' for version specifier: 'version(#)'"); - config_parser__recover_parse(ctx); - return(0); - } - - i32 *ptr = push_array(ctx->arena, i32, 1); - *ptr = value.integer; - return(ptr); -} - -function Config_Assignment* -config_parser__assignment(Config_Parser *ctx){ - u8 *pos = config_parser__get_pos(ctx); - - Config_LValue *l = config_parser__lvalue(ctx); - if (l == 0){ - config_parser__log_error(ctx, "expected an l-value; l-value formats: 'identifier', 'identifier[#]'"); - config_parser__recover_parse(ctx); - return(0); - } - - if (!config_parser__match_token(ctx, TokenCppKind_Eq)){ - config_parser__log_error(ctx, "expected token '=' for assignment: 'l-value = r-value;'"); - config_parser__recover_parse(ctx); - return(0); - } - - Config_RValue *r = config_parser__rvalue(ctx); - if (r == 0){ - config_parser__log_error(ctx, "expected an r-value; r-value formats:\n" - "\tconstants (true, false, integers, hexadecimal integers, strings, characters)\n" - "\tany l-value that is set in the file\n" - "\tcompound: '{ compound-element, compound-element, compound-element ...}'\n" - "\ta compound-element is an r-value, and can have a layout specifier\n" - "\tcompound-element with layout specifier: .name = r-value, .integer = r-value"); - config_parser__recover_parse(ctx); - return(0); - } - - if (!config_parser__match_token(ctx, TokenCppKind_Semicolon)){ - config_parser__log_error(ctx, "expected token ';' for assignment: 'l-value = r-value;'"); - config_parser__recover_parse(ctx); - return(0); - } - - Config_Assignment *assignment = push_array_zero(ctx->arena, Config_Assignment, 1); - assignment->pos = pos; - assignment->l = l; - assignment->r = r; - return(assignment); -} - -function Config_LValue* -config_parser__lvalue(Config_Parser *ctx){ - require(config_parser__recognize_token(ctx, TokenCppKind_Identifier)); - String_Const_u8 identifier = config_parser__get_lexeme(ctx); - config_parser__advance_to_next(ctx); - - i32 index = 0; - if (config_parser__match_token(ctx, TokenCppKind_BrackOp)){ - require(config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)); - Config_Integer value = config_parser__get_int(ctx); - index = value.integer; - config_parser__advance_to_next(ctx); - require(config_parser__match_token(ctx, TokenCppKind_BrackCl)); - } - - Config_LValue *lvalue = push_array_zero(ctx->arena, Config_LValue, 1); - lvalue->identifier = identifier; - lvalue->index = index; - return(lvalue); -} - -function Config_RValue* -config_parser__rvalue(Config_Parser *ctx){ - Config_RValue *rvalue = 0; - if (config_parser__recognize_token(ctx, TokenCppKind_Identifier)){ - Config_LValue *l = config_parser__lvalue(ctx); - require(l != 0); - rvalue = push_array_zero(ctx->arena, Config_RValue, 1); - rvalue->type = ConfigRValueType_LValue; - rvalue->lvalue = l; - } - else if (config_parser__recognize_token(ctx, TokenCppKind_BraceOp)){ - config_parser__advance_to_next(ctx); - Config_Compound *compound = config_parser__compound(ctx); - require(compound != 0); - rvalue = push_array_zero(ctx->arena, Config_RValue, 1); - rvalue->type = ConfigRValueType_Compound; - rvalue->compound = compound; - } - else if (config_parser__recognize_boolean(ctx)){ - b32 b = config_parser__get_boolean(ctx); - config_parser__advance_to_next(ctx); - rvalue = push_array_zero(ctx->arena, Config_RValue, 1); - rvalue->type = ConfigRValueType_Boolean; - rvalue->boolean = b; - } - else if (config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ - Config_Integer value = config_parser__get_int(ctx); - config_parser__advance_to_next(ctx); - rvalue = push_array_zero(ctx->arena, Config_RValue, 1); - rvalue->type = ConfigRValueType_Integer; - if (value.is_signed){ - rvalue->integer = value.integer; - } - else{ - rvalue->uinteger = value.uinteger; - } - } - else if (config_parser__recognize_token(ctx, TokenCppKind_LiteralString)){ - String_Const_u8 s = config_parser__get_lexeme(ctx); - config_parser__advance_to_next(ctx); - s = string_chop(string_skip(s, 1), 1); - String_Const_u8 interpreted = string_interpret_escapes(ctx->arena, s); - rvalue = push_array_zero(ctx->arena, Config_RValue, 1); - rvalue->type = ConfigRValueType_String; - rvalue->string = interpreted; - } - else if (config_parser__recognize_token(ctx, TokenCppKind_LiteralCharacter)){ - String_Const_u8 s = config_parser__get_lexeme(ctx); - config_parser__advance_to_next(ctx); - s = string_chop(string_skip(s, 1), 1); - String_Const_u8 interpreted = string_interpret_escapes(ctx->arena, s); - rvalue = push_array_zero(ctx->arena, Config_RValue, 1); - rvalue->type = ConfigRValueType_Character; - rvalue->character = string_get_character(interpreted, 0); - } - return(rvalue); -} - -function void -config_parser__compound__check(Config_Parser *ctx, Config_Compound *compound){ - b32 implicit_index_allowed = true; - for (Config_Compound_Element *node = compound->first; - node != 0; - node = node->next){ - if (node->l.type != ConfigLayoutType_Unset){ - implicit_index_allowed = false; - } - else if (!implicit_index_allowed){ - config_parser__log_error_pos(ctx, node->l.pos, - "encountered unlabeled member after one or more labeled members"); - } - } -} - -function Config_Compound* -config_parser__compound(Config_Parser *ctx){ - Config_Compound_Element *first = 0; - Config_Compound_Element *last = 0; - i32 count = 0; - - Config_Compound_Element *element = config_parser__element(ctx); - require(element != 0); - zdll_push_back(first, last, element); - count += 1; - - for (;config_parser__match_token(ctx, TokenCppKind_Comma);){ - if (config_parser__recognize_token(ctx, TokenCppKind_BraceCl)){ - break; - } - element = config_parser__element(ctx); - require(element != 0); - zdll_push_back(first, last, element); - count += 1; - } - - require(config_parser__match_token(ctx, TokenCppKind_BraceCl)); - - Config_Compound *compound = push_array(ctx->arena, Config_Compound, 1); - block_zero_struct(compound); - compound->first = first; - compound->last = last; - compound->count = count; - config_parser__compound__check(ctx, compound); - return(compound); -} - -function Config_Compound_Element* -config_parser__element(Config_Parser *ctx){ - Config_Layout layout = {}; - layout.pos = config_parser__get_pos(ctx); - if (config_parser__match_token(ctx, TokenCppKind_Dot)){ - if (config_parser__recognize_token(ctx, TokenCppKind_Identifier)){ - layout.type = ConfigLayoutType_Identifier; - layout.identifier = config_parser__get_lexeme(ctx); - config_parser__advance_to_next(ctx); - } - else if (config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ - layout.type = ConfigLayoutType_Integer; - Config_Integer value = config_parser__get_int(ctx); - layout.integer = value.integer; - config_parser__advance_to_next(ctx); - } - else{ - return(0); - } - require(config_parser__match_token(ctx, TokenCppKind_Eq)); - } - Config_RValue *rvalue = config_parser__rvalue(ctx); - require(rvalue != 0); - Config_Compound_Element *element = push_array(ctx->arena, Config_Compound_Element, 1); - block_zero_struct(element); - element->l = layout; - element->r = rvalue; - return(element); -} - -//////////////////////////////// - -function Config_Error* -config_add_error(Arena *arena, Config *config, u8 *pos, char *error_text){ - return(config_error_push(arena, &config->errors, config->file_name, pos, - error_text)); -} - -//////////////////////////////// - -function Config_Assignment* -config_lookup_assignment(Config *config, String_Const_u8 var_name, i32 subscript){ - Config_Assignment *assignment = 0; - for (assignment = config->first; - assignment != 0; - assignment = assignment->next){ - Config_LValue *l = assignment->l; - if (l != 0 && string_match(l->identifier, var_name) && l->index == subscript){ - break; - } - } - return(assignment); -} - -function Config_Get_Result -config_var(Config *config, String_Const_u8 var_name, i32 subscript); - -function Config_Get_Result -config_evaluate_rvalue(Config *config, Config_Assignment *assignment, Config_RValue *r){ - Config_Get_Result result = {}; - if (r != 0 && !assignment->visited){ - if (r->type == ConfigRValueType_LValue){ - assignment->visited = true; - Config_LValue *l = r->lvalue; - result = config_var(config, l->identifier, l->index); - assignment->visited = false; - } - else{ - result.success = true; - result.pos = assignment->pos; - result.type = r->type; - switch (r->type){ - case ConfigRValueType_Boolean: - { - result.boolean = r->boolean; - }break; - - case ConfigRValueType_Integer: - { - result.integer = r->integer; - }break; - - case ConfigRValueType_String: - { - result.string = r->string; - }break; - - case ConfigRValueType_Character: - { - result.character = r->character; - }break; - - case ConfigRValueType_Compound: - { - result.compound = r->compound; - }break; - } - } - } - return(result); -} - -function Config_Get_Result -config_var(Config *config, String_Const_u8 var_name, i32 subscript){ - Config_Get_Result result = {}; - Config_Assignment *assignment = config_lookup_assignment(config, var_name, subscript); - if (assignment != 0){ - result = config_evaluate_rvalue(config, assignment, assignment->r); - } - return(result); -} - -function Config_Get_Result -config_compound_member(Config *config, Config_Compound *compound, String_Const_u8 var_name, i32 index){ - Config_Get_Result result = {}; - i32 implicit_index = 0; - b32 implicit_index_is_valid = true; - for (Config_Compound_Element *element = compound->first; - element != 0; - element = element->next, implicit_index += 1){ - b32 element_matches_query = false; - switch (element->l.type){ - case ConfigLayoutType_Unset: - { - if (implicit_index_is_valid && index == implicit_index){ - element_matches_query = true; - } - }break; - - case ConfigLayoutType_Identifier: - { - implicit_index_is_valid = false; - if (string_match(element->l.identifier, var_name)){ - element_matches_query = true; - } - }break; - - case ConfigLayoutType_Integer: - { - implicit_index_is_valid = false; - if (element->l.integer == index){ - element_matches_query = true; - } - }break; - } - if (element_matches_query){ - Config_Assignment dummy_assignment = {}; - dummy_assignment.pos = element->l.pos; - result = config_evaluate_rvalue(config, &dummy_assignment, element->r); - break; - } - } - return(result); -} - -function Config_Iteration_Step_Result -typed_array_iteration_step(Config *parsed, Config_Compound *compound, Config_RValue_Type type, i32 index); - -function i32 -typed_array_get_count(Config *parsed, Config_Compound *compound, Config_RValue_Type type); - -function Config_Get_Result_List -typed_array_reference_list(Arena *arena, Config *parsed, Config_Compound *compound, Config_RValue_Type type); - -#define config_fixed_string_var(c,v,s,o,a) config_placed_string_var((c),(v),(s),(o),(a),sizeof(a)) - -//////////////////////////////// - -function b32 -config_has_var(Config *config, String_Const_u8 var_name, i32 subscript){ - Config_Get_Result result = config_var(config, var_name, subscript); - return(result.success && result.type == ConfigRValueType_NoType); -} - -function b32 -config_has_var(Config *config, char *var_name, i32 subscript){ - return(config_has_var(config, SCu8(var_name), subscript)); -} - -function b32 -config_bool_var(Config *config, String_Const_u8 var_name, i32 subscript, b32* var_out){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = (result.success && result.type == ConfigRValueType_Boolean); - if (success){ - *var_out = result.boolean; - } - return(success); -} -function b32 -config_bool_var(Config *config, String_Const_u8 var_name, i32 subscript, b8 *var_out){ - b32 temp = false; - b32 success = config_bool_var(config, var_name, subscript, &temp); - if (success){ - *var_out = (temp != false); - } - return(success); -} -function b32 -config_bool_var(Config *config, char *var_name, i32 subscript, b32* var_out){ - return(config_bool_var(config, SCu8(var_name), subscript, var_out)); -} -function b32 -config_bool_var(Config *config, char* var_name, i32 subscript, b8 *var_out){ - b32 temp = false; - b32 success = config_bool_var(config, SCu8(var_name), subscript, &temp); - if (success){ - *var_out = (temp != false); - } - return(success); -} - -function b32 -config_int_var(Config *config, String_Const_u8 var_name, i32 subscript, i32* var_out){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = result.success && result.type == ConfigRValueType_Integer; - if (success){ - *var_out = result.integer; - } - return(success); -} - -function b32 -config_int_var(Config *config, char *var_name, i32 subscript, i32* var_out){ - return(config_int_var(config, SCu8(var_name), subscript, var_out)); -} - -function b32 -config_uint_var(Config *config, String_Const_u8 var_name, i32 subscript, u32* var_out){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = result.success && result.type == ConfigRValueType_Integer; - if (success){ - *var_out = result.uinteger; - } - return(success); -} - -function b32 -config_uint_var(Config *config, char *var_name, i32 subscript, u32* var_out){ - return(config_uint_var(config, SCu8(var_name), subscript, var_out)); -} - -function b32 -config_string_var(Config *config, String_Const_u8 var_name, i32 subscript, String_Const_u8* var_out){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = result.success && result.type == ConfigRValueType_String; - if (success){ - *var_out = result.string; - } - return(success); -} - -function b32 -config_string_var(Config *config, char *var_name, i32 subscript, String_Const_u8* var_out){ - return(config_string_var(config, SCu8(var_name), subscript, var_out)); -} - -function b32 -config_placed_string_var(Config *config, String_Const_u8 var_name, i32 subscript, String_Const_u8* var_out, u8 *space, u64 space_size){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = (result.success && result.type == ConfigRValueType_String); - if (success){ - u64 size = result.string.size; - size = clamp_top(size, space_size); - block_copy(space, result.string.str, size); - *var_out = SCu8(space, size); - } - return(success); -} - -function b32 -config_placed_string_var(Config *config, char *var_name, i32 subscript, String_Const_u8* var_out, u8 *space, u64 space_size){ - return(config_placed_string_var(config, SCu8(var_name), subscript, var_out, space, space_size)); -} - -function b32 -config_char_var(Config *config, String_Const_u8 var_name, i32 subscript, char* var_out){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = result.success && result.type == ConfigRValueType_Character; - if (success){ - *var_out = result.character; - } - return(success); -} - -function b32 -config_char_var(Config *config, char *var_name, i32 subscript, char* var_out){ - return(config_char_var(config, SCu8(var_name), subscript, var_out)); -} - -function b32 -config_compound_var(Config *config, String_Const_u8 var_name, i32 subscript, Config_Compound** var_out){ - Config_Get_Result result = config_var(config, var_name, subscript); - b32 success = (result.success && result.type == ConfigRValueType_Compound); - if (success){ - *var_out = result.compound; - } - return(success); -} - -function b32 -config_compound_var(Config *config, char *var_name, i32 subscript, Config_Compound** var_out){ - return(config_compound_var(config, SCu8(var_name), subscript, var_out)); -} - -function b32 -config_compound_has_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = result.success && result.type == ConfigRValueType_NoType; - return(success); -} - -function b32 -config_compound_has_member(Config *config, Config_Compound *compound, - char *var_name, i32 index){ - return(config_compound_has_member(config, compound, SCu8(var_name), index)); -} - -function b32 -config_compound_bool_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, b32* var_out){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = result.success && result.type == ConfigRValueType_Boolean; - if (success){ - *var_out = result.boolean; - } - return(success); -} - -function b32 -config_compound_bool_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, b32* var_out){ - return(config_compound_bool_member(config, compound, SCu8(var_name), index, var_out)); -} - -function b32 -config_compound_int_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, i32* var_out){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = result.success && result.type == ConfigRValueType_Integer; - if (success){ - *var_out = result.integer; - } - return(success); -} - -function b32 -config_compound_int_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, i32* var_out){ - return(config_compound_int_member(config, compound, SCu8(var_name), index, var_out)); -} - -function b32 -config_compound_uint_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, u32* var_out){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = result.success && result.type == ConfigRValueType_Integer; - if (success){ - *var_out = result.uinteger; - } - return(success); -} - -function b32 -config_compound_uint_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, u32* var_out){ - return(config_compound_uint_member(config, compound, SCu8(var_name), index, var_out)); -} - -function b32 -config_compound_string_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, String_Const_u8* var_out){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = (result.success && result.type == ConfigRValueType_String); - if (success){ - *var_out = result.string; - } - return(success); -} - -function b32 -config_compound_string_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, String_Const_u8* var_out){ - return(config_compound_string_member(config, compound, SCu8(var_name), index, var_out)); -} - -function b32 -config_compound_placed_string_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, String_Const_u8* var_out, u8 *space, u64 space_size){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = (result.success && result.type == ConfigRValueType_String); - if (success){ - u64 size = result.string.size; - size = clamp_top(size, space_size); - block_copy(space, result.string.str, size); - *var_out = SCu8(space, size); - } - return(success); -} - -function b32 -config_compound_placed_string_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, String_Const_u8* var_out, u8 *space, u64 space_size){ - return(config_compound_placed_string_member(config, compound, SCu8(var_name), index, var_out, space, space_size)); -} - -function b32 -config_compound_char_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, char* var_out){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = result.success && result.type == ConfigRValueType_Character; - if (success){ - *var_out = result.character; - } - return(success); -} - -function b32 -config_compound_char_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, char* var_out){ - return(config_compound_char_member(config, compound, SCu8(var_name), index, var_out)); -} - -function b32 -config_compound_compound_member(Config *config, Config_Compound *compound, - String_Const_u8 var_name, i32 index, Config_Compound** var_out){ - Config_Get_Result result = config_compound_member(config, compound, var_name, index); - b32 success = result.success && result.type == ConfigRValueType_Compound; - if (success){ - *var_out = result.compound; - } - return(success); -} - -function b32 -config_compound_compound_member(Config *config, Config_Compound *compound, - char *var_name, i32 index, Config_Compound** var_out){ - return(config_compound_compound_member(config, compound, SCu8(var_name), index, var_out)); -} - -function Iteration_Step_Result -typed_has_array_iteration_step(Config *config, Config_Compound *compound, i32 index){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_NoType, index); - return(result.step); -} - -function Iteration_Step_Result -typed_bool_array_iteration_step(Config *config, Config_Compound *compound, i32 index, b32* var_out){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Boolean, index); - b32 success = (result.step == Iteration_Good); - if (success){ - *var_out = result.get.boolean; - } - return(result.step); -} - -function Iteration_Step_Result -typed_int_array_iteration_step(Config *config, Config_Compound *compound, i32 index, i32* var_out){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Integer, index); - b32 success = (result.step == Iteration_Good); - if (success){ - *var_out = result.get.integer; - } - return(result.step); -} - -function Iteration_Step_Result -typed_uint_array_iteration_step(Config *config, Config_Compound *compound, i32 index, u32* var_out){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Integer, index); - b32 success = (result.step == Iteration_Good); - if (success){ - *var_out = result.get.uinteger; - } - return(result.step); -} - -function Iteration_Step_Result -typed_string_array_iteration_step(Config *config, Config_Compound *compound, i32 index, String_Const_u8* var_out){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_String, index); - b32 success = (result.step == Iteration_Good); - if (success){ - *var_out = result.get.string; - } - return(result.step); -} - -function Iteration_Step_Result -typed_placed_string_array_iteration_step(Config *config, Config_Compound *compound, i32 index, String_Const_u8* var_out, u8 *space, u64 space_size){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_String, index); - b32 success = (result.step == Iteration_Good); - if (success){ - u64 size = result.get.string.size; - size = clamp_top(size, space_size); - block_copy(space, result.get.string.str, size); - *var_out = SCu8(space, size); - } - return(result.step); -} - -function Iteration_Step_Result -typed_char_array_iteration_step(Config *config, Config_Compound *compound, i32 index, char* var_out){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Character, index); - b32 success = (result.step == Iteration_Good); - if (success){ - *var_out = result.get.character; - } - return(result.step); -} - -function Iteration_Step_Result -typed_compound_array_iteration_step(Config *config, Config_Compound *compound, i32 index, Config_Compound** var_out){ - Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Compound, index); - b32 success = (result.step == Iteration_Good); - if (success){ - *var_out = result.get.compound; - } - return(result.step); -} - -function i32 -typed_bool_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_Boolean); - return(count); -} - -function i32 -typed_int_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_Integer); - return(count); -} - -function i32 -typed_float_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_Float); - return(count); -} - -function i32 -typed_string_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_String); - return(count); -} - -function i32 -typed_character_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_Character); - return(count); -} - -function i32 -typed_compound_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_Compound); - return(count); -} - -function i32 -typed_no_type_array_get_count(Config *config, Config_Compound *compound){ - i32 count = typed_array_get_count(config, compound, ConfigRValueType_NoType); - return(count); -} - -function Config_Get_Result_List -typed_bool_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Boolean); - return(list); -} - -function Config_Get_Result_List -typed_int_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Integer); - return(list); -} - -function Config_Get_Result_List -typed_float_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Float); - return(list); -} - -function Config_Get_Result_List -typed_string_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_String); - return(list); -} - -function Config_Get_Result_List -typed_character_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Character); - return(list); -} - -function Config_Get_Result_List -typed_compound_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Compound); - return(list); -} - -function Config_Get_Result_List -typed_no_type_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ - Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_NoType); - return(list); -} - -//////////////////////////////// - -function Config_Iteration_Step_Result -typed_array_iteration_step(Config *parsed, Config_Compound *compound, Config_RValue_Type type, i32 index){ - Config_Iteration_Step_Result result = {}; - result.step = Iteration_Quit; - Config_Get_Result get_result = config_compound_member(parsed, compound, string_u8_litexpr("~"), index); - if (get_result.success){ - if (get_result.type == type || type == ConfigRValueType_NoType){ - result.step = Iteration_Good; - result.get = get_result; - } - else{ - result.step = Iteration_Skip; - } - } - return(result); -} - -function i32 -typed_array_get_count(Config *parsed, Config_Compound *compound, Config_RValue_Type type){ - i32 count = 0; - for (i32 i = 0;; ++i){ - Config_Iteration_Step_Result result = typed_array_iteration_step(parsed, compound, type, i); - if (result.step == Iteration_Skip){ - continue; - } - else if (result.step == Iteration_Quit){ - break; - } - count += 1; - } - return(count); -} - -function Config_Get_Result_List -typed_array_reference_list(Arena *arena, Config *parsed, Config_Compound *compound, Config_RValue_Type type){ - Config_Get_Result_List list = {}; - for (i32 i = 0;; ++i){ - Config_Iteration_Step_Result result = typed_array_iteration_step(parsed, compound, type, i); - if (result.step == Iteration_Skip){ - continue; - } - else if (result.step == Iteration_Quit){ - break; - } - Config_Get_Result_Node *node = push_array(arena, Config_Get_Result_Node, 1); - node->result = result.get; - zdll_push_back(list.first, list.last, node); - list.count += 1; - } - return(list); -} - -//////////////////////////////// - -function void -change_mode(Application_Links *app, String_Const_u8 mode){ - fcoder_mode = FCoderMode_Original; - if (string_match(mode, string_u8_litexpr("4coder"))){ - fcoder_mode = FCoderMode_Original; - } - else if (string_match(mode, string_u8_litexpr("notepad-like"))){ - begin_notepad_mode(app); - } - else{ - print_message(app, string_u8_litexpr("Unknown mode.\n")); - } -} - -//////////////////////////////// - -function Token_Array -token_array_from_text(Application_Links *app, Arena *arena, String_Const_u8 data){ - ProfileScope(app, "token array from text"); - Token_List list = lex_full_input_cpp(arena, data); - return(token_array_from_list(arena, &list)); -} - -function Config* -config_from_text(Application_Links *app, Arena *arena, String_Const_u8 file_name, - String_Const_u8 data){ - Config *parsed = 0; - Temp_Memory restore_point = begin_temp(arena); - Token_Array array = token_array_from_text(app, arena, data); - if (array.tokens != 0){ - parsed = config_parse(app, arena, file_name, data, array); - if (parsed == 0){ - end_temp(restore_point); - } - } - return(parsed); -} - -//////////////////////////////// - -function void -config_init_default(Config_Data *config){ - config->user_name = SCu8(config->user_name_space, (u64)0); - - block_zero_struct(&config->code_exts); - - config->mode = SCu8(config->mode_space, (u64)0); - - config->use_scroll_bars = false; - config->use_file_bars = true; - config->hide_file_bar_in_ui = true; - config->use_error_highlight = true; - config->use_jump_highlight = true; - config->use_scope_highlight = true; - config->use_paren_helper = true; - config->use_comment_keyword = true; - config->lister_whole_word_backspace_when_modified = false; - config->show_line_number_margins = false; - - config->enable_virtual_whitespace = true; - config->enable_code_wrapping = true; - config->automatically_adjust_wrapping = true; - config->automatically_indent_text_on_save = true; - config->automatically_save_changes_on_build = true; - config->automatically_load_project = false; - - config->indent_with_tabs = false; - config->indent_width = 4; - - config->default_wrap_width = 672; - config->default_min_base_width = 550; - - config->default_theme_name = SCu8(config->default_theme_name_space, sizeof("4coder") - 1); - block_copy(config->default_theme_name.str, "4coder", config->default_theme_name.size); - config->highlight_line_at_cursor = true; - - config->default_font_name = SCu8(config->default_font_name_space, (u64)0); - config->default_font_size = 16; - config->default_font_hinting = false; - - config->default_compiler_bat = SCu8(config->default_compiler_bat_space, 2); - block_copy(config->default_compiler_bat.str, "cl", 2); - - config->default_flags_bat = SCu8(config->default_flags_bat_space, (u64)0); - - config->default_compiler_sh = SCu8(config->default_compiler_sh_space, 3); - block_copy(config->default_compiler_sh.str, "g++", 3); - - config->default_flags_sh = SCu8(config->default_flags_sh_space, (u64)0); - - config->lalt_lctrl_is_altgr = false; -} - -function Config* -config_parse__data(Application_Links *app, Arena *arena, String_Const_u8 file_name, - String_Const_u8 data, Config_Data *config){ - config_init_default(config); - - b32 success = false; - - Config *parsed = config_from_text(app, arena, file_name, data); - if (parsed != 0){ - success = true; - - config_fixed_string_var(parsed, "user_name", 0, - &config->user_name, config->user_name_space); - - String_Const_u8 str = {}; - if (config_string_var(parsed, "treat_as_code", 0, &str)){ - config->code_exts = - parse_extension_line_to_extension_list(app, arena, str); - } - - config_fixed_string_var(parsed, "mode", 0, - &config->mode, config->mode_space); - - config_bool_var(parsed, "use_scroll_bars", 0, &config->use_scroll_bars); - config_bool_var(parsed, "use_file_bars", 0, &config->use_file_bars); - config_bool_var(parsed, "hide_file_bar_in_ui", 0, &config->hide_file_bar_in_ui); - config_bool_var(parsed, "use_error_highlight", 0, &config->use_error_highlight); - config_bool_var(parsed, "use_jump_highlight", 0, &config->use_jump_highlight); - config_bool_var(parsed, "use_scope_highlight", 0, &config->use_scope_highlight); - config_bool_var(parsed, "use_paren_helper", 0, &config->use_paren_helper); - config_bool_var(parsed, "use_comment_keyword", 0, &config->use_comment_keyword); - config_bool_var(parsed, "lister_whole_word_backspace_when_modified", 0, &config->lister_whole_word_backspace_when_modified); - config_bool_var(parsed, "show_line_number_margins", 0, &config->show_line_number_margins); - - - config_bool_var(parsed, "enable_virtual_whitespace", 0, &config->enable_virtual_whitespace); - config_bool_var(parsed, "enable_code_wrapping", 0, &config->enable_code_wrapping); - config_bool_var(parsed, "automatically_adjust_wrapping", 0, &config->automatically_adjust_wrapping); - config_bool_var(parsed, "automatically_indent_text_on_save", 0, &config->automatically_indent_text_on_save); - config_bool_var(parsed, "automatically_save_changes_on_build", 0, &config->automatically_save_changes_on_build); - config_bool_var(parsed, "automatically_load_project", 0, &config->automatically_load_project); - - config_bool_var(parsed, "indent_with_tabs", 0, &config->indent_with_tabs); - config_int_var(parsed, "indent_width", 0, &config->indent_width); - - config_int_var(parsed, "default_wrap_width", 0, &config->default_wrap_width); - config_int_var(parsed, "default_min_base_width", 0, &config->default_min_base_width); - - config_fixed_string_var(parsed, "default_theme_name", 0, - &config->default_theme_name, config->default_theme_name_space); - config_bool_var(parsed, "highlight_line_at_cursor", 0, &config->highlight_line_at_cursor); - - config_fixed_string_var(parsed, "default_font_name", 0, - &config->default_font_name, config->default_font_name_space); - config_int_var(parsed, "default_font_size", 0, &config->default_font_size); - config_bool_var(parsed, "default_font_hinting", 0, &config->default_font_hinting); - - config_fixed_string_var(parsed, "default_compiler_bat", 0, - &config->default_compiler_bat, config->default_compiler_bat_space); - config_fixed_string_var(parsed, "default_flags_bat", 0, - &config->default_flags_bat, config->default_flags_bat_space); - config_fixed_string_var(parsed, "default_compiler_sh", 0, - &config->default_compiler_sh, config->default_compiler_sh_space); - config_fixed_string_var(parsed, "default_flags_sh", 0, - &config->default_flags_sh, config->default_flags_sh_space); - - config_bool_var(parsed, "lalt_lctrl_is_altgr", 0, &config->lalt_lctrl_is_altgr); - } - - if (!success){ - config_init_default(config); - } - - return(parsed); -} - -function Config* -config_parse__file_handle(Application_Links *app, Arena *arena, - String_Const_u8 file_name, FILE *file, Config_Data *config){ - Config *parsed = 0; - Data data = dump_file_handle(arena, file); - if (data.data != 0){ - parsed = config_parse__data(app, arena, file_name, SCu8(data), config); - } - else{ - config_init_default(config); - } - return(parsed); -} - -function Config* -config_parse__file_name(Application_Links *app, Arena *arena, char *file_name, Config_Data *config){ - Config *parsed = 0; - b32 success = false; - FILE *file = open_file_try_current_path_then_binary_path(app, file_name); - if (file != 0){ - Data data = dump_file_handle(arena, file); - fclose(file); - if (data.data != 0){ - parsed = config_parse__data(app, arena, SCu8(file_name), SCu8(data), - config); - success = true; - } - } - if (!success){ - config_init_default(config); - } - return(parsed); -} - -function Config* -theme_parse__data(Application_Links *app, Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Arena *color_arena, Color_Table *color_table){ - Config *parsed = config_from_text(app, arena, file_name, data); - if (parsed != 0){ - for (Config_Assignment *node = parsed->first; - node != 0; - node = node->next){ - Scratch_Block scratch(app); - Config_LValue *l = node->l; - String_Const_u8 l_name = push_string_copy(scratch, l->identifier); - Managed_ID id = managed_id_get(app, string_u8_litexpr("colors"), l_name); - if (id != 0){ - u32 color = 0; - if (config_uint_var(parsed, l_name, 0, &color)){ - color_table->arrays[id%color_table->count] = make_colors(color_arena, color); - } - else{ - Config_Compound *compound = 0; - if (config_compound_var(parsed, l_name, 0, &compound)){ - local_persist u32 color_array[256]; - i32 counter = 0; - for (i32 i = 0;; i += 1){ - Config_Iteration_Step_Result result = typed_array_iteration_step(parsed, compound, ConfigRValueType_Integer, i); - if (result.step == Iteration_Skip){ - continue; - } - else if (result.step == Iteration_Quit){ - break; - } - - color_array[counter] = result.get.uinteger; - counter += 1; - if (counter == 256){ - break; - } - } - - color_table->arrays[id%color_table->count] = make_colors(color_arena, color_array, counter); - } - } - } - - } - } - return(parsed); -} - -function Config* -theme_parse__file_handle(Application_Links *app, Arena *arena, String_Const_u8 file_name, FILE *file, Arena *color_arena, Color_Table *color_table){ - Data data = dump_file_handle(arena, file); - Config *parsed = 0; - if (data.data != 0){ - parsed = theme_parse__data(app, arena, file_name, SCu8(data), color_arena, color_table); - } - return(parsed); -} - -function Config* -theme_parse__file_name(Application_Links *app, Arena *arena, char *file_name, Arena *color_arena, Color_Table *color_table){ - Config *parsed = 0; - FILE *file = open_file_try_current_path_then_binary_path(app, file_name); - if (file != 0){ - Data data = dump_file_handle(arena, file); - fclose(file); - parsed = theme_parse__data(app, arena, SCu8(file_name), SCu8(data), color_arena, color_table); - } - if (parsed == 0){ - Scratch_Block scratch(app); - String_Const_u8 str = push_u8_stringf(arena, "Did not find %s, theme not loaded", file_name); - print_message(app, str); - } - return(parsed); -} - -//////////////////////////////// - -function void -config_feedback_bool(Arena *arena, List_String_Const_u8 *list, char *name, b32 val){ - string_list_pushf(arena, list, "%s = %s;\n", name, (char*)(val?"true":"false")); -} - -function void -config_feedback_string(Arena *arena, List_String_Const_u8 *list, char *name, String_Const_u8 val){ - val.size = clamp_bot(0, val.size); - string_list_pushf(arena, list, "%s = \"%.*s\";\n", name, string_expand(val)); -} - -function void -config_feedback_string(Arena *arena, List_String_Const_u8 *list, char *name, char *val){ - string_list_pushf(arena, list, "%s = \"%s\";\n", name, val); -} - -function void -config_feedback_extension_list(Arena *arena, List_String_Const_u8 *list, char *name, String_Const_u8_Array *extensions){ - string_list_pushf(arena, list, "%s = \"", name); - for (i32 i = 0; i < extensions->count; ++i){ - String_Const_u8 ext = extensions->strings[i]; - string_list_pushf(arena, list, ".%.*s", string_expand(ext)); - } - string_list_push_u8_lit(arena, list, "\";\n"); -} - -function void -config_feedback_int(Arena *arena, List_String_Const_u8 *list, char *name, i32 val){ - string_list_pushf(arena, list, "%s = %d;\n", name, val); -} - -//////////////////////////////// - -function void -load_config_and_apply(Application_Links *app, Arena *out_arena, Config_Data *config, - i32 override_font_size, b32 override_hinting){ - Scratch_Block scratch(app); - - linalloc_clear(out_arena); - Config *parsed = config_parse__file_name(app, out_arena, "config.4coder", config); - - if (parsed != 0){ - // Top - print_message(app, string_u8_litexpr("Loaded config file:\n")); - - // Errors - String_Const_u8 error_text = config_stringize_errors(app, scratch, parsed); - if (error_text.str != 0){ - print_message(app, error_text); - } - } - else{ - print_message(app, string_u8_litexpr("Using default config:\n")); - Face_Description description = get_face_description(app, 0); - if (description.font.file_name.str != 0){ - u64 size = Min(description.font.file_name.size, sizeof(config->default_font_name_space)); - block_copy(config->default_font_name_space, description.font.file_name.str, size); - config->default_font_name.size = size; - } - } - - if (config->default_font_name.size == 0){ -#define M "liberation-mono.ttf" - block_copy(config->default_font_name_space, M, sizeof(M) - 1); - config->default_font_name.size = sizeof(M) - 1; -#undef M - } - - { - // Values - Temp_Memory temp2 = begin_temp(scratch); - List_String_Const_u8 list = {}; - - config_feedback_string(scratch, &list, "user_name", config->user_name); - config_feedback_extension_list(scratch, &list, "treat_as_code", &config->code_exts); - - config_feedback_string(scratch, &list, "mode", config->mode); - - config_feedback_bool(scratch, &list, "use_scroll_bars", config->use_scroll_bars); - config_feedback_bool(scratch, &list, "use_file_bars", config->use_file_bars); - config_feedback_bool(scratch, &list, "hide_file_bar_in_ui", config->hide_file_bar_in_ui); - config_feedback_bool(scratch, &list, "use_error_highlight", config->use_error_highlight); - config_feedback_bool(scratch, &list, "use_jump_highlight", config->use_jump_highlight); - config_feedback_bool(scratch, &list, "use_scope_highlight", config->use_scope_highlight); - config_feedback_bool(scratch, &list, "use_paren_helper", config->use_paren_helper); - config_feedback_bool(scratch, &list, "use_comment_keyword", config->use_comment_keyword); - config_feedback_bool(scratch, &list, "lister_whole_word_backspace_when_modified", config->lister_whole_word_backspace_when_modified); - config_feedback_bool(scratch, &list, "show_line_number_margins", config->show_line_number_margins); - - config_feedback_bool(scratch, &list, "enable_virtual_whitespace", config->enable_virtual_whitespace); - config_feedback_bool(scratch, &list, "enable_code_wrapping", config->enable_code_wrapping); - config_feedback_bool(scratch, &list, "automatically_indent_text_on_save", config->automatically_indent_text_on_save); - config_feedback_bool(scratch, &list, "automatically_save_changes_on_build", config->automatically_save_changes_on_build); - config_feedback_bool(scratch, &list, "automatically_adjust_wrapping", config->automatically_adjust_wrapping); - config_feedback_bool(scratch, &list, "automatically_load_project", config->automatically_load_project); - - config_feedback_bool(scratch, &list, "indent_with_tabs", config->indent_with_tabs); - config_feedback_int(scratch, &list, "indent_width", config->indent_width); - - config_feedback_int(scratch, &list, "default_wrap_width", config->default_wrap_width); - config_feedback_int(scratch, &list, "default_min_base_width", config->default_min_base_width); - - config_feedback_string(scratch, &list, "default_theme_name", config->default_theme_name); - config_feedback_bool(scratch, &list, "highlight_line_at_cursor", config->highlight_line_at_cursor); - - config_feedback_string(scratch, &list, "default_font_name", config->default_font_name); - config_feedback_int(scratch, &list, "default_font_size", config->default_font_size); - config_feedback_bool(scratch, &list, "default_font_hinting", config->default_font_hinting); - - config_feedback_string(scratch, &list, "default_compiler_bat", config->default_compiler_bat); - config_feedback_string(scratch, &list, "default_flags_bat", config->default_flags_bat); - config_feedback_string(scratch, &list, "default_compiler_sh", config->default_compiler_sh); - config_feedback_string(scratch, &list, "default_flags_sh", config->default_flags_sh); - - config_feedback_bool(scratch, &list, "lalt_lctrl_is_altgr", config->lalt_lctrl_is_altgr); - - string_list_push_u8_lit(scratch, &list, "\n"); - String_Const_u8 message = string_list_flatten(scratch, list); - print_message(app, message); - end_temp(temp2); - } - - // Apply config - change_mode(app, config->mode); - global_set_setting(app, GlobalSetting_LAltLCtrlIsAltGr, config->lalt_lctrl_is_altgr); - - Color_Table *colors = get_color_table_by_name(config->default_theme_name); - set_active_color(colors); - - Face_Description description = {}; - if (override_font_size != 0){ - description.parameters.pt_size = override_font_size; - } - else{ - description.parameters.pt_size = config->default_font_size; - } - description.parameters.hinting = config->default_font_hinting || override_hinting; - - description.font.file_name = config->default_font_name; - if (!modify_global_face_by_description(app, description)){ - description.font.file_name = get_file_path_in_fonts_folder(scratch, config->default_font_name); - modify_global_face_by_description(app, description); - } -} - -function void -load_theme_file_into_live_set(Application_Links *app, char *file_name){ - Arena *arena = &global_theme_arena; - Color_Table color_table = make_color_table(app, arena); - Scratch_Block scratch(app); - Config *config = theme_parse__file_name(app, scratch, file_name, arena, &color_table); - String_Const_u8 error_text = config_stringize_errors(app, scratch, config); - print_message(app, error_text); - - String_Const_u8 name = SCu8(file_name); - name = string_front_of_path(name); - if (string_match(string_postfix(name, 7), string_u8_litexpr(".4coder"))){ - name = string_chop(name, 7); - } - save_theme(color_table, name); -} - -function void -load_folder_of_themes_into_live_set(Application_Links *app, String_Const_u8 path){ - Scratch_Block scratch(app, Scratch_Share); - - File_List list = system_get_file_list(scratch, path); - for (File_Info **ptr = list.infos, **end = list.infos + list.count; - ptr < end; - ptr += 1){ - File_Info *info = *ptr; - if (!HasFlag(info->attributes.flags, FileAttribute_IsDirectory)){ - String_Const_u8 name = info->file_name; - Temp_Memory_Block temp(scratch); - String_Const_u8 full_name = push_u8_stringf(scratch, "%.*s/%.*s", - string_expand(path), - string_expand(name)); - load_theme_file_into_live_set(app, (char*)full_name.str); - } - } -} - -// BOTTOM - +/* +4coder_config.cpp - Parsing *.4coder files. +*/ + +// TOP + +function String_Const_u8_Array +parse_extension_line_to_extension_list(Application_Links *app, + Arena *arena, String_Const_u8 str){ + ProfileScope(app, "parse extension line to extension list"); + i32 count = 0; + for (u64 i = 0; i < str.size; i += 1){ + if (str.str[i] == '.'){ + count += 1; + } + } + + String_Const_u8_Array array = {}; + array.count = count; + array.strings = push_array(arena, String_Const_u8, count); + + push_align(arena, 1); + str = string_skip(str, string_find_first(str, '.') + 1); + for (i32 i = 0; i < count; i += 1){ + u64 next_period = string_find_first(str, '.'); + String_Const_u8 extension = string_prefix(str, next_period); + str = string_skip(str, next_period + 1); + array.strings[i] = push_string_copy(arena, extension); + } + push_align(arena, 8); + + return(array); +} + +//////////////////////////////// + +function Error_Location +get_error_location(Application_Links *app, u8 *base, u8 *pos){ + ProfileScope(app, "get error location"); + Error_Location location = {}; + location.line_number = 1; + location.column_number = 1; + for (u8 *ptr = base; + ptr < pos; + ptr += 1){ + if (*ptr == '\n'){ + location.line_number += 1; + location.column_number = 1; + } + else{ + location.column_number += 1; + } + } + return(location); +} + +function String_Const_u8 +config_stringize_errors(Application_Links *app, Arena *arena, Config *parsed){ + ProfileScope(app, "stringize errors"); + String_Const_u8 result = {}; + if (parsed->errors.first != 0){ + List_String_Const_u8 list = {}; + for (Config_Error *error = parsed->errors.first; + error != 0; + error = error->next){ + Error_Location location = get_error_location(app, parsed->data.str, error->pos); + string_list_pushf(arena, &list, "%.*s:%d:%d: %.*s\n", + string_expand(error->file_name), location.line_number, location.column_number, string_expand(error->text)); + } + result = string_list_flatten(arena, list); + } + return(result); +} + +//////////////////////////////// + +function void +config_parser__advance_to_next(Config_Parser *ctx){ + Token *t = ctx->token; + Token *e = ctx->end; + for (t += 1; + t < e && (t->kind == TokenBaseKind_Comment || + t->kind == TokenBaseKind_Whitespace); + t += 1); + ctx->token = t; +} + +function Config_Parser +make_config_parser(Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Token_Array array){ + Config_Parser ctx = {}; + ctx.start = array.tokens; + ctx.token = ctx.start - 1; + ctx.end = ctx.start + array.count; + ctx.file_name = file_name; + ctx.data = data; + ctx.arena = arena; + config_parser__advance_to_next(&ctx); + return(ctx); +} + +function b32 +config_parser__recognize_base_token(Config_Parser *ctx, Token_Base_Kind kind){ + b32 result = false; + if (ctx->start <= ctx->token && ctx->token < ctx->end){ + result = (ctx->token->kind == kind); + } + else if (kind == TokenBaseKind_EOF){ + result = true; + } + return(result); +} + +function b32 +config_parser__recognize_token(Config_Parser *ctx, Token_Cpp_Kind kind){ + b32 result = false; + if (ctx->start <= ctx->token && ctx->token < ctx->end){ + result = (ctx->token->sub_kind == kind); + } + else if (kind == TokenCppKind_EOF){ + result = true; + } + return(result); +} + +function b32 +config_parser__recognize_boolean(Config_Parser *ctx){ + b32 result = false; + Token *token = ctx->token; + if (ctx->start <= ctx->token && ctx->token < ctx->end){ + result = (token->sub_kind == TokenCppKind_LiteralTrue || + token->sub_kind == TokenCppKind_LiteralFalse); + } + return(result); +} + +function String_Const_u8 +config_parser__get_lexeme(Config_Parser *ctx){ + String_Const_u8 lexeme = {}; + Token *token = ctx->token; + if (ctx->start <= token && token < ctx->end){ + lexeme = SCu8(ctx->data.str + token->pos, token->size); + } + return(lexeme); +} + +function Config_Integer +config_parser__get_int(Config_Parser *ctx){ + Config_Integer config_integer = {}; + String_Const_u8 str = config_parser__get_lexeme(ctx); + if (string_match(string_prefix(str, 2), string_u8_litexpr("0x"))){ + config_integer.is_signed = false; + config_integer.uinteger = (u32)(string_to_integer(string_skip(str, 2), 16)); + } + else{ + b32 is_negative = (string_get_character(str, 0) == '-'); + if (is_negative){ + str = string_skip(str, 1); + } + config_integer.is_signed = true; + config_integer.integer = (i32)(string_to_integer(str, 10)); + if (is_negative){ + config_integer.integer *= -1; + } + } + return(config_integer); +} + +function b32 +config_parser__get_boolean(Config_Parser *ctx){ + String_Const_u8 str = config_parser__get_lexeme(ctx); + return(string_match(str, string_u8_litexpr("true"))); +} + +function b32 +config_parser__recognize_text(Config_Parser *ctx, String_Const_u8 text){ + String_Const_u8 lexeme = config_parser__get_lexeme(ctx); + return(lexeme.str != 0 && string_match(lexeme, text)); +} + +function b32 +config_parser__match_token(Config_Parser *ctx, Token_Cpp_Kind kind){ + b32 result = config_parser__recognize_token(ctx, kind); + if (result){ + config_parser__advance_to_next(ctx); + } + return(result); +} + +function b32 +config_parser__match_text(Config_Parser *ctx, String_Const_u8 text){ + b32 result = config_parser__recognize_text(ctx, text); + if (result){ + config_parser__advance_to_next(ctx); + } + return(result); +} + +#define config_parser__match_text_lit(c,s) config_parser__match_text((c), string_u8_litexpr(s)) + +function Config *config_parser__config (Config_Parser *ctx); +function i32 *config_parser__version (Config_Parser *ctx); +function Config_Assignment *config_parser__assignment(Config_Parser *ctx); +function Config_LValue *config_parser__lvalue (Config_Parser *ctx); +function Config_RValue *config_parser__rvalue (Config_Parser *ctx); +function Config_Compound *config_parser__compound (Config_Parser *ctx); +function Config_Compound_Element *config_parser__element (Config_Parser *ctx); + +function Config* +config_parse(Application_Links *app, Arena *arena, String_Const_u8 file_name, + String_Const_u8 data, Token_Array array){ + ProfileScope(app, "config parse"); + Temp_Memory restore_point = begin_temp(arena); + Config_Parser ctx = make_config_parser(arena, file_name, data, array); + Config *config = config_parser__config(&ctx); + if (config == 0){ + end_temp(restore_point); + } + return(config); +} + +// TODO(allen): Move to string library +function Config_Error* +config_error_push(Arena *arena, Config_Error_List *list, String_Const_u8 file_name, + u8 *pos, char *error_text){ + Config_Error *error = push_array(arena, Config_Error, 1); + zdll_push_back(list->first, list->last, error); + list->count += 1; + error->file_name = file_name; + error->pos = pos; + error->text = push_string_copy(arena, SCu8(error_text)); + return(error); +} + +function u8* +config_parser__get_pos(Config_Parser *ctx){ + return(ctx->data.str + ctx->token->pos); +} + +function void +config_parser__log_error_pos(Config_Parser *ctx, u8 *pos, char *error_text){ + config_error_push(ctx->arena, &ctx->errors, ctx->file_name, pos, error_text); +} + +function void +config_parser__log_error(Config_Parser *ctx, char *error_text){ + config_parser__log_error_pos(ctx, config_parser__get_pos(ctx), error_text); +} + +function Config* +config_parser__config(Config_Parser *ctx){ + i32 *version = config_parser__version(ctx); + + Config_Assignment *first = 0; + Config_Assignment *last = 0; + i32 count = 0; + for (;!config_parser__recognize_token(ctx, TokenCppKind_EOF);){ + Config_Assignment *assignment = config_parser__assignment(ctx); + if (assignment != 0){ + zdll_push_back(first, last, assignment); + count += 1; + } + } + + Config *config = push_array(ctx->arena, Config, 1); + block_zero_struct(config); + config->version = version; + config->first = first; + config->last = last; + config->count = count; + config->errors = ctx->errors; + config->file_name = ctx->file_name; + config->data = ctx->data; + return(config); +} + +function void +config_parser__recover_parse(Config_Parser *ctx){ + for (;;){ + if (config_parser__match_token(ctx, TokenCppKind_Semicolon)){ + break; + } + if (config_parser__recognize_token(ctx, TokenCppKind_EOF)){ + break; + } + config_parser__advance_to_next(ctx); + } +} + +function i32* +config_parser__version(Config_Parser *ctx){ + require(config_parser__match_text_lit(ctx, "version")); + + if (!config_parser__match_token(ctx, TokenCppKind_ParenOp)){ + config_parser__log_error(ctx, "expected token '(' for version specifier: 'version(#)'"); + config_parser__recover_parse(ctx); + return(0); + } + + if (!config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ + config_parser__log_error(ctx, "expected an integer constant for version specifier: 'version(#)'"); + config_parser__recover_parse(ctx); + return(0); + } + + Config_Integer value = config_parser__get_int(ctx); + config_parser__advance_to_next(ctx); + + if (!config_parser__match_token(ctx, TokenCppKind_ParenCl)){ + config_parser__log_error(ctx, "expected token ')' for version specifier: 'version(#)'"); + config_parser__recover_parse(ctx); + return(0); + } + + if (!config_parser__match_token(ctx, TokenCppKind_Semicolon)){ + config_parser__log_error(ctx, "expected token ';' for version specifier: 'version(#)'"); + config_parser__recover_parse(ctx); + return(0); + } + + i32 *ptr = push_array(ctx->arena, i32, 1); + *ptr = value.integer; + return(ptr); +} + +function Config_Assignment* +config_parser__assignment(Config_Parser *ctx){ + u8 *pos = config_parser__get_pos(ctx); + + Config_LValue *l = config_parser__lvalue(ctx); + if (l == 0){ + config_parser__log_error(ctx, "expected an l-value; l-value formats: 'identifier', 'identifier[#]'"); + config_parser__recover_parse(ctx); + return(0); + } + + if (!config_parser__match_token(ctx, TokenCppKind_Eq)){ + config_parser__log_error(ctx, "expected token '=' for assignment: 'l-value = r-value;'"); + config_parser__recover_parse(ctx); + return(0); + } + + Config_RValue *r = config_parser__rvalue(ctx); + if (r == 0){ + config_parser__log_error(ctx, "expected an r-value; r-value formats:\n" + "\tconstants (true, false, integers, hexadecimal integers, strings, characters)\n" + "\tany l-value that is set in the file\n" + "\tcompound: '{ compound-element, compound-element, compound-element ...}'\n" + "\ta compound-element is an r-value, and can have a layout specifier\n" + "\tcompound-element with layout specifier: .name = r-value, .integer = r-value"); + config_parser__recover_parse(ctx); + return(0); + } + + if (!config_parser__match_token(ctx, TokenCppKind_Semicolon)){ + config_parser__log_error(ctx, "expected token ';' for assignment: 'l-value = r-value;'"); + config_parser__recover_parse(ctx); + return(0); + } + + Config_Assignment *assignment = push_array_zero(ctx->arena, Config_Assignment, 1); + assignment->pos = pos; + assignment->l = l; + assignment->r = r; + return(assignment); +} + +function Config_LValue* +config_parser__lvalue(Config_Parser *ctx){ + require(config_parser__recognize_token(ctx, TokenCppKind_Identifier)); + String_Const_u8 identifier = config_parser__get_lexeme(ctx); + config_parser__advance_to_next(ctx); + + i32 index = 0; + if (config_parser__match_token(ctx, TokenCppKind_BrackOp)){ + require(config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)); + Config_Integer value = config_parser__get_int(ctx); + index = value.integer; + config_parser__advance_to_next(ctx); + require(config_parser__match_token(ctx, TokenCppKind_BrackCl)); + } + + Config_LValue *lvalue = push_array_zero(ctx->arena, Config_LValue, 1); + lvalue->identifier = identifier; + lvalue->index = index; + return(lvalue); +} + +function Config_RValue* +config_parser__rvalue(Config_Parser *ctx){ + Config_RValue *rvalue = 0; + if (config_parser__recognize_token(ctx, TokenCppKind_Identifier)){ + Config_LValue *l = config_parser__lvalue(ctx); + require(l != 0); + rvalue = push_array_zero(ctx->arena, Config_RValue, 1); + rvalue->type = ConfigRValueType_LValue; + rvalue->lvalue = l; + } + else if (config_parser__recognize_token(ctx, TokenCppKind_BraceOp)){ + config_parser__advance_to_next(ctx); + Config_Compound *compound = config_parser__compound(ctx); + require(compound != 0); + rvalue = push_array_zero(ctx->arena, Config_RValue, 1); + rvalue->type = ConfigRValueType_Compound; + rvalue->compound = compound; + } + else if (config_parser__recognize_boolean(ctx)){ + b32 b = config_parser__get_boolean(ctx); + config_parser__advance_to_next(ctx); + rvalue = push_array_zero(ctx->arena, Config_RValue, 1); + rvalue->type = ConfigRValueType_Boolean; + rvalue->boolean = b; + } + else if (config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ + Config_Integer value = config_parser__get_int(ctx); + config_parser__advance_to_next(ctx); + rvalue = push_array_zero(ctx->arena, Config_RValue, 1); + rvalue->type = ConfigRValueType_Integer; + if (value.is_signed){ + rvalue->integer = value.integer; + } + else{ + rvalue->uinteger = value.uinteger; + } + } + else if (config_parser__recognize_token(ctx, TokenCppKind_LiteralString)){ + String_Const_u8 s = config_parser__get_lexeme(ctx); + config_parser__advance_to_next(ctx); + s = string_chop(string_skip(s, 1), 1); + String_Const_u8 interpreted = string_interpret_escapes(ctx->arena, s); + rvalue = push_array_zero(ctx->arena, Config_RValue, 1); + rvalue->type = ConfigRValueType_String; + rvalue->string = interpreted; + } + else if (config_parser__recognize_token(ctx, TokenCppKind_LiteralCharacter)){ + String_Const_u8 s = config_parser__get_lexeme(ctx); + config_parser__advance_to_next(ctx); + s = string_chop(string_skip(s, 1), 1); + String_Const_u8 interpreted = string_interpret_escapes(ctx->arena, s); + rvalue = push_array_zero(ctx->arena, Config_RValue, 1); + rvalue->type = ConfigRValueType_Character; + rvalue->character = string_get_character(interpreted, 0); + } + return(rvalue); +} + +function void +config_parser__compound__check(Config_Parser *ctx, Config_Compound *compound){ + b32 implicit_index_allowed = true; + for (Config_Compound_Element *node = compound->first; + node != 0; + node = node->next){ + if (node->l.type != ConfigLayoutType_Unset){ + implicit_index_allowed = false; + } + else if (!implicit_index_allowed){ + config_parser__log_error_pos(ctx, node->l.pos, + "encountered unlabeled member after one or more labeled members"); + } + } +} + +function Config_Compound* +config_parser__compound(Config_Parser *ctx){ + Config_Compound_Element *first = 0; + Config_Compound_Element *last = 0; + i32 count = 0; + + Config_Compound_Element *element = config_parser__element(ctx); + require(element != 0); + zdll_push_back(first, last, element); + count += 1; + + for (;config_parser__match_token(ctx, TokenCppKind_Comma);){ + if (config_parser__recognize_token(ctx, TokenCppKind_BraceCl)){ + break; + } + element = config_parser__element(ctx); + require(element != 0); + zdll_push_back(first, last, element); + count += 1; + } + + require(config_parser__match_token(ctx, TokenCppKind_BraceCl)); + + Config_Compound *compound = push_array(ctx->arena, Config_Compound, 1); + block_zero_struct(compound); + compound->first = first; + compound->last = last; + compound->count = count; + config_parser__compound__check(ctx, compound); + return(compound); +} + +function Config_Compound_Element* +config_parser__element(Config_Parser *ctx){ + Config_Layout layout = {}; + layout.pos = config_parser__get_pos(ctx); + if (config_parser__match_token(ctx, TokenCppKind_Dot)){ + if (config_parser__recognize_token(ctx, TokenCppKind_Identifier)){ + layout.type = ConfigLayoutType_Identifier; + layout.identifier = config_parser__get_lexeme(ctx); + config_parser__advance_to_next(ctx); + } + else if (config_parser__recognize_base_token(ctx, TokenBaseKind_LiteralInteger)){ + layout.type = ConfigLayoutType_Integer; + Config_Integer value = config_parser__get_int(ctx); + layout.integer = value.integer; + config_parser__advance_to_next(ctx); + } + else{ + return(0); + } + require(config_parser__match_token(ctx, TokenCppKind_Eq)); + } + Config_RValue *rvalue = config_parser__rvalue(ctx); + require(rvalue != 0); + Config_Compound_Element *element = push_array(ctx->arena, Config_Compound_Element, 1); + block_zero_struct(element); + element->l = layout; + element->r = rvalue; + return(element); +} + +//////////////////////////////// + +function Config_Error* +config_add_error(Arena *arena, Config *config, u8 *pos, char *error_text){ + return(config_error_push(arena, &config->errors, config->file_name, pos, + error_text)); +} + +//////////////////////////////// + +function Config_Assignment* +config_lookup_assignment(Config *config, String_Const_u8 var_name, i32 subscript){ + Config_Assignment *assignment = 0; + for (assignment = config->first; + assignment != 0; + assignment = assignment->next){ + Config_LValue *l = assignment->l; + if (l != 0 && string_match(l->identifier, var_name) && l->index == subscript){ + break; + } + } + return(assignment); +} + +function Config_Get_Result +config_var(Config *config, String_Const_u8 var_name, i32 subscript); + +function Config_Get_Result +config_evaluate_rvalue(Config *config, Config_Assignment *assignment, Config_RValue *r){ + Config_Get_Result result = {}; + if (r != 0 && !assignment->visited){ + if (r->type == ConfigRValueType_LValue){ + assignment->visited = true; + Config_LValue *l = r->lvalue; + result = config_var(config, l->identifier, l->index); + assignment->visited = false; + } + else{ + result.success = true; + result.pos = assignment->pos; + result.type = r->type; + switch (r->type){ + case ConfigRValueType_Boolean: + { + result.boolean = r->boolean; + }break; + + case ConfigRValueType_Integer: + { + result.integer = r->integer; + }break; + + case ConfigRValueType_String: + { + result.string = r->string; + }break; + + case ConfigRValueType_Character: + { + result.character = r->character; + }break; + + case ConfigRValueType_Compound: + { + result.compound = r->compound; + }break; + } + } + } + return(result); +} + +function Config_Get_Result +config_var(Config *config, String_Const_u8 var_name, i32 subscript){ + Config_Get_Result result = {}; + Config_Assignment *assignment = config_lookup_assignment(config, var_name, subscript); + if (assignment != 0){ + result = config_evaluate_rvalue(config, assignment, assignment->r); + } + return(result); +} + +function Config_Get_Result +config_compound_member(Config *config, Config_Compound *compound, String_Const_u8 var_name, i32 index){ + Config_Get_Result result = {}; + i32 implicit_index = 0; + b32 implicit_index_is_valid = true; + for (Config_Compound_Element *element = compound->first; + element != 0; + element = element->next, implicit_index += 1){ + b32 element_matches_query = false; + switch (element->l.type){ + case ConfigLayoutType_Unset: + { + if (implicit_index_is_valid && index == implicit_index){ + element_matches_query = true; + } + }break; + + case ConfigLayoutType_Identifier: + { + implicit_index_is_valid = false; + if (string_match(element->l.identifier, var_name)){ + element_matches_query = true; + } + }break; + + case ConfigLayoutType_Integer: + { + implicit_index_is_valid = false; + if (element->l.integer == index){ + element_matches_query = true; + } + }break; + } + if (element_matches_query){ + Config_Assignment dummy_assignment = {}; + dummy_assignment.pos = element->l.pos; + result = config_evaluate_rvalue(config, &dummy_assignment, element->r); + break; + } + } + return(result); +} + +function Config_Iteration_Step_Result +typed_array_iteration_step(Config *parsed, Config_Compound *compound, Config_RValue_Type type, i32 index); + +function i32 +typed_array_get_count(Config *parsed, Config_Compound *compound, Config_RValue_Type type); + +function Config_Get_Result_List +typed_array_reference_list(Arena *arena, Config *parsed, Config_Compound *compound, Config_RValue_Type type); + +#define config_fixed_string_var(c,v,s,o,a) config_placed_string_var((c),(v),(s),(o),(a),sizeof(a)) + +//////////////////////////////// + +function b32 +config_has_var(Config *config, String_Const_u8 var_name, i32 subscript){ + Config_Get_Result result = config_var(config, var_name, subscript); + return(result.success && result.type == ConfigRValueType_NoType); +} + +function b32 +config_has_var(Config *config, char *var_name, i32 subscript){ + return(config_has_var(config, SCu8(var_name), subscript)); +} + +function b32 +config_bool_var(Config *config, String_Const_u8 var_name, i32 subscript, b32* var_out){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = (result.success && result.type == ConfigRValueType_Boolean); + if (success){ + *var_out = result.boolean; + } + return(success); +} +function b32 +config_bool_var(Config *config, String_Const_u8 var_name, i32 subscript, b8 *var_out){ + b32 temp = false; + b32 success = config_bool_var(config, var_name, subscript, &temp); + if (success){ + *var_out = (temp != false); + } + return(success); +} +function b32 +config_bool_var(Config *config, char *var_name, i32 subscript, b32* var_out){ + return(config_bool_var(config, SCu8(var_name), subscript, var_out)); +} +function b32 +config_bool_var(Config *config, char* var_name, i32 subscript, b8 *var_out){ + b32 temp = false; + b32 success = config_bool_var(config, SCu8(var_name), subscript, &temp); + if (success){ + *var_out = (temp != false); + } + return(success); +} + +function b32 +config_int_var(Config *config, String_Const_u8 var_name, i32 subscript, i32* var_out){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = result.success && result.type == ConfigRValueType_Integer; + if (success){ + *var_out = result.integer; + } + return(success); +} + +function b32 +config_int_var(Config *config, char *var_name, i32 subscript, i32* var_out){ + return(config_int_var(config, SCu8(var_name), subscript, var_out)); +} + +function b32 +config_uint_var(Config *config, String_Const_u8 var_name, i32 subscript, u32* var_out){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = result.success && result.type == ConfigRValueType_Integer; + if (success){ + *var_out = result.uinteger; + } + return(success); +} + +function b32 +config_uint_var(Config *config, char *var_name, i32 subscript, u32* var_out){ + return(config_uint_var(config, SCu8(var_name), subscript, var_out)); +} + +function b32 +config_string_var(Config *config, String_Const_u8 var_name, i32 subscript, String_Const_u8* var_out){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = result.success && result.type == ConfigRValueType_String; + if (success){ + *var_out = result.string; + } + return(success); +} + +function b32 +config_string_var(Config *config, char *var_name, i32 subscript, String_Const_u8* var_out){ + return(config_string_var(config, SCu8(var_name), subscript, var_out)); +} + +function b32 +config_placed_string_var(Config *config, String_Const_u8 var_name, i32 subscript, String_Const_u8* var_out, u8 *space, u64 space_size){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = (result.success && result.type == ConfigRValueType_String); + if (success){ + u64 size = result.string.size; + size = clamp_top(size, space_size); + block_copy(space, result.string.str, size); + *var_out = SCu8(space, size); + } + return(success); +} + +function b32 +config_placed_string_var(Config *config, char *var_name, i32 subscript, String_Const_u8* var_out, u8 *space, u64 space_size){ + return(config_placed_string_var(config, SCu8(var_name), subscript, var_out, space, space_size)); +} + +function b32 +config_char_var(Config *config, String_Const_u8 var_name, i32 subscript, char* var_out){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = result.success && result.type == ConfigRValueType_Character; + if (success){ + *var_out = result.character; + } + return(success); +} + +function b32 +config_char_var(Config *config, char *var_name, i32 subscript, char* var_out){ + return(config_char_var(config, SCu8(var_name), subscript, var_out)); +} + +function b32 +config_compound_var(Config *config, String_Const_u8 var_name, i32 subscript, Config_Compound** var_out){ + Config_Get_Result result = config_var(config, var_name, subscript); + b32 success = (result.success && result.type == ConfigRValueType_Compound); + if (success){ + *var_out = result.compound; + } + return(success); +} + +function b32 +config_compound_var(Config *config, char *var_name, i32 subscript, Config_Compound** var_out){ + return(config_compound_var(config, SCu8(var_name), subscript, var_out)); +} + +function b32 +config_compound_has_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = result.success && result.type == ConfigRValueType_NoType; + return(success); +} + +function b32 +config_compound_has_member(Config *config, Config_Compound *compound, + char *var_name, i32 index){ + return(config_compound_has_member(config, compound, SCu8(var_name), index)); +} + +function b32 +config_compound_bool_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, b32* var_out){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = result.success && result.type == ConfigRValueType_Boolean; + if (success){ + *var_out = result.boolean; + } + return(success); +} + +function b32 +config_compound_bool_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, b32* var_out){ + return(config_compound_bool_member(config, compound, SCu8(var_name), index, var_out)); +} + +function b32 +config_compound_int_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, i32* var_out){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = result.success && result.type == ConfigRValueType_Integer; + if (success){ + *var_out = result.integer; + } + return(success); +} + +function b32 +config_compound_int_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, i32* var_out){ + return(config_compound_int_member(config, compound, SCu8(var_name), index, var_out)); +} + +function b32 +config_compound_uint_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, u32* var_out){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = result.success && result.type == ConfigRValueType_Integer; + if (success){ + *var_out = result.uinteger; + } + return(success); +} + +function b32 +config_compound_uint_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, u32* var_out){ + return(config_compound_uint_member(config, compound, SCu8(var_name), index, var_out)); +} + +function b32 +config_compound_string_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, String_Const_u8* var_out){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = (result.success && result.type == ConfigRValueType_String); + if (success){ + *var_out = result.string; + } + return(success); +} + +function b32 +config_compound_string_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, String_Const_u8* var_out){ + return(config_compound_string_member(config, compound, SCu8(var_name), index, var_out)); +} + +function b32 +config_compound_placed_string_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, String_Const_u8* var_out, u8 *space, u64 space_size){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = (result.success && result.type == ConfigRValueType_String); + if (success){ + u64 size = result.string.size; + size = clamp_top(size, space_size); + block_copy(space, result.string.str, size); + *var_out = SCu8(space, size); + } + return(success); +} + +function b32 +config_compound_placed_string_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, String_Const_u8* var_out, u8 *space, u64 space_size){ + return(config_compound_placed_string_member(config, compound, SCu8(var_name), index, var_out, space, space_size)); +} + +function b32 +config_compound_char_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, char* var_out){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = result.success && result.type == ConfigRValueType_Character; + if (success){ + *var_out = result.character; + } + return(success); +} + +function b32 +config_compound_char_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, char* var_out){ + return(config_compound_char_member(config, compound, SCu8(var_name), index, var_out)); +} + +function b32 +config_compound_compound_member(Config *config, Config_Compound *compound, + String_Const_u8 var_name, i32 index, Config_Compound** var_out){ + Config_Get_Result result = config_compound_member(config, compound, var_name, index); + b32 success = result.success && result.type == ConfigRValueType_Compound; + if (success){ + *var_out = result.compound; + } + return(success); +} + +function b32 +config_compound_compound_member(Config *config, Config_Compound *compound, + char *var_name, i32 index, Config_Compound** var_out){ + return(config_compound_compound_member(config, compound, SCu8(var_name), index, var_out)); +} + +function Iteration_Step_Result +typed_has_array_iteration_step(Config *config, Config_Compound *compound, i32 index){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_NoType, index); + return(result.step); +} + +function Iteration_Step_Result +typed_bool_array_iteration_step(Config *config, Config_Compound *compound, i32 index, b32* var_out){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Boolean, index); + b32 success = (result.step == Iteration_Good); + if (success){ + *var_out = result.get.boolean; + } + return(result.step); +} + +function Iteration_Step_Result +typed_int_array_iteration_step(Config *config, Config_Compound *compound, i32 index, i32* var_out){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Integer, index); + b32 success = (result.step == Iteration_Good); + if (success){ + *var_out = result.get.integer; + } + return(result.step); +} + +function Iteration_Step_Result +typed_uint_array_iteration_step(Config *config, Config_Compound *compound, i32 index, u32* var_out){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Integer, index); + b32 success = (result.step == Iteration_Good); + if (success){ + *var_out = result.get.uinteger; + } + return(result.step); +} + +function Iteration_Step_Result +typed_string_array_iteration_step(Config *config, Config_Compound *compound, i32 index, String_Const_u8* var_out){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_String, index); + b32 success = (result.step == Iteration_Good); + if (success){ + *var_out = result.get.string; + } + return(result.step); +} + +function Iteration_Step_Result +typed_placed_string_array_iteration_step(Config *config, Config_Compound *compound, i32 index, String_Const_u8* var_out, u8 *space, u64 space_size){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_String, index); + b32 success = (result.step == Iteration_Good); + if (success){ + u64 size = result.get.string.size; + size = clamp_top(size, space_size); + block_copy(space, result.get.string.str, size); + *var_out = SCu8(space, size); + } + return(result.step); +} + +function Iteration_Step_Result +typed_char_array_iteration_step(Config *config, Config_Compound *compound, i32 index, char* var_out){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Character, index); + b32 success = (result.step == Iteration_Good); + if (success){ + *var_out = result.get.character; + } + return(result.step); +} + +function Iteration_Step_Result +typed_compound_array_iteration_step(Config *config, Config_Compound *compound, i32 index, Config_Compound** var_out){ + Config_Iteration_Step_Result result = typed_array_iteration_step(config, compound, ConfigRValueType_Compound, index); + b32 success = (result.step == Iteration_Good); + if (success){ + *var_out = result.get.compound; + } + return(result.step); +} + +function i32 +typed_bool_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_Boolean); + return(count); +} + +function i32 +typed_int_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_Integer); + return(count); +} + +function i32 +typed_float_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_Float); + return(count); +} + +function i32 +typed_string_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_String); + return(count); +} + +function i32 +typed_character_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_Character); + return(count); +} + +function i32 +typed_compound_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_Compound); + return(count); +} + +function i32 +typed_no_type_array_get_count(Config *config, Config_Compound *compound){ + i32 count = typed_array_get_count(config, compound, ConfigRValueType_NoType); + return(count); +} + +function Config_Get_Result_List +typed_bool_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Boolean); + return(list); +} + +function Config_Get_Result_List +typed_int_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Integer); + return(list); +} + +function Config_Get_Result_List +typed_float_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Float); + return(list); +} + +function Config_Get_Result_List +typed_string_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_String); + return(list); +} + +function Config_Get_Result_List +typed_character_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Character); + return(list); +} + +function Config_Get_Result_List +typed_compound_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_Compound); + return(list); +} + +function Config_Get_Result_List +typed_no_type_array_reference_list(Arena *arena, Config *config, Config_Compound *compound){ + Config_Get_Result_List list = typed_array_reference_list(arena, config, compound, ConfigRValueType_NoType); + return(list); +} + +//////////////////////////////// + +function Config_Iteration_Step_Result +typed_array_iteration_step(Config *parsed, Config_Compound *compound, Config_RValue_Type type, i32 index){ + Config_Iteration_Step_Result result = {}; + result.step = Iteration_Quit; + Config_Get_Result get_result = config_compound_member(parsed, compound, string_u8_litexpr("~"), index); + if (get_result.success){ + if (get_result.type == type || type == ConfigRValueType_NoType){ + result.step = Iteration_Good; + result.get = get_result; + } + else{ + result.step = Iteration_Skip; + } + } + return(result); +} + +function i32 +typed_array_get_count(Config *parsed, Config_Compound *compound, Config_RValue_Type type){ + i32 count = 0; + for (i32 i = 0;; ++i){ + Config_Iteration_Step_Result result = typed_array_iteration_step(parsed, compound, type, i); + if (result.step == Iteration_Skip){ + continue; + } + else if (result.step == Iteration_Quit){ + break; + } + count += 1; + } + return(count); +} + +function Config_Get_Result_List +typed_array_reference_list(Arena *arena, Config *parsed, Config_Compound *compound, Config_RValue_Type type){ + Config_Get_Result_List list = {}; + for (i32 i = 0;; ++i){ + Config_Iteration_Step_Result result = typed_array_iteration_step(parsed, compound, type, i); + if (result.step == Iteration_Skip){ + continue; + } + else if (result.step == Iteration_Quit){ + break; + } + Config_Get_Result_Node *node = push_array(arena, Config_Get_Result_Node, 1); + node->result = result.get; + zdll_push_back(list.first, list.last, node); + list.count += 1; + } + return(list); +} + +//////////////////////////////// + +function void +change_mode(Application_Links *app, String_Const_u8 mode){ + fcoder_mode = FCoderMode_Original; + if (string_match(mode, string_u8_litexpr("4coder"))){ + fcoder_mode = FCoderMode_Original; + } + else if (string_match(mode, string_u8_litexpr("notepad-like"))){ + begin_notepad_mode(app); + } + else{ + print_message(app, string_u8_litexpr("Unknown mode.\n")); + } +} + +//////////////////////////////// + +function Token_Array +token_array_from_text(Application_Links *app, Arena *arena, String_Const_u8 data){ + ProfileScope(app, "token array from text"); + Token_List list = lex_full_input_cpp(arena, data); + return(token_array_from_list(arena, &list)); +} + +function Config* +config_from_text(Application_Links *app, Arena *arena, String_Const_u8 file_name, + String_Const_u8 data){ + Config *parsed = 0; + Temp_Memory restore_point = begin_temp(arena); + Token_Array array = token_array_from_text(app, arena, data); + if (array.tokens != 0){ + parsed = config_parse(app, arena, file_name, data, array); + if (parsed == 0){ + end_temp(restore_point); + } + } + return(parsed); +} + +//////////////////////////////// + +function void +config_init_default(Config_Data *config){ + config->user_name = SCu8(config->user_name_space, (u64)0); + + block_zero_struct(&config->code_exts); + + config->mapping = SCu8(config->mapping_space, (u64)0); + config->mode = SCu8(config->mode_space, (u64)0); + + config->use_scroll_bars = false; + config->use_file_bars = true; + config->hide_file_bar_in_ui = true; + config->use_error_highlight = true; + config->use_jump_highlight = true; + config->use_scope_highlight = true; + config->use_paren_helper = true; + config->use_comment_keyword = true; + config->lister_whole_word_backspace_when_modified = false; + config->show_line_number_margins = false; + + config->enable_virtual_whitespace = true; + config->enable_code_wrapping = true; + config->automatically_indent_text_on_save = true; + config->automatically_save_changes_on_build = true; + config->automatically_load_project = false; + + config->indent_with_tabs = false; + config->indent_width = 4; + + config->default_theme_name = SCu8(config->default_theme_name_space, sizeof("4coder") - 1); + block_copy(config->default_theme_name.str, "4coder", config->default_theme_name.size); + config->highlight_line_at_cursor = true; + + config->default_font_name = SCu8(config->default_font_name_space, (u64)0); + config->default_font_size = 16; + config->default_font_hinting = false; + + config->default_compiler_bat = SCu8(config->default_compiler_bat_space, 2); + block_copy(config->default_compiler_bat.str, "cl", 2); + + config->default_flags_bat = SCu8(config->default_flags_bat_space, (u64)0); + + config->default_compiler_sh = SCu8(config->default_compiler_sh_space, 3); + block_copy(config->default_compiler_sh.str, "g++", 3); + + config->default_flags_sh = SCu8(config->default_flags_sh_space, (u64)0); + + config->lalt_lctrl_is_altgr = false; +} + +function Config* +config_parse__data(Application_Links *app, Arena *arena, String_Const_u8 file_name, + String_Const_u8 data, Config_Data *config){ + config_init_default(config); + + b32 success = false; + + Config *parsed = config_from_text(app, arena, file_name, data); + if (parsed != 0){ + success = true; + + config_fixed_string_var(parsed, "user_name", 0, + &config->user_name, config->user_name_space); + + String_Const_u8 str = {}; + if (config_string_var(parsed, "treat_as_code", 0, &str)){ + config->code_exts = + parse_extension_line_to_extension_list(app, arena, str); + } + + config_fixed_string_var(parsed, "mapping", 0, &config->mapping, config->mapping_space); + config_fixed_string_var(parsed, "mode", 0, &config->mode, config->mode_space); + + config_bool_var(parsed, "use_scroll_bars", 0, &config->use_scroll_bars); + config_bool_var(parsed, "use_file_bars", 0, &config->use_file_bars); + config_bool_var(parsed, "hide_file_bar_in_ui", 0, &config->hide_file_bar_in_ui); + config_bool_var(parsed, "use_error_highlight", 0, &config->use_error_highlight); + config_bool_var(parsed, "use_jump_highlight", 0, &config->use_jump_highlight); + config_bool_var(parsed, "use_scope_highlight", 0, &config->use_scope_highlight); + config_bool_var(parsed, "use_paren_helper", 0, &config->use_paren_helper); + config_bool_var(parsed, "use_comment_keyword", 0, &config->use_comment_keyword); + config_bool_var(parsed, "lister_whole_word_backspace_when_modified", 0, &config->lister_whole_word_backspace_when_modified); + config_bool_var(parsed, "show_line_number_margins", 0, &config->show_line_number_margins); + + + config_bool_var(parsed, "enable_virtual_whitespace", 0, &config->enable_virtual_whitespace); + config_bool_var(parsed, "enable_code_wrapping", 0, &config->enable_code_wrapping); + config_bool_var(parsed, "automatically_indent_text_on_save", 0, &config->automatically_indent_text_on_save); + config_bool_var(parsed, "automatically_save_changes_on_build", 0, &config->automatically_save_changes_on_build); + config_bool_var(parsed, "automatically_load_project", 0, &config->automatically_load_project); + + config_bool_var(parsed, "indent_with_tabs", 0, &config->indent_with_tabs); + config_int_var(parsed, "indent_width", 0, &config->indent_width); + + config_fixed_string_var(parsed, "default_theme_name", 0, + &config->default_theme_name, config->default_theme_name_space); + config_bool_var(parsed, "highlight_line_at_cursor", 0, &config->highlight_line_at_cursor); + + config_fixed_string_var(parsed, "default_font_name", 0, + &config->default_font_name, config->default_font_name_space); + config_int_var(parsed, "default_font_size", 0, &config->default_font_size); + config_bool_var(parsed, "default_font_hinting", 0, &config->default_font_hinting); + + config_fixed_string_var(parsed, "default_compiler_bat", 0, + &config->default_compiler_bat, config->default_compiler_bat_space); + config_fixed_string_var(parsed, "default_flags_bat", 0, + &config->default_flags_bat, config->default_flags_bat_space); + config_fixed_string_var(parsed, "default_compiler_sh", 0, + &config->default_compiler_sh, config->default_compiler_sh_space); + config_fixed_string_var(parsed, "default_flags_sh", 0, + &config->default_flags_sh, config->default_flags_sh_space); + + config_bool_var(parsed, "lalt_lctrl_is_altgr", 0, &config->lalt_lctrl_is_altgr); + } + + if (!success){ + config_init_default(config); + } + + return(parsed); +} + +function Config* +config_parse__file_handle(Application_Links *app, Arena *arena, + String_Const_u8 file_name, FILE *file, Config_Data *config){ + Config *parsed = 0; + Data data = dump_file_handle(arena, file); + if (data.data != 0){ + parsed = config_parse__data(app, arena, file_name, SCu8(data), config); + } + else{ + config_init_default(config); + } + return(parsed); +} + +function Config* +config_parse__file_name(Application_Links *app, Arena *arena, char *file_name, Config_Data *config){ + Config *parsed = 0; + b32 success = false; + FILE *file = open_file_try_current_path_then_binary_path(app, file_name); + if (file != 0){ + Data data = dump_file_handle(arena, file); + fclose(file); + if (data.data != 0){ + parsed = config_parse__data(app, arena, SCu8(file_name), SCu8(data), + config); + success = true; + } + } + if (!success){ + config_init_default(config); + } + return(parsed); +} + +function Config* +theme_parse__data(Application_Links *app, Arena *arena, String_Const_u8 file_name, String_Const_u8 data, Arena *color_arena, Color_Table *color_table){ + Config *parsed = config_from_text(app, arena, file_name, data); + if (parsed != 0){ + for (Config_Assignment *node = parsed->first; + node != 0; + node = node->next){ + Scratch_Block scratch(app); + Config_LValue *l = node->l; + String_Const_u8 l_name = push_string_copy(scratch, l->identifier); + Managed_ID id = managed_id_get(app, string_u8_litexpr("colors"), l_name); + if (id != 0){ + u32 color = 0; + if (config_uint_var(parsed, l_name, 0, &color)){ + color_table->arrays[id%color_table->count] = make_colors(color_arena, color); + } + else{ + Config_Compound *compound = 0; + if (config_compound_var(parsed, l_name, 0, &compound)){ + local_persist u32 color_array[256]; + i32 counter = 0; + for (i32 i = 0;; i += 1){ + Config_Iteration_Step_Result result = typed_array_iteration_step(parsed, compound, ConfigRValueType_Integer, i); + if (result.step == Iteration_Skip){ + continue; + } + else if (result.step == Iteration_Quit){ + break; + } + + color_array[counter] = result.get.uinteger; + counter += 1; + if (counter == 256){ + break; + } + } + + color_table->arrays[id%color_table->count] = make_colors(color_arena, color_array, counter); + } + } + } + + } + } + return(parsed); +} + +function Config* +theme_parse__file_handle(Application_Links *app, Arena *arena, String_Const_u8 file_name, FILE *file, Arena *color_arena, Color_Table *color_table){ + Data data = dump_file_handle(arena, file); + Config *parsed = 0; + if (data.data != 0){ + parsed = theme_parse__data(app, arena, file_name, SCu8(data), color_arena, color_table); + } + return(parsed); +} + +function Config* +theme_parse__file_name(Application_Links *app, Arena *arena, char *file_name, Arena *color_arena, Color_Table *color_table){ + Config *parsed = 0; + FILE *file = open_file_try_current_path_then_binary_path(app, file_name); + if (file != 0){ + Data data = dump_file_handle(arena, file); + fclose(file); + parsed = theme_parse__data(app, arena, SCu8(file_name), SCu8(data), color_arena, color_table); + } + if (parsed == 0){ + Scratch_Block scratch(app); + String_Const_u8 str = push_u8_stringf(arena, "Did not find %s, theme not loaded", file_name); + print_message(app, str); + } + return(parsed); +} + +//////////////////////////////// + +function void +config_feedback_bool(Arena *arena, List_String_Const_u8 *list, char *name, b32 val){ + string_list_pushf(arena, list, "%s = %s;\n", name, (char*)(val?"true":"false")); +} + +function void +config_feedback_string(Arena *arena, List_String_Const_u8 *list, char *name, String_Const_u8 val){ + val.size = clamp_bot(0, val.size); + string_list_pushf(arena, list, "%s = \"%.*s\";\n", name, string_expand(val)); +} + +function void +config_feedback_string(Arena *arena, List_String_Const_u8 *list, char *name, char *val){ + string_list_pushf(arena, list, "%s = \"%s\";\n", name, val); +} + +function void +config_feedback_extension_list(Arena *arena, List_String_Const_u8 *list, char *name, String_Const_u8_Array *extensions){ + string_list_pushf(arena, list, "%s = \"", name); + for (i32 i = 0; i < extensions->count; ++i){ + String_Const_u8 ext = extensions->strings[i]; + string_list_pushf(arena, list, ".%.*s", string_expand(ext)); + } + string_list_push_u8_lit(arena, list, "\";\n"); +} + +function void +config_feedback_int(Arena *arena, List_String_Const_u8 *list, char *name, i32 val){ + string_list_pushf(arena, list, "%s = %d;\n", name, val); +} + +//////////////////////////////// + +function void +load_config_and_apply(Application_Links *app, Arena *out_arena, Config_Data *config, + i32 override_font_size, b32 override_hinting){ + Scratch_Block scratch(app); + + linalloc_clear(out_arena); + Config *parsed = config_parse__file_name(app, out_arena, "config.4coder", config); + + if (parsed != 0){ + // Top + print_message(app, string_u8_litexpr("Loaded config file:\n")); + + // Errors + String_Const_u8 error_text = config_stringize_errors(app, scratch, parsed); + if (error_text.str != 0){ + print_message(app, error_text); + } + } + else{ + print_message(app, string_u8_litexpr("Using default config:\n")); + Face_Description description = get_face_description(app, 0); + if (description.font.file_name.str != 0){ + u64 size = Min(description.font.file_name.size, sizeof(config->default_font_name_space)); + block_copy(config->default_font_name_space, description.font.file_name.str, size); + config->default_font_name.size = size; + } + } + + if (config->default_font_name.size == 0){ +#define M "liberation-mono.ttf" + block_copy(config->default_font_name_space, M, sizeof(M) - 1); + config->default_font_name.size = sizeof(M) - 1; +#undef M + } + + { + // Values + Temp_Memory temp2 = begin_temp(scratch); + List_String_Const_u8 list = {}; + + config_feedback_string(scratch, &list, "user_name", config->user_name); + config_feedback_extension_list(scratch, &list, "treat_as_code", &config->code_exts); + + config_feedback_string(scratch, &list, "mapping", config->mapping); + config_feedback_string(scratch, &list, "mode", config->mode); + + config_feedback_bool(scratch, &list, "use_scroll_bars", config->use_scroll_bars); + config_feedback_bool(scratch, &list, "use_file_bars", config->use_file_bars); + config_feedback_bool(scratch, &list, "hide_file_bar_in_ui", config->hide_file_bar_in_ui); + config_feedback_bool(scratch, &list, "use_error_highlight", config->use_error_highlight); + config_feedback_bool(scratch, &list, "use_jump_highlight", config->use_jump_highlight); + config_feedback_bool(scratch, &list, "use_scope_highlight", config->use_scope_highlight); + config_feedback_bool(scratch, &list, "use_paren_helper", config->use_paren_helper); + config_feedback_bool(scratch, &list, "use_comment_keyword", config->use_comment_keyword); + config_feedback_bool(scratch, &list, "lister_whole_word_backspace_when_modified", config->lister_whole_word_backspace_when_modified); + config_feedback_bool(scratch, &list, "show_line_number_margins", config->show_line_number_margins); + + config_feedback_bool(scratch, &list, "enable_virtual_whitespace", config->enable_virtual_whitespace); + config_feedback_bool(scratch, &list, "enable_code_wrapping", config->enable_code_wrapping); + config_feedback_bool(scratch, &list, "automatically_indent_text_on_save", config->automatically_indent_text_on_save); + config_feedback_bool(scratch, &list, "automatically_save_changes_on_build", config->automatically_save_changes_on_build); + config_feedback_bool(scratch, &list, "automatically_load_project", config->automatically_load_project); + + config_feedback_bool(scratch, &list, "indent_with_tabs", config->indent_with_tabs); + config_feedback_int(scratch, &list, "indent_width", config->indent_width); + + config_feedback_string(scratch, &list, "default_theme_name", config->default_theme_name); + config_feedback_bool(scratch, &list, "highlight_line_at_cursor", config->highlight_line_at_cursor); + + config_feedback_string(scratch, &list, "default_font_name", config->default_font_name); + config_feedback_int(scratch, &list, "default_font_size", config->default_font_size); + config_feedback_bool(scratch, &list, "default_font_hinting", config->default_font_hinting); + + config_feedback_string(scratch, &list, "default_compiler_bat", config->default_compiler_bat); + config_feedback_string(scratch, &list, "default_flags_bat", config->default_flags_bat); + config_feedback_string(scratch, &list, "default_compiler_sh", config->default_compiler_sh); + config_feedback_string(scratch, &list, "default_flags_sh", config->default_flags_sh); + + config_feedback_bool(scratch, &list, "lalt_lctrl_is_altgr", config->lalt_lctrl_is_altgr); + + string_list_push_u8_lit(scratch, &list, "\n"); + String_Const_u8 message = string_list_flatten(scratch, list); + print_message(app, message); + end_temp(temp2); + } + + // Apply config + setup_built_in_mapping(app, config->mapping, &framework_mapping, mapid_global, mapid_file, mapid_code); + change_mode(app, config->mode); + global_set_setting(app, GlobalSetting_LAltLCtrlIsAltGr, config->lalt_lctrl_is_altgr); + + Color_Table *colors = get_color_table_by_name(config->default_theme_name); + set_active_color(colors); + + Face_Description description = {}; + if (override_font_size != 0){ + description.parameters.pt_size = override_font_size; + } + else{ + description.parameters.pt_size = config->default_font_size; + } + description.parameters.hinting = config->default_font_hinting || override_hinting; + + description.font.file_name = config->default_font_name; + if (!modify_global_face_by_description(app, description)){ + description.font.file_name = get_file_path_in_fonts_folder(scratch, config->default_font_name); + modify_global_face_by_description(app, description); + } +} + +function void +load_theme_file_into_live_set(Application_Links *app, char *file_name){ + Arena *arena = &global_theme_arena; + Color_Table color_table = make_color_table(app, arena); + Scratch_Block scratch(app); + Config *config = theme_parse__file_name(app, scratch, file_name, arena, &color_table); + String_Const_u8 error_text = config_stringize_errors(app, scratch, config); + print_message(app, error_text); + + String_Const_u8 name = SCu8(file_name); + name = string_front_of_path(name); + if (string_match(string_postfix(name, 7), string_u8_litexpr(".4coder"))){ + name = string_chop(name, 7); + } + save_theme(color_table, name); +} + +function void +load_folder_of_themes_into_live_set(Application_Links *app, String_Const_u8 path){ + Scratch_Block scratch(app, Scratch_Share); + + File_List list = system_get_file_list(scratch, path); + for (File_Info **ptr = list.infos, **end = list.infos + list.count; + ptr < end; + ptr += 1){ + File_Info *info = *ptr; + if (!HasFlag(info->attributes.flags, FileAttribute_IsDirectory)){ + String_Const_u8 name = info->file_name; + Temp_Memory_Block temp(scratch); + String_Const_u8 full_name = push_u8_stringf(scratch, "%.*s/%.*s", + string_expand(path), + string_expand(name)); + load_theme_file_into_live_set(app, (char*)full_name.str); + } + } +} + +// BOTTOM + diff --git a/custom/4coder_config.h b/custom/4coder_config.h index 2e868610..a418b4dd 100644 --- a/custom/4coder_config.h +++ b/custom/4coder_config.h @@ -185,6 +185,9 @@ struct Config_Data{ String_Const_u8_Array code_exts; + u8 mapping_space[64]; + String_Const_u8 mapping; + u8 mode_space[64]; String_Const_u8 mode; @@ -203,15 +206,11 @@ struct Config_Data{ b8 enable_code_wrapping; b8 automatically_indent_text_on_save; b8 automatically_save_changes_on_build; - b8 automatically_adjust_wrapping; b8 automatically_load_project; b8 indent_with_tabs; i32 indent_width; - i32 default_wrap_width; - i32 default_min_base_width; - u8 default_theme_name_space[256]; String_Const_u8 default_theme_name; diff --git a/custom/4coder_default_bindings.cpp b/custom/4coder_default_bindings.cpp index 2dc315cd..d4e34071 100644 --- a/custom/4coder_default_bindings.cpp +++ b/custom/4coder_default_bindings.cpp @@ -34,6 +34,30 @@ custom_layer_init(Application_Links *app){ setup_default_mapping(&framework_mapping, mapid_global, mapid_file, mapid_code); } +function void +setup_built_in_mapping(Application_Links *app, String_Const_u8 name, Mapping *mapping, i64 global_id, i64 file_id, i64 code_id){ + Thread_Context *tctx = get_thread_context(app); + if (string_match(name, string_u8_litexpr("default"))){ + mapping_release(tctx, mapping); + mapping_init(tctx, mapping); + setup_default_mapping(mapping, global_id, file_id, code_id); + } + else if (string_match(name, string_u8_litexpr("mac-default"))){ + mapping_release(tctx, mapping); + mapping_init(tctx, mapping); + setup_mac_mapping(mapping, global_id, file_id, code_id); + } + else if (string_match(name, string_u8_litexpr("choose"))){ + mapping_release(tctx, mapping); + mapping_init(tctx, mapping); +#if OS_MAC + setup_mac_mapping(mapping, global_id, file_id, code_id); +#else + setup_default_mapping(mapping, global_id, file_id, code_id); +#endif + } +} + #endif //FCODER_DEFAULT_BINDINGS // BOTTOM diff --git a/custom/4coder_default_framework.h b/custom/4coder_default_framework.h index b1daa3e2..be49d9c7 100644 --- a/custom/4coder_default_framework.h +++ b/custom/4coder_default_framework.h @@ -114,6 +114,11 @@ struct Fade_Range_List{ i32 count; }; +//////////////////////////////// + +function void +setup_built_in_mapping(Application_Links *app, String_Const_u8 name, Mapping *mapping, i64 global_id, i64 file_id, i64 code_id); + #endif // BOTTOM diff --git a/custom/4coder_mac_map.cpp b/custom/4coder_mac_map.cpp index 26844ee2..305ff07e 100644 --- a/custom/4coder_mac_map.cpp +++ b/custom/4coder_mac_map.cpp @@ -52,7 +52,7 @@ setup_mac_mapping(Mapping *mapping, i64 global_id, i64 file_id, i64 code_id){ Bind(project_fkey_command, KeyCode_F14); Bind(project_fkey_command, KeyCode_F15); Bind(project_fkey_command, KeyCode_F16); - Bind(exit_4coder, KeyCode_F4, KeyCode_Control); + Bind(exit_4coder, KeyCode_F4, KeyCode_Alt); BindMouseWheel(mouse_wheel_scroll); BindMouseWheel(mouse_wheel_change_face_size, KeyCode_Command); @@ -79,13 +79,13 @@ setup_mac_mapping(Mapping *mapping, i64 global_id, i64 file_id, i64 code_id){ Bind(move_down_to_blank_line_end, KeyCode_Down, KeyCode_Command); Bind(move_left_whitespace_boundary, KeyCode_Left, KeyCode_Command); Bind(move_right_whitespace_boundary, KeyCode_Right, KeyCode_Command); - Bind(move_line_up, KeyCode_Up, KeyCode_Control); - Bind(move_line_down, KeyCode_Down, KeyCode_Control); + Bind(move_line_up, KeyCode_Up, KeyCode_Alt); + Bind(move_line_down, KeyCode_Down, KeyCode_Alt); Bind(backspace_alpha_numeric_boundary, KeyCode_Backspace, KeyCode_Command); Bind(delete_alpha_numeric_boundary, KeyCode_Delete, KeyCode_Command); Bind(snipe_backward_whitespace_or_token_boundary, KeyCode_Backspace, KeyCode_Control); Bind(snipe_forward_whitespace_or_token_boundary, KeyCode_Delete, KeyCode_Control); - Bind(set_mark, KeyCode_Space, KeyCode_Command); + Bind(set_mark, KeyCode_Space, KeyCode_Control); Bind(replace_in_range, KeyCode_A, KeyCode_Command); Bind(copy, KeyCode_C, KeyCode_Command); Bind(delete_range, KeyCode_D, KeyCode_Command); diff --git a/ship_files/config.4coder b/ship_files/config.4coder index a2846415..cbf71c6b 100644 --- a/ship_files/config.4coder +++ b/ship_files/config.4coder @@ -1,5 +1,5 @@ // Command Mapping -// "" - Leave the bindings unaltered from their startup value. +// "" - Leave the bindings unaltered. // "choose" - Ask 4coder to choose based on platform. // "default" - Use the default keybindings 4coder has always had. // "mac-default" - Use keybindings similar to those found in other Mac applications. @@ -25,9 +25,6 @@ show_line_number_margins = false; treat_as_code = ".cpp.c.hpp.h.cc.cs.java.rs.glsl.m.mm"; enable_virtual_whitespace = true; enable_code_wrapping = true; -automatically_adjust_wrapping = true; -default_wrap_width = 672; -default_min_base_width = 550; // This only applies to code files in code-wrapping mode. // Plain text and code files without virtual-whitespace will not be effected. From af546592ce79075049ed3b86f8e2a330f5da2cc6 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 20 Jan 2020 09:29:32 -0800 Subject: [PATCH 108/128] 4.1.2 --- custom/4coder_version.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom/4coder_version.h b/custom/4coder_version.h index 0b0c6500..7b6ac772 100644 --- a/custom/4coder_version.h +++ b/custom/4coder_version.h @@ -1,6 +1,6 @@ #define MAJOR 4 #define MINOR 1 -#define PATCH 1 +#define PATCH 2 // string #define VN__(a,b,c) #a "." #b "." #c From de7eca0c8874dc76106c6956b08cced1618548e3 Mon Sep 17 00:00:00 2001 From: Yuval Dolev Date: Tue, 21 Jan 2020 04:17:21 +0200 Subject: [PATCH 109/128] Fixed the package script to work on macOS. --- bin/4ed_build.cpp | 93 +++--- custom/bin/buildsuper_x86-mac.sh | 49 +-- custom/generated/command_metadata.h | 458 ++++++++++++++-------------- platform_mac/mac_4ed.mm | 39 ++- 4 files changed, 322 insertions(+), 317 deletions(-) diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index ed5b07db..4ec43253 100644 --- a/bin/4ed_build.cpp +++ b/bin/4ed_build.cpp @@ -587,6 +587,53 @@ enum{ Tier_COUNT, }; +function void +package_for_arch(Arena *arena, u32 arch, char *cdir, char *build_dir, char *pack_dir, i32 tier, char *tier_name, char *current_dist_tier, u32 flags, char** dist_files, i32 dist_file_count){ + 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)); + + if (tier == Tier_Demo){ + dist_file_count -= 1; + } + + for (i32 j = 0; j < dist_file_count; j += 1){ + fm_copy_all(dist_files[j], dir); + } + + if (tier == Tier_Super){ + char *custom_src_dir = fm_str(arena, cdir, SLASH, "custom"); + char *custom_dst_dir = fm_str(arena, dir, SLASH, "custom"); + // HACK(yuval): make_folder_if_missing seems to cause a second custom folder to be created inside the custom folder on macOS. + if (This_OS != Platform_Mac){ + 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); +} + internal void package(Arena *arena, char *cdir){ // NOTE(allen): meta @@ -615,48 +662,12 @@ package(Arena *arena, char *cdir){ 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; + if (This_OS == Platform_Mac){ + package_for_arch(arena, Arch_X64, cdir, build_dir, pack_dir, i, tier_name, current_dist_tier, flags, dist_files, ArrayCount(dist_files)); + } else{ + for (u32 arch = 0; arch < Arch_COUNT; ++arch){ + package_for_arch(arena, arch, cdir, build_dir, pack_dir, i, tier_name, current_dist_tier, flags, dist_files, ArrayCount(dist_files)); } - - 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); diff --git a/custom/bin/buildsuper_x86-mac.sh b/custom/bin/buildsuper_x86-mac.sh index e3dde9b0..fbdb4b2c 100755 --- a/custom/bin/buildsuper_x86-mac.sh +++ b/custom/bin/buildsuper_x86-mac.sh @@ -1,53 +1,30 @@ #!/bin/bash -# Store the real CWD -REAL_PWD="$PWD" +# If any command errors, stop the script +set -e -# Find the code home folder -TARGET_FILE="$0" -cd `dirname $TARGET_FILE` -TARGET_FILE=`basename $TARGET_FILE` -while [ -L "$TARGET_FILE" ] -do - TARGET_FILE=`readlink $TARGET_FILE` - cd `dirname $TARGET_FILE` - TARGET_FILE=`basename $TARGET_FILE` -done -PHYS_DIR=`pwd -P` -SCRIPT_FILE=$PHYS_DIR/$TARGET_FILE -code_home=$(dirname "$SCRIPT_FILE") +# Store the real CWD +ME="$(realpath "$0")" +LOCATION="$(dirname "$ME")" +CODE_HOME="$(dirname "$LOCATION")" # Find the most reasonable candidate build file SOURCE="$1" if [ -z "$SOURCE" ]; then - SOURCE="$code_home/4coder_default_bindings.cpp" + SOURCE="$(readlink -f "$CODE_HOME/4coder_default_bindings.cpp")" fi -TARGET_FILE="$SOURCE" -cd `dirname $TARGET_FILE` -TARGET_FILE=`basename $TARGET_FILE` -while [ -L "$TARGET_FILE" ] -do - TARGET_FILE=`readlink $TARGET_FILE` - cd `dirname $TARGET_FILE` - TARGET_FILE=`basename $TARGET_FILE` -done -PHYS_DIR=`pwd -P` -SOURCE=$PHYS_DIR/$TARGET_FILE - # 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" +opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-missing-declarations -Wno-logical-op-parentheses -g" arch=-m32 -cd "$REAL_PWD" preproc_file=4coder_command_metadata.i meta_macros="-DMETA_PASS" -g++ -I"$code_home" $meta_macros $arch $opts $debug -std=gnu++0x "$SOURCE" -E -o $preproc_file -g++ -I"$code_home" $opts $debug -std=gnu++0x "$code_home/4coder_metadata_generator.cpp" -o metadata_generator -./metadata_generator -R "$code_home" "$PWD/$preproc_file" +clang++ -I"$CODE_HOME" $meta_macros $arch $opts $debug -std=gnu++0x "$SOURCE" -E -o $preproc_file +clang++ -I"$CODE_HOME" $opts $debug -std=gnu++0x "$CODE_HOME/4coder_metadata_generator.cpp" -o "$CODE_HOME/metadata_generator" +"$CODE_HOME/metadata_generator" -R "$CODE_HOME" "$PWD/$preproc_file" -g++ -I"$code_home" $arch $opts $debug -std=gnu++0x "$SOURCE" -shared -o custom_4coder.so -fPIC +clang++ -I"$CODE_HOME" $arch $opts $debug -std=c++11 "$SOURCE" -shared -o custom_4coder.so -fPIC -rm metadata_generator +rm "$CODE_HOME/metadata_generator" rm $preproc_file - diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 4b514631..f1f6a3f3 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 407 }, -{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 417 }, -{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 398 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 154 }, -{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 611 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 128 }, -{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 186 }, -{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 576 }, -{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 480 }, -{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 243 }, -{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 842 }, -{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 180 }, -{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 619 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 190 }, -{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 753 }, -{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 149 }, -{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 19 }, -{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 175 }, -{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 28 }, -{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 682 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1793 }, -{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 7 }, -{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 23 }, -{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 51 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 162 }, -{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1219 }, -{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1391 }, -{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 134 }, -{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1377 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 7 }, -{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 738 }, -{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 2184 }, -{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 525 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 542 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 348 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 375 }, -{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 746 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 464 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 494 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 481 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 511 }, -{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 649 }, -{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 635 }, -{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 564 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 581 }, -{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 671 }, -{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 520 }, -{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 657 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 707 }, -{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 612 }, -{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 510 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_code_index_listers.cpp", 65, 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 54 }, -{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 77 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 41 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1537 }, -{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 296 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 302 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1331 }, -{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 249 }, -{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 693 }, -{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 265 }, -{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 336 }, -{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 348 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 354 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 407 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 431 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 419 }, -{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 437 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 514 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 528 }, -{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 486 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 471 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 500 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1371 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1365 }, -{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 445 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 507 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 521 }, -{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 479 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 463 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 493 }, -{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 330 }, -{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 342 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 401 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 425 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 413 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1456 }, -{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1787 }, -{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1488 }, -{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 310 }, -{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 372 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 364 }, -{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 109 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 70 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 116 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 106 }, -{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 226 }, -{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 219 }, -{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 212 }, -{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "/Users/allenwebster/4ed/code/custom/4coder_profile_inspect.cpp", 62, 886 }, -{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1147 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1168 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1184 }, -{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1626 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1711 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1296 }, -{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1555 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1057 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1048 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1039 }, -{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 980 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 992 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1545 }, -{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1263 }, -{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 974 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 986 }, -{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 537 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 27 }, -{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 99 }, -{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 115 }, -{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 427 }, -{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 1230 }, -{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 642 }, -{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 628 }, -{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "/Users/allenwebster/4ed/code/custom/4coder_log_parser.cpp", 57, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 187 }, -{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 403 }, -{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1513 }, -{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 777 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 563 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 550 }, -{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 656 }, -{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 665 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 439 }, -{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 433 }, -{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 719 }, -{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 725 }, -{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 445 }, -{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 710 }, -{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "/Users/allenwebster/4ed/code/custom/4coder_code_index.cpp", 57, 1170 }, -{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 20 }, -{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 34 }, -{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 137 }, -{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1613 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1640 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1501 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_lister.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 392 }, -{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 639 }, -{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 88 }, -{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 427 }, -{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 76 }, -{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 73 }, -{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 100 }, +{ PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 407 }, +{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 417 }, +{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 398 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 154 }, +{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 611 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 128 }, +{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 186 }, +{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 576 }, +{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 480 }, +{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 243 }, +{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 842 }, +{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 180 }, +{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 619 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_docs.cpp", 49, 190 }, +{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 753 }, +{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 149 }, +{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 19 }, +{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_docs.cpp", 49, 175 }, +{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 28 }, +{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 682 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1793 }, +{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 7 }, +{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 23 }, +{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 51 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 162 }, +{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1219 }, +{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1391 }, +{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 134 }, +{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1377 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_cli_command.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_cli_command.cpp", 56, 7 }, +{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 738 }, +{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 2184 }, +{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 525 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 542 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 348 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 375 }, +{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 746 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 464 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 494 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 481 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 511 }, +{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 649 }, +{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 635 }, +{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 564 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 581 }, +{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 671 }, +{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 520 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 657 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 707 }, +{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 612 }, +{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 510 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_code_index_listers.cpp", 63, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 54 }, +{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 77 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 41 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1537 }, +{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 296 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 302 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1331 }, +{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 249 }, +{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 693 }, +{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 265 }, +{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 336 }, +{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 348 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 354 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 407 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 431 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 419 }, +{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 437 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 514 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 528 }, +{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 486 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 471 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 500 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1371 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1365 }, +{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 445 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 507 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 521 }, +{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 479 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 463 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 493 }, +{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 330 }, +{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 342 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 401 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 425 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 413 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1456 }, +{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1787 }, +{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1488 }, +{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 310 }, +{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 372 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 364 }, +{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 109 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 70 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 116 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 106 }, +{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 226 }, +{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 219 }, +{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 212 }, +{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "/Users/yuvaldolev/4ed/code/custom/4coder_profile_inspect.cpp", 60, 886 }, +{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1147 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1168 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1184 }, +{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1626 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1711 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1296 }, +{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1555 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1057 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1048 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1039 }, +{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 980 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 992 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1545 }, +{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1263 }, +{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 974 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 986 }, +{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 537 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 27 }, +{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 99 }, +{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 115 }, +{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 427 }, +{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 1230 }, +{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 642 }, +{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 628 }, +{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_log_parser.cpp", 55, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 187 }, +{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 403 }, +{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1513 }, +{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 777 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 563 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 550 }, +{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 656 }, +{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 665 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 439 }, +{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 433 }, +{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 719 }, +{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 725 }, +{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 445 }, +{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 710 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_code_index.cpp", 55, 1170 }, +{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 20 }, +{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 34 }, +{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 137 }, +{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1613 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1640 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1501 }, +{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_lister.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 392 }, +{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 639 }, +{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 88 }, +{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 427 }, +{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 76 }, +{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 73 }, +{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 100 }, }; static i32 fcoder_metacmd_ID_allow_mouse = 0; static i32 fcoder_metacmd_ID_auto_indent_line_at_cursor = 1; diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 87e1f0d0..7e42b6ac 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -324,6 +324,23 @@ mac_error_box(char *msg, b32 shutdown = true){ } } + +function void +os_popup_error(char *title, char *message){ + // TODO(yuval): Condense this with mac_error_box + + NSAlert *alert = [[[NSAlert alloc] init] autorelease]; + + NSString *title_string = [NSString stringWithUTF8String:title]; + NSString *message_string = [NSString stringWithUTF8String:message]; + [alert setMessageText:title_string]; + [alert setInformativeText:message_string]; + + [alert runModal]; + + exit(1); +} + //////////////////////////////// #if defined(FRED_INTERNAL) @@ -533,7 +550,7 @@ mac_read_clipboard_contents(Arena *scratch){ mac_vars.clipboard_contents = string_const_u8_push(clip_arena, copy_length); [data getBytes:mac_vars.clipboard_contents.str - length:mac_vars.clipboard_contents.size]; + length:mac_vars.clipboard_contents.size]; result = true; } @@ -552,13 +569,13 @@ mac_post_clipboard(Arena *scratch, char *text, i32 len){ NSString *utf8_type = @"public.utf8-plain-text"; NSArray *types_array = [NSArray arrayWithObjects:utf8_type, nil]; [board declareTypes:types_array - owner:nil]; + owner:nil]; NSString *paste_string = [[NSString alloc] initWithBytes:text - length:len - encoding:NSUTF8StringEncoding]; + length:len + encoding:NSUTF8StringEncoding]; [board setString:paste_string - forType:utf8_type]; + forType:utf8_type]; [paste_string release]; mac_vars.next_clipboard_is_self = true; @@ -1272,9 +1289,9 @@ main(int arg_count, char **args){ u32 style_mask = NSWindowStyleMaskTitled | NSWindowStyleMaskClosable | NSWindowStyleMaskMiniaturizable | NSWindowStyleMaskResizable; mac_vars.window = [[NSWindow alloc] initWithContentRect:initial_frame - styleMask:style_mask - backing:NSBackingStoreBuffered - defer:NO]; + styleMask:style_mask + backing:NSBackingStoreBuffered + defer:NO]; FCoder_Window_Delegate *window_delegate = [[FCoder_Window_Delegate alloc] init]; [mac_vars.window setDelegate:window_delegate]; @@ -1319,9 +1336,9 @@ main(int arg_count, char **args){ // NOTE(yuval): Start the clipboard polling timer [NSTimer scheduledTimerWithTimeInterval: 0.5 - target:mac_vars.view - selector:@selector(check_clipboard) - userInfo:nil repeats:YES]; + target:mac_vars.view + selector:@selector(check_clipboard) + userInfo:nil repeats:YES]; } // NOTE(yuval): Initialize the virtul keycodes table From 5c2471f7e22b77a44890fbf8bcff23b388e626da Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 20 Jan 2020 23:22:26 -0800 Subject: [PATCH 110/128] folder copy fixup in mac package script --- bin/4ed_build.cpp | 24 +- bin/package-mac.sh | 4 + custom/4coder_file_moving.h | 26 +- custom/generated/command_metadata.h | 458 ++++++++++++++-------------- 4 files changed, 261 insertions(+), 251 deletions(-) create mode 100755 bin/package-mac.sh diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index 4ec43253..0a838e23 100644 --- a/bin/4ed_build.cpp +++ b/bin/4ed_build.cpp @@ -603,8 +603,9 @@ package_for_arch(Arena *arena, u32 arch, char *cdir, char *build_dir, char *pack 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, 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)); @@ -622,9 +623,9 @@ package_for_arch(Arena *arena, u32 arch, char *cdir, char *build_dir, char *pack char *custom_src_dir = fm_str(arena, cdir, SLASH, "custom"); char *custom_dst_dir = fm_str(arena, dir, SLASH, "custom"); // HACK(yuval): make_folder_if_missing seems to cause a second custom folder to be created inside the custom folder on macOS. - if (This_OS != Platform_Mac){ - fm_make_folder_if_missing(arena, custom_dst_dir); - } + //if (This_OS != Platform_Mac){ + fm_make_folder_if_missing(arena, custom_dst_dir); + //} fm_copy_all(custom_src_dir, custom_dst_dir); } @@ -662,12 +663,17 @@ package(Arena *arena, char *cdir){ Temp_Memory temp = begin_temp(arena); char *current_dist_tier = fm_str(arena, ".." SLASH "current_dist_", tier_name); + i32 arch_count = Arch_COUNT; + u32 arch_array[2] = { + Arch_X64, + Arch_X86, + }; if (This_OS == Platform_Mac){ - package_for_arch(arena, Arch_X64, cdir, build_dir, pack_dir, i, tier_name, current_dist_tier, flags, dist_files, ArrayCount(dist_files)); - } else{ - for (u32 arch = 0; arch < Arch_COUNT; ++arch){ - package_for_arch(arena, arch, cdir, build_dir, pack_dir, i, tier_name, current_dist_tier, flags, dist_files, ArrayCount(dist_files)); - } + arch_count = 1; + } + for (u32 arch_ind = 0; arch_ind < arch_count; ++arch_ind){ + u32 arch = arch_array[arch_ind]; + package_for_arch(arena, arch, cdir, build_dir, pack_dir, i, tier_name, current_dist_tier, flags, dist_files, ArrayCount(dist_files)); } end_temp(temp); diff --git a/bin/package-mac.sh b/bin/package-mac.sh new file mode 100755 index 00000000..92eb8a24 --- /dev/null +++ b/bin/package-mac.sh @@ -0,0 +1,4 @@ +#!/bin/bash + +chmod 777 bin/build-mac.sh +bin/build-mac.sh "-DPACKAGE" diff --git a/custom/4coder_file_moving.h b/custom/4coder_file_moving.h index 3b8f0172..9e5ea59f 100644 --- a/custom/4coder_file_moving.h +++ b/custom/4coder_file_moving.h @@ -33,11 +33,11 @@ static i32 prev_error = 0; #endif #define systemf(...) do{ \ - i32 n = snprintf(SF_CMD, sizeof(SF_CMD), __VA_ARGS__); \ - Assert(n < sizeof(SF_CMD)); \ - SYSTEMF_PRINTF("%s\n", SF_CMD); \ - prev_error = system(SF_CMD); \ - if (prev_error != 0) error_state = 1; \ +i32 n = snprintf(SF_CMD, sizeof(SF_CMD), __VA_ARGS__); \ +Assert(n < sizeof(SF_CMD)); \ +SYSTEMF_PRINTF("%s\n", SF_CMD); \ +prev_error = system(SF_CMD); \ +if (prev_error != 0) error_state = 1; \ }while(0) internal void fm_execute_in_dir(char *dir, char *str, char *args); @@ -109,18 +109,18 @@ internal void fm__swap_ptr(char **A, char **B); #if COMPILER_CL #define fm_add_to_line(line, str, ...) do{ \ - snprintf(line.build_options, \ - line.build_max, "%s "str, \ - line.build_options_prev, __VA_ARGS__); \ - fm__swap_ptr(&line.build_options, &line.build_options_prev); \ +snprintf(line.build_options, \ +line.build_max, "%s "str, \ +line.build_options_prev, __VA_ARGS__); \ +fm__swap_ptr(&line.build_options, &line.build_options_prev); \ }while(0) #elif COMPILER_GCC | COMPILER_CLANG #define fm_add_to_line(line, str, ...) do{ \ - snprintf(line.build_options, line.build_max, "%s " str, \ - line.build_options_prev, ##__VA_ARGS__); \ - fm__swap_ptr(&line.build_options, &line.build_options_prev); \ +snprintf(line.build_options, line.build_max, "%s " str, \ +line.build_options_prev, ##__VA_ARGS__); \ +fm__swap_ptr(&line.build_options, &line.build_options_prev); \ }while(0) #endif @@ -510,7 +510,7 @@ fm_copy_file(char *file, char *newname){ internal void fm_copy_all(char *source, char *folder){ fprintf(stdout, "copy %s to %s\n", source, folder); - systemf("cp -rf %s %s > /dev/null", source, folder); + systemf("cp -rf %s/* %s > /dev/null", source, folder); } internal void diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index f1f6a3f3..4b514631 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 407 }, -{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 417 }, -{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 398 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 154 }, -{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 611 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 128 }, -{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 186 }, -{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 576 }, -{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 480 }, -{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 243 }, -{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 842 }, -{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_build_commands.cpp", 59, 180 }, -{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 619 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_docs.cpp", 49, 190 }, -{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 753 }, -{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 149 }, -{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 19 }, -{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_docs.cpp", 49, 175 }, -{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 28 }, -{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 682 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1793 }, -{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 7 }, -{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 23 }, -{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_default_hooks.cpp", 58, 51 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 162 }, -{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1219 }, -{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1391 }, -{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 134 }, -{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1377 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_cli_command.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_cli_command.cpp", 56, 7 }, -{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 738 }, -{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 2184 }, -{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 525 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 542 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 348 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 375 }, -{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 746 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 464 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 494 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 481 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 511 }, -{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 649 }, -{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 635 }, -{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 564 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_sticky.cpp", 56, 581 }, -{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 671 }, -{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 520 }, -{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 657 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 707 }, -{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 612 }, -{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 510 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_code_index_listers.cpp", 63, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 54 }, -{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 77 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_keyboard_macro.cpp", 59, 41 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1537 }, -{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 296 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 302 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_function_list.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1331 }, -{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 249 }, -{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_miblo_numbers.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 693 }, -{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 265 }, -{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 336 }, -{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 348 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 354 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 407 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 431 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 419 }, -{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 437 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 514 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 528 }, -{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 486 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 471 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 500 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1371 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1365 }, -{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 445 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 507 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 521 }, -{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 479 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 463 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 493 }, -{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 330 }, -{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 342 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 401 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 425 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 413 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1456 }, -{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1787 }, -{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1488 }, -{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 310 }, -{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 372 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 364 }, -{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 109 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 70 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_clipboard.cpp", 54, 116 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 106 }, -{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 226 }, -{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 219 }, -{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_profile.cpp", 52, 212 }, -{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "/Users/yuvaldolev/4ed/code/custom/4coder_profile_inspect.cpp", 60, 886 }, -{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1147 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1168 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1184 }, -{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1626 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1711 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1296 }, -{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1555 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1057 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1048 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1039 }, -{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 980 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 992 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1545 }, -{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1263 }, -{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 974 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 986 }, -{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_helper.cpp", 51, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 537 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 27 }, -{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "/Users/yuvaldolev/4ed/code/custom/4coder_scope_commands.cpp", 59, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_eol.cpp", 48, 99 }, -{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 115 }, -{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 427 }, -{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_project_commands.cpp", 61, 1230 }, -{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 642 }, -{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 628 }, -{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "/Users/yuvaldolev/4ed/code/custom/4coder_log_parser.cpp", 55, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 187 }, -{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 403 }, -{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1513 }, -{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_lists.cpp", 50, 777 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 563 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 550 }, -{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 656 }, -{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 665 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 439 }, -{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 433 }, -{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 719 }, -{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 725 }, -{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_default_framework.cpp", 62, 445 }, -{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 710 }, -{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_code_index.cpp", 55, 1170 }, -{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 20 }, -{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "/Users/yuvaldolev/4ed/code/custom/4coder_tutorial.cpp", 53, 34 }, -{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 137 }, -{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1613 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1640 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 1501 }, -{ 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, "/Users/yuvaldolev/4ed/code/custom/4coder_jump_lister.cpp", 56, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 392 }, -{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "/Users/yuvaldolev/4ed/code/custom/4coder_search.cpp", 51, 639 }, -{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 88 }, -{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_auto_indent.cpp", 56, 427 }, -{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 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, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 76 }, -{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "/Users/yuvaldolev/4ed/code/custom/4coder_base_commands.cpp", 58, 73 }, -{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "/Users/yuvaldolev/4ed/code/custom/4coder_combined_write_commands.cpp", 68, 100 }, +{ PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 407 }, +{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 417 }, +{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 398 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 154 }, +{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 611 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 128 }, +{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 186 }, +{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 576 }, +{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 480 }, +{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 243 }, +{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 842 }, +{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 180 }, +{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 619 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 190 }, +{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 753 }, +{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 149 }, +{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 19 }, +{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 175 }, +{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 28 }, +{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 682 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1793 }, +{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 7 }, +{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 23 }, +{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 51 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 162 }, +{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1219 }, +{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1391 }, +{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 134 }, +{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1377 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 7 }, +{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 738 }, +{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 2184 }, +{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 525 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 542 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 348 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 375 }, +{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 746 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 464 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 494 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 481 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 511 }, +{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 649 }, +{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 635 }, +{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 564 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 581 }, +{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 671 }, +{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 520 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 657 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 707 }, +{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 612 }, +{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 510 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_code_index_listers.cpp", 65, 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 54 }, +{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 77 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 41 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1537 }, +{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 296 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 302 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1331 }, +{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 249 }, +{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 693 }, +{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 265 }, +{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 336 }, +{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 348 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 354 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 407 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 431 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 419 }, +{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 437 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 514 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 528 }, +{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 486 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 471 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 500 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1371 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1365 }, +{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 445 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 507 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 521 }, +{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 479 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 463 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 493 }, +{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 330 }, +{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 342 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 401 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 425 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 413 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1456 }, +{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1787 }, +{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1488 }, +{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 310 }, +{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 372 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 364 }, +{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 109 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 70 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 116 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 106 }, +{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 226 }, +{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 219 }, +{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 212 }, +{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "/Users/allenwebster/4ed/code/custom/4coder_profile_inspect.cpp", 62, 886 }, +{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1147 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1168 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1184 }, +{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1626 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1711 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1296 }, +{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1555 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1057 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1048 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1039 }, +{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 980 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 992 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1545 }, +{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1263 }, +{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 974 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 986 }, +{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 537 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 27 }, +{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 99 }, +{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 115 }, +{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 427 }, +{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 1230 }, +{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 642 }, +{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 628 }, +{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "/Users/allenwebster/4ed/code/custom/4coder_log_parser.cpp", 57, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 187 }, +{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 403 }, +{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1513 }, +{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 777 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 563 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 550 }, +{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 656 }, +{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 665 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 439 }, +{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 433 }, +{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 719 }, +{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 725 }, +{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 445 }, +{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 710 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "/Users/allenwebster/4ed/code/custom/4coder_code_index.cpp", 57, 1170 }, +{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 20 }, +{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 34 }, +{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 137 }, +{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1613 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1640 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1501 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_lister.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 392 }, +{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 639 }, +{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 88 }, +{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 427 }, +{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 76 }, +{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 73 }, +{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 100 }, }; static i32 fcoder_metacmd_ID_allow_mouse = 0; static i32 fcoder_metacmd_ID_auto_indent_line_at_cursor = 1; From 69bb6cb2bf870634e9fb5e3e049c32424bec77ce Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Mon, 20 Jan 2020 23:59:51 -0800 Subject: [PATCH 111/128] Updated initial message, readme, and changes --- custom/4coder_default_framework.cpp | 7 ++++++- ship_files/README.txt | 5 ++++- ship_files/changes.txt | 26 ++++++++++++++++++++++++++ 3 files changed, 36 insertions(+), 2 deletions(-) diff --git a/custom/4coder_default_framework.cpp b/custom/4coder_default_framework.cpp index 28588d3a..07e019f4 100644 --- a/custom/4coder_default_framework.cpp +++ b/custom/4coder_default_framework.cpp @@ -501,9 +501,14 @@ default_4coder_initialize(Application_Links *app, String_Const_u8_Array file_nam #define M \ "Welcome to " VERSION "\n" \ -"If you're new to 4coder there are some tutorials at http://4coder.net/tutorials.html\n" \ +"If you're new to 4coder there is a built in tutorial\n" \ +"Use the key combination [ X Alt ] (on mac [ X Control ])\n" \ +"Type in 'hms_demo_tutorial' and press enter\n" \ +"\n" \ "Direct bug reports and feature requests to https://github.com/4coder-editor/4coder/issues\n" \ +"\n" \ "Other questions and discussion can be directed to editor@4coder.net or 4coder.handmade.network\n" \ +"\n" \ "The change log can be found in CHANGES.txt\n" \ "\n" print_message(app, string_u8_litexpr(M)); diff --git a/ship_files/README.txt b/ship_files/README.txt index d01c6fe6..03441be9 100644 --- a/ship_files/README.txt +++ b/ship_files/README.txt @@ -6,9 +6,12 @@ https://github.com/4coder-editor/4coder/issues For questions email: editor@4coder.net +Sign up for the newsletter for the most critical 4coder news: +newsletter.4coder.net + Watch the 4coder.handmade.network blog and @AllenWebster4th twitter for news about 4coder. -For documentation, feature lists, and usage tutorial videos go to: +For documentation, feature lists, and more visit the home page: 4coder.net diff --git a/ship_files/changes.txt b/ship_files/changes.txt index cde4f694..8b92d375 100644 --- a/ship_files/changes.txt +++ b/ship_files/changes.txt @@ -1,3 +1,29 @@ + +4.1.2 + + Cursor color changes when recording macro if the theme provides a second cursor color + + Default custom layer now has a feature for supporting fade ranges as used in pasting and undoing + + Ability to "partially" paint text with a blend factor to create blends + + In file lister, typing a slash with a name for a folder that does not exist asks the user if they would like to create a folder + + Fix: parser in code index recognizes functions with more than one parameter + + Fix: trying to create a face with a font file that doesn't exist doesn't crash + + Fix: escaping command documentation lister doesn't crash + + Fix: lexer generator switched to new macro names Max and Min + + Fix: implementation for getting previous view iterates from null to the last view in order (instead of the first) + + Fix: auto-indent when a file with virtual whitespace is saved + + Fix: can create up to sixteen panels, and doesn't crash when trying to create more + + Fix: faster text range highlighting + + Fix: side by side editing a single buffer doesn't scroll the lower view down when insterting lines in the higher view + + Fix: indentation after paren group is correct + +4.1.1 + Changes not documented + +4.1.0 + Initial beta version + +************************************************** +************************************************** + New in alpha 4.0.30: -Mouse events (clicking, scroll wheel, mouse move) can now be bound with modifier keys -New and changed commands: From d6b0387f0d22df04e35a32a09b3d22064a7df402 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Tue, 21 Jan 2020 12:01:47 -0800 Subject: [PATCH 112/128] Decent fix for fullscreen problem --- platform_mac/mac_4ed.mm | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index 7e42b6ac..a8688811 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -824,8 +824,8 @@ mac_toggle_fullscreen(void){ // NOTE(yuval): Toggle full screen MacProfileScope("Toggle Full Screen"){ if (mac_vars.do_toggle){ - mac_toggle_fullscreen(); mac_vars.do_toggle = false; + mac_toggle_fullscreen(); } } From b2bdfbd05dff4c2e3fe69965c931d241dc448b7a Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Tue, 21 Jan 2020 12:57:42 -0800 Subject: [PATCH 113/128] Slightly better mac fullscreen fix --- platform_mac/mac_4ed.mm | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/platform_mac/mac_4ed.mm b/platform_mac/mac_4ed.mm index a8688811..46997aff 100644 --- a/platform_mac/mac_4ed.mm +++ b/platform_mac/mac_4ed.mm @@ -612,7 +612,9 @@ mac_toggle_fullscreen(void){ - (void)windowDidResize:(NSNotification*)notification{ mac_resize(mac_vars.window); - [mac_vars.view display]; + if (!mac_vars.do_toggle){ + [mac_vars.view display]; + } } - (void)windowDidMiniaturize:(NSNotification*)notification{ @@ -824,8 +826,8 @@ mac_toggle_fullscreen(void){ // NOTE(yuval): Toggle full screen MacProfileScope("Toggle Full Screen"){ if (mac_vars.do_toggle){ - mac_vars.do_toggle = false; mac_toggle_fullscreen(); + mac_vars.do_toggle = false; } } From 628429d7f63357e6d8bda9c91c6e8d7f9359226b Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Tue, 21 Jan 2020 13:24:42 -0800 Subject: [PATCH 114/128] Fix another readlink in for mac buildsuper script --- custom/bin/buildsuper_x64-mac.sh | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/custom/bin/buildsuper_x64-mac.sh b/custom/bin/buildsuper_x64-mac.sh index ff3699a8..7113ed24 100755 --- a/custom/bin/buildsuper_x64-mac.sh +++ b/custom/bin/buildsuper_x64-mac.sh @@ -11,7 +11,7 @@ CODE_HOME="$(dirname "$LOCATION")" # Find the most reasonable candidate build file SOURCE="$1" if [ -z "$SOURCE" ]; then - SOURCE="$(readlink -f "$CODE_HOME/4coder_default_bindings.cpp")" + SOURCE="$(realpath "$CODE_HOME/4coder_default_bindings.cpp")" fi # NOTE(yuval): Removed -Wno-writable-strings as it is the same as -Wno-write-strings From b22b296adf885175d74c4551d7e64e32785022dd Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Tue, 21 Jan 2020 13:35:40 -0800 Subject: [PATCH 115/128] Alternate set mark binding --- custom/4coder_mac_map.cpp | 1 + 1 file changed, 1 insertion(+) diff --git a/custom/4coder_mac_map.cpp b/custom/4coder_mac_map.cpp index 305ff07e..f21d5dd2 100644 --- a/custom/4coder_mac_map.cpp +++ b/custom/4coder_mac_map.cpp @@ -86,6 +86,7 @@ setup_mac_mapping(Mapping *mapping, i64 global_id, i64 file_id, i64 code_id){ Bind(snipe_backward_whitespace_or_token_boundary, KeyCode_Backspace, KeyCode_Control); Bind(snipe_forward_whitespace_or_token_boundary, KeyCode_Delete, KeyCode_Control); Bind(set_mark, KeyCode_Space, KeyCode_Control); + Bind(set_mark, KeyCode_ForwardSlash, KeyCode_Command); Bind(replace_in_range, KeyCode_A, KeyCode_Command); Bind(copy, KeyCode_C, KeyCode_Command); Bind(delete_range, KeyCode_D, KeyCode_Command); From f23385bb1bffc63b6fc955c22d6689f712e7e427 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Tue, 21 Jan 2020 14:13:13 -0800 Subject: [PATCH 116/128] Rearranging some of the binding files --- custom/4coder_config.cpp | 26 ++++++++++++++++++++++++++ custom/4coder_default_bindings.cpp | 26 -------------------------- custom/4coder_default_framework.h | 5 ----- custom/4coder_default_include.cpp | 2 ++ 4 files changed, 28 insertions(+), 31 deletions(-) diff --git a/custom/4coder_config.cpp b/custom/4coder_config.cpp index 3b5f429d..b013bb91 100644 --- a/custom/4coder_config.cpp +++ b/custom/4coder_config.cpp @@ -34,6 +34,32 @@ parse_extension_line_to_extension_list(Application_Links *app, //////////////////////////////// +function void +setup_built_in_mapping(Application_Links *app, String_Const_u8 name, Mapping *mapping, i64 global_id, i64 file_id, i64 code_id){ + Thread_Context *tctx = get_thread_context(app); + if (string_match(name, string_u8_litexpr("default"))){ + mapping_release(tctx, mapping); + mapping_init(tctx, mapping); + setup_default_mapping(mapping, global_id, file_id, code_id); + } + else if (string_match(name, string_u8_litexpr("mac-default"))){ + mapping_release(tctx, mapping); + mapping_init(tctx, mapping); + setup_mac_mapping(mapping, global_id, file_id, code_id); + } + else if (string_match(name, string_u8_litexpr("choose"))){ + mapping_release(tctx, mapping); + mapping_init(tctx, mapping); +#if OS_MAC + setup_mac_mapping(mapping, global_id, file_id, code_id); +#else + setup_default_mapping(mapping, global_id, file_id, code_id); +#endif + } +} + +//////////////////////////////// + function Error_Location get_error_location(Application_Links *app, u8 *base, u8 *pos){ ProfileScope(app, "get error location"); diff --git a/custom/4coder_default_bindings.cpp b/custom/4coder_default_bindings.cpp index d4e34071..a2c2866c 100644 --- a/custom/4coder_default_bindings.cpp +++ b/custom/4coder_default_bindings.cpp @@ -11,8 +11,6 @@ // NOTE(allen): Users can declare their own managed IDs here. -#include "4coder_default_map.cpp" -#include "4coder_mac_map.cpp" #include "generated/managed_id_metadata.cpp" void @@ -34,30 +32,6 @@ custom_layer_init(Application_Links *app){ setup_default_mapping(&framework_mapping, mapid_global, mapid_file, mapid_code); } -function void -setup_built_in_mapping(Application_Links *app, String_Const_u8 name, Mapping *mapping, i64 global_id, i64 file_id, i64 code_id){ - Thread_Context *tctx = get_thread_context(app); - if (string_match(name, string_u8_litexpr("default"))){ - mapping_release(tctx, mapping); - mapping_init(tctx, mapping); - setup_default_mapping(mapping, global_id, file_id, code_id); - } - else if (string_match(name, string_u8_litexpr("mac-default"))){ - mapping_release(tctx, mapping); - mapping_init(tctx, mapping); - setup_mac_mapping(mapping, global_id, file_id, code_id); - } - else if (string_match(name, string_u8_litexpr("choose"))){ - mapping_release(tctx, mapping); - mapping_init(tctx, mapping); -#if OS_MAC - setup_mac_mapping(mapping, global_id, file_id, code_id); -#else - setup_default_mapping(mapping, global_id, file_id, code_id); -#endif - } -} - #endif //FCODER_DEFAULT_BINDINGS // BOTTOM diff --git a/custom/4coder_default_framework.h b/custom/4coder_default_framework.h index be49d9c7..b1daa3e2 100644 --- a/custom/4coder_default_framework.h +++ b/custom/4coder_default_framework.h @@ -114,11 +114,6 @@ struct Fade_Range_List{ i32 count; }; -//////////////////////////////// - -function void -setup_built_in_mapping(Application_Links *app, String_Const_u8 name, Mapping *mapping, i64 global_id, i64 file_id, i64 code_id); - #endif // BOTTOM diff --git a/custom/4coder_default_include.cpp b/custom/4coder_default_include.cpp index 51ee72b2..063567c6 100644 --- a/custom/4coder_default_include.cpp +++ b/custom/4coder_default_include.cpp @@ -78,6 +78,8 @@ #include "4coder_token.cpp" #include "generated/lexer_cpp.cpp" #include "4coder_command_map.cpp" +#include "4coder_default_map.cpp" +#include "4coder_mac_map.cpp" #include "4coder_default_framework_variables.cpp" #include "4coder_default_colors.cpp" #include "4coder_helper.cpp" From 7ba15fed20677a5006e56a5fee8a2056c4673ac5 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Wed, 22 Jan 2020 14:01:42 -0800 Subject: [PATCH 117/128] Site update --- custom/4coder_doc_commands.cpp | 272 +++++++++-------- custom/generated/command_metadata.h | 458 ++++++++++++++-------------- site/4ed_site_render_main.cpp | 71 +++-- site/static/home.html | 33 +- 4 files changed, 436 insertions(+), 398 deletions(-) diff --git a/custom/4coder_doc_commands.cpp b/custom/4coder_doc_commands.cpp index 92c2f6f8..d2aa3e09 100644 --- a/custom/4coder_doc_commands.cpp +++ b/custom/4coder_doc_commands.cpp @@ -14,7 +14,7 @@ doc_commands(Arena *arena){ Doc_Cluster *cluster = new_doc_cluster(arena, "Commands", "commands"); for (i32 i = 0; i < ArrayCount(fcoder_metacmd_table); i += 1){ String_Const_u8 cmd_name = SCu8(fcoder_metacmd_table[i].name, - fcoder_metacmd_table[i].name_len); + fcoder_metacmd_table[i].name_len); String_Const_u8 title = push_u8_stringf(arena, "Command %.*s", string_expand(cmd_name)); Doc_Page *page = new_doc_page(arena, cluster, (char*)title.str, (char*)cmd_name.str); Doc_Block *block = new_doc_block(arena, page, "brief"); @@ -24,146 +24,150 @@ doc_commands(Arena *arena){ } function Doc_Cluster* -doc_default_bindings(Arena *arena, Mapping *mapping, i64 global_id, i64 file_id, i64 code_id){ +doc_default_bindings(Arena *arena, i32 map_count, Mapping *mapping_array, char **page_titles, char **page_names, + i64 global_id, i64 file_id, i64 code_id){ Doc_Cluster *cluster = new_doc_cluster(arena, "Bindings", "bindings"); - Doc_Page *page = new_doc_page(arena, cluster, "Default Bindings", "default_bindings"); - for (Command_Map *map = mapping->first_map; - map != 0; - map = map->next){ - char *map_name = ""; - if (map->id == global_id){ - map_name = "Global"; - } - else if (map->id == file_id){ - map_name = "File"; - } - else if (map->id == code_id){ - map_name = "Code"; - } - - Doc_Block *block = new_doc_block(arena, page, map_name); - Doc_Paragraph *par = new_doc_par_table(arena, block); - - struct Bind_Node{ - Bind_Node *next; - Input_Event_Kind kind; - u32 sub_code; - Input_Modifier_Set mods; - Command_Binding binding; - u32 j; - }; - - Bind_Node *first = 0; - Bind_Node *last = 0; - i32 node_count = 0; - - if (map->text_input_command.name != 0){ - Bind_Node *node = push_array_zero(arena, Bind_Node, 1); - sll_queue_push(first, last, node); - node_count += 1; - node->binding = map->text_input_command; - node->j = max_u32; - } - - u32 counts[] = { - KeyCode_COUNT, - KeyCode_COUNT, - MouseCode_COUNT, - MouseCode_COUNT, - 1, - 1, - CoreCode_COUNT, - }; - - u32 event_codes[] = { - InputEventKind_KeyStroke, - InputEventKind_KeyRelease, - InputEventKind_MouseButton, - InputEventKind_MouseButtonRelease, - InputEventKind_MouseWheel, - InputEventKind_MouseMove, - InputEventKind_Core, - }; - - char *mouse_wheel_name[] = {"MoveWheel"}; - char *mouse_move_name[] = {"MoveMove"}; - - char **event_names[] = { - key_code_name, - key_code_name, - mouse_code_name, - mouse_code_name, - mouse_wheel_name, - mouse_move_name, - core_code_name, - }; - - b32 is_release[] = { - false, - true, - false, - true, - false, - false, - false, - }; - - for (u32 j = 0; j < ArrayCount(counts); j += 1){ - for (u32 code = 0; code < counts[j]; code += 1){ - u64 key = mapping__key(event_codes[j], code); - Table_Lookup lookup = table_lookup(&map->event_code_to_binding_list, key); - if (lookup.found_match){ - u64 val = 0; - table_read(&map->event_code_to_binding_list, lookup, &val); - Command_Binding_List *list = (Command_Binding_List*)IntAsPtr(val); - for (SNode *snode = list->first; - snode != 0; - snode = snode->next){ - Command_Modified_Binding *mod_binding = CastFromMember(Command_Modified_Binding, order_node, snode); - - Bind_Node *node = push_array_zero(arena, Bind_Node, 1); - sll_queue_push(first, last, node); - node_count += 1; - node->kind = event_codes[j]; - node->sub_code = code; - node->mods = mod_binding->mods; - node->binding = mod_binding->binding; - node->j = j; + for (i32 i = 0; i < map_count; i += 1){ + Mapping *mapping = &mapping_array[i]; + Doc_Page *page = new_doc_page(arena, cluster, page_titles[i], page_names[i]); + for (Command_Map *map = mapping->first_map; + map != 0; + map = map->next){ + char *map_name = ""; + if (map->id == global_id){ + map_name = "Global"; + } + else if (map->id == file_id){ + map_name = "File"; + } + else if (map->id == code_id){ + map_name = "Code"; + } + + Doc_Block *block = new_doc_block(arena, page, map_name); + Doc_Paragraph *par = new_doc_par_table(arena, block); + + struct Bind_Node{ + Bind_Node *next; + Input_Event_Kind kind; + u32 sub_code; + Input_Modifier_Set mods; + Command_Binding binding; + u32 j; + }; + + Bind_Node *first = 0; + Bind_Node *last = 0; + i32 node_count = 0; + + if (map->text_input_command.name != 0){ + Bind_Node *node = push_array_zero(arena, Bind_Node, 1); + sll_queue_push(first, last, node); + node_count += 1; + node->binding = map->text_input_command; + node->j = max_u32; + } + + u32 counts[] = { + KeyCode_COUNT, + KeyCode_COUNT, + MouseCode_COUNT, + MouseCode_COUNT, + 1, + 1, + CoreCode_COUNT, + }; + + u32 event_codes[] = { + InputEventKind_KeyStroke, + InputEventKind_KeyRelease, + InputEventKind_MouseButton, + InputEventKind_MouseButtonRelease, + InputEventKind_MouseWheel, + InputEventKind_MouseMove, + InputEventKind_Core, + }; + + char *mouse_wheel_name[] = {"MoveWheel"}; + char *mouse_move_name[] = {"MoveMove"}; + + char **event_names[] = { + key_code_name, + key_code_name, + mouse_code_name, + mouse_code_name, + mouse_wheel_name, + mouse_move_name, + core_code_name, + }; + + b32 is_release[] = { + false, + true, + false, + true, + false, + false, + false, + }; + + for (u32 j = 0; j < ArrayCount(counts); j += 1){ + for (u32 code = 0; code < counts[j]; code += 1){ + u64 key = mapping__key(event_codes[j], code); + Table_Lookup lookup = table_lookup(&map->event_code_to_binding_list, key); + if (lookup.found_match){ + u64 val = 0; + table_read(&map->event_code_to_binding_list, lookup, &val); + Command_Binding_List *list = (Command_Binding_List*)IntAsPtr(val); + for (SNode *snode = list->first; + snode != 0; + snode = snode->next){ + Command_Modified_Binding *mod_binding = CastFromMember(Command_Modified_Binding, order_node, snode); + + Bind_Node *node = push_array_zero(arena, Bind_Node, 1); + sll_queue_push(first, last, node); + node_count += 1; + node->kind = event_codes[j]; + node->sub_code = code; + node->mods = mod_binding->mods; + node->binding = mod_binding->binding; + node->j = j; + } } } } - } - - Vec2_i32 table_dims = V2i32(2, node_count); - Doc_Content_List *vals = push_array_zero(arena, Doc_Content_List, table_dims.x*table_dims.y); - Bind_Node *bnode = first; - for (i32 y = 0; y < table_dims.y; y += 1, bnode = bnode->next){ - Doc_Content_List *line = &vals[y*table_dims.x]; - doc_text(arena, &line[0], "["); - if (bnode->j != max_u32){ - doc_text(arena, &line[0], event_names[bnode->j][bnode->sub_code]); - if (is_release[bnode->j]){ - doc_text(arena, &line[0], "Release"); - } - - Input_Modifier_Set *mods = &bnode->mods; - for (i32 k = 0; k < mods->count; k += 1){ - doc_text(arena, &line[0], key_code_name[mods->mods[k]]); - } - } - else{ - doc_text(arena, &line[0], "TextInput"); - } - doc_text(arena, &line[0], "]"); - Doc_Content *content = doc_text(arena, &line[1], bnode->binding.name); - content->page_link = SCu8(bnode->binding.name); - } - - par->table.dim = table_dims; - par->table.vals = vals; + Vec2_i32 table_dims = V2i32(2, node_count); + Doc_Content_List *vals = push_array_zero(arena, Doc_Content_List, table_dims.x*table_dims.y); + Bind_Node *bnode = first; + for (i32 y = 0; y < table_dims.y; y += 1, bnode = bnode->next){ + Doc_Content_List *line = &vals[y*table_dims.x]; + doc_text(arena, &line[0], "["); + if (bnode->j != max_u32){ + doc_text(arena, &line[0], event_names[bnode->j][bnode->sub_code]); + if (is_release[bnode->j]){ + doc_text(arena, &line[0], "Release"); + } + + Input_Modifier_Set *mods = &bnode->mods; + for (i32 k = 0; k < mods->count; k += 1){ + doc_text(arena, &line[0], key_code_name[mods->mods[k]]); + } + } + else{ + doc_text(arena, &line[0], "TextInput"); + } + doc_text(arena, &line[0], "]"); + + Doc_Content *content = doc_text(arena, &line[1], bnode->binding.name); + content->page_link = SCu8(bnode->binding.name); + } + + par->table.dim = table_dims; + par->table.vals = vals; } + } return(cluster); } diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 4b514631..1c461ef6 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 407 }, -{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 417 }, -{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 398 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 154 }, -{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 611 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 128 }, -{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 186 }, -{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 576 }, -{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 480 }, -{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 243 }, -{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 842 }, -{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 180 }, -{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 619 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 190 }, -{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 753 }, -{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 149 }, -{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 19 }, -{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 175 }, -{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 28 }, -{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 682 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1793 }, -{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 7 }, -{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 23 }, -{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 51 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 162 }, -{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1219 }, -{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1391 }, -{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 134 }, -{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1377 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 7 }, -{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 738 }, -{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 2184 }, -{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 525 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 542 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 348 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 375 }, -{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 746 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 464 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 494 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 481 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 511 }, -{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 649 }, -{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 635 }, -{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 564 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 581 }, -{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 671 }, -{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 520 }, -{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 657 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 707 }, -{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 612 }, -{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 510 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_code_index_listers.cpp", 65, 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 54 }, -{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 77 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 41 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1537 }, -{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 296 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 302 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1331 }, -{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 249 }, -{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 693 }, -{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 265 }, -{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 336 }, -{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 348 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 354 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 407 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 431 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 419 }, -{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 437 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 514 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 528 }, -{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 486 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 471 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 500 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1371 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1365 }, -{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 445 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 507 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 521 }, -{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 479 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 463 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 493 }, -{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 330 }, -{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 342 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 401 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 425 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 413 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1456 }, -{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1787 }, -{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1488 }, -{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 310 }, -{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 372 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 364 }, -{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 109 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 70 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 116 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 106 }, -{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 226 }, -{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 219 }, -{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 212 }, -{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "/Users/allenwebster/4ed/code/custom/4coder_profile_inspect.cpp", 62, 886 }, -{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1147 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1168 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1184 }, -{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1626 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1711 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1296 }, -{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1555 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1057 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1048 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1039 }, -{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 980 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 992 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1545 }, -{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1263 }, -{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 974 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 986 }, -{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 537 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 27 }, -{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 99 }, -{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 115 }, -{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 427 }, -{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 1230 }, -{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 642 }, -{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 628 }, -{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "/Users/allenwebster/4ed/code/custom/4coder_log_parser.cpp", 57, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 187 }, -{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 403 }, -{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1513 }, -{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 777 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 563 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 550 }, -{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 656 }, -{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 665 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 439 }, -{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 433 }, -{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 719 }, -{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 725 }, -{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 445 }, -{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 710 }, -{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "/Users/allenwebster/4ed/code/custom/4coder_code_index.cpp", 57, 1170 }, -{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 20 }, -{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 34 }, -{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 137 }, -{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1613 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1640 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1501 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_lister.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 392 }, -{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 639 }, -{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 88 }, -{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 427 }, -{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 76 }, -{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 73 }, -{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 100 }, +{ 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, 407 }, +{ 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, 417 }, +{ 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, 398 }, +{ 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, 611 }, +{ 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, 576 }, +{ 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, 619 }, +{ 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, 753 }, +{ 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, 682 }, +{ 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, 1793 }, +{ 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, 51 }, +{ 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, 1219 }, +{ 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, 1391 }, +{ 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, 1377 }, +{ 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, 738 }, +{ 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, 525 }, +{ 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, 542 }, +{ 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, 348 }, +{ 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, 375 }, +{ 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, 746 }, +{ 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, 464 }, +{ 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, 494 }, +{ 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, 481 }, +{ 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, 511 }, +{ 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, 649 }, +{ 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, 635 }, +{ 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, 564 }, +{ 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, 581 }, +{ 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, 671 }, +{ 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, 520 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 657 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 707 }, +{ 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, 612 }, +{ 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, 510 }, +{ 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, 54 }, +{ 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, 77 }, +{ 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, 41 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1537 }, +{ 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, 296 }, +{ 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, 302 }, +{ 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, 1331 }, +{ 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, 693 }, +{ 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, 336 }, +{ 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, 348 }, +{ 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, 354 }, +{ 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, 407 }, +{ 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, 431 }, +{ 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, 419 }, +{ 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, 437 }, +{ 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, 514 }, +{ 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, 528 }, +{ 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, 486 }, +{ 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, 471 }, +{ 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, 500 }, +{ 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, 1371 }, +{ 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, 1365 }, +{ 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, 445 }, +{ 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, 507 }, +{ 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, 521 }, +{ 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, 479 }, +{ 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, 463 }, +{ 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, 493 }, +{ 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, 330 }, +{ 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, 342 }, +{ 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, 401 }, +{ 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, 425 }, +{ 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, 413 }, +{ 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, 1456 }, +{ 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, 1787 }, +{ 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, 1488 }, +{ 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, 372 }, +{ 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, 364 }, +{ 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, 109 }, +{ 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, 70 }, +{ 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, 116 }, +{ 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, 1147 }, +{ 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, 1168 }, +{ 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, 1184 }, +{ 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, 1626 }, +{ 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, 1711 }, +{ 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, 1296 }, +{ 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, 1555 }, +{ 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, 1057 }, +{ 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, 1048 }, +{ 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, 1039 }, +{ 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, 980 }, +{ 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, 992 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1545 }, +{ 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, 1263 }, +{ 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, 974 }, +{ 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, 986 }, +{ 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, 537 }, +{ 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, 642 }, +{ 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, 628 }, +{ 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, 1513 }, +{ 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, 777 }, +{ 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, 563 }, +{ 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, 550 }, +{ 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, 656 }, +{ 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, 665 }, +{ 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, 719 }, +{ 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, 725 }, +{ 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, 710 }, +{ 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, 1170 }, +{ 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, 1613 }, +{ 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, 1640 }, +{ 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, 1501 }, +{ 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 a space.", 16, "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, 427 }, +{ 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 }, }; static i32 fcoder_metacmd_ID_allow_mouse = 0; static i32 fcoder_metacmd_ID_auto_indent_line_at_cursor = 1; diff --git a/site/4ed_site_render_main.cpp b/site/4ed_site_render_main.cpp index 532f5f3f..3da30516 100644 --- a/site/4ed_site_render_main.cpp +++ b/site/4ed_site_render_main.cpp @@ -33,6 +33,7 @@ #define MAP_METADATA_ONLY 1 #include "4coder_command_map.cpp" #include "4coder_default_map.cpp" +#include "4coder_mac_map.cpp" #include "generated/custom_api_constructor.cpp" #include "../docs/4ed_doc_custom_api.cpp" #include "4coder_doc_commands.cpp" @@ -151,7 +152,7 @@ render_doc_page_to_html__code(Arena *scratch, Doc_Code_Sample_List *code, FILE * "", string_expand(node->contents)); if (node->next != 0){ - fprintf(out, "
    \n"); + fprintf(out, "
    \n"); } } } @@ -170,7 +171,7 @@ render_doc_page_to_html__table(Arena *scratch, Vec2_i32 dim, Doc_Content_List *v } fprintf(out, ""); } - fprintf(out, ""); + fprintf(out, ""); } function void @@ -313,11 +314,11 @@ render_doc_cluster_to_html(Arena *scratch, Doc_Cluster *cluster, fprintf(file, html_footer); } -{ + { Temp_Memory_Block temp(scratch); fprintf(file_index, html_header, string_expand(cluster->title)); - + Doc_Page **ptrs = push_array(scratch, Doc_Page*, cluster->page_count); i32 counter = 0; for (Doc_Page *node = cluster->first_page; @@ -340,19 +341,19 @@ render_doc_cluster_to_html(Arena *scratch, Doc_Cluster *cluster, fprintf(file_index, "
    \n"); fprintf(file_index, ""); - fprintf(file_index, "
    \n"); - - fprintf(file_index, "
    \n"); fprintf(file_index, "\n"); @@ -374,8 +375,8 @@ render_doc_cluster_to_html(Arena *scratch, Doc_Cluster *cluster, } } - fprintf(file_index, html_footer); -} + fprintf(file_index, html_footer); + } } function void @@ -421,33 +422,49 @@ int main(){ String_Const_u8 root = string_prefix(self, code_pos + 5); String_Const_u8 outside_root = string_prefix(self, code_pos); String_Const_u8 build_root = push_u8_stringf(&arena, "%.*sbuild/", - string_expand(outside_root)); + string_expand(outside_root)); String_Const_u8 site_root = push_u8_stringf(&arena, "%.*ssite/", - string_expand(build_root)); + string_expand(build_root)); String_Const_u8 docs_root = push_u8_stringf(&arena, "%.*sdocs/", string_expand(site_root)); (void)root; - Mapping mapping = {}; - mapping_init(tctx, &mapping); - setup_default_mapping(&mapping, 1, 2, 3); + i64 global_id = 1; + i64 file_id = 2; + i64 code_id = 3; + + local_const i32 map_count = 2; + Mapping mapping_array[map_count] = {}; + char *page_tiles[map_count] = {}; + char *page_names[map_count] = {}; + + mapping_init(tctx, &mapping_array[0]); + setup_default_mapping(&mapping_array[0], global_id, file_id, code_id); + page_tiles[0] = "Default Bindings"; + page_names[0] = "default_bindings"; + + mapping_init(tctx, &mapping_array[1]); + setup_mac_mapping(&mapping_array[1], global_id, file_id, code_id); + page_tiles[1] = "Default Mac Bindings"; + page_names[1] = "default_mac_bindings"; API_Definition *api_def = custom_api_construct(&arena); Doc_Cluster *cluster_array[] = { doc_custom_api(&arena, api_def), doc_commands(&arena), - doc_default_bindings(&arena, &mapping, 1, 2, 3), + doc_default_bindings(&arena, map_count, mapping_array, page_tiles, page_names, + global_id, file_id, code_id), }; for (i32 i = 0; i < ArrayCount(cluster_array); i += 1){ Doc_Cluster *cluster = cluster_array[i]; for (Doc_Page *node = cluster->first_page; - node != 0; + node != 0; node = node->next){ render_doc_page_to_html(&arena, node, docs_root); - } - render_doc_cluster_to_html(&arena, cluster, docs_root); + } + render_doc_cluster_to_html(&arena, cluster, docs_root); } return(0); diff --git a/site/static/home.html b/site/static/home.html index cd63187e..08a954a7 100644 --- a/site/static/home.html +++ b/site/static/home.html @@ -37,10 +37,6 @@ li.firstli { margin-top: 0px; } -table.normal tr { - -} - .normal a:link, a:link { color: #D08F20; } @@ -81,6 +77,16 @@ table.normal tr { text-align: left; } +.normal table { + border-spacing: 0; +} + +.normal td { + font-size: 1.25em; + color: #90B080; + padding-right: .6em; +} + .comment { margin-left: 14px; margin-right: 14px; @@ -165,11 +171,22 @@ table.normal tr {
    From f7a642a2a189b59f61b2960d788c489ed150ad9f Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Wed, 22 Jan 2020 14:04:12 -0800 Subject: [PATCH 118/128] Fix signed/unsigned mismatch --- bin/4ed_build.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/bin/4ed_build.cpp b/bin/4ed_build.cpp index 0a838e23..f76e9880 100644 --- a/bin/4ed_build.cpp +++ b/bin/4ed_build.cpp @@ -663,7 +663,7 @@ package(Arena *arena, char *cdir){ Temp_Memory temp = begin_temp(arena); char *current_dist_tier = fm_str(arena, ".." SLASH "current_dist_", tier_name); - i32 arch_count = Arch_COUNT; + u32 arch_count = Arch_COUNT; u32 arch_array[2] = { Arch_X64, Arch_X86, @@ -671,7 +671,7 @@ package(Arena *arena, char *cdir){ if (This_OS == Platform_Mac){ arch_count = 1; } - for (u32 arch_ind = 0; arch_ind < arch_count; ++arch_ind){ + for (u32 arch_ind = 0; arch_ind < arch_count; arch_ind += 1){ u32 arch = arch_array[arch_ind]; package_for_arch(arena, arch, cdir, build_dir, pack_dir, i, tier_name, current_dist_tier, flags, dist_files, ArrayCount(dist_files)); } From 3e729e5d37c620880ce0756bdf5034dcbb39c337 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 23 Jan 2020 13:39:47 -0800 Subject: [PATCH 119/128] Various fixes from the issues list --- 4ed_history.cpp | 4 + custom/4coder_base_commands.cpp | 23 +- custom/4coder_draw.cpp | 2 +- custom/4coder_search.cpp | 5 +- custom/generated/command_metadata.h | 275 ++++++++++--------- ship_files/changes.txt | 7 + ship_files/themes/theme-4coder.4coder | 3 + ship_files/themes/theme-handmade-hero.4coder | 5 +- ship_files/themes/theme-hjortshoej.4coder | 4 +- ship_files/themes/theme-midnight.4coder | 5 +- ship_files/themes/theme-stb-dark.4coder | 3 + ship_files/themes/theme-stb.4coder | 2 + ship_files/themes/theme-strange.4coder | 2 + ship_files/themes/theme-sunlight.4coder | 3 + ship_files/themes/theme-twilight.4coder | 5 +- ship_files/themes/theme-wombat.4coder | 3 + 16 files changed, 201 insertions(+), 150 deletions(-) diff --git a/4ed_history.cpp b/4ed_history.cpp index d18e84b1..d292fdea 100644 --- a/4ed_history.cpp +++ b/4ed_history.cpp @@ -314,6 +314,7 @@ history__optimize_group(Arena *scratch, History *history, Record *record){ String_Const_u8 merged_forward = {}; String_Const_u8 merged_backward = {}; + i64 merged_first = 0; if (left->single.first + (i64)left->single.forward_text.size == right->single.first){ do_merge = true; merged_forward = push_u8_stringf(scratch, "%.*s%.*s", @@ -322,6 +323,7 @@ history__optimize_group(Arena *scratch, History *history, Record *record){ merged_backward = push_u8_stringf(scratch, "%.*s%.*s", string_expand(left->single.backward_text), string_expand(right->single.backward_text)); + merged_first = left->single.first; } else if (right->single.first + (i64)right->single.backward_text.size == left->single.first){ do_merge = true; @@ -331,6 +333,7 @@ history__optimize_group(Arena *scratch, History *history, Record *record){ merged_backward = push_u8_stringf(scratch, "%.*s%.*s", string_expand(right->single.backward_text), string_expand(left->single.backward_text)); + merged_first = right->single.first; } else{ break; @@ -340,6 +343,7 @@ history__optimize_group(Arena *scratch, History *history, Record *record){ end_temp(left->restore_point); left->edit_number = right->edit_number; + left->single.first = merged_first; left->single.forward_text = push_string_copy(history->arena, merged_forward); left->single.backward_text = push_string_copy(history->arena, merged_backward); diff --git a/custom/4coder_base_commands.cpp b/custom/4coder_base_commands.cpp index 45b100b4..6b204cb2 100644 --- a/custom/4coder_base_commands.cpp +++ b/custom/4coder_base_commands.cpp @@ -112,6 +112,17 @@ CUSTOM_DOC("Deletes the character to the left of the cursor.") } } +CUSTOM_COMMAND_SIG(test_double_backspace) +CUSTOM_DOC("Made for testing purposes (I should have deleted this if you are reading it let me know)") +{ + View_ID view = get_active_view(app, Access_ReadWriteVisible); + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); + History_Group group = history_group_begin(app, buffer); + backspace_char(app); + backspace_char(app); + history_group_end(group); +} + CUSTOM_COMMAND_SIG(set_mark) CUSTOM_DOC("Sets the mark to the current position of the cursor.") { @@ -1077,10 +1088,8 @@ query_replace_base(Application_Links *app, View_ID view, Buffer_ID buffer_id, i6 i64 new_pos = 0; seek_string_forward(app, buffer_id, pos - 1, 0, r, &new_pos); - i64 buffer_size = buffer_get_size(app, buffer_id); - User_Input in = {}; - for (;new_pos < buffer_size;){ + for (;;){ Range_i64 match = Ii64(new_pos, new_pos + r.size); isearch__update_highlight(app, view, match); @@ -1089,9 +1098,11 @@ query_replace_base(Application_Links *app, View_ID view, Buffer_ID buffer_id, i6 break; } - if (match_key_code(&in, KeyCode_Y) || - match_key_code(&in, KeyCode_Return) || - match_key_code(&in, KeyCode_Tab)){ + i64 size = buffer_get_size(app, buffer_id); + if (match.max <= size && + (match_key_code(&in, KeyCode_Y) || + match_key_code(&in, KeyCode_Return) || + match_key_code(&in, KeyCode_Tab))){ buffer_replace_range(app, buffer_id, match, w); pos = match.start + w.size; } diff --git a/custom/4coder_draw.cpp b/custom/4coder_draw.cpp index 60ee2b6d..d6ebc6cf 100644 --- a/custom/4coder_draw.cpp +++ b/custom/4coder_draw.cpp @@ -302,9 +302,9 @@ draw_file_bar(Application_Links *app, View_ID view_id, Buffer_ID buffer, Face_ID }break; } + u8 space[3]; { 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(" ")); diff --git a/custom/4coder_search.cpp b/custom/4coder_search.cpp index 0b35787d..07f293a8 100644 --- a/custom/4coder_search.cpp +++ b/custom/4coder_search.cpp @@ -91,17 +91,20 @@ internal String_Const_u8_Array user_list_definition_array(Application_Links *app, Arena *arena, String_Const_u8 base_needle){ String_Const_u8_Array result = {}; if (base_needle.size > 0){ - result.count = 9; + result.count = 12; result.vals = push_array(arena, String_Const_u8, result.count); i32 i = 0; result.vals[i++] = (push_u8_stringf(arena, "struct %.*s{" , string_expand(base_needle))); result.vals[i++] = (push_u8_stringf(arena, "struct %.*s\n{", string_expand(base_needle))); + result.vals[i++] = (push_u8_stringf(arena, "struct %.*s\r\n{", string_expand(base_needle))); result.vals[i++] = (push_u8_stringf(arena, "struct %.*s {" , string_expand(base_needle))); result.vals[i++] = (push_u8_stringf(arena, "union %.*s{" , string_expand(base_needle))); result.vals[i++] = (push_u8_stringf(arena, "union %.*s\n{" , string_expand(base_needle))); + result.vals[i++] = (push_u8_stringf(arena, "union %.*s\r\n{" , string_expand(base_needle))); result.vals[i++] = (push_u8_stringf(arena, "union %.*s {" , string_expand(base_needle))); result.vals[i++] = (push_u8_stringf(arena, "enum %.*s{" , string_expand(base_needle))); result.vals[i++] = (push_u8_stringf(arena, "enum %.*s\n{" , string_expand(base_needle))); + result.vals[i++] = (push_u8_stringf(arena, "enum %.*s\r\n{" , string_expand(base_needle))); result.vals[i++] = (push_u8_stringf(arena, "enum %.*s {" , string_expand(base_needle))); Assert(i == result.count); } diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 1c461ef6..d5f6e936 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -2,7 +2,7 @@ #define command_id(c) (fcoder_metacmd_ID_##c) #define command_metadata(c) (&fcoder_metacmd_table[command_id(c)]) #define command_metadata_by_id(id) (&fcoder_metacmd_table[id]) -#define command_one_past_last_id 229 +#define command_one_past_last_id 230 #if defined(CUSTOM_COMMAND_SIG) #define PROC_LINKS(x,y) x #else @@ -206,6 +206,7 @@ CUSTOM_COMMAND_SIG(snipe_forward_whitespace_or_token_boundary); CUSTOM_COMMAND_SIG(snippet_lister); CUSTOM_COMMAND_SIG(suppress_mouse); CUSTOM_COMMAND_SIG(swap_panels); +CUSTOM_COMMAND_SIG(test_double_backspace); CUSTOM_COMMAND_SIG(theme_lister); CUSTOM_COMMAND_SIG(to_lowercase); CUSTOM_COMMAND_SIG(to_uppercase); @@ -250,70 +251,70 @@ char *source_name; i32 source_name_len; i32 line_number; }; -static Command_Metadata fcoder_metacmd_table[229] = { +static Command_Metadata fcoder_metacmd_table[230] = { { 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, 407 }, { 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, 417 }, { 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, 398 }, -{ 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_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, 165 }, { 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, 611 }, +{ 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, 622 }, { 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(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, 208 }, { 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, 576 }, +{ 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, 587 }, { 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(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, 244 }, +{ 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, 234 }, +{ 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, 254 }, +{ 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, 266 }, { 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, 619 }, +{ 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, 630 }, { 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, 753 }, { 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(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, 135 }, { 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, 682 }, -{ 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, 1793 }, +{ 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, 693 }, +{ 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, 1804 }, { 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, 51 }, -{ 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_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, 173 }, { 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, 1219 }, -{ 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, 1391 }, -{ 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, 1377 }, +{ 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, 1230 }, +{ 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, 1402 }, +{ 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, 145 }, +{ 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, 1388 }, { 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, 738 }, +{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 749 }, { 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, 525 }, { 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, 542 }, { 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, 348 }, { 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, 375 }, -{ 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, 746 }, +{ 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, 757 }, { 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, 464 }, { 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, 494 }, { 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, 481 }, { 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, 511 }, -{ 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, 649 }, -{ 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, 635 }, +{ 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, 660 }, +{ 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, 646 }, { 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, 564 }, { 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, 581 }, -{ 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, 671 }, +{ 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, 682 }, { 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, 520 }, { PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 657 }, { PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 707 }, @@ -323,72 +324,72 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 54 }, { 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, 77 }, { 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, 41 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1537 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1548 }, { 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(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, 222 }, { 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, 296 }, { 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, 302 }, { 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(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, 165 }, +{ 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, 177 }, +{ 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, 189 }, +{ 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, 195 }, +{ 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, 201 }, +{ 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, 207 }, +{ 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, 213 }, +{ 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, 221 }, +{ 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, 171 }, +{ 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, 183 }, { 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, 1331 }, +{ 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, 1342 }, { 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, 693 }, -{ 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, 336 }, -{ 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, 348 }, -{ 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, 354 }, -{ 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, 407 }, -{ 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, 431 }, -{ 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, 419 }, -{ 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, 437 }, -{ 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, 514 }, -{ 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, 528 }, -{ 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, 486 }, -{ 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, 471 }, -{ 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, 500 }, -{ 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, 1371 }, -{ 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, 1365 }, -{ 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, 445 }, -{ 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, 507 }, -{ 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, 521 }, -{ 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, 479 }, -{ 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, 463 }, -{ 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, 493 }, -{ 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, 330 }, -{ 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, 342 }, -{ 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, 401 }, -{ 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, 425 }, -{ 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, 413 }, +{ 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, 704 }, +{ 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, 276 }, +{ 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, 347 }, +{ 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, 359 }, +{ 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, 365 }, +{ 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, 418 }, +{ 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, 442 }, +{ 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, 430 }, +{ 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, 448 }, +{ 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, 525 }, +{ 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, 539 }, +{ 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, 497 }, +{ 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, 482 }, +{ 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, 511 }, +{ 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, 1382 }, +{ 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, 1376 }, +{ 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, 456 }, +{ 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, 518 }, +{ 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, 532 }, +{ 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, 490 }, +{ 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, 474 }, +{ 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, 504 }, +{ 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, 341 }, +{ 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, 353 }, +{ 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, 412 }, +{ 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, 436 }, +{ 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, 424 }, { 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, 1456 }, -{ 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, 1787 }, +{ 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, 1467 }, +{ 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, 1798 }, { 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, 1488 }, +{ 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, 1499 }, { 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, 372 }, -{ 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, 364 }, +{ 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, 383 }, +{ 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, 375 }, { 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, 109 }, { 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, 70 }, @@ -401,28 +402,28 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, 1147 }, -{ 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, 1168 }, -{ 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, 1184 }, -{ 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, 1626 }, -{ 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, 1711 }, -{ 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, 1296 }, -{ 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, 1555 }, -{ 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, 1057 }, -{ 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, 1048 }, -{ 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, 1039 }, -{ 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, 980 }, -{ 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, 992 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1545 }, +{ 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, 1158 }, +{ 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, 1179 }, +{ 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, 1195 }, +{ 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, 1637 }, +{ 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, 1722 }, +{ 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, 1307 }, +{ 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, 1566 }, +{ 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, 1068 }, +{ 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, 1059 }, +{ 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, 1050 }, +{ 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, 991 }, +{ 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, 1003 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1556 }, { 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, 1263 }, -{ 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, 974 }, -{ 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, 986 }, +{ 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, 1274 }, +{ 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, 985 }, +{ 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, 997 }, { 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, 537 }, +{ 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, 548 }, { 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 }, @@ -433,44 +434,45 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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_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, 126 }, { 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, 642 }, -{ 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, 628 }, +{ 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, 653 }, +{ 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, 639 }, { 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(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, 190 }, +{ 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, 198 }, { 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, 1513 }, +{ 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, 1524 }, +{ PROC_LINKS(test_double_backspace, 0), false, "test_double_backspace", 21, "Made for testing purposes (I should have deleted this if you are reading it let me know)", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 115 }, { 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, 777 }, -{ 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, 563 }, -{ 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, 550 }, -{ 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, 656 }, -{ 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, 665 }, +{ 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, 574 }, +{ 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, 561 }, +{ 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, 667 }, +{ 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, 676 }, { 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, 719 }, -{ 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, 725 }, +{ 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, 730 }, +{ 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, 736 }, { 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, 710 }, +{ 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, 721 }, { 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, 1170 }, { 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, 1613 }, -{ 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, 1640 }, -{ 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, 1501 }, +{ 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, 1624 }, +{ 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, 1651 }, +{ 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, 1512 }, { 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(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, 395 }, +{ 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, 642 }, { 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 }, @@ -678,36 +680,37 @@ static i32 fcoder_metacmd_ID_snipe_forward_whitespace_or_token_boundary = 193; static i32 fcoder_metacmd_ID_snippet_lister = 194; static i32 fcoder_metacmd_ID_suppress_mouse = 195; static i32 fcoder_metacmd_ID_swap_panels = 196; -static i32 fcoder_metacmd_ID_theme_lister = 197; -static i32 fcoder_metacmd_ID_to_lowercase = 198; -static i32 fcoder_metacmd_ID_to_uppercase = 199; -static i32 fcoder_metacmd_ID_toggle_filebar = 200; -static i32 fcoder_metacmd_ID_toggle_fps_meter = 201; -static i32 fcoder_metacmd_ID_toggle_fullscreen = 202; -static i32 fcoder_metacmd_ID_toggle_highlight_enclosing_scopes = 203; -static i32 fcoder_metacmd_ID_toggle_highlight_line_at_cursor = 204; -static i32 fcoder_metacmd_ID_toggle_line_numbers = 205; -static i32 fcoder_metacmd_ID_toggle_line_wrap = 206; -static i32 fcoder_metacmd_ID_toggle_mouse = 207; -static i32 fcoder_metacmd_ID_toggle_paren_matching_helper = 208; -static i32 fcoder_metacmd_ID_toggle_show_whitespace = 209; -static i32 fcoder_metacmd_ID_toggle_virtual_whitespace = 210; -static i32 fcoder_metacmd_ID_tutorial_maximize = 211; -static i32 fcoder_metacmd_ID_tutorial_minimize = 212; -static i32 fcoder_metacmd_ID_uncomment_line = 213; -static i32 fcoder_metacmd_ID_undo = 214; -static i32 fcoder_metacmd_ID_undo_all_buffers = 215; -static i32 fcoder_metacmd_ID_view_buffer_other_panel = 216; -static i32 fcoder_metacmd_ID_view_jump_list_with_lister = 217; -static i32 fcoder_metacmd_ID_word_complete = 218; -static i32 fcoder_metacmd_ID_word_complete_drop_down = 219; -static i32 fcoder_metacmd_ID_write_block = 220; -static i32 fcoder_metacmd_ID_write_hack = 221; -static i32 fcoder_metacmd_ID_write_note = 222; -static i32 fcoder_metacmd_ID_write_space = 223; -static i32 fcoder_metacmd_ID_write_text_and_auto_indent = 224; -static i32 fcoder_metacmd_ID_write_text_input = 225; -static i32 fcoder_metacmd_ID_write_todo = 226; -static i32 fcoder_metacmd_ID_write_underscore = 227; -static i32 fcoder_metacmd_ID_write_zero_struct = 228; +static i32 fcoder_metacmd_ID_test_double_backspace = 197; +static i32 fcoder_metacmd_ID_theme_lister = 198; +static i32 fcoder_metacmd_ID_to_lowercase = 199; +static i32 fcoder_metacmd_ID_to_uppercase = 200; +static i32 fcoder_metacmd_ID_toggle_filebar = 201; +static i32 fcoder_metacmd_ID_toggle_fps_meter = 202; +static i32 fcoder_metacmd_ID_toggle_fullscreen = 203; +static i32 fcoder_metacmd_ID_toggle_highlight_enclosing_scopes = 204; +static i32 fcoder_metacmd_ID_toggle_highlight_line_at_cursor = 205; +static i32 fcoder_metacmd_ID_toggle_line_numbers = 206; +static i32 fcoder_metacmd_ID_toggle_line_wrap = 207; +static i32 fcoder_metacmd_ID_toggle_mouse = 208; +static i32 fcoder_metacmd_ID_toggle_paren_matching_helper = 209; +static i32 fcoder_metacmd_ID_toggle_show_whitespace = 210; +static i32 fcoder_metacmd_ID_toggle_virtual_whitespace = 211; +static i32 fcoder_metacmd_ID_tutorial_maximize = 212; +static i32 fcoder_metacmd_ID_tutorial_minimize = 213; +static i32 fcoder_metacmd_ID_uncomment_line = 214; +static i32 fcoder_metacmd_ID_undo = 215; +static i32 fcoder_metacmd_ID_undo_all_buffers = 216; +static i32 fcoder_metacmd_ID_view_buffer_other_panel = 217; +static i32 fcoder_metacmd_ID_view_jump_list_with_lister = 218; +static i32 fcoder_metacmd_ID_word_complete = 219; +static i32 fcoder_metacmd_ID_word_complete_drop_down = 220; +static i32 fcoder_metacmd_ID_write_block = 221; +static i32 fcoder_metacmd_ID_write_hack = 222; +static i32 fcoder_metacmd_ID_write_note = 223; +static i32 fcoder_metacmd_ID_write_space = 224; +static i32 fcoder_metacmd_ID_write_text_and_auto_indent = 225; +static i32 fcoder_metacmd_ID_write_text_input = 226; +static i32 fcoder_metacmd_ID_write_todo = 227; +static i32 fcoder_metacmd_ID_write_underscore = 228; +static i32 fcoder_metacmd_ID_write_zero_struct = 229; #endif diff --git a/ship_files/changes.txt b/ship_files/changes.txt index 8b92d375..6724954b 100644 --- a/ship_files/changes.txt +++ b/ship_files/changes.txt @@ -1,4 +1,11 @@ +4.1.3 + + Fix: search and replace never exits early + + Fix: optimized builds of the custom layer display the dirty * on the file bar correclty + + Fix: can merge "backwards" strings in the history correctly + + Fix: the helper user_list_definition_array matches both LF and CRLF line endings + + Fix: line number background and text colors in the built in theme files + 4.1.2 + Cursor color changes when recording macro if the theme provides a second cursor color + Default custom layer now has a feature for supporting fade ranges as used in pasting and undoing diff --git a/ship_files/themes/theme-4coder.4coder b/ship_files/themes/theme-4coder.4coder index 224fb242..879ff82e 100644 --- a/ship_files/themes/theme-4coder.4coder +++ b/ship_files/themes/theme-4coder.4coder @@ -41,3 +41,6 @@ defcolor_pop2 = 0xFFFF0000; defcolor_back_cycle = {0x10A00000, 0x0C00A000, 0x0C0000A0, 0x0CA0A000}; defcolor_text_cycle = {0xFFA00000, 0xFF00A000, 0xFF0030B0, 0xFFA0A000}; + +defcolor_line_numbers_back = 0xFF101010; +defcolor_line_numbers_text = 0xFF404040; diff --git a/ship_files/themes/theme-handmade-hero.4coder b/ship_files/themes/theme-handmade-hero.4coder index de1af82a..54531399 100644 --- a/ship_files/themes/theme-handmade-hero.4coder +++ b/ship_files/themes/theme-handmade-hero.4coder @@ -43,6 +43,5 @@ defcolor_pop2 = 0xFFFF0000; defcolor_back_cycle = {0x0CA00000, 0x0800A000, 0x080000A0, 0x08A0A000}; defcolor_text_cycle = {0xFFA00000, 0xFF00A000, 0xFF0020B0, 0xFFA0A000}; - - - +defcolor_line_numbers_back = 0xFF202020; +defcolor_line_numbers_text = 0xFF484848; diff --git a/ship_files/themes/theme-hjortshoej.4coder b/ship_files/themes/theme-hjortshoej.4coder index 917de699..b84e7b70 100644 --- a/ship_files/themes/theme-hjortshoej.4coder +++ b/ship_files/themes/theme-hjortshoej.4coder @@ -7,7 +7,7 @@ defcolor_margin_active = 0xFF5C5C5C; defcolor_list_item = defcolor_margin; defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; -defcolor_cursor = {0xFF000000, 0xFF002020}; +defcolor_cursor = {0xFF000000, 0xFF008080}; defcolor_at_cursor = 0xFFD6D6D6; defcolor_highlight_cursor_line = 0xFFB8B098; defcolor_mark = 0xFF525252; @@ -42,3 +42,5 @@ defcolor_pop2 = 0xFFE80505; defcolor_back_cycle = {0x1CA00000, 0x1C00A000, 0x1C0000A0, 0x1CA0A000}; defcolor_text_cycle = {0xFFF01010, 0xFF20D020, 0xFF0000F0, 0xFFD0D000}; +defcolor_line_numbers_back = 0xFFD0D0D0; +defcolor_line_numbers_text = 0xFF404040; diff --git a/ship_files/themes/theme-midnight.4coder b/ship_files/themes/theme-midnight.4coder index cfa30340..b0768625 100644 --- a/ship_files/themes/theme-midnight.4coder +++ b/ship_files/themes/theme-midnight.4coder @@ -6,7 +6,7 @@ defcolor_margin_active = 0xFF484848; defcolor_list_item = defcolor_margin; defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; -defcolor_cursor = {0xFFDDDDDD, 0xFFDDF0F0}; +defcolor_cursor = {0xFFDDDDDD, 0xFFDD7777}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF383838; defcolor_mark = 0xFF808080; @@ -40,3 +40,6 @@ defcolor_pop2 = 0xFFFF3A00; defcolor_back_cycle = {0x08A00000, 0x0800A000, 0x080000A0, 0x08A0A000}; defcolor_text_cycle = {0xFFF01010, 0xFF20D020, 0xFF0080E0, 0xFFD0D000}; + +defcolor_line_numbers_back = 0xFF383838; +defcolor_line_numbers_text = 0xFF686860; diff --git a/ship_files/themes/theme-stb-dark.4coder b/ship_files/themes/theme-stb-dark.4coder index 5461f890..e747e24a 100644 --- a/ship_files/themes/theme-stb-dark.4coder +++ b/ship_files/themes/theme-stb-dark.4coder @@ -40,3 +40,6 @@ defcolor_pop2 = 0xFFFF3A00; defcolor_back_cycle = {0x06A00000, 0x0600A000, 0x060000A0, 0x06A0A000}; defcolor_text_cycle = {0xFFAA0A0A, 0xFF149014, 0xFF0060A8, 0xFF909000}; + +defcolor_line_numbers_back = 0xFF808080; +defcolor_line_numbers_text = 0xFF303030; diff --git a/ship_files/themes/theme-stb.4coder b/ship_files/themes/theme-stb.4coder index 3cdce02b..012be474 100644 --- a/ship_files/themes/theme-stb.4coder +++ b/ship_files/themes/theme-stb.4coder @@ -41,3 +41,5 @@ defcolor_pop2 = 0xFFE80505; defcolor_back_cycle = {0x10A00000, 0x1000A000, 0x100000A0, 0x10A0A000}; defcolor_text_cycle = {0xFFA00000, 0xFF00A000, 0xFF0000A0, 0xFFA0A000}; +defcolor_line_numbers_back = 0xFF808080; +defcolor_line_numbers_text = 0xFFD6D6D6; diff --git a/ship_files/themes/theme-strange.4coder b/ship_files/themes/theme-strange.4coder index a023e650..5dad726e 100644 --- a/ship_files/themes/theme-strange.4coder +++ b/ship_files/themes/theme-strange.4coder @@ -42,3 +42,5 @@ defcolor_pop2 = 0xFFFF0000; defcolor_back_cycle = {0x0CA00000, 0x0C00A000, 0x0C0000A0, 0x0CA0A000}; defcolor_text_cycle = {0xFFF00000, 0xFF00F000, 0xFF0080F0, 0xFFF0F000}; +defcolor_line_numbers_back = 0xFF262626; +defcolor_line_numbers_text = 0xFF8880C0; diff --git a/ship_files/themes/theme-sunlight.4coder b/ship_files/themes/theme-sunlight.4coder index 9439f4e3..b7c09653 100644 --- a/ship_files/themes/theme-sunlight.4coder +++ b/ship_files/themes/theme-sunlight.4coder @@ -40,3 +40,6 @@ defcolor_pop2 = 0xFF00C5FF; defcolor_back_cycle = {0x14A00000, 0x1400A000, 0x140000A0, 0x14A0A000}; defcolor_text_cycle = {0xFFF00000, 0xFF00C030, 0xFF0000F0, 0xFFF0F000}; + +defcolor_line_numbers_back = 0xFFC7C7C7; +defcolor_line_numbers_text = 0xFF87878F; diff --git a/ship_files/themes/theme-twilight.4coder b/ship_files/themes/theme-twilight.4coder index ce266643..22f6f0fa 100644 --- a/ship_files/themes/theme-twilight.4coder +++ b/ship_files/themes/theme-twilight.4coder @@ -8,7 +8,7 @@ defcolor_list_item_hover = defcolor_margin_hover; defcolor_list_item_active = defcolor_margin_active; defcolor_cursor = {0xFFEEE800, 0xFFEE00E8}; defcolor_at_cursor = defcolor_back; -defcolor_highlight_cursor_line = 0xFF151F2A; +defcolor_highlight_cursor_line = 0xFF1A2634; defcolor_mark = 0xFF8BA8CC; defcolor_highlight = 0xFF037A7B; defcolor_at_highlight = defcolor_back; @@ -40,3 +40,6 @@ defcolor_pop2 = 0xFFFF200D; defcolor_back_cycle = {0x0EA00000, 0x0D00A000, 0x0D0000A0, 0x0EA0A000}; defcolor_text_cycle = {0xFFF00000, 0xFF00C030, 0xFF0040F0, 0xFFB0B000}; + +defcolor_line_numbers_back = 0xFF1A2634; +defcolor_line_numbers_text = 0xFF6F817E; diff --git a/ship_files/themes/theme-wombat.4coder b/ship_files/themes/theme-wombat.4coder index 4a0501c2..3d130606 100644 --- a/ship_files/themes/theme-wombat.4coder +++ b/ship_files/themes/theme-wombat.4coder @@ -42,3 +42,6 @@ defcolor_pop2 = defcolor_highlight_junk; defcolor_back_cycle = {0x10A00000, 0x0C00A000, 0x0C0000A0, 0x0CA0A000}; defcolor_text_cycle = {0xFFA00000, 0xFF00A000, 0xFF0030B8, 0xFFA0A000}; + +defcolor_line_numbers_back = 0xFF202020; +defcolor_line_numbers_text = 0xFF737067; From 9dd79d59579dbd107a57650894dd4c720831cd83 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 26 Jan 2020 18:27:38 -0800 Subject: [PATCH 120/128] Fix drive letter problem; add unkillable setting --- 4ed_api_implementation.cpp | 19 ++++++++++++------- 4ed_file.h | 1 + custom/4coder_base_types.cpp | 12 ++++++++++++ custom/4coder_lists.cpp | 12 ++++++++++-- custom/4coder_types.h | 1 + custom/generated/command_metadata.h | 8 ++++---- 6 files changed, 40 insertions(+), 13 deletions(-) diff --git a/4ed_api_implementation.cpp b/4ed_api_implementation.cpp index e1607aaf..9b668788 100644 --- a/4ed_api_implementation.cpp +++ b/4ed_api_implementation.cpp @@ -799,6 +799,11 @@ buffer_get_setting(Application_Links *app, Buffer_ID buffer_id, Buffer_Setting_I *value_out = file->settings.unimportant; }break; + case BufferSetting_Unkillable: + { + *value_out = (file->settings.never_kill || file->settings.unkillable); + }break; + case BufferSetting_ReadOnly: { *value_out = file->settings.read_only; @@ -837,14 +842,14 @@ buffer_set_setting(Application_Links *app, Buffer_ID buffer_id, Buffer_Setting_I } }break; + case BufferSetting_Unkillable: + { + file->settings.unkillable = (value != 0); + }break; + case BufferSetting_ReadOnly: { - if (value){ - file->settings.read_only = true; - } - else{ - file->settings.read_only = false; - } + file->settings.read_only = (value != 0); }break; case BufferSetting_RecordsHistory: @@ -943,7 +948,7 @@ buffer_kill(Application_Links *app, Buffer_ID buffer_id, Buffer_Kill_Flag flags) Editing_File *file = imp_get_file(models, buffer_id); Buffer_Kill_Result result = BufferKillResult_DoesNotExist; if (api_check_buffer(file)){ - if (!file->settings.never_kill){ + if (!file->settings.never_kill && !file->settings.unkillable){ b32 needs_to_save = file_needs_save(file); if (!needs_to_save || (flags & BufferKill_AlwaysKill) != 0){ Thread_Context *tctx = app->tctx; diff --git a/4ed_file.h b/4ed_file.h index 8844aad7..e292bbb2 100644 --- a/4ed_file.h +++ b/4ed_file.h @@ -31,6 +31,7 @@ struct Editing_File_Settings{ b8 is_initialized; b8 unimportant; b8 read_only; + b8 unkillable; b8 never_kill; }; diff --git a/custom/4coder_base_types.cpp b/custom/4coder_base_types.cpp index 4df57089..6585e4e7 100644 --- a/custom/4coder_base_types.cpp +++ b/custom/4coder_base_types.cpp @@ -4321,6 +4321,18 @@ string_remove_last_folder(String_Const_u32 str){ return(str); } +function b32 +string_looks_like_drive_letter(String_Const_u8 string){ + b32 result = false; + if (string.size == 3 && + character_is_alpha(string.str[0]) && + string.str[1] == ':' && + character_is_slash(string.str[2])){ + result = true; + } + return(result); +} + function String_Const_char string_remove_front_of_path(String_Const_char str){ i64 slash_pos = string_find_last_slash(str); diff --git a/custom/4coder_lists.cpp b/custom/4coder_lists.cpp index 443c5f74..26595d4b 100644 --- a/custom/4coder_lists.cpp +++ b/custom/4coder_lists.cpp @@ -638,7 +638,11 @@ CUSTOM_DOC("Interactively open a file out of the file system.") if (HasFlag(attribs.flags, FileAttribute_IsDirectory)){ set_hot_directory(app, full_file_name); continue; - } + } + if (string_looks_like_drive_letter(file_name)){ + set_hot_directory(app, file_name); + continue; + } if (query_create_folder(app, file_name)){ set_hot_directory(app, full_file_name); continue; @@ -687,7 +691,11 @@ CUSTOM_DOC("Interactively creates a new file.") if (HasFlag(attribs.flags, FileAttribute_IsDirectory)){ set_hot_directory(app, full_file_name); continue; - } + } + if (string_looks_like_drive_letter(file_name)){ + set_hot_directory(app, file_name); + continue; + } if (query_create_folder(app, file_name)){ set_hot_directory(app, full_file_name); continue; diff --git a/custom/4coder_types.h b/custom/4coder_types.h index b6feca08..e979bd8c 100644 --- a/custom/4coder_types.h +++ b/custom/4coder_types.h @@ -178,6 +178,7 @@ enum{ BufferSetting_Unimportant, BufferSetting_ReadOnly, BufferSetting_RecordsHistory, + BufferSetting_Unkillable, }; api(custom) diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index d5f6e936..acd7f03e 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -275,7 +275,7 @@ static Command_Metadata fcoder_metacmd_table[230] = { { 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, 630 }, { 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, 753 }, +{ 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, 761 }, { 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 }, @@ -316,8 +316,8 @@ static Command_Metadata fcoder_metacmd_table[230] = { { 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, 581 }, { 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, 682 }, { 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, 520 }, -{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 657 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 707 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 661 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 715 }, { 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, 612 }, { 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, 510 }, { 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 }, @@ -450,7 +450,7 @@ static Command_Metadata fcoder_metacmd_table[230] = { { 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, 1524 }, { PROC_LINKS(test_double_backspace, 0), false, "test_double_backspace", 21, "Made for testing purposes (I should have deleted this if you are reading it let me know)", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 115 }, -{ 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, 777 }, +{ 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, 785 }, { 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, 574 }, { 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, 561 }, { 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, 667 }, From bff434be531674091cc492b801bc91a4b9b34f77 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 26 Jan 2020 19:32:54 -0800 Subject: [PATCH 121/128] Better highlighting in listers, panel margin color fix --- custom/4coder_default_colors.cpp | 8 ++-- custom/4coder_draw.cpp | 40 ++++++++++++++++---- custom/4coder_lister_base.cpp | 4 +- custom/4coder_log_parser.cpp | 2 +- custom/4coder_tutorial.cpp | 10 ++--- ship_files/themes/theme-4coder.4coder | 6 +-- ship_files/themes/theme-handmade-hero.4coder | 6 +-- ship_files/themes/theme-hjortshoej.4coder | 6 +-- ship_files/themes/theme-midnight.4coder | 6 +-- ship_files/themes/theme-stb-dark.4coder | 6 +-- ship_files/themes/theme-stb.4coder | 6 +-- ship_files/themes/theme-strange.4coder | 6 +-- ship_files/themes/theme-sunlight.4coder | 6 +-- ship_files/themes/theme-twilight.4coder | 6 +-- ship_files/themes/theme-wombat.4coder | 6 +-- 15 files changed, 74 insertions(+), 50 deletions(-) diff --git a/custom/4coder_default_colors.cpp b/custom/4coder_default_colors.cpp index 9a9ba453..022b8dc2 100644 --- a/custom/4coder_default_colors.cpp +++ b/custom/4coder_default_colors.cpp @@ -104,7 +104,7 @@ make_color_table(Application_Links *app, Arena *arena){ function void set_default_color_scheme(Application_Links *app){ if (global_theme_arena.base_allocator == 0){ - global_theme_arena = make_arena_system(); + global_theme_arena = make_arena_system(); } Arena *arena = &global_theme_arena; @@ -120,9 +120,9 @@ set_default_color_scheme(Application_Links *app){ default_color_table.arrays[defcolor_margin] = make_colors(arena, 0xFF181818); default_color_table.arrays[defcolor_margin_hover] = make_colors(arena, 0xFF252525); default_color_table.arrays[defcolor_margin_active] = make_colors(arena, 0xFF323232); - default_color_table.arrays[defcolor_list_item] = make_colors(arena, 0xFF181818); - default_color_table.arrays[defcolor_list_item_hover] = make_colors(arena, 0xFF252525); - default_color_table.arrays[defcolor_list_item_active] = make_colors(arena, 0xFF323232); + default_color_table.arrays[defcolor_list_item] = make_colors(arena, 0xFF181818, 0xFF0C0C0C); + default_color_table.arrays[defcolor_list_item_hover] = make_colors(arena, 0xFF252525, 0xFF0C0C0C); + default_color_table.arrays[defcolor_list_item_active] = make_colors(arena, 0xFF323232, 0xFF0C0C0C); default_color_table.arrays[defcolor_cursor] = make_colors(arena, 0xFF00EE00, 0xFFEE7700); default_color_table.arrays[defcolor_at_cursor] = make_colors(arena, 0xFF0C0C0C); default_color_table.arrays[defcolor_highlight_cursor_line] = make_colors(arena, 0xFF1E1E1E); diff --git a/custom/4coder_draw.cpp b/custom/4coder_draw.cpp index d6ebc6cf..4121ae13 100644 --- a/custom/4coder_draw.cpp +++ b/custom/4coder_draw.cpp @@ -12,21 +12,45 @@ draw_text_layout_default(Application_Links *app, Text_Layout_ID layout_id){ } function FColor -get_margin_color(i32 level){ +get_item_margin_color(i32 level, i32 sub_id){ FColor margin = fcolor_zero(); switch (level){ default: case UIHighlight_None: { - margin = fcolor_id(defcolor_list_item); + margin = fcolor_id(defcolor_list_item, sub_id); }break; case UIHighlight_Hover: { - margin = fcolor_id(defcolor_list_item_hover); + margin = fcolor_id(defcolor_list_item_hover, sub_id); }break; case UIHighlight_Active: { - margin = fcolor_id(defcolor_list_item_active); + margin = fcolor_id(defcolor_list_item_active, sub_id); + }break; + } + return(margin); +} +function FColor +get_item_margin_color(i32 level){ + return(get_item_margin_color(level, 0)); +} +function FColor +get_panel_margin_color(i32 level){ + FColor margin = fcolor_zero(); + switch (level){ + default: + case UIHighlight_None: + { + margin = fcolor_id(defcolor_margin); + }break; + case UIHighlight_Hover: + { + margin = fcolor_id(defcolor_margin_hover); + }break; + case UIHighlight_Active: + { + margin = fcolor_id(defcolor_margin_active); }break; } return(margin); @@ -254,7 +278,7 @@ draw_background_and_margin(Application_Links *app, View_ID view, FColor margin, 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); + FColor margin_color = get_panel_margin_color(is_active_view?UIHighlight_Active:UIHighlight_None); return(draw_background_and_margin(app, view, margin_color, fcolor_id(defcolor_back))); } @@ -832,10 +856,10 @@ draw_button(Application_Links *app, Rect_f32 rect, Vec2_f32 mouse_p, Face_ID fac hovered = true; } - FColor margin_color = get_margin_color(hovered?UIHighlight_Active:UIHighlight_None); - draw_rectangle_fcolor(app, rect, 3.f, margin_color); + UI_Highlight_Level highlight = hovered?UIHighlight_Active:UIHighlight_None; + draw_rectangle_fcolor(app, rect, 3.f, get_item_margin_color(highlight)); rect = rect_inner(rect, 3.f); - draw_rectangle_fcolor(app, rect, 3.f, fcolor_id(defcolor_back)); + draw_rectangle_fcolor(app, rect, 3.f, get_item_margin_color(highlight, 1)); Scratch_Block scratch(app); Fancy_String *fancy = push_fancy_string(scratch, 0, face, fcolor_id(defcolor_text_default), text); diff --git a/custom/4coder_lister_base.cpp b/custom/4coder_lister_base.cpp index 06341b16..7e98b502 100644 --- a/custom/4coder_lister_base.cpp +++ b/custom/4coder_lister_base.cpp @@ -266,8 +266,8 @@ lister_render(Application_Links *app, Frame_Info frame_info, View_ID view){ highlight = UIHighlight_Hover; } - draw_rectangle_fcolor(app, item_rect, 6.f, get_margin_color(highlight)); - draw_rectangle_fcolor(app, item_inner, 6.f, fcolor_id(defcolor_back)); + draw_rectangle_fcolor(app, item_rect, 6.f, get_item_margin_color(highlight)); + draw_rectangle_fcolor(app, item_inner, 6.f, get_item_margin_color(highlight, 1)); Fancy_Line line = {}; push_fancy_string(scratch, &line, fcolor_id(defcolor_text_default), node->string); diff --git a/custom/4coder_log_parser.cpp b/custom/4coder_log_parser.cpp index dfbccc96..c2b8a3c9 100644 --- a/custom/4coder_log_parser.cpp +++ b/custom/4coder_log_parser.cpp @@ -672,7 +672,7 @@ log_graph_render(Application_Links *app, Frame_Info frame_info, View_ID view){ Rect_f32 view_rect = view_get_screen_rect(app, view); Rect_f32 inner = rect_inner(view_rect, 3); draw_rectangle_fcolor(app, view_rect, 0.f, - get_margin_color(is_active_view?UIHighlight_Active:UIHighlight_None)); + get_item_margin_color(is_active_view?UIHighlight_Active:UIHighlight_None)); draw_rectangle_fcolor(app, inner, 0.f, fcolor_id(defcolor_back)); Rect_f32 prev_clip = draw_set_clip(app, inner); diff --git a/custom/4coder_tutorial.cpp b/custom/4coder_tutorial.cpp index 33067db5..6f4c86cb 100644 --- a/custom/4coder_tutorial.cpp +++ b/custom/4coder_tutorial.cpp @@ -121,7 +121,7 @@ tutorial_render(Application_Links *app, Frame_Info frame_info, View_ID view_id){ View_ID active_view = get_active_view(app, Access_Always); b32 is_active_view = (active_view == view_id); - FColor margin_color = get_margin_color(is_active_view?UIHighlight_Active:UIHighlight_None); + FColor margin_color = get_panel_margin_color(is_active_view?UIHighlight_Active:UIHighlight_None); Rect_f32 region = draw_background_and_margin(app, view_id, margin_color, margin_color); Rect_f32 prev_clip = draw_set_clip(app, region); @@ -152,9 +152,9 @@ tutorial_render(Application_Links *app, Frame_Info frame_info, View_ID view_id){ Rect_f32_Pair pair = rect_split_left_right(footer, b_width); footer = pair.max; footer.x0 += 10.f; - if (draw_button(app, pair.min, m_p, face, string_u8_litexpr("minimize"))){ - tutorial.hover_action = TutorialAction_Minimize; - } + if (draw_button(app, pair.min, m_p, face, string_u8_litexpr("minimize"))){ + tutorial.hover_action = TutorialAction_Minimize; + } } { @@ -241,7 +241,7 @@ tutorial_run_loop(Application_Links *app){ case CoreCode_ClickActivateView: { tutorial_maximize(app); - tutorial_action(app, tutorial.hover_action); + tutorial_action(app, tutorial.hover_action); change_active_panel(app); }break; diff --git a/ship_files/themes/theme-4coder.4coder b/ship_files/themes/theme-4coder.4coder index 879ff82e..b60ec7b2 100644 --- a/ship_files/themes/theme-4coder.4coder +++ b/ship_files/themes/theme-4coder.4coder @@ -3,9 +3,9 @@ defcolor_back = 0xFF0C0C0C; defcolor_margin = 0xFF181818; defcolor_margin_hover = 0xFF252525; defcolor_margin_active = 0xFF323232; -defcolor_list_item = defcolor_margin; -defcolor_list_item_hover = defcolor_margin_hover; -defcolor_list_item_active = defcolor_margin_active; +defcolor_list_item = {defcolor_margin, defcolor_back}; +defcolor_list_item_hover = {defcolor_margin_hover, defcolor_margin}; +defcolor_list_item_active = {defcolor_margin_active, defcolor_margin_active}; defcolor_cursor = {0xFF00EE00, 0xFFEE7700}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF1E1E1E; diff --git a/ship_files/themes/theme-handmade-hero.4coder b/ship_files/themes/theme-handmade-hero.4coder index 54531399..2ede1758 100644 --- a/ship_files/themes/theme-handmade-hero.4coder +++ b/ship_files/themes/theme-handmade-hero.4coder @@ -4,9 +4,9 @@ defcolor_back = 0xFF161616; defcolor_margin = 0xFF262626; defcolor_margin_hover = 0xFF333333; defcolor_margin_active = 0xFF404040; -defcolor_list_item = defcolor_margin; -defcolor_list_item_hover = defcolor_margin_hover; -defcolor_list_item_active = defcolor_margin_active; +defcolor_list_item = {defcolor_margin, defcolor_back}; +defcolor_list_item_hover = {defcolor_margin_hover, defcolor_margin}; +defcolor_list_item_active = {defcolor_margin_active, defcolor_margin_active}; defcolor_cursor = {0xFF40FF40, 0xFFFF4040}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF121E12; diff --git a/ship_files/themes/theme-hjortshoej.4coder b/ship_files/themes/theme-hjortshoej.4coder index b84e7b70..577cbf12 100644 --- a/ship_files/themes/theme-hjortshoej.4coder +++ b/ship_files/themes/theme-hjortshoej.4coder @@ -4,9 +4,9 @@ defcolor_back = 0xFFF0F0F0; defcolor_margin = 0xFF9E9E9E; defcolor_margin_hover = 0xFF7E7E7E; defcolor_margin_active = 0xFF5C5C5C; -defcolor_list_item = defcolor_margin; -defcolor_list_item_hover = defcolor_margin_hover; -defcolor_list_item_active = defcolor_margin_active; +defcolor_list_item = {defcolor_margin, defcolor_back}; +defcolor_list_item_hover = {defcolor_margin_hover, defcolor_margin}; +defcolor_list_item_active = {defcolor_margin_active, defcolor_margin_active}; defcolor_cursor = {0xFF000000, 0xFF008080}; defcolor_at_cursor = 0xFFD6D6D6; defcolor_highlight_cursor_line = 0xFFB8B098; diff --git a/ship_files/themes/theme-midnight.4coder b/ship_files/themes/theme-midnight.4coder index b0768625..28e09dfd 100644 --- a/ship_files/themes/theme-midnight.4coder +++ b/ship_files/themes/theme-midnight.4coder @@ -3,9 +3,9 @@ defcolor_back = 0xFF202020; defcolor_margin = 0xFF383838; defcolor_margin_hover = 0xFF404040; defcolor_margin_active = 0xFF484848; -defcolor_list_item = defcolor_margin; -defcolor_list_item_hover = defcolor_margin_hover; -defcolor_list_item_active = defcolor_margin_active; +defcolor_list_item = {defcolor_margin, defcolor_back}; +defcolor_list_item_hover = {defcolor_margin_hover, defcolor_margin}; +defcolor_list_item_active = {defcolor_margin_active, defcolor_margin_active}; defcolor_cursor = {0xFFDDDDDD, 0xFFDD7777}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF383838; diff --git a/ship_files/themes/theme-stb-dark.4coder b/ship_files/themes/theme-stb-dark.4coder index e747e24a..a5b0b9f5 100644 --- a/ship_files/themes/theme-stb-dark.4coder +++ b/ship_files/themes/theme-stb-dark.4coder @@ -3,9 +3,9 @@ defcolor_back = 0xFF303030; defcolor_margin = 0xFF383838; defcolor_margin_hover = 0xFF404040; defcolor_margin_active = 0xFF484848; -defcolor_list_item = defcolor_margin; -defcolor_list_item_hover = defcolor_margin_hover; -defcolor_list_item_active = defcolor_margin_active; +defcolor_list_item = {defcolor_margin, defcolor_back}; +defcolor_list_item_hover = {defcolor_margin_hover, defcolor_margin}; +defcolor_list_item_active = {defcolor_margin_active, defcolor_margin_active}; defcolor_cursor = {0xFFDDDDDD, 0xFFDDF0F0}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF383838; diff --git a/ship_files/themes/theme-stb.4coder b/ship_files/themes/theme-stb.4coder index 012be474..9c6e9556 100644 --- a/ship_files/themes/theme-stb.4coder +++ b/ship_files/themes/theme-stb.4coder @@ -3,9 +3,9 @@ defcolor_back = 0xFFD6D6D6; defcolor_margin = 0xFF9E9E9E; defcolor_margin_hover = 0xFF7E7E7E; defcolor_margin_active = 0xFF5C5C5C; -defcolor_list_item = defcolor_margin; -defcolor_list_item_hover = defcolor_margin_hover; -defcolor_list_item_active = defcolor_margin_active; +defcolor_list_item = {defcolor_margin, defcolor_back}; +defcolor_list_item_hover = {defcolor_margin_hover, defcolor_margin}; +defcolor_list_item_active = {defcolor_margin_active, defcolor_margin_active}; defcolor_cursor = {0xFF000000, 0xFF002020}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFFBCBCBC; diff --git a/ship_files/themes/theme-strange.4coder b/ship_files/themes/theme-strange.4coder index 5dad726e..ffc1b76f 100644 --- a/ship_files/themes/theme-strange.4coder +++ b/ship_files/themes/theme-strange.4coder @@ -4,9 +4,9 @@ defcolor_back = 0xFF161616; defcolor_margin = 0xFF606590; defcolor_margin_hover = 0xFF606590; defcolor_margin_active = 0xFF9A99E7; -defcolor_list_item = defcolor_margin; -defcolor_list_item_hover = defcolor_margin_hover; -defcolor_list_item_active = defcolor_margin_active; +defcolor_list_item = {defcolor_margin, defcolor_back}; +defcolor_list_item_hover = {defcolor_margin_hover, defcolor_margin}; +defcolor_list_item_active = {defcolor_margin_active, defcolor_margin_active}; defcolor_cursor = {0xFFd96e26, 0xFFd9d926}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF002222; diff --git a/ship_files/themes/theme-sunlight.4coder b/ship_files/themes/theme-sunlight.4coder index b7c09653..ccb1cd6f 100644 --- a/ship_files/themes/theme-sunlight.4coder +++ b/ship_files/themes/theme-sunlight.4coder @@ -3,9 +3,9 @@ defcolor_back = 0xFFDFD5D0; defcolor_margin = 0xFFC7C7C7; defcolor_margin_hover = 0xFFBFBFBF; defcolor_margin_active = 0xFFB7B7B7; -defcolor_list_item = defcolor_margin; -defcolor_list_item_hover = defcolor_margin_hover; -defcolor_list_item_active = defcolor_margin_active; +defcolor_list_item = {defcolor_margin, defcolor_back}; +defcolor_list_item_hover = {defcolor_margin_hover, defcolor_margin}; +defcolor_list_item_active = {defcolor_margin_active, defcolor_margin_active}; defcolor_cursor = {0xFF222222, 0xFF442244}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFFC7C7C7; diff --git a/ship_files/themes/theme-twilight.4coder b/ship_files/themes/theme-twilight.4coder index 22f6f0fa..11f8d305 100644 --- a/ship_files/themes/theme-twilight.4coder +++ b/ship_files/themes/theme-twilight.4coder @@ -3,9 +3,9 @@ defcolor_back = 0xFF090D12; defcolor_margin = 0xFF1A2634; defcolor_margin_hover = 0xFF2D415B; defcolor_margin_active = 0xFF405D82; -defcolor_list_item = defcolor_margin; -defcolor_list_item_hover = defcolor_margin_hover; -defcolor_list_item_active = defcolor_margin_active; +defcolor_list_item = {defcolor_margin, defcolor_back}; +defcolor_list_item_hover = {defcolor_margin_hover, defcolor_margin}; +defcolor_list_item_active = {defcolor_margin_active, defcolor_margin_active}; defcolor_cursor = {0xFFEEE800, 0xFFEE00E8}; defcolor_at_cursor = defcolor_back; defcolor_highlight_cursor_line = 0xFF1A2634; diff --git a/ship_files/themes/theme-wombat.4coder b/ship_files/themes/theme-wombat.4coder index 3d130606..ee927d23 100644 --- a/ship_files/themes/theme-wombat.4coder +++ b/ship_files/themes/theme-wombat.4coder @@ -4,9 +4,9 @@ defcolor_back = 0xFF242424; defcolor_margin = 0xFF181818; defcolor_margin_hover = 0xFF252525; defcolor_margin_active = 0xFF323232; -defcolor_list_item = defcolor_margin; -defcolor_list_item_hover = defcolor_margin_hover; -defcolor_list_item_active = defcolor_margin_active; +defcolor_list_item = {defcolor_margin, defcolor_back}; +defcolor_list_item_hover = {defcolor_margin_hover, defcolor_margin}; +defcolor_list_item_active = {defcolor_margin_active, defcolor_margin_active}; defcolor_cursor = {0xFF656565, 0xFF654065}; defcolor_highlight = 0xFF636066; defcolor_mark = defcolor_cursor; From 797e05a3a24dae69ed54cb1e27b635e993a07f5b Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 26 Jan 2020 19:36:02 -0800 Subject: [PATCH 122/128] Fix paste crash when view is not editable --- custom/4coder_clipboard.cpp | 126 +++++++++++++++------------- custom/generated/command_metadata.h | 6 +- 2 files changed, 69 insertions(+), 63 deletions(-) diff --git a/custom/4coder_clipboard.cpp b/custom/4coder_clipboard.cpp index ba37ad61..8b562253 100644 --- a/custom/4coder_clipboard.cpp +++ b/custom/4coder_clipboard.cpp @@ -46,23 +46,25 @@ CUSTOM_DOC("At the cursor, insert the text at the top of the clipboard.") Managed_Scope scope = view_get_managed_scope(app, view); Rewrite_Type *next_rewrite = scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); - *next_rewrite = Rewrite_Paste; - i32 *paste_index = scope_attachment(app, scope, view_paste_index_loc, i32); - *paste_index = 0; - - Scratch_Block scratch(app); - - String_Const_u8 string = push_clipboard_index(app, scratch, 0, *paste_index); - if (string.size > 0){ - Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); + if (next_rewrite != 0){ + *next_rewrite = Rewrite_Paste; + i32 *paste_index = scope_attachment(app, scope, view_paste_index_loc, i32); + *paste_index = 0; - i64 pos = view_get_cursor_pos(app, view); - buffer_replace_range(app, buffer, Ii64(pos), string); - view_set_mark(app, view, seek_pos(pos)); - view_set_cursor_and_preferred_x(app, view, seek_pos(pos + (i32)string.size)); + Scratch_Block scratch(app); - ARGB_Color argb = fcolor_resolve(fcolor_id(defcolor_paste)); - buffer_post_fade(app, buffer, 0.667f, Ii64_size(pos, string.size), argb); + String_Const_u8 string = push_clipboard_index(app, scratch, 0, *paste_index); + if (string.size > 0){ + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); + + i64 pos = view_get_cursor_pos(app, view); + buffer_replace_range(app, buffer, Ii64(pos), string); + view_set_mark(app, view, seek_pos(pos)); + view_set_cursor_and_preferred_x(app, view, seek_pos(pos + (i32)string.size)); + + ARGB_Color argb = fcolor_resolve(fcolor_id(defcolor_paste)); + buffer_post_fade(app, buffer, 0.667f, Ii64_size(pos, string.size), argb); + } } } } @@ -79,29 +81,31 @@ CUSTOM_DOC("If the previous command was paste or paste_next, replaces the paste no_mark_snap_to_cursor(app, scope); Rewrite_Type *rewrite = scope_attachment(app, scope, view_rewrite_loc, Rewrite_Type); - if (*rewrite == Rewrite_Paste){ - Rewrite_Type *next_rewrite = scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); - *next_rewrite = Rewrite_Paste; - - i32 *paste_index_ptr = scope_attachment(app, scope, view_paste_index_loc, i32); - i32 paste_index = (*paste_index_ptr) + 1; - *paste_index_ptr = paste_index; - - String_Const_u8 string = push_clipboard_index(app, scratch, 0, paste_index); - - Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); - - Range_i64 range = get_view_range(app, view); - i64 pos = range.min; - - buffer_replace_range(app, buffer, range, string); - view_set_cursor_and_preferred_x(app, view, seek_pos(pos + string.size)); - - ARGB_Color argb = fcolor_resolve(fcolor_id(defcolor_paste)); - buffer_post_fade(app, buffer, 0.667f, Ii64_size(pos, string.size), argb); - } - else{ - paste(app); + if (rewrite != 0){ + if (*rewrite == Rewrite_Paste){ + Rewrite_Type *next_rewrite = scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); + *next_rewrite = Rewrite_Paste; + + i32 *paste_index_ptr = scope_attachment(app, scope, view_paste_index_loc, i32); + i32 paste_index = (*paste_index_ptr) + 1; + *paste_index_ptr = paste_index; + + String_Const_u8 string = push_clipboard_index(app, scratch, 0, paste_index); + + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); + + Range_i64 range = get_view_range(app, view); + i64 pos = range.min; + + buffer_replace_range(app, buffer, range, string); + view_set_cursor_and_preferred_x(app, view, seek_pos(pos + string.size)); + + ARGB_Color argb = fcolor_resolve(fcolor_id(defcolor_paste)); + buffer_post_fade(app, buffer, 0.667f, Ii64_size(pos, string.size), argb); + } + else{ + paste(app); + } } } } @@ -131,28 +135,30 @@ CUSTOM_COMMAND_SIG(multi_paste){ Managed_Scope scope = view_get_managed_scope(app, view); Rewrite_Type *rewrite = scope_attachment(app, scope, view_rewrite_loc, Rewrite_Type); - if (*rewrite == Rewrite_Paste){ - Rewrite_Type *next_rewrite = scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); - *next_rewrite = Rewrite_Paste; - i32 *paste_index_ptr = scope_attachment(app, scope, view_paste_index_loc, i32); - i32 paste_index = (*paste_index_ptr) + 1; - *paste_index_ptr = paste_index; - - String_Const_u8 string = push_clipboard_index(app, scratch, 0, paste_index); - - String_Const_u8 insert_string = push_u8_stringf(scratch, "\n%.*s", string_expand(string)); - - Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); - Range_i64 range = get_view_range(app, view); - buffer_replace_range(app, buffer, Ii64(range.max), insert_string); - view_set_mark(app, view, seek_pos(range.max + 1)); - view_set_cursor_and_preferred_x(app, view, seek_pos(range.max + insert_string.size)); - - ARGB_Color argb = fcolor_resolve(fcolor_id(defcolor_paste)); - view_post_fade(app, buffer, 0.667f, Ii64(range.max + 1, range.max + insert_string.size), argb); - } - else{ - paste(app); + if (rewrite != 0){ + if (*rewrite == Rewrite_Paste){ + Rewrite_Type *next_rewrite = scope_attachment(app, scope, view_next_rewrite_loc, Rewrite_Type); + *next_rewrite = Rewrite_Paste; + i32 *paste_index_ptr = scope_attachment(app, scope, view_paste_index_loc, i32); + i32 paste_index = (*paste_index_ptr) + 1; + *paste_index_ptr = paste_index; + + String_Const_u8 string = push_clipboard_index(app, scratch, 0, paste_index); + + String_Const_u8 insert_string = push_u8_stringf(scratch, "\n%.*s", string_expand(string)); + + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible); + Range_i64 range = get_view_range(app, view); + buffer_replace_range(app, buffer, Ii64(range.max), insert_string); + view_set_mark(app, view, seek_pos(range.max + 1)); + view_set_cursor_and_preferred_x(app, view, seek_pos(range.max + insert_string.size)); + + ARGB_Color argb = fcolor_resolve(fcolor_id(defcolor_paste)); + view_post_fade(app, buffer, 0.667f, Ii64(range.max + 1, range.max + insert_string.size), argb); + } + else{ + paste(app); + } } } } diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index acd7f03e..9f806e50 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -391,9 +391,9 @@ static Command_Metadata fcoder_metacmd_table[230] = { { 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, 383 }, { 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, 375 }, { 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, 109 }, -{ 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, 70 }, -{ 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, 116 }, +{ 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, 113 }, +{ 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, 72 }, +{ 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, 120 }, { 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 }, From 88e618619293bbc422ff998b89acab8d19e9d8fe Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 26 Jan 2020 21:24:26 -0800 Subject: [PATCH 123/128] Added load_theme_current_buffer command and updated changes.txt --- custom/4coder_config.cpp | 40 ++++ custom/generated/command_metadata.h | 287 ++++++++++++++-------------- ship_files/changes.txt | 5 + 3 files changed, 190 insertions(+), 142 deletions(-) diff --git a/custom/4coder_config.cpp b/custom/4coder_config.cpp index b013bb91..337914ae 100644 --- a/custom/4coder_config.cpp +++ b/custom/4coder_config.cpp @@ -1419,6 +1419,17 @@ theme_parse__data(Application_Links *app, Arena *arena, String_Const_u8 file_nam return(parsed); } +function Config* +theme_parse__buffer(Application_Links *app, Arena *arena, Buffer_ID buffer, Arena *color_arena, Color_Table *color_table){ + String_Const_u8 contents = push_whole_buffer(app, arena, buffer); + Config *parsed = 0; + if (contents.str != 0){ + String_Const_u8 file_name = push_buffer_file_name(app, arena, buffer); + parsed = theme_parse__data(app, arena, file_name, contents, color_arena, color_table); + } + return(parsed); +} + function Config* theme_parse__file_handle(Application_Links *app, Arena *arena, String_Const_u8 file_name, FILE *file, Arena *color_arena, Color_Table *color_table){ Data data = dump_file_handle(arena, file); @@ -1608,6 +1619,35 @@ load_theme_file_into_live_set(Application_Links *app, char *file_name){ save_theme(color_table, name); } +CUSTOM_COMMAND_SIG(load_theme_current_buffer) +CUSTOM_DOC("Parse the current buffer as a theme file and add the theme to the theme list. If the buffer has a .4coder postfix in it's name, it is removed when the name is saved.") +{ + View_ID view = get_active_view(app, Access_ReadVisible); + Buffer_ID buffer = view_get_buffer(app, view, Access_ReadVisible); + + Scratch_Block scratch(app); + String_Const_u8 file_name = push_buffer_file_name(app, scratch, buffer); + if (file_name.size > 0){ + Arena *arena = &global_theme_arena; + Color_Table color_table = make_color_table(app, arena); + Scratch_Block scratch(app); + Config *config = theme_parse__buffer(app, scratch, buffer, arena, &color_table); + String_Const_u8 error_text = config_stringize_errors(app, scratch, config); + print_message(app, error_text); + + String_Const_u8 name = string_front_of_path(file_name); + if (string_match(string_postfix(name, 7), string_u8_litexpr(".4coder"))){ + name = string_chop(name, 7); + } + save_theme(color_table, name); + + Color_Table_Node *node = global_theme_list.last; + if (node != 0 && string_match(node->name, name)){ + active_color_table = node->table; + } + } +} + function void load_folder_of_themes_into_live_set(Application_Links *app, String_Const_u8 path){ Scratch_Block scratch(app, Scratch_Share); diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 9f806e50..8167c98d 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -2,7 +2,7 @@ #define command_id(c) (fcoder_metacmd_ID_##c) #define command_metadata(c) (&fcoder_metacmd_table[command_id(c)]) #define command_metadata_by_id(id) (&fcoder_metacmd_table[id]) -#define command_one_past_last_id 230 +#define command_one_past_last_id 231 #if defined(CUSTOM_COMMAND_SIG) #define PROC_LINKS(x,y) x #else @@ -99,6 +99,7 @@ CUSTOM_COMMAND_SIG(list_all_locations_of_type_definition_of_identifier); CUSTOM_COMMAND_SIG(list_all_substring_locations); CUSTOM_COMMAND_SIG(list_all_substring_locations_case_insensitive); CUSTOM_COMMAND_SIG(load_project); +CUSTOM_COMMAND_SIG(load_theme_current_buffer); CUSTOM_COMMAND_SIG(load_themes_default_folder); CUSTOM_COMMAND_SIG(load_themes_hot_directory); CUSTOM_COMMAND_SIG(make_directory_query); @@ -251,7 +252,7 @@ char *source_name; i32 source_name_len; i32 line_number; }; -static Command_Metadata fcoder_metacmd_table[230] = { +static Command_Metadata fcoder_metacmd_table[231] = { { 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, 407 }, { 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, 417 }, @@ -342,6 +343,7 @@ static Command_Metadata fcoder_metacmd_table[230] = { { 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, 171 }, { 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, 183 }, { 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_theme_current_buffer, 0), false, "load_theme_current_buffer", 25, "Parse the current buffer as a theme file and add the theme to the theme list. If the buffer has a .4coder postfix in it's name, it is removed when the name is saved.", 165, "w:\\4ed\\code\\custom\\4coder_config.cpp", 36, 1622 }, { 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, 1342 }, @@ -573,144 +575,145 @@ static i32 fcoder_metacmd_ID_list_all_locations_of_type_definition_of_identifier static i32 fcoder_metacmd_ID_list_all_substring_locations = 87; static i32 fcoder_metacmd_ID_list_all_substring_locations_case_insensitive = 88; static i32 fcoder_metacmd_ID_load_project = 89; -static i32 fcoder_metacmd_ID_load_themes_default_folder = 90; -static i32 fcoder_metacmd_ID_load_themes_hot_directory = 91; -static i32 fcoder_metacmd_ID_make_directory_query = 92; -static i32 fcoder_metacmd_ID_miblo_decrement_basic = 93; -static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp = 94; -static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp_minute = 95; -static i32 fcoder_metacmd_ID_miblo_increment_basic = 96; -static i32 fcoder_metacmd_ID_miblo_increment_time_stamp = 97; -static i32 fcoder_metacmd_ID_miblo_increment_time_stamp_minute = 98; -static i32 fcoder_metacmd_ID_mouse_wheel_change_face_size = 99; -static i32 fcoder_metacmd_ID_mouse_wheel_scroll = 100; -static i32 fcoder_metacmd_ID_move_down = 101; -static i32 fcoder_metacmd_ID_move_down_10 = 102; -static i32 fcoder_metacmd_ID_move_down_textual = 103; -static i32 fcoder_metacmd_ID_move_down_to_blank_line = 104; -static i32 fcoder_metacmd_ID_move_down_to_blank_line_end = 105; -static i32 fcoder_metacmd_ID_move_down_to_blank_line_skip_whitespace = 106; -static i32 fcoder_metacmd_ID_move_left = 107; -static i32 fcoder_metacmd_ID_move_left_alpha_numeric_boundary = 108; -static i32 fcoder_metacmd_ID_move_left_alpha_numeric_or_camel_boundary = 109; -static i32 fcoder_metacmd_ID_move_left_token_boundary = 110; -static i32 fcoder_metacmd_ID_move_left_whitespace_boundary = 111; -static i32 fcoder_metacmd_ID_move_left_whitespace_or_token_boundary = 112; -static i32 fcoder_metacmd_ID_move_line_down = 113; -static i32 fcoder_metacmd_ID_move_line_up = 114; -static i32 fcoder_metacmd_ID_move_right = 115; -static i32 fcoder_metacmd_ID_move_right_alpha_numeric_boundary = 116; -static i32 fcoder_metacmd_ID_move_right_alpha_numeric_or_camel_boundary = 117; -static i32 fcoder_metacmd_ID_move_right_token_boundary = 118; -static i32 fcoder_metacmd_ID_move_right_whitespace_boundary = 119; -static i32 fcoder_metacmd_ID_move_right_whitespace_or_token_boundary = 120; -static i32 fcoder_metacmd_ID_move_up = 121; -static i32 fcoder_metacmd_ID_move_up_10 = 122; -static i32 fcoder_metacmd_ID_move_up_to_blank_line = 123; -static i32 fcoder_metacmd_ID_move_up_to_blank_line_end = 124; -static i32 fcoder_metacmd_ID_move_up_to_blank_line_skip_whitespace = 125; -static i32 fcoder_metacmd_ID_open_all_code = 126; -static i32 fcoder_metacmd_ID_open_all_code_recursive = 127; -static i32 fcoder_metacmd_ID_open_file_in_quotes = 128; -static i32 fcoder_metacmd_ID_open_in_other = 129; -static i32 fcoder_metacmd_ID_open_long_braces = 130; -static i32 fcoder_metacmd_ID_open_long_braces_break = 131; -static i32 fcoder_metacmd_ID_open_long_braces_semicolon = 132; -static i32 fcoder_metacmd_ID_open_matching_file_cpp = 133; -static i32 fcoder_metacmd_ID_open_panel_hsplit = 134; -static i32 fcoder_metacmd_ID_open_panel_vsplit = 135; -static i32 fcoder_metacmd_ID_page_down = 136; -static i32 fcoder_metacmd_ID_page_up = 137; -static i32 fcoder_metacmd_ID_paste = 138; -static i32 fcoder_metacmd_ID_paste_and_indent = 139; -static i32 fcoder_metacmd_ID_paste_next = 140; -static i32 fcoder_metacmd_ID_paste_next_and_indent = 141; -static i32 fcoder_metacmd_ID_place_in_scope = 142; -static i32 fcoder_metacmd_ID_profile_clear = 143; -static i32 fcoder_metacmd_ID_profile_disable = 144; -static i32 fcoder_metacmd_ID_profile_enable = 145; -static i32 fcoder_metacmd_ID_profile_inspect = 146; -static i32 fcoder_metacmd_ID_project_command_lister = 147; -static i32 fcoder_metacmd_ID_project_fkey_command = 148; -static i32 fcoder_metacmd_ID_project_go_to_root_directory = 149; -static i32 fcoder_metacmd_ID_query_replace = 150; -static i32 fcoder_metacmd_ID_query_replace_identifier = 151; -static i32 fcoder_metacmd_ID_query_replace_selection = 152; -static i32 fcoder_metacmd_ID_redo = 153; -static i32 fcoder_metacmd_ID_redo_all_buffers = 154; -static i32 fcoder_metacmd_ID_rename_file_query = 155; -static i32 fcoder_metacmd_ID_reopen = 156; -static i32 fcoder_metacmd_ID_replace_in_all_buffers = 157; -static i32 fcoder_metacmd_ID_replace_in_buffer = 158; -static i32 fcoder_metacmd_ID_replace_in_range = 159; -static i32 fcoder_metacmd_ID_reverse_search = 160; -static i32 fcoder_metacmd_ID_reverse_search_identifier = 161; -static i32 fcoder_metacmd_ID_save = 162; -static i32 fcoder_metacmd_ID_save_all_dirty_buffers = 163; -static i32 fcoder_metacmd_ID_save_to_query = 164; -static i32 fcoder_metacmd_ID_search = 165; -static i32 fcoder_metacmd_ID_search_identifier = 166; -static i32 fcoder_metacmd_ID_seek_beginning_of_line = 167; -static i32 fcoder_metacmd_ID_seek_beginning_of_textual_line = 168; -static i32 fcoder_metacmd_ID_seek_end_of_line = 169; -static i32 fcoder_metacmd_ID_seek_end_of_textual_line = 170; -static i32 fcoder_metacmd_ID_select_all = 171; -static i32 fcoder_metacmd_ID_select_next_scope_absolute = 172; -static i32 fcoder_metacmd_ID_select_next_scope_after_current = 173; -static i32 fcoder_metacmd_ID_select_prev_scope_absolute = 174; -static i32 fcoder_metacmd_ID_select_prev_top_most_scope = 175; -static i32 fcoder_metacmd_ID_select_surrounding_scope = 176; -static i32 fcoder_metacmd_ID_select_surrounding_scope_maximal = 177; -static i32 fcoder_metacmd_ID_set_eol_mode_from_contents = 178; -static i32 fcoder_metacmd_ID_set_eol_mode_to_binary = 179; -static i32 fcoder_metacmd_ID_set_eol_mode_to_crlf = 180; -static i32 fcoder_metacmd_ID_set_eol_mode_to_lf = 181; -static i32 fcoder_metacmd_ID_set_mark = 182; -static i32 fcoder_metacmd_ID_set_mode_to_notepad_like = 183; -static i32 fcoder_metacmd_ID_set_mode_to_original = 184; -static i32 fcoder_metacmd_ID_setup_build_bat = 185; -static i32 fcoder_metacmd_ID_setup_build_bat_and_sh = 186; -static i32 fcoder_metacmd_ID_setup_build_sh = 187; -static i32 fcoder_metacmd_ID_setup_new_project = 188; -static i32 fcoder_metacmd_ID_show_filebar = 189; -static i32 fcoder_metacmd_ID_show_scrollbar = 190; -static i32 fcoder_metacmd_ID_show_the_log_graph = 191; -static i32 fcoder_metacmd_ID_snipe_backward_whitespace_or_token_boundary = 192; -static i32 fcoder_metacmd_ID_snipe_forward_whitespace_or_token_boundary = 193; -static i32 fcoder_metacmd_ID_snippet_lister = 194; -static i32 fcoder_metacmd_ID_suppress_mouse = 195; -static i32 fcoder_metacmd_ID_swap_panels = 196; -static i32 fcoder_metacmd_ID_test_double_backspace = 197; -static i32 fcoder_metacmd_ID_theme_lister = 198; -static i32 fcoder_metacmd_ID_to_lowercase = 199; -static i32 fcoder_metacmd_ID_to_uppercase = 200; -static i32 fcoder_metacmd_ID_toggle_filebar = 201; -static i32 fcoder_metacmd_ID_toggle_fps_meter = 202; -static i32 fcoder_metacmd_ID_toggle_fullscreen = 203; -static i32 fcoder_metacmd_ID_toggle_highlight_enclosing_scopes = 204; -static i32 fcoder_metacmd_ID_toggle_highlight_line_at_cursor = 205; -static i32 fcoder_metacmd_ID_toggle_line_numbers = 206; -static i32 fcoder_metacmd_ID_toggle_line_wrap = 207; -static i32 fcoder_metacmd_ID_toggle_mouse = 208; -static i32 fcoder_metacmd_ID_toggle_paren_matching_helper = 209; -static i32 fcoder_metacmd_ID_toggle_show_whitespace = 210; -static i32 fcoder_metacmd_ID_toggle_virtual_whitespace = 211; -static i32 fcoder_metacmd_ID_tutorial_maximize = 212; -static i32 fcoder_metacmd_ID_tutorial_minimize = 213; -static i32 fcoder_metacmd_ID_uncomment_line = 214; -static i32 fcoder_metacmd_ID_undo = 215; -static i32 fcoder_metacmd_ID_undo_all_buffers = 216; -static i32 fcoder_metacmd_ID_view_buffer_other_panel = 217; -static i32 fcoder_metacmd_ID_view_jump_list_with_lister = 218; -static i32 fcoder_metacmd_ID_word_complete = 219; -static i32 fcoder_metacmd_ID_word_complete_drop_down = 220; -static i32 fcoder_metacmd_ID_write_block = 221; -static i32 fcoder_metacmd_ID_write_hack = 222; -static i32 fcoder_metacmd_ID_write_note = 223; -static i32 fcoder_metacmd_ID_write_space = 224; -static i32 fcoder_metacmd_ID_write_text_and_auto_indent = 225; -static i32 fcoder_metacmd_ID_write_text_input = 226; -static i32 fcoder_metacmd_ID_write_todo = 227; -static i32 fcoder_metacmd_ID_write_underscore = 228; -static i32 fcoder_metacmd_ID_write_zero_struct = 229; +static i32 fcoder_metacmd_ID_load_theme_current_buffer = 90; +static i32 fcoder_metacmd_ID_load_themes_default_folder = 91; +static i32 fcoder_metacmd_ID_load_themes_hot_directory = 92; +static i32 fcoder_metacmd_ID_make_directory_query = 93; +static i32 fcoder_metacmd_ID_miblo_decrement_basic = 94; +static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp = 95; +static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp_minute = 96; +static i32 fcoder_metacmd_ID_miblo_increment_basic = 97; +static i32 fcoder_metacmd_ID_miblo_increment_time_stamp = 98; +static i32 fcoder_metacmd_ID_miblo_increment_time_stamp_minute = 99; +static i32 fcoder_metacmd_ID_mouse_wheel_change_face_size = 100; +static i32 fcoder_metacmd_ID_mouse_wheel_scroll = 101; +static i32 fcoder_metacmd_ID_move_down = 102; +static i32 fcoder_metacmd_ID_move_down_10 = 103; +static i32 fcoder_metacmd_ID_move_down_textual = 104; +static i32 fcoder_metacmd_ID_move_down_to_blank_line = 105; +static i32 fcoder_metacmd_ID_move_down_to_blank_line_end = 106; +static i32 fcoder_metacmd_ID_move_down_to_blank_line_skip_whitespace = 107; +static i32 fcoder_metacmd_ID_move_left = 108; +static i32 fcoder_metacmd_ID_move_left_alpha_numeric_boundary = 109; +static i32 fcoder_metacmd_ID_move_left_alpha_numeric_or_camel_boundary = 110; +static i32 fcoder_metacmd_ID_move_left_token_boundary = 111; +static i32 fcoder_metacmd_ID_move_left_whitespace_boundary = 112; +static i32 fcoder_metacmd_ID_move_left_whitespace_or_token_boundary = 113; +static i32 fcoder_metacmd_ID_move_line_down = 114; +static i32 fcoder_metacmd_ID_move_line_up = 115; +static i32 fcoder_metacmd_ID_move_right = 116; +static i32 fcoder_metacmd_ID_move_right_alpha_numeric_boundary = 117; +static i32 fcoder_metacmd_ID_move_right_alpha_numeric_or_camel_boundary = 118; +static i32 fcoder_metacmd_ID_move_right_token_boundary = 119; +static i32 fcoder_metacmd_ID_move_right_whitespace_boundary = 120; +static i32 fcoder_metacmd_ID_move_right_whitespace_or_token_boundary = 121; +static i32 fcoder_metacmd_ID_move_up = 122; +static i32 fcoder_metacmd_ID_move_up_10 = 123; +static i32 fcoder_metacmd_ID_move_up_to_blank_line = 124; +static i32 fcoder_metacmd_ID_move_up_to_blank_line_end = 125; +static i32 fcoder_metacmd_ID_move_up_to_blank_line_skip_whitespace = 126; +static i32 fcoder_metacmd_ID_open_all_code = 127; +static i32 fcoder_metacmd_ID_open_all_code_recursive = 128; +static i32 fcoder_metacmd_ID_open_file_in_quotes = 129; +static i32 fcoder_metacmd_ID_open_in_other = 130; +static i32 fcoder_metacmd_ID_open_long_braces = 131; +static i32 fcoder_metacmd_ID_open_long_braces_break = 132; +static i32 fcoder_metacmd_ID_open_long_braces_semicolon = 133; +static i32 fcoder_metacmd_ID_open_matching_file_cpp = 134; +static i32 fcoder_metacmd_ID_open_panel_hsplit = 135; +static i32 fcoder_metacmd_ID_open_panel_vsplit = 136; +static i32 fcoder_metacmd_ID_page_down = 137; +static i32 fcoder_metacmd_ID_page_up = 138; +static i32 fcoder_metacmd_ID_paste = 139; +static i32 fcoder_metacmd_ID_paste_and_indent = 140; +static i32 fcoder_metacmd_ID_paste_next = 141; +static i32 fcoder_metacmd_ID_paste_next_and_indent = 142; +static i32 fcoder_metacmd_ID_place_in_scope = 143; +static i32 fcoder_metacmd_ID_profile_clear = 144; +static i32 fcoder_metacmd_ID_profile_disable = 145; +static i32 fcoder_metacmd_ID_profile_enable = 146; +static i32 fcoder_metacmd_ID_profile_inspect = 147; +static i32 fcoder_metacmd_ID_project_command_lister = 148; +static i32 fcoder_metacmd_ID_project_fkey_command = 149; +static i32 fcoder_metacmd_ID_project_go_to_root_directory = 150; +static i32 fcoder_metacmd_ID_query_replace = 151; +static i32 fcoder_metacmd_ID_query_replace_identifier = 152; +static i32 fcoder_metacmd_ID_query_replace_selection = 153; +static i32 fcoder_metacmd_ID_redo = 154; +static i32 fcoder_metacmd_ID_redo_all_buffers = 155; +static i32 fcoder_metacmd_ID_rename_file_query = 156; +static i32 fcoder_metacmd_ID_reopen = 157; +static i32 fcoder_metacmd_ID_replace_in_all_buffers = 158; +static i32 fcoder_metacmd_ID_replace_in_buffer = 159; +static i32 fcoder_metacmd_ID_replace_in_range = 160; +static i32 fcoder_metacmd_ID_reverse_search = 161; +static i32 fcoder_metacmd_ID_reverse_search_identifier = 162; +static i32 fcoder_metacmd_ID_save = 163; +static i32 fcoder_metacmd_ID_save_all_dirty_buffers = 164; +static i32 fcoder_metacmd_ID_save_to_query = 165; +static i32 fcoder_metacmd_ID_search = 166; +static i32 fcoder_metacmd_ID_search_identifier = 167; +static i32 fcoder_metacmd_ID_seek_beginning_of_line = 168; +static i32 fcoder_metacmd_ID_seek_beginning_of_textual_line = 169; +static i32 fcoder_metacmd_ID_seek_end_of_line = 170; +static i32 fcoder_metacmd_ID_seek_end_of_textual_line = 171; +static i32 fcoder_metacmd_ID_select_all = 172; +static i32 fcoder_metacmd_ID_select_next_scope_absolute = 173; +static i32 fcoder_metacmd_ID_select_next_scope_after_current = 174; +static i32 fcoder_metacmd_ID_select_prev_scope_absolute = 175; +static i32 fcoder_metacmd_ID_select_prev_top_most_scope = 176; +static i32 fcoder_metacmd_ID_select_surrounding_scope = 177; +static i32 fcoder_metacmd_ID_select_surrounding_scope_maximal = 178; +static i32 fcoder_metacmd_ID_set_eol_mode_from_contents = 179; +static i32 fcoder_metacmd_ID_set_eol_mode_to_binary = 180; +static i32 fcoder_metacmd_ID_set_eol_mode_to_crlf = 181; +static i32 fcoder_metacmd_ID_set_eol_mode_to_lf = 182; +static i32 fcoder_metacmd_ID_set_mark = 183; +static i32 fcoder_metacmd_ID_set_mode_to_notepad_like = 184; +static i32 fcoder_metacmd_ID_set_mode_to_original = 185; +static i32 fcoder_metacmd_ID_setup_build_bat = 186; +static i32 fcoder_metacmd_ID_setup_build_bat_and_sh = 187; +static i32 fcoder_metacmd_ID_setup_build_sh = 188; +static i32 fcoder_metacmd_ID_setup_new_project = 189; +static i32 fcoder_metacmd_ID_show_filebar = 190; +static i32 fcoder_metacmd_ID_show_scrollbar = 191; +static i32 fcoder_metacmd_ID_show_the_log_graph = 192; +static i32 fcoder_metacmd_ID_snipe_backward_whitespace_or_token_boundary = 193; +static i32 fcoder_metacmd_ID_snipe_forward_whitespace_or_token_boundary = 194; +static i32 fcoder_metacmd_ID_snippet_lister = 195; +static i32 fcoder_metacmd_ID_suppress_mouse = 196; +static i32 fcoder_metacmd_ID_swap_panels = 197; +static i32 fcoder_metacmd_ID_test_double_backspace = 198; +static i32 fcoder_metacmd_ID_theme_lister = 199; +static i32 fcoder_metacmd_ID_to_lowercase = 200; +static i32 fcoder_metacmd_ID_to_uppercase = 201; +static i32 fcoder_metacmd_ID_toggle_filebar = 202; +static i32 fcoder_metacmd_ID_toggle_fps_meter = 203; +static i32 fcoder_metacmd_ID_toggle_fullscreen = 204; +static i32 fcoder_metacmd_ID_toggle_highlight_enclosing_scopes = 205; +static i32 fcoder_metacmd_ID_toggle_highlight_line_at_cursor = 206; +static i32 fcoder_metacmd_ID_toggle_line_numbers = 207; +static i32 fcoder_metacmd_ID_toggle_line_wrap = 208; +static i32 fcoder_metacmd_ID_toggle_mouse = 209; +static i32 fcoder_metacmd_ID_toggle_paren_matching_helper = 210; +static i32 fcoder_metacmd_ID_toggle_show_whitespace = 211; +static i32 fcoder_metacmd_ID_toggle_virtual_whitespace = 212; +static i32 fcoder_metacmd_ID_tutorial_maximize = 213; +static i32 fcoder_metacmd_ID_tutorial_minimize = 214; +static i32 fcoder_metacmd_ID_uncomment_line = 215; +static i32 fcoder_metacmd_ID_undo = 216; +static i32 fcoder_metacmd_ID_undo_all_buffers = 217; +static i32 fcoder_metacmd_ID_view_buffer_other_panel = 218; +static i32 fcoder_metacmd_ID_view_jump_list_with_lister = 219; +static i32 fcoder_metacmd_ID_word_complete = 220; +static i32 fcoder_metacmd_ID_word_complete_drop_down = 221; +static i32 fcoder_metacmd_ID_write_block = 222; +static i32 fcoder_metacmd_ID_write_hack = 223; +static i32 fcoder_metacmd_ID_write_note = 224; +static i32 fcoder_metacmd_ID_write_space = 225; +static i32 fcoder_metacmd_ID_write_text_and_auto_indent = 226; +static i32 fcoder_metacmd_ID_write_text_input = 227; +static i32 fcoder_metacmd_ID_write_todo = 228; +static i32 fcoder_metacmd_ID_write_underscore = 229; +static i32 fcoder_metacmd_ID_write_zero_struct = 230; #endif diff --git a/ship_files/changes.txt b/ship_files/changes.txt index 6724954b..e2238ccb 100644 --- a/ship_files/changes.txt +++ b/ship_files/changes.txt @@ -1,10 +1,15 @@ 4.1.3 + + Unkillable buffer setting + + UI elements in listers and buttons can have different highlight backgrounds + + command 'load_theme_current_buffer' for loading the current file as a theme and setting it as the theme + Fix: search and replace never exits early + Fix: optimized builds of the custom layer display the dirty * on the file bar correclty + Fix: can merge "backwards" strings in the history correctly + Fix: the helper user_list_definition_array matches both LF and CRLF line endings + Fix: line number background and text colors in the built in theme files + + Fix: a drive letter by itself is recognized as an existing path + + Fix: the margin colors for panels are determined by the margins in theme files 4.1.2 + Cursor color changes when recording macro if the theme provides a second cursor color From 79c8499385a6eca29a6de975d4f445c87b6a1d29 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Sun, 26 Jan 2020 21:28:49 -0800 Subject: [PATCH 124/128] Updated built in color theme to match theme-4coder.4coder version --- custom/4coder_default_colors.cpp | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/custom/4coder_default_colors.cpp b/custom/4coder_default_colors.cpp index 022b8dc2..94554e66 100644 --- a/custom/4coder_default_colors.cpp +++ b/custom/4coder_default_colors.cpp @@ -121,8 +121,8 @@ set_default_color_scheme(Application_Links *app){ default_color_table.arrays[defcolor_margin_hover] = make_colors(arena, 0xFF252525); default_color_table.arrays[defcolor_margin_active] = make_colors(arena, 0xFF323232); default_color_table.arrays[defcolor_list_item] = make_colors(arena, 0xFF181818, 0xFF0C0C0C); - default_color_table.arrays[defcolor_list_item_hover] = make_colors(arena, 0xFF252525, 0xFF0C0C0C); - default_color_table.arrays[defcolor_list_item_active] = make_colors(arena, 0xFF323232, 0xFF0C0C0C); + default_color_table.arrays[defcolor_list_item_hover] = make_colors(arena, 0xFF252525, 0xFF181818); + default_color_table.arrays[defcolor_list_item_active] = make_colors(arena, 0xFF323232, 0xFF323232); default_color_table.arrays[defcolor_cursor] = make_colors(arena, 0xFF00EE00, 0xFFEE7700); default_color_table.arrays[defcolor_at_cursor] = make_colors(arena, 0xFF0C0C0C); default_color_table.arrays[defcolor_highlight_cursor_line] = make_colors(arena, 0xFF1E1E1E); From d12c4aa2e6e187151671956e9f793ec36268a341 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 30 Jan 2020 21:02:18 -0800 Subject: [PATCH 125/128] Hacky fix for the signal step breaking on the non-main thread --- bin/itchio_push_all.sh | 2 - bin/itchio_push_mac.sh | 22 ++ custom/generated/command_metadata.h | 458 ++++++++++++++-------------- platform_mac/mac_4ed_functions.mm | 11 + 4 files changed, 262 insertions(+), 231 deletions(-) create mode 100755 bin/itchio_push_mac.sh diff --git a/bin/itchio_push_all.sh b/bin/itchio_push_all.sh index cc37cd27..bb606ddf 100644 --- a/bin/itchio_push_all.sh +++ b/bin/itchio_push_all.sh @@ -1,7 +1,5 @@ #!/bin/sh -#todo rewrite this as a build.cpp script - if [ "$#" -lt "3" ] then echo need 3 parameters diff --git a/bin/itchio_push_mac.sh b/bin/itchio_push_mac.sh new file mode 100755 index 00000000..cf5a7d5b --- /dev/null +++ b/bin/itchio_push_mac.sh @@ -0,0 +1,22 @@ +#!/bin/sh + +if [ "$#" -lt "3" ] +then +echo need 3 parameters +exit +else + +fake=$1 +maj=$2 +min=$3 + +vr=$fake.$maj.$min +fv=$fake-$maj-$min + +flags="--fix-permissions --userversion=$vr" +dir=../distributions + +butler push $flags $dir/demo_x64/4coder-$fv-demo-mac-x64.zip 4coder/4coder:mac-x64-demo +butler push $flags $dir/super_x64/4coder-$fv-super-mac-x64.zip 4coder/4coder:mac-x64 + +fi diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 1c461ef6..4b514631 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, 407 }, -{ 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, 417 }, -{ 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, 398 }, -{ 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, 611 }, -{ 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, 576 }, -{ 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, 619 }, -{ 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, 753 }, -{ 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, 682 }, -{ 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, 1793 }, -{ 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, 51 }, -{ 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, 1219 }, -{ 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, 1391 }, -{ 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, 1377 }, -{ 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, 738 }, -{ 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, 525 }, -{ 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, 542 }, -{ 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, 348 }, -{ 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, 375 }, -{ 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, 746 }, -{ 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, 464 }, -{ 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, 494 }, -{ 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, 481 }, -{ 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, 511 }, -{ 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, 649 }, -{ 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, 635 }, -{ 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, 564 }, -{ 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, 581 }, -{ 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, 671 }, -{ 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, 520 }, -{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 657 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 707 }, -{ 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, 612 }, -{ 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, 510 }, -{ 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, 54 }, -{ 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, 77 }, -{ 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, 41 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1537 }, -{ 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, 296 }, -{ 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, 302 }, -{ 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, 1331 }, -{ 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, 693 }, -{ 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, 336 }, -{ 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, 348 }, -{ 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, 354 }, -{ 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, 407 }, -{ 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, 431 }, -{ 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, 419 }, -{ 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, 437 }, -{ 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, 514 }, -{ 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, 528 }, -{ 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, 486 }, -{ 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, 471 }, -{ 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, 500 }, -{ 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, 1371 }, -{ 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, 1365 }, -{ 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, 445 }, -{ 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, 507 }, -{ 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, 521 }, -{ 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, 479 }, -{ 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, 463 }, -{ 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, 493 }, -{ 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, 330 }, -{ 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, 342 }, -{ 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, 401 }, -{ 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, 425 }, -{ 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, 413 }, -{ 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, 1456 }, -{ 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, 1787 }, -{ 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, 1488 }, -{ 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, 372 }, -{ 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, 364 }, -{ 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, 109 }, -{ 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, 70 }, -{ 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, 116 }, -{ 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, 1147 }, -{ 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, 1168 }, -{ 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, 1184 }, -{ 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, 1626 }, -{ 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, 1711 }, -{ 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, 1296 }, -{ 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, 1555 }, -{ 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, 1057 }, -{ 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, 1048 }, -{ 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, 1039 }, -{ 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, 980 }, -{ 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, 992 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1545 }, -{ 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, 1263 }, -{ 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, 974 }, -{ 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, 986 }, -{ 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, 537 }, -{ 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, 642 }, -{ 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, 628 }, -{ 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, 1513 }, -{ 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, 777 }, -{ 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, 563 }, -{ 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, 550 }, -{ 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, 656 }, -{ 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, 665 }, -{ 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, 719 }, -{ 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, 725 }, -{ 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, 710 }, -{ 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, 1170 }, -{ 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, 1613 }, -{ 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, 1640 }, -{ 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, 1501 }, -{ 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 a space.", 16, "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, 427 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 407 }, +{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 417 }, +{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 398 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 154 }, +{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 611 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 128 }, +{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 186 }, +{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 576 }, +{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 480 }, +{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 243 }, +{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 842 }, +{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 180 }, +{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 619 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 190 }, +{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 753 }, +{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 149 }, +{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 19 }, +{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 175 }, +{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 28 }, +{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 682 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1793 }, +{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 7 }, +{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 23 }, +{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 51 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 162 }, +{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1219 }, +{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1391 }, +{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 134 }, +{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1377 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 7 }, +{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 738 }, +{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 2184 }, +{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 525 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 542 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 348 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 375 }, +{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 746 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 464 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 494 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 481 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 511 }, +{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 649 }, +{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 635 }, +{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 564 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 581 }, +{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 671 }, +{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 520 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 657 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 707 }, +{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 612 }, +{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 510 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_code_index_listers.cpp", 65, 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 54 }, +{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 77 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 41 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1537 }, +{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 296 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 302 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1331 }, +{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 249 }, +{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 693 }, +{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 265 }, +{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 336 }, +{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 348 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 354 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 407 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 431 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 419 }, +{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 437 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 514 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 528 }, +{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 486 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 471 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 500 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1371 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1365 }, +{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 445 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 507 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 521 }, +{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 479 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 463 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 493 }, +{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 330 }, +{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 342 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 401 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 425 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 413 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1456 }, +{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1787 }, +{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1488 }, +{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 310 }, +{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 372 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 364 }, +{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 109 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 70 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 116 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 106 }, +{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 226 }, +{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 219 }, +{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 212 }, +{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "/Users/allenwebster/4ed/code/custom/4coder_profile_inspect.cpp", 62, 886 }, +{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1147 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1168 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1184 }, +{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1626 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1711 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1296 }, +{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1555 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1057 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1048 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1039 }, +{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 980 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 992 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1545 }, +{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1263 }, +{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 974 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 986 }, +{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 537 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 27 }, +{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 99 }, +{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 115 }, +{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 427 }, +{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 1230 }, +{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 642 }, +{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 628 }, +{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "/Users/allenwebster/4ed/code/custom/4coder_log_parser.cpp", 57, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 187 }, +{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 403 }, +{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1513 }, +{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 777 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 563 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 550 }, +{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 656 }, +{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 665 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 439 }, +{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 433 }, +{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 719 }, +{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 725 }, +{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 445 }, +{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 710 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "/Users/allenwebster/4ed/code/custom/4coder_code_index.cpp", 57, 1170 }, +{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 20 }, +{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 34 }, +{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 137 }, +{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1613 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1640 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1501 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_lister.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 392 }, +{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 639 }, +{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 88 }, +{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 427 }, +{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 76 }, +{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 73 }, +{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 100 }, }; static i32 fcoder_metacmd_ID_allow_mouse = 0; static i32 fcoder_metacmd_ID_auto_indent_line_at_cursor = 1; diff --git a/platform_mac/mac_4ed_functions.mm b/platform_mac/mac_4ed_functions.mm index 93b19ce6..677af480 100644 --- a/platform_mac/mac_4ed_functions.mm +++ b/platform_mac/mac_4ed_functions.mm @@ -406,6 +406,7 @@ system_wake_up_timer_set_sig(){ function system_signal_step_sig(){ +#if 0 if (!mac_vars.step_requested){ [NSTimer scheduledTimerWithTimeInterval:0.0 target:mac_vars.view @@ -414,6 +415,16 @@ system_signal_step_sig(){ mac_vars.step_requested = true; } +#else + mac_vars.step_requested = true; + dispatch_async(dispatch_get_main_queue(), + ^{ + [NSTimer scheduledTimerWithTimeInterval:0.0 + target:mac_vars.view + selector:@selector(request_display) + userInfo:nil repeats:NO]; + }); +#endif } function From 18f7f6e67abc60eee578f33423086d12c6ae930e Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 30 Jan 2020 21:13:11 -0800 Subject: [PATCH 126/128] Put all OSes on the same command execution rule in build commands --- custom/4coder_build_commands.cpp | 10 ++-------- custom/generated/command_metadata.h | 8 ++++---- 2 files changed, 6 insertions(+), 12 deletions(-) diff --git a/custom/4coder_build_commands.cpp b/custom/4coder_build_commands.cpp index 1988b2fe..52d924e9 100644 --- a/custom/4coder_build_commands.cpp +++ b/custom/4coder_build_commands.cpp @@ -63,7 +63,7 @@ standard_build_exec_command(Application_Links *app, View_ID view, String_Const_u standard_build_exec_flags); } - function b32 +function b32 standard_search_and_build_from_dir(Application_Links *app, View_ID view, String_Const_u8 start_dir){ Scratch_Block scratch(app); @@ -82,15 +82,9 @@ standard_search_and_build_from_dir(Application_Links *app, View_ID view, String_ if (result){ // NOTE(allen): Build String_Const_u8 path = string_remove_last_folder(full_file_path); -#if OS_WINDOWS String_Const_u8 command = push_u8_stringf(scratch, "\"%.*s/%.*s\"", string_expand(path), string_expand(cmd_string)); -#elif OS_LINUX || OS_MAC - String_Const_u8 command = cmd_string; -#else -#error OS needs standard search and build rules -#endif if (global_config.automatically_save_changes_on_build){ save_all_dirty_buffers(app); } @@ -153,7 +147,7 @@ get_or_open_build_panel(Application_Links *app){ return(view); } - function void +function void set_fancy_compilation_buffer_font(Application_Links *app){ Buffer_ID buffer = get_comp_buffer(app); Font_Load_Location font = {}; diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index 4b514631..d97fd570 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -258,12 +258,12 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 154 }, { PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 611 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 128 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 159 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 122 }, { PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 186 }, +{ 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 180 }, { PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 576 }, { PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 480 }, { PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 233 }, @@ -271,7 +271,7 @@ static Command_Metadata fcoder_metacmd_table[229] = { { 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 243 }, { PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 842 }, -{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 180 }, +{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 174 }, { PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 619 }, { 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 190 }, { PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 753 }, From a268055da79a7c2cc152bbdfb64f6a906eb030e1 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Thu, 30 Jan 2020 21:33:36 -0800 Subject: [PATCH 127/128] Added check to file change checker that detects file deletion; updated changes.txt --- 4ed_working_set.cpp | 3 +- custom/generated/command_metadata.h | 462 ++++++++++++++-------------- ship_files/changes.txt | 2 + 3 files changed, 235 insertions(+), 232 deletions(-) diff --git a/4ed_working_set.cpp b/4ed_working_set.cpp index e51c6c40..7077007e 100644 --- a/4ed_working_set.cpp +++ b/4ed_working_set.cpp @@ -21,7 +21,8 @@ file_change_notification_check(Arena *scratch, Working_Set *working_set, Editing if (file->canon.name_size > 0 && !file->settings.unimportant){ String_Const_u8 name = SCu8(file->canon.name_space, file->canon.name_size); File_Attributes attributes = system_quick_file_attributes(scratch, name); - if (attributes.last_write_time > file->attributes.last_write_time){ + if ((attributes.last_write_time > file->attributes.last_write_time) || + (attributes.last_write_time == 0 && file->attributes.last_write_time > 0)){ if (file->state.save_state == FileSaveState_SavedWaitingForNotification){ file->state.save_state = FileSaveState_Normal; file->attributes = attributes; diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index af31b774..ca2eb30a 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -253,237 +253,237 @@ i32 source_name_len; i32 line_number; }; static Command_Metadata fcoder_metacmd_table[231] = { -{ PROC_LINKS(allow_mouse, 0), false, "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 407 }, -{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 417 }, -{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 398 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 165 }, -{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 622 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 159 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 122 }, -{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 208 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 180 }, -{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 587 }, -{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 480 }, -{ PROC_LINKS(click_set_cursor, 0), false, "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 244 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 234 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 254 }, -{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 266 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 842 }, -{ PROC_LINKS(close_build_panel, 0), false, "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "/Users/allenwebster/4ed/code/custom/4coder_build_commands.cpp", 61, 174 }, -{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 630 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 190 }, -{ PROC_LINKS(command_lister, 0), true, "command_lister", 14, "Opens an interactive list of all registered commands.", 53, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 761 }, -{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 149 }, -{ PROC_LINKS(copy, 0), false, "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 19 }, -{ PROC_LINKS(cursor_mark_swap, 0), false, "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 135 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_docs.cpp", 51, 175 }, -{ PROC_LINKS(cut, 0), false, "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 28 }, -{ PROC_LINKS(decrease_face_size, 0), false, "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 693 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1804 }, -{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 7 }, -{ PROC_LINKS(default_try_exit, 0), false, "default_try_exit", 16, "Default command for responding to a try-exit event", 50, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 23 }, -{ PROC_LINKS(default_view_input_handler, 0), false, "default_view_input_handler", 26, "Input consumption loop for default view behavior", 48, "/Users/allenwebster/4ed/code/custom/4coder_default_hooks.cpp", 60, 51 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 173 }, -{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1230 }, -{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1402 }, -{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 145 }, -{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1388 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_cli_command.cpp", 58, 7 }, -{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 749 }, -{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 2184 }, -{ PROC_LINKS(goto_end_of_file, 0), false, "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 525 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 542 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 348 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 375 }, -{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 757 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 464 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 494 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 481 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 511 }, -{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 660 }, -{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 646 }, -{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 564 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_sticky.cpp", 58, 581 }, -{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 682 }, -{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 520 }, -{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 661 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 715 }, -{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 612 }, -{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 510 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_code_index_listers.cpp", 65, 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 54 }, -{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 77 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_keyboard_macro.cpp", 61, 41 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1548 }, -{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 222 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 296 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 302 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_function_list.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 165 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 177 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 189 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 195 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 201 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 207 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 213 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 221 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 171 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 183 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 862 }, -{ PROC_LINKS(load_theme_current_buffer, 0), false, "load_theme_current_buffer", 25, "Parse the current buffer as a theme file and add the theme to the theme list. If the buffer has a .4coder postfix in it's name, it is removed when the name is saved.", 165, "/Users/allenwebster/4ed/code/custom/4coder_config.cpp", 53, 1622 }, -{ PROC_LINKS(load_themes_default_folder, 0), false, "load_themes_default_folder", 26, "Loads all the theme files in the default theme folder.", 54, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1342 }, -{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 249 }, -{ PROC_LINKS(miblo_increment_basic, 0), false, "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_miblo_numbers.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 704 }, -{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 276 }, -{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 347 }, -{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 359 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 365 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 418 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 442 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 430 }, -{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 448 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 525 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 539 }, -{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 497 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 482 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 511 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1382 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1376 }, -{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 456 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 518 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 532 }, -{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 490 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 474 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 504 }, -{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 341 }, -{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 353 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 412 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 436 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 424 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1467 }, -{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1798 }, -{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1499 }, -{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 310 }, -{ PROC_LINKS(open_panel_vsplit, 0), false, "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 383 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 375 }, -{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 113 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 72 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_clipboard.cpp", 56, 120 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 106 }, -{ PROC_LINKS(profile_clear, 0), false, "profile_clear", 13, "Clear all profiling information from 4coder's self profiler.", 60, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 226 }, -{ PROC_LINKS(profile_disable, 0), false, "profile_disable", 15, "Prevent 4coder's self profiler from gathering new profiling information.", 72, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 219 }, -{ PROC_LINKS(profile_enable, 0), false, "profile_enable", 14, "Allow 4coder's self profiler to gather new profiling information.", 65, "/Users/allenwebster/4ed/code/custom/4coder_profile.cpp", 54, 212 }, -{ PROC_LINKS(profile_inspect, 0), true, "profile_inspect", 15, "Inspect all currently collected profiling information in 4coder's self profiler.", 80, "/Users/allenwebster/4ed/code/custom/4coder_profile_inspect.cpp", 62, 886 }, -{ PROC_LINKS(project_command_lister, 0), false, "project_command_lister", 22, "Open a lister of all commands in the currently loaded project.", 62, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1158 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1179 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1195 }, -{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1637 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1722 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1307 }, -{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1566 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1068 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1059 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1050 }, -{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 991 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1003 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1556 }, -{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1274 }, -{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 985 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 997 }, -{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_helper.cpp", 53, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 548 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 27 }, -{ PROC_LINKS(select_surrounding_scope_maximal, 0), false, "select_surrounding_scope_maximal", 32, "Selects the top-most scope that surrounds the cursor.", 53, "/Users/allenwebster/4ed/code/custom/4coder_scope_commands.cpp", 61, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 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, "/Users/allenwebster/4ed/code/custom/4coder_eol.cpp", 50, 99 }, -{ PROC_LINKS(set_mark, 0), false, "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 126 }, -{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 427 }, -{ PROC_LINKS(set_mode_to_original, 0), false, "set_mode_to_original", 20, "Sets the edit mode to 4coder original.", 38, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 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, "/Users/allenwebster/4ed/code/custom/4coder_project_commands.cpp", 63, 1230 }, -{ PROC_LINKS(show_filebar, 0), false, "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 653 }, -{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 639 }, -{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "/Users/allenwebster/4ed/code/custom/4coder_log_parser.cpp", 57, 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 190 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 198 }, -{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 403 }, -{ PROC_LINKS(swap_panels, 0), false, "swap_panels", 11, "Swaps the active panel with it's sibling.", 41, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1524 }, -{ PROC_LINKS(test_double_backspace, 0), false, "test_double_backspace", 21, "Made for testing purposes (I should have deleted this if you are reading it let me know)", 88, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 115 }, -{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "/Users/allenwebster/4ed/code/custom/4coder_lists.cpp", 52, 785 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 574 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 561 }, -{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 667 }, -{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 676 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 439 }, -{ PROC_LINKS(toggle_highlight_line_at_cursor, 0), false, "toggle_highlight_line_at_cursor", 31, "Toggles the line highlight at the cursor.", 41, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 433 }, -{ PROC_LINKS(toggle_line_numbers, 0), false, "toggle_line_numbers", 19, "Toggles the left margin line numbers.", 37, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 730 }, -{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 736 }, -{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 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, "/Users/allenwebster/4ed/code/custom/4coder_default_framework.cpp", 64, 445 }, -{ PROC_LINKS(toggle_show_whitespace, 0), false, "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 721 }, -{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "/Users/allenwebster/4ed/code/custom/4coder_code_index.cpp", 57, 1170 }, -{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 20 }, -{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "/Users/allenwebster/4ed/code/custom/4coder_tutorial.cpp", 55, 34 }, -{ PROC_LINKS(uncomment_line, 0), false, "uncomment_line", 14, "If present, delete '//' at the beginning of the line after leading whitespace.", 78, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 137 }, -{ PROC_LINKS(undo, 0), false, "undo", 4, "Advances backwards through the undo history of the current buffer.", 66, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1624 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1651 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 1512 }, -{ 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, "/Users/allenwebster/4ed/code/custom/4coder_jump_lister.cpp", 58, 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, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 395 }, -{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "/Users/allenwebster/4ed/code/custom/4coder_search.cpp", 53, 642 }, -{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 88 }, -{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_auto_indent.cpp", 58, 427 }, -{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 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, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 76 }, -{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "/Users/allenwebster/4ed/code/custom/4coder_base_commands.cpp", 60, 73 }, -{ PROC_LINKS(write_zero_struct, 0), false, "write_zero_struct", 17, "At the cursor, insert a ' = {};'.", 33, "/Users/allenwebster/4ed/code/custom/4coder_combined_write_commands.cpp", 70, 100 }, +{ 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, 407 }, +{ 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, 417 }, +{ 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, 398 }, +{ 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, 165 }, +{ 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, 622 }, +{ 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, 159 }, +{ 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, 122 }, +{ 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, 208 }, +{ 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, 180 }, +{ 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, 587 }, +{ 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, 244 }, +{ 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, 234 }, +{ 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, 254 }, +{ 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, 266 }, +{ 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, 174 }, +{ 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, 630 }, +{ 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, 761 }, +{ 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, 135 }, +{ 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, 693 }, +{ 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, 1804 }, +{ 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, 51 }, +{ 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, 173 }, +{ 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, 1230 }, +{ 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, 1402 }, +{ 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, 145 }, +{ 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, 1388 }, +{ 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, 749 }, +{ 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, 525 }, +{ 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, 542 }, +{ 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, 348 }, +{ 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, 375 }, +{ 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, 757 }, +{ 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, 464 }, +{ 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, 494 }, +{ 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, 481 }, +{ 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, 511 }, +{ 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, 660 }, +{ 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, 646 }, +{ 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, 564 }, +{ 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, 581 }, +{ 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, 682 }, +{ 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, 520 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 661 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 715 }, +{ 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, 612 }, +{ 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, 510 }, +{ 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, 54 }, +{ 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, 77 }, +{ 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, 41 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1548 }, +{ 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, 222 }, +{ 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, 296 }, +{ 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, 302 }, +{ 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, 165 }, +{ 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, 177 }, +{ 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, 189 }, +{ 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, 195 }, +{ 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, 201 }, +{ 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, 207 }, +{ 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, 213 }, +{ 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, 221 }, +{ 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, 171 }, +{ 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, 183 }, +{ 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_theme_current_buffer, 0), false, "load_theme_current_buffer", 25, "Parse the current buffer as a theme file and add the theme to the theme list. If the buffer has a .4coder postfix in it's name, it is removed when the name is saved.", 165, "w:\\4ed\\code\\custom\\4coder_config.cpp", 36, 1622 }, +{ 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, 1342 }, +{ 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, 704 }, +{ 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, 276 }, +{ 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, 347 }, +{ 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, 359 }, +{ 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, 365 }, +{ 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, 418 }, +{ 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, 442 }, +{ 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, 430 }, +{ 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, 448 }, +{ 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, 525 }, +{ 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, 539 }, +{ 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, 497 }, +{ 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, 482 }, +{ 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, 511 }, +{ 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, 1382 }, +{ 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, 1376 }, +{ 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, 456 }, +{ 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, 518 }, +{ 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, 532 }, +{ 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, 490 }, +{ 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, 474 }, +{ 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, 504 }, +{ 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, 341 }, +{ 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, 353 }, +{ 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, 412 }, +{ 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, 436 }, +{ 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, 424 }, +{ 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, 1467 }, +{ 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, 1798 }, +{ 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, 1499 }, +{ 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, 383 }, +{ 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, 375 }, +{ 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, 113 }, +{ 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, 72 }, +{ 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, 120 }, +{ 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, 1158 }, +{ 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, 1179 }, +{ 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, 1195 }, +{ 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, 1637 }, +{ 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, 1722 }, +{ 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, 1307 }, +{ 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, 1566 }, +{ 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, 1068 }, +{ 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, 1059 }, +{ 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, 1050 }, +{ 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, 991 }, +{ 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, 1003 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1556 }, +{ 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, 1274 }, +{ 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, 985 }, +{ 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, 997 }, +{ 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, 548 }, +{ 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, 126 }, +{ 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, 653 }, +{ 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, 639 }, +{ 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, 190 }, +{ 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, 198 }, +{ 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, 1524 }, +{ PROC_LINKS(test_double_backspace, 0), false, "test_double_backspace", 21, "Made for testing purposes (I should have deleted this if you are reading it let me know)", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 115 }, +{ 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, 785 }, +{ 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, 574 }, +{ 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, 561 }, +{ 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, 667 }, +{ 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, 676 }, +{ 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, 730 }, +{ 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, 736 }, +{ 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, 721 }, +{ 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, 1170 }, +{ 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, 1624 }, +{ 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, 1651 }, +{ 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, 1512 }, +{ 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, 395 }, +{ 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, 642 }, +{ 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 a space.", 16, "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, 427 }, +{ 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 }, }; static i32 fcoder_metacmd_ID_allow_mouse = 0; static i32 fcoder_metacmd_ID_auto_indent_line_at_cursor = 1; diff --git a/ship_files/changes.txt b/ship_files/changes.txt index e2238ccb..2c0837b8 100644 --- a/ship_files/changes.txt +++ b/ship_files/changes.txt @@ -10,6 +10,8 @@ + Fix: line number background and text colors in the built in theme files + Fix: a drive letter by itself is recognized as an existing path + Fix: the margin colors for panels are determined by the margins in theme files + + Fix: when a file is deleted outside of 4coder, the '!' dirty status is added to the buffer + + Fix: on mac file changes outside of 4coder are detected and do not stall the UI 4.1.2 + Cursor color changes when recording macro if the theme provides a second cursor color From d9e196eda8ac669630bd0e11349ac6695d169c13 Mon Sep 17 00:00:00 2001 From: Allen Webster Date: Fri, 31 Jan 2020 13:23:40 -0800 Subject: [PATCH 128/128] Fixed double declaration of scratch --- custom/4coder_config.cpp | 3 +- custom/generated/command_metadata.h | 462 ++++++++++++++-------------- 2 files changed, 232 insertions(+), 233 deletions(-) diff --git a/custom/4coder_config.cpp b/custom/4coder_config.cpp index 337914ae..753b09d6 100644 --- a/custom/4coder_config.cpp +++ b/custom/4coder_config.cpp @@ -1143,7 +1143,7 @@ function i32 typed_array_get_count(Config *parsed, Config_Compound *compound, Config_RValue_Type type){ i32 count = 0; for (i32 i = 0;; ++i){ - Config_Iteration_Step_Result result = typed_array_iteration_step(parsed, compound, type, i); + Config_Iteration_Step_Result result = typed_array_iteration_step(parsed, compound, type, i); if (result.step == Iteration_Skip){ continue; } @@ -1630,7 +1630,6 @@ CUSTOM_DOC("Parse the current buffer as a theme file and add the theme to the th if (file_name.size > 0){ Arena *arena = &global_theme_arena; Color_Table color_table = make_color_table(app, arena); - Scratch_Block scratch(app); Config *config = theme_parse__buffer(app, scratch, buffer, arena, &color_table); String_Const_u8 error_text = config_stringize_errors(app, scratch, config); print_message(app, error_text); diff --git a/custom/generated/command_metadata.h b/custom/generated/command_metadata.h index ca2eb30a..f4843974 100644 --- a/custom/generated/command_metadata.h +++ b/custom/generated/command_metadata.h @@ -253,237 +253,237 @@ i32 source_name_len; i32 line_number; }; static Command_Metadata fcoder_metacmd_table[231] = { -{ 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, 407 }, -{ 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, 417 }, -{ 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, 398 }, -{ 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, 165 }, -{ 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, 622 }, -{ 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, 159 }, -{ 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, 122 }, -{ 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, 208 }, -{ 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, 180 }, -{ 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, 587 }, -{ 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, 244 }, -{ 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, 234 }, -{ 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, 254 }, -{ 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, 266 }, -{ 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, 174 }, -{ 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, 630 }, -{ 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, 761 }, -{ 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, 135 }, -{ 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, 693 }, -{ 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, 1804 }, -{ 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, 51 }, -{ 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, 173 }, -{ 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, 1230 }, -{ 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, 1402 }, -{ 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, 145 }, -{ 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, 1388 }, -{ 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, 749 }, -{ 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, 525 }, -{ 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, 542 }, -{ 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, 348 }, -{ 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, 375 }, -{ 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, 757 }, -{ 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, 464 }, -{ 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, 494 }, -{ 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, 481 }, -{ 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, 511 }, -{ 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, 660 }, -{ 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, 646 }, -{ 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, 564 }, -{ 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, 581 }, -{ 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, 682 }, -{ 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, 520 }, -{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 661 }, -{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "w:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 715 }, -{ 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, 612 }, -{ 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, 510 }, -{ 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, 54 }, -{ 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, 77 }, -{ 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, 41 }, -{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1548 }, -{ 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, 222 }, -{ 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, 296 }, -{ 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, 302 }, -{ 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, 165 }, -{ 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, 177 }, -{ 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, 189 }, -{ 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, 195 }, -{ 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, 201 }, -{ 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, 207 }, -{ 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, 213 }, -{ 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, 221 }, -{ 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, 171 }, -{ 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, 183 }, -{ 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_theme_current_buffer, 0), false, "load_theme_current_buffer", 25, "Parse the current buffer as a theme file and add the theme to the theme list. If the buffer has a .4coder postfix in it's name, it is removed when the name is saved.", 165, "w:\\4ed\\code\\custom\\4coder_config.cpp", 36, 1622 }, -{ 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, 1342 }, -{ 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, 704 }, -{ 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, 276 }, -{ 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, 347 }, -{ 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, 359 }, -{ 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, 365 }, -{ 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, 418 }, -{ 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, 442 }, -{ 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, 430 }, -{ 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, 448 }, -{ 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, 525 }, -{ 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, 539 }, -{ 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, 497 }, -{ 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, 482 }, -{ 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, 511 }, -{ 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, 1382 }, -{ 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, 1376 }, -{ 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, 456 }, -{ 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, 518 }, -{ 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, 532 }, -{ 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, 490 }, -{ 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, 474 }, -{ 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, 504 }, -{ 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, 341 }, -{ 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, 353 }, -{ 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, 412 }, -{ 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, 436 }, -{ 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, 424 }, -{ 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, 1467 }, -{ 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, 1798 }, -{ 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, 1499 }, -{ 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, 383 }, -{ 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, 375 }, -{ 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, 113 }, -{ 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, 72 }, -{ 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, 120 }, -{ 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, 1158 }, -{ 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, 1179 }, -{ 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, 1195 }, -{ 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, 1637 }, -{ 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, 1722 }, -{ 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, 1307 }, -{ 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, 1566 }, -{ 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, 1068 }, -{ 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, 1059 }, -{ 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, 1050 }, -{ 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, 991 }, -{ 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, 1003 }, -{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1556 }, -{ 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, 1274 }, -{ 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, 985 }, -{ 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, 997 }, -{ 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, 548 }, -{ 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, 126 }, -{ 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, 653 }, -{ 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, 639 }, -{ 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, 190 }, -{ 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, 198 }, -{ 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, 1524 }, -{ PROC_LINKS(test_double_backspace, 0), false, "test_double_backspace", 21, "Made for testing purposes (I should have deleted this if you are reading it let me know)", 88, "w:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 115 }, -{ 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, 785 }, -{ 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, 574 }, -{ 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, 561 }, -{ 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, 667 }, -{ 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, 676 }, -{ 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, 730 }, -{ 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, 736 }, -{ 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, 721 }, -{ 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, 1170 }, -{ 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, 1624 }, -{ 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, 1651 }, -{ 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, 1512 }, -{ 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, 395 }, -{ 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, 642 }, -{ 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 a space.", 16, "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, 427 }, -{ 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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 407 }, +{ PROC_LINKS(auto_indent_range, 0), false, "auto_indent_range", 17, "Auto-indents the range between the cursor and the mark.", 55, "c:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 417 }, +{ PROC_LINKS(auto_indent_whole_file, 0), false, "auto_indent_whole_file", 22, "Audo-indents the entire current buffer.", 39, "c:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 398 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 165 }, +{ PROC_LINKS(backspace_char, 0), false, "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 622 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 159 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 122 }, +{ PROC_LINKS(center_view, 0), false, "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 208 }, +{ 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, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 180 }, +{ PROC_LINKS(clean_all_lines, 0), false, "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 587 }, +{ PROC_LINKS(clear_all_themes, 0), false, "clear_all_themes", 16, "Clear the theme list", 20, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 244 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 234 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 254 }, +{ PROC_LINKS(click_set_mark, 0), false, "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 266 }, +{ 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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_build_commands.cpp", 44, 174 }, +{ PROC_LINKS(close_panel, 0), false, "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 630 }, +{ 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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 761 }, +{ PROC_LINKS(comment_line, 0), false, "comment_line", 12, "Insert '//' at the beginning of the line after leading whitespace.", 66, "c:\\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, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 135 }, +{ 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, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 693 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1804 }, +{ PROC_LINKS(default_startup, 0), false, "default_startup", 15, "Default command for responding to a startup event", 49, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_default_hooks.cpp", 43, 51 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 173 }, +{ PROC_LINKS(delete_char, 0), false, "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1230 }, +{ PROC_LINKS(delete_line, 0), false, "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1402 }, +{ PROC_LINKS(delete_range, 0), false, "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 145 }, +{ PROC_LINKS(duplicate_line, 0), false, "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1388 }, +{ 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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_cli_command.cpp", 41, 7 }, +{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 749 }, +{ PROC_LINKS(goto_beginning_of_file, 0), false, "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 525 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 542 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 348 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 375 }, +{ PROC_LINKS(goto_line, 0), false, "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 757 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 464 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 494 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 481 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 511 }, +{ PROC_LINKS(hide_filebar, 0), false, "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 660 }, +{ PROC_LINKS(hide_scrollbar, 0), false, "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 646 }, +{ PROC_LINKS(hms_demo_tutorial, 0), false, "hms_demo_tutorial", 17, "Tutorial for built in 4coder bindings and features.", 51, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 564 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_jump_sticky.cpp", 41, 581 }, +{ PROC_LINKS(increase_face_size, 0), false, "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 682 }, +{ PROC_LINKS(interactive_kill_buffer, 0), true, "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 520 }, +{ PROC_LINKS(interactive_new, 0), true, "interactive_new", 15, "Interactively creates a new file.", 33, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 661 }, +{ PROC_LINKS(interactive_open, 0), true, "interactive_open", 16, "Interactively opens a file.", 27, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 715 }, +{ PROC_LINKS(interactive_open_or_new, 0), true, "interactive_open_or_new", 23, "Interactively open a file out of the file system.", 49, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 612 }, +{ PROC_LINKS(interactive_switch_buffer, 0), true, "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 510 }, +{ 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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 54 }, +{ PROC_LINKS(keyboard_macro_replay, 0), false, "keyboard_macro_replay", 21, "Replay the most recently recorded keyboard macro", 48, "c:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 77 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_keyboard_macro.cpp", 44, 41 }, +{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1548 }, +{ PROC_LINKS(kill_tutorial, 0), false, "kill_tutorial", 13, "If there is an active tutorial, kill it.", 40, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 222 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 296 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_function_list.cpp", 43, 302 }, +{ 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, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 165 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 177 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 189 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 195 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 201 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 207 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 213 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 221 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 171 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 183 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_project_commands.cpp", 46, 862 }, +{ PROC_LINKS(load_theme_current_buffer, 0), false, "load_theme_current_buffer", 25, "Parse the current buffer as a theme file and add the theme to the theme list. If the buffer has a .4coder postfix in it's name, it is removed when the name is saved.", 165, "c:\\4ed\\code\\custom\\4coder_config.cpp", 36, 1622 }, +{ PROC_LINKS(load_themes_default_folder, 0), false, "load_themes_default_folder", 26, "Loads all the theme files in the default theme folder.", 54, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1342 }, +{ PROC_LINKS(miblo_decrement_basic, 0), false, "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 704 }, +{ PROC_LINKS(mouse_wheel_scroll, 0), false, "mouse_wheel_scroll", 18, "Reads the scroll wheel value from the mouse state and scrolls accordingly.", 74, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 276 }, +{ PROC_LINKS(move_down, 0), false, "move_down", 9, "Moves the cursor down one line.", 31, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 347 }, +{ PROC_LINKS(move_down_10, 0), false, "move_down_10", 12, "Moves the cursor down ten lines.", 32, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 359 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 365 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 418 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 442 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 430 }, +{ PROC_LINKS(move_left, 0), false, "move_left", 9, "Moves the cursor one character to the left.", 43, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 448 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 525 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 539 }, +{ PROC_LINKS(move_left_token_boundary, 0), false, "move_left_token_boundary", 24, "Seek left for the next beginning of a token.", 44, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 497 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 482 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 511 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1382 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1376 }, +{ PROC_LINKS(move_right, 0), false, "move_right", 10, "Moves the cursor one character to the right.", 44, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 456 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 518 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 532 }, +{ PROC_LINKS(move_right_token_boundary, 0), false, "move_right_token_boundary", 25, "Seek right for the next end of a token.", 39, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 490 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 474 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 504 }, +{ PROC_LINKS(move_up, 0), false, "move_up", 7, "Moves the cursor up one line.", 29, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 341 }, +{ PROC_LINKS(move_up_10, 0), false, "move_up_10", 10, "Moves the cursor up ten lines.", 30, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 353 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 412 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 436 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 424 }, +{ 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, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1467 }, +{ PROC_LINKS(open_in_other, 0), false, "open_in_other", 13, "Interactively opens a file in the other panel.", 46, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1798 }, +{ PROC_LINKS(open_long_braces, 0), false, "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "c:\\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, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1499 }, +{ PROC_LINKS(open_panel_hsplit, 0), false, "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 383 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 375 }, +{ PROC_LINKS(paste, 0), false, "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "c:\\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, "c:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 113 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 72 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 120 }, +{ 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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1158 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1179 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1195 }, +{ PROC_LINKS(redo, 0), false, "redo", 4, "Advances forwards through the undo history of the current buffer.", 65, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1637 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1722 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1307 }, +{ PROC_LINKS(reopen, 0), false, "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1566 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1068 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1059 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1050 }, +{ PROC_LINKS(reverse_search, 0), false, "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 991 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1003 }, +{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1556 }, +{ PROC_LINKS(save_all_dirty_buffers, 0), false, "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1274 }, +{ PROC_LINKS(search, 0), false, "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 985 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 997 }, +{ PROC_LINKS(seek_beginning_of_line, 0), false, "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 548 }, +{ 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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 126 }, +{ PROC_LINKS(set_mode_to_notepad_like, 0), false, "set_mode_to_notepad_like", 24, "Sets the edit mode to Notepad like.", 35, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 653 }, +{ PROC_LINKS(show_scrollbar, 0), false, "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 639 }, +{ PROC_LINKS(show_the_log_graph, 0), true, "show_the_log_graph", 18, "Parses *log* and displays the 'log graph' UI", 44, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 190 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 198 }, +{ PROC_LINKS(snippet_lister, 0), true, "snippet_lister", 14, "Opens a snippet lister for inserting whole pre-written snippets of text.", 72, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1524 }, +{ PROC_LINKS(test_double_backspace, 0), false, "test_double_backspace", 21, "Made for testing purposes (I should have deleted this if you are reading it let me know)", 88, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 115 }, +{ PROC_LINKS(theme_lister, 0), true, "theme_lister", 12, "Opens an interactive list of all registered themes.", 51, "c:\\4ed\\code\\custom\\4coder_lists.cpp", 35, 785 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 574 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 561 }, +{ PROC_LINKS(toggle_filebar, 0), false, "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 667 }, +{ PROC_LINKS(toggle_fps_meter, 0), false, "toggle_fps_meter", 16, "Toggles the visibility of the FPS performance meter", 51, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 676 }, +{ 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, "c:\\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, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 730 }, +{ PROC_LINKS(toggle_line_wrap, 0), false, "toggle_line_wrap", 16, "Toggles the line wrap setting on this buffer.", 45, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 736 }, +{ PROC_LINKS(toggle_mouse, 0), false, "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 721 }, +{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "c:\\4ed\\code\\custom\\4coder_code_index.cpp", 40, 1170 }, +{ PROC_LINKS(tutorial_maximize, 0), false, "tutorial_maximize", 17, "Expand the tutorial window", 26, "c:\\4ed\\code\\custom\\4coder_tutorial.cpp", 38, 20 }, +{ PROC_LINKS(tutorial_minimize, 0), false, "tutorial_minimize", 17, "Shrink the tutorial window", 26, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1624 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1651 }, +{ 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, "c:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1512 }, +{ 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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 395 }, +{ PROC_LINKS(word_complete_drop_down, 0), false, "word_complete_drop_down", 23, "Word complete with drop down menu.", 34, "c:\\4ed\\code\\custom\\4coder_search.cpp", 36, 642 }, +{ PROC_LINKS(write_block, 0), false, "write_block", 11, "At the cursor, insert a block comment.", 38, "c:\\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, "c:\\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, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 88 }, +{ PROC_LINKS(write_space, 0), false, "write_space", 11, "Inserts a space.", 16, "c:\\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, "c:\\4ed\\code\\custom\\4coder_auto_indent.cpp", 41, 427 }, +{ PROC_LINKS(write_text_input, 0), false, "write_text_input", 16, "Inserts whatever text was used to trigger this command.", 55, "c:\\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, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 76 }, +{ PROC_LINKS(write_underscore, 0), false, "write_underscore", 16, "Inserts an underscore.", 22, "c:\\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, "c:\\4ed\\code\\custom\\4coder_combined_write_commands.cpp", 53, 100 }, }; static i32 fcoder_metacmd_ID_allow_mouse = 0; static i32 fcoder_metacmd_ID_auto_indent_line_at_cursor = 1;