Merge remote-tracking branch 'origin/master' into linux-update

This commit is contained in:
Alex Baines 2020-03-07 15:08:57 +00:00
commit 712b8a5896
70 changed files with 3805 additions and 5139 deletions

View File

@ -252,7 +252,7 @@ App_Init_Sig(app_init){
working_set_init(models, &models->working_set);
Mutex_Lock file_order_lock(models->working_set.mutex);
// NOTE(allen):
// NOTE(allen):
global_history_init(&models->global_history);
text_layout_init(tctx, &models->text_layouts);
@ -748,6 +748,10 @@ App_Step_Sig(app_step){
}
}
if (models->whole_screen_render_caller != 0){
models->whole_screen_render_caller(&app, frame);
}
models->in_render_mode = false;
end_render_section(target);
}

View File

@ -2234,6 +2234,10 @@ set_custom_hook(Application_Links *app, Hook_ID hook_id, Void_Func *func_ptr){
{
models->render_caller = (Render_Caller_Function*)func_ptr;
}break;
case HookID_WholeScreenRenderCaller:
{
models->whole_screen_render_caller = (Whole_Screen_Render_Caller_Function*)func_ptr;
}break;
case HookID_BufferNameResolver:
{
models->buffer_name_resolver = (Buffer_Name_Resolver_Function*)func_ptr;

View File

@ -62,6 +62,7 @@ struct Models{
Tick_Function *tick;
Render_Caller_Function *render_caller;
Whole_Screen_Render_Caller_Function *whole_screen_render_caller;
Delta_Rule_Function *delta_rule;
u64 delta_rule_memory_size;

View File

@ -123,9 +123,20 @@ make_key_list(Arena *arena){
add_code(arena, &list, string_u8_litexpr("Control"));
add_code(arena, &list, string_u8_litexpr("Alt"));
add_code(arena, &list, string_u8_litexpr("Command"));
for (u32 i = 1; i <= 16; i += 1){
for (u32 i = 1; i <= 24; i += 1){
add_code(arena, &list, push_u8_stringf(arena, "F%d", i));
}
for (u32 i = '0'; i <= '9'; i += 1){
add_code(arena, &list, push_u8_stringf(arena, "NumPad%c", i));
}
add_code(arena, &list, string_u8_litexpr("NumPadStar"));
add_code(arena, &list, string_u8_litexpr("NumPadPlus"));
add_code(arena, &list, string_u8_litexpr("NumPadMinus"));
add_code(arena, &list, string_u8_litexpr("NumPadDot"));
add_code(arena, &list, string_u8_litexpr("NumPadSlash"));
for (i32 i = 0; i < 30; i += 1){
add_code(arena, &list, push_u8_stringf(arena, "Ex%d", i));
}
return(list);
}

View File

@ -25,6 +25,19 @@
// OS and compiler index
//
typedef u32 Tier_Code;
enum{
Tier_Demo,
Tier_Super,
Tier_COUNT,
};
char *tier_names[] = {
"demo",
"super",
};
typedef u32 Platform_Code;
enum{
Platform_Windows,
Platform_Linux,
@ -40,6 +53,7 @@ char *platform_names[] = {
"mac",
};
typedef u32 Compiler_Code;
enum{
Compiler_CL,
Compiler_GCC,
@ -55,6 +69,21 @@ char *compiler_names[] = {
"clang",
};
typedef u32 Arch_Code;
enum{
Arch_X64,
Arch_X86,
//
Arch_COUNT,
Arch_None = Arch_COUNT,
};
char *arch_names[] = {
"x64",
"x86",
};
#if OS_WINDOWS
# define This_OS Platform_Windows
#elif OS_LINUX
@ -115,22 +144,6 @@ char **platform_includes[Platform_COUNT][Compiler_COUNT] = {
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{
@ -294,7 +307,8 @@ build(Arena *arena, u32 flags, u32 arch, char *code_path, char **code_files, cha
"-Wno-write-strings " \
"-D_GNU_SOURCE -fPIC " \
"-fno-threadsafe-statics -pthread " \
"-Wno-unused-result"
"-Wno-unused-result " \
"-std=c++11"
#define GCC_LIBS_COMMON \
"-lX11 -lpthread -lm -lrt " \
@ -491,24 +505,20 @@ build_and_run(Arena *arena, char *cdir, char *filename, char *name, u32 flags){
{
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);
printf("BUILDSUPER:\n cdir = %s;\n file = %s;\n arch = %s;\n", cdir, file, arch_names[arch]);
fflush(stdout);
BEGIN_TIME_SECTION();
Temp_Dir temp = fm_pushdir(fm_str(arena, BUILD_DIR));
char *build_script_postfix = "";
@ -535,7 +545,6 @@ buildsuper(Arena *arena, char *cdir, char *file, u32 arch){
systemf("%s", build_command);
fm_popdir(temp);
END_TIME_SECTION("build custom");
fflush(stdout);
}
@ -549,26 +558,20 @@ build_main(Arena *arena, char *cdir, b32 update_local_theme, u32 flags, u32 arch
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);
@ -592,12 +595,6 @@ get_4coder_dist_name(Arena *arena, u32 platform, char *tier, u32 arch){
return(name);
}
enum{
Tier_Demo,
Tier_Super,
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];
@ -605,10 +602,10 @@ package_for_arch(Arena *arena, u32 arch, char *cdir, char *build_dir, char *pack
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);
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);
@ -633,10 +630,7 @@ package_for_arch(Arena *arena, u32 arch, char *cdir, char *build_dir, char *pack
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);
}
@ -646,8 +640,20 @@ package_for_arch(Arena *arena, u32 arch, char *cdir, char *build_dir, char *pack
fm_zip(parent_dir, "4coder", zip_name);
}
internal u32
tier_flags(Tier_Code code){
u32 result = 0;
switch (code){
case Tier_Super:
{
result = SUPER;
}break;
}
return(result);
}
internal void
package(Arena *arena, char *cdir){
package(Arena *arena, char *cdir, Tier_Code tier, Arch_Code arch){
// NOTE(allen): meta
char *build_dir = fm_str(arena, BUILD_DIR);
char *pack_dir = fm_str(arena, PACK_DIR);
@ -661,44 +667,24 @@ package(Arena *arena, char *cdir){
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);
u32 arch_count = Arch_COUNT;
u32 arch_array[2] = {
Arch_X64,
Arch_X86,
};
if (This_OS == Platform_Mac){
arch_count = 1;
}
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));
}
end_temp(temp);
}
char *tier_name = tier_names[tier];
u32 flags = base_flags | tier_flags(tier);
Temp_Memory temp = begin_temp(arena);
char *current_dist_tier = fm_str(arena, ".." SLASH "current_dist_", tier_name);
package_for_arch(arena, arch, cdir, build_dir, pack_dir, tier, tier_name, current_dist_tier, flags, dist_files, ArrayCount(dist_files));
end_temp(temp);
}
int main(int argc, char **argv){
Arena arena = fm_init_system();
Arena arena = fm_init_system(DetailLevel_FileOperations);
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;
@ -715,8 +701,17 @@ int main(int argc, char **argv){
#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);
#elif defined(PACKAGE_DEMO_X64)
package(&arena, cdir, Tier_Demo, Arch_X64);
#elif defined(PACKAGE_DEMO_X86)
package(&arena, cdir, Tier_Demo, Arch_X86);
#elif defined(PACKAGE_SUPER_X64)
package(&arena, cdir, Tier_Super, Arch_X64);
#elif defined(PACKAGE_SUPER_X86)
package(&arena, cdir, Tier_Super, Arch_X86);
#else
# error No build type specified.

View File

@ -3,7 +3,8 @@
# If any command errors, stop the script
set -e
# Set up directories (mirrors build.bat)
# Set up directories
ME="$(readlink -f "$0")"
LOCATION="$(dirname "$ME")"
SRC_ROOT="$(dirname "$LOCATION")"
@ -22,15 +23,7 @@ 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-logical-op-parentheses -Wno-null-dereference -Wno-switch"
fi
FLAGS="-D_GNU_SOURCE -fPIC -fpermissive $BUILD_MODE"
INCLUDES="-I$SRC_ROOT -I$CUSTOM_ROOT"

View File

@ -3,7 +3,7 @@
# If any command errors, stop the script
set -e
# Set up directories (mirrors build.bat)
# Set up directories
# NOTE(yuval): Replaced readlink with realpath which works for both macOS and Linux
ME="$(realpath "$0")"
LOCATION="$(dirname "$ME")"
@ -23,15 +23,7 @@ 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-logical-op-parentheses -Wno-switch"
fi
FLAGS="-D_GNU_SOURCE -fPIC -fpermissive $BUILD_MODE"
INCLUDES="-I$SRC_ROOT -I$CUSTOM_ROOT"

7
bin/build-x86-linux.sh Executable file
View File

@ -0,0 +1,7 @@
#!/bin/bash
ME="$(readlink -f "$0")"
LOCATION="$(dirname "$ME")"
$LOCATION/build-linux.sh -DDEV_BUILD_X86

3
bin/build-x86.bat Normal file
View File

@ -0,0 +1,3 @@
@echo off
build.bat /DDEV_BUILD_X86

View File

@ -1,5 +0,0 @@
#!/bin/bash
./build.sh -DDEV_BUILD_X86

View File

@ -1,5 +0,0 @@
#!/bin/bash
./build.sh -DDEV_BUILD_X86

0
bin/itchio_push_all.sh Normal file → Executable file
View File

22
bin/itchio_push_linux-x86.sh Executable file
View File

@ -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=../current_dist_all_os
butler push $flags $dir/demo_x86/4coder-$fv-demo-linux-x86.zip 4coder/4coder:linux-x86-demo
butler push $flags $dir/super_x86/4coder-$fv-super-linux-x86.zip 4coder/4coder:linux-x86
fi

22
bin/itchio_push_linux.sh Executable file
View File

@ -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=../current_dist_all_os
butler push $flags $dir/demo_x64/4coder-$fv-demo-linux-x64.zip 4coder/4coder:linux-x64-demo
butler push $flags $dir/super_x64/4coder-$fv-super-linux-x64.zip 4coder/4coder:linux-x64
fi

View File

@ -17,6 +17,6 @@ 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
butler push $flags $dir/super_x64/4coder-$fv-super-mac-x64.zip 4coder/4coder:mac-x64
fi

5
bin/package-linux.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
chmod +x bin/build-linux.sh
bin/build-linux.sh "-DPACKAGE_DEMO_X64"
bin/build-linux.sh "-DPACKAGE_SUPER_X64"

View File

@ -1,4 +1,5 @@
#!/bin/bash
chmod 777 bin/build-mac.sh
bin/build-mac.sh "-DPACKAGE"
chmod +x bin/build-mac.sh
bin/build-mac.sh "-DPACKAGE_DEMO_X64"
bin/build-mac.sh "-DPACKAGE_SUPER_X64"

5
bin/package-x86-linux.sh Executable file
View File

@ -0,0 +1,5 @@
#!/bin/bash
chmod +x bin/build-linux.sh
bin/build-linux.sh "-DPACKAGE_DEMO_X86"
bin/build-linux.sh "-DPACKAGE_SUPER_X86"

View File

@ -1,3 +1,6 @@
@echo off
bin\build.bat /DPACKAGE
bin\build.bat /DPACKAGE_DEMO_X64
bin\build.bat /DPACKAGE_DEMO_X86
bin\build.bat /DPACKAGE_SUPER_X64
bin\build.bat /DPACKAGE_SUPER_X86

View File

@ -1,4 +0,0 @@
#!/bin/bash
chmod 777 build.sh
./build.sh "-DPACKAGE"

View File

@ -112,17 +112,6 @@ 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.")
{
@ -909,8 +898,7 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos,
}
isearch__update_highlight(app, view, Ii64_size(pos, match_size));
in = get_next_input(app, EventPropertyGroup_AnyKeyboardEvent,
EventProperty_Escape|EventProperty_ViewActivation);
in = get_next_input(app, EventPropertyGroup_Any, EventProperty_Escape);
if (in.abort){
break;
}
@ -953,9 +941,6 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos,
}
}
// TODO(allen): how to detect if the input corresponds to
// a search or rsearch command, a scroll wheel command?
b32 do_scan_action = false;
b32 do_scroll_wheel = false;
Scan_Direction change_scan = scan;
@ -965,17 +950,41 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos,
change_scan = Scan_Forward;
do_scan_action = true;
}
if (match_key_code(&in, KeyCode_PageUp) ||
match_key_code(&in, KeyCode_Up)){
else if (match_key_code(&in, KeyCode_PageUp) ||
match_key_code(&in, KeyCode_Up)){
change_scan = Scan_Backward;
do_scan_action = true;
}
#if 0
if (in.command == mouse_wheel_scroll){
do_scroll_wheel = true;
else{
// NOTE(allen): is the user trying to execute another command?
View_Context ctx = view_current_context(app, view);
Mapping *mapping = ctx.mapping;
Command_Map *map = mapping_get_map(mapping, ctx.map_id);
Command_Binding binding = map_get_binding_recursive(mapping, map, &in.event);
if (binding.custom != 0){
if (binding.custom == search){
change_scan = Scan_Forward;
do_scan_action = true;
}
else if (binding.custom == reverse_search){
change_scan = Scan_Backward;
do_scan_action = true;
}
else{
Command_Metadata *metadata = get_command_metadata(binding.custom);
if (metadata != 0){
if (metadata->is_ui){
view_enqueue_command_function(app, view, binding.custom);
break;
}
}
binding.custom(app);
}
}
else{
leave_current_input_unhandled(app);
}
}
#endif
}
if (string_change){
@ -1028,9 +1037,6 @@ isearch(Application_Links *app, Scan_Direction start_scan, i64 first_pos,
else if (do_scroll_wheel){
mouse_wheel_scroll(app);
}
else{
leave_current_input_unhandled(app);
}
}
view_disable_highlight_range(app, view);

View File

@ -135,17 +135,17 @@
////////////////////////////////
#if COMPILER_CL
#if _MSC_VER <= 1800
# define snprintf _snprintf
#endif
# if _MSC_VER <= 1800
# define snprintf _snprintf
# endif
#if (_MSC_VER <= 1500)
#define JUST_GUESS_INTS
#endif
# if (_MSC_VER <= 1500)
# define JUST_GUESS_INTS
# endif
#endif
// NOTE(yuval): Changed this so that CALL_CONVENTION will be defined for all platforms
#if ARCH_32BIT
#if ARCH_32BIT && OS_WINDOWS
# define CALL_CONVENTION __stdcall
#else
# define CALL_CONVENTION
@ -527,8 +527,8 @@ union SNode{
#define zdll_remove_back_NP_(f,l,next,prev) ((f==l)?(f=l=0):(l->prev->next=0,l=l->prev))
#define zdll_remove_NP_(f,l,n,next,prev) \
((l==n)?(zdll_remove_back_NP_(f,l,next,prev)) \
:(f==n)?(zdll_remove_back_NP_(l,f,prev,next)) \
: (dll_remove_NP_(n,n,next,prev)))
:(f==n)?(zdll_remove_back_NP_(l,f,prev,next)) \
: (dll_remove_NP_(n,n,next,prev)))
#define zdll_push_back(f,l,n) zdll_push_back_NP_((f),(l),(n),next,prev)
#define zdll_push_front(f,l,n) zdll_push_back_NP_((l),(f),(n),prev,next)

View File

@ -15,9 +15,9 @@ CUSTOM_DOC("List all definitions in the code index and jump to one chosen by the
char *query = "Definition:";
Scratch_Block scratch(app);
Lister *lister = begin_lister(app, scratch);
Lister_Block lister(app, scratch);
lister_set_query(lister, query);
lister->handlers = lister_get_default_handlers();
lister_set_default_handlers(lister);
code_index_lock();
for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always);

View File

@ -211,9 +211,9 @@ function Snippet*
get_snippet_from_user(Application_Links *app, Snippet *snippets, i32 snippet_count,
String_Const_u8 query){
Scratch_Block scratch(app, Scratch_Share);
Lister *lister = begin_lister(app, scratch);
Lister_Block lister(app, scratch);
lister_set_query(lister, query);
lister->handlers = lister_get_default_handlers();
lister_set_default_handlers(lister);
Snippet *snippet = snippets;
for (i32 i = 0; i < snippet_count; i += 1, snippet += 1){

View File

@ -1367,7 +1367,7 @@ config_parse__file_name(Application_Links *app, Arena *arena, char *file_name, C
if (data.data != 0){
parsed = config_parse__data(app, arena, SCu8(file_name), SCu8(data),
config);
success = true;
success = true;
}
}
if (!success){

View File

@ -103,15 +103,15 @@ open_footer_panel(Application_Links *app, View_ID view){
function void
close_build_footer_panel(Application_Links *app){
if (build_footer_panel_view_id != 0){
if (view_exists(app, build_footer_panel_view_id)){
view_close(app, build_footer_panel_view_id);
build_footer_panel_view_id = 0;
}
build_footer_panel_view_id = 0;
}
function View_ID
open_build_footer_panel(Application_Links *app){
if (build_footer_panel_view_id == 0){
if (!view_exists(app, build_footer_panel_view_id)){
View_ID view = get_active_view(app, Access_Always);
build_footer_panel_view_id = open_footer_panel(app, view);
view_set_active(app, view);
@ -497,18 +497,18 @@ function void
default_4coder_initialize(Application_Links *app, String_Const_u8_Array file_names,
i32 override_font_size, b32 override_hinting){
#define M \
"Welcome to " VERSION "\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));
"Welcome to " VERSION "\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));
#undef M
load_config_and_apply(app, global_config_arena, &global_config, override_font_size, override_hinting);

View File

@ -15,6 +15,7 @@ CUSTOM_ID(attachment, view_highlight_range);
CUSTOM_ID(attachment, view_highlight_buffer);
CUSTOM_ID(attachment, view_render_hook);
CUSTOM_ID(attachment, view_word_complete_menu);
CUSTOM_ID(attachment, view_lister_loc);
CUSTOM_ID(attachment, buffer_map_id);
CUSTOM_ID(attachment, buffer_eol_setting);

View File

@ -474,6 +474,20 @@ default_render_caller(Application_Links *app, Frame_Info frame_info, View_ID vie
draw_set_clip(app, prev_clip);
}
function void
default_whole_screen_render_caller(Application_Links *app, Frame_Info frame_info){
#if 0
Rect_f32 region = global_get_screen_rectangle(app);
Vec2_f32 center = rect_center(region);
Face_ID face_id = get_face_id(app, 0);
Scratch_Block scratch(app);
draw_string_oriented(app, face_id, finalize_color(defcolor_text_default, 0),
SCu8("Hello, World!"), center,
GlyphFlag_Rotate90, V2f32(0.f, 1.f));
#endif
}
HOOK_SIG(default_view_adjust){
// NOTE(allen): Called whenever the view layout/sizes have been modified,
// including by full window resize.
@ -1022,6 +1036,7 @@ set_all_default_hooks(Application_Links *app){
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);
set_custom_hook(app, HookID_WholeScreenRenderCaller, default_whole_screen_render_caller);
#if 0
set_custom_hook(app, HookID_DeltaRule, original_delta);
set_custom_hook_memory_size(app, HookID_DeltaRule,

View File

@ -125,6 +125,8 @@
#include "4coder_doc_commands.cpp"
#include "4coder_docs.cpp"
#include "4coder_examples.cpp"
#include "4coder_default_hooks.cpp"
#endif

View File

@ -53,7 +53,7 @@ delta_apply(Application_Links *app, View_ID view,
}
function Buffer_Point_Delta_Result
delta_apply(Application_Links *app, View_ID view,
delta_apply(Application_Links *app, View_ID view,
Delta_Rule_Function *func, Data delta_ctx,
f32 dt, Buffer_Scroll scroll){
return(delta_apply(app, view, func, delta_ctx,
@ -61,7 +61,7 @@ delta_apply(Application_Links *app, View_ID view,
}
function Buffer_Point_Delta_Result
delta_apply(Application_Links *app, View_ID view,
delta_apply(Application_Links *app, View_ID view,
f32 dt, Buffer_Point position, Buffer_Point target){
View_Context ctx = view_current_context(app, view);
Data delta_ctx = view_current_context_hook_memory(app, view, HookID_DeltaRule);
@ -70,7 +70,7 @@ delta_apply(Application_Links *app, View_ID view,
}
function Buffer_Point_Delta_Result
delta_apply(Application_Links *app, View_ID view,
delta_apply(Application_Links *app, View_ID view,
f32 dt, Buffer_Scroll scroll){
View_Context ctx = view_current_context(app, view);
Data delta_ctx = view_current_context_hook_memory(app, view, HookID_DeltaRule);
@ -119,7 +119,7 @@ delta_apply(Application_Links *app, View_ID view,
}
function Vec2_f32_Delta_Result
delta_apply(Application_Links *app, View_ID view,
delta_apply(Application_Links *app, View_ID view,
f32 dt, Vec2_f32 position, Vec2_f32 target){
View_Context ctx = view_current_context(app, view);
Data delta_ctx = view_current_context_hook_memory(app, view, HookID_DeltaRule);
@ -128,7 +128,7 @@ delta_apply(Application_Links *app, View_ID view,
}
function Vec2_f32_Delta_Result
delta_apply(Application_Links *app, View_ID view,
delta_apply(Application_Links *app, View_ID view,
f32 dt, Basic_Scroll scroll){
View_Context ctx = view_current_context(app, view);
Data delta_ctx = view_current_context_hook_memory(app, view, HookID_DeltaRule);

View File

@ -7,9 +7,9 @@
function Doc_Page*
get_doc_page_from_user(Application_Links *app, Doc_Cluster *doc, String_Const_u8 query){
Scratch_Block scratch(app, Scratch_Share);
Lister *lister = begin_lister(app, scratch);
Lister_Block lister(app, scratch);
lister_set_query(lister, query);
lister->handlers = lister_get_default_handlers();
lister_set_default_handlers(lister);
for (Doc_Page *page = doc->first_page;
page != 0;
@ -125,7 +125,7 @@ render_doc_page(Application_Links *app, Doc_Page *page){
}
Buffer_Insertion insert = begin_buffer_insertion_at_buffered(app, buffer, 0, scratch, KB(16));
char dashes[] =
char dashes[] =
"----------------------------------------------------------------"
"----------------------------------------------------------------"
"----------------------------------------------------------------"

View File

@ -132,14 +132,17 @@ enum{
EventPropertyGroup_AnyUserInput =
EventPropertyGroup_AnyKeyboardEvent|
EventPropertyGroup_AnyMouseEvent,
EventPropertyGroup_Any =
EventPropertyGroup_AnyUserInput|
EventPropertyGroup_AnyCore =
EventProperty_Animate|
EventProperty_ViewActivation|
EventProperty_AnyFile|
EventProperty_Startup|
EventProperty_Exit|
EventProperty_Clipboard|
EventProperty_Animate,
EventPropertyGroup_Any =
EventPropertyGroup_AnyUserInput|
EventPropertyGroup_AnyCore|
EventProperty_CustomFunction,
};

209
custom/4coder_examples.cpp Normal file
View File

@ -0,0 +1,209 @@
/*
4coder_examples.cpp - Commands that are included mainly to serve as example code for
customization writers.
*/
// TOP
// tags: history; group
// example-of: History_Group; history_group_begin; history_group_end
CUSTOM_COMMAND_SIG(double_backspace)
CUSTOM_DOC("Example of history group helpers")
{
/* History_Group is a wrapper around the history API that makes it easy to
group any series of edits into a single undo/redo record in the buffer's history.
Before any edits call history_group_begin and afterwards call history_group_end.
After history_group_end all of the edits to the buffer supplied in history_group_begin
will be merged, including all edits from function and command calls. */
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);
}
// tags: query; bar
// example-of: Query_Bar
CUSTOM_COMMAND_SIG(play_with_a_counter)
CUSTOM_DOC("Example of query bar")
{
/* Query bars make a quick lightweight display of a single line of text for interactive
commands, while still showing the buffer. Query bars are convenient because they don't
require any complex UI setup, or extra rendering work inside your command.
First, constructing a Query_Bar_Group is a convenient way to make sure the query bar
states are fully cleaned up when the command ends.
Second, we make our query bar and start showing it with start_query_bar. Until we
call end_query_bar on the same bar, or the group's destructor runs, the bar struct
needs to remain in memory. The easy way to accomplish this is to just let the bar be
on the commands stack frame. */
i32 counter = 0;
Query_Bar_Group group(app);
Query_Bar dumb_bar = {};
dumb_bar.prompt = SCu8("Goes away at >= 10");
if (!start_query_bar(app, &dumb_bar, 0)){
return;
}
Query_Bar bar = {};
bar.prompt = SCu8("Counter = ");
bar.string = SCu8("");
if (!start_query_bar(app, &bar, 0)){
return;
}
for (;;){
/* Notice here, we set the string of the query bar BEFORE we call get_next_input.
get_next_input blocks this command until the next input is sent from the core. Whatever
string we put in the bar now will be shown and remain in the bar until an event wakes
up this command and we get a chance to modify the bar again. */
Scratch_Block scratch(app);
bar.string = push_stringf(scratch, "%d", counter);
if (counter >= 10){
end_query_bar(app, &dumb_bar, 0);
}
User_Input in = get_next_input(app, EventPropertyGroup_Any, EventProperty_Escape);
if (in.abort){
break;
}
if (match_key_code(&in.event, KeyCode_Up)){
counter += 1;
}
else if (match_key_code(&in.event, KeyCode_Down)){
counter -= 1;
}
else{
leave_current_input_unhandled(app);
}
}
}
// tags: input; loop
// example-of: get_next_input; leave_current_input_unhandled
CUSTOM_COMMAND_SIG(display_key_codes)
CUSTOM_DOC("Example of input handling loop")
{
/* In the 4coder custom layer, inputs are handled by a view context. A view context is a
thread that hands off control with the main thread of the 4coder core. When a command is
running in a view context thread, it can wait for inputs from the core by calling
get_next_input. If your command gets inputs from the core, then default input handling
isn't happening, so command bindings don't trigger unless you trigger them yourself. */
Query_Bar_Group group(app);
Query_Bar bar = {};
bar.prompt = SCu8("KeyCode = ");
if (!start_query_bar(app, &bar, 0)){
return;
}
Key_Code code = 0;
for (;;){
Scratch_Block scratch(app);
if (code == 0){
bar.string = SCu8("...");
}
else{
bar.string = push_stringf(scratch, "KeyCode_%s (%d)", key_code_name[code], code);
}
User_Input in = get_next_input(app, EventPropertyGroup_Any, EventProperty_Escape);
if (in.abort){
break;
}
if (in.event.kind == InputEventKind_KeyStroke){
code = in.event.key.code;
}
else{
/* Marking inputs as handled lets the core determine if certain inputs should
be passed to additional handlers. This is especially important for text input,
which is explained more in the example display_text_input. */
leave_current_input_unhandled(app);
}
}
}
// tags: text; input
// example-of: get_next_input; leave_current_input_unhandled; to_writable
CUSTOM_COMMAND_SIG(display_text_input)
CUSTOM_DOC("Example of to_writable and leave_current_input_unhandled")
{
/* In the 4coder custom layer, inputs are handled by a view context. A view context is a
thread that hands off control with the main thread of the 4coder core. When a command is
running in a view context thread, it can wait for inputs from the core by calling
get_next_input. If your command gets inputs from the core, then default input handling
isn't happening, so command bindings don't trigger unless you trigger them yourself. */
Query_Bar_Group group(app);
Query_Bar bar = {};
bar.prompt = SCu8("Weird String: ");
if (!start_query_bar(app, &bar, 0)){
return;
}
u8 buffer[256];
u64 size = 0;
for (;;){
User_Input in = get_next_input(app, EventPropertyGroup_Any, EventProperty_Escape);
if (in.abort){
break;
}
String_Const_u8 in_string = to_writable(&in);
if (in_string.size > 0){
size = clamp_top(in_string.size, sizeof(buffer));
block_copy(buffer, in_string.str, size);
bar.string = SCu8(buffer, size);
}
else if (in.event.kind == InputEventKind_KeyStroke){
/* If we handle a key stroke then the core marks any text input generated from that
key stroke as handled too, and the text input is never passed. By marking key strokes
as unhandled, we ensure we get text input events. */
leave_current_input_unhandled(app);
}
}
}
// tags: string; number; query; user
// example-of: query_user_string; query_user_number
CUSTOM_COMMAND_SIG(string_repeat)
CUSTOM_DOC("Example of query_user_string and query_user_number")
{
Query_Bar_Group group(app);
Query_Bar string_bar = {};
string_bar.prompt = SCu8("String: ");
u8 string_buffer[KB(1)];
string_bar.string.str = string_buffer;
string_bar.string_capacity = sizeof(string_buffer);
Query_Bar number_bar = {};
number_bar.prompt = SCu8("Repeat Count: ");
u8 number_buffer[KB(1)];
number_bar.string.str = number_buffer;
number_bar.string_capacity = sizeof(number_buffer);
if (query_user_string(app, &string_bar)){
if (string_bar.string.size > 0){
if (query_user_number(app, &number_bar)){
if (number_bar.string.size > 0){
i32 repeats = (i32)string_to_integer(number_bar.string, 10);
repeats = clamp_top(repeats, 1000);
Scratch_Block scratch(app);
String_Const_u8 msg = push_stringf(scratch, "%.*s\n", string_expand(string_bar.string));
for (i32 i = 0; i < repeats; i += 1){
print_message(app, msg);
}
}
}
}
}
}
// BOTTOM

View File

@ -17,10 +17,6 @@
#include <stdarg.h>
#include <string.h>
//
// API
//
// System commands
static char SF_CMD[4096];
static i32 error_state = 0;
@ -43,15 +39,18 @@ if (prev_error != 0) error_state = 1; \
internal void fm_execute_in_dir(char *dir, char *str, char *args);
// Init
internal Arena fm_init_system();
enum{
DetailLevel_Basics = 0,
DetailLevel_FileOperations = 1,
DetailLevel_Everything = 2,
};
global i32 detail_level = 0;
internal Arena fm_init_system(i32 detail_level);
// Timing
internal u64 fm_get_time();
#define LLU_CAST(n) (long long unsigned int)(n)
#define BEGIN_TIME_SECTION() u64 start = fm_get_time()
#define END_TIME_SECTION(n) u64 total = fm_get_time() - start; printf("%-20s: %.2llu.%.6llu\n", (n), LLU_CAST(total/1000000), LLU_CAST(total%1000000));
// Files and Folders Manipulation
internal void fm_make_folder_if_missing(Arena *arena, char *dir);
internal void fm_clear_folder(char *folder);
@ -183,6 +182,16 @@ fm__init_memory(void){
return(make_arena_malloc(MB(512), 8));
}
function b32
fm__show_details_for_file_operations(void){
return(detail_level >= DetailLevel_FileOperations);
}
function b32
fm__show_details_for_zip_output(void){
return(detail_level >= DetailLevel_Everything);
}
//
// Windows implementation
//
@ -266,7 +275,8 @@ extern "C"{
global u64 perf_frequency;
internal Arena
fm_init_system(void){
fm_init_system(i32 det){
detail_level = det;
LARGE_INTEGER lint;
if (QueryPerformanceFrequency(&lint)){
perf_frequency = lint.QuadPart;
@ -351,7 +361,9 @@ fm_make_folder_if_missing(Arena *arena, char *dir){
internal void
fm_clear_folder(char *folder){
fprintf(stdout, "clearing folder %s\n", folder);
if (fm__show_details_for_file_operations()){
fprintf(stdout, "clearing folder %s\n", folder);
}
fflush(stdout);
systemf("del /S /Q /F %s\\* > nul & rmdir /S /Q %s > nul & mkdir %s > nul", folder, folder, folder);
}
@ -363,14 +375,18 @@ fm_delete_file(char *file){
internal void
fm_copy_file(char *file, char *newname){
printf("copy %s to %s\n", file, newname);
if (fm__show_details_for_file_operations()){
printf("copy %s to %s\n", file, newname);
}
fflush(stdout);
CopyFileA(file, newname, 0);
}
internal void
fm_copy_all(char *source, char *folder){
fprintf(stdout, "copy %s to %s\n", source, folder);
if (fm__show_details_for_file_operations()){
fprintf(stdout, "copy %s to %s\n", source, folder);
}
fflush(stdout);
systemf("xcopy /s /e /y /q %s %s > nul", source, folder);
}
@ -394,17 +410,27 @@ fm_write_file(char *file_name, char *data, u32 size){
internal void
fm_zip(char *parent, char *folder, char *dest){
printf("zipping %s\\%s to %s\n", parent, folder, dest);
if (fm__show_details_for_file_operations()){
printf("zipping %s\\%s to %s\n", parent, folder, dest);
}
fflush(stdout);
char cdir[512];
fm_get_current_directory(cdir, sizeof(cdir));
char *hide_output = " > nul >> nul";
char *show_output = "";
char *output_rule = hide_output;
if (fm__show_details_for_zip_output()){
output_rule = show_output;
}
Temp_Dir temp = fm_pushdir(parent);
systemf("%s\\bin\\zip %s\\4ed_gobble.zip > nul", cdir, cdir);
systemf("%s\\bin\\zip %s\\4ed_gobble.zip%s", cdir, cdir, output_rule);
fm_popdir(temp);
systemf("copy %s\\4ed_gobble.zip %s > nul & del %s\\4ed_gobble.zip > nul", cdir, dest, cdir);
systemf("copy %s\\4ed_gobble.zip %s%s & del %s\\4ed_gobble.zip%s",
cdir, dest, output_rule, cdir, output_rule);
}
//
@ -435,7 +461,8 @@ fm_popdir(Temp_Dir temp){
}
internal Arena
fm_init_system(){
fm_init_system(i32 det){
detail_level = det;
return(fm__init_memory());
}
@ -492,7 +519,9 @@ fm_make_folder_if_missing(Arena *arena, char *dir){
internal void
fm_clear_folder(char *folder){
fprintf(stdout, "clearing folder %s\n", folder);
if (fm__show_details_for_file_operations()){
fprintf(stdout, "clearing folder %s\n", folder);
}
fflush(stdout);
systemf("rm -rf %s* > /dev/null", folder);
}
@ -504,12 +533,19 @@ fm_delete_file(char *file){
internal void
fm_copy_file(char *file, char *newname){
if (fm__show_details_for_file_operations()){
printf("copy %s to %s\n", file, newname);
}
fflush(stdout);
systemf("cp %s %s", file, newname);
}
internal void
fm_copy_all(char *source, char *folder){
fprintf(stdout, "copy %s to %s\n", source, folder);
if (fm__show_details_for_file_operations()){
fprintf(stdout, "copy %s to %s\n", source, folder);
}
fflush(stdout);
systemf("cp -rf %s/* %s > /dev/null", source, folder);
}
@ -525,9 +561,20 @@ fm_write_file(char *file_name, char *data, u32 size){
internal void
fm_zip(char *parent, char *folder, char *file){
if (fm__show_details_for_file_operations()){
printf("zipping %s/%s to %s\n", parent, folder, file);
}
fflush(stdout);
char *hide_output = " > nul 2> nul";
char *show_output = "";
char *output_rule = hide_output;
if (fm__show_details_for_zip_output()){
output_rule = show_output;
}
Temp_Dir temp = fm_pushdir(parent);
printf("PARENT DIR: %s\n", parent);
systemf("zip -r %s %s", file, folder);
systemf("zip -r %s %s%s", file, folder, output_rule);
fm_popdir(temp);
}

File diff suppressed because it is too large Load Diff

View File

@ -10,9 +10,9 @@ get_jump_index_from_user(Application_Links *app, Marker_List *list,
Jump_Lister_Result result = {};
if (list != 0){
Scratch_Block scratch(app);
Lister *lister = begin_lister(app, scratch);
Lister_Block lister(app, scratch);
lister_set_query(lister, query);
lister->handlers = lister_get_default_handlers();
lister_set_default_handlers(lister);
Buffer_ID list_buffer = list->buffer_id;

View File

@ -38,11 +38,27 @@ lister_get_top_level_layout(Rect_f32 rect, f32 text_field_height){
////////////////////////////////
Lister *global_lister_state[16] = {};
function Lister*
view_get_lister(Application_Links *app, View_ID view){
Managed_Scope scope = view_get_managed_scope(app, view);
Lister **ptr = scope_attachment(app, scope, view_lister_loc, Lister*);
Lister *result = 0;
if (ptr != 0){
result = *ptr;
}
return(result);
}
function Lister*
view_get_lister(View_ID view){
return(global_lister_state[view - 1]);
view_set_lister(Application_Links *app, View_ID view, Lister *lister){
Managed_Scope scope = view_get_managed_scope(app, view);
Lister **ptr = scope_attachment(app, scope, view_lister_loc, Lister*);
Lister *result = 0;
if (ptr != 0){
result = *ptr;
*ptr = lister;
}
return(result);
}
function void
@ -57,19 +73,36 @@ lister_set_map(Lister *lister, Mapping *mapping, Command_Map_ID map){
lister->map = mapping_get_map(mapping, map);
}
function Lister*
function Lister_Prev_Current
begin_lister(Application_Links *app, Arena *arena){
Lister_Prev_Current result = {};
Lister *lister = push_array_zero(arena, Lister, 1);
lister->arena = arena;
lister->query = Su8(lister->query_space, 0, sizeof(lister->query_space));
lister->text_field = Su8(lister->text_field_space, 0, sizeof(lister->text_field_space));
lister->key_string = Su8(lister->key_string_space, 0, sizeof(lister->key_string_space));
View_ID view = get_this_ctx_view(app, Access_Always);
global_lister_state[view - 1] = lister;
result.prev = view_set_lister(app, view, lister);
result.current = lister;
lister->restore_all_point = begin_temp(lister->arena);
View_Context ctx = view_current_context(app, view);
lister_set_map(lister, ctx.mapping, ctx.map_id);
return(lister);
return(result);
}
Lister_Block::Lister_Block(Application_Links *a, Arena *arena){
Lister_Prev_Current new_lister = begin_lister(a, arena);
this->app = a;
this->lister = new_lister;
}
Lister_Block::~Lister_Block(){
View_ID view = get_this_ctx_view(app, Access_Always);
view_set_lister(this->app, view, this->lister.prev);
}
Lister_Block::operator Lister *(){
return(this->lister.current);
}
function void
@ -132,6 +165,11 @@ lister_append_key(Lister *lister, char *string){
lister_append_string(SCu8(string), &lister->key_string);
}
function void
lister_set_handlers(Lister *lister, Lister_Handlers *handlers){
block_copy_struct(&lister->handlers, handlers);
}
function void
lister_zero_scroll(Lister *lister){
block_zero_struct(&lister->scroll);
@ -141,7 +179,7 @@ function void
lister_render(Application_Links *app, Frame_Info frame_info, View_ID view){
Scratch_Block scratch(app);
Lister *lister = view_get_lister(view);
Lister *lister = view_get_lister(app, view);
if (lister == 0){
return;
}
@ -721,7 +759,7 @@ 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);
Lister *lister = view_get_lister(app, view);
if (lister != 0){
User_Input in = get_current_input(app);
String_Const_u8 string = to_writable(&in);
@ -739,7 +777,7 @@ lister__write_string__default(Application_Links *app){
function void
lister__backspace_text_field__default(Application_Links *app){
View_ID view = get_active_view(app, Access_Always);
Lister *lister = view_get_lister(view);
Lister *lister = view_get_lister(app, view);
if (lister != 0){
lister->text_field.string = backspace_utf8(lister->text_field.string);
lister->key_string.string = backspace_utf8(lister->key_string.string);
@ -775,15 +813,21 @@ lister_get_default_handlers(void){
return(handlers);
}
function void
lister_set_default_handlers(Lister *lister){
Lister_Handlers handlers = lister_get_default_handlers();
lister_set_handlers(lister, &handlers);
}
////////////////////////////////
function Lister_Result
run_lister_with_refresh_handler(Application_Links *app, Arena *arena, String_Const_u8 query, Lister_Handlers handlers){
Lister_Result result = {};
if (handlers.refresh != 0){
Lister *lister = begin_lister(app, arena);
Lister_Block lister(app, arena);
lister_set_query(lister, query);
lister->handlers = handlers;
lister_set_handlers(lister, &handlers);
handlers.refresh(app, lister);
result = run_lister(app, lister);
}
@ -865,7 +909,7 @@ function Lister_Activation_Code
lister__key_stroke__choice_list(Application_Links *app){
Lister_Activation_Code result = ListerActivation_Continue;
View_ID view = get_active_view(app, Access_Always);
Lister *lister = view_get_lister(view);
Lister *lister = view_get_lister(app, view);
if (lister != 0){
User_Input in = get_current_input(app);
if (in.event.kind == InputEventKind_KeyStroke){
@ -894,7 +938,7 @@ function Lister_Choice*
get_choice_from_user(Application_Links *app, String_Const_u8 query,
Lister_Choice_List list){
Scratch_Block scratch(app);
Lister *lister = begin_lister(app, scratch);
Lister_Block lister(app, scratch);
for (Lister_Choice *choice = list.first;
choice != 0;
choice = choice->next){
@ -907,8 +951,7 @@ get_choice_from_user(Application_Links *app, String_Const_u8 query,
Lister_Handlers handlers = {};
handlers.navigate = lister__navigate__default;
handlers.key_stroke = lister__key_stroke__choice_list;
lister->handlers = handlers;
lister->handlers.refresh = 0;
lister_set_handlers(lister, &handlers);
Lister_Result l_result = run_lister(app, lister);
Lister_Choice *result = 0;

View File

@ -92,6 +92,19 @@ struct Lister{
Lister_Result out;
};
struct Lister_Prev_Current{
Lister *prev;
Lister *current;
};
struct Lister_Block{
Application_Links *app;
Lister_Prev_Current lister;
Lister_Block(Application_Links *app, Arena *arena);
~Lister_Block();
operator Lister *();
};
struct Lister_Prealloced_String{
String_Const_u8 string;
};

View File

@ -132,9 +132,9 @@ get_command_from_user(Application_Links *app, String_Const_u8 query, i32 *comman
}
Scratch_Block scratch(app, Scratch_Share);
Lister *lister = begin_lister(app, scratch);
Lister_Block lister(app, scratch);
lister_set_query(lister, query);
lister->handlers = lister_get_default_handlers();
lister_set_default_handlers(lister);
for (i32 i = 0; i < command_id_count; i += 1){
i32 j = i;
@ -206,9 +206,9 @@ get_color_table_from_user(Application_Links *app, String_Const_u8 query, Color_T
}
Scratch_Block scratch(app, Scratch_Share);
Lister *lister = begin_lister(app, scratch);
Lister_Block lister(app, scratch);
lister_set_query(lister, query);
lister->handlers = lister_get_default_handlers();
lister_set_default_handlers(lister);
lister_add_item(lister, string_u8_litexpr("4coder"), string_u8_litexpr(""),
(void*)&default_color_table, 0);
@ -240,7 +240,7 @@ 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);
Lister *lister = view_get_lister(app, view);
if (lister != 0){
User_Input in = get_current_input(app);
String_Const_u8 string = to_writable(&in);
@ -265,7 +265,7 @@ lister__write_character__file_path(Application_Links *app){
function void
lister__backspace_text_field__file_path(Application_Links *app){
View_ID view = get_this_ctx_view(app, Access_Always);
Lister *lister = view_get_lister(view);
Lister *lister = view_get_lister(app, view);
if (lister != 0){
if (lister->text_field.size > 0){
char last_char = lister->text_field.str[lister->text_field.size - 1];

View File

@ -1261,9 +1261,9 @@ get_project_command_from_user(Application_Links *app, Project *project,
Project_Command_Lister_Result result = {};
if (project != 0){
Scratch_Block scratch(app);
Lister *lister = begin_lister(app, scratch);
Lister_Block lister(app, scratch);
lister_set_query(lister, query);
lister->handlers = lister_get_default_handlers();
lister_set_default_handlers(lister);
Project_Command *proj_cmd = project->command_array.commands;
i32 count = project->command_array.count;

View File

@ -638,6 +638,7 @@ typedef i32 Hook_ID;
enum{
HookID_Tick,
HookID_RenderCaller,
HookID_WholeScreenRenderCaller,
HookID_DeltaRule,
HookID_BufferViewerUpdate,
HookID_ViewEventHandler,
@ -695,6 +696,9 @@ typedef void Tick_Function(Application_Links *app, Frame_Info frame_info);
api(custom)
typedef void Render_Caller_Function(Application_Links *app, Frame_Info frame_info, View_ID view);
api(custom)
typedef void Whole_Screen_Render_Caller_Function(Application_Links *app, Frame_Info frame_info);
api(custom)
typedef u32 Layout_Item_Flag;
enum{

0
custom/bin/build_metadata.sh Normal file → Executable file
View File

42
custom/bin/build_one_time.sh Executable file
View File

@ -0,0 +1,42 @@
#!/bin/bash
# If any command errors, stop the script
set -e
# Set up directories
ORIGINAL=$PWD
ME="$(readlink -f "$0")"
LOCATION="$(dirname "$ME")"
cd $LOCATION
cd ..
CUSTOM_ROOT=$PWD
cd $ORIGINAL
target=$1
if [ -z "$target" ]
then
echo error: no input file
exit 1
fi
full_target=$target
if [[ ${target:0:1} != "/" ]];
then
full_target="$PWD/$target"
fi
dst=$2
if [[ $dst == "" ]];
then
dst=.
fi
debug=-g
opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-missing-declarations -Wno-logical-op-parentheses -g -DOS_LINUX=1 -DOS_WINDOWS=0 -DOS_MAC=0"
pushd $dst
g++ -I"$CUSTOM_ROOT" $opts $full_target -o one_time
popd

9
custom/bin/buildsuper_x64-linux.sh Normal file → Executable file
View File

@ -13,14 +13,17 @@ SOURCE="$1"
if [ -z "$SOURCE" ]; then
SOURCE="$(readlink -f "$CODE_HOME/4coder_default_bindings.cpp")"
fi
echo SOURCE = $SOURCE
opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-writable-strings -g -DOS_LINUX=1 -DOS_WINDOWS=0 -DOS_MAC=1"
opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-missing-declarations -Wno-logical-op-parentheses -g -DOS_LINUX=1 -DOS_WINDOWS=0 -DOS_MAC=0"
arch=-m64
debug=-g
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"
g++ -I"$CODE_HOME" $meta_macros $arch $opts $debug -std=c++11 "$SOURCE" -E -o $preproc_file
g++ -I"$CODE_HOME" $opts $debug -std=c++11 "$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

View File

@ -18,10 +18,12 @@ fi
opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-missing-declarations -Wno-logical-op-parentheses -g -DOS_MAC=1 -DOS_WINDOWS=0 -DOS_LINUX=0"
arch=-m64
debug=-g
preproc_file=4coder_command_metadata.i
meta_macros="-DMETA_PASS"
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"
clang++ -I"$CODE_HOME" $meta_macros $arch $opts $debug -std=c++11 "$SOURCE" -E -o $preproc_file
clang++ -I"$CODE_HOME" $opts $debug -std=c++11 "$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=c++11 "$SOURCE" -shared -o custom_4coder.so -fPIC

51
custom/bin/buildsuper_x86-linux.sh Normal file → Executable file
View File

@ -1,52 +1,33 @@
#!/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="$(readlink -f "$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
opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-writable-strings -g -DOS_LINUX=1 -DOS_WINDOWS=0 -DOS_MAC=1"
opts="-Wno-write-strings -Wno-null-dereference -Wno-comment -Wno-switch -Wno-missing-declarations -Wno-logical-op-parentheses -g -DOS_LINUX=1 -DOS_WINDOWS=0 -DOS_MAC=0"
arch=-m32
cd "$REAL_PWD"
debug=-g
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" $meta_macros $arch $opts $debug -std=c++11 "$SOURCE" -E -o $preproc_file
g++ -I"$CODE_HOME" $opts $debug -std=c++11 "$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
g++ -I"$CODE_HOME" $arch $opts $debug -std=gnu++0x "$SOURCE" -shared -o custom_4coder.so -fPIC
rm metadata_generator
rm "$CODE_HOME/metadata_generator"
rm $preproc_file

0
custom/bin/detect_os.sh Normal file → Executable file
View File

View File

@ -1,212 +1,318 @@
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_F17 = 88,
KeyCode_F18 = 89,
KeyCode_F19 = 90,
KeyCode_F20 = 91,
KeyCode_F21 = 92,
KeyCode_F22 = 93,
KeyCode_F23 = 94,
KeyCode_F24 = 95,
KeyCode_NumPad0 = 96,
KeyCode_NumPad1 = 97,
KeyCode_NumPad2 = 98,
KeyCode_NumPad3 = 99,
KeyCode_NumPad4 = 100,
KeyCode_NumPad5 = 101,
KeyCode_NumPad6 = 102,
KeyCode_NumPad7 = 103,
KeyCode_NumPad8 = 104,
KeyCode_NumPad9 = 105,
KeyCode_NumPadStar = 106,
KeyCode_NumPadPlus = 107,
KeyCode_NumPadMinus = 108,
KeyCode_NumPadDot = 109,
KeyCode_NumPadSlash = 110,
KeyCode_Ex0 = 111,
KeyCode_Ex1 = 112,
KeyCode_Ex2 = 113,
KeyCode_Ex3 = 114,
KeyCode_Ex4 = 115,
KeyCode_Ex5 = 116,
KeyCode_Ex6 = 117,
KeyCode_Ex7 = 118,
KeyCode_Ex8 = 119,
KeyCode_Ex9 = 120,
KeyCode_Ex10 = 121,
KeyCode_Ex11 = 122,
KeyCode_Ex12 = 123,
KeyCode_Ex13 = 124,
KeyCode_Ex14 = 125,
KeyCode_Ex15 = 126,
KeyCode_Ex16 = 127,
KeyCode_Ex17 = 128,
KeyCode_Ex18 = 129,
KeyCode_Ex19 = 130,
KeyCode_Ex20 = 131,
KeyCode_Ex21 = 132,
KeyCode_Ex22 = 133,
KeyCode_Ex23 = 134,
KeyCode_Ex24 = 135,
KeyCode_Ex25 = 136,
KeyCode_Ex26 = 137,
KeyCode_Ex27 = 138,
KeyCode_Ex28 = 139,
KeyCode_Ex29 = 140,
KeyCode_COUNT = 141,
};
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",
"F17",
"F18",
"F19",
"F20",
"F21",
"F22",
"F23",
"F24",
"NumPad0",
"NumPad1",
"NumPad2",
"NumPad3",
"NumPad4",
"NumPad5",
"NumPad6",
"NumPad7",
"NumPad8",
"NumPad9",
"NumPadStar",
"NumPadPlus",
"NumPadMinus",
"NumPadDot",
"NumPadSlash",
"Ex0",
"Ex1",
"Ex2",
"Ex3",
"Ex4",
"Ex5",
"Ex6",
"Ex7",
"Ex8",
"Ex9",
"Ex10",
"Ex11",
"Ex12",
"Ex13",
"Ex14",
"Ex15",
"Ex16",
"Ex17",
"Ex18",
"Ex19",
"Ex20",
"Ex21",
"Ex22",
"Ex23",
"Ex24",
"Ex25",
"Ex26",
"Ex27",
"Ex28",
"Ex29",
};
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",
};

View File

@ -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 238
#define command_one_past_last_id 242
#if defined(CUSTOM_COMMAND_SIG)
#define PROC_LINKS(x,y) x
#else
@ -53,6 +53,9 @@ CUSTOM_COMMAND_SIG(delete_current_scope);
CUSTOM_COMMAND_SIG(delete_file_query);
CUSTOM_COMMAND_SIG(delete_line);
CUSTOM_COMMAND_SIG(delete_range);
CUSTOM_COMMAND_SIG(display_key_codes);
CUSTOM_COMMAND_SIG(display_text_input);
CUSTOM_COMMAND_SIG(double_backspace);
CUSTOM_COMMAND_SIG(duplicate_line);
CUSTOM_COMMAND_SIG(execute_any_cli);
CUSTOM_COMMAND_SIG(execute_previous_cli);
@ -158,6 +161,7 @@ CUSTOM_COMMAND_SIG(paste_and_indent);
CUSTOM_COMMAND_SIG(paste_next);
CUSTOM_COMMAND_SIG(paste_next_and_indent);
CUSTOM_COMMAND_SIG(place_in_scope);
CUSTOM_COMMAND_SIG(play_with_a_counter);
CUSTOM_COMMAND_SIG(profile_clear);
CUSTOM_COMMAND_SIG(profile_disable);
CUSTOM_COMMAND_SIG(profile_enable);
@ -212,9 +216,9 @@ CUSTOM_COMMAND_SIG(show_the_log_graph);
CUSTOM_COMMAND_SIG(snipe_backward_whitespace_or_token_boundary);
CUSTOM_COMMAND_SIG(snipe_forward_whitespace_or_token_boundary);
CUSTOM_COMMAND_SIG(snippet_lister);
CUSTOM_COMMAND_SIG(string_repeat);
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);
@ -259,73 +263,76 @@ char *source_name;
i32 source_name_len;
i32 line_number;
};
static Command_Metadata fcoder_metacmd_table[238] = {
static Command_Metadata fcoder_metacmd_table[242] = {
{ 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, 413 },
{ 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, 423 },
{ 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, 404 },
{ 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_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, 658 },
{ 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, 647 },
{ PROC_LINKS(begin_clipboard_collection_mode, 0), true, "begin_clipboard_collection_mode", 31, "Allows the user to copy multiple strings from other applications before switching to 4coder and pasting them all.", 113, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 68 },
{ 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(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, 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, 647 },
{ 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, 636 },
{ 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(clear_clipboard, 0), false, "clear_clipboard", 15, "Clears the history of the clipboard", 35, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 216 },
{ 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(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(clipboard_record_clip, 0), false, "clipboard_record_clip", 21, "In response to a new clipboard contents events, saves the new clip onto the clipboard history", 93, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 7 },
{ 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, 843 },
{ 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, 666 },
{ 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, 655 },
{ 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, 107 },
{ 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(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, 116 },
{ 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, 749 },
{ 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, 1891 },
{ 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, 738 },
{ 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, 1897 },
{ 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_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, 1317 },
{ 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, 1489 },
{ 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, 1475 },
{ 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, 1323 },
{ 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, 1495 },
{ 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(display_key_codes, 0), false, "display_key_codes", 17, "Example of input handling loop", 30, "W:\\4ed\\code\\custom\\4coder_examples.cpp", 38, 90 },
{ PROC_LINKS(display_text_input, 0), false, "display_text_input", 18, "Example of to_writable and leave_current_input_unhandled", 56, "W:\\4ed\\code\\custom\\4coder_examples.cpp", 38, 134 },
{ PROC_LINKS(double_backspace, 0), false, "double_backspace", 16, "Example of history group helpers", 32, "W:\\4ed\\code\\custom\\4coder_examples.cpp", 38, 10 },
{ 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, 1481 },
{ 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, 836 },
{ 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, 2201 },
{ 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, 2209 },
{ PROC_LINKS(exit_4coder, 0), false, "exit_4coder", 11, "Attempts to close 4coder.", 25, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 825 },
{ 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, 2224 },
{ 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, 2232 },
{ 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, 844 },
{ 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, 833 },
{ 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, 696 },
{ 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, 682 },
{ 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, 685 },
{ 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, 671 },
{ 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, 738 },
{ 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, 727 },
{ 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 },
@ -335,9 +342,9 @@ static Command_Metadata fcoder_metacmd_table[238] = {
{ 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, 1635 },
{ PROC_LINKS(kill_buffer, 0), false, "kill_buffer", 11, "Kills the current buffer.", 25, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1641 },
{ 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(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), true, "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 },
@ -356,59 +363,60 @@ static Command_Metadata fcoder_metacmd_table[238] = {
{ 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, 1627 },
{ 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, 1429 },
{ 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, 1435 },
{ 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, 791 },
{ 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, 1469 },
{ 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, 1463 },
{ 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(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, 780 },
{ 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, 1475 },
{ 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, 1469 },
{ 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(multi_paste_interactive, 0), false, "multi_paste_interactive", 23, "Paste multiple lines from the clipboard history, controlled with arrow keys", 75, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 364 },
{ PROC_LINKS(multi_paste_interactive_quick, 0), false, "multi_paste_interactive_quick", 29, "Paste multiple lines from the clipboard history, controlled by inputing the number of lines to paste", 100, "W:\\4ed\\code\\custom\\4coder_clipboard.cpp", 39, 373 },
{ 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, 849 },
{ 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, 855 },
{ 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, 1554 },
{ 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, 1885 },
{ 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, 1560 },
{ 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, 1891 },
{ 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, 1586 },
{ 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, 1592 },
{ 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(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, 127 },
{ 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, 202 },
{ 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, 161 },
{ 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, 209 },
{ 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(play_with_a_counter, 0), false, "play_with_a_counter", 19, "Example of query bar", 20, "W:\\4ed\\code\\custom\\4coder_examples.cpp", 38, 29 },
{ 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 },
@ -416,28 +424,28 @@ static Command_Metadata fcoder_metacmd_table[238] = {
{ 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, 1290 },
{ 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, 871 },
{ 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, 897 },
{ 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, 1245 },
{ 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, 1266 },
{ 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, 1282 },
{ 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, 1724 },
{ 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, 1809 },
{ 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, 1394 },
{ 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, 1653 },
{ 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, 1155 },
{ 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, 1146 },
{ 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, 1137 },
{ 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, 1078 },
{ 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, 1090 },
{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1643 },
{ 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, 1251 },
{ 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, 1272 },
{ 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, 1288 },
{ 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, 1730 },
{ 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, 1815 },
{ 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, 1400 },
{ 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, 1659 },
{ 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, 1161 },
{ 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, 1152 },
{ 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, 1143 },
{ 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, 1084 },
{ 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, 1096 },
{ PROC_LINKS(save, 0), false, "save", 4, "Saves the current buffer.", 25, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 1649 },
{ 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, 1361 },
{ 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, 1072 },
{ 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, 1084 },
{ 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, 2189 },
{ 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, 2177 },
{ 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, 2195 },
{ 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, 2183 },
{ 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(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, 1367 },
{ 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, 1078 },
{ 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, 1090 },
{ 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, 2212 },
{ 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, 2200 },
{ 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, 2218 },
{ 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, 2206 },
{ 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 },
@ -448,44 +456,44 @@ static Command_Metadata fcoder_metacmd_table[238] = {
{ 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_face_size, 0), false, "set_face_size", 13, "Set face size of the face used by the current buffer.", 53, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 718 },
{ PROC_LINKS(set_face_size_this_buffer, 0), false, "set_face_size_this_buffer", 25, "Set face size of the face used by the current buffer; if any other buffers are using the same face a new face is created so that only this buffer is effected", 157, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 760 },
{ 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_face_size, 0), false, "set_face_size", 13, "Set face size of the face used by the current buffer.", 53, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 707 },
{ PROC_LINKS(set_face_size_this_buffer, 0), false, "set_face_size_this_buffer", 25, "Set face size of the face used by the current buffer; if any other buffers are using the same face a new face is created so that only this buffer is effected", 157, "W:\\4ed\\code\\custom\\4coder_base_commands.cpp", 43, 749 },
{ 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, 1238 },
{ 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, 1250 },
{ 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, 1244 },
{ 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, 1231 },
{ 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, 689 },
{ 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, 675 },
{ 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, 678 },
{ 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, 664 },
{ 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(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(string_repeat, 0), false, "string_repeat", 13, "Example of query_user_string and query_user_number", 50, "W:\\4ed\\code\\custom\\4coder_examples.cpp", 38, 176 },
{ 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, 1611 },
{ 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(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, 1617 },
{ 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, 703 },
{ 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, 712 },
{ 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, 692 },
{ 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, 701 },
{ 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, 817 },
{ 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, 823 },
{ 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, 806 },
{ 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, 812 },
{ 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, 808 },
{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles virtual whitespace for all files.", 41, "W:\\4ed\\code\\custom\\4coder_code_index.cpp", 40, 1175 },
{ 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, 797 },
{ PROC_LINKS(toggle_virtual_whitespace, 0), false, "toggle_virtual_whitespace", 25, "Toggles virtual whitespace for all files.", 41, "W:\\4ed\\code\\custom\\4coder_code_index.cpp", 40, 1176 },
{ 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, 1711 },
{ 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, 1738 },
{ 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, 1599 },
{ 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, 1717 },
{ 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, 1744 },
{ 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, 1605 },
{ 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 },
@ -543,198 +551,202 @@ static i32 fcoder_metacmd_ID_delete_current_scope = 40;
static i32 fcoder_metacmd_ID_delete_file_query = 41;
static i32 fcoder_metacmd_ID_delete_line = 42;
static i32 fcoder_metacmd_ID_delete_range = 43;
static i32 fcoder_metacmd_ID_duplicate_line = 44;
static i32 fcoder_metacmd_ID_execute_any_cli = 45;
static i32 fcoder_metacmd_ID_execute_previous_cli = 46;
static i32 fcoder_metacmd_ID_exit_4coder = 47;
static i32 fcoder_metacmd_ID_goto_beginning_of_file = 48;
static i32 fcoder_metacmd_ID_goto_end_of_file = 49;
static i32 fcoder_metacmd_ID_goto_first_jump = 50;
static i32 fcoder_metacmd_ID_goto_first_jump_same_panel_sticky = 51;
static i32 fcoder_metacmd_ID_goto_jump_at_cursor = 52;
static i32 fcoder_metacmd_ID_goto_jump_at_cursor_same_panel = 53;
static i32 fcoder_metacmd_ID_goto_line = 54;
static i32 fcoder_metacmd_ID_goto_next_jump = 55;
static i32 fcoder_metacmd_ID_goto_next_jump_no_skips = 56;
static i32 fcoder_metacmd_ID_goto_prev_jump = 57;
static i32 fcoder_metacmd_ID_goto_prev_jump_no_skips = 58;
static i32 fcoder_metacmd_ID_hide_filebar = 59;
static i32 fcoder_metacmd_ID_hide_scrollbar = 60;
static i32 fcoder_metacmd_ID_hms_demo_tutorial = 61;
static i32 fcoder_metacmd_ID_if0_off = 62;
static i32 fcoder_metacmd_ID_if_read_only_goto_position = 63;
static i32 fcoder_metacmd_ID_if_read_only_goto_position_same_panel = 64;
static i32 fcoder_metacmd_ID_increase_face_size = 65;
static i32 fcoder_metacmd_ID_interactive_kill_buffer = 66;
static i32 fcoder_metacmd_ID_interactive_new = 67;
static i32 fcoder_metacmd_ID_interactive_open = 68;
static i32 fcoder_metacmd_ID_interactive_open_or_new = 69;
static i32 fcoder_metacmd_ID_interactive_switch_buffer = 70;
static i32 fcoder_metacmd_ID_jump_to_definition = 71;
static i32 fcoder_metacmd_ID_keyboard_macro_finish_recording = 72;
static i32 fcoder_metacmd_ID_keyboard_macro_replay = 73;
static i32 fcoder_metacmd_ID_keyboard_macro_start_recording = 74;
static i32 fcoder_metacmd_ID_kill_buffer = 75;
static i32 fcoder_metacmd_ID_kill_tutorial = 76;
static i32 fcoder_metacmd_ID_left_adjust_view = 77;
static i32 fcoder_metacmd_ID_list_all_functions_all_buffers = 78;
static i32 fcoder_metacmd_ID_list_all_functions_all_buffers_lister = 79;
static i32 fcoder_metacmd_ID_list_all_functions_current_buffer = 80;
static i32 fcoder_metacmd_ID_list_all_functions_current_buffer_lister = 81;
static i32 fcoder_metacmd_ID_list_all_locations = 82;
static i32 fcoder_metacmd_ID_list_all_locations_case_insensitive = 83;
static i32 fcoder_metacmd_ID_list_all_locations_of_identifier = 84;
static i32 fcoder_metacmd_ID_list_all_locations_of_identifier_case_insensitive = 85;
static i32 fcoder_metacmd_ID_list_all_locations_of_selection = 86;
static i32 fcoder_metacmd_ID_list_all_locations_of_selection_case_insensitive = 87;
static i32 fcoder_metacmd_ID_list_all_locations_of_type_definition = 88;
static i32 fcoder_metacmd_ID_list_all_locations_of_type_definition_of_identifier = 89;
static i32 fcoder_metacmd_ID_list_all_substring_locations = 90;
static i32 fcoder_metacmd_ID_list_all_substring_locations_case_insensitive = 91;
static i32 fcoder_metacmd_ID_load_project = 92;
static i32 fcoder_metacmd_ID_load_theme_current_buffer = 93;
static i32 fcoder_metacmd_ID_load_themes_default_folder = 94;
static i32 fcoder_metacmd_ID_load_themes_hot_directory = 95;
static i32 fcoder_metacmd_ID_make_directory_query = 96;
static i32 fcoder_metacmd_ID_miblo_decrement_basic = 97;
static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp = 98;
static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp_minute = 99;
static i32 fcoder_metacmd_ID_miblo_increment_basic = 100;
static i32 fcoder_metacmd_ID_miblo_increment_time_stamp = 101;
static i32 fcoder_metacmd_ID_miblo_increment_time_stamp_minute = 102;
static i32 fcoder_metacmd_ID_mouse_wheel_change_face_size = 103;
static i32 fcoder_metacmd_ID_mouse_wheel_scroll = 104;
static i32 fcoder_metacmd_ID_move_down = 105;
static i32 fcoder_metacmd_ID_move_down_10 = 106;
static i32 fcoder_metacmd_ID_move_down_textual = 107;
static i32 fcoder_metacmd_ID_move_down_to_blank_line = 108;
static i32 fcoder_metacmd_ID_move_down_to_blank_line_end = 109;
static i32 fcoder_metacmd_ID_move_down_to_blank_line_skip_whitespace = 110;
static i32 fcoder_metacmd_ID_move_left = 111;
static i32 fcoder_metacmd_ID_move_left_alpha_numeric_boundary = 112;
static i32 fcoder_metacmd_ID_move_left_alpha_numeric_or_camel_boundary = 113;
static i32 fcoder_metacmd_ID_move_left_token_boundary = 114;
static i32 fcoder_metacmd_ID_move_left_whitespace_boundary = 115;
static i32 fcoder_metacmd_ID_move_left_whitespace_or_token_boundary = 116;
static i32 fcoder_metacmd_ID_move_line_down = 117;
static i32 fcoder_metacmd_ID_move_line_up = 118;
static i32 fcoder_metacmd_ID_move_right = 119;
static i32 fcoder_metacmd_ID_move_right_alpha_numeric_boundary = 120;
static i32 fcoder_metacmd_ID_move_right_alpha_numeric_or_camel_boundary = 121;
static i32 fcoder_metacmd_ID_move_right_token_boundary = 122;
static i32 fcoder_metacmd_ID_move_right_whitespace_boundary = 123;
static i32 fcoder_metacmd_ID_move_right_whitespace_or_token_boundary = 124;
static i32 fcoder_metacmd_ID_move_up = 125;
static i32 fcoder_metacmd_ID_move_up_10 = 126;
static i32 fcoder_metacmd_ID_move_up_to_blank_line = 127;
static i32 fcoder_metacmd_ID_move_up_to_blank_line_end = 128;
static i32 fcoder_metacmd_ID_move_up_to_blank_line_skip_whitespace = 129;
static i32 fcoder_metacmd_ID_multi_paste_interactive = 130;
static i32 fcoder_metacmd_ID_multi_paste_interactive_quick = 131;
static i32 fcoder_metacmd_ID_open_all_code = 132;
static i32 fcoder_metacmd_ID_open_all_code_recursive = 133;
static i32 fcoder_metacmd_ID_open_file_in_quotes = 134;
static i32 fcoder_metacmd_ID_open_in_other = 135;
static i32 fcoder_metacmd_ID_open_long_braces = 136;
static i32 fcoder_metacmd_ID_open_long_braces_break = 137;
static i32 fcoder_metacmd_ID_open_long_braces_semicolon = 138;
static i32 fcoder_metacmd_ID_open_matching_file_cpp = 139;
static i32 fcoder_metacmd_ID_open_panel_hsplit = 140;
static i32 fcoder_metacmd_ID_open_panel_vsplit = 141;
static i32 fcoder_metacmd_ID_page_down = 142;
static i32 fcoder_metacmd_ID_page_up = 143;
static i32 fcoder_metacmd_ID_paste = 144;
static i32 fcoder_metacmd_ID_paste_and_indent = 145;
static i32 fcoder_metacmd_ID_paste_next = 146;
static i32 fcoder_metacmd_ID_paste_next_and_indent = 147;
static i32 fcoder_metacmd_ID_place_in_scope = 148;
static i32 fcoder_metacmd_ID_profile_clear = 149;
static i32 fcoder_metacmd_ID_profile_disable = 150;
static i32 fcoder_metacmd_ID_profile_enable = 151;
static i32 fcoder_metacmd_ID_profile_inspect = 152;
static i32 fcoder_metacmd_ID_project_command_lister = 153;
static i32 fcoder_metacmd_ID_project_fkey_command = 154;
static i32 fcoder_metacmd_ID_project_go_to_root_directory = 155;
static i32 fcoder_metacmd_ID_query_replace = 156;
static i32 fcoder_metacmd_ID_query_replace_identifier = 157;
static i32 fcoder_metacmd_ID_query_replace_selection = 158;
static i32 fcoder_metacmd_ID_redo = 159;
static i32 fcoder_metacmd_ID_redo_all_buffers = 160;
static i32 fcoder_metacmd_ID_rename_file_query = 161;
static i32 fcoder_metacmd_ID_reopen = 162;
static i32 fcoder_metacmd_ID_replace_in_all_buffers = 163;
static i32 fcoder_metacmd_ID_replace_in_buffer = 164;
static i32 fcoder_metacmd_ID_replace_in_range = 165;
static i32 fcoder_metacmd_ID_reverse_search = 166;
static i32 fcoder_metacmd_ID_reverse_search_identifier = 167;
static i32 fcoder_metacmd_ID_save = 168;
static i32 fcoder_metacmd_ID_save_all_dirty_buffers = 169;
static i32 fcoder_metacmd_ID_save_to_query = 170;
static i32 fcoder_metacmd_ID_search = 171;
static i32 fcoder_metacmd_ID_search_identifier = 172;
static i32 fcoder_metacmd_ID_seek_beginning_of_line = 173;
static i32 fcoder_metacmd_ID_seek_beginning_of_textual_line = 174;
static i32 fcoder_metacmd_ID_seek_end_of_line = 175;
static i32 fcoder_metacmd_ID_seek_end_of_textual_line = 176;
static i32 fcoder_metacmd_ID_select_all = 177;
static i32 fcoder_metacmd_ID_select_next_scope_absolute = 178;
static i32 fcoder_metacmd_ID_select_next_scope_after_current = 179;
static i32 fcoder_metacmd_ID_select_prev_scope_absolute = 180;
static i32 fcoder_metacmd_ID_select_prev_top_most_scope = 181;
static i32 fcoder_metacmd_ID_select_surrounding_scope = 182;
static i32 fcoder_metacmd_ID_select_surrounding_scope_maximal = 183;
static i32 fcoder_metacmd_ID_set_eol_mode_from_contents = 184;
static i32 fcoder_metacmd_ID_set_eol_mode_to_binary = 185;
static i32 fcoder_metacmd_ID_set_eol_mode_to_crlf = 186;
static i32 fcoder_metacmd_ID_set_eol_mode_to_lf = 187;
static i32 fcoder_metacmd_ID_set_face_size = 188;
static i32 fcoder_metacmd_ID_set_face_size_this_buffer = 189;
static i32 fcoder_metacmd_ID_set_mark = 190;
static i32 fcoder_metacmd_ID_set_mode_to_notepad_like = 191;
static i32 fcoder_metacmd_ID_set_mode_to_original = 192;
static i32 fcoder_metacmd_ID_setup_build_bat = 193;
static i32 fcoder_metacmd_ID_setup_build_bat_and_sh = 194;
static i32 fcoder_metacmd_ID_setup_build_sh = 195;
static i32 fcoder_metacmd_ID_setup_new_project = 196;
static i32 fcoder_metacmd_ID_show_filebar = 197;
static i32 fcoder_metacmd_ID_show_scrollbar = 198;
static i32 fcoder_metacmd_ID_show_the_log_graph = 199;
static i32 fcoder_metacmd_ID_snipe_backward_whitespace_or_token_boundary = 200;
static i32 fcoder_metacmd_ID_snipe_forward_whitespace_or_token_boundary = 201;
static i32 fcoder_metacmd_ID_snippet_lister = 202;
static i32 fcoder_metacmd_ID_suppress_mouse = 203;
static i32 fcoder_metacmd_ID_swap_panels = 204;
static i32 fcoder_metacmd_ID_test_double_backspace = 205;
static i32 fcoder_metacmd_ID_theme_lister = 206;
static i32 fcoder_metacmd_ID_to_lowercase = 207;
static i32 fcoder_metacmd_ID_to_uppercase = 208;
static i32 fcoder_metacmd_ID_toggle_filebar = 209;
static i32 fcoder_metacmd_ID_toggle_fps_meter = 210;
static i32 fcoder_metacmd_ID_toggle_fullscreen = 211;
static i32 fcoder_metacmd_ID_toggle_highlight_enclosing_scopes = 212;
static i32 fcoder_metacmd_ID_toggle_highlight_line_at_cursor = 213;
static i32 fcoder_metacmd_ID_toggle_line_numbers = 214;
static i32 fcoder_metacmd_ID_toggle_line_wrap = 215;
static i32 fcoder_metacmd_ID_toggle_mouse = 216;
static i32 fcoder_metacmd_ID_toggle_paren_matching_helper = 217;
static i32 fcoder_metacmd_ID_toggle_show_whitespace = 218;
static i32 fcoder_metacmd_ID_toggle_virtual_whitespace = 219;
static i32 fcoder_metacmd_ID_tutorial_maximize = 220;
static i32 fcoder_metacmd_ID_tutorial_minimize = 221;
static i32 fcoder_metacmd_ID_uncomment_line = 222;
static i32 fcoder_metacmd_ID_undo = 223;
static i32 fcoder_metacmd_ID_undo_all_buffers = 224;
static i32 fcoder_metacmd_ID_view_buffer_other_panel = 225;
static i32 fcoder_metacmd_ID_view_jump_list_with_lister = 226;
static i32 fcoder_metacmd_ID_word_complete = 227;
static i32 fcoder_metacmd_ID_word_complete_drop_down = 228;
static i32 fcoder_metacmd_ID_write_block = 229;
static i32 fcoder_metacmd_ID_write_hack = 230;
static i32 fcoder_metacmd_ID_write_note = 231;
static i32 fcoder_metacmd_ID_write_space = 232;
static i32 fcoder_metacmd_ID_write_text_and_auto_indent = 233;
static i32 fcoder_metacmd_ID_write_text_input = 234;
static i32 fcoder_metacmd_ID_write_todo = 235;
static i32 fcoder_metacmd_ID_write_underscore = 236;
static i32 fcoder_metacmd_ID_write_zero_struct = 237;
static i32 fcoder_metacmd_ID_display_key_codes = 44;
static i32 fcoder_metacmd_ID_display_text_input = 45;
static i32 fcoder_metacmd_ID_double_backspace = 46;
static i32 fcoder_metacmd_ID_duplicate_line = 47;
static i32 fcoder_metacmd_ID_execute_any_cli = 48;
static i32 fcoder_metacmd_ID_execute_previous_cli = 49;
static i32 fcoder_metacmd_ID_exit_4coder = 50;
static i32 fcoder_metacmd_ID_goto_beginning_of_file = 51;
static i32 fcoder_metacmd_ID_goto_end_of_file = 52;
static i32 fcoder_metacmd_ID_goto_first_jump = 53;
static i32 fcoder_metacmd_ID_goto_first_jump_same_panel_sticky = 54;
static i32 fcoder_metacmd_ID_goto_jump_at_cursor = 55;
static i32 fcoder_metacmd_ID_goto_jump_at_cursor_same_panel = 56;
static i32 fcoder_metacmd_ID_goto_line = 57;
static i32 fcoder_metacmd_ID_goto_next_jump = 58;
static i32 fcoder_metacmd_ID_goto_next_jump_no_skips = 59;
static i32 fcoder_metacmd_ID_goto_prev_jump = 60;
static i32 fcoder_metacmd_ID_goto_prev_jump_no_skips = 61;
static i32 fcoder_metacmd_ID_hide_filebar = 62;
static i32 fcoder_metacmd_ID_hide_scrollbar = 63;
static i32 fcoder_metacmd_ID_hms_demo_tutorial = 64;
static i32 fcoder_metacmd_ID_if0_off = 65;
static i32 fcoder_metacmd_ID_if_read_only_goto_position = 66;
static i32 fcoder_metacmd_ID_if_read_only_goto_position_same_panel = 67;
static i32 fcoder_metacmd_ID_increase_face_size = 68;
static i32 fcoder_metacmd_ID_interactive_kill_buffer = 69;
static i32 fcoder_metacmd_ID_interactive_new = 70;
static i32 fcoder_metacmd_ID_interactive_open = 71;
static i32 fcoder_metacmd_ID_interactive_open_or_new = 72;
static i32 fcoder_metacmd_ID_interactive_switch_buffer = 73;
static i32 fcoder_metacmd_ID_jump_to_definition = 74;
static i32 fcoder_metacmd_ID_keyboard_macro_finish_recording = 75;
static i32 fcoder_metacmd_ID_keyboard_macro_replay = 76;
static i32 fcoder_metacmd_ID_keyboard_macro_start_recording = 77;
static i32 fcoder_metacmd_ID_kill_buffer = 78;
static i32 fcoder_metacmd_ID_kill_tutorial = 79;
static i32 fcoder_metacmd_ID_left_adjust_view = 80;
static i32 fcoder_metacmd_ID_list_all_functions_all_buffers = 81;
static i32 fcoder_metacmd_ID_list_all_functions_all_buffers_lister = 82;
static i32 fcoder_metacmd_ID_list_all_functions_current_buffer = 83;
static i32 fcoder_metacmd_ID_list_all_functions_current_buffer_lister = 84;
static i32 fcoder_metacmd_ID_list_all_locations = 85;
static i32 fcoder_metacmd_ID_list_all_locations_case_insensitive = 86;
static i32 fcoder_metacmd_ID_list_all_locations_of_identifier = 87;
static i32 fcoder_metacmd_ID_list_all_locations_of_identifier_case_insensitive = 88;
static i32 fcoder_metacmd_ID_list_all_locations_of_selection = 89;
static i32 fcoder_metacmd_ID_list_all_locations_of_selection_case_insensitive = 90;
static i32 fcoder_metacmd_ID_list_all_locations_of_type_definition = 91;
static i32 fcoder_metacmd_ID_list_all_locations_of_type_definition_of_identifier = 92;
static i32 fcoder_metacmd_ID_list_all_substring_locations = 93;
static i32 fcoder_metacmd_ID_list_all_substring_locations_case_insensitive = 94;
static i32 fcoder_metacmd_ID_load_project = 95;
static i32 fcoder_metacmd_ID_load_theme_current_buffer = 96;
static i32 fcoder_metacmd_ID_load_themes_default_folder = 97;
static i32 fcoder_metacmd_ID_load_themes_hot_directory = 98;
static i32 fcoder_metacmd_ID_make_directory_query = 99;
static i32 fcoder_metacmd_ID_miblo_decrement_basic = 100;
static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp = 101;
static i32 fcoder_metacmd_ID_miblo_decrement_time_stamp_minute = 102;
static i32 fcoder_metacmd_ID_miblo_increment_basic = 103;
static i32 fcoder_metacmd_ID_miblo_increment_time_stamp = 104;
static i32 fcoder_metacmd_ID_miblo_increment_time_stamp_minute = 105;
static i32 fcoder_metacmd_ID_mouse_wheel_change_face_size = 106;
static i32 fcoder_metacmd_ID_mouse_wheel_scroll = 107;
static i32 fcoder_metacmd_ID_move_down = 108;
static i32 fcoder_metacmd_ID_move_down_10 = 109;
static i32 fcoder_metacmd_ID_move_down_textual = 110;
static i32 fcoder_metacmd_ID_move_down_to_blank_line = 111;
static i32 fcoder_metacmd_ID_move_down_to_blank_line_end = 112;
static i32 fcoder_metacmd_ID_move_down_to_blank_line_skip_whitespace = 113;
static i32 fcoder_metacmd_ID_move_left = 114;
static i32 fcoder_metacmd_ID_move_left_alpha_numeric_boundary = 115;
static i32 fcoder_metacmd_ID_move_left_alpha_numeric_or_camel_boundary = 116;
static i32 fcoder_metacmd_ID_move_left_token_boundary = 117;
static i32 fcoder_metacmd_ID_move_left_whitespace_boundary = 118;
static i32 fcoder_metacmd_ID_move_left_whitespace_or_token_boundary = 119;
static i32 fcoder_metacmd_ID_move_line_down = 120;
static i32 fcoder_metacmd_ID_move_line_up = 121;
static i32 fcoder_metacmd_ID_move_right = 122;
static i32 fcoder_metacmd_ID_move_right_alpha_numeric_boundary = 123;
static i32 fcoder_metacmd_ID_move_right_alpha_numeric_or_camel_boundary = 124;
static i32 fcoder_metacmd_ID_move_right_token_boundary = 125;
static i32 fcoder_metacmd_ID_move_right_whitespace_boundary = 126;
static i32 fcoder_metacmd_ID_move_right_whitespace_or_token_boundary = 127;
static i32 fcoder_metacmd_ID_move_up = 128;
static i32 fcoder_metacmd_ID_move_up_10 = 129;
static i32 fcoder_metacmd_ID_move_up_to_blank_line = 130;
static i32 fcoder_metacmd_ID_move_up_to_blank_line_end = 131;
static i32 fcoder_metacmd_ID_move_up_to_blank_line_skip_whitespace = 132;
static i32 fcoder_metacmd_ID_multi_paste_interactive = 133;
static i32 fcoder_metacmd_ID_multi_paste_interactive_quick = 134;
static i32 fcoder_metacmd_ID_open_all_code = 135;
static i32 fcoder_metacmd_ID_open_all_code_recursive = 136;
static i32 fcoder_metacmd_ID_open_file_in_quotes = 137;
static i32 fcoder_metacmd_ID_open_in_other = 138;
static i32 fcoder_metacmd_ID_open_long_braces = 139;
static i32 fcoder_metacmd_ID_open_long_braces_break = 140;
static i32 fcoder_metacmd_ID_open_long_braces_semicolon = 141;
static i32 fcoder_metacmd_ID_open_matching_file_cpp = 142;
static i32 fcoder_metacmd_ID_open_panel_hsplit = 143;
static i32 fcoder_metacmd_ID_open_panel_vsplit = 144;
static i32 fcoder_metacmd_ID_page_down = 145;
static i32 fcoder_metacmd_ID_page_up = 146;
static i32 fcoder_metacmd_ID_paste = 147;
static i32 fcoder_metacmd_ID_paste_and_indent = 148;
static i32 fcoder_metacmd_ID_paste_next = 149;
static i32 fcoder_metacmd_ID_paste_next_and_indent = 150;
static i32 fcoder_metacmd_ID_place_in_scope = 151;
static i32 fcoder_metacmd_ID_play_with_a_counter = 152;
static i32 fcoder_metacmd_ID_profile_clear = 153;
static i32 fcoder_metacmd_ID_profile_disable = 154;
static i32 fcoder_metacmd_ID_profile_enable = 155;
static i32 fcoder_metacmd_ID_profile_inspect = 156;
static i32 fcoder_metacmd_ID_project_command_lister = 157;
static i32 fcoder_metacmd_ID_project_fkey_command = 158;
static i32 fcoder_metacmd_ID_project_go_to_root_directory = 159;
static i32 fcoder_metacmd_ID_query_replace = 160;
static i32 fcoder_metacmd_ID_query_replace_identifier = 161;
static i32 fcoder_metacmd_ID_query_replace_selection = 162;
static i32 fcoder_metacmd_ID_redo = 163;
static i32 fcoder_metacmd_ID_redo_all_buffers = 164;
static i32 fcoder_metacmd_ID_rename_file_query = 165;
static i32 fcoder_metacmd_ID_reopen = 166;
static i32 fcoder_metacmd_ID_replace_in_all_buffers = 167;
static i32 fcoder_metacmd_ID_replace_in_buffer = 168;
static i32 fcoder_metacmd_ID_replace_in_range = 169;
static i32 fcoder_metacmd_ID_reverse_search = 170;
static i32 fcoder_metacmd_ID_reverse_search_identifier = 171;
static i32 fcoder_metacmd_ID_save = 172;
static i32 fcoder_metacmd_ID_save_all_dirty_buffers = 173;
static i32 fcoder_metacmd_ID_save_to_query = 174;
static i32 fcoder_metacmd_ID_search = 175;
static i32 fcoder_metacmd_ID_search_identifier = 176;
static i32 fcoder_metacmd_ID_seek_beginning_of_line = 177;
static i32 fcoder_metacmd_ID_seek_beginning_of_textual_line = 178;
static i32 fcoder_metacmd_ID_seek_end_of_line = 179;
static i32 fcoder_metacmd_ID_seek_end_of_textual_line = 180;
static i32 fcoder_metacmd_ID_select_all = 181;
static i32 fcoder_metacmd_ID_select_next_scope_absolute = 182;
static i32 fcoder_metacmd_ID_select_next_scope_after_current = 183;
static i32 fcoder_metacmd_ID_select_prev_scope_absolute = 184;
static i32 fcoder_metacmd_ID_select_prev_top_most_scope = 185;
static i32 fcoder_metacmd_ID_select_surrounding_scope = 186;
static i32 fcoder_metacmd_ID_select_surrounding_scope_maximal = 187;
static i32 fcoder_metacmd_ID_set_eol_mode_from_contents = 188;
static i32 fcoder_metacmd_ID_set_eol_mode_to_binary = 189;
static i32 fcoder_metacmd_ID_set_eol_mode_to_crlf = 190;
static i32 fcoder_metacmd_ID_set_eol_mode_to_lf = 191;
static i32 fcoder_metacmd_ID_set_face_size = 192;
static i32 fcoder_metacmd_ID_set_face_size_this_buffer = 193;
static i32 fcoder_metacmd_ID_set_mark = 194;
static i32 fcoder_metacmd_ID_set_mode_to_notepad_like = 195;
static i32 fcoder_metacmd_ID_set_mode_to_original = 196;
static i32 fcoder_metacmd_ID_setup_build_bat = 197;
static i32 fcoder_metacmd_ID_setup_build_bat_and_sh = 198;
static i32 fcoder_metacmd_ID_setup_build_sh = 199;
static i32 fcoder_metacmd_ID_setup_new_project = 200;
static i32 fcoder_metacmd_ID_show_filebar = 201;
static i32 fcoder_metacmd_ID_show_scrollbar = 202;
static i32 fcoder_metacmd_ID_show_the_log_graph = 203;
static i32 fcoder_metacmd_ID_snipe_backward_whitespace_or_token_boundary = 204;
static i32 fcoder_metacmd_ID_snipe_forward_whitespace_or_token_boundary = 205;
static i32 fcoder_metacmd_ID_snippet_lister = 206;
static i32 fcoder_metacmd_ID_string_repeat = 207;
static i32 fcoder_metacmd_ID_suppress_mouse = 208;
static i32 fcoder_metacmd_ID_swap_panels = 209;
static i32 fcoder_metacmd_ID_theme_lister = 210;
static i32 fcoder_metacmd_ID_to_lowercase = 211;
static i32 fcoder_metacmd_ID_to_uppercase = 212;
static i32 fcoder_metacmd_ID_toggle_filebar = 213;
static i32 fcoder_metacmd_ID_toggle_fps_meter = 214;
static i32 fcoder_metacmd_ID_toggle_fullscreen = 215;
static i32 fcoder_metacmd_ID_toggle_highlight_enclosing_scopes = 216;
static i32 fcoder_metacmd_ID_toggle_highlight_line_at_cursor = 217;
static i32 fcoder_metacmd_ID_toggle_line_numbers = 218;
static i32 fcoder_metacmd_ID_toggle_line_wrap = 219;
static i32 fcoder_metacmd_ID_toggle_mouse = 220;
static i32 fcoder_metacmd_ID_toggle_paren_matching_helper = 221;
static i32 fcoder_metacmd_ID_toggle_show_whitespace = 222;
static i32 fcoder_metacmd_ID_toggle_virtual_whitespace = 223;
static i32 fcoder_metacmd_ID_tutorial_maximize = 224;
static i32 fcoder_metacmd_ID_tutorial_minimize = 225;
static i32 fcoder_metacmd_ID_uncomment_line = 226;
static i32 fcoder_metacmd_ID_undo = 227;
static i32 fcoder_metacmd_ID_undo_all_buffers = 228;
static i32 fcoder_metacmd_ID_view_buffer_other_panel = 229;
static i32 fcoder_metacmd_ID_view_jump_list_with_lister = 230;
static i32 fcoder_metacmd_ID_word_complete = 231;
static i32 fcoder_metacmd_ID_word_complete_drop_down = 232;
static i32 fcoder_metacmd_ID_write_block = 233;
static i32 fcoder_metacmd_ID_write_hack = 234;
static i32 fcoder_metacmd_ID_write_note = 235;
static i32 fcoder_metacmd_ID_write_space = 236;
static i32 fcoder_metacmd_ID_write_text_and_auto_indent = 237;
static i32 fcoder_metacmd_ID_write_text_input = 238;
static i32 fcoder_metacmd_ID_write_todo = 239;
static i32 fcoder_metacmd_ID_write_underscore = 240;
static i32 fcoder_metacmd_ID_write_zero_struct = 241;
#endif

View File

@ -48,6 +48,7 @@ view_highlight_range = managed_id_declare(app, string_u8_litexpr("attachment"),
view_highlight_buffer = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_highlight_buffer"));
view_render_hook = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_render_hook"));
view_word_complete_menu = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_word_complete_menu"));
view_lister_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_lister_loc"));
buffer_map_id = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("buffer_map_id"));
buffer_eol_setting = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("buffer_eol_setting"));
buffer_lex_task = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("buffer_lex_task"));

View File

@ -210,22 +210,20 @@ typedef char GLchar;
typedef short GLshort;
typedef signed char GLbyte;
typedef unsigned short GLushort;
#if !OS_LINUX
typedef ptrdiff_t GLsizeiptr;
typedef ptrdiff_t GLintptr;
#endif
typedef void GL_Debug_Function(GLenum src,
GLenum type,
GLuint id,
GLenum severity,
GLsizei length,
#ifdef OS_LINUX
const GLchar* message,
const void *user_data
#else
GLchar *message,
void *user_data
#endif
);
const void *user_data);
typedef GL_Debug_Function *GLDEBUGPROC;
#endif

View File

@ -13,19 +13,21 @@
#include "4ed_opengl_funcs.h"
*/
#if OS_WINDOWS || OS_LINUX
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))
#ifndef OS_LINUX
GL_FUNC(glGenVertexArrays, void, (GLsizei n, GLuint *arrays))
GL_FUNC(glBindVertexArray, void, (GLuint array))
GL_FUNC(glDeleteVertexArrays, void, (GLsizei n, const GLuint *arrays))
#if !OS_LINUX
GL_FUNC(glTexImage3D, void, (GLenum target, GLint level, GLint internalformat, GLsizei width, GLsizei height, GLsizei depth, GLint border, GLenum format, GLenum type, const void *pixels))
GL_FUNC(glTexSubImage3D, void, (GLenum target, GLint level, GLint xoffset, GLint yoffset, GLint zoffset, GLsizei width, GLsizei height, GLsizei depth, GLenum format, GLenum type, const void *pixels))
GL_FUNC(glActiveTexture, void, (GLenum texture))
#endif
GL_FUNC(glGenVertexArrays, void, (GLsizei n, GLuint *arrays))
GL_FUNC(glBindVertexArray, void, (GLuint array))
GL_FUNC(glDeleteVertexArrays, void, (GLsizei n, const GLuint *arrays))
GL_FUNC(glGenBuffers, void, (GLsizei n, GLuint *buffers))
GL_FUNC(glBindBuffer, void, (GLenum target, GLuint buffer))
GL_FUNC(glBufferData, void, (GLenum target, GLsizeiptr size, const void *data, GLenum usage))
@ -54,6 +56,7 @@ GL_FUNC(glDisableVertexAttribArray, void, (GLuint index))
GL_FUNC(glEnableVertexAttribArray, void, (GLuint index))
GL_FUNC(glVertexAttribPointer, void, (GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *pointer))
GL_FUNC(glVertexAttribIPointer, void, (GLuint index, GLint size, GLenum type, GLsizei stride, const void *pointer))
GL_FUNC(glUniform1f, void, (GLint location, GLfloat v0))
@ -87,6 +90,18 @@ GL_FUNC(glBlitFramebuffer, void, (GLint srcX0, GLint srcY0, GLint srcX1, GLint s
GL_FUNC(glTexImage2DMultisample, void, (GLenum target, GLsizei samples, GLenum internalformat, GLsizei width, GLsizei height, GLboolean fixedsamplelocations))
#elif OS_MAC
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))
#endif
#undef GL_FUNC
// BOTTOM

View File

@ -54,11 +54,7 @@ gl__fill_texture(Texture_Kind texture_kind, u32 texture, Vec3_i32 p, Vec3_i32 di
}
internal void
#ifdef OS_LINUX
gl__error_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const char *message, const void *userParam){
#else
gl__error_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, char *message, void *userParam){
#endif
switch (id){
case 131218:
{
@ -72,70 +68,70 @@ gl__error_callback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsiz
}
}
char *gl__header = R"foo(#version 150
)foo";
char *gl__header = R"foo(#version 130
)foo";
char *gl__vertex = R"foo(
uniform vec2 view_t;
uniform mat2x2 view_m;
in vec2 vertex_p;
in vec3 vertex_t;
in uint vertex_c;
in float vertex_ht;
smooth out vec4 fragment_color;
smooth out vec3 uvw;
smooth out vec2 xy;
smooth out vec2 adjusted_half_dim;
smooth out float half_thickness;
void main(void)
{
gl_Position = vec4(view_m*(vertex_p - view_t), 0.0, 1.0);
fragment_color.b = (float((vertex_c )&0xFFu))/255.0;
fragment_color.g = (float((vertex_c>> 8u)&0xFFu))/255.0;
fragment_color.r = (float((vertex_c>>16u)&0xFFu))/255.0;
fragment_color.a = (float((vertex_c>>24u)&0xFFu))/255.0;
uvw = vertex_t;
vec2 center = vertex_t.xy;
vec2 half_dim = abs(vertex_p - center);
adjusted_half_dim = half_dim - vertex_t.zz + vec2(0.5, 0.5);
half_thickness = vertex_ht;
xy = vertex_p;
}
)foo";
uniform vec2 view_t;
uniform mat2x2 view_m;
in vec2 vertex_p;
in vec3 vertex_t;
in uint vertex_c;
in float vertex_ht;
smooth out vec4 fragment_color;
smooth out vec3 uvw;
smooth out vec2 xy;
smooth out vec2 adjusted_half_dim;
smooth out float half_thickness;
void main(void)
{
gl_Position = vec4(view_m*(vertex_p - view_t), 0.0, 1.0);
fragment_color.b = (float((vertex_c )&0xFFu))/255.0;
fragment_color.g = (float((vertex_c>> 8u)&0xFFu))/255.0;
fragment_color.r = (float((vertex_c>>16u)&0xFFu))/255.0;
fragment_color.a = (float((vertex_c>>24u)&0xFFu))/255.0;
uvw = vertex_t;
vec2 center = vertex_t.xy;
vec2 half_dim = abs(vertex_p - center);
adjusted_half_dim = half_dim - vertex_t.zz + vec2(0.5, 0.5);
half_thickness = vertex_ht;
xy = vertex_p;
}
)foo";
char *gl__fragment = R"foo(
smooth in vec4 fragment_color;
smooth in vec3 uvw;
smooth in vec2 xy;
smooth in vec2 adjusted_half_dim;
smooth in float half_thickness;
uniform sampler2DArray sampler;
out vec4 out_color;
float rectangle_sd(vec2 p, vec2 b){
vec2 d = abs(p) - b;
return(length(max(d, vec2(0.0, 0.0))) + min(max(d.x, d.y), 0.0));
}
void main(void)
{
float has_thickness = (step(0.49, half_thickness));
float does_not_have_thickness = 1.0 - has_thickness;
float sample_value = texture(sampler, uvw).r;
sample_value *= does_not_have_thickness;
vec2 center = uvw.xy;
float roundness = uvw.z;
float sd = rectangle_sd(xy - center, adjusted_half_dim);
sd = sd - roundness;
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));
}
)foo";
smooth in vec4 fragment_color;
smooth in vec3 uvw;
smooth in vec2 xy;
smooth in vec2 adjusted_half_dim;
smooth in float half_thickness;
uniform sampler2DArray sampler;
out vec4 out_color;
float rectangle_sd(vec2 p, vec2 b){
vec2 d = abs(p) - b;
return(length(max(d, vec2(0.0, 0.0))) + min(max(d.x, d.y), 0.0));
}
void main(void)
{
float has_thickness = (step(0.49, half_thickness));
float does_not_have_thickness = 1.0 - has_thickness;
float sample_value = texture(sampler, uvw).r;
sample_value *= does_not_have_thickness;
vec2 center = uvw.xy;
float roundness = uvw.z;
float sd = rectangle_sd(xy - center, adjusted_half_dim);
sd = sd - roundness;
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));
}
)foo";
#define AttributeList(X) \
X(vertex_p) \
@ -154,7 +150,7 @@ struct GL_Program{
AttributeList(GetAttributeLocation)
#undef GetAttributeLocation
#define GetUniformLocation(N) i32 N;
UniformList(GetUniformLocation)
UniformList(GetUniformLocation)
#undef GetUniformLocation
};
@ -205,9 +201,9 @@ gl__make_program(char *header, char *vertex, char *fragment){
AttributeList(GetAttributeLocation)
#undef GetAttributeLocation
#define GetUniformLocation(N) result.N = glGetUniformLocation(program, #N);
UniformList(GetUniformLocation)
UniformList(GetUniformLocation)
#undef GetUniformLocation
return(result);
return(result);
}
#define GLOffsetStruct(p,m) ((void*)(OffsetOfMemberStruct(p,m)))
@ -294,9 +290,9 @@ gl_render(Render_Target *t){
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,
};
Rect_i32 scissor_box = {
box.x0, height - box.y1, box.x1 - box.x0, box.y1 - box.y0,
};
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);

File diff suppressed because it is too large Load Diff

View File

@ -11,7 +11,7 @@
internal String_Const_u8
system_get_path(Arena* arena, System_Path_Code path_code){
String_Const_u8 result = {};
switch (path_code){
case SystemPath_CurrentDirectory: {
// glibc extension: getcwd allocates its own memory if passed NULL
@ -19,70 +19,70 @@ system_get_path(Arena* arena, System_Path_Code path_code){
u64 working_dir_len = cstring_length(working_dir);
u8 *out = push_array(arena, u8, working_dir_len + 1);
block_copy(out, working_dir, working_dir_len);
// NOTE: 4ed appears to expect a slash on the end.
out[working_dir_len] = '/';
free(working_dir);
result = SCu8(out, working_dir_len + 1);
} break;
case SystemPath_Binary: {
// linux-specific: binary path symlinked at /proc/self/exe
// PATH_MAX is probably good enough...
// read the 'readlink' manpage for some comedy about it being 'broken by design'.
char* buf = push_array(arena, char, PATH_MAX);
ssize_t n = readlink("/proc/self/exe", buf, PATH_MAX);
if(n == -1) {
perror("readlink");
*buf = n = 0;
}
result = string_remove_last_folder(SCu8(buf, n));
} break;
}
return(result);
}
internal String_Const_u8
system_get_canonical(Arena* arena, String_Const_u8 name){
// first remove redundant ../, //, ./ parts
const u8* input = (u8*) strndupa((char*)name.str, name.size);
u8* output = push_array(arena, u8, name.size + 1);
const u8* p = input;
u8* q = output;
while(*p) {
// not a slash - copy char
if(p[0] != '/') {
*q++ = *p++;
continue;
}
// two slashes in a row, skip one.
if(p[1] == '/') {
++p;
}
else if(p[1] == '.') {
// skip "/./" or trailing "/."
if(p[2] == '/' || p[2] == '\0') {
p += 2;
}
// if we encounter "/../" or trailing "/..", remove last directory instead
else if(p[2] == '.' && (p[3] == '/' || p[3] == '\0')) {
while(q > output && *--q != '/'){};
p += 3;
}
else {
*q++ = *p++;
}
@ -91,13 +91,13 @@ system_get_canonical(Arena* arena, String_Const_u8 name){
*q++ = *p++;
}
}
#ifdef INSO_DEBUG
if(name.size != q - output) {
LINUX_FN_DEBUG("[%.*s] -> [%.*s]", (int)name.size, name.str, (int)(q - output), output);
}
#endif
// TODO: use realpath at this point to resolve symlinks?
return SCu8(output, q - output);
}
@ -106,66 +106,73 @@ internal File_List
system_get_file_list(Arena* arena, String_Const_u8 directory){
//LINUX_FN_DEBUG("%.*s", (int)directory.size, directory.str);
File_List result = {};
char* path = strndupa((char*)directory.str, directory.size);
int fd = open(path, O_RDONLY | O_DIRECTORY);
if(fd == -1) {
perror("open");
return result;
}
DIR* dir = fdopendir(fd);
struct dirent* d;
File_Info* head = NULL;
File_Info** fip = &head;
while((d = readdir(dir))) {
const char* name = d->d_name;
// ignore . and ..
if(*name == '.' && (name[1] == '\0' || (name[1] == '.' && name[2] == '\0'))) {
continue;
}
*fip = push_array(arena, File_Info, 1);
(*fip)->file_name = push_u8_stringf(arena, "%.*s", d->d_reclen, name);
struct stat st;
if(fstatat(fd, name, &st, 0) == -1){
if (fstatat(fd, name, &st, 0) == -1){
perror("fstatat");
}
(*fip)->attributes = linux_file_attributes_from_struct_stat(&st);
else{
(*fip)->attributes = linux_file_attributes_from_struct_stat(&st);
}
fip = &(*fip)->next;
result.count++;
}
closedir(dir);
if(result.count > 0) {
result.infos = fip = push_array(arena, File_Info*, result.count);
for(File_Info* f = head; f; f = f->next) {
*fip++ = f;
}
qsort(result.infos, result.count, sizeof(File_Info*), (__compar_fn_t)&linux_compare_file_infos);
for(u32 i = 0; i < result.count - 1; ++i) {
result.infos[i]->next = result.infos[i+1];
}
result.infos[result.count-1]->next = NULL;
}
return result;
}
internal File_Attributes
system_quick_file_attributes(Arena* scratch, String_Const_u8 file_name){
//LINUX_FN_DEBUG("%.*s", (int)file_name.size, file_name.str);
Temp_Memory_Block temp(scratch);
file_name = push_string_copy(scratch, file_name);
File_Attributes result = {};
struct stat file_stat;
stat((const char*)file_name.str, &file_stat);
return linux_file_attributes_from_struct_stat(&file_stat);
if (stat((const char*)file_name.str, &file_stat) == 0){
result = linux_file_attributes_from_struct_stat(&file_stat);
}
return(result);
}
internal b32
@ -182,9 +189,12 @@ system_load_handle(Arena* scratch, char* file_name, Plat_Handle* out){
internal File_Attributes
system_load_attributes(Plat_Handle handle){
LINUX_FN_DEBUG();
File_Attributes result = {};
struct stat file_stat;
fstat(*(int*)&handle, &file_stat);
return linux_file_attributes_from_struct_stat(&file_stat);
if (fstat(*(int*)&handle, &file_stat) == 0){
result = linux_file_attributes_from_struct_stat(&file_stat);
}
return(result);
}
internal b32
@ -209,23 +219,25 @@ internal File_Attributes
system_save_file(Arena* scratch, char* file_name, String_Const_u8 data){
LINUX_FN_DEBUG("%s", file_name);
File_Attributes result = {};
// TODO(inso): should probably put a \n on the end if it's a text file.
int fd = open(file_name, O_WRONLY, O_CREAT);
int fd = open(file_name, O_TRUNC|O_WRONLY|O_CREAT, 0666);
if (fd != -1) {
int bytes_written = write(fd, data.str, data.size);
if (bytes_written == -1) {
perror("write");
} else if(bytes_written == data.size) {
} else if (bytes_written == data.size) {
struct stat file_stat;
fstat(fd, &file_stat);
return linux_file_attributes_from_struct_stat(&file_stat);
if (fstat(fd, &file_stat) == 0){
result = linux_file_attributes_from_struct_stat(&file_stat);
}
}
close(fd);
} else {
perror("open");
}
return result;
}
@ -256,8 +268,8 @@ internal u64
system_now_time(void){
//LINUX_FN_DEBUG();
struct timespec time;
clock_gettime(CLOCK_MONOTONIC_RAW, &time);
return linux_ns_from_timespec(time);
clock_gettime(CLOCK_MONOTONIC, &time);
return linux_us_from_timespec(time);
}
internal Plat_Handle
@ -265,7 +277,7 @@ system_wake_up_timer_create(void){
LINUX_FN_DEBUG();
Linux_Object* object = linux_alloc_object(LinuxObjectKind_Timer);
dll_insert(&linuxvars.timer_objects, &object->node);
// NOTE(inso): timers created on-demand to avoid file-descriptor exhaustion.
object->timer.fd = -1;
}
@ -287,23 +299,23 @@ internal void
system_wake_up_timer_set(Plat_Handle handle, u32 time_milliseconds){
//LINUX_FN_DEBUG("%u", time_milliseconds);
Linux_Object* object = handle_to_object(handle);
if (object->kind == LinuxObjectKind_Timer){
if(object->timer.fd == -1) {
object->timer.fd = timerfd_create(CLOCK_MONOTONIC, TFD_NONBLOCK | TFD_CLOEXEC);
struct epoll_event ev;
ev.events = EPOLLIN | EPOLLET | EPOLLONESHOT;
ev.data.ptr = &object->timer.epoll_tag;
epoll_ctl(linuxvars.epoll, EPOLL_CTL_ADD, object->timer.fd, &ev);
}
struct itimerspec it = {};
it.it_value.tv_sec = time_milliseconds / 1000;
it.it_value.tv_nsec = (time_milliseconds % 1000) * UINT64_C(1000000);
timerfd_settime(object->timer.fd, 0, &it, NULL);
}
}
internal void
@ -323,33 +335,6 @@ system_sleep(u64 microseconds){
nanosleep(&requested, &remaining);
}
internal String_Const_u8
system_get_clipboard(Arena* arena, i32 index){
// TODO(inso): index?
u8* ptr = push_array_write(arena, u8, linuxvars.clipboard_contents.size, linuxvars.clipboard_contents.str);
return SCu8(ptr, linuxvars.clipboard_contents.size);
}
internal void
system_post_clipboard(String_Const_u8 str, i32 index){
// TODO(inso): index?
//LINUX_FN_DEBUG("%.*s", string_expand(str));
linalloc_clear(linuxvars.clipboard_arena);
linuxvars.clipboard_contents = push_u8_stringf(linuxvars.clipboard_arena, "%.*s", str.size, str.str);
XSetSelectionOwner(linuxvars.dpy, linuxvars.atom_CLIPBOARD, linuxvars.win, CurrentTime);
}
internal void
system_set_clipboard_catch_all(b32 enabled){
LINUX_FN_DEBUG("%d", enabled);
linuxvars.clipboard_catch_all = !!enabled;
}
internal b32
system_get_clipboard_catch_all(void){
return linuxvars.clipboard_catch_all;
}
internal b32
system_cli_call(Arena* scratch, char* path, char* script, CLI_Handles* cli_out){
LINUX_FN_DEBUG("%s / %s", path, script);
@ -358,28 +343,28 @@ system_cli_call(Arena* scratch, char* path, char* script, CLI_Handles* cli_out){
perror("system_cli_call: pipe");
return 0;
}
pid_t child_pid = vfork();
if (child_pid == -1){
perror("system_cli_call: fork");
return 0;
}
enum { PIPE_FD_READ, PIPE_FD_WRITE };
// child
if (child_pid == 0){
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, NULL };
if (execv("/bin/sh", argv) == -1){
perror("system_cli_call: execv");
}
@ -387,17 +372,17 @@ system_cli_call(Arena* scratch, char* path, char* script, CLI_Handles* cli_out){
}
else{
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];
struct epoll_event e = {};
e.events = EPOLLIN | EPOLLET;
e.data.ptr = &epoll_tag_cli_pipe;
epoll_ctl(linuxvars.epoll, EPOLL_CTL_ADD, pipe_fds[PIPE_FD_READ], &e);
}
return(true);
}
@ -411,16 +396,16 @@ internal b32
system_cli_update_step(CLI_Handles* cli, char* dest, u32 max, u32* amount){
LINUX_FN_DEBUG();
int pipe_read_fd = *(int*)&cli->out_read;
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){
@ -433,7 +418,7 @@ system_cli_update_step(CLI_Handles* cli, char* dest, u32 max, u32* amount){
space_left -= num;
}
}
*amount = (ptr - dest);
return((ptr - dest) > 0);
}
@ -443,16 +428,16 @@ system_cli_end_update(CLI_Handles* cli){
LINUX_FN_DEBUG();
pid_t pid = *(pid_t*)&cli->proc;
b32 close_me = false;
int status;
if (pid && waitpid(pid, &status, WNOHANG) > 0){
cli->exit = WEXITSTATUS(status);
close_me = true;
close(*(int*)&cli->out_read);
close(*(int*)&cli->out_write);
}
return(close_me);
}
@ -484,28 +469,28 @@ internal System_Thread
system_thread_launch(Thread_Function* proc, void* ptr){
LINUX_FN_DEBUG();
System_Thread result = {};
Linux_Object* thread_info = linux_alloc_object(LinuxObjectKind_Thread);
thread_info->thread.proc = proc;
thread_info->thread.ptr = ptr;
pthread_attr_t thread_attr;
pthread_attr_init(&thread_attr);
int create_result = pthread_create(
&thread_info->thread.pthread,
&thread_attr,
linux_thread_proc_start,
thread_info);
&thread_info->thread.pthread,
&thread_attr,
linux_thread_proc_start,
thread_info);
pthread_attr_destroy(&thread_attr);
// TODO(andrew): Need to wait for thread to confirm it launched?
if (create_result == 0) {
static_assert(sizeof(Linux_Object*) <= sizeof(System_Thread));
static_assert(sizeof(Linux_Object*) <= sizeof(System_Thread), "Linux_Object doesn't fit inside System_Thread");
*(Linux_Object**)&result = thread_info;
return result;
}
return result;
}
@ -554,7 +539,10 @@ internal System_Mutex
system_mutex_make(void){
System_Mutex result = {};
Linux_Object* object = linux_alloc_object(LinuxObjectKind_Mutex);
pthread_mutex_init(&object->mutex, NULL);
pthread_mutexattr_t attr;
pthread_mutexattr_init(&attr);
pthread_mutexattr_settype(&attr, PTHREAD_MUTEX_RECURSIVE);
pthread_mutex_init(&object->mutex, &attr);
*(Linux_Object**)&result = object;
//LINUX_FN_DEBUG("%p", object);
return result;
@ -626,31 +614,31 @@ system_condition_variable_free(System_Condition_Variable cv){
internal void*
system_memory_allocate(u64 size, String_Const_u8 location){
static_assert(MEMORY_PREFIX_SIZE >= sizeof(Memory_Annotation_Node));
static_assert(MEMORY_PREFIX_SIZE >= sizeof(Memory_Annotation_Node), "MEMORY_PREFIX_SIZE is not enough to contain Memory_Annotation_Node");
u64 adjusted_size = size + MEMORY_PREFIX_SIZE;
Assert(adjusted_size > size);
const int prot = PROT_READ | PROT_WRITE;
const int flags = MAP_PRIVATE | MAP_ANONYMOUS;
void* result = mmap(NULL, adjusted_size, prot, flags, -1, 0);
if(result == MAP_FAILED) {
perror("mmap");
return NULL;
}
Linux_Memory_Tracker_Node* node = (Linux_Memory_Tracker_Node*)result;
node->location = location;
node->size = size;
pthread_mutex_lock(&linuxvars.memory_tracker_mutex);
zdll_push_back(linuxvars.memory_tracker_head, linuxvars.memory_tracker_tail, node);
linuxvars.memory_tracker_count++;
pthread_mutex_unlock(&linuxvars.memory_tracker_mutex);
return (u8*)result + MEMORY_PREFIX_SIZE;
}
@ -669,12 +657,12 @@ internal void
system_memory_free(void* ptr, u64 size){
u64 adjusted_size = size + MEMORY_PREFIX_SIZE;
Linux_Memory_Tracker_Node* node = (Linux_Memory_Tracker_Node*)((u8*)ptr - MEMORY_PREFIX_SIZE);
pthread_mutex_lock(&linuxvars.memory_tracker_mutex);
zdll_remove(linuxvars.memory_tracker_head, linuxvars.memory_tracker_tail, node);
linuxvars.memory_tracker_count--;
pthread_mutex_unlock(&linuxvars.memory_tracker_mutex);
if(munmap(node, adjusted_size) == -1) {
perror("munmap");
}
@ -683,12 +671,12 @@ system_memory_free(void* ptr, u64 size){
internal Memory_Annotation
system_memory_annotation(Arena* arena){
LINUX_FN_DEBUG();
Memory_Annotation result;
Memory_Annotation_Node** ptr = &result.first;
pthread_mutex_lock(&linuxvars.memory_tracker_mutex);
for(Linux_Memory_Tracker_Node* node = linuxvars.memory_tracker_head; node; node = node->next) {
*ptr = push_array(arena, Memory_Annotation_Node, 1);
(*ptr)->location = node->location;
@ -697,25 +685,25 @@ system_memory_annotation(Arena* arena){
ptr = &(*ptr)->next;
result.count++;
}
pthread_mutex_unlock(&linuxvars.memory_tracker_mutex);
*ptr = NULL;
result.last = CastFromMember(Memory_Annotation_Node, next, ptr);
return result;
}
internal void
system_show_mouse_cursor(i32 show){
LINUX_FN_DEBUG("%d", show);
linuxvars.cursor_show = show;
XDefineCursor(
linuxvars.dpy,
linuxvars.win,
show ? None : linuxvars.hidden_cursor);
linuxvars.dpy,
linuxvars.win,
show ? None : linuxvars.hidden_cursor);
}
internal b32
@ -727,11 +715,11 @@ system_set_fullscreen(b32 full_screen){
internal b32
system_is_fullscreen(void){
b32 result = 0;
// NOTE(inso): This will get the "true" state of fullscreen,
// even if it was toggled outside of 4coder.
// (e.g. super-F11 on some WMs sets fullscreen for any window/program)
Atom type, *prop;
unsigned long nitems, pad;
int fmt;
@ -741,12 +729,12 @@ system_is_fullscreen(void){
0, 32, False, XA_ATOM,
&type, &fmt, &nitems, &pad,
(unsigned char**)&prop);
if(ret == Success && prop){
result = *prop == linuxvars.atom__NET_WM_STATE_FULLSCREEN;
XFree((unsigned char*)prop);
}
return result;
}

View File

@ -86,7 +86,7 @@
#define frame_useconds (1000000UL / FPS)
#define LINUX_FN_DEBUG(fmt, ...) do { \
/*LOGF("%s: " fmt "\n", __func__, ##__VA_ARGS__);*/ \
/*LOGF("%s: " fmt "\n", __func__, ##__VA_ARGS__);*/ \
} while (0)
// TODO(allen): Make an intrinsics header that uses the cracked OS to define a single set of intrinsic names.
@ -547,41 +547,41 @@ Sys_Font_Path(name, parameters){
Font_Path path = {};
FcPattern *pattern_regular = FcPatternBuild(
0,
FC_POSTSCRIPT_NAME, FcTypeString, name,
FC_SIZE, FcTypeDouble, (double)parameters->pt_size,
FC_FONTFORMAT, FcTypeString, "TrueType",
FC_STYLE, FcTypeString, (FcChar8*)"Regular",
(void*)0);
0,
FC_POSTSCRIPT_NAME, FcTypeString, name,
FC_SIZE, FcTypeDouble, (double)parameters->pt_size,
FC_FONTFORMAT, FcTypeString, "TrueType",
FC_STYLE, FcTypeString, (FcChar8*)"Regular",
(void*)0);
FcPattern *pattern_styled = 0;
if (parameters->italics || parameters->bold){
if (parameters->italics && !parameters->bold){
pattern_styled = FcPatternBuild(
0,
FC_POSTSCRIPT_NAME, FcTypeString, name,
FC_SIZE, FcTypeDouble, (double)parameters->pt_size,
FC_FONTFORMAT, FcTypeString, "TrueType",
FC_STYLE, FcTypeString, (FcChar8*)"Italic",
(void*)0);
0,
FC_POSTSCRIPT_NAME, FcTypeString, name,
FC_SIZE, FcTypeDouble, (double)parameters->pt_size,
FC_FONTFORMAT, FcTypeString, "TrueType",
FC_STYLE, FcTypeString, (FcChar8*)"Italic",
(void*)0);
}
else if (!parameters->italics && parameters->bold){
pattern_styled = FcPatternBuild(
0,
FC_POSTSCRIPT_NAME, FcTypeString, name,
FC_SIZE, FcTypeDouble, (double)parameters->pt_size,
FC_FONTFORMAT, FcTypeString, "TrueType",
FC_STYLE, FcTypeString, (FcChar8*)"Bold",
(void*)0);
0,
FC_POSTSCRIPT_NAME, FcTypeString, name,
FC_SIZE, FcTypeDouble, (double)parameters->pt_size,
FC_FONTFORMAT, FcTypeString, "TrueType",
FC_STYLE, FcTypeString, (FcChar8*)"Bold",
(void*)0);
}
else{
pattern_styled = FcPatternBuild(
0,
FC_POSTSCRIPT_NAME, FcTypeString, name,
FC_SIZE, FcTypeDouble, (double)parameters->pt_size,
FC_FONTFORMAT, FcTypeString, "TrueType",
FC_STYLE, FcTypeString, (FcChar8*)"Bold Italic",
(void*)0);
0,
FC_POSTSCRIPT_NAME, FcTypeString, name,
FC_SIZE, FcTypeDouble, (double)parameters->pt_size,
FC_FONTFORMAT, FcTypeString, "TrueType",
FC_STYLE, FcTypeString, (FcChar8*)"Bold Italic",
(void*)0);
}
}
@ -672,9 +672,9 @@ linux_get_loadable_fonts(Partition *part, Font_Setup_List *list){
}
FcPattern* pat = FcPatternBuild(
0,
FC_STYLE, FcTypeString, (FcChar8*)"Regular",
(void*)0);
0,
FC_STYLE, FcTypeString, (FcChar8*)"Regular",
(void*)0);
FcObjectSet* os = FcObjectSetBuild(FC_FAMILY, FC_FILE, (char*)0);
FcFontSet* fs = FcFontList(fc_config, pat, os);
if (fs != 0){
@ -778,7 +778,7 @@ InitializeOpenGLContext(Display *XDisplay, Window XWindow, GLXFBConfig *best_con
if (glXCreateContextAttribsARB == 0){
//LOG("glXCreateContextAttribsARB() not found, using old-style GLX context\n" );
ctx = glXCreateNewContext( XDisplay, *best_config, GLX_RGBA_TYPE, 0, True );
}
}
else{
int context_attribs[] = {
GLX_CONTEXT_MAJOR_VERSION_ARB, 2,
@ -926,7 +926,7 @@ ChooseGLXConfig(Display *XDisplay, int XScreenIndex)
GLX_STENCIL_SIZE , 8,
GLX_DOUBLEBUFFER , True,
None
};
};
int ConfigCount = 0;
GLXFBConfig *Configs = glXChooseFBConfig(XDisplay, XScreenIndex, DesiredAttributes, &ConfigCount);
@ -1196,7 +1196,7 @@ LinuxGetXSettingsDPI(Display* dpy, int screen)
Window xset_win = XGetSelectionOwner(dpy, XSET_SEL);
if (xset_win == None){
// TODO(inso): listen for the ClientMessage about it becoming available?
// there's not much point atm if DPI scaling is only done at startup
// there's not much point atm if DPI scaling is only done at startup
goto out;
}
@ -1760,11 +1760,11 @@ linux_handle_x11_events(void)
else if ((Atom)event.xclient.data.l[0] == linuxvars.atom__NET_WM_PING){
event.xclient.window = DefaultRootWindow(linuxvars.XDisplay);
XSendEvent(
linuxvars.XDisplay,
event.xclient.window,
False,
SubstructureRedirectMask | SubstructureNotifyMask,
&event);
linuxvars.XDisplay,
event.xclient.window,
False,
SubstructureRedirectMask | SubstructureNotifyMask,
&event);
}
}break;
@ -1792,14 +1792,14 @@ linux_handle_x11_events(void)
if (request.target == linuxvars.atom_TARGETS){
XChangeProperty(
request.display,
request.requestor,
request.property,
XA_ATOM,
32,
PropModeReplace,
(u8*)atoms,
ArrayCount(atoms));
request.display,
request.requestor,
request.property,
XA_ATOM,
32,
PropModeReplace,
(u8*)atoms,
ArrayCount(atoms));
response.property = request.property;
@ -1814,15 +1814,15 @@ linux_handle_x11_events(void)
if (found){
XChangeProperty(
request.display,
request.requestor,
request.property,
request.target,
8,
PropModeReplace,
(u8*)linuxvars.clipboard_outgoing.str,
linuxvars.clipboard_outgoing.size
);
request.display,
request.requestor,
request.property,
request.target,
8,
PropModeReplace,
(u8*)linuxvars.clipboard_outgoing.str,
linuxvars.clipboard_outgoing.size
);
response.property = request.property;
}
@ -1915,7 +1915,7 @@ main(int argc, char **argv){
memory_init();
//
// HACK(allen):
// HACK(allen):
// Previously zipped stuff is here, it should be zipped in the new pattern now.
//

View File

@ -15,16 +15,16 @@ internal void
system_error_box(char *msg, b32 shutdown = true){
fprintf(stderr, "Fatal Error: %s\n", msg);
//LOGF("Fatal Error: %s\n", msg);
Display *dpy = XOpenDisplay(0);
if (!dpy){
exit(1);
}
const int num_cols = 50;
int win_w = (num_cols + 10) * 9;
int win_h = 140;
{
const char *start_p = msg, *space_p = NULL;
for(const char* p = msg; *p; ++p){
@ -36,86 +36,86 @@ system_error_box(char *msg, b32 shutdown = true){
}
}
}
Window w = XCreateSimpleWindow(dpy, DefaultRootWindow(dpy), 0, 0, win_w, win_h, 0, 0, 0x227A3B);
XStoreName(dpy, w, "4coder Error");
XSizeHints* sh = XAllocSizeHints();
sh->flags = PMinSize;
sh->min_width = win_w;
sh->min_height = win_h;
XSetWMNormalHints(dpy, w, sh);
Atom type = XInternAtom(dpy, "_NET_WM_WINDOW_TYPE_DIALOG", False);
XChangeProperty(dpy, w, XInternAtom(dpy, "_NET_WM_WINDOW_TYPE", False), XA_ATOM, 32, PropModeReplace, (unsigned char*) &type, 1);
Atom WM_DELETE_WINDOW = XInternAtom(dpy, "WM_DELETE_WINDOW", False);
XSetWMProtocols(dpy, w, &WM_DELETE_WINDOW, 1);
linux_set_icon(dpy, w);
XMapRaised(dpy, w);
XSync(dpy, False);
XSelectInput(dpy, w, ExposureMask | StructureNotifyMask | PointerMotionMask | ButtonPressMask | ButtonReleaseMask | KeyPressMask);
XFontStruct* font = XLoadQueryFont(dpy, "-*-fixed-bold-*-*-*-*-140-*-*-*-*-iso8859-1");
if (!font){
exit(1);
}
XGCValues gcv;
gcv.foreground = WhitePixel(dpy, 0);
gcv.line_width = 2;
gcv.font = font->fid;
GC gc1 = XCreateGC(dpy, w, GCForeground | GCFont | GCLineWidth, &gcv);
gcv.foreground = BlackPixel(dpy, 0);
GC gc2 = XCreateGC(dpy, w, GCForeground | GCFont | GCLineWidth, &gcv);
int button_trigger = 0;
int button_hi = 0;
int redraw = 1;
XEvent ev;
while (1){
XNextEvent(dpy, &ev);
if (ev.type == Expose) redraw = 1;
if (ev.type == ConfigureNotify){
redraw = 1;
win_w = ev.xconfigure.width;
win_h = ev.xconfigure.height;
}
XRectangle button_rect = { (short)(win_w/2-40), (short)(win_h*0.8f), 80, 20 };
if (ev.type == MotionNotify){
int new_hi = (ev.xmotion.x > button_rect.x &&
ev.xmotion.y > button_rect.y &&
ev.xmotion.x < button_rect.x + button_rect.width &&
ev.xmotion.y < button_rect.y + button_rect.height);
if (new_hi != button_hi){
button_hi = new_hi;
redraw = 1;
}
}
if (ev.type == KeyPress){
KeySym sym = XLookupKeysym(&ev.xkey, 0);
if (sym == XK_Escape || sym == XK_Return){
exit(1);
}
}
if (ev.type == ButtonPress && ev.xbutton.button == Button1){
if (button_hi) button_trigger = 1;
redraw = 1;
}
if (ev.type == ButtonRelease && ev.xbutton.button == Button1){
if (button_trigger){
if (button_hi){
@ -126,61 +126,61 @@ system_error_box(char *msg, b32 shutdown = true){
}
redraw = 1;
}
if (ev.type == ClientMessage && ev.xclient.window == w && (Atom)ev.xclient.data.l[0] == WM_DELETE_WINDOW){
exit(1);
}
#define DRAW_STR(x, y, str, len) \
XDrawString(dpy, w, gc2, (x)+1, (y)+1, (str), (len)); \
XDrawString(dpy, w, gc1, (x) , (y) , (str), (len))
XDrawString(dpy, w, gc2, (x)+1, (y)+1, (str), (len)); \
XDrawString(dpy, w, gc1, (x) , (y) , (str), (len))
if (redraw){
redraw = 0;
XClearWindow(dpy, w);
const char* line_start = msg;
const char* last_space = NULL;
int y = 30;
{
const char title[] = "4coder - Fatal Error";
int width = XTextWidth(font, title, sizeof(title)-1);
int x = (win_w/2) - (width/2);
DRAW_STR(x, y, title, sizeof(title)-1);
}
y += 36;
int width = XTextWidth(font, "x", 1) * num_cols;
int x = (win_w/2) - (width/2);
for(const char* p = line_start; *p; ++p){
if (*p == ' ') last_space = p;
if (p - line_start > num_cols || *p == '\n' || !p[1]){
const char* new_line_start = last_space + 1;
if (!last_space || *p == '\n' || !p[1]){
new_line_start = last_space = (p + !p[1]);
}
DRAW_STR(x, y, line_start, last_space - line_start);
line_start = new_line_start;
last_space = NULL;
y += 18;
}
}
XDrawRectangles(dpy, w, gc1, &button_rect, 1);
if (button_hi || button_trigger){
XDrawRectangle(dpy, w, gc2, button_rect.x+1, button_rect.y+1, button_rect.width-2, button_rect.height-2);
}
DRAW_STR(button_rect.x + 20, button_rect.y + 15, "Drat!", 5);
}
}
#undef DRAW_STR
if (shutdown){
exit(1);
}

View File

@ -94,8 +94,8 @@ struct Mac_Input_Chunk_Transient{
b8 mouse_r_press;
b8 mouse_r_release;
b8 out_of_window;
i8 mouse_wheel;
b8 trying_to_kill;
i32 mouse_wheel;
};
struct Mac_Input_Chunk_Persistent{
@ -193,10 +193,9 @@ 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;
b32 clip_catch_all;
Arena clip_post_arena;
String_Const_u8 clip_post;
@ -530,39 +529,7 @@ mac_get_clipboard_change_count(void){
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 *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){
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);
}
function void
internal void
mac_post_clipboard(Arena *scratch, char *text, i32 len){
NSPasteboard *board = [NSPasteboard generalPasteboard];
@ -583,6 +550,65 @@ mac_post_clipboard(Arena *scratch, char *text, i32 len){
////////////////////////////////
internal
system_get_clipboard_sig(){
String_Const_u8 result = {};
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 {
NSPasteboard *board = [NSPasteboard generalPasteboard];
NSString *utf8_type = @"public.utf8-plain-text";
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){
u32 copy_length = data.length;
if (copy_length > 0){
result = string_const_u8_push(arena, copy_length);
[data getBytes:result.str length:result.size];
}
}
}
}
mac_vars.clipboard_change_count = change_count;
}
return(result);
}
internal
system_post_clipboard_sig(){
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
}
}
internal
system_set_clipboard_catch_all_sig(){
mac_vars.clip_catch_all = enabled?true:false;
}
internal
system_get_clipboard_catch_all_sig(){
return(mac_vars.clip_catch_all);
}
////////////////////////////////
function void
mac_toggle_fullscreen(void){
[mac_vars.window toggleFullScreen:nil];
@ -712,31 +738,11 @@ mac_toggle_fullscreen(void){
}
// NOTE(yuval): Frame clipboard input
Scratch_Block scratch(mac_vars.tctx);
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;
}
if (mac_vars.clipboard_change_count != 0 && mac_vars.clip_catch_all){
input.clipboard = system_get_clipboard(scratch, 0);
}
input.clipboard = mac_vars.clipboard_contents;
}
mac_vars.clip_post.size = 0;
@ -759,7 +765,6 @@ mac_toggle_fullscreen(void){
// 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);
}
}
@ -979,17 +984,9 @@ mac_toggle_fullscreen(void){
}
- (void)scrollWheel:(NSEvent *)event{
float dx = event.scrollingDeltaX;
float dy = event.scrollingDeltaY;
i8 wheel_delta = 0;
if (dy > 0){
wheel_delta = -100;
} else if (dy < 0){
wheel_delta = 100;
}
mac_vars.input_chunk.trans.mouse_wheel = wheel_delta;
f32 dx = event.scrollingDeltaX;
f32 dy = event.scrollingDeltaY;
mac_vars.input_chunk.trans.mouse_wheel = (i32)(-dy);
system_signal_step(0);
}
@ -1326,16 +1323,11 @@ main(int arg_count, char **args){
// NOTE(yuval): Initialize clipboard
{
mac_vars.clipboard_arena = reserve_arena(mac_vars.tctx);
Scratch_Block scratch(mac_vars.tctx);
mac_post_clipboard(scratch, "", 0);
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
@ -1368,7 +1360,7 @@ 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, mac_vars.base_ptr, mac_vars.clipboard_contents, curdir, custom);
app.init(mac_vars.tctx, &target, mac_vars.base_ptr, curdir, custom);
}
//

View File

@ -440,27 +440,6 @@ system_sleep_sig(){
////////////////////////////////
function
system_post_clipboard_sig(){
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
}
}
////////////////////////////////
function
system_cli_call_sig(){
b32 result = false;

View File

@ -1,874 +0,0 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 28.06.2017
*
* Mac C++ layer for 4coder
*
*/
// TOP
#define IS_PLAT_LAYER
#include "4coder_base_types.h"
#include "4coder_API/4coder_version.h"
#include "4coder_lib/4coder_utf8.h"
#if defined(FRED_SUPER)
# include "4coder_lib/4coder_arena.h"
# include "4coder_lib/4coder_arena.cpp"
# define FSTRING_IMPLEMENTATION
# include "4coder_lib/4coder_string.h"
#include "4coder_keycode_extension.h"
# include "4coder_API/4coder_style.h"
# include "4coder_API/4coder_types.h"
#else
# include "4coder_default_bindings.cpp"
#endif
#include "osx_objective_c_to_cpp_links.h"
#include "4ed_math.h"
#include <string.h>
#include "4ed_font.h"
#include "4ed_system.h"
#include "4ed_render_target.h"
#include "4ed_render_format.h"
#include "4ed.h"
#include "4ed_linked_node_macros.h"
#include "4ed_file_track.h"
#include "4ed_system_shared.h"
#include "unix_4ed_headers.h"
#include <sys/syslimits.h>
#undef external
#undef internal
#include <mach/mach.h>
#define external extern "C"
#define internal static
#include <mach-o/dyld.h>
#include <stdlib.h>
////////////////////////////////
#include "4ed_shared_thread_constants.h"
#include "unix_threading_wrapper.h"
#include "mac_semaphore_wrapper.h"
// TODO(allen): Make an intrinsics header that uses the cracked OS to define a single set of intrinsic names.
#define InterlockedCompareExchange(dest, ex, comp) \
__sync_val_compare_and_swap((dest), (comp), (ex))
////////////////////////////////
#define SLASH '/'
#define DLL "so"
global System_Functions sysfunc;
#include "4ed_shared_library_constants.h"
#include "unix_library_wrapper.h"
#include "4ed_standard_libraries.cpp"
#include "4ed_coroutine.cpp"
#include "4ed_font.cpp"
////////////////////////////////
struct OSX_Vars{
Application_Step_Input input;
String clipboard_contents;
b32 keep_running;
b32 has_prev_time;
u64 prev_time_u;
File_Track_System track;
void *track_table;
u32 track_table_size;
u32 track_node_size;
};
////////////////////////////////
OSX_Objective_C_Vars osx_objc;
OSX_Vars osxvars;
global Render_Target target;
global Application_Memory memory_vars;
global Plat_Settings plat_settings;
global Libraries libraries;
global App_Functions app;
global Custom_API custom_api;
global Coroutine_System_Auto_Alloc coroutines;
////////////////////////////////
#include "mac_error_box.cpp"
////////////////////////////////
internal
Sys_Get_4ed_Path_Sig(system_get_4ed_path){
Partition *scratch = &shared_vars.scratch;
Temp_Memory temp = begin_temp_memory(scratch);
char *temp_buffer = push_array(scratch, char, capacity);
i32 size = 0;
u32 buf_size = capacity;
i32 status = _NSGetExecutablePath(temp_buffer, &buf_size);
buf_size = str_size(temp_buffer);
if (status == 0){
ssize_t ln_len = readlink(temp_buffer, out, capacity);
if (ln_len != -1){
out[ln_len] = 0;
String str = make_string_cap(out, ln_len, capacity);
remove_last_folder(&str);
terminate_with_null(&str);
size = str.size;
}
else{
memcpy(out, temp_buffer, buf_size);
String str = make_string_cap(out, buf_size, capacity);
remove_last_folder(&str);
terminate_with_null(&str);
size = str.size;
}
}
end_temp_memory(temp);
return(size);
}
//#include "mac_fd_check.cpp"
#include "unix_4ed_functions.cpp"
internal
Sys_Now_Time_Sig(system_now_time){
f64 t = osx_timer_seconds();
u64 result = (u64)(t*1000000.f);
return(result);
}
////////////////////////////////
void
osx_log(char *m, i32 l){
system_log(m, l);
}
////////////////////////////////
internal void
system_schedule_step(void){
osx_schedule_step();
}
////////////////////////////////
#include "4ed_work_queues.cpp"
////////////////////////////////
internal
Sys_Show_Mouse_Cursor_Sig(system_show_mouse_cursor){
switch (show){
case MouseCursorShow_Never:
{
osx_show_cursor(-1, 0);
}break;
case MouseCursorShow_Always:
{
osx_show_cursor(1, 0);
}break;
}
}
internal
Sys_Set_Fullscreen_Sig(system_set_fullscreen){
osx_objc.do_toggle = (osx_objc.full_screen != full_screen);
return(true);
}
internal
Sys_Is_Fullscreen_Sig(system_is_fullscreen){
b32 result = (osx_objc.full_screen != osx_objc.do_toggle);
return(result);
}
#include "4ed_coroutine_functions.cpp"
#include "4ed_system_shared.cpp"
// File Change Listeners
internal b32
handle_track_out_of_memory(i32 val){
b32 result = false;
switch (val){
case FileTrack_OutOfTableMemory:
{
u32 new_table_size = osxvars.track_table_size*2;
void *new_table = system_memory_allocate(new_table_size);
move_track_system(&osxvars.track, &shared_vars.scratch, new_table, new_table_size);
system_memory_free(osxvars.track_table, osxvars.track_table_size);
osxvars.track_table_size = new_table_size;
osxvars.track_table = new_table;
}break;
case FileTrack_OutOfListenerMemory:
{
osxvars.track_node_size *= 2;
void *node_expansion = system_memory_allocate(osxvars.track_node_size);
expand_track_system_listeners(&osxvars.track, &shared_vars.scratch, node_expansion, osxvars.track_node_size);
}break;
default: result = true; break;
}
return(result);
}
internal
Sys_Add_Listener_Sig(system_add_listener){
b32 result = false;
for (;;){
i32 track_result = add_listener(&osxvars.track, &shared_vars.scratch, (u8*)filename);
if (handle_track_out_of_memory(track_result)){
if (track_result == FileTrack_Good){
result = true;
}
break;
}
}
return(result);
}
internal
Sys_Remove_Listener_Sig(system_remove_listener){
b32 result = false;
i32 track_result = remove_listener(&osxvars.track, &shared_vars.scratch, (u8*)filename);
if (track_result == FileTrack_Good){
result = true;
}
return(result);
}
internal
Sys_Get_File_Change_Sig(system_get_file_change){
b32 result = false;
i32 size = 0;
i32 get_result = get_change_event(&osxvars.track, &shared_vars.scratch, (u8*)buffer, max, &size);
*required_size = size;
*mem_too_small = false;
if (get_result == FileTrack_Good){
result = true;
}
else if (get_result == FileTrack_MemoryTooSmall){
*mem_too_small = true;
result = true;
}
return(result);
}
//
// Clipboard
//
internal
Sys_Post_Clipboard_Sig(system_post_clipboard){
char *string = str.str;
if (!terminate_with_null(&str)){
if (osx_objc.clipboard_space_max <= str.size + 1){
if (osx_objc.clipboard_space != 0){
system_memory_free(osx_objc.clipboard_space, osx_objc.clipboard_space_max);
}
osx_objc.clipboard_space_max = l_round_up_u32(str.size*2 + 1, KB(4096));
osx_objc.clipboard_space = (char*)system_memory_allocate(osx_objc.clipboard_space_max);
}
memcpy(osx_objc.clipboard_space, str.str, str.size);
osx_objc.clipboard_space[str.size] = 0;
string = osx_objc.clipboard_space;
}
osx_post_to_clipboard(string);
}
//
// CLI
//
// HACK(allen): ALMOST an exact duplicate from the Linux version. Just epoll doesn't port. deduplicate or switch to NSTask.
global i32 cli_count = 0;
internal
Sys_CLI_Call_Sig(system_cli_call, path, script_name, cli_out){
i32 pipe_fds[2];
if (pipe(pipe_fds) == -1){
return 0;
}
i32 child_pid = fork();
if (child_pid == -1){
return 0;
}
enum { PIPE_FD_READ, PIPE_FD_WRITE };
// child
if (child_pid == 0){
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){
exit(1);
}
char* argv[] = {
"sh",
"-c",
script_name,
0
};
if (execv("/bin/sh", argv) == -1){
}
exit(1);
}
else{
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];
++cli_count;
}
return(true);
}
internal
Sys_CLI_Begin_Update_Sig(system_cli_begin_update){
// NOTE(inso): I don't think anything needs to be done here.
}
internal
Sys_CLI_Update_Step_Sig(system_cli_update_step){
i32 pipe_read_fd = *(i32*)&cli->out_read;
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){
} else if (num == 0){
// NOTE(inso): EOF
break;
} else {
ptr += num;
space_left -= num;
}
}
*amount = (ptr - dest);
return((ptr - dest) > 0);
}
internal
Sys_CLI_End_Update_Sig(system_cli_end_update){
pid_t pid = *(pid_t*)&cli->proc;
b32 close_me = false;
int status;
if (pid && waitpid(pid, &status, WNOHANG) > 0){
close_me = true;
cli->exit = WEXITSTATUS(status);
close(*(int*)&cli->out_read);
close(*(int*)&cli->out_write);
--cli_count;
}
return(close_me);
}
#include "4ed_font_provider_freetype.h"
global u32 system_font_method = SystemFontMethod_FilePath;
#include "4ed_font_provider_freetype.cpp"
internal
Sys_Font_Path(name, parameters){
b32 italic = (parameters != 0 && parameters->italics);
b32 bold = (parameters != 0 && parameters->bold);
i32 pt_size = 12;
if (parameters != 0){
pt_size = parameters->pt_size;
}
OSX_Font_Match match = osx_get_font_match(name, pt_size, italic, bold);
Font_Path path = {};
Partition *part = &shared_vars.font_scratch;
path.temp = begin_temp_memory(part);
if (match.path != 0){
i32 len = str_size(match.path);
char *buffer = push_array(part, char, len + 1);
if (buffer == 0){
sysshared_partition_grow(part, l_round_up_i32(len + 1, KB(4)));
buffer = push_array(part, char, len + 1);
}
if (buffer != 0){
push_align(part, 8);
memcpy(buffer, match.path, len + 1);
path.len = len;
path.name = buffer;
}
}
return(path);
}
Sys_Font_Data_Not_Used;
internal void
osx_get_loadable_fonts(Partition *part, Font_Setup_List *list){
OSX_Loadable_Fonts fonts = osx_list_loadable_fonts();
for (i32 i = 0; i < fonts.count; ++i){
char *name = fonts.names[i];
char *path = fonts.paths[i];
if (name == 0 || path == 0){
continue;
}
Temp_Memory reset= begin_temp_memory(part);
Font_Setup *setup = push_array(part, Font_Setup, 1);
if (setup != 0){
memset(setup, 0, sizeof(*setup));
i32 len = str_size(path);
if (len < sizeof(setup->stub.name)){
i32 name_len = str_size(name);
if (name_len < sizeof(setup->name)){
setup->stub.load_from_path = true;
memcpy(setup->stub.name, path, len + 1);
setup->stub.len = len;
setup->has_display_name = true;
setup->len = name_len;
memcpy(setup->name, name, name_len + 1);
sll_push(list->first, list->last, setup);
}
else{
end_temp_memory(reset);
}
}
else{
end_temp_memory(reset);
}
}
}
free(fonts.names);
}
#include <OpenGL/OpenGL.h>
#include <OpenGL/gl.h>
#include "opengl/4ed_opengl_render.cpp"
////////////////////////////////
#include "4ed_link_system_functions.cpp"
#include "4ed_shared_init_logic.cpp"
external void*
osx_allocate(u64 size){
void *result = system_memory_allocate(size);
return(result);
}
external void
osx_free(void *ptr, u64 size){
system_memory_free(ptr, size);
}
external void
osx_resize(int width, int height){
if (width > 0 && height > 0){
osx_objc.width = width;
osx_objc.height = height;
target.width = width;
target.height = height;
osx_schedule_step();
}
}
internal void
osx_push_key(Key_Code code, Key_Code chr, Key_Code chr_nocaps, b8 *mods){
i32 count = osxvars.input.keys.count;
if (count < KEY_INPUT_BUFFER_SIZE){
Key_Event_Data *data = osxvars.input.keys.keys;
data[count].keycode = code;
data[count].character = chr;
data[count].character_no_caps_lock = chr_nocaps;
memcpy(data[count].modifiers, mods, sizeof(*mods)*MDFR_INDEX_COUNT);
osxvars.input.keys.count = count + 1;
}
}
internal void
osx_mods_struct_to_array(OSX_Keyboard_Modifiers flags, b8 *mods){
mods[MDFR_SHIFT_INDEX] = ((flags.shift) != 0);
mods[MDFR_CONTROL_INDEX] = ((flags.control) != 0);
mods[MDFR_ALT_INDEX] = ((flags.option) != 0);
mods[MDFR_COMMAND_INDEX] = ((flags.command) != 0);
mods[MDFR_CAPS_INDEX] = ((flags.caps) != 0);
}
external void
osx_character_input(u32 code, OSX_Keyboard_Modifiers modifier_flags){
Key_Code c = 0;
switch (code){
// TODO(allen): Find the canonical list of these things.
case 0x007F: c = key_back; break;
case 0xF700: c = key_up; break;
case 0xF701: c = key_down; break;
case 0xF702: c = key_left; break;
case 0xF703: c = key_right; break;
case 0xF728: c = key_del; break;
case 0xF729: c = key_home; break;
case 0xF72B: c = key_end; break;
case 0xF72C: c = key_page_up; break;
case 0xF72D: c = key_page_down; break;
case 0x001B: c = key_esc; break;
case 0xF704: c = key_f1; break;
case 0xF705: c = key_f2; break;
case 0xF706: c = key_f3; break;
case 0xF707: c = key_f4; break;
case 0xF708: c = key_f5; break;
case 0xF709: c = key_f6; break;
case 0xF70A: c = key_f7; break;
case 0xF70B: c = key_f8; break;
case 0xF70C: c = key_f9; break;
case 0xF70D: c = key_f10; break;
case 0xF70E: c = key_f11; break;
case 0xF70F: c = key_f12; break;
case 0xF710: c = key_f13; break;
case 0xF711: c = key_f14; break;
case 0xF712: c = key_f15; break;
case 0xF713: c = key_f16; break;
}
b8 mods[MDFR_INDEX_COUNT] = {};
osx_mods_struct_to_array(modifier_flags, mods);
if (c != 0){
osx_push_key(c, 0, 0, mods);
}
else if (code != 0){
if (code < 0xE000 || code > 0xF8FF){
if (code == '\r'){
code = '\n';
}
Key_Code chr = code;
Key_Code nocaps = code;
if (modifier_flags.caps){
if ('a' <= nocaps && nocaps <= 'z'){
chr += 'A' - 'a';
}
else if ('A' <= nocaps && nocaps <= 'Z'){
chr += 'a' - 'A';
}
}
osx_push_key(code, chr, nocaps, mods);
}
else{
fprintf(stdout, "unhandled private code %x\n", code);
}
}
else{
osx_push_key(0, 0, 0, mods);
}
osx_schedule_step();
}
external void
osx_mouse(i32 mx, i32 my, u32 type){
i32 new_x = mx;
i32 new_y = osx_objc.height - my;
if (new_x != osxvars.input.mouse.x || new_y != osxvars.input.mouse.y){
osxvars.input.mouse.x = new_x;
osxvars.input.mouse.y = new_y;
osx_schedule_step();
}
if (type == MouseType_Press){
osxvars.input.mouse.press_l = true;
osxvars.input.mouse.l = true;
osx_schedule_step();
}
if (type == MouseType_Release){
osxvars.input.mouse.release_l = true;
osxvars.input.mouse.l = false;
osx_schedule_step();
}
}
external void
osx_mouse_wheel(float dx, float dy){
osxvars.input.mouse.wheel = - (int32_t)(dy);
osx_schedule_step();
}
external void
osx_try_to_close(void){
osxvars.keep_running = false;
osx_schedule_step();
}
external void
osx_step(void){
Application_Step_Result result = {};
// NOTE(allen): Prepare the Frame Input
osxvars.input.dt = 1.f/60.f;
if (osxvars.has_prev_time){
u64 time_u = system_now_time();
u64 time_elapsed_u = time_u - osxvars.prev_time_u;
osxvars.input.dt = time_elapsed_u/1000000.f;
osxvars.prev_time_u = time_u;
}
else{
osxvars.has_prev_time = true;
osxvars.prev_time_u = system_now_time();
}
// TODO(allen): CROSS REFERENCE WITH WINDOWS SPECIAL CODE "TIC898989"
Application_Step_Input frame_input = osxvars.input;
frame_input.trying_to_kill = !osxvars.keep_running;
OSX_Keyboard_Modifiers mods = osx_get_modifiers();
osx_mods_struct_to_array(mods, frame_input.keys.modifiers);
osxvars.input.first_step = false;
memset(&osxvars.input.keys, 0, sizeof(osxvars.input.keys));
osxvars.input.mouse.press_l = false;
osxvars.input.mouse.release_l = false;
osxvars.input.mouse.press_r = false;
osxvars.input.mouse.release_r = false;
osxvars.input.mouse.wheel = 0;
// NOTE(allen): Frame Clipboard Input
if (osx_objc.has_clipboard_item){
frame_input.clipboard = make_string(osx_objc.clipboard_data, (i32)osx_objc.clipboard_size);
}
else{
frame_input.clipboard = null_string;
}
// HACK(allen): Got this all messed up with respect to how everyone else (other OS layers) work
osx_objc.do_toggle = false;
osx_objc.full_screen = osx_is_fullscreen();
// HACK(allen): THIS SHIT IS FUCKED (happens on linux too)
b32 keep_running = osxvars.keep_running;
// NOTE(allen): Application Core Update
target.buffer.pos = 0;
if (app.step != 0){
result = app.step(&sysfunc, &target, &memory_vars, &frame_input);
}
else{
//LOG("app.step == 0 -- skipping\n");
}
// NOTE(allen): Finish the Loop
if (result.perform_kill){
osx_close_app();
}
else if (!keep_running && !osxvars.keep_running){
osxvars.keep_running = true;
}
// NOTE(allen): Switch to New Title
if (result.has_new_title){
osx_change_title(result.title_string);
}
// NOTE(allen): Switch to New Cursor
osx_show_cursor(0, result.mouse_cursor_type);
// NOTE(allen): Render
osx_begin_render();
gl_render(&target, &shared_vars.pixel_scratch);
osx_end_render();
// NOTE(allen): Toggle Full Screen
if (osx_objc.do_toggle){
osx_toggle_fullscreen();
}
// NOTE(allen): Schedule Another Step if Needed
if (result.animating || cli_count > 0){
osx_schedule_step();
}
}
external void
osx_init(){
//
// System Linkage
//
link_system_code();
//
// Memory init
//
memset(&target, 0, sizeof(target));
memset(&memory_vars, 0, sizeof(memory_vars));
memset(&plat_settings, 0, sizeof(plat_settings));
memset(&libraries, 0, sizeof(libraries));
memset(&app, 0, sizeof(app));
memset(&custom_api, 0, sizeof(custom_api));
memory_init();
osxvars.keep_running = true;
osxvars.input.first_step = true;
//
// HACK(allen):
// Previously zipped stuff is here, it should be zipped in the new pattern now.
//
init_shared_vars();
osxvars.track_table_size = KB(16);
osxvars.track_table = system_memory_allocate(osxvars.track_table_size);
osxvars.track_node_size = KB(16);
void *track_nodes = system_memory_allocate(osxvars.track_node_size);
i32 track_result = init_track_system(&osxvars.track, &shared_vars.scratch,
osxvars.track_table, osxvars.track_table_size,
track_nodes, osxvars.track_node_size);
if (track_result != FileTrack_Good){
exit(1);
}
//
// Load Core Code
//
load_app_code();
//
// Read command line
//
read_command_line(osx_objc.argc, osx_objc.argv);
//
// Load Custom Code
//
#if defined(FRED_SUPER)
load_custom_code();
#else
DontCompile;
#endif
//
// Threads
//
work_system_init();
//
// Coroutines
//
coroutines_init();
//
// Font System Init
//
Partition *scratch = &shared_vars.scratch;
Temp_Memory temp = begin_temp_memory(scratch);
Font_Setup_List font_setup = system_font_get_local_stubs(scratch);
osx_get_loadable_fonts(scratch, &font_setup);
system_font_init(&sysfunc.font, plat_settings.font_size, plat_settings.use_hinting, font_setup);
end_temp_memory(temp);
//
// App Init
//
char cwd[4096];
u32 size = sysfunc.get_current_path(cwd, sizeof(cwd));
if (size == 0 || size >= sizeof(cwd)){
system_error_box("Could not get current directory at launch.");
}
String curdir = make_string(cwd, size);
terminate_with_null(&curdir);
replace_char(&curdir, '\\', '/');
String clipboard_string = {};
if (osx_objc.has_clipboard_item){
clipboard_string = make_string(osx_objc.clipboard_data, osx_objc.clipboard_size);
}
//LOG("Initializing application variables\n");
app.init(&sysfunc, &target, &memory_vars, clipboard_string, curdir, custom_api);
}
#include "mac_4ed_file_track.cpp"
// BOTTOM

View File

@ -1,895 +0,0 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 28.06.2017
*
* Mac Objective C layer for 4coder
*
*/
// TOP
#define IS_OBJC_LAYER
#include "4coder_base_types.h"
#include "4coder_API/4coder_version.h"
#include "4ed_cursor_codes.h"
#include "4ed_linked_node_macros.h"
#undef global
#undef external
#define external
#include "osx_objective_c_to_cpp_links.h"
#include <CoreServices/CoreServices.h>
#import <Cocoa/Cocoa.h>
#import <CoreVideo/CVDisplayLink.h>
#import <IOKit/hid/IOHIDLib.h>
#import <OpenGL/OpenGL.h>
#import <OpenGL/gl.h>
#include <sys/types.h>
#include <sys/event.h>
#include <sys/time.h>
#include <time.h>
#include <string.h>
void
osx_post_to_clipboard(char *str){
NSPasteboard *board = [NSPasteboard generalPasteboard];
NSString *utf8_type = @"public.utf8-plain-text";
NSArray<NSString*> *typesArray = [NSArray arrayWithObjects: utf8_type, nil];
[board declareTypes:typesArray owner:nil];
NSString *paste_string = [NSString stringWithUTF8String:str];
[board setString:paste_string forType:utf8_type];
osx_objc.just_posted_to_clipboard = true;
}
void
osx_error_dialogue(char *str){
NSAlert *alert = [[NSAlert alloc] init];
[alert addButtonWithTitle:@"OK"];
NSString *text = [NSString stringWithUTF8String:str];
[alert setMessageText:text];
[alert setAlertStyle:NSCriticalAlertStyle];
[alert runModal];
}
//
// Entry point, OpenGL window setup.
//
@interface AppDelegate : NSObject <NSApplicationDelegate>
@end
@interface My4coderView : NSOpenGLView{
@public
//CVDisplayLinkRef displayLink;
}
- (void)requestDisplay;
- (void)checkClipboard;
- (CVReturn)getFrame;
- (void)drawRect:(NSRect)bounds;
@end
#define DISPLINK_SIG(n) CVReturn n(CVDisplayLinkRef link, const CVTimeStamp *now, const CVTimeStamp *output, CVOptionFlags flags_in, CVOptionFlags *flags_out, void *context)
static DISPLINK_SIG(osx_display_link);
static OSX_Keyboard_Modifiers
osx_mods_nsevent_to_struct(NSEventModifierFlags flags){
OSX_Keyboard_Modifiers mods = {};
mods.shift = ((flags & NSEventModifierFlagShift) != 0);
mods.command = ((flags & NSEventModifierFlagCommand) != 0);
mods.control = ((flags & NSEventModifierFlagControl) != 0);
mods.option = ((flags & NSEventModifierFlagOption) != 0);
mods.caps = ((flags & NSEventModifierFlagCapsLock) != 0);
return(mods);
}
@implementation My4coderView
- (void)keyDown:(NSEvent *)event{
NSString *real = [event charactersIgnoringModifiers];
NSString *with_mods = [event characters];
b32 is_dead_key = false;
if (real && !with_mods){
is_dead_key = true;
}
OSX_Keyboard_Modifiers mods = osx_get_modifiers();
// TODO(allen): Not ideal solution, look for realer text
// input on Mac. This just makes sure we're getting good
// results for unmodified keys when cmnd and ctrl aren't down.
NSString *which = with_mods;
if (mods.command || mods.control){
which = real;
}
u32 length = which.length;
for (u32 i = 0; i < length; ++i){
unichar c = [which characterAtIndex:i];
osx_character_input(c, mods);
}
}
- (void)mouseDown:(NSEvent*)event{
NSPoint m = [event locationInWindow];
osx_mouse(m.x, m.y, MouseType_Press);
}
- (void)mouseDragged:(NSEvent*)event{
NSPoint m = [event locationInWindow];
osx_mouse(m.x, m.y, MouseType_Move);
}
- (void)mouseMoved:(NSEvent*)event{
NSPoint m = [event locationInWindow];
osx_mouse(m.x, m.y, MouseType_Move);
}
- (void)mouseUp:(NSEvent*)event{
NSPoint m = [event locationInWindow];
osx_mouse(m.x, m.y, MouseType_Release);
}
- (void)scrollWheel:(NSEvent*)event{
float dx = event.scrollingDeltaX;
float dy = event.scrollingDeltaY;
osx_mouse_wheel(dx, dy);
}
- (BOOL)windowShouldClose:(NSWindow*)sender{
osx_try_to_close();
return(NO);
}
- (void)requestDisplay{
CGRect cg_rect = CGRectMake(0, 0, osx_objc.width, osx_objc.height);
NSRect rect = NSRectFromCGRect(cg_rect);
[self setNeedsDisplayInRect:rect];
}
static i32 did_update_for_clipboard = true;
- (void)checkClipboard{
NSPasteboard *board = [NSPasteboard generalPasteboard];
if (board.changeCount != osx_objc.prev_clipboard_change_count && did_update_for_clipboard){
[self requestDisplay];
did_update_for_clipboard = false;
}
}
- (CVReturn)getFrame{
did_update_for_clipboard = true;
@autoreleasepool
{
if (osx_objc.running){
osx_objc.has_clipboard_item = false;
NSPasteboard *board = [NSPasteboard generalPasteboard];
if (board.changeCount != osx_objc.prev_clipboard_change_count){
if (!osx_objc.just_posted_to_clipboard){
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){
if (copy_length + 1 > osx_objc.clipboard_max){
osx_free(osx_objc.clipboard_data, osx_objc.clipboard_max);
osx_objc.clipboard_max = l_round_up_u32(copy_length + 1, KB(4));
osx_objc.clipboard_data = osx_allocate(osx_objc.clipboard_max);
}
if (copy_length + 1 < osx_objc.clipboard_max){
osx_objc.clipboard_size = copy_length;
[data
getBytes: osx_objc.clipboard_data
length: copy_length];
((char*)osx_objc.clipboard_data)[copy_length] = 0;
osx_objc.has_clipboard_item = true;
}
}
}
}
}
else{
osx_objc.just_posted_to_clipboard = false;
}
osx_objc.prev_clipboard_change_count = board.changeCount;
}
osx_step();
}
}
return kCVReturnSuccess;
}
- (void)reshape
{
[super reshape];
NSRect rect = [self bounds];
osx_resize(rect.size.width, rect.size.height);
}
- (void)init_gl
{
if (osx_objc.gl_is_initialized){
return;
}
[self setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
NSOpenGLPixelFormatAttribute attrs[] = {
NSOpenGLPFAOpenGLProfile, NSOpenGLProfileVersionLegacy,
NSOpenGLPFAColorSize, 24,
NSOpenGLPFAAlphaSize, 8,
NSOpenGLPFAAccelerated,
NSOpenGLPFADoubleBuffer,
0
};
NSOpenGLPixelFormat* format = [[NSOpenGLPixelFormat alloc] initWithAttributes:attrs];
if(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];
osx_objc.gl_is_initialized = true;
}
- (id)init
{
self = [super init];
if(self == nil)
{
return nil;
}
[self init_gl];
return self;
}
- (void)drawRect: (NSRect) bounds{
[self getFrame];
}
- (void)awakeFromNib
{
[self init_gl];
}
- (void)prepareOpenGL
{
[super prepareOpenGL];
[[self openGLContext] makeCurrentContext];
GLint swapInt = 1;
[[self openGLContext] setValues:&swapInt forParameter:NSOpenGLCPSwapInterval];
}
- (void)dealloc
{
[super dealloc];
}
- (BOOL)acceptsFirstResponder
{
return YES;
}
- (BOOL)becomeFirstResponder
{
return YES;
}
- (BOOL)resignFirstResponder
{
return YES;
}
@end
@implementation AppDelegate
- (void)applicationDidFinishLaunching:(id)sender
{
}
- (BOOL)applicationShouldTerminateAfterLastWindowClosed:(NSApplication*)sender
{
return YES;
}
- (void)applicationWillTerminate:(NSApplication*)sender
{
}
@end
//////////////////
typedef struct File_Change_Node File_Change_Node;
struct File_Change_Node{
File_Change_Node *next;
char *name;
i32 len;
};
typedef struct{
File_Change_Node *first;
File_Change_Node *last;
volatile i64 lock;
} File_Change_Queue;
static File_Change_Queue file_queue = {};
File_Change_Node*
file_change_node(char *name){
i32 len = strlen(name);
void *block = malloc(len + 1 + sizeof(File_Change_Node));
File_Change_Node *node = (File_Change_Node*)block;
memset(node, 0, sizeof(*node));
node->name = (char*)(node + 1);
node->len = len;
memcpy(node->name, name, len + 1);
return(node);
}
void
file_change_node_free(File_Change_Node *node){
free(node);
}
#define file_queue_lock() for(;;){i64 v=__sync_val_compare_and_swap(&file_queue.lock,0,1);if(v==0){break;}}
#define file_queue_unlock() __sync_lock_test_and_set(&file_queue.lock, 0)
void
file_watch_callback(ConstFSEventStreamRef stream, void *callbackInfo, size_t numEvents, void *evPaths, const FSEventStreamEventFlags *evFlags, const FSEventStreamEventId *evIds){
char **paths = (char**)evPaths;
for (int i = 0; i < numEvents; ++i){
File_Change_Node *node = file_change_node(paths[i]);
file_queue_lock();
sll_push(file_queue.first, file_queue.last, node);
file_queue_unlock();
}
}
//////////////////
typedef struct{
FSEventStreamRef stream;
} File_Watching_Handle;
File_Watching_Handle
schedule_file_watching(char *f){
File_Watching_Handle handle = {};
CFStringRef arg = CFStringCreateWithCString(0, f, kCFStringEncodingUTF8);
CFArrayRef paths = CFArrayCreate(0, (const void**)&arg, 1, 0);
void *callbackInfo = 0;
CFAbsoluteTime latency = 2.0;
handle.stream = FSEventStreamCreate(0, &file_watch_callback, 0, paths, kFSEventStreamEventIdSinceNow, latency, kFSEventStreamCreateFlagFileEvents);
FSEventStreamScheduleWithRunLoop(handle.stream, CFRunLoopGetMain(), kCFRunLoopDefaultMode);
if (!FSEventStreamStart(handle.stream)){
fprintf(stdout, "BAD SCHED: %s\n", f);
}
return(handle);
}
void
unschedule_file_watching(File_Watching_Handle handle){
FSEventStreamStop(handle.stream);
FSEventStreamInvalidate(handle.stream);
FSEventStreamRelease(handle.stream);
}
typedef struct File_Table_Entry{
u64 hash;
void *name;
i32 counter;
File_Watching_Handle handle;
} File_Table_Entry;
typedef struct File_Change_Table{
File_Table_Entry *table;
i32 count;
i32 size;
} File_Change_Table;
static File_Change_Table file_change_table = {};
void*
osx_file_name_prefixed_length(char *name){
i32 len = 0;
for (; name[len] != 0; ++len);
char *name_stored = (char*)malloc(4 + l_round_up_u32(len + 1, 4));
*(i32*)name_stored = len;
memcpy(name_stored + 4, name, len);
name_stored[4 + len] = 0;
return(name_stored);
}
b32
osx_name_prefixed_match(void *a, void *b){
b32 result = false;
i32 *len_a = (i32*)a;
i32 *len_b = (i32*)b;
if (*len_a == *len_b){
char *str_a = (char*)(len_a + 1);
char *str_b = (char*)(len_b + 1);
if (strncmp(str_a, str_b, *len_a) == 0){
result = true;
}
}
return(result);
}
File_Table_Entry*
osx_file_listener_lookup_and_return_pointer(u64 hash, void *name){
File_Table_Entry *result = 0;
i32 index = (i32)(hash % file_change_table.size);
i32 first_index = index;
for (;;){
File_Table_Entry *entry = &file_change_table.table[index];
if (entry->hash == hash){
if (osx_name_prefixed_match(name, entry->name)){
result = entry;
break;
}
}
if (entry->name == 0){
break;
}
index = (index + 1)%file_change_table.size;
if (index == first_index){
break;
}
}
return(result);
}
void
osx_file_listener_table_entry_erase(File_Table_Entry *entry){
free(entry->name);
unschedule_file_watching(entry->handle);
memset(entry, 0, sizeof(*entry));
entry->name = (void*)1;
}
b32
osx_file_listener_lookup_and_decrement(u64 hash, void *name){
b32 found = false;
File_Table_Entry *entry = osx_file_listener_lookup_and_return_pointer(hash, name);
if (entry != 0){
found = true;
--entry->counter;
if (entry->counter <= 0){
osx_file_listener_table_entry_erase(entry);
}
}
return(found);
}
b32
osx_file_listener_hash(u64 hash, void *name, i32 counter, File_Watching_Handle **handle_address_out){
b32 result = 0;
if (file_change_table.count*6 < file_change_table.size*5){
i32 index = (i32)(hash % file_change_table.size);
i32 first_index = index;
for (;;){
File_Table_Entry *entry = &file_change_table.table[index];
if (entry->name == 0 || entry->name == (void*)1){
entry->hash = hash;
entry->name = name;
entry->counter = counter;
*handle_address_out = &entry->handle;
result = true;
++file_change_table.count;
break;
}
index = (index + 1)%file_change_table.size;
if (index == first_index){
break;
}
}
if (!result){
//LOG("file change listener table error: could not find a free slot in the table\n");
}
}
return(result);
}
void
osx_file_listener_grow_table(i32 size){
if (file_change_table.size < size){
File_Table_Entry *old_table = file_change_table.table;
i32 old_size = file_change_table.size;
file_change_table.table = (File_Table_Entry*)osx_allocate(size*sizeof(File_Table_Entry));
memset(file_change_table.table, 0, size*sizeof(File_Table_Entry));
file_change_table.size = size;
for (i32 i = 0; i < old_size; ++i){
void *name = file_change_table.table[i].name;
if (name != 0 && name != (void*)1){
File_Table_Entry *e = &file_change_table.table[i];
File_Watching_Handle *handle_address = 0;
osx_file_listener_hash(e->hash, e->name, e->counter, &handle_address);
*handle_address = e->handle;
}
}
if (old_table != 0){
osx_free(old_table, old_size*sizeof(File_Table_Entry));
}
}
}
void
osx_file_listener_double_table(){
osx_file_listener_grow_table(file_change_table.size*2);
}
b32
osx_file_listener_insert_or_increment_always(u64 hash, void *name, File_Watching_Handle **handle_address_out){
b32 was_already_in_table = false;
File_Table_Entry *entry = osx_file_listener_lookup_and_return_pointer(hash, name);
if (entry != 0){
++entry->counter;
was_already_in_table = true;
}
else{
b32 result = osx_file_listener_hash(hash, name, 1, handle_address_out);
if (!result){
osx_file_listener_double_table();
osx_file_listener_hash(hash, name, 1, handle_address_out);
}
}
return(was_already_in_table);
}
u64
osx_get_file_hash(void *name){
u32 count = *(u32*)(name);
char *str = (char*)name + 4;
u64 hash = 0;
u64 state = count;
u64 inc = 1 + 2*count;
for (u32 i = 0; i <= count; ++i){
u64 old_state = state;
state = state*6364136223846783005ULL + inc;
u32 xorshifted = ((old_state >> 18u) ^ old_state) >> 27u;
u32 rot = old_state >> 59u;
hash = (hash << 3) + (hash & 1) + ((xorshifted >> rot) | (xorshifted << ((-rot) & 31)));
if (i < count){
inc = 1 + 2*(((inc - 1) << 7) | (u8)str[i]);
}
}
return(hash);
}
void
osx_file_listener_init(void){
osx_file_listener_grow_table(4096);
}
void
osx_add_file_listener(char *dir_name){
// TODO(allen): Decide what to do about these darn string mallocs.
void *name_stored = osx_file_name_prefixed_length(dir_name);
File_Watching_Handle *handle_address = 0;
b32 was_already_in_table = osx_file_listener_insert_or_increment_always(osx_get_file_hash(name_stored), name_stored, &handle_address);
if (was_already_in_table){
free(name_stored);
}
else{
*handle_address = schedule_file_watching(dir_name);
}
}
void
osx_remove_file_listener(char *dir_name){
void *name_stored = osx_file_name_prefixed_length(dir_name);
osx_file_listener_lookup_and_decrement(osx_get_file_hash(name_stored), name_stored);
free(name_stored);
}
i32
osx_get_file_change_event(char *buffer, i32 max, i32 *size){
file_queue_lock();
File_Change_Node *node = file_queue.first;
sll_pop(file_queue.first, file_queue.last);
file_queue_unlock();
i32 result = 0;
if (node != 0){
if (node->len < max){
result = 1;
memcpy(buffer, node->name, node->len);
*size = node->len;
}
else{
result = -1;
// TODO(allen): Somehow save the node?
}
file_change_node_free(node);
}
return(result);
}
void
osx_show_cursor(i32 show, i32 cursor_type){
local_persist b32 cursor_is_shown = 1;
if (show == 1){
if (!cursor_is_shown){
[NSCursor unhide];
cursor_is_shown = true;
}
}
else if (show == -1){
if (cursor_is_shown){
[NSCursor hide];
cursor_is_shown = false;
}
}
if (cursor_type > 0){
switch (cursor_type){
case APP_MOUSE_CURSOR_ARROW:
{
[[NSCursor arrowCursor] set];
}break;
case APP_MOUSE_CURSOR_IBEAM:
{
[[NSCursor IBeamCursor] set];
}break;
case APP_MOUSE_CURSOR_LEFTRIGHT:
{
[[NSCursor resizeLeftRightCursor] set];
}break;
case APP_MOUSE_CURSOR_UPDOWN:
{
[[NSCursor resizeUpDownCursor] set];
}break;
}
}
}
My4coderView* view = 0;
NSWindow* window = 0;
void
osx_begin_render(){
CGLLockContext([[view openGLContext] CGLContextObj]);
[[view openGLContext] makeCurrentContext];
}
void
osx_end_render(){
[[view openGLContext] flushBuffer];
CGLUnlockContext([[view openGLContext] CGLContextObj]);
}
void
osx_schedule_step(void){
[NSTimer scheduledTimerWithTimeInterval: 0.0
target: view
selector: @selector(requestDisplay)
userInfo: nil repeats:NO];
}
void
osx_toggle_fullscreen(void){
[window toggleFullScreen:nil];
}
b32
osx_is_fullscreen(void){
b32 result = (([window styleMask] & NSFullScreenWindowMask) != 0);
return(result);
}
void
osx_close_app(void){
[NSApp terminate: nil];
}
f32
osx_timer_seconds(void){
f32 result = CACurrentMediaTime();
return(result);
}
NSFontManager *font_manager = 0;
NSString *get_font_path(NSFont *font){
CFStringRef name = (CFStringRef)[font fontName];
CGFloat size = [font pointSize];
CTFontDescriptorRef ref = CTFontDescriptorCreateWithNameAndSize(name, size);
CFURLRef url = CTFontDescriptorCopyAttribute(ref, kCTFontURLAttribute);
NSString *path = [(NSURL *)CFBridgingRelease(url) path];
return(path);
}
OSX_Font_Match
osx_get_font_match(char *name, i32 pt_size, b32 italic, b32 bold){
if (font_manager == 0){
font_manager = [NSFontManager sharedFontManager];
}
NSString *name_string = [NSString stringWithUTF8String:name];
NSFontTraitMask trait_mask = 0;
if (italic){
trait_mask = (trait_mask | NSItalicFontMask);
}
NSInteger weight = 5;
if (bold){
weight = 9;
}
b32 used_base_file = false;
NSFont *font = [font_manager
fontWithFamily: name_string
traits: trait_mask
weight: weight
size:(float)pt_size];
if (font == nil){
font = [font_manager
fontWithFamily: name_string
traits: 0
weight: 5
size:(float)pt_size];
used_base_file = true;
}
OSX_Font_Match match = {};
if (font != nil){
NSString *path = get_font_path(font);
char *path_c = 0;
if (path != nil){
path_c = (char*)[path UTF8String];
}
if (path_c != 0){
match.path = path_c;
match.used_base_file = used_base_file;
}
}
return(match);
}
OSX_Loadable_Fonts
osx_list_loadable_fonts(void){
if (font_manager == 0){
font_manager = [NSFontManager sharedFontManager];
}
NSArray<NSString*> *fonts = [font_manager availableFontFamilies];
OSX_Loadable_Fonts result = {};
NSUInteger count_u = [fonts count];
int count = (int)count_u;
result.count = count;
size_t memsize = count*2*sizeof(char*);
void *mem = malloc(memsize);
result.names = (char**)mem;
result.paths = result.names + count;
for (int i = 0; i < count; ++i){
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
size:12];
NSString *path = get_font_path(font);
char *path_c = 0;
if (path != nil){
path_c = (char*)[path UTF8String];
}
result.names[i] = font_n_c;
result.paths[i] = path_c;
}
return(result);
}
void
osx_change_title(char *str_c){
NSString *str = [NSString stringWithUTF8String:str_c];
[window setTitle:str];
}
OSX_Keyboard_Modifiers
osx_get_modifiers(void){
return(osx_mods_nsevent_to_struct([NSEvent modifierFlags]));
}
int
main(int argc, char **argv){
memset(&osx_objc, 0, sizeof(osx_objc));
u32 clipboard_size = KB(16);
osx_objc.clipboard_data = osx_allocate(clipboard_size);
osx_objc.clipboard_max = clipboard_size;
osx_objc.argc = argc;
osx_objc.argv = argv;
osx_file_listener_init();
@autoreleasepool{
NSApplication *app = [NSApplication sharedApplication];
[NSApp setActivationPolicy:NSApplicationActivationPolicyRegular];
[app setDelegate:[[AppDelegate alloc] init]];
NSRect screenRect = [[NSScreen mainScreen] frame];
float w = 800.f;
float h = 600.f;
NSRect frame = NSMakeRect((screenRect.size.width - w) * 0.5, (screenRect.size.height - h) * 0.5, w, h);
u32 flags = NSTitledWindowMask | NSClosableWindowMask | NSMiniaturizableWindowMask | NSResizableWindowMask;
window = [[NSWindow alloc] initWithContentRect:frame styleMask:flags backing:NSBackingStoreBuffered defer:NO];
[window setAcceptsMouseMovedEvents:YES];
view = [[My4coderView alloc] init];
[view setFrame:[[window contentView] bounds]];
[view setAutoresizingMask:NSViewWidthSizable | NSViewHeightSizable];
[[window contentView] addSubview:view];
[window setMinSize:NSMakeSize(100, 100)];
[window setTitle:@WINDOW_NAME];
[window makeKeyAndOrderFront:nil];
[NSTimer scheduledTimerWithTimeInterval: 0.5
target: view
selector: @selector(checkClipboard)
userInfo: nil repeats:YES];
osx_init();
osx_objc.running = true;
[NSApp run];
}
return(0);
}
// BOTTOM

View File

@ -6,6 +6,7 @@
#include "4ed_opengl_funcs.h"
*/
// TODO(allen): eliminate this
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))

View File

@ -1,160 +0,0 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 06.29.2017
*
* Types and functions for communication between C++ and Objective-C layers.
*
*/
// TOP
#if !defined(OSX_OBJECTIVE_C_TO_CPP_LINKS_H)
#define OSX_OBJECTIVE_C_TO_CPP_LINKS_H
#include <stdio.h>
#if 0
#define DBG_POINT() fprintf(stdout, "%s\n", __FILE__ ":" LINE_STR ":")
#else
#define DBG_POINT()
#endif
typedef enum OSX_Mouse_Event_Type{
MouseType_Move,
MouseType_Press,
MouseType_Release,
} OSX_Mouse_Event_Type;
typedef struct OSX_Keyboard_Modifiers{
b32 shift;
b32 command;
b32 control;
b32 option;
b32 caps;
} OSX_Keyboard_Modifiers;
typedef struct OSX_Objective_C_Vars{
i32 width, height;
b32 gl_is_initialized;
b32 running;
u32 key_count;
u32 keys[8];
u32 prev_clipboard_change_count;
b32 has_clipboard_item;
void *clipboard_data;
u32 clipboard_size;
u32 clipboard_max;
b32 just_posted_to_clipboard;
char *clipboard_space;
u64 clipboard_space_max;
b32 full_screen;
b32 do_toggle;
i32 argc;
char **argv;
} OSX_Objective_C_Vars;
typedef struct OSX_Loadable_Fonts{
char **names;
char **paths;
i32 count;
} OSX_Loadable_Fonts;
typedef struct OSX_Font_Match{
char *path;
b32 used_base_file;
} OSX_Font_Match;
// In C++ layer.
extern OSX_Objective_C_Vars osx_objc;
external void*
osx_allocate(u64 size);
external void
osx_free(void *ptr, u64 size);
external void
osx_resize(int width, int height);
external void
osx_character_input(u32 code, OSX_Keyboard_Modifiers modifier_flags);
external void
osx_mouse(i32 mx, i32 my, u32 type);
external void
osx_mouse_wheel(float dx, float dy);
external void
osx_try_to_close(void);
external void
osx_step();
external void
osx_init();
external void
osx_log(char *m, i32 l);
// In Objective-C layer.
external void
osx_post_to_clipboard(char *str);
external void
osx_error_dialogue(char *str);
external void
osx_add_file_listener(char *file_name);
external void
osx_remove_file_listener(char *file_name);
external i32
osx_get_file_change_event(char *buffer, i32 max, i32 *size);
external void
osx_show_cursor(i32 show_inc, i32 cursor_type);
external void
osx_begin_render(void);
external void
osx_end_render(void);
external void
osx_schedule_step(void);
external void
osx_toggle_fullscreen(void);
external b32
osx_is_fullscreen(void);
external void
osx_close_app(void);
external f32
osx_timer_seconds(void);
external OSX_Font_Match
osx_get_font_match(char *name, i32 pt_size, b32 italic, b32 bold);
external OSX_Loadable_Fonts
osx_list_loadable_fonts(void);
external void
osx_change_title(char *str);
external OSX_Keyboard_Modifiers
osx_get_modifiers(void);
#endif
// BOTTOM

View File

@ -9,6 +9,8 @@
// TOP
#error IS THIS STILL REAL? (February 27th 2020)
#if !defined(FD_CHECK)
#define FD_CHECK()
#endif

View File

@ -9,6 +9,8 @@
// TOP
#error IS THIS STILL REAL? (February 27th 2020)
#include <sys/mman.h>
#include <sys/types.h>
#include <sys/stat.h>

View File

@ -9,6 +9,8 @@
// TOP
#error IS THIS STILL REAL? (February 27th 2020)
union Library{
void *lib;
FixSize(LIBRARY_TYPE_SIZE);

View File

@ -9,6 +9,8 @@
// TOP
#error IS THIS STILL REAL? (February 27th 2020)
#if !defined(MAC_THREADING_WRAPPER)
#define MAC_THREADING_WRAPPER

View File

@ -718,8 +718,8 @@ win32_keycode_init(void){
keycode_lookup_table[VK_F6] = KeyCode_F6;
keycode_lookup_table[VK_F7] = KeyCode_F7;
keycode_lookup_table[VK_F8] = KeyCode_F8;
keycode_lookup_table[VK_F9] = KeyCode_F9;
keycode_lookup_table[VK_F9] = KeyCode_F9;
keycode_lookup_table[VK_F10] = KeyCode_F10;
keycode_lookup_table[VK_F11] = KeyCode_F11;
keycode_lookup_table[VK_F12] = KeyCode_F12;
@ -727,6 +727,36 @@ win32_keycode_init(void){
keycode_lookup_table[VK_F14] = KeyCode_F14;
keycode_lookup_table[VK_F15] = KeyCode_F15;
keycode_lookup_table[VK_F16] = KeyCode_F16;
keycode_lookup_table[VK_F17] = KeyCode_F17;
keycode_lookup_table[VK_F18] = KeyCode_F18;
keycode_lookup_table[VK_F19] = KeyCode_F19;
keycode_lookup_table[VK_F20] = KeyCode_F20;
keycode_lookup_table[VK_F21] = KeyCode_F21;
keycode_lookup_table[VK_F22] = KeyCode_F22;
keycode_lookup_table[VK_F23] = KeyCode_F23;
keycode_lookup_table[VK_F24] = KeyCode_F24;
keycode_lookup_table[VK_NUMPAD0] = KeyCode_NumPad0;
keycode_lookup_table[VK_NUMPAD1] = KeyCode_NumPad1;
keycode_lookup_table[VK_NUMPAD2] = KeyCode_NumPad2;
keycode_lookup_table[VK_NUMPAD3] = KeyCode_NumPad3;
keycode_lookup_table[VK_NUMPAD4] = KeyCode_NumPad4;
keycode_lookup_table[VK_NUMPAD5] = KeyCode_NumPad5;
keycode_lookup_table[VK_NUMPAD6] = KeyCode_NumPad6;
keycode_lookup_table[VK_NUMPAD7] = KeyCode_NumPad7;
keycode_lookup_table[VK_NUMPAD8] = KeyCode_NumPad8;
keycode_lookup_table[VK_NUMPAD9] = KeyCode_NumPad9;
keycode_lookup_table[VK_MULTIPLY] = KeyCode_NumPadStar;
keycode_lookup_table[VK_ADD] = KeyCode_NumPadPlus;
keycode_lookup_table[VK_SUBTRACT] = KeyCode_NumPadMinus;
keycode_lookup_table[VK_DECIMAL] = KeyCode_NumPadDot;
keycode_lookup_table[VK_DIVIDE] = KeyCode_NumPadSlash;
for (i32 i = 0xDF; i < 0xFF; i += 1){
keycode_lookup_table[i] = KeyCode_Ex0 + 1;
}
}
internal void
@ -1343,9 +1373,9 @@ 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));)
b32 load_success = true;
(l) = (l) && win32_wgl_good((Void_Func*)(f));)
b32 load_success = true;
LoadWGL(wglCreateContextAttribsARB, load_success);
LoadWGL(wglChoosePixelFormatARB, load_success);
LoadWGL(wglGetExtensionsStringEXT, load_success);
@ -1443,7 +1473,6 @@ win32_gl_create_window(HWND *wnd_out, HGLRC *context_out, DWORD style, RECT rect
goto fail_window_init;
}
#if 1
i32 context_attrib_list[] = {
/*0*/WGL_CONTEXT_MAJOR_VERSION_ARB, 3,
/*2*/WGL_CONTEXT_MINOR_VERSION_ARB, 2,
@ -1455,15 +1484,6 @@ win32_gl_create_window(HWND *wnd_out, HGLRC *context_out, DWORD style, RECT rect
/*6*/WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
/*8*/0
};
#else
i32 context_attrib_list[] = {
WGL_CONTEXT_MAJOR_VERSION_ARB, 2,
WGL_CONTEXT_MINOR_VERSION_ARB, 1,
WGL_CONTEXT_FLAGS_ARB, 0,
WGL_CONTEXT_PROFILE_MASK_ARB, WGL_CONTEXT_CORE_PROFILE_BIT_ARB,
0
};
#endif
HGLRC context = wglCreateContextAttribsARB(dc, 0, context_attrib_list);
if (context == 0){

View File

@ -26,8 +26,8 @@ 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_linux = "echo build: x64 & bin/build.sh";
build_x86_linux = "echo build: x86 & bin/build.sh -DDEV_BUILD_X86";
build_x64_linux = "echo build: x64 & bin/build-linux.sh";
build_x86_linux = "echo build: x86 & bin/build-linux.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";
@ -46,18 +46,20 @@ command_list = {
{ .name = "package",
.out = "*compilation*", .footer_panel = false, .save_dirty_files = true,
.cmd = { {"echo package & bin\\package.bat", .os = "win" },
{"echo package & bin/package.sh" , .os = "linux"},
{"echo package & bin/package.sh" , .os = "mac" }, }, },
.cmd = { {"echo package & bin\\package.bat" , .os = "win" },
{"echo package & bin/package-linux.sh", .os = "linux"},
{"echo package & bin/package-max.sh" , .os = "mac" }, }, },
{ .name = "run one time",
.out = "*run*", .footer_panel = false, .save_dirty_files = false,
.cmd = { { "pushd ..\\build & one_time", .os = "win" },
{ "pushd ../build & one_time", .os = "mac" }, }, },
{ "cd ../build && ./one_time" , .os = "linux" },
{ "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" },
{ "custom/bin/build_one_time.sh docs/4ed_doc_custom_api_main.cpp ../build", .os = "linux" },
{ "custom/bin/build_one_time.sh docs/4ed_doc_custom_api_main.cpp ../build", .os = "mac" }, }, },
{ .name = "build C++ lexer generator",
@ -90,7 +92,8 @@ command_list = {
{ .name = "build keycode generator",
.out = "*compilation*", .footer_panel = true, .save_dirty_files = true,
.cmd = { { "custom\\bin\\build_one_time 4ed_generate_keycodes.cpp ..\\build", .os = "win" }, }, },
.cmd = { { "custom\\bin\\build_one_time 4ed_generate_keycodes.cpp ..\\build", .os = "win" },
{ "custom/bin/build_one_time.sh 4ed_generate_keycodes.cpp ../build", .os = "linux" }, }, },
{ .name = "build site render",
.out = "*compilation*", .footer_panel = true, .save_dirty_files = true,

View File

@ -7,11 +7,14 @@
+ in config.4coder the variable virtual_whitespace_regular_indent determines the number of space-widths to use as the regular indentation in a virtual whitespace layout
+ show whitespace mode implemented in 'default_render_buffer'
+ `set_face_size` and `set_face_size_this_buffer` commands
+ `HookID_WholeScreenRenderCaller` hook runs once per frame after all views render
+ Extended key codes list
+ Fix: tabs are measured with the correct amount of width for the user's settings
+ Fix: virtual whitespace toggling works when the config initially diabled virtual whitespace
+ Fix: never miss the most recent post to the clipboard on windows
+ Fix: command `load_theme_current_buffer` gaurds against destroying the active color palette when bad files are loaded
+ Fix: project deep copy routine copies strings in the whitelist and blacklist pattern arrays
+ Fix: footer panel manipulation functions check if the view exists
4.1.3
+ Unkillable buffer setting
@ -85,7 +88,7 @@ New in alpha 4.0.29:
-Highlighting and marking API, supporting customizable line higlights, range highlights, cursors and marks
-In config.4coder "use_line_highlight" enables the highlight at the cursor in the active view
-In config.4coder "use_scope_highlight" enables background highlighting to distinguish scopes in code files
-In config.4coder "use_paren_helper" enalbes distinct coloring for matching parentheses
-In config.4coder "use_paren_helper" enalbes distinct coloring for matching parentheses
-In config.4coder "use_comment_keyword" enables special coloring for the strings 'TODO' and 'NOTE' anywhere they occur, in code or text
-In config.4coder "mode" sets the editing mode
"4coder" the default 4coder mode