simulated input testing mostly done

This commit is contained in:
Allen Webster 2018-03-02 23:46:44 -08:00
parent 08ad61316f
commit ce5039d0ca
18 changed files with 1804 additions and 746 deletions

View File

@ -379,7 +379,7 @@ STRUCT Mouse_State{
int8_t release_r;
/* DOC(Mouse is outside of the window.) */
int8_t out_of_window;
/* DOC(The motion of the wheel. Zero indicates no motion. Positive indicates downard scrolling. Negative indicates upward scrolling. The magnitude corresponds to the number of pixels of scroll will be applied at standard scroll speeds.) */
/* DOC(The motion of the wheel. Zero indicates no motion. Positive indicates downard scrolling. Negative indicates upward scrolling. The magnitude corresponds to the number of pixels of scroll that would be applied at standard scroll speeds.) */
int32_t wheel;
/* DOC(X position of the mouse where the left of the window is x = 0, and x grows to the right.) */
int32_t x;

457
4coder_file.h Normal file
View File

@ -0,0 +1,457 @@
/*
4coder_file.h - File enumeration and reading procedures for each platform.
TYPE: 'utility'
*/
// TOP
#if !defined(FCODER_FILE_ENUMERATOR_CPP)
#define FCODER_FILE_ENUMERATOR_CPP
#include "4coder_lib/4coder_mem.h"
#include "4coder_os_comp_cracking.h"
#define FSTRING_IMPLEMENTATION
#include "4coder_lib/4coder_string.h"
#include <stdio.h>
typedef int32_t bool32;
#if defined(IS_WINDOWS)
//// WINDOWS BEGIN ////
#define UNICODE
#include <Windows.h>
typedef TCHAR Filename_Character;
#define SLASH '\\'
//// WINDOWS END ////
#elif defined(IS_LINUX) || defined(IS_MAC)
//// UNIX BEGIN ////
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
typedef char Filename_Character;
#define SLASH '/'
//// UNIX END ////
#else
# error metdata generator not supported on this platform
#endif
struct Cross_Platform_File_Info{
Filename_Character *name;
int32_t len;
bool32 is_folder;
};
struct Cross_Platform_File_List{
Cross_Platform_File_Info *info;
int32_t count;
int32_t final_length;
Filename_Character final_name[4096];
};
typedef bool32 File_Filter(Filename_Character *name, int32_t len);
static Cross_Platform_File_List
get_file_list(Partition *part, Filename_Character *dir, File_Filter *filter);
static Filename_Character*
encode(Partition *part, char *str){
int32_t size = 0;
for (;str[size]!=0;++size);
Filename_Character *out = push_array(part, Filename_Character, size + 1);
push_align(part, 8);
if (out == 0){
fprintf(stdout, "fatal error: ran out of memory encoding string to filename\n");
exit(1);
}
int32_t j = 0;
for (int32_t i = 0; i <= size; ++i){
if (str[i] != '"'){
out[j++] = str[i];
}
}
return(out);
}
static char*
unencode(Partition *part, Filename_Character *str, int32_t len){
Temp_Memory temp = begin_temp_memory(part);
char *out = push_array(part, char, len + 1);
push_align(part, 8);
if (out == 0){
fprintf(stdout, "fatal error: ran out of memory unencoding string to filename\n");
exit(1);
}
for (int32_t i = 0; i <= len; ++i){
if (str[i] <= 127){
out[i] = (char)str[i];
}
else{
out = 0;
end_temp_memory(temp);
break;
}
}
return(out);
}
static bool32
filter_all(Filename_Character *name, int32_t len){
return(true);
}
static bool32
filter_is_code_file(Filename_Character *name, int32_t len){
bool32 is_code = false;
if (len >= 5){
Filename_Character *ext = &name[len - 4];
if (ext[0] == '.' && ext[1] == 'c' && ext[2] == 'p' && ext[3] == 'p'){
is_code = true;
}
else if (ext[0] == '.' && ext[1] == 'h' && ext[2] == 'p' && ext[3] == 'p'){
is_code = true;
}
}
if (len >= 4){
Filename_Character *ext = &name[len - 3];
if (ext[0] == '.' && ext[1] == 'c' && ext[2] == 'c'){
is_code = true;
}
}
if (len >= 3){
Filename_Character *ext = &name[len - 2];
if (ext[0] == '.' && ext[1] == 'h'){
is_code = true;
}
else if (ext[0] == '.' && ext[1] == 'c'){
is_code = true;
}
}
return(is_code);
}
#if defined(IS_WINDOWS)
//// WINDOWS BEGIN ////
static Cross_Platform_File_List
get_file_list(Partition *part, Filename_Character *dir, File_Filter *filter){
if (part == 0){
fprintf(stdout, "fatal error: NULL part passed to %s\n", __FUNCTION__);
exit(1);
}
if (dir == 0){
fprintf(stdout, "fatal error: NULL dir passed to %s\n", __FUNCTION__);
exit(1);
}
HANDLE dir_handle =
CreateFile(dir,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
0,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
0);
if (dir_handle == INVALID_HANDLE_VALUE){
fprintf(stdout, "fatal error: could not open directory handle\n");
exit(1);
}
Filename_Character final_name[4096];
DWORD final_length = GetFinalPathNameByHandle(dir_handle, final_name, sizeof(final_name), 0);
if (final_length > sizeof(final_name)){
fprintf(stdout, "fatal error: path name too long for local buffer\n");
exit(1);
}
CloseHandle(dir_handle);
final_length -= 4;
memmove(final_name, final_name + 4, final_length*sizeof(*final_name));
final_name[final_length] = '\\';
final_name[final_length + 1] = '*';
final_name[final_length + 2] = 0;
WIN32_FIND_DATA find_data = {0};
HANDLE search = FindFirstFile(final_name, &find_data);
if (search == INVALID_HANDLE_VALUE){
fprintf(stdout, "fatal error: could not begin a file search\n");
exit(1);
}
int32_t character_count = 0;
int32_t file_count = 0;
BOOL more_files = true;
do{
Filename_Character *name = &find_data.cFileName[0];
int32_t size = 0;
for(;name[size];++size);
uint32_t attribs = find_data.dwFileAttributes;
bool32 is_folder = ((attribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
bool32 is_hidden = ((attribs & FILE_ATTRIBUTE_HIDDEN) != 0);
if (!is_hidden){
if (name[0] != '.' && (is_folder || filter(name, size))){
++file_count;
character_count += size + 1;
}
}
more_files = FindNextFile(search, &find_data);
}while(more_files);
FindClose(search);
Cross_Platform_File_List list = {0};
Temp_Memory part_reset = begin_temp_memory(part);
int32_t rounded_char_size = (character_count*sizeof(Filename_Character) + 7)&(~7);
int32_t memsize = rounded_char_size + file_count*sizeof(Cross_Platform_File_Info);
void *mem = push_array(part, uint8_t, memsize);
if (mem == 0){
fprintf(stdout, "fatal error: not enough memory on the partition for a file list.\n");
exit(1);
}
Filename_Character *char_ptr = (Filename_Character*)mem;
Cross_Platform_File_Info *info_ptr = (Cross_Platform_File_Info*)((uint8_t*)mem + rounded_char_size);
Filename_Character *char_ptr_end = (Filename_Character*)info_ptr;
Cross_Platform_File_Info *info_ptr_end = info_ptr + file_count;
Cross_Platform_File_Info *info_ptr_base = info_ptr;
search = FindFirstFile(final_name, &find_data);
if (search == INVALID_HANDLE_VALUE){
fprintf(stdout, "fatal error: could not restart a file search\n");
exit(1);
}
int32_t adjusted_file_count = 0;
more_files = true;
do{
Filename_Character *name = &find_data.cFileName[0];
int32_t size = 0;
for(;name[size]!=0;++size);
uint32_t attribs = find_data.dwFileAttributes;
bool32 is_folder = ((attribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
bool32 is_hidden = ((attribs & FILE_ATTRIBUTE_HIDDEN) != 0);
if (!is_hidden){
if (name[0] != '.' && (is_folder || filter(name, size))){
if (info_ptr + 1 > info_ptr_end || char_ptr + size + 1 > char_ptr_end){
memset(&list, 0, sizeof(list));
end_temp_memory(part_reset);
FindClose(search);
return(list);
}
info_ptr->name = char_ptr;
info_ptr->len = size;
info_ptr->is_folder = is_folder;
memmove(char_ptr, name, size*sizeof(*name));
char_ptr[size] = 0;
char_ptr += size + 1;
++info_ptr;
++adjusted_file_count;
}
}
more_files = FindNextFile(search, &find_data);
}while(more_files);
FindClose(search);
list.info = info_ptr_base;
list.count = adjusted_file_count;
list.final_length = final_length;
memcpy(list.final_name, final_name, list.final_length*sizeof(*final_name));
list.final_name[list.final_length] = 0;
return(list);
}
//// WINDOWS END ////
#elif defined(IS_LINUX) || defined(IS_MAC)
//// UNIX BEGIN ////
static Cross_Platform_File_List
get_file_list(Partition *part, Filename_Character *directory, File_Filter *filter){
if (part == 0){
fprintf(stdout, "fatal error: NULL part passed to %s\n", __FUNCTION__);
exit(1);
}
if (directory == 0){
fprintf(stdout, "fatal error: NULL dir passed to %s\n", __FUNCTION__);
exit(1);
}
DIR *dir_handle = opendir(directory);
if (dir_handle == 0){
fprintf(stdout, "fatal error: could not open directory handle\n");
if (sizeof(*directory) == 2){
fprintf(stdout, "%ls\n", (wchar_t*)directory);
}
else{
fprintf(stdout, "%s\n", (char*)directory);
}
exit(1);
}
Filename_Character final_name[4096];
int32_t final_length = str_size(directory);
if (final_length + 1 > sizeof(final_name)){
fprintf(stdout, "fatal error: path name too long for local buffer\n");
exit(1);
}
memcpy(final_name, directory, final_length + 1);
int32_t character_count = 0;
int32_t file_count = 0;
for (struct dirent *entry = readdir(dir_handle);
entry != 0;
entry = readdir(dir_handle)){
Filename_Character *name = entry->d_name;
int32_t size = 0;
for(;name[size];++size);
bool32 is_folder = false;
if (entry->d_type == DT_LNK){
struct stat st;
if (stat(entry->d_name, &st) != -1){
is_folder = S_ISDIR(st.st_mode);
}
}
else{
is_folder = (entry->d_type == DT_DIR);
}
if (name[0] != '.' && (is_folder || filter(name, size))){
++file_count;
character_count += size + 1;
}
}
Cross_Platform_File_List list = {0};
Temp_Memory part_reset = begin_temp_memory(part);
int32_t rounded_char_size = (character_count*sizeof(Filename_Character) + 7)&(~7);
int32_t memsize = rounded_char_size + file_count*sizeof(Cross_Platform_File_Info);
void *mem = push_array(part, uint8_t, memsize);
if (mem == 0){
fprintf(stdout, "fatal error: not enough memory on the partition for a file list.\n");
exit(1);
}
Filename_Character *char_ptr = (Filename_Character*)mem;
Cross_Platform_File_Info *info_ptr = (Cross_Platform_File_Info*)((uint8_t*)mem + rounded_char_size);
Filename_Character *char_ptr_end = (Filename_Character*)info_ptr;
Cross_Platform_File_Info *info_ptr_end = info_ptr + file_count;
Cross_Platform_File_Info *info_ptr_base = info_ptr;
rewinddir(dir_handle);
int32_t adjusted_file_count = 0;
for (struct dirent *entry = readdir(dir_handle);
entry != 0;
entry = readdir(dir_handle)){
Filename_Character *name = entry->d_name;
int32_t size = 0;
for(;name[size];++size);
bool32 is_folder = false;
if (entry->d_type == DT_LNK){
struct stat st;
if (stat(entry->d_name, &st) != -1){
is_folder = S_ISDIR(st.st_mode);
}
}
else{
is_folder = (entry->d_type == DT_DIR);
}
if (name[0] != '.' && (is_folder || filter(name, size))){
if (info_ptr + 1 > info_ptr_end || char_ptr + size + 1 > char_ptr_end){
memset(&list, 0, sizeof(list));
end_temp_memory(part_reset);
closedir(dir_handle);
return(list);
}
info_ptr->name = char_ptr;
info_ptr->len = size;
info_ptr->is_folder = is_folder;
memmove(char_ptr, name, size*sizeof(*name));
char_ptr[size] = 0;
char_ptr += size + 1;
++info_ptr;
++adjusted_file_count;
}
}
closedir(dir_handle);
list.info = info_ptr_base;
list.count = adjusted_file_count;
list.final_length = final_length;
memcpy(list.final_name, final_name, list.final_length*sizeof(*final_name));
list.final_name[list.final_length] = 0;
return(list);
}
//// UNIX END ////
#else
# error metdata generator not supported on this platform
#endif
static String
file_dump(Partition *part, char *name){
String text = {0};
FILE *file = fopen(name, "rb");
if (file != 0){
fseek(file, 0, SEEK_END);
text.size = ftell(file);
fseek(file, 0, SEEK_SET);
text.memory_size = text.size + 1;
text.str = push_array(part, char, text.memory_size);
push_align(part, 8);
if (text.str == 0){
fprintf(stdout, "fatal error: not enough memory in partition for file dumping");
exit(1);
}
fread(text.str, 1, text.size, file);
terminate_with_null(&text);
fclose(file);
}
return(text);
}
#endif
// BOTTOM

View File

@ -212,198 +212,198 @@ int32_t source_name_len;
int32_t line_number;
};
static Command_Metadata fcoder_metacmd_table[192] = {
{ PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "C:\\4ed\\code\\4coder_default_framework.h", 41, 232 },
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "C:\\4ed\\code\\4coder_auto_indent.cpp", 37, 667 },
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "C:\\4ed\\code\\4coder_auto_indent.cpp", 37, 678 },
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "C:\\4ed\\code\\4coder_auto_indent.cpp", 37, 657 },
{ PROC_LINKS(backspace_char, 0), "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 81 },
{ PROC_LINKS(backspace_word, 0), "backspace_word", 14, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 147 },
{ PROC_LINKS(basic_change_active_panel, 0), "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 514 },
{ PROC_LINKS(build_in_build_panel, 0), "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "C:\\4ed\\code\\4coder_build_commands.cpp", 40, 203 },
{ PROC_LINKS(build_search, 0), "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "C:\\4ed\\code\\4coder_build_commands.cpp", 40, 169 },
{ PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 136 },
{ PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "C:\\4ed\\code\\4coder_default_framework.h", 41, 125 },
{ PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "C:\\4ed\\code\\4coder_default_framework.h", 41, 143 },
{ PROC_LINKS(change_to_build_panel, 0), "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "C:\\4ed\\code\\4coder_build_commands.cpp", 40, 225 },
{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 446 },
{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 190 },
{ PROC_LINKS(click_set_mark, 0), "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 203 },
{ PROC_LINKS(close_all_code, 0), "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "C:\\4ed\\code\\4coder_project_commands.cpp", 42, 188 },
{ PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "C:\\4ed\\code\\4coder_build_commands.cpp", 40, 219 },
{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 522 },
{ PROC_LINKS(copy, 0), "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "C:\\4ed\\code\\4coder_clipboard.cpp", 35, 52 },
{ PROC_LINKS(cursor_mark_swap, 0), "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 109 },
{ PROC_LINKS(cut, 0), "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "C:\\4ed\\code\\4coder_clipboard.cpp", 35, 61 },
{ PROC_LINKS(decrease_face_size, 0), "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 615 },
{ PROC_LINKS(decrease_line_wrap, 0), "decrease_line_wrap", 18, "Decrases the current buffer's width for line wrapping.", 54, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 592 },
{ PROC_LINKS(delete_char, 0), "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 63 },
{ PROC_LINKS(delete_current_scope, 0), "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "C:\\4ed\\code\\4coder_scope_commands.cpp", 40, 492 },
{ PROC_LINKS(delete_file_query, 0), "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1062 },
{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 369 },
{ PROC_LINKS(delete_range, 0), "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 121 },
{ PROC_LINKS(delete_word, 0), "delete_word", 11, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 167 },
{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 347 },
{ PROC_LINKS(eol_dosify, 0), "eol_dosify", 10, "Puts the buffer in DOS line ending mode.", 40, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 645 },
{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 653 },
{ PROC_LINKS(execute_any_cli, 0), "execute_any_cli", 15, "Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.", 133, "C:\\4ed\\code\\4coder_system_command.cpp", 40, 30 },
{ PROC_LINKS(execute_arbitrary_command, 0), "execute_arbitrary_command", 25, "Execute a 'long form' command.", 30, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 750 },
{ PROC_LINKS(execute_previous_cli, 0), "execute_previous_cli", 20, "If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.", 126, "C:\\4ed\\code\\4coder_system_command.cpp", 40, 14 },
{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 661 },
{ PROC_LINKS(goto_first_jump_direct, 0), "goto_first_jump_direct", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "C:\\4ed\\code\\4coder_jump_direct.cpp", 37, 100 },
{ PROC_LINKS(goto_first_jump_same_panel_sticky, 0), "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "C:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 562 },
{ PROC_LINKS(goto_first_jump_sticky, 0), "goto_first_jump_sticky", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "C:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 544 },
{ PROC_LINKS(goto_jump_at_cursor_direct, 0), "goto_jump_at_cursor_direct", 26, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "C:\\4ed\\code\\4coder_jump_direct.cpp", 37, 24 },
{ PROC_LINKS(goto_jump_at_cursor_same_panel_direct, 0), "goto_jump_at_cursor_same_panel_direct", 37, "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..", 168, "C:\\4ed\\code\\4coder_jump_direct.cpp", 37, 45 },
{ PROC_LINKS(goto_jump_at_cursor_same_panel_sticky, 0), "goto_jump_at_cursor_same_panel_sticky", 37, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "C:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 388 },
{ PROC_LINKS(goto_jump_at_cursor_sticky, 0), "goto_jump_at_cursor_sticky", 26, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "C:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 360 },
{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 671 },
{ PROC_LINKS(goto_next_jump_direct, 0), "goto_next_jump_direct", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "C:\\4ed\\code\\4coder_jump_direct.cpp", 37, 64 },
{ PROC_LINKS(goto_next_jump_no_skips_direct, 0), "goto_next_jump_no_skips_direct", 30, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "C:\\4ed\\code\\4coder_jump_direct.cpp", 37, 82 },
{ PROC_LINKS(goto_next_jump_no_skips_sticky, 0), "goto_next_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "C:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 513 },
{ PROC_LINKS(goto_next_jump_sticky, 0), "goto_next_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "C:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 483 },
{ PROC_LINKS(goto_prev_jump_direct, 0), "goto_prev_jump_direct", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "C:\\4ed\\code\\4coder_jump_direct.cpp", 37, 73 },
{ PROC_LINKS(goto_prev_jump_no_skips_direct, 0), "goto_prev_jump_no_skips_direct", 30, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "C:\\4ed\\code\\4coder_jump_direct.cpp", 37, 91 },
{ PROC_LINKS(goto_prev_jump_no_skips_sticky, 0), "goto_prev_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "C:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 529 },
{ PROC_LINKS(goto_prev_jump_sticky, 0), "goto_prev_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "C:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 499 },
{ PROC_LINKS(hide_filebar, 0), "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 555 },
{ PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 541 },
{ PROC_LINKS(highlight_next_scope_absolute, 0), "highlight_next_scope_absolute", 29, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "C:\\4ed\\code\\4coder_scope_commands.cpp", 40, 368 },
{ PROC_LINKS(highlight_prev_scope_absolute, 0), "highlight_prev_scope_absolute", 29, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "C:\\4ed\\code\\4coder_scope_commands.cpp", 40, 387 },
{ PROC_LINKS(highlight_surrounding_scope, 0), "highlight_surrounding_scope", 27, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "C:\\4ed\\code\\4coder_scope_commands.cpp", 40, 346 },
{ PROC_LINKS(if0_off, 0), "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 537 },
{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 603 },
{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 581 },
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1201 },
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1177 },
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1183 },
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively opens or creates a new file.", 42, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1189 },
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1195 },
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1219 },
{ PROC_LINKS(kill_rect, 0), "kill_rect", 9, "Delete characters in a rectangular region. Range testing is done by unwrapped-xy coordinates.", 93, "C:\\4ed\\code\\power\\4coder_experiments.cpp", 44, 31 },
{ PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 151 },
{ PROC_LINKS(list_all_functions_current_buffer, 0), "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "C:\\4ed\\code\\4coder_function_list.cpp", 39, 348 },
{ PROC_LINKS(list_all_locations, 0), "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "C:\\4ed\\code\\4coder_search.cpp", 32, 702 },
{ PROC_LINKS(list_all_locations_case_insensitive, 0), "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "C:\\4ed\\code\\4coder_search.cpp", 32, 722 },
{ PROC_LINKS(list_all_locations_of_identifier, 0), "list_all_locations_of_identifier", 32, "Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.", 102, "C:\\4ed\\code\\4coder_search.cpp", 32, 786 },
{ PROC_LINKS(list_all_locations_of_identifier_case_insensitive, 0), "list_all_locations_of_identifier_case_insensitive", 49, "Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.", 104, "C:\\4ed\\code\\4coder_search.cpp", 32, 792 },
{ PROC_LINKS(list_all_locations_of_selection, 0), "list_all_locations_of_selection", 31, "Reads the string in the selected range and lists all exact case-sensitive mathces in all open buffers.", 102, "C:\\4ed\\code\\4coder_search.cpp", 32, 834 },
{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "C:\\4ed\\code\\4coder_search.cpp", 32, 840 },
{ PROC_LINKS(list_all_locations_of_type_definition, 0), "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 454 },
{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 466 },
{ PROC_LINKS(list_all_substring_locations, 0), "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "C:\\4ed\\code\\4coder_search.cpp", 32, 712 },
{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "C:\\4ed\\code\\4coder_search.cpp", 32, 732 },
{ PROC_LINKS(load_project, 0), "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "C:\\4ed\\code\\4coder_project_commands.cpp", 42, 408 },
{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1130 },
{ PROC_LINKS(miblo_decrement_basic, 0), "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "C:\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 46, 119 },
{ PROC_LINKS(miblo_decrement_time_stamp, 0), "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "C:\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 46, 392 },
{ PROC_LINKS(miblo_decrement_time_stamp_minute, 0), "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "C:\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 46, 404 },
{ PROC_LINKS(miblo_increment_basic, 0), "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "C:\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 46, 103 },
{ PROC_LINKS(miblo_increment_time_stamp, 0), "miblo_increment_time_stamp", 26, "Increment a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "C:\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 46, 386 },
{ PROC_LINKS(miblo_increment_time_stamp_minute, 0), "miblo_increment_time_stamp_minute", 33, "Increment a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "C:\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 46, 398 },
{ PROC_LINKS(move_down, 0), "move_down", 9, "Moves the cursor down one line.", 31, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 233 },
{ PROC_LINKS(move_down_10, 0), "move_down_10", 12, "Moves the cursor down ten lines.", 32, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 245 },
{ PROC_LINKS(move_down_textual, 0), "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 318 },
{ PROC_LINKS(move_left, 0), "move_left", 9, "Moves the cursor one character to the left.", 43, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 286 },
{ PROC_LINKS(move_line_down, 0), "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 330 },
{ PROC_LINKS(move_line_up, 0), "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 271 },
{ PROC_LINKS(move_right, 0), "move_right", 10, "Moves the cursor one character to the right.", 44, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 295 },
{ PROC_LINKS(move_up, 0), "move_up", 7, "Moves the cursor up one line.", 29, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 227 },
{ PROC_LINKS(move_up_10, 0), "move_up_10", 10, "Moves the cursor up ten lines.", 30, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 239 },
{ PROC_LINKS(multi_line_edit, 0), "multi_line_edit", 15, "Begin multi-line mode. In multi-line mode characters are inserted at every line between the mark and cursor. All characters are inserted at the same character offset into the line. This mode uses line_char coordinates.", 221, "C:\\4ed\\code\\power\\4coder_experiments.cpp", 44, 122 },
{ PROC_LINKS(newline_or_goto_position_direct, 0), "newline_or_goto_position_direct", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "C:\\4ed\\code\\4coder_jump_direct.cpp", 37, 117 },
{ PROC_LINKS(newline_or_goto_position_same_panel_direct, 0), "newline_or_goto_position_same_panel_direct", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "C:\\4ed\\code\\4coder_jump_direct.cpp", 37, 132 },
{ PROC_LINKS(newline_or_goto_position_same_panel_sticky, 0), "newline_or_goto_position_same_panel_sticky", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "C:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 600 },
{ PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "C:\\4ed\\code\\4coder_jump_sticky.cpp", 37, 585 },
{ PROC_LINKS(open_all_code, 0), "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "C:\\4ed\\code\\4coder_project_commands.cpp", 42, 165 },
{ PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "C:\\4ed\\code\\4coder_project_commands.cpp", 42, 180 },
{ PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder colors and fonts selector menu.", 48, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1225 },
{ PROC_LINKS(open_debug, 0), "open_debug", 10, "Opens a debug view for internal use.", 36, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1231 },
{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 634 },
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file, displaying it in the other view.", 127, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 651 },
{ PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 513 },
{ PROC_LINKS(open_long_braces_break, 0), "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 529 },
{ PROC_LINKS(open_long_braces_semicolon, 0), "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 521 },
{ PROC_LINKS(open_matching_file_cpp, 0), "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 707 },
{ PROC_LINKS(open_panel_hsplit, 0), "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "C:\\4ed\\code\\4coder_default_framework.h", 41, 170 },
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "C:\\4ed\\code\\4coder_default_framework.h", 41, 161 },
{ PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 276 },
{ PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 267 },
{ PROC_LINKS(paste, 0), "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "C:\\4ed\\code\\4coder_clipboard.cpp", 35, 70 },
{ PROC_LINKS(paste_and_indent, 0), "paste_and_indent", 16, "Paste from the top of clipboard and run auto-indent on the newly pasted text.", 77, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 391 },
{ PROC_LINKS(paste_next, 0), "paste_next", 10, "If the previous command was paste or paste_next, replaces the paste range with the next text down on the clipboard, otherwise operates as the paste command.", 156, "C:\\4ed\\code\\4coder_clipboard.cpp", 35, 108 },
{ PROC_LINKS(paste_next_and_indent, 0), "paste_next_and_indent", 21, "Paste the next item on the clipboard and run auto-indent on the newly pasted text.", 82, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 398 },
{ PROC_LINKS(place_in_scope, 0), "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "C:\\4ed\\code\\4coder_scope_commands.cpp", 40, 486 },
{ PROC_LINKS(project_fkey_command, 0), "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "C:\\4ed\\code\\4coder_project_commands.cpp", 42, 575 },
{ PROC_LINKS(project_go_to_root_directory, 0), "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "C:\\4ed\\code\\4coder_project_commands.cpp", 42, 601 },
{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 983 },
{ PROC_LINKS(query_replace_identifier, 0), "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1004 },
{ PROC_LINKS(query_replace_selection, 0), "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 240 },
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forewards through the undo history.", 44, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1171 },
{ PROC_LINKS(reload_current_project, 0), "reload_current_project", 22, "If a project file has already been loaded, reloads the same file. Useful for when the project configuration is changed.", 120, "C:\\4ed\\code\\4coder_project_commands.cpp", 42, 479 },
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "C:\\4ed\\code\\4coder_default_framework.h", 41, 743 },
{ PROC_LINKS(rename_file_query, 0), "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1088 },
{ PROC_LINKS(rename_parameter, 0), "rename_parameter", 16, "If the cursor is found to be on the name of a function parameter in the signature of a function definition, all occurences within the scope of the function will be replaced with a new provided string.", 200, "C:\\4ed\\code\\power\\4coder_experiments.cpp", 44, 387 },
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1207 },
{ PROC_LINKS(replace_all_occurrences, 0), "replace_all_occurrences", 23, "Queries the user for two strings, and replaces all occurrences of the first string with the second string in all open buffers.", 126, "C:\\4ed\\code\\power\\4coder_experiments.cpp", 44, 773 },
{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.", 150, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 880 },
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 851 },
{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 869 },
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1213 },
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1027 },
{ PROC_LINKS(scope_absorb_down, 0), "scope_absorb_down", 17, "If a scope is currently selected, and a statement or block statement is present below the current scope, the statement is moved into the scope.", 143, "C:\\4ed\\code\\4coder_scope_commands.cpp", 40, 751 },
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 844 },
{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 858 },
{ PROC_LINKS(seek_alphanumeric_left, 0), "seek_alphanumeric_left", 22, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 128 },
{ PROC_LINKS(seek_alphanumeric_or_camel_left, 0), "seek_alphanumeric_or_camel_left", 31, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 136 },
{ PROC_LINKS(seek_alphanumeric_or_camel_right, 0), "seek_alphanumeric_or_camel_right", 32, "Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 107, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 132 },
{ PROC_LINKS(seek_alphanumeric_right, 0), "seek_alphanumeric_right", 23, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 124 },
{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 361 },
{ PROC_LINKS(seek_beginning_of_textual_line, 0), "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 339 },
{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 374 },
{ PROC_LINKS(seek_end_of_textual_line, 0), "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 350 },
{ PROC_LINKS(seek_token_left, 0), "seek_token_left", 15, "Seek left for the next beginning of a token.", 44, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 112 },
{ PROC_LINKS(seek_token_right, 0), "seek_token_right", 16, "Seek right for the next end of a token.", 39, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 108 },
{ PROC_LINKS(seek_white_or_token_left, 0), "seek_white_or_token_left", 24, "Seek left for the next end of a token or boundary between whitespace and non-whitespace.", 88, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 120 },
{ PROC_LINKS(seek_white_or_token_right, 0), "seek_white_or_token_right", 25, "Seek right for the next end of a token or boundary between whitespace and non-whitespace.", 89, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 116 },
{ PROC_LINKS(seek_whitespace_down, 0), "seek_whitespace_down", 20, "Seeks the cursor down to the next blank line.", 45, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 328 },
{ PROC_LINKS(seek_whitespace_down_end_line, 0), "seek_whitespace_down_end_line", 29, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 394 },
{ PROC_LINKS(seek_whitespace_left, 0), "seek_whitespace_left", 20, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 104 },
{ PROC_LINKS(seek_whitespace_right, 0), "seek_whitespace_right", 21, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 100 },
{ PROC_LINKS(seek_whitespace_up, 0), "seek_whitespace_up", 18, "Seeks the cursor up to the next blank line.", 43, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 317 },
{ PROC_LINKS(seek_whitespace_up_end_line, 0), "seek_whitespace_up_end_line", 27, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 387 },
{ PROC_LINKS(select_all, 0), "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 304 },
{ PROC_LINKS(set_bindings_choose, 0), "set_bindings_choose", 19, "Remap keybindings using the 'choose' mapping rule.", 50, "C:\\4ed\\code\\4coder_remapping_commands.cpp", 44, 49 },
{ PROC_LINKS(set_bindings_default, 0), "set_bindings_default", 20, "Remap keybindings using the 'default' mapping rule.", 51, "C:\\4ed\\code\\4coder_remapping_commands.cpp", 44, 63 },
{ PROC_LINKS(set_bindings_mac_default, 0), "set_bindings_mac_default", 24, "Remap keybindings using the 'mac-default' mapping rule.", 55, "C:\\4ed\\code\\4coder_remapping_commands.cpp", 44, 77 },
{ PROC_LINKS(set_mark, 0), "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 100 },
{ PROC_LINKS(setup_new_project, 0), "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "C:\\4ed\\code\\4coder_project_commands.cpp", 42, 658 },
{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 548 },
{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 534 },
{ PROC_LINKS(snipe_token_or_word, 0), "snipe_token_or_word", 19, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 187 },
{ PROC_LINKS(snipe_token_or_word_right, 0), "snipe_token_or_word_right", 25, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 211 },
{ PROC_LINKS(suppress_mouse, 0), "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "C:\\4ed\\code\\4coder_default_framework.h", 41, 226 },
{ PROC_LINKS(swap_buffers_between_panels, 0), "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 731 },
{ PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 426 },
{ PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 406 },
{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 562 },
{ PROC_LINKS(toggle_fullscreen, 0), "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "C:\\4ed\\code\\4coder_default_framework.h", 41, 244 },
{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 571 },
{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "C:\\4ed\\code\\4coder_default_framework.h", 41, 238 },
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 638 },
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 627 },
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history.", 44, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 1165 },
{ PROC_LINKS(view_buffer_other_panel, 0), "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 721 },
{ PROC_LINKS(word_complete, 0), "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "C:\\4ed\\code\\4coder_search.cpp", 32, 863 },
{ PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "C:\\4ed\\code\\4coder_auto_indent.cpp", 37, 690 },
{ PROC_LINKS(write_block, 0), "write_block", 11, "At the cursor, insert a block comment.", 38, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 584 },
{ PROC_LINKS(write_character, 0), "write_character", 15, "Inserts whatever character was used to trigger this command.", 60, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 47 },
{ PROC_LINKS(write_explicit_enum_flags, 0), "write_explicit_enum_flags", 25, "If the cursor is found to be on the '{' of an enum definition, the values of the enum will be filled in to give each a unique power of 2 value, starting from 1. Existing values are overwritten.", 194, "C:\\4ed\\code\\power\\4coder_experiments.cpp", 44, 709 },
{ PROC_LINKS(write_explicit_enum_values, 0), "write_explicit_enum_values", 26, "If the cursor is found to be on the '{' of an enum definition, the values of the enum will be filled in sequentially starting from zero. Existing values are overwritten.", 170, "C:\\4ed\\code\\power\\4coder_experiments.cpp", 44, 703 },
{ PROC_LINKS(write_hack, 0), "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 572 },
{ PROC_LINKS(write_note, 0), "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 578 },
{ PROC_LINKS(write_todo, 0), "write_todo", 10, "At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.", 99, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 566 },
{ PROC_LINKS(write_underscore, 0), "write_underscore", 16, "Inserts an underscore.", 22, "C:\\4ed\\code\\4coder_base_commands.cpp", 39, 56 },
{ PROC_LINKS(write_zero_struct, 0), "write_zero_struct", 17, "At the cursor, insert a ' = {0};'.", 34, "C:\\4ed\\code\\4coder_default_include.cpp", 41, 590 },
{ PROC_LINKS(allow_mouse, 0), "allow_mouse", 11, "Shows the mouse and causes all mouse input to be processed normally.", 68, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 232 },
{ PROC_LINKS(auto_tab_line_at_cursor, 0), "auto_tab_line_at_cursor", 23, "Auto-indents the line on which the cursor sits.", 47, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 667 },
{ PROC_LINKS(auto_tab_range, 0), "auto_tab_range", 14, "Auto-indents the range between the cursor and the mark.", 55, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 678 },
{ PROC_LINKS(auto_tab_whole_file, 0), "auto_tab_whole_file", 19, "Audo-indents the entire current buffer.", 39, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 657 },
{ PROC_LINKS(backspace_char, 0), "backspace_char", 14, "Deletes the character to the left of the cursor.", 48, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 81 },
{ PROC_LINKS(backspace_word, 0), "backspace_word", 14, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 147 },
{ PROC_LINKS(basic_change_active_panel, 0), "basic_change_active_panel", 25, "Change the currently active panel, moving to the panel with the next highest view_id. Will not skipe the build panel if it is open.", 132, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 514 },
{ PROC_LINKS(build_in_build_panel, 0), "build_in_build_panel", 20, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*. Puts the *compilation* buffer in a panel at the footer of the current view.", 230, "C:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 203 },
{ PROC_LINKS(build_search, 0), "build_search", 12, "Looks for a build.bat, build.sh, or makefile in the current and parent directories. Runs the first that it finds and prints the output to *compilation*.", 153, "C:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 169 },
{ PROC_LINKS(center_view, 0), "center_view", 11, "Centers the view vertically on the line on which the cursor sits.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 136 },
{ PROC_LINKS(change_active_panel, 0), "change_active_panel", 19, "Change the currently active panel, moving to the panel with the next highest view_id.", 85, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 125 },
{ PROC_LINKS(change_active_panel_backwards, 0), "change_active_panel_backwards", 29, "Change the currently active panel, moving to the panel with the next lowest view_id.", 84, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 143 },
{ PROC_LINKS(change_to_build_panel, 0), "change_to_build_panel", 21, "If the special build panel is open, makes the build panel the active panel.", 75, "C:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 225 },
{ PROC_LINKS(clean_all_lines, 0), "clean_all_lines", 15, "Removes trailing whitespace from all lines in the current buffer.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 446 },
{ PROC_LINKS(click_set_cursor, 0), "click_set_cursor", 16, "Sets the cursor position to the mouse position.", 47, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 190 },
{ PROC_LINKS(click_set_mark, 0), "click_set_mark", 14, "Sets the mark position to the mouse position.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 203 },
{ PROC_LINKS(close_all_code, 0), "close_all_code", 14, "Closes any buffer with a filename ending with an extension configured to be recognized as a code file type.", 107, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 188 },
{ PROC_LINKS(close_build_panel, 0), "close_build_panel", 17, "If the special build panel is open, closes it.", 46, "C:\\work\\4ed\\code\\4coder_build_commands.cpp", 46, 219 },
{ PROC_LINKS(close_panel, 0), "close_panel", 11, "Closes the currently active panel if it is not the only panel open.", 67, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 522 },
{ PROC_LINKS(copy, 0), "copy", 4, "Copy the text in the range from the cursor to the mark onto the clipboard.", 74, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 52 },
{ PROC_LINKS(cursor_mark_swap, 0), "cursor_mark_swap", 16, "Swaps the position of the cursor and the mark.", 46, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 109 },
{ PROC_LINKS(cut, 0), "cut", 3, "Cut the text in the range from the cursor to the mark onto the clipboard.", 73, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 61 },
{ PROC_LINKS(decrease_face_size, 0), "decrease_face_size", 18, "Decrease the size of the face used by the current buffer.", 57, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 615 },
{ PROC_LINKS(decrease_line_wrap, 0), "decrease_line_wrap", 18, "Decrases the current buffer's width for line wrapping.", 54, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 592 },
{ PROC_LINKS(delete_char, 0), "delete_char", 11, "Deletes the character to the right of the cursor.", 49, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 63 },
{ PROC_LINKS(delete_current_scope, 0), "delete_current_scope", 20, "Deletes the braces surrounding the currently selected scope. Leaves the contents within the scope.", 99, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 492 },
{ PROC_LINKS(delete_file_query, 0), "delete_file_query", 17, "Deletes the file of the current buffer if 4coder has the appropriate access rights. Will ask the user for confirmation first.", 125, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1062 },
{ PROC_LINKS(delete_line, 0), "delete_line", 11, "Delete the line the on which the cursor sits.", 45, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 369 },
{ PROC_LINKS(delete_range, 0), "delete_range", 12, "Deletes the text in the range between the cursor and the mark.", 62, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 121 },
{ PROC_LINKS(delete_word, 0), "delete_word", 11, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 167 },
{ PROC_LINKS(duplicate_line, 0), "duplicate_line", 14, "Create a copy of the line on which the cursor sits.", 51, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 347 },
{ PROC_LINKS(eol_dosify, 0), "eol_dosify", 10, "Puts the buffer in DOS line ending mode.", 40, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 645 },
{ PROC_LINKS(eol_nixify, 0), "eol_nixify", 10, "Puts the buffer in NIX line ending mode.", 40, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 653 },
{ PROC_LINKS(execute_any_cli, 0), "execute_any_cli", 15, "Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.", 133, "C:\\work\\4ed\\code\\4coder_system_command.cpp", 46, 30 },
{ PROC_LINKS(execute_arbitrary_command, 0), "execute_arbitrary_command", 25, "Execute a 'long form' command.", 30, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 750 },
{ PROC_LINKS(execute_previous_cli, 0), "execute_previous_cli", 20, "If the command execute_any_cli has already been used, this will execute a CLI reusing the most recent buffer name and command.", 126, "C:\\work\\4ed\\code\\4coder_system_command.cpp", 46, 14 },
{ PROC_LINKS(exit_4coder, 0), "exit_4coder", 11, "Attempts to close 4coder.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 661 },
{ PROC_LINKS(goto_first_jump_direct, 0), "goto_first_jump_direct", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 100 },
{ PROC_LINKS(goto_first_jump_same_panel_sticky, 0), "goto_first_jump_same_panel_sticky", 33, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer and views the buffer in the panel where the jump list was.", 153, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 562 },
{ PROC_LINKS(goto_first_jump_sticky, 0), "goto_first_jump_sticky", 22, "If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.", 95, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 544 },
{ PROC_LINKS(goto_jump_at_cursor_direct, 0), "goto_jump_at_cursor_direct", 26, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 24 },
{ PROC_LINKS(goto_jump_at_cursor_same_panel_direct, 0), "goto_jump_at_cursor_same_panel_direct", 37, "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..", 168, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 45 },
{ PROC_LINKS(goto_jump_at_cursor_same_panel_sticky, 0), "goto_jump_at_cursor_same_panel_sticky", 37, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in this view, losing the compilation output or jump list.", 167, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 388 },
{ PROC_LINKS(goto_jump_at_cursor_sticky, 0), "goto_jump_at_cursor_sticky", 26, "If the cursor is found to be on a jump location, parses the jump location and brings up the file and position in another view and changes the active panel to the view containing the jump.", 187, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 360 },
{ PROC_LINKS(goto_line, 0), "goto_line", 9, "Queries the user for a number, and jumps the cursor to the corresponding line.", 78, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 671 },
{ PROC_LINKS(goto_next_jump_direct, 0), "goto_next_jump_direct", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 64 },
{ PROC_LINKS(goto_next_jump_no_skips_direct, 0), "goto_next_jump_no_skips_direct", 30, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 82 },
{ PROC_LINKS(goto_next_jump_no_skips_sticky, 0), "goto_next_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, and does not skip sub jump locations.", 132, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 513 },
{ PROC_LINKS(goto_next_jump_sticky, 0), "goto_next_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.", 123, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 483 },
{ PROC_LINKS(goto_prev_jump_direct, 0), "goto_prev_jump_direct", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 73 },
{ PROC_LINKS(goto_prev_jump_no_skips_direct, 0), "goto_prev_jump_no_skips_direct", 30, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 91 },
{ PROC_LINKS(goto_prev_jump_no_skips_sticky, 0), "goto_prev_jump_no_skips_sticky", 30, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, and does not skip sub jump locations.", 136, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 529 },
{ PROC_LINKS(goto_prev_jump_sticky, 0), "goto_prev_jump_sticky", 21, "If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.", 127, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 499 },
{ PROC_LINKS(hide_filebar, 0), "hide_filebar", 12, "Sets the current view to hide it's filebar.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 555 },
{ PROC_LINKS(hide_scrollbar, 0), "hide_scrollbar", 14, "Sets the current view to hide it's scrollbar.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 541 },
{ PROC_LINKS(highlight_next_scope_absolute, 0), "highlight_next_scope_absolute", 29, "Finds the first scope started by '{' after the cursor and puts the cursor and mark on the '{' and '}'.", 102, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 368 },
{ PROC_LINKS(highlight_prev_scope_absolute, 0), "highlight_prev_scope_absolute", 29, "Finds the first scope started by '{' before the cursor and puts the cursor and mark on the '{' and '}'.", 103, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 387 },
{ PROC_LINKS(highlight_surrounding_scope, 0), "highlight_surrounding_scope", 27, "Finds the scope enclosed by '{' '}' surrounding the cursor and puts the cursor and mark on the '{' and '}'.", 107, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 346 },
{ PROC_LINKS(if0_off, 0), "if0_off", 7, "Surround the range between the cursor and mark with an '#if 0' and an '#endif'", 78, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 537 },
{ PROC_LINKS(increase_face_size, 0), "increase_face_size", 18, "Increase the size of the face used by the current buffer.", 57, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 603 },
{ PROC_LINKS(increase_line_wrap, 0), "increase_line_wrap", 18, "Increases the current buffer's width for line wrapping.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 581 },
{ PROC_LINKS(interactive_kill_buffer, 0), "interactive_kill_buffer", 23, "Interactively kill an open buffer.", 34, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1201 },
{ PROC_LINKS(interactive_new, 0), "interactive_new", 15, "Interactively creates a new file.", 33, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1177 },
{ PROC_LINKS(interactive_open, 0), "interactive_open", 16, "Interactively opens a file.", 27, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1183 },
{ PROC_LINKS(interactive_open_or_new, 0), "interactive_open_or_new", 23, "Interactively opens or creates a new file.", 42, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1189 },
{ PROC_LINKS(interactive_switch_buffer, 0), "interactive_switch_buffer", 25, "Interactively switch to an open buffer.", 39, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1195 },
{ PROC_LINKS(kill_buffer, 0), "kill_buffer", 11, "Kills the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1219 },
{ PROC_LINKS(kill_rect, 0), "kill_rect", 9, "Delete characters in a rectangular region. Range testing is done by unwrapped-xy coordinates.", 93, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 31 },
{ PROC_LINKS(left_adjust_view, 0), "left_adjust_view", 16, "Sets the left size of the view near the x position of the cursor.", 65, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 151 },
{ PROC_LINKS(list_all_functions_current_buffer, 0), "list_all_functions_current_buffer", 33, "Creates a jump list of lines of the current buffer that appear to define or declare functions.", 94, "C:\\work\\4ed\\code\\4coder_function_list.cpp", 45, 348 },
{ PROC_LINKS(list_all_locations, 0), "list_all_locations", 18, "Queries the user for a string and lists all exact case-sensitive matches found in all open buffers.", 99, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 702 },
{ PROC_LINKS(list_all_locations_case_insensitive, 0), "list_all_locations_case_insensitive", 35, "Queries the user for a string and lists all exact case-insensitive matches found in all open buffers.", 101, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 722 },
{ PROC_LINKS(list_all_locations_of_identifier, 0), "list_all_locations_of_identifier", 32, "Reads a token or word under the cursor and lists all exact case-sensitive mathces in all open buffers.", 102, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 786 },
{ PROC_LINKS(list_all_locations_of_identifier_case_insensitive, 0), "list_all_locations_of_identifier_case_insensitive", 49, "Reads a token or word under the cursor and lists all exact case-insensitive mathces in all open buffers.", 104, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 792 },
{ PROC_LINKS(list_all_locations_of_selection, 0), "list_all_locations_of_selection", 31, "Reads the string in the selected range and lists all exact case-sensitive mathces in all open buffers.", 102, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 834 },
{ PROC_LINKS(list_all_locations_of_selection_case_insensitive, 0), "list_all_locations_of_selection_case_insensitive", 48, "Reads the string in the selected range and lists all exact case-insensitive mathces in all open buffers.", 104, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 840 },
{ PROC_LINKS(list_all_locations_of_type_definition, 0), "list_all_locations_of_type_definition", 37, "Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.", 121, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 454 },
{ PROC_LINKS(list_all_locations_of_type_definition_of_identifier, 0), "list_all_locations_of_type_definition_of_identifier", 51, "Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.", 125, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 466 },
{ PROC_LINKS(list_all_substring_locations, 0), "list_all_substring_locations", 28, "Queries the user for a string and lists all case-sensitive substring matches found in all open buffers.", 103, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 712 },
{ PROC_LINKS(list_all_substring_locations_case_insensitive, 0), "list_all_substring_locations_case_insensitive", 45, "Queries the user for a string and lists all case-insensitive substring matches found in all open buffers.", 105, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 732 },
{ PROC_LINKS(load_project, 0), "load_project", 12, "Looks for a project.4coder file in the current directory and tries to load it. Looks in parent directories until a project file is found or there are no more parents.", 167, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 408 },
{ PROC_LINKS(make_directory_query, 0), "make_directory_query", 20, "Queries the user for a name and creates a new directory with the given name.", 76, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1130 },
{ PROC_LINKS(miblo_decrement_basic, 0), "miblo_decrement_basic", 21, "Decrement an integer under the cursor by one.", 45, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 119 },
{ PROC_LINKS(miblo_decrement_time_stamp, 0), "miblo_decrement_time_stamp", 26, "Decrement a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 392 },
{ PROC_LINKS(miblo_decrement_time_stamp_minute, 0), "miblo_decrement_time_stamp_minute", 33, "Decrement a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 404 },
{ PROC_LINKS(miblo_increment_basic, 0), "miblo_increment_basic", 21, "Increment an integer under the cursor by one.", 45, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 103 },
{ PROC_LINKS(miblo_increment_time_stamp, 0), "miblo_increment_time_stamp", 26, "Increment a time stamp under the cursor by one second. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 386 },
{ PROC_LINKS(miblo_increment_time_stamp_minute, 0), "miblo_increment_time_stamp_minute", 33, "Increment a time stamp under the cursor by one minute. (format [m]m:ss or h:mm:ss", 81, "C:\\work\\4ed\\code\\power\\4coder_miblo_numbers.cpp", 52, 398 },
{ PROC_LINKS(move_down, 0), "move_down", 9, "Moves the cursor down one line.", 31, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 233 },
{ PROC_LINKS(move_down_10, 0), "move_down_10", 12, "Moves the cursor down ten lines.", 32, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 245 },
{ PROC_LINKS(move_down_textual, 0), "move_down_textual", 17, "Moves down to the next line of actual text, regardless of line wrapping.", 72, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 318 },
{ PROC_LINKS(move_left, 0), "move_left", 9, "Moves the cursor one character to the left.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 286 },
{ PROC_LINKS(move_line_down, 0), "move_line_down", 14, "Swaps the line under the cursor with the line below it, and moves the cursor down with it.", 90, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 330 },
{ PROC_LINKS(move_line_up, 0), "move_line_up", 12, "Swaps the line under the cursor with the line above it, and moves the cursor up with it.", 88, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 271 },
{ PROC_LINKS(move_right, 0), "move_right", 10, "Moves the cursor one character to the right.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 295 },
{ PROC_LINKS(move_up, 0), "move_up", 7, "Moves the cursor up one line.", 29, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 227 },
{ PROC_LINKS(move_up_10, 0), "move_up_10", 10, "Moves the cursor up ten lines.", 30, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 239 },
{ PROC_LINKS(multi_line_edit, 0), "multi_line_edit", 15, "Begin multi-line mode. In multi-line mode characters are inserted at every line between the mark and cursor. All characters are inserted at the same character offset into the line. This mode uses line_char coordinates.", 221, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 122 },
{ PROC_LINKS(newline_or_goto_position_direct, 0), "newline_or_goto_position_direct", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 117 },
{ PROC_LINKS(newline_or_goto_position_same_panel_direct, 0), "newline_or_goto_position_same_panel_direct", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "C:\\work\\4ed\\code\\4coder_jump_direct.cpp", 43, 132 },
{ PROC_LINKS(newline_or_goto_position_same_panel_sticky, 0), "newline_or_goto_position_same_panel_sticky", 42, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor_same_panel.", 117, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 600 },
{ PROC_LINKS(newline_or_goto_position_sticky, 0), "newline_or_goto_position_sticky", 31, "If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.", 106, "C:\\work\\4ed\\code\\4coder_jump_sticky.cpp", 43, 585 },
{ PROC_LINKS(open_all_code, 0), "open_all_code", 13, "Open all code in the current directory. File types are determined by extensions. An extension is considered code based on the extensions specified in 4coder.config.", 164, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 165 },
{ PROC_LINKS(open_all_code_recursive, 0), "open_all_code_recursive", 23, "Works as open_all_code but also runs in all subdirectories.", 59, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 180 },
{ PROC_LINKS(open_color_tweaker, 0), "open_color_tweaker", 18, "Opens the 4coder colors and fonts selector menu.", 48, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1225 },
{ PROC_LINKS(open_debug, 0), "open_debug", 10, "Opens a debug view for internal use.", 36, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1231 },
{ PROC_LINKS(open_file_in_quotes, 0), "open_file_in_quotes", 19, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file.", 94, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 634 },
{ PROC_LINKS(open_in_other, 0), "open_in_other", 13, "Reads a filename from surrounding '\"' characters and attempts to open the corresponding file, displaying it in the other view.", 127, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 651 },
{ PROC_LINKS(open_long_braces, 0), "open_long_braces", 16, "At the cursor, insert a '{' and '}' separated by a blank line.", 62, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 513 },
{ PROC_LINKS(open_long_braces_break, 0), "open_long_braces_break", 22, "At the cursor, insert a '{' and '}break;' separated by a blank line.", 68, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 529 },
{ PROC_LINKS(open_long_braces_semicolon, 0), "open_long_braces_semicolon", 26, "At the cursor, insert a '{' and '};' separated by a blank line.", 63, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 521 },
{ PROC_LINKS(open_matching_file_cpp, 0), "open_matching_file_cpp", 22, "If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view.", 110, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 707 },
{ PROC_LINKS(open_panel_hsplit, 0), "open_panel_hsplit", 17, "Create a new panel by horizontally splitting the active panel.", 62, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 170 },
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 161 },
{ PROC_LINKS(page_down, 0), "page_down", 9, "Scrolls the view down one view height and moves the cursor down one view height.", 80, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 276 },
{ PROC_LINKS(page_up, 0), "page_up", 7, "Scrolls the view up one view height and moves the cursor up one view height.", 76, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 267 },
{ PROC_LINKS(paste, 0), "paste", 5, "At the cursor, insert the text at the top of the clipboard.", 59, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 70 },
{ PROC_LINKS(paste_and_indent, 0), "paste_and_indent", 16, "Paste from the top of clipboard and run auto-indent on the newly pasted text.", 77, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 391 },
{ PROC_LINKS(paste_next, 0), "paste_next", 10, "If the previous command was paste or paste_next, replaces the paste range with the next text down on the clipboard, otherwise operates as the paste command.", 156, "C:\\work\\4ed\\code\\4coder_clipboard.cpp", 41, 108 },
{ PROC_LINKS(paste_next_and_indent, 0), "paste_next_and_indent", 21, "Paste the next item on the clipboard and run auto-indent on the newly pasted text.", 82, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 398 },
{ PROC_LINKS(place_in_scope, 0), "place_in_scope", 14, "Wraps the code contained in the range between cursor and mark with a new curly brace scope.", 91, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 486 },
{ PROC_LINKS(project_fkey_command, 0), "project_fkey_command", 20, "Run an 'fkey command' configured in a project.4coder file. Determines the index of the 'fkey command' by which function key or numeric key was pressed to trigger the command.", 175, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 575 },
{ PROC_LINKS(project_go_to_root_directory, 0), "project_go_to_root_directory", 28, "Changes 4coder's hot directory to the root directory of the currently loaded project. With no loaded project nothing hapepns.", 125, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 601 },
{ PROC_LINKS(query_replace, 0), "query_replace", 13, "Queries the user for two strings, and incrementally replaces every occurence of the first string with the second string.", 120, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 983 },
{ PROC_LINKS(query_replace_identifier, 0), "query_replace_identifier", 24, "Queries the user for a string, and incrementally replace every occurence of the word or token found at the cursor with the specified string.", 140, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1004 },
{ PROC_LINKS(query_replace_selection, 0), "query_replace_selection", 23, "Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string.", 141, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 240 },
{ PROC_LINKS(redo, 0), "redo", 4, "Advances forewards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1171 },
{ PROC_LINKS(reload_current_project, 0), "reload_current_project", 22, "If a project file has already been loaded, reloads the same file. Useful for when the project configuration is changed.", 120, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 479 },
{ PROC_LINKS(remap_interactive, 0), "remap_interactive", 17, "Switch to a named key binding map.", 34, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 743 },
{ PROC_LINKS(rename_file_query, 0), "rename_file_query", 17, "Queries the user for a new name and renames the file of the current buffer, altering the buffer's name too.", 107, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1088 },
{ PROC_LINKS(rename_parameter, 0), "rename_parameter", 16, "If the cursor is found to be on the name of a function parameter in the signature of a function definition, all occurences within the scope of the function will be replaced with a new provided string.", 200, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 387 },
{ PROC_LINKS(reopen, 0), "reopen", 6, "Reopen the current buffer from the hard drive.", 46, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1207 },
{ PROC_LINKS(replace_all_occurrences, 0), "replace_all_occurrences", 23, "Queries the user for two strings, and replaces all occurrences of the first string with the second string in all open buffers.", 126, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 773 },
{ PROC_LINKS(replace_in_range, 0), "replace_in_range", 16, "Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.", 150, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 880 },
{ PROC_LINKS(reverse_search, 0), "reverse_search", 14, "Begins an incremental search up through the current buffer for a user specified string.", 87, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 851 },
{ PROC_LINKS(reverse_search_identifier, 0), "reverse_search_identifier", 25, "Begins an incremental search up through the current buffer for the word or token under the cursor.", 98, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 869 },
{ PROC_LINKS(save, 0), "save", 4, "Saves the current buffer.", 25, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1213 },
{ PROC_LINKS(save_all_dirty_buffers, 0), "save_all_dirty_buffers", 22, "Saves all buffers marked dirty (showing the '*' indicator).", 59, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1027 },
{ PROC_LINKS(scope_absorb_down, 0), "scope_absorb_down", 17, "If a scope is currently selected, and a statement or block statement is present below the current scope, the statement is moved into the scope.", 143, "C:\\work\\4ed\\code\\4coder_scope_commands.cpp", 46, 751 },
{ PROC_LINKS(search, 0), "search", 6, "Begins an incremental search down through the current buffer for a user specified string.", 89, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 844 },
{ PROC_LINKS(search_identifier, 0), "search_identifier", 17, "Begins an incremental search down through the current buffer for the word or token under the cursor.", 100, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 858 },
{ PROC_LINKS(seek_alphanumeric_left, 0), "seek_alphanumeric_left", 22, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 128 },
{ PROC_LINKS(seek_alphanumeric_or_camel_left, 0), "seek_alphanumeric_or_camel_left", 31, "Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 106, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 136 },
{ PROC_LINKS(seek_alphanumeric_or_camel_right, 0), "seek_alphanumeric_or_camel_right", 32, "Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters.", 107, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 132 },
{ PROC_LINKS(seek_alphanumeric_right, 0), "seek_alphanumeric_right", 23, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 124 },
{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 361 },
{ PROC_LINKS(seek_beginning_of_textual_line, 0), "seek_beginning_of_textual_line", 30, "Seeks the cursor to the beginning of the line across all text.", 62, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 339 },
{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 374 },
{ PROC_LINKS(seek_end_of_textual_line, 0), "seek_end_of_textual_line", 24, "Seeks the cursor to the end of the line across all text.", 56, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 350 },
{ PROC_LINKS(seek_token_left, 0), "seek_token_left", 15, "Seek left for the next beginning of a token.", 44, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 112 },
{ PROC_LINKS(seek_token_right, 0), "seek_token_right", 16, "Seek right for the next end of a token.", 39, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 108 },
{ PROC_LINKS(seek_white_or_token_left, 0), "seek_white_or_token_left", 24, "Seek left for the next end of a token or boundary between whitespace and non-whitespace.", 88, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 120 },
{ PROC_LINKS(seek_white_or_token_right, 0), "seek_white_or_token_right", 25, "Seek right for the next end of a token or boundary between whitespace and non-whitespace.", 89, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 116 },
{ PROC_LINKS(seek_whitespace_down, 0), "seek_whitespace_down", 20, "Seeks the cursor down to the next blank line.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 328 },
{ PROC_LINKS(seek_whitespace_down_end_line, 0), "seek_whitespace_down_end_line", 29, "Seeks the cursor down to the next blank line and places it at the end of the line.", 82, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 394 },
{ PROC_LINKS(seek_whitespace_left, 0), "seek_whitespace_left", 20, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 104 },
{ PROC_LINKS(seek_whitespace_right, 0), "seek_whitespace_right", 21, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 100 },
{ PROC_LINKS(seek_whitespace_up, 0), "seek_whitespace_up", 18, "Seeks the cursor up to the next blank line.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 317 },
{ PROC_LINKS(seek_whitespace_up_end_line, 0), "seek_whitespace_up_end_line", 27, "Seeks the cursor up to the next blank line and places it at the end of the line.", 80, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 387 },
{ PROC_LINKS(select_all, 0), "select_all", 10, "Puts the cursor at the top of the file, and the mark at the bottom of the file.", 79, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 304 },
{ PROC_LINKS(set_bindings_choose, 0), "set_bindings_choose", 19, "Remap keybindings using the 'choose' mapping rule.", 50, "C:\\work\\4ed\\code\\4coder_remapping_commands.cpp", 50, 49 },
{ PROC_LINKS(set_bindings_default, 0), "set_bindings_default", 20, "Remap keybindings using the 'default' mapping rule.", 51, "C:\\work\\4ed\\code\\4coder_remapping_commands.cpp", 50, 63 },
{ PROC_LINKS(set_bindings_mac_default, 0), "set_bindings_mac_default", 24, "Remap keybindings using the 'mac-default' mapping rule.", 55, "C:\\work\\4ed\\code\\4coder_remapping_commands.cpp", 50, 77 },
{ PROC_LINKS(set_mark, 0), "set_mark", 8, "Sets the mark to the current position of the cursor.", 52, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 100 },
{ PROC_LINKS(setup_new_project, 0), "setup_new_project", 17, "Queries the user for several configuration options and initializes a new 4coder project with build scripts for every OS.", 120, "C:\\work\\4ed\\code\\4coder_project_commands.cpp", 48, 658 },
{ PROC_LINKS(show_filebar, 0), "show_filebar", 12, "Sets the current view to show it's filebar.", 43, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 548 },
{ PROC_LINKS(show_scrollbar, 0), "show_scrollbar", 14, "Sets the current view to show it's scrollbar.", 45, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 534 },
{ PROC_LINKS(snipe_token_or_word, 0), "snipe_token_or_word", 19, "Delete a single, whole token on or to the left of the cursor and post it to the clipboard.", 90, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 187 },
{ PROC_LINKS(snipe_token_or_word_right, 0), "snipe_token_or_word_right", 25, "Delete a single, whole token on or to the right of the cursor and post it to the clipboard.", 91, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 211 },
{ PROC_LINKS(suppress_mouse, 0), "suppress_mouse", 14, "Hides the mouse and causes all mosue input (clicks, position, wheel) to be ignored.", 83, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 226 },
{ PROC_LINKS(swap_buffers_between_panels, 0), "swap_buffers_between_panels", 27, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 731 },
{ PROC_LINKS(to_lowercase, 0), "to_lowercase", 12, "Converts all ascii text in the range between the cursor and the mark to lowercase.", 82, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 426 },
{ PROC_LINKS(to_uppercase, 0), "to_uppercase", 12, "Converts all ascii text in the range between the cursor and the mark to uppercase.", 82, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 406 },
{ PROC_LINKS(toggle_filebar, 0), "toggle_filebar", 14, "Toggles the visibility status of the current view's filebar.", 60, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 562 },
{ PROC_LINKS(toggle_fullscreen, 0), "toggle_fullscreen", 17, "Toggle fullscreen mode on or off. The change(s) do not take effect until the next frame.", 89, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 244 },
{ PROC_LINKS(toggle_line_wrap, 0), "toggle_line_wrap", 16, "Toggles the current buffer's line wrapping status.", 50, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 571 },
{ PROC_LINKS(toggle_mouse, 0), "toggle_mouse", 12, "Toggles the mouse suppression mode, see suppress_mouse and allow_mouse.", 71, "C:\\work\\4ed\\code\\4coder_default_framework.h", 47, 238 },
{ PROC_LINKS(toggle_show_whitespace, 0), "toggle_show_whitespace", 22, "Toggles the current buffer's whitespace visibility status.", 58, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 638 },
{ PROC_LINKS(toggle_virtual_whitespace, 0), "toggle_virtual_whitespace", 25, "Toggles the current buffer's virtual whitespace status.", 55, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 627 },
{ PROC_LINKS(undo, 0), "undo", 4, "Advances backwards through the undo history.", 44, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 1165 },
{ PROC_LINKS(view_buffer_other_panel, 0), "view_buffer_other_panel", 23, "Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.", 104, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 721 },
{ PROC_LINKS(word_complete, 0), "word_complete", 13, "Iteratively tries completing the word to the left of the cursor with other words in open buffers that have the same prefix string.", 130, "C:\\work\\4ed\\code\\4coder_search.cpp", 38, 863 },
{ PROC_LINKS(write_and_auto_tab, 0), "write_and_auto_tab", 18, "Inserts a character and auto-indents the line on which the cursor sits.", 71, "C:\\work\\4ed\\code\\4coder_auto_indent.cpp", 43, 690 },
{ PROC_LINKS(write_block, 0), "write_block", 11, "At the cursor, insert a block comment.", 38, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 584 },
{ PROC_LINKS(write_character, 0), "write_character", 15, "Inserts whatever character was used to trigger this command.", 60, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 47 },
{ PROC_LINKS(write_explicit_enum_flags, 0), "write_explicit_enum_flags", 25, "If the cursor is found to be on the '{' of an enum definition, the values of the enum will be filled in to give each a unique power of 2 value, starting from 1. Existing values are overwritten.", 194, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 709 },
{ PROC_LINKS(write_explicit_enum_values, 0), "write_explicit_enum_values", 26, "If the cursor is found to be on the '{' of an enum definition, the values of the enum will be filled in sequentially starting from zero. Existing values are overwritten.", 170, "C:\\work\\4ed\\code\\power\\4coder_experiments.cpp", 50, 703 },
{ PROC_LINKS(write_hack, 0), "write_hack", 10, "At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder.", 99, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 572 },
{ PROC_LINKS(write_note, 0), "write_note", 10, "At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.", 99, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 578 },
{ PROC_LINKS(write_todo, 0), "write_todo", 10, "At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.", 99, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 566 },
{ PROC_LINKS(write_underscore, 0), "write_underscore", 16, "Inserts an underscore.", 22, "C:\\work\\4ed\\code\\4coder_base_commands.cpp", 45, 56 },
{ PROC_LINKS(write_zero_struct, 0), "write_zero_struct", 17, "At the cursor, insert a ' = {0};'.", 34, "C:\\work\\4ed\\code\\4coder_default_include.cpp", 47, 590 },
};
static int32_t fcoder_metacmd_ID_allow_mouse = 0;
static int32_t fcoder_metacmd_ID_auto_tab_line_at_cursor = 1;

View File

@ -8,447 +8,18 @@ TYPE: 'code-preprocessor'
#define COMMAND_METADATA_OUT "4coder_generated/command_metadata.h"
#include "4coder_os_comp_cracking.h"
#include "4coder_file.h"
#include "4coder_lib/4coder_mem.h"
#define FSTRING_IMPLEMENTATION
#include "4coder_lib/4coder_string.h"
#include "4coder_lib/4cpp_lexer.h"
#include <stdio.h>
#include <stdlib.h>
#include <stdint.h>
#define str_to_l_c(s) ((s).size), ((s).str)
#define str_to_c_l(s) ((s).str), ((s).size)
#include <stdlib.h>
#include <stdio.h>
#include <stdint.h>
typedef int32_t bool32;
#if defined(IS_WINDOWS)
//// WINDOWS BEGIN ////
#define UNICODE
#include <Windows.h>
typedef TCHAR Filename_Character;
#define SLASH '\\'
//// WINDOWS END ////
#elif defined(IS_LINUX) || defined(IS_MAC)
//// UNIX BEGIN ////
#include <sys/types.h>
#include <sys/stat.h>
#include <unistd.h>
#include <dirent.h>
typedef char Filename_Character;
#define SLASH '/'
//// UNIX END ////
#else
# error metdata generator not supported on this platform
#endif
struct File_Info{
Filename_Character *name;
int32_t len;
bool32 is_folder;
};
struct File_List{
File_Info *info;
int32_t count;
int32_t final_length;
Filename_Character final_name[4096];
};
static File_List
get_file_list(Partition *part, Filename_Character *dir);
static Filename_Character*
encode(Partition *part, char *str){
int32_t size = 0;
for (;str[size]!=0;++size);
Filename_Character *out = push_array(part, Filename_Character, size + 1);
push_align(part, 8);
if (out == 0){
fprintf(stdout, "fatal error: ran out of memory encoding string to filename\n");
exit(1);
}
int32_t j = 0;
for (int32_t i = 0; i <= size; ++i){
if (str[i] != '"'){
out[j++] = str[i];
}
}
return(out);
}
static char*
unencode(Partition *part, Filename_Character *str, int32_t len){
Temp_Memory temp = begin_temp_memory(part);
char *out = push_array(part, char, len + 1);
push_align(part, 8);
if (out == 0){
fprintf(stdout, "fatal error: ran out of memory unencoding string to filename\n");
exit(1);
}
for (int32_t i = 0; i <= len; ++i){
if (str[i] <= 127){
out[i] = (char)str[i];
}
else{
out = 0;
end_temp_memory(temp);
break;
}
}
return(out);
}
static bool32
is_code_file(Filename_Character *name, int32_t len){
bool32 is_code = false;
if (len >= 5){
Filename_Character *ext = &name[len - 4];
if (ext[0] == '.' && ext[1] == 'c' && ext[2] == 'p' && ext[3] == 'p'){
is_code = true;
}
else if (ext[0] == '.' && ext[1] == 'h' && ext[2] == 'p' && ext[3] == 'p'){
is_code = true;
}
}
if (len >= 4){
Filename_Character *ext = &name[len - 3];
if (ext[0] == '.' && ext[1] == 'c' && ext[2] == 'c'){
is_code = true;
}
}
if (len >= 3){
Filename_Character *ext = &name[len - 2];
if (ext[0] == '.' && ext[1] == 'h'){
is_code = true;
}
else if (ext[0] == '.' && ext[1] == 'c'){
is_code = true;
}
}
return(is_code);
}
#if defined(IS_WINDOWS)
//// WINDOWS BEGIN ////
static File_List
get_file_list(Partition *part, Filename_Character *dir){
if (part == 0){
fprintf(stdout, "fatal error: NULL part passed to %s\n", __FUNCTION__);
exit(1);
}
if (dir == 0){
fprintf(stdout, "fatal error: NULL dir passed to %s\n", __FUNCTION__);
exit(1);
}
HANDLE dir_handle =
CreateFile(dir,
FILE_LIST_DIRECTORY,
FILE_SHARE_READ | FILE_SHARE_WRITE | FILE_SHARE_DELETE,
0,
OPEN_EXISTING,
FILE_FLAG_BACKUP_SEMANTICS | FILE_FLAG_OVERLAPPED,
0);
if (dir_handle == INVALID_HANDLE_VALUE){
fprintf(stdout, "fatal error: could not open directory handle\n");
exit(1);
}
Filename_Character final_name[4096];
DWORD final_length = GetFinalPathNameByHandle(dir_handle, final_name, sizeof(final_name), 0);
if (final_length > sizeof(final_name)){
fprintf(stdout, "fatal error: path name too long for local buffer\n");
exit(1);
}
CloseHandle(dir_handle);
final_length -= 4;
memmove(final_name, final_name + 4, final_length*sizeof(*final_name));
final_name[final_length] = '\\';
final_name[final_length + 1] = '*';
final_name[final_length + 2] = 0;
WIN32_FIND_DATA find_data = {0};
HANDLE search = FindFirstFile(final_name, &find_data);
if (search == INVALID_HANDLE_VALUE){
fprintf(stdout, "fatal error: could not begin a file search\n");
exit(1);
}
int32_t character_count = 0;
int32_t file_count = 0;
BOOL more_files = true;
do{
Filename_Character *name = &find_data.cFileName[0];
int32_t size = 0;
for(;name[size];++size);
uint32_t attribs = find_data.dwFileAttributes;
bool32 is_folder = ((attribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
bool32 is_hidden = ((attribs & FILE_ATTRIBUTE_HIDDEN) != 0);
if (!is_hidden){
if (name[0] != '.' && (is_folder || is_code_file(name, size))){
++file_count;
character_count += size + 1;
}
}
more_files = FindNextFile(search, &find_data);
}while(more_files);
FindClose(search);
File_List list = {0};
Temp_Memory part_reset = begin_temp_memory(part);
int32_t rounded_char_size = (character_count*sizeof(Filename_Character) + 7)&(~7);
int32_t memsize = rounded_char_size + file_count*sizeof(File_Info);
void *mem = push_array(part, uint8_t, memsize);
if (mem == 0){
fprintf(stdout, "fatal error: not enough memory on the partition for a file list.\n");
exit(1);
}
Filename_Character *char_ptr = (Filename_Character*)mem;
File_Info *info_ptr = (File_Info*)((uint8_t*)mem + rounded_char_size);
Filename_Character *char_ptr_end = (Filename_Character*)info_ptr;
File_Info *info_ptr_end = info_ptr + file_count;
File_Info *info_ptr_base = info_ptr;
search = FindFirstFile(final_name, &find_data);
if (search == INVALID_HANDLE_VALUE){
fprintf(stdout, "fatal error: could not restart a file search\n");
exit(1);
}
int32_t adjusted_file_count = 0;
more_files = true;
do{
Filename_Character *name = &find_data.cFileName[0];
int32_t size = 0;
for(;name[size]!=0;++size);
uint32_t attribs = find_data.dwFileAttributes;
bool32 is_folder = ((attribs & FILE_ATTRIBUTE_DIRECTORY) != 0);
bool32 is_hidden = ((attribs & FILE_ATTRIBUTE_HIDDEN) != 0);
if (!is_hidden){
if (name[0] != '.' && (is_folder || is_code_file(name, size))){
if (info_ptr + 1 > info_ptr_end || char_ptr + size + 1 > char_ptr_end){
memset(&list, 0, sizeof(list));
end_temp_memory(part_reset);
FindClose(search);
return(list);
}
info_ptr->name = char_ptr;
info_ptr->len = size;
info_ptr->is_folder = is_folder;
memmove(char_ptr, name, size*sizeof(*name));
char_ptr[size] = 0;
char_ptr += size + 1;
++info_ptr;
++adjusted_file_count;
}
}
more_files = FindNextFile(search, &find_data);
}while(more_files);
FindClose(search);
list.info = info_ptr_base;
list.count = adjusted_file_count;
list.final_length = final_length;
memcpy(list.final_name, final_name, list.final_length*sizeof(*final_name));
list.final_name[list.final_length] = 0;
return(list);
}
//// WINDOWS END ////
#elif defined(IS_LINUX) || defined(IS_MAC)
//// UNIX BEGIN ////
static File_List
get_file_list(Partition *part, Filename_Character *directory){
if (part == 0){
fprintf(stdout, "fatal error: NULL part passed to %s\n", __FUNCTION__);
exit(1);
}
if (directory == 0){
fprintf(stdout, "fatal error: NULL dir passed to %s\n", __FUNCTION__);
exit(1);
}
DIR *dir_handle = opendir(directory);
if (dir_handle == 0){
fprintf(stdout, "fatal error: could not open directory handle\n");
if (sizeof(*directory) == 2){
fprintf(stdout, "%ls\n", (wchar_t*)directory);
}
else{
fprintf(stdout, "%s\n", (char*)directory);
}
exit(1);
}
Filename_Character final_name[4096];
int32_t final_length = str_size(directory);
if (final_length + 1 > sizeof(final_name)){
fprintf(stdout, "fatal error: path name too long for local buffer\n");
exit(1);
}
memcpy(final_name, directory, final_length + 1);
int32_t character_count = 0;
int32_t file_count = 0;
for (struct dirent *entry = readdir(dir_handle);
entry != 0;
entry = readdir(dir_handle)){
Filename_Character *name = entry->d_name;
int32_t size = 0;
for(;name[size];++size);
bool32 is_folder = false;
if (entry->d_type == DT_LNK){
struct stat st;
if (stat(entry->d_name, &st) != -1){
is_folder = S_ISDIR(st.st_mode);
}
}
else{
is_folder = (entry->d_type == DT_DIR);
}
if (name[0] != '.' && (is_folder || is_code_file(name, size))){
++file_count;
character_count += size + 1;
}
}
File_List list = {0};
Temp_Memory part_reset = begin_temp_memory(part);
int32_t rounded_char_size = (character_count*sizeof(Filename_Character) + 7)&(~7);
int32_t memsize = rounded_char_size + file_count*sizeof(File_Info);
void *mem = push_array(part, uint8_t, memsize);
if (mem == 0){
fprintf(stdout, "fatal error: not enough memory on the partition for a file list.\n");
exit(1);
}
Filename_Character *char_ptr = (Filename_Character*)mem;
File_Info *info_ptr = (File_Info*)((uint8_t*)mem + rounded_char_size);
Filename_Character *char_ptr_end = (Filename_Character*)info_ptr;
File_Info *info_ptr_end = info_ptr + file_count;
File_Info *info_ptr_base = info_ptr;
rewinddir(dir_handle);
int32_t adjusted_file_count = 0;
for (struct dirent *entry = readdir(dir_handle);
entry != 0;
entry = readdir(dir_handle)){
Filename_Character *name = entry->d_name;
int32_t size = 0;
for(;name[size];++size);
bool32 is_folder = false;
if (entry->d_type == DT_LNK){
struct stat st;
if (stat(entry->d_name, &st) != -1){
is_folder = S_ISDIR(st.st_mode);
}
}
else{
is_folder = (entry->d_type == DT_DIR);
}
if (name[0] != '.' && (is_folder || is_code_file(name, size))){
if (info_ptr + 1 > info_ptr_end || char_ptr + size + 1 > char_ptr_end){
memset(&list, 0, sizeof(list));
end_temp_memory(part_reset);
closedir(dir_handle);
return(list);
}
info_ptr->name = char_ptr;
info_ptr->len = size;
info_ptr->is_folder = is_folder;
memmove(char_ptr, name, size*sizeof(*name));
char_ptr[size] = 0;
char_ptr += size + 1;
++info_ptr;
++adjusted_file_count;
}
}
closedir(dir_handle);
list.info = info_ptr_base;
list.count = adjusted_file_count;
list.final_length = final_length;
memcpy(list.final_name, final_name, list.final_length*sizeof(*final_name));
list.final_name[list.final_length] = 0;
return(list);
}
//// UNIX END ////
#else
# error metdata generator not supported on this platform
#endif
static String
file_dump(Partition *part, char *name){
String text = {0};
FILE *file = fopen(name, "rb");
if (file != 0){
fseek(file, 0, SEEK_END);
text.size = ftell(file);
fseek(file, 0, SEEK_SET);
text.memory_size = text.size + 1;
text.str = push_array(part, char, text.memory_size);
if (text.str == 0){
fprintf(stdout, "fatal error: not enough memory in partition for file dumping");
exit(1);
}
fread(text.str, 1, text.size, file);
terminate_with_null(&text);
fclose(file);
}
return(text);
}
///////////////////////////////
struct Line_Column_Coordinates{
@ -1063,9 +634,9 @@ parse_file(Partition *part, Meta_Command_Entry_Arrays *entry_arrays, Filename_Ch
static void
parse_files_in_directory(Partition *part, Meta_Command_Entry_Arrays *entry_arrays, Filename_Character *root, bool32 recursive){
File_List list = get_file_list(part, root);
Cross_Platform_File_List list = get_file_list(part, root, filter_is_code_file);
for (int32_t i = 0; i < list.count; ++i){
File_Info *info = &list.info[i];
Cross_Platform_File_Info *info = &list.info[i];
if (info->is_folder && match(make_string(info->name, info->len), "4coder_generated")){
continue;

45
4ed.cpp
View File

@ -1123,7 +1123,8 @@ enum Command_Line_Action{
CLAct_FontUseHinting,
CLAct_LogStdout,
CLAct_LogFile,
CLAct_Count
CLAct_TestInput,
CLAct_COUNT,
};
enum Command_Line_Mode{
@ -1179,6 +1180,8 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
case 'l': action = CLAct_LogStdout; --i; break;
case 'L': action = CLAct_LogFile; --i; break;
case 'T': action = CLAct_TestInput; --i; break;
}
}
else if (arg[0] != 0){
@ -1285,6 +1288,12 @@ init_command_line_settings(App_Settings *settings, Plat_Settings *plat_settings,
plat_settings->use_log = LogTo_LogFile;
action = CLAct_Nothing;
}break;
case CLAct_TestInput:
{
plat_settings->use_test_input = true;
action = CLAct_Nothing;
}break;
}
}break;
@ -1499,12 +1508,13 @@ App_Init_Sig(app_init){
}
App_Step_Sig(app_step){
Application_Step_Result app_result = *app_result_;
app_result.animating = 0;
App_Vars *vars = (App_Vars*)memory->vars_memory;
Models *models = &vars->models;
Application_Step_Result app_result = {0};
app_result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr;
// NOTE(allen): OS clipboard event handling
String clipboard = input->clipboard;
if (clipboard.str){
@ -1772,7 +1782,7 @@ App_Step_Sig(app_step){
}
// NOTE(allen): respond if the user is trying to kill the application
if (app_result.trying_to_kill){
if (input->trying_to_kill){
b32 there_is_unsaved = 0;
app_result.animating = 1;
@ -2044,16 +2054,11 @@ App_Step_Sig(app_step){
}
b32 file_scroll = false;
GUI_Scroll_Vars scroll_zero = {0};
GUI_Scroll_Vars *scroll_vars = &view->gui_scroll;
if (view->showing_ui == VUI_None){
if (view->file_data.file){
scroll_vars = &view->edit_pos->scroll;
file_scroll = true;
}
else{
scroll_vars = &scroll_zero;
}
Assert(view->file_data.file != 0);
scroll_vars = &view->edit_pos->scroll;
file_scroll = true;
}
i32 max_y = 0;
@ -2387,16 +2392,11 @@ App_Step_Sig(app_step){
draw_rectangle(target, full, back_color);
b32 file_scroll = false;
GUI_Scroll_Vars scroll_zero = {0};
GUI_Scroll_Vars *scroll_vars = &view->gui_scroll;
if (view->showing_ui == VUI_None){
if (view->file_data.file){
scroll_vars = &view->edit_pos->scroll;
file_scroll = true;
}
else{
scroll_vars = &scroll_zero;
}
Assert(view->file_data.file != 0);
scroll_vars = &view->edit_pos->scroll;
file_scroll = true;
}
do_render_file_view(system, view, models, scroll_vars, active_view, panel->inner, active, target, &dead_input);
@ -2449,9 +2449,8 @@ App_Step_Sig(app_step){
app_result.lctrl_lalt_is_altgr = models->settings.lctrl_lalt_is_altgr;
app_result.perform_kill = !models->keep_playing;
*app_result_ = app_result;
// end-of-app_step
return(app_result);
}
extern "C" App_Get_Functions_Sig(app_get_functions){

9
4ed.h
View File

@ -60,6 +60,7 @@ struct Plat_Settings{
b8 fullscreen_window;
u8 use_log;
b8 use_test_input;
i32 window_w, window_h;
i32 window_x, window_y;
@ -91,7 +92,6 @@ typedef App_Init_Sig(App_Init);
struct Application_Step_Result{
Application_Mouse_Cursor mouse_cursor_type;
b32 lctrl_lalt_is_altgr;
b32 trying_to_kill;
b32 perform_kill;
b32 animating;
b32 has_new_title;
@ -104,14 +104,15 @@ struct Application_Step_Input{
Key_Input_Data keys;
Mouse_State mouse;
String clipboard;
b32 trying_to_kill;
u32 debug_number;
};
#define App_Step_Sig(name) void \
#define App_Step_Sig(name) Application_Step_Result \
name(System_Functions *system, \
Render_Target *target, \
Application_Memory *memory, \
Application_Step_Input *input, \
Application_Step_Result *app_result_)
Application_Step_Input *input)
typedef App_Step_Sig(App_Step);

View File

@ -2755,13 +2755,10 @@ view_set_relative_scrolling(View *view, Relative_Scrolling scrolling){
inline i32_Rect
view_widget_rect(View *view, i32 line_height){
Assert(view->file_data.file);
Panel *panel = view->panel;
i32_Rect result = panel->inner;
if (view->file_data.file){
result.y0 = result.y0 + line_height + 2;
}
result.y0 = result.y0 + line_height + 2;
return(result);
}
@ -3006,9 +3003,7 @@ file_edit_cursor_fix(System_Functions *system, Models *models, Editing_File *fil
}
}
// TODO(NAME): dump all the markers in the file and then read them back out.
// Make a plan for "right leaning" markers.
if (cursor_count > 0){
if (cursor_count > 0 || r_cursor_count > 0){
buffer_sort_cursors(cursors, cursor_count);
if (desc.is_batch){
buffer_batch_edit_update_cursors(cursors, cursor_count, desc.batch, desc.batch_size, false);
@ -4090,7 +4085,8 @@ internal b32
file_step(View *view, i32_Rect region, Input_Summary *user_input, b32 is_active, b32 *consumed_l){
b32 is_animating = false;
Editing_File *file = view->file_data.file;
if (file && !file->is_loading){
Assert(file != 0);
if (!file->is_loading){
if (file->state.paste_effect.seconds_down > 0.f){
file->state.paste_effect.seconds_down -= user_input->dt;
is_animating = true;
@ -4542,10 +4538,9 @@ step_file_view(System_Functions *system, View *view, Models *models, View *activ
GUI_Scroll_Vars scroll_zero = {0};
GUI_Scroll_Vars *scroll = &scroll_zero;
if (view->file_data.file){
Assert(view->edit_pos);
scroll = &view->edit_pos->scroll;
}
Assert(view->file_data.file != 0);
Assert(view->edit_pos != 0);
scroll = &view->edit_pos->scroll;
gui_begin_scrollable(target, scroll_context, *scroll,
delta, show_scrollbar);
@ -4584,15 +4579,15 @@ step_file_view(System_Functions *system, View *view, Models *models, View *activ
view->color_mode = CV_Mode_Adjusting;
}
if (view->file_data.file){
message = make_lit_string("Set Font");
id.id[0] = (u64)(&view->file_data.file->settings.font_id);
Assert(view->file_data.file != 0);
if (gui_do_button(target, id, message)){
view->color_mode = CV_Mode_Font;
}
message = make_lit_string("Set Font");
id.id[0] = (u64)(&view->file_data.file->settings.font_id);
if (gui_do_button(target, id, message)){
view->color_mode = CV_Mode_Font;
}
message = make_lit_string("Set Global Font");
id.id[0] = (u64)(&models->global_font_id);
@ -6464,6 +6459,8 @@ internal i32
do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Scroll_Vars *scroll, View *active, i32_Rect rect, b32 is_active, Render_Target *target, Input_Summary *user_input){
Editing_File *file = view->file_data.file;
Assert(file != 0);
i32 result = 0;
GUI_Session gui_session = {0};
@ -6474,8 +6471,6 @@ do_render_file_view(System_Functions *system, View *view, Models *models, GUI_Sc
f32 v = {0};
i32 max_y = view_compute_max_target_y(view);
Assert(file != 0);
Face_ID font_id = file->settings.font_id;
if (gui_target->push.pos > 0){
gui_session_init(&gui_session, gui_target, rect, view->line_height);

222
4ed_input_simulation.cpp Normal file
View File

@ -0,0 +1,222 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 02.03.2018
*
* Input simulation implementation
*
*/
// TOP
internal void
simulate_key(Application_Step_Input *input,
Key_Code keycode, Key_Code character, Key_Code character_no_caps_lock, i8 *modifiers){
Key_Input_Data *keys = &input->keys;
Assert(keys->count < ArrayCount(keys->keys));
Key_Event_Data *key = &keys->keys[keys->count++];
key->keycode = keycode;
key->character = character;
key->character_no_caps_lock = character_no_caps_lock;
memcpy(key->modifiers, modifiers, sizeof(key->modifiers));
}
internal void
simulate_key(Application_Step_Input *input,
Key_Code code, i8 *modifiers){
i32 size = 0;
char *keycode_name = global_key_name(code, &size);
if (keycode_name != 0){
simulate_key(input, code, 0, 0, modifiers);
}
else{
Key_Code no_caps = code;
if (modifiers[MDFR_CAPS_INDEX]){
if (no_caps >= 'a' && no_caps <= 'z'){
no_caps -= (u8)('a' - 'A');
}
else if (no_caps >= 'A' && no_caps <= 'Z'){
no_caps += (u8)('a' - 'A');
}
}
simulate_key(input, code, code, no_caps, modifiers);
}
}
internal void
simulate_key(Application_Step_Input *input,
Key_Code code, u8 modifiers){
i8 mod_array[MDFR_INDEX_COUNT];
memset(mod_array, 0, sizeof(mod_array));
if (modifiers & MDFR_CTRL){
mod_array[MDFR_CONTROL_INDEX] = 1;
}
if (modifiers & MDFR_ALT){
mod_array[MDFR_ALT_INDEX] = 1;
}
if (modifiers & MDFR_CMND){
mod_array[MDFR_COMMAND_INDEX] = 1;
}
if (modifiers & MDFR_SHIFT){
mod_array[MDFR_SHIFT_INDEX] = 1;
}
simulate_key(input, code, mod_array);
}
internal void
simulate_mouse_state(Application_Step_Input *input, Mouse_State state){
input->mouse = state;
}
internal void
simulate_mouse_update(Application_Step_Input *input, Mouse_State prev_mouse){
input->mouse = prev_mouse;
input->mouse.press_l = false;
input->mouse.press_r = false;
input->mouse.release_l = false;
input->mouse.release_r = false;
input->mouse.wheel = 0;
}
internal void
simulate_mouse_xy(Application_Step_Input *input, i32 x, i32 y, i32 width, i32 height){
input->mouse.x = x;
input->mouse.y = y;
input->mouse.out_of_window = (x < 0 || y < 0 || x > width || y > height);
}
internal void
simulate_mouse_left_press(Application_Step_Input *input){
input->mouse.l = true;
input->mouse.press_l = true;
}
internal void
simulate_mouse_left_release(Application_Step_Input *input){
input->mouse.l = false;
input->mouse.release_l = true;
}
internal void
simulate_mouse_right_press(Application_Step_Input *input){
input->mouse.r = true;
input->mouse.press_r = true;
}
internal void
simulate_mouse_right_release(Application_Step_Input *input){
input->mouse.r = false;
input->mouse.release_r = true;
}
internal void
simulate_mouse_wheel(Application_Step_Input *input, i32 wheel){
input->mouse.wheel = wheel;
}
internal void
simulate_exit(Application_Step_Input *input){
input->trying_to_kill = true;
}
////////////////
internal void
simulation_init(Input_Simulation_Controls *sim_controls){
memset(sim_controls, 0, sizeof(*sim_controls));
sim_controls->enforce_regular_mouse = true;
}
internal void
simulation_step_begin(Input_Simulation_Controls *sim_controls,
Application_Step_Input *input,
b32 first_step, f32 dt){
if (sim_controls->enforce_regular_mouse){
simulate_mouse_update(input, sim_controls->prev_mouse);
}
input->first_step = first_step;
input->dt = dt;
}
internal void
simulation_step_end(Input_Simulation_Controls *sim_controls,
Application_Step_Input *input){
sim_controls->counter += 1;
sim_controls->prev_mouse = input->mouse;
}
////////////////
internal void
simulation_stream_init(Simulation_Event_Stream_State *stream){
stream->index = 0;
}
internal void
simulation_drive_from_events(Input_Simulation_Controls *sim_controls,
Simulation_Event_Stream_State *stream,
Application_Step_Input *input,
Simulation_Event *events, i32 event_count,
i32 width, i32 height){
Simulation_Event *event = events + stream->index;
for (; stream->index < event_count; ++stream->index, ++event){
if (event->counter_index > sim_controls->counter){
break;
}
switch (event->type){
case SimulationEvent_Noop:InvalidCodePath;
case SimulationEvent_DebugNumber:
{
input->debug_number = event->debug_number;
}break;
case SimulationEvent_Key:
{
simulate_key(input, event->key.code, event->key.modifiers);
}break;
case SimulationEvent_MouseLeftPress:
{
simulate_mouse_left_press(input);
}break;
case SimulationEvent_MouseLeftRelease:
{
simulate_mouse_left_release(input);
}break;
case SimulationEvent_MouseRightPress:
{
simulate_mouse_right_press(input);
}break;
case SimulationEvent_MouseRightRelease:
{
simulate_mouse_right_release(input);
}break;
case SimulationEvent_MouseWheel:
{
simulate_mouse_wheel(input, event->wheel);
}break;
case SimulationEvent_MouseXY:
{
simulate_mouse_xy(input, event->mouse_xy.x, event->mouse_xy.y,
width, height);
}break;
case SimulationEvent_Exit:
{
simulate_exit(input);
}break;
default:InvalidCodePath;
}
}
}
// BOTTOM

34
4ed_input_simulation.h Normal file
View File

@ -0,0 +1,34 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 02.03.2018
*
* Input simulation data declarations
*
*/
// TOP
#if !defined(FRED_INPUT_SIMULATION_H)
#define FRED_INPUT_SIMULATION_H
#include "4ed_input_simulation_event.h"
////////////////
struct Input_Simulation_Controls{
b32 enforce_regular_mouse;
i32 counter;
Mouse_State prev_mouse;
};
////////////////
struct Simulation_Event_Stream_State{
i32 index;
};
#endif
// BOTTOM

View File

@ -0,0 +1,49 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 02.03.2018
*
* Input simulation data declarations ~ events data
*
*/
// TOP
#if !defined(FRED_INPUT_SIMULATION_EVENT_H)
#define FRED_INPUT_SIMULATION_EVENT_H
typedef u32 Simulation_Event_Type;
enum{
SimulationEvent_Noop,
SimulationEvent_DebugNumber,
SimulationEvent_Key,
SimulationEvent_MouseLeftPress,
SimulationEvent_MouseLeftRelease,
SimulationEvent_MouseRightPress,
SimulationEvent_MouseRightRelease,
SimulationEvent_MouseWheel,
SimulationEvent_MouseXY,
SimulationEvent_Exit,
};
struct Simulation_Event{
i32 counter_index;
Simulation_Event_Type type;
union{
i32 debug_number;
struct{
u32 code;
u8 modifiers;
} key;
i32 wheel;
struct{
i32 x;
i32 y;
} mouse_xy;
};
};
#endif
// BOTTOM

25
build_tests.bat Normal file
View File

@ -0,0 +1,25 @@
@echo off
if not exist ..\tests (mkdir ..\tests)
if not exist ..\tests\input_data (mkdir ..\tests\input_data)
set code_home=%cd%
pushd ..\build
set build_home=%cd%
popd
pushd ..\tests\input_data
set data_home=%cd%
popd
set opts=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /wd4390 /WX
set opts=%opts% /GR- /EHa- /nologo /FC
set inc=-I%code_home%
pushd %build_home%
cl %opts% %inc% %code_home%\meta\4ed_test_builder.cpp /Zi /Fetest_builder
popd
pushd %data_home%
%build_home%\test_builder %code_home%\test_scripts
popd

584
meta/4ed_test_builder.cpp Normal file
View File

@ -0,0 +1,584 @@
/*
* Mr. 4th Dimention - Allen Webster
*
* 02.03.2018
*
* Converter for *.4is -> *.4id
*
*/
// TOP
#include "4ed_defines.h"
#include "4ed_input_simulation_event.h"
#include "4coder_lib/4coder_string.h"
#include "4coder_generated/style.h"
#include "4coder_API/types.h"
#include "4coder_generated/keycodes.h"
#include "4coder_file.h"
#include <stdio.h>
internal void
print_usage(char *name){
fprintf(stdout,
"usage: %s <src-root> [<src-root> ...]\n"
"all files with the extension .4is in src-root will be converted\n",
name);
}
// TODO(allen): // TODO(allen): // TODO(allen): // TODO(allen):
// TODO(allen): // TODO(allen): // TODO(allen): // TODO(allen):
// TODO(allen): // TODO(allen): // TODO(allen): // TODO(allen):
// This belongs in the string library or something like that.
struct String_Array{
String *strings;
i32 count;
};
internal String_Array
get_lines(Partition *part, String data){
String_Array array = {0};
array.strings = push_array(part, String, 0);
char *line_ptr = data.str;
for (i32 i = 0; i <= data.size; ++i){
char *c_ptr = data.str + i;
b32 delim = false;
if (i < data.size){
switch (*c_ptr){
case '\n': case '\r':
{
delim = true;
}break;
}
}
else{
delim = true;
}
if (delim){
String s = make_string(line_ptr, (i32)(c_ptr - line_ptr));
s = skip_chop_whitespace(s);
if (s.size > 0){
String *new_s = push_array(part, String, 1);
*new_s = s;
array.count += 1;
}
line_ptr = c_ptr + 1;
}
}
return(array);
}
internal String_Array
get_words(Partition *part, String data){
String_Array array = {0};
array.strings = push_array(part, String, 0);
char *word_ptr = data.str;
for (i32 i = 0; i <= data.size; ++i){
char *c_ptr = data.str + i;
b32 delim = false;
if (i < data.size){
delim = char_is_whitespace(*c_ptr);
}
else{
delim = true;
}
if (delim){
String s = make_string(word_ptr, (i32)(c_ptr - word_ptr));
if (s.size > 0){
String *new_s = push_array(part, String, 1);
*new_s = s;
array.count += 1;
}
word_ptr = c_ptr + 1;
}
}
return(array);
}
internal String_Array
get_flags(Partition *part, String data){
String_Array array = {0};
array.strings = push_array(part, String, 0);
char *word_ptr = data.str;
for (i32 i = 0; i <= data.size; ++i){
char *c_ptr = data.str + i;
b32 delim = false;
if (i < data.size){
delim = (*c_ptr == '|');
}
else{
delim = true;
}
if (delim){
String s = make_string(word_ptr, (i32)(c_ptr - word_ptr));
s = skip_chop_whitespace(s);
if (s.size > 0){
String *new_s = push_array(part, String, 1);
*new_s = s;
array.count += 1;
}
word_ptr = c_ptr + 1;
}
}
return(array);
}
internal void
show_error(char *name, String data, char *ptr, char *error_message){
i32 line = 1;
i32 column = 1;
i32 stop = (i32)(ptr - data.str);
if (stop > data.size){
stop = data.size;
}
for (i32 i = 0; i < stop; ++i){
if (data.str[i] == '\n'){
line += 1;
column = 1;
}
else{
column += 1;
}
}
fprintf(stdout, "%s:%d:%d: error %s\n", name, line, column, error_message);
}
struct Line_Parse_Context{
char *name;
String data;
String_Array words;
};
internal void
show_error(Line_Parse_Context context, char *ptr, char *error_message){
show_error(context.name, context.data, ptr, error_message);
}
internal bool32
require_blank(Line_Parse_Context context, i32 index){
bool32 result = (context.words.count <= index);
if (!result){
show_error(context, context.words.strings[index].str,
"unexpected word");
}
return(result);
}
internal bool32
require_integer(Line_Parse_Context context, i32 index, i32 *int_out){
bool32 result = false;
if (index < context.words.count){
String s = context.words.strings[index];
if (str_is_int(s)){
*int_out = str_to_int(s);
result = true;
}
else{
show_error(context,
context.words.strings[index].str,
"expected integer");
}
}
else{
show_error(context,
context.words.strings[context.words.count - 1].str,
"expected integer");
}
return(result);
}
internal bool32
require_string(Line_Parse_Context context, i32 index, String *str_out){
bool32 result = false;
if (index < context.words.count){
*str_out = context.words.strings[index];
result = true;
}
else{
show_error(context,
context.words.strings[context.words.count - 1].str,
"expected another word");
}
return(result);
}
internal bool32
key_name_to_code(Line_Parse_Context context, String key_name, u32 *key_code_out){
bool32 result = false;
if (key_name.size == 1){
*key_code_out = key_name.str[0];
result = true;
}
else{
#define KEY_CODE_CHK_SET(S,N) else if (match(key_name, S)) \
do{ *key_code_out = N; result = true; }while(0)
#define KEY_CODE_CHK(N) KEY_CODE_CHK_SET(#N,N)
if (false){}
KEY_CODE_CHK(key_back);
KEY_CODE_CHK(key_up);
KEY_CODE_CHK(key_down);
KEY_CODE_CHK(key_left);
KEY_CODE_CHK(key_right);
KEY_CODE_CHK(key_del);
KEY_CODE_CHK(key_insert);
KEY_CODE_CHK(key_home);
KEY_CODE_CHK(key_end);
KEY_CODE_CHK(key_page_up);
KEY_CODE_CHK(key_page_down);
KEY_CODE_CHK(key_esc);
KEY_CODE_CHK(key_mouse_left);
KEY_CODE_CHK(key_mouse_right);
KEY_CODE_CHK(key_mouse_left_release);
KEY_CODE_CHK(key_mouse_right_release);
KEY_CODE_CHK(key_f1);
KEY_CODE_CHK(key_f2);
KEY_CODE_CHK(key_f3);
KEY_CODE_CHK(key_f4);
KEY_CODE_CHK(key_f5);
KEY_CODE_CHK(key_f6);
KEY_CODE_CHK(key_f7);
KEY_CODE_CHK(key_f8);
KEY_CODE_CHK(key_f9);
KEY_CODE_CHK(key_f10);
KEY_CODE_CHK(key_f11);
KEY_CODE_CHK(key_f12);
KEY_CODE_CHK(key_f13);
KEY_CODE_CHK(key_f14);
KEY_CODE_CHK(key_f15);
KEY_CODE_CHK(key_f16);
KEY_CODE_CHK_SET("key_space", ' ');
}
if (!result){
show_error(context, key_name.str, "expected key name");
}
return(result);
}
internal bool32
mod_name_to_flags(Line_Parse_Context context, Partition *part, String mod_name, u8 *modifiers_out){
bool32 result = true;
Temp_Memory temp = begin_temp_memory(part);
String_Array flags = get_flags(part, mod_name);
u8 modifiers = 0;
for (i32 i = 0; i < flags.count; ++i){
String flag_string = flags.strings[i];
u8 this_flag = 0;
#define MDFR_FLAG_CHK(N) \
else if (match(flag_string, #N)) do{ this_flag = N; }while(0)
if (false){}
MDFR_FLAG_CHK(MDFR_NONE);
MDFR_FLAG_CHK(MDFR_CTRL);
MDFR_FLAG_CHK(MDFR_ALT);
MDFR_FLAG_CHK(MDFR_CMND);
MDFR_FLAG_CHK(MDFR_SHIFT);
else{
result = false;
show_error(context, flag_string.str,
"unrecognized flag string");
break;
}
modifiers |= this_flag;
}
end_temp_memory(temp);
*modifiers_out = modifiers;
return(result);
}
internal void
process_script_inner(Partition *part, char *name){
String data = file_dump(part, name);
String_Array lines = get_lines(part, data);
Simulation_Event *events = push_array(part, Simulation_Event, 0);
i32 event_count = 0;
i32 time_counter = 0;
for (i32 i = 0; i < lines.count; ++i){
Temp_Memory word_temp = begin_temp_memory(part);
String line = lines.strings[i];
String_Array words = get_words(part, line);
Line_Parse_Context context = {0};
context.name = name;
context.data = data;
context.words = words;
bool32 emit_event = false;
Simulation_Event event = {0};
bool32 emit_type = false;
i32 type_increment = 0;
String type_string = {0};
if (words.count != 0){
String first_word = words.strings[0];
if (!match(substr(first_word, 0, 2), "//")){
if (match(first_word, "debug_number")){
i32 debug_number = 0;
if (require_integer(context, 1, &debug_number) &&
require_blank(context, 2)){
emit_event = true;
event.counter_index = time_counter;
event.type = SimulationEvent_DebugNumber;
event.debug_number = debug_number;
}
else{
return;
}
}
else if (match(first_word, "wait")){
i32 increment = 0;
if (require_integer(context, 1, &increment) &&
require_blank(context, 2)){
time_counter += increment;
}
else{
return;
}
}
else if (match(first_word, "key")){
String key_name = {0};
String mod_name = {0};
if (require_string(context, 1, &key_name) &&
require_string(context, 2, &mod_name) &&
require_blank(context, 3)){
u32 key_code = 0;
u8 modifiers = 0;
if (key_name_to_code(context, key_name, &key_code) &&
mod_name_to_flags(context, part, mod_name, &modifiers)){
emit_event = true;
event.counter_index = time_counter;
event.type = SimulationEvent_Key;
event.key.code = key_code;
event.key.modifiers = modifiers;
}
else{
return;
}
}
else{
return;
}
}
else if (match(first_word, "type")){
i32 increment = 0;
String string = {0};
if (require_integer(context, 1, &increment) &&
require_string(context, 2, &string) &&
require_blank(context, 3)){
emit_type = true;
type_increment = increment;
type_string = string;
}
else{
return;
}
}
else if (match(first_word, "mouse_left_press")){
if (require_blank(context, 1)){
emit_event = true;
event.counter_index = time_counter;
event.type = SimulationEvent_MouseLeftPress;
}
else{
return;
}
}
else if (match(first_word, "mouse_right_press")){
if (require_blank(context, 1)){
emit_event = true;
event.counter_index = time_counter;
event.type = SimulationEvent_MouseRightPress;
}
else{
return;
}
}
else if (match(first_word, "mouse_left_release")){
if (require_blank(context, 1)){
emit_event = true;
event.counter_index = time_counter;
event.type = SimulationEvent_MouseLeftRelease;
}
else{
return;
}
}
else if (match(first_word, "mouse_right_release")){
if (require_blank(context, 1)){
emit_event = true;
event.counter_index = time_counter;
event.type = SimulationEvent_MouseRightRelease;
}
else{
return;
}
}
else if (match(first_word, "mouse_wheel")){
i32 wheel = 0;
if (require_integer(context, 1, &wheel) &&
require_blank(context, 2)){
emit_event = true;
event.counter_index = time_counter;
event.type = SimulationEvent_MouseWheel;
event.wheel = wheel;
}
else{
return;
}
}
else if (match(first_word, "mouse_xy")){
i32 x = 0;
i32 y = 0;
if (require_integer(context, 1, &x) &&
require_integer(context, 2, &y) &&
require_blank(context, 3)){
emit_event = true;
event.counter_index = time_counter;
event.type = SimulationEvent_MouseXY;
event.mouse_xy.x = x;
event.mouse_xy.y = y;
}
else{
return;
}
}
else if (match(first_word, "exit")){
if (require_blank(context, 1)){
emit_event = true;
event.counter_index = time_counter;
event.type = SimulationEvent_Exit;
}
else{
return;
}
}
else{
show_error(name, data, first_word.str,
"unrecognized control word");
return;
}
}
}
end_temp_memory(word_temp);
if (emit_event){
Simulation_Event *new_event = push_array(part, Simulation_Event, 1);
memset(new_event, 0, sizeof(*new_event));
*new_event = event;
event_count += 1;
}
if (emit_type){
for (i32 j = 0; j < type_string.size; ++j){
Simulation_Event *new_event = push_array(part, Simulation_Event, 1);
memset(new_event, 0, sizeof(*new_event));
new_event->counter_index = time_counter;
new_event->type = SimulationEvent_Key;
new_event->key.code = type_string.str[j];
new_event->key.modifiers = MDFR_NONE;
event_count += 1;
time_counter += type_increment;
}
}
}
String out_name_s = front_of_directory(make_string_slowly(name));
char *out_name = push_array(part, char, out_name_s.size + 1);
memcpy(out_name, out_name_s.str, out_name_s.size);
Assert(out_name[out_name_s.size - 1] == 's');
out_name[out_name_s.size - 1] = 'd';
out_name[out_name_s.size] = 0;
FILE *out = fopen(out_name, "wb");
if (out != 0){
fwrite(&event_count, sizeof(event_count), 1, out);
fwrite(events, sizeof(*events), event_count, out);
fclose(out);
}
else{
fprintf(stdout, "fatal error: cannot open output %s\n",
out_name);
}
}
internal void
process_script(Partition *part, char *name){
Temp_Memory temp = begin_temp_memory(part);
process_script_inner(part, name);
end_temp_memory(temp);
}
int
main(int argc, char **argv){
if (argc <= 1){
char *name = "test_builder";
if (argc > 0){
name = argv[0];
}
print_usage(name);
}
int32_t size = (256 << 20);
void *mem = malloc(size);
Partition part_ = make_part(mem, size);
Partition *part = &part_;
for (i32 i = 1; i < argc; ++i){
Cross_Platform_File_List files = get_file_list(part, encode(part, argv[i]), filter_all);
char *final_name = unencode(part, files.final_name, files.final_length);
String final_name_s = make_string_slowly(final_name);
Cross_Platform_File_Info *info = files.info;
for (i32 j = 0; j < files.count; ++j, ++info){
if (info->is_folder){
continue;
}
char *name = unencode(part, info->name, info->len);
String s = make_string_slowly(name);
if (!match(substr_tail(s, s.size - 4), ".4is")){
continue;
}
i32 whole_name_max = final_name_s.size + 1 + s.size + 1;
char *whole_name = push_array(part, char, whole_name_max);
push_align(part, 8);
String w = make_string_cap(whole_name, 0, whole_name_max);
append(&w, final_name_s);
append(&w, '/');
append(&w, s);
terminate_with_null(&w);
process_script(part, w.str);
}
}
}
// BOTTOM

View File

@ -1932,18 +1932,17 @@ main(int argc, char **argv){
linuxvars.input.clipboard = null_string;
}
// NOTE(allen): Initialize result So the Core Doesn't Have to Fill Things it Doesn't Care About
Application_Step_Result result = {0};
result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
result.trying_to_kill = !linuxvars.keep_running;
Application_Step_Result frame_input = linuxvars.input;
frame_input.trying_to_kill = !linuxvars.keep_running;
// HACK(allen): THIS SHIT IS FUCKED (happens on mac too)
b32 keep_running = linuxvars.keep_running;
// NOTE(allen): Application Core Update
target.buffer.pos = 0;
Application_Step_Result result = {0};
if (app.step != 0){
app.step(&sysfunc, &target, &memory_vars, &linuxvars.input, &result);
result = app.step(&sysfunc, &target, &memory_vars, &frame_input);
}
else{
LOG("app.step == 0 -- skipping\n");

View File

@ -593,10 +593,7 @@ osx_try_to_close(void){
external void
osx_step(void){
Application_Step_Result result = {};
result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
result.trying_to_kill = !osxvars.keep_running;
// NOTE(allen): Prepare the Frame Input
osxvars.input.dt = 1.f/60.f;
@ -621,6 +618,8 @@ osx_step(void){
osxvars.input.mouse.release_r = false;
osxvars.input.mouse.wheel = 0;
frame_input.trying_to_kill = !osxvars.keep_running;
// 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);
@ -639,7 +638,7 @@ osx_step(void){
// NOTE(allen): Application Core Update
target.buffer.pos = 0;
if (app.step != 0){
app.step(&sysfunc, &target, &memory_vars, &frame_input, &result);
result = app.step(&sysfunc, &target, &memory_vars, &frame_input);
}
else{
LOG("app.step == 0 -- skipping\n");

View File

@ -980,7 +980,7 @@ win32_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
character = '\n';
}
else if (character == '\t'){
character = '\t';
// Do nothing
}
else if (character < 32 || character == 127){
break;
@ -1146,6 +1146,9 @@ win32_proc(HWND hwnd, UINT uMsg, WPARAM wParam, LPARAM lParam){
#include "4ed_link_system_functions.cpp"
#include "4ed_shared_init_logic.cpp"
#include "4ed_input_simulation.h"
#include "4ed_input_simulation.cpp"
int CALL_CONVENTION
WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdShow){
i32 argc = __argc;
@ -1358,6 +1361,12 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
LOG("Initializing application variables\n");
app.init(&sysfunc, &target, &memory_vars, win32vars.clipboard_contents, curdir, custom_api);
Input_Simulation_Controls sim_controls = {0};
simulation_init(&sim_controls);
Simulation_Event_Stream_State sim_stream = {0};
simulation_stream_init(&sim_stream);
//
// Main loop
//
@ -1392,7 +1401,7 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
b32 get_more_messages = true;
do{
if (win32vars.got_useful_event == 0){
if (win32vars.got_useful_event == 0 && !plat_settings.use_test_input){
get_more_messages = GetMessage(&msg, 0, 0, 0);
}
else{
@ -1508,62 +1517,140 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
Application_Step_Input input = {0};
input.first_step = win32vars.first;
if (!plat_settings.use_test_input){
input.first_step = win32vars.first;
input.dt = frame_useconds/1000000.f;
input.dt = frame_useconds / 1000000.f;
input.keys = input_chunk.trans.key_data;
input.keys = input_chunk.trans.key_data;
input.mouse.out_of_window = input_chunk.trans.out_of_window;
input.mouse.out_of_window = input_chunk.trans.out_of_window;
input.mouse.l = input_chunk.pers.mouse_l;
input.mouse.press_l = input_chunk.trans.mouse_l_press;
input.mouse.release_l = input_chunk.trans.mouse_l_release;
input.mouse.l = input_chunk.pers.mouse_l;
input.mouse.press_l = input_chunk.trans.mouse_l_press;
input.mouse.release_l = input_chunk.trans.mouse_l_release;
input.mouse.r = input_chunk.pers.mouse_r;
input.mouse.press_r = input_chunk.trans.mouse_r_press;
input.mouse.release_r = input_chunk.trans.mouse_r_release;
input.mouse.r = input_chunk.pers.mouse_r;
input.mouse.press_r = input_chunk.trans.mouse_r_press;
input.mouse.release_r = input_chunk.trans.mouse_r_release;
input.mouse.wheel = input_chunk.trans.mouse_wheel;
input.mouse.x = input_chunk.pers.mouse_x;
input.mouse.y = input_chunk.pers.mouse_y;
input.mouse.wheel = input_chunk.trans.mouse_wheel;
input.mouse.x = input_chunk.pers.mouse_x;
input.trying_to_kill = input_chunk.trans.trying_to_kill;
input.mouse.y = input_chunk.pers.mouse_y;
// TODO(allen): Not really appropriate to round trip this all the way to the OS layer, redo this system.
// NOTE(allen): Ask the Core About Exiting if We Have an Exit Signal
if (win32vars.send_exit_signal){
input.trying_to_kill = true;
win32vars.send_exit_signal = false;
}
// NOTE(allen): Frame Clipboard Input
win32vars.clipboard_contents = null_string;
if (win32vars.clipboard_sequence != 0){
DWORD new_number = GetClipboardSequenceNumber();
if (new_number != win32vars.clipboard_sequence){
win32vars.clipboard_sequence = new_number;
if (win32vars.next_clipboard_is_self){
win32vars.next_clipboard_is_self = 0;
}
else{
win32_read_clipboard_contents();
// NOTE(allen): Frame Clipboard Input
win32vars.clipboard_contents = null_string;
if (win32vars.clipboard_sequence != 0){
DWORD new_number = GetClipboardSequenceNumber();
if (new_number != win32vars.clipboard_sequence){
win32vars.clipboard_sequence = new_number;
if (win32vars.next_clipboard_is_self){
win32vars.next_clipboard_is_self = 0;
}
else{
win32_read_clipboard_contents();
}
}
}
input.clipboard = win32vars.clipboard_contents;
}
else{
Simulation_Event sim_events[19];
i32 sim_event_count = ArrayCount(sim_events);
sim_events[0].counter_index = 0;
sim_events[0].type = SimulationEvent_MouseXY;
sim_events[0].mouse_xy.x = 20;
sim_events[0].mouse_xy.y = 20;
sim_events[1].counter_index = 45;
sim_events[1].type = SimulationEvent_DebugNumber;
sim_events[1].debug_number = 1;
sim_events[2].counter_index = 45;
sim_events[2].type = SimulationEvent_Key;
sim_events[2].key.code = '_';
sim_events[2].key.modifiers = MDFR_CTRL;
sim_events[3].counter_index = 50;
sim_events[3].type = SimulationEvent_DebugNumber;
sim_events[3].debug_number = 2;
sim_events[4].counter_index = 50;
sim_events[4].type = SimulationEvent_Key;
sim_events[4].key.code = '4';
sim_events[4].key.modifiers = MDFR_NONE;
sim_events[5].counter_index = 50;
sim_events[5].type = SimulationEvent_Key;
sim_events[5].key.code = 'c';
sim_events[5].key.modifiers = MDFR_NONE;
sim_events[6].counter_index = 50;
sim_events[6].type = SimulationEvent_Key;
sim_events[6].key.code = 'o';
sim_events[6].key.modifiers = MDFR_NONE;
sim_events[7].counter_index = 50;
sim_events[7].type = SimulationEvent_Key;
sim_events[7].key.code = 'd';
sim_events[7].key.modifiers = MDFR_NONE;
sim_events[8].counter_index = 50;
sim_events[8].type = SimulationEvent_Key;
sim_events[8].key.code = 'e';
sim_events[8].key.modifiers = MDFR_NONE;
sim_events[9].counter_index = 50;
sim_events[9].type = SimulationEvent_Key;
sim_events[9].key.code = 'r';
sim_events[9].key.modifiers = MDFR_NONE;
sim_events[10].counter_index = 80;
sim_events[10].type = SimulationEvent_MouseLeftPress;
sim_events[11].counter_index = 90;
sim_events[11].type = SimulationEvent_MouseLeftRelease;
sim_events[12].counter_index = 100;
sim_events[12].type = SimulationEvent_MouseLeftPress;
sim_events[13].counter_index = 110;
sim_events[13].type = SimulationEvent_MouseXY;
sim_events[13].mouse_xy.x = 50;
sim_events[13].mouse_xy.y = 20;
sim_events[14].counter_index = 110;
sim_events[14].type = SimulationEvent_MouseLeftRelease;
sim_events[15].counter_index = 150;
sim_events[15].type = SimulationEvent_Key;
sim_events[15].key.code = key_back;
sim_events[15].key.modifiers = MDFR_CTRL;
sim_events[16].counter_index = 150;
sim_events[16].type = SimulationEvent_Key;
sim_events[16].key.code = key_end;
sim_events[16].key.modifiers = MDFR_NONE;
sim_events[17].counter_index = 300;
sim_events[17].type = SimulationEvent_DebugNumber;
sim_events[17].debug_number = 3;
sim_events[18].counter_index = 300;
sim_events[18].type = SimulationEvent_Exit;
simulation_step_begin(&sim_controls, &input,
win32vars.first, frame_useconds/1000000.f);
simulation_drive_from_events(&sim_controls, &sim_stream, &input,
sim_events, sim_event_count,
target.width, target.height);
simulation_step_end(&sim_controls, &input);
}
input.clipboard = win32vars.clipboard_contents;
win32vars.clip_post_len = 0;
// NOTE(allen): Initialize result So the Core Doesn't Have to Fill Things it Doesn't Care About
Application_Step_Result result = {0};
result.mouse_cursor_type = APP_MOUSE_CURSOR_DEFAULT;
result.lctrl_lalt_is_altgr = win32vars.lctrl_lalt_is_altgr;
result.trying_to_kill = input_chunk.trans.trying_to_kill;
// TODO(allen): Not really appropriate to round trip this all the way to the OS layer, redo this system.
// NOTE(allen): Ask the Core About Exiting if We Have an Exit Signal
if (win32vars.send_exit_signal){
result.trying_to_kill = true;
win32vars.send_exit_signal = false;
}
// NOTE(allen): Application Core Update
target.buffer.pos = 0;
Application_Step_Result result = {0};
if (app.step != 0){
app.step(&sysfunc, &target, &memory_vars, &input, &result);
result = app.step(&sysfunc, &target, &memory_vars, &input);
}
else{
LOG("app.step == 0 -- skipping\n");

View File

@ -1,4 +1,4 @@
extensions = ".c.cpp.h.m.bat.sh.4coder.txt";
extensions = ".c.cpp.h.m.bat.sh.4coder.txt.4is";
open_recursively = true;
fkey_command_win[1] = {"echo build: x64 & build.bat", "*compilation*" , true , true };
@ -7,6 +7,7 @@ fkey_command_win[3] = {"build_string.bat" , "*compilation*" , true ,
fkey_command_win[4] = {"echo build: x86 & build.bat /DDEV_BUILD_X86" , "*compilation*", true, true };
fkey_command_win[5] = {"build_metadata.bat" , "*compilation*" , true , true };
fkey_command_win[6] = {"run_profile.bat" , "*profile*" , false, true };
fkey_command_win[7] = {"build_tests.bat" , "*compilation*" , true , true };
fkey_command_win[12] = {"package.bat" , "*package*" , false, true };
fkey_command_linux[1] = {"echo build: x64 & ./build.sh", "*compilation*" , true , true };

View File

@ -44,8 +44,8 @@ The following bindings apply in all situations.
\ITEM \STYLE{code} <alt d> \END Opens a debug view for internal use.
\ITEM \STYLE{code} <alt .> \END If the special build panel is open, makes the build panel the active panel.
\ITEM \STYLE{code} <alt ,> \END If the special build panel is open, closes it.
\ITEM \STYLE{code} <alt n> \END If a buffer containing jump locations has been locked in, goes to the next jump in the buffer, skipping sub jump locations.
\ITEM \STYLE{code} <alt N> \END If a buffer containing jump locations has been locked in, goes to the previous jump in the buffer, skipping sub jump locations.
\ITEM \STYLE{code} <alt n> \END 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.
\ITEM \STYLE{code} <alt N> \END 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.
\ITEM \STYLE{code} <alt M> \END If a buffer containing jump locations has been locked in, goes to the first jump in the buffer.
\ITEM \STYLE{code} <alt m> \END 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.
\ITEM \STYLE{code} <alt z> \END Queries for an output buffer name and system command, runs the system command as a CLI and prints the output to the specified buffer.
@ -104,8 +104,8 @@ The following bindings apply in general text files and most apply in code files,
\ITEM \STYLE{code} <alt down> \END Swaps the line under the cursor with the line below it, and moves the cursor down with it.
\ITEM \STYLE{code} <ctrl backspace> \END Delete characters between the cursor position and the first alphanumeric boundary to the left.
\ITEM \STYLE{code} <ctrl delete> \END Delete characters between the cursor position and the first alphanumeric boundary to the right.
\ITEM \STYLE{code} <alt backspace> \END Delete a single, whole token on or to the left of the cursor.
\ITEM \STYLE{code} <alt delete> \END Delete a single, whole token on or to the right of the cursor.
\ITEM \STYLE{code} <alt backspace> \END Delete a single, whole token on or to the left of the cursor and post it to the clipboard.
\ITEM \STYLE{code} <alt delete> \END Delete a single, whole token on or to the right of the cursor and post it to the clipboard.
\ITEM \STYLE{code} <ctrl space> \END Sets the mark to the current position of the cursor.
\ITEM \STYLE{code} <ctrl a> \END Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.
\ITEM \STYLE{code} <ctrl c> \END Copy the text in the range from the cursor to the mark onto the clipboard.
@ -138,8 +138,8 @@ The following bindings apply in general text files and most apply in code files,
\ITEM \STYLE{code} <ctrl x> \END Cut the text in the range from the cursor to the mark onto the clipboard.
\ITEM \STYLE{code} <ctrl y> \END Advances forewards through the undo history.
\ITEM \STYLE{code} <ctrl z> \END Advances backwards through the undo history.
\ITEM \STYLE{code} <ctrl 2> \END Decrases the current buffer's width for line wrapping.
\ITEM \STYLE{code} <ctrl 3> \END Increases the current buffer's width for line wrapping.
\ITEM \STYLE{code} <ctrl 1> \END Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.
\ITEM \STYLE{code} <ctrl 2> \END Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.
\ITEM \STYLE{code} <ctrl ?> \END Toggles the current buffer's whitespace visibility status.
\ITEM \STYLE{code} <ctrl ~> \END Removes trailing whitespace from all lines in the current buffer.
\ITEM \STYLE{code} <return> \END If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.
@ -166,6 +166,8 @@ The following commands only apply in files where the lexer (syntax highlighting)
\ITEM \STYLE{code} <alt r> \END At the cursor, insert a block comment.
\ITEM \STYLE{code} <alt t> \END At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.
\ITEM \STYLE{code} <alt y> \END At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.
\ITEM \STYLE{code} <alt D> \END Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.
\ITEM \STYLE{code} <alt T> \END Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.
\ITEM \STYLE{code} <ctrl [> \END At the cursor, insert a '{' and '}' separated by a blank line.
\ITEM \STYLE{code} <ctrl {> \END At the cursor, insert a '{' and '};' separated by a blank line.
\ITEM \STYLE{code} <ctrl }> \END At the cursor, insert a '{' and '}break;' separated by a blank line.
@ -263,8 +265,8 @@ The following bindings apply in general text files and most apply in code files,
\ITEM \STYLE{code} <cmnd down> \END Seeks the cursor down to the next blank line and places it at the end of the line.
\ITEM \STYLE{code} <cmnd backspace> \END Delete characters between the cursor position and the first alphanumeric boundary to the left.
\ITEM \STYLE{code} <cmnd delete> \END Delete characters between the cursor position and the first alphanumeric boundary to the right.
\ITEM \STYLE{code} <ctrl backspace> \END Delete a single, whole token on or to the left of the cursor.
\ITEM \STYLE{code} <ctrl delete> \END Delete a single, whole token on or to the right of the cursor.
\ITEM \STYLE{code} <ctrl backspace> \END Delete a single, whole token on or to the left of the cursor and post it to the clipboard.
\ITEM \STYLE{code} <ctrl delete> \END Delete a single, whole token on or to the right of the cursor and post it to the clipboard.
\ITEM \STYLE{code} <cmnd /> \END Sets the mark to the current position of the cursor.
\ITEM \STYLE{code} <cmnd a> \END Queries the user for two strings, and replaces all occurences of the first string in the range between the cursor and the mark with the second string.
\ITEM \STYLE{code} <cmnd c> \END Copy the text in the range from the cursor to the mark onto the clipboard.
@ -296,8 +298,8 @@ The following bindings apply in general text files and most apply in code files,
\ITEM \STYLE{code} <cmnd x> \END Cut the text in the range from the cursor to the mark onto the clipboard.
\ITEM \STYLE{code} <cmnd y> \END Advances forewards through the undo history.
\ITEM \STYLE{code} <cmnd z> \END Advances backwards through the undo history.
\ITEM \STYLE{code} <cmnd 2> \END Decrases the current buffer's width for line wrapping.
\ITEM \STYLE{code} <cmnd 3> \END Increases the current buffer's width for line wrapping.
\ITEM \STYLE{code} <cmnd 1> \END Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.
\ITEM \STYLE{code} <cmnd 2> \END Set the other non-active panel to view the buffer that the active panel views, and switch to that panel.
\ITEM \STYLE{code} <cmnd ?> \END Toggles the current buffer's whitespace visibility status.
\ITEM \STYLE{code} <cmnd ~> \END Removes trailing whitespace from all lines in the current buffer.
\ITEM \STYLE{code} <return> \END If the buffer in the active view is writable, inserts a character, otherwise performs goto_jump_at_cursor.
@ -324,6 +326,8 @@ The following commands only apply in files where the lexer (syntax highlighting)
\ITEM \STYLE{code} <ctrl r> \END At the cursor, insert a block comment.
\ITEM \STYLE{code} <ctrl t> \END At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder.
\ITEM \STYLE{code} <ctrl y> \END At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder.
\ITEM \STYLE{code} <ctrl D> \END Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string.
\ITEM \STYLE{code} <ctrl T> \END Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it.
\ITEM \STYLE{code} <cmnd [> \END At the cursor, insert a '{' and '}' separated by a blank line.
\ITEM \STYLE{code} <cmnd {> \END At the cursor, insert a '{' and '};' separated by a blank line.
\ITEM \STYLE{code} <cmnd }> \END At the cursor, insert a '{' and '}break;' separated by a blank line.

View File

@ -0,0 +1,31 @@
mouse_xy 20 20
wait 45
debug_number 1
key _ MDFR_CTRL
wait 5
debug_number 2
type 1 4coder
wait 30
mouse_left_press
wait 10
mouse_left_release
wait 10
mouse_left_press
wait 10
mouse_xy 50 20
mouse_left_release
wait 40
key key_back MDFR_CTRL
key key_end MDFR_NONE
wait 150
debug_number 3
exit