Replaced streaming implementations of seeks with a core based character class seek system
parent
0096b6339e
commit
9ce2eeeb11
|
@ -152,6 +152,10 @@ ENUM(i32, Buffer_Setting_ID){
|
||||||
BufferSetting_RecordsHistory,
|
BufferSetting_RecordsHistory,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
STRUCT Character_Predicate{
|
||||||
|
u8 b[32];
|
||||||
|
};
|
||||||
|
|
||||||
/* DOC(A View_Setting_ID names an adjustable setting in a view.) */
|
/* DOC(A View_Setting_ID names an adjustable setting in a view.) */
|
||||||
ENUM(i32, View_Setting_ID){
|
ENUM(i32, View_Setting_ID){
|
||||||
/* DOC(ViewSetting_Null is not a valid setting, it is reserved to detect errors.) */
|
/* DOC(ViewSetting_Null is not a valid setting, it is reserved to detect errors.) */
|
||||||
|
|
|
@ -20,6 +20,7 @@ struct Application_Links;
|
||||||
#define BUFFER_READ_RANGE_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, i32 start, i32 one_past_last, char *out)
|
#define BUFFER_READ_RANGE_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, i32 start, i32 one_past_last, char *out)
|
||||||
#define BUFFER_REPLACE_RANGE_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, Range range, String_Const_u8 string)
|
#define BUFFER_REPLACE_RANGE_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, Range range, String_Const_u8 string)
|
||||||
#define BUFFER_BATCH_EDIT_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, char *str, Buffer_Edit *edits, i32 edit_count)
|
#define BUFFER_BATCH_EDIT_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, char *str, Buffer_Edit *edits, i32 edit_count)
|
||||||
|
#define BUFFER_SEEK_CHARACTER_CLASS_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, Character_Predicate *predicate, Scan_Direction direction, i32 start_pos, i32 *pos_out)
|
||||||
#define BUFFER_COMPUTE_CURSOR_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, Buffer_Seek seek, Partial_Cursor *cursor_out)
|
#define BUFFER_COMPUTE_CURSOR_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id, Buffer_Seek seek, Partial_Cursor *cursor_out)
|
||||||
#define BUFFER_EXISTS_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id)
|
#define BUFFER_EXISTS_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id)
|
||||||
#define BUFFER_READY_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id)
|
#define BUFFER_READY_SIG(n) b32 n(Application_Links *app, Buffer_ID buffer_id)
|
||||||
|
@ -203,6 +204,7 @@ typedef GET_BUFFER_BY_FILE_NAME_SIG(Get_Buffer_By_File_Name_Function);
|
||||||
typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function);
|
typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function);
|
||||||
typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
|
typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function);
|
||||||
typedef BUFFER_BATCH_EDIT_SIG(Buffer_Batch_Edit_Function);
|
typedef BUFFER_BATCH_EDIT_SIG(Buffer_Batch_Edit_Function);
|
||||||
|
typedef BUFFER_SEEK_CHARACTER_CLASS_SIG(Buffer_Seek_Character_Class_Function);
|
||||||
typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function);
|
typedef BUFFER_COMPUTE_CURSOR_SIG(Buffer_Compute_Cursor_Function);
|
||||||
typedef BUFFER_EXISTS_SIG(Buffer_Exists_Function);
|
typedef BUFFER_EXISTS_SIG(Buffer_Exists_Function);
|
||||||
typedef BUFFER_READY_SIG(Buffer_Ready_Function);
|
typedef BUFFER_READY_SIG(Buffer_Ready_Function);
|
||||||
|
@ -388,6 +390,7 @@ Get_Buffer_By_File_Name_Function *get_buffer_by_file_name;
|
||||||
Buffer_Read_Range_Function *buffer_read_range;
|
Buffer_Read_Range_Function *buffer_read_range;
|
||||||
Buffer_Replace_Range_Function *buffer_replace_range;
|
Buffer_Replace_Range_Function *buffer_replace_range;
|
||||||
Buffer_Batch_Edit_Function *buffer_batch_edit;
|
Buffer_Batch_Edit_Function *buffer_batch_edit;
|
||||||
|
Buffer_Seek_Character_Class_Function *buffer_seek_character_class;
|
||||||
Buffer_Compute_Cursor_Function *buffer_compute_cursor;
|
Buffer_Compute_Cursor_Function *buffer_compute_cursor;
|
||||||
Buffer_Exists_Function *buffer_exists;
|
Buffer_Exists_Function *buffer_exists;
|
||||||
Buffer_Ready_Function *buffer_ready;
|
Buffer_Ready_Function *buffer_ready;
|
||||||
|
@ -572,6 +575,7 @@ Get_Buffer_By_File_Name_Function *get_buffer_by_file_name_;
|
||||||
Buffer_Read_Range_Function *buffer_read_range_;
|
Buffer_Read_Range_Function *buffer_read_range_;
|
||||||
Buffer_Replace_Range_Function *buffer_replace_range_;
|
Buffer_Replace_Range_Function *buffer_replace_range_;
|
||||||
Buffer_Batch_Edit_Function *buffer_batch_edit_;
|
Buffer_Batch_Edit_Function *buffer_batch_edit_;
|
||||||
|
Buffer_Seek_Character_Class_Function *buffer_seek_character_class_;
|
||||||
Buffer_Compute_Cursor_Function *buffer_compute_cursor_;
|
Buffer_Compute_Cursor_Function *buffer_compute_cursor_;
|
||||||
Buffer_Exists_Function *buffer_exists_;
|
Buffer_Exists_Function *buffer_exists_;
|
||||||
Buffer_Ready_Function *buffer_ready_;
|
Buffer_Ready_Function *buffer_ready_;
|
||||||
|
@ -764,6 +768,7 @@ app_links->get_buffer_by_file_name_ = Get_Buffer_By_File_Name;\
|
||||||
app_links->buffer_read_range_ = Buffer_Read_Range;\
|
app_links->buffer_read_range_ = Buffer_Read_Range;\
|
||||||
app_links->buffer_replace_range_ = Buffer_Replace_Range;\
|
app_links->buffer_replace_range_ = Buffer_Replace_Range;\
|
||||||
app_links->buffer_batch_edit_ = Buffer_Batch_Edit;\
|
app_links->buffer_batch_edit_ = Buffer_Batch_Edit;\
|
||||||
|
app_links->buffer_seek_character_class_ = Buffer_Seek_Character_Class;\
|
||||||
app_links->buffer_compute_cursor_ = Buffer_Compute_Cursor;\
|
app_links->buffer_compute_cursor_ = Buffer_Compute_Cursor;\
|
||||||
app_links->buffer_exists_ = Buffer_Exists;\
|
app_links->buffer_exists_ = Buffer_Exists;\
|
||||||
app_links->buffer_ready_ = Buffer_Ready;\
|
app_links->buffer_ready_ = Buffer_Ready;\
|
||||||
|
@ -948,6 +953,7 @@ static b32 get_buffer_by_file_name(Application_Links *app, String_Const_u8 file_
|
||||||
static b32 buffer_read_range(Application_Links *app, Buffer_ID buffer_id, i32 start, i32 one_past_last, char *out){return(app->buffer_read_range(app, buffer_id, start, one_past_last, out));}
|
static b32 buffer_read_range(Application_Links *app, Buffer_ID buffer_id, i32 start, i32 one_past_last, char *out){return(app->buffer_read_range(app, buffer_id, start, one_past_last, out));}
|
||||||
static b32 buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range range, String_Const_u8 string){return(app->buffer_replace_range(app, buffer_id, range, string));}
|
static b32 buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range range, String_Const_u8 string){return(app->buffer_replace_range(app, buffer_id, range, string));}
|
||||||
static b32 buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, char *str, Buffer_Edit *edits, i32 edit_count){return(app->buffer_batch_edit(app, buffer_id, str, edits, edit_count));}
|
static b32 buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, char *str, Buffer_Edit *edits, i32 edit_count){return(app->buffer_batch_edit(app, buffer_id, str, edits, edit_count));}
|
||||||
|
static b32 buffer_seek_character_class(Application_Links *app, Buffer_ID buffer_id, Character_Predicate *predicate, Scan_Direction direction, i32 start_pos, i32 *pos_out){return(app->buffer_seek_character_class(app, buffer_id, predicate, direction, start_pos, pos_out));}
|
||||||
static b32 buffer_compute_cursor(Application_Links *app, Buffer_ID buffer_id, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor(app, buffer_id, seek, cursor_out));}
|
static b32 buffer_compute_cursor(Application_Links *app, Buffer_ID buffer_id, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor(app, buffer_id, seek, cursor_out));}
|
||||||
static b32 buffer_exists(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_exists(app, buffer_id));}
|
static b32 buffer_exists(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_exists(app, buffer_id));}
|
||||||
static b32 buffer_ready(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_ready(app, buffer_id));}
|
static b32 buffer_ready(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_ready(app, buffer_id));}
|
||||||
|
@ -1132,6 +1138,7 @@ static b32 get_buffer_by_file_name(Application_Links *app, String_Const_u8 file_
|
||||||
static b32 buffer_read_range(Application_Links *app, Buffer_ID buffer_id, i32 start, i32 one_past_last, char *out){return(app->buffer_read_range_(app, buffer_id, start, one_past_last, out));}
|
static b32 buffer_read_range(Application_Links *app, Buffer_ID buffer_id, i32 start, i32 one_past_last, char *out){return(app->buffer_read_range_(app, buffer_id, start, one_past_last, out));}
|
||||||
static b32 buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range range, String_Const_u8 string){return(app->buffer_replace_range_(app, buffer_id, range, string));}
|
static b32 buffer_replace_range(Application_Links *app, Buffer_ID buffer_id, Range range, String_Const_u8 string){return(app->buffer_replace_range_(app, buffer_id, range, string));}
|
||||||
static b32 buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, char *str, Buffer_Edit *edits, i32 edit_count){return(app->buffer_batch_edit_(app, buffer_id, str, edits, edit_count));}
|
static b32 buffer_batch_edit(Application_Links *app, Buffer_ID buffer_id, char *str, Buffer_Edit *edits, i32 edit_count){return(app->buffer_batch_edit_(app, buffer_id, str, edits, edit_count));}
|
||||||
|
static b32 buffer_seek_character_class(Application_Links *app, Buffer_ID buffer_id, Character_Predicate *predicate, Scan_Direction direction, i32 start_pos, i32 *pos_out){return(app->buffer_seek_character_class_(app, buffer_id, predicate, direction, start_pos, pos_out));}
|
||||||
static b32 buffer_compute_cursor(Application_Links *app, Buffer_ID buffer_id, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor_(app, buffer_id, seek, cursor_out));}
|
static b32 buffer_compute_cursor(Application_Links *app, Buffer_ID buffer_id, Buffer_Seek seek, Partial_Cursor *cursor_out){return(app->buffer_compute_cursor_(app, buffer_id, seek, cursor_out));}
|
||||||
static b32 buffer_exists(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_exists_(app, buffer_id));}
|
static b32 buffer_exists(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_exists_(app, buffer_id));}
|
||||||
static b32 buffer_ready(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_ready_(app, buffer_id));}
|
static b32 buffer_ready(Application_Links *app, Buffer_ID buffer_id){return(app->buffer_ready_(app, buffer_id));}
|
||||||
|
|
|
@ -256,30 +256,30 @@ int32_t line_number;
|
||||||
};
|
};
|
||||||
static Command_Metadata fcoder_metacmd_table[234] = {
|
static Command_Metadata fcoder_metacmd_table[234] = {
|
||||||
{ 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, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 806 },
|
{ 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, "w:\\4ed\\code\\4coder_experiments.cpp", 34, 806 },
|
||||||
{ PROC_LINKS(seek_whitespace_up, 0), "seek_whitespace_up", 18, "Seeks the cursor up to the next blank line.", 43, "w:\\4ed\\code\\4coder_seek.cpp", 27, 833 },
|
{ PROC_LINKS(seek_whitespace_up, 0), "seek_whitespace_up", 18, "Seeks the cursor up to the next blank line.", 43, "w:\\4ed\\code\\4coder_seek.cpp", 27, 674 },
|
||||||
{ PROC_LINKS(seek_whitespace_down, 0), "seek_whitespace_down", 20, "Seeks the cursor down to the next blank line.", 45, "w:\\4ed\\code\\4coder_seek.cpp", 27, 839 },
|
{ PROC_LINKS(seek_whitespace_down, 0), "seek_whitespace_down", 20, "Seeks the cursor down to the next blank line.", 45, "w:\\4ed\\code\\4coder_seek.cpp", 27, 680 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 845 },
|
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 686 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 851 },
|
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 692 },
|
||||||
{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\4coder_seek.cpp", 27, 857 },
|
{ PROC_LINKS(seek_beginning_of_line, 0), "seek_beginning_of_line", 22, "Seeks the cursor to the beginning of the visual line.", 53, "w:\\4ed\\code\\4coder_seek.cpp", 27, 698 },
|
||||||
{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "w:\\4ed\\code\\4coder_seek.cpp", 27, 863 },
|
{ PROC_LINKS(seek_end_of_line, 0), "seek_end_of_line", 16, "Seeks the cursor to the end of the visual line.", 47, "w:\\4ed\\code\\4coder_seek.cpp", 27, 704 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 869 },
|
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 710 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 875 },
|
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 716 },
|
||||||
{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\4coder_seek.cpp", 27, 881 },
|
{ PROC_LINKS(goto_beginning_of_file, 0), "goto_beginning_of_file", 22, "Sets the cursor to the beginning of the file.", 45, "w:\\4ed\\code\\4coder_seek.cpp", 27, 722 },
|
||||||
{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\4coder_seek.cpp", 27, 890 },
|
{ PROC_LINKS(goto_end_of_file, 0), "goto_end_of_file", 16, "Sets the cursor to the end of the file.", 39, "w:\\4ed\\code\\4coder_seek.cpp", 27, 731 },
|
||||||
{ PROC_LINKS(seek_whitespace_right, 0), "seek_whitespace_right", 21, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "w:\\4ed\\code\\4coder_seek.cpp", 27, 905 },
|
{ PROC_LINKS(seek_whitespace_right, 0), "seek_whitespace_right", 21, "Seek right for the next boundary between whitespace and non-whitespace.", 71, "w:\\4ed\\code\\4coder_seek.cpp", 27, 746 },
|
||||||
{ PROC_LINKS(seek_whitespace_left, 0), "seek_whitespace_left", 20, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "w:\\4ed\\code\\4coder_seek.cpp", 27, 911 },
|
{ PROC_LINKS(seek_whitespace_left, 0), "seek_whitespace_left", 20, "Seek left for the next boundary between whitespace and non-whitespace.", 70, "w:\\4ed\\code\\4coder_seek.cpp", 27, 752 },
|
||||||
{ PROC_LINKS(seek_token_right, 0), "seek_token_right", 16, "Seek right for the next end of a token.", 39, "w:\\4ed\\code\\4coder_seek.cpp", 27, 917 },
|
{ PROC_LINKS(seek_token_right, 0), "seek_token_right", 16, "Seek right for the next end of a token.", 39, "w:\\4ed\\code\\4coder_seek.cpp", 27, 758 },
|
||||||
{ PROC_LINKS(seek_token_left, 0), "seek_token_left", 15, "Seek left for the next beginning of a token.", 44, "w:\\4ed\\code\\4coder_seek.cpp", 27, 923 },
|
{ PROC_LINKS(seek_token_left, 0), "seek_token_left", 15, "Seek left for the next beginning of a token.", 44, "w:\\4ed\\code\\4coder_seek.cpp", 27, 764 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 929 },
|
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 770 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 935 },
|
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 776 },
|
||||||
{ PROC_LINKS(seek_alphanumeric_right, 0), "seek_alphanumeric_right", 23, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "w:\\4ed\\code\\4coder_seek.cpp", 27, 941 },
|
{ PROC_LINKS(seek_alphanumeric_right, 0), "seek_alphanumeric_right", 23, "Seek right for boundary between alphanumeric characters and non-alphanumeric characters.", 88, "w:\\4ed\\code\\4coder_seek.cpp", 27, 782 },
|
||||||
{ PROC_LINKS(seek_alphanumeric_left, 0), "seek_alphanumeric_left", 22, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "w:\\4ed\\code\\4coder_seek.cpp", 27, 947 },
|
{ PROC_LINKS(seek_alphanumeric_left, 0), "seek_alphanumeric_left", 22, "Seek left for boundary between alphanumeric characters and non-alphanumeric characters.", 87, "w:\\4ed\\code\\4coder_seek.cpp", 27, 788 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 953 },
|
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 794 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 959 },
|
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 800 },
|
||||||
{ PROC_LINKS(backspace_word, 0), "backspace_word", 14, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "w:\\4ed\\code\\4coder_seek.cpp", 27, 967 },
|
{ PROC_LINKS(backspace_word, 0), "backspace_word", 14, "Delete characters between the cursor position and the first alphanumeric boundary to the left.", 94, "w:\\4ed\\code\\4coder_seek.cpp", 27, 808 },
|
||||||
{ PROC_LINKS(delete_word, 0), "delete_word", 11, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "w:\\4ed\\code\\4coder_seek.cpp", 27, 973 },
|
{ PROC_LINKS(delete_word, 0), "delete_word", 11, "Delete characters between the cursor position and the first alphanumeric boundary to the right.", 95, "w:\\4ed\\code\\4coder_seek.cpp", 27, 814 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 979 },
|
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 820 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 985 },
|
{ 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, "w:\\4ed\\code\\4coder_seek.cpp", 27, 826 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 206 },
|
{ 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, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 206 },
|
||||||
{ 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, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 217 },
|
{ 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, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 217 },
|
||||||
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 228 },
|
{ PROC_LINKS(open_panel_vsplit, 0), "open_panel_vsplit", 17, "Create a new panel by vertically splitting the active panel.", 60, "w:\\4ed\\code\\4coder_default_framework.cpp", 40, 228 },
|
||||||
|
|
|
@ -279,6 +279,106 @@ get_key_code(char *buffer){
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
|
internal Character_Predicate
|
||||||
|
character_predicate_from_function(Character_Predicate_Function *func){
|
||||||
|
Character_Predicate predicate = {};
|
||||||
|
i32 byte_index = 0;
|
||||||
|
for (u32 i = 0; i <= 255;){
|
||||||
|
b8 v[8];
|
||||||
|
for (i32 bit_index = 0; bit_index < 8; i += 1, bit_index += 1){
|
||||||
|
v[bit_index] = func((u8)i);
|
||||||
|
}
|
||||||
|
predicate.b[byte_index] = (
|
||||||
|
(v[0] << 0) |
|
||||||
|
(v[1] << 1) |
|
||||||
|
(v[2] << 2) |
|
||||||
|
(v[3] << 3) |
|
||||||
|
(v[4] << 4) |
|
||||||
|
(v[5] << 5) |
|
||||||
|
(v[6] << 6) |
|
||||||
|
(v[7] << 7)
|
||||||
|
);
|
||||||
|
byte_index += 1;
|
||||||
|
}
|
||||||
|
return(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Character_Predicate
|
||||||
|
character_predicate_from_character(u8 character){
|
||||||
|
Character_Predicate predicate = {};
|
||||||
|
predicate.b[character/8] = (1 << (character%8));
|
||||||
|
return(predicate);
|
||||||
|
}
|
||||||
|
|
||||||
|
#define character_predicate_check_character(p, c) (((p).b[(c)/8] & (1 << ((c)%8))) != 0)
|
||||||
|
|
||||||
|
internal Character_Predicate
|
||||||
|
character_predicate_or(Character_Predicate *a, Character_Predicate *b){
|
||||||
|
Character_Predicate p = {};
|
||||||
|
for (i32 i = 0; i < ArrayCount(p.b); i += 1){
|
||||||
|
p.b[i] = a->b[i] | b->b[i];
|
||||||
|
}
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Character_Predicate
|
||||||
|
character_predicate_and(Character_Predicate *a, Character_Predicate *b){
|
||||||
|
Character_Predicate p = {};
|
||||||
|
for (i32 i = 0; i < ArrayCount(p.b); i += 1){
|
||||||
|
p.b[i] = a->b[i] & b->b[i];
|
||||||
|
}
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal Character_Predicate
|
||||||
|
character_predicate_not(Character_Predicate *a){
|
||||||
|
Character_Predicate p = {};
|
||||||
|
for (i32 i = 0; i < ArrayCount(p.b); i += 1){
|
||||||
|
p.b[i] = ~(a->b[i]);
|
||||||
|
}
|
||||||
|
return(p);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal i32
|
||||||
|
buffer_seek_character_class_change__inner(Application_Links *app, Buffer_ID buffer, Character_Predicate *positive, Character_Predicate *negative, Scan_Direction direction, i32 start_pos){
|
||||||
|
i32 pos = start_pos;
|
||||||
|
switch (direction){
|
||||||
|
case Scan_Backward:
|
||||||
|
{
|
||||||
|
b32 s1 = buffer_seek_character_class(app, buffer, negative, direction, pos, &pos);
|
||||||
|
b32 s2 = buffer_seek_character_class(app, buffer, positive, direction, pos, &pos);
|
||||||
|
if (s1 && s2){
|
||||||
|
pos += 1;
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
case Scan_Forward:
|
||||||
|
{
|
||||||
|
pos -= 1;
|
||||||
|
buffer_seek_character_class(app, buffer, positive, direction, pos, &pos);
|
||||||
|
buffer_seek_character_class(app, buffer, negative, direction, pos, &pos);
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
return(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal i32
|
||||||
|
buffer_seek_character_class_change_1_0(Application_Links *app, Buffer_ID buffer, Character_Predicate *predicate, Scan_Direction direction, i32 start_pos){
|
||||||
|
Character_Predicate negative = character_predicate_not(predicate);
|
||||||
|
return(buffer_seek_character_class_change__inner(app, buffer,
|
||||||
|
predicate, &negative,
|
||||||
|
direction, start_pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
internal i32
|
||||||
|
buffer_seek_character_class_change_0_1(Application_Links *app, Buffer_ID buffer, Character_Predicate *predicate, Scan_Direction direction, i32 start_pos){
|
||||||
|
Character_Predicate negative = character_predicate_not(predicate);
|
||||||
|
return(buffer_seek_character_class_change__inner(app, buffer,
|
||||||
|
&negative, predicate,
|
||||||
|
direction, start_pos));
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
static String_Const_u8
|
static String_Const_u8
|
||||||
push_hot_directory(Application_Links *app, Arena *arena){
|
push_hot_directory(Application_Links *app, Arena *arena){
|
||||||
String_Const_u8 result = {};
|
String_Const_u8 result = {};
|
||||||
|
@ -550,8 +650,6 @@ pos_range_enclose_whole_tokens(Application_Links *app, Buffer_ID buffer, Cpp_Tok
|
||||||
return(range);
|
return(range);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
// NOTE(allen): range enclose operators:
|
// NOTE(allen): range enclose operators:
|
||||||
// enclose whole *** ?
|
// enclose whole *** ?
|
||||||
|
|
||||||
|
@ -685,22 +783,28 @@ move_past_lead_whitespace(Application_Links *app, View_ID view){
|
||||||
move_past_lead_whitespace(app, view, buffer);
|
move_past_lead_whitespace(app, view, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static b32
|
||||||
|
line_is_blank(Application_Links *app, Buffer_ID buffer, i32 line_number){
|
||||||
|
Scratch_Block scratch(app);
|
||||||
|
String_Const_u8 line = push_buffer_line(app, scratch, buffer, line_number);
|
||||||
|
b32 is_blank = true;
|
||||||
|
for (umem i = 0; i < line.size; i += 1){
|
||||||
|
if (!character_is_whitespace(line.str[i])){
|
||||||
|
is_blank = false;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(is_blank);
|
||||||
|
}
|
||||||
|
|
||||||
static i32
|
static i32
|
||||||
get_line_number_of_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i32 line_number_start){
|
get_line_number_of__whitespace_status_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i32 line_number_start, b32 get_blank_line){
|
||||||
i32 line_count = 0;
|
i32 line_count = 0;
|
||||||
buffer_get_line_count(app, buffer, &line_count);
|
buffer_get_line_count(app, buffer, &line_count);
|
||||||
i32 line_number = line_number_start + direction;
|
i32 line_number = line_number_start + direction;
|
||||||
for (;1 <= line_number && line_number <= line_count; line_number += direction){
|
for (;1 <= line_number && line_number <= line_count; line_number += direction){
|
||||||
Scratch_Block scratch(app);
|
b32 is_blank = line_is_blank(app, buffer, line_number);
|
||||||
String_Const_u8 line = push_buffer_line(app, scratch, buffer, line_number);
|
if (is_blank == get_blank_line){
|
||||||
b32 is_blank = true;
|
|
||||||
for (umem i = 0; i < line.size; i += 1){
|
|
||||||
if (!character_is_whitespace(line.str[i])){
|
|
||||||
is_blank = false;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (is_blank){
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -708,6 +812,16 @@ get_line_number_of_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Dir
|
||||||
return(line_number);
|
return(line_number);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static i32
|
||||||
|
get_line_number_of_non_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i32 line_number_start){
|
||||||
|
return(get_line_number_of__whitespace_status_line(app, buffer, direction, line_number_start, false));
|
||||||
|
}
|
||||||
|
|
||||||
|
static i32
|
||||||
|
get_line_number_of_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i32 line_number_start){
|
||||||
|
return(get_line_number_of__whitespace_status_line(app, buffer, direction, line_number_start, true));
|
||||||
|
}
|
||||||
|
|
||||||
static i32
|
static i32
|
||||||
get_pos_of_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i32 pos_start){
|
get_pos_of_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i32 pos_start){
|
||||||
i32 line_number_start = get_line_number_from_pos(app, buffer, pos_start);
|
i32 line_number_start = get_line_number_from_pos(app, buffer, pos_start);
|
||||||
|
@ -716,6 +830,24 @@ get_pos_of_blank_line(Application_Links *app, Buffer_ID buffer, Scan_Direction d
|
||||||
return(pos);
|
return(pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static i32
|
||||||
|
get_line_number_of_blank_line_grouped(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i32 line_number_start){
|
||||||
|
i32 line_number = line_number_start;
|
||||||
|
if (line_is_blank(app, buffer, line_number)){
|
||||||
|
line_number = get_line_number_of_non_blank_line(app, buffer, direction, line_number);
|
||||||
|
}
|
||||||
|
line_number = get_line_number_of_blank_line(app, buffer, direction, line_number);
|
||||||
|
return(line_number);
|
||||||
|
}
|
||||||
|
|
||||||
|
static i32
|
||||||
|
get_pos_of_blank_line_grouped(Application_Links *app, Buffer_ID buffer, Scan_Direction direction, i32 pos_start){
|
||||||
|
i32 line_number_start = get_line_number_from_pos(app, buffer, pos_start);
|
||||||
|
i32 blank_line = get_line_number_of_blank_line_grouped(app, buffer, direction, line_number_start);
|
||||||
|
i32 pos = get_line_start_pos(app, buffer, blank_line);
|
||||||
|
return(pos);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
static Cpp_Token_Array
|
static Cpp_Token_Array
|
||||||
|
|
|
@ -33,6 +33,73 @@ struct File_Name_Data{
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
|
typedef b8 Character_Predicate_Function(u8 c);
|
||||||
|
|
||||||
|
global Character_Predicate character_predicate_alpha = { {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
254, 255, 255, 7, 254, 255, 255, 7,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
} };
|
||||||
|
|
||||||
|
global Character_Predicate character_predicate_alpha_numeric = { {
|
||||||
|
0, 0, 0, 0, 0, 0, 255, 3,
|
||||||
|
254, 255, 255, 7, 254, 255, 255, 7,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
} };
|
||||||
|
|
||||||
|
global Character_Predicate character_predicate_alpha_numeric_underscore = { {
|
||||||
|
0, 0, 0, 0, 0, 0, 255, 3,
|
||||||
|
254, 255, 255, 135, 254, 255, 255, 7,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
} };
|
||||||
|
|
||||||
|
global Character_Predicate character_predicate_uppercase = { {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
254, 255, 255, 7, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
} };
|
||||||
|
|
||||||
|
global Character_Predicate character_predicate_lowercase = { {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 254, 255, 255, 7,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
} };
|
||||||
|
|
||||||
|
global Character_Predicate character_predicate_base10 = { {
|
||||||
|
0, 0, 0, 0, 0, 0, 255, 3,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
} };
|
||||||
|
|
||||||
|
global Character_Predicate character_predicate_base16 = { {
|
||||||
|
0, 0, 0, 0, 0, 0, 255, 3,
|
||||||
|
126, 0, 0, 0, 126, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
} };
|
||||||
|
|
||||||
|
global Character_Predicate character_predicate_whitespace = { {
|
||||||
|
0, 62, 0, 0, 1, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
} };
|
||||||
|
|
||||||
|
global Character_Predicate character_predicate_utf8_byte = { {
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
0, 0, 0, 0, 0, 0, 0, 0,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
255, 255, 255, 255, 255, 255, 255, 255,
|
||||||
|
} };
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
struct Stream_Chunk{
|
struct Stream_Chunk{
|
||||||
Application_Links *app;
|
Application_Links *app;
|
||||||
Buffer_ID buffer_id;
|
Buffer_ID buffer_id;
|
||||||
|
|
332
4coder_seek.cpp
332
4coder_seek.cpp
|
@ -4,293 +4,67 @@
|
||||||
|
|
||||||
// TOP
|
// TOP
|
||||||
|
|
||||||
|
// TODO(allen): replace everything until the END comment -- START --
|
||||||
|
|
||||||
static i32
|
static i32
|
||||||
buffer_seek_whitespace_right(Application_Links *app, Buffer_ID buffer_id, i32 pos){
|
buffer_seek_whitespace_right(Application_Links *app, Buffer_ID buffer, i32 pos){
|
||||||
i32 buffer_size = 0;
|
return(buffer_seek_character_class_change_0_1(app, buffer, &character_predicate_whitespace,
|
||||||
buffer_get_size(app, buffer_id, &buffer_size);
|
Scan_Forward, pos));
|
||||||
i32 result = buffer_size + 1;
|
|
||||||
if (pos < 0){
|
|
||||||
pos = 0;
|
|
||||||
}
|
|
||||||
pos += 1;
|
|
||||||
if (pos < buffer_size){
|
|
||||||
char data_chunk[1024];
|
|
||||||
Stream_Chunk stream = {};
|
|
||||||
stream.add_null = true;
|
|
||||||
if (init_stream_chunk(&stream, app, buffer_id, pos, data_chunk, sizeof(data_chunk))){
|
|
||||||
b32 still_looping = true;
|
|
||||||
b32 is_whitespace_1 = character_is_whitespace(buffer_get_char(app, buffer_id, pos - 1));
|
|
||||||
do{
|
|
||||||
for (; pos < stream.end; ++pos){
|
|
||||||
char c2 = stream.data[pos];
|
|
||||||
b32 is_whitespace_2 = true;
|
|
||||||
if (c2 != 0){
|
|
||||||
is_whitespace_2 = character_is_whitespace(c2);
|
|
||||||
}
|
|
||||||
if (!is_whitespace_1 && is_whitespace_2){
|
|
||||||
result = pos;
|
|
||||||
goto double_break;
|
|
||||||
}
|
|
||||||
is_whitespace_1 = is_whitespace_2;
|
|
||||||
}
|
|
||||||
still_looping = forward_stream_chunk(&stream);
|
|
||||||
}while(still_looping);
|
|
||||||
double_break:;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static i32
|
static i32
|
||||||
buffer_seek_whitespace_left(Application_Links *app, Buffer_ID buffer_id, i32 pos){
|
buffer_seek_whitespace_left(Application_Links *app, Buffer_ID buffer, i32 pos){
|
||||||
i32 buffer_size = 0;
|
return(buffer_seek_character_class_change_1_0(app, buffer, &character_predicate_whitespace,
|
||||||
buffer_get_size(app, buffer_id, &buffer_size);
|
Scan_Backward, pos));
|
||||||
|
|
||||||
i32 result = -1;
|
|
||||||
if (pos > buffer_size){
|
|
||||||
pos = buffer_size;
|
|
||||||
}
|
|
||||||
pos -= 2;
|
|
||||||
if (pos >= 0){
|
|
||||||
char data_chunk[1024];
|
|
||||||
Stream_Chunk stream = {};
|
|
||||||
if (init_stream_chunk(&stream, app, buffer_id, pos, data_chunk, sizeof(data_chunk))){
|
|
||||||
b32 still_looping = true;
|
|
||||||
b32 is_whitespace_2 = character_is_whitespace(buffer_get_char(app, buffer_id, pos + 1));
|
|
||||||
do{
|
|
||||||
for (; pos >= stream.start; --pos){
|
|
||||||
char c1 = stream.data[pos];
|
|
||||||
b32 is_whitespace_1 = character_is_whitespace(c1);
|
|
||||||
if (is_whitespace_1 && !is_whitespace_2){
|
|
||||||
result = pos + 1;
|
|
||||||
goto double_break;
|
|
||||||
}
|
|
||||||
is_whitespace_2 = is_whitespace_1;
|
|
||||||
}
|
|
||||||
still_looping = backward_stream_chunk(&stream);
|
|
||||||
}while(still_looping);
|
|
||||||
double_break:;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (pos == -1){
|
|
||||||
if (!character_is_whitespace(buffer_get_char(app, buffer_id, 0))){
|
|
||||||
result = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static i32
|
static i32
|
||||||
buffer_seek_alphanumeric_right(Application_Links *app, Buffer_ID buffer_id, i32 pos){
|
buffer_seek_alphanumeric_right(Application_Links *app, Buffer_ID buffer, i32 pos){
|
||||||
char data_chunk[1024];
|
return(buffer_seek_character_class_change_1_0(app, buffer, &character_predicate_alpha_numeric,
|
||||||
Stream_Chunk stream = {};
|
Scan_Forward, pos));
|
||||||
if (init_stream_chunk(&stream, app, buffer_id, pos, data_chunk, sizeof(data_chunk))){
|
|
||||||
b32 still_looping = true;
|
|
||||||
do{
|
|
||||||
for (; pos < stream.end; ++pos){
|
|
||||||
u8 c = stream.data[pos];
|
|
||||||
if (c != '_' && character_is_alpha_numeric_unicode(c)){
|
|
||||||
goto double_break1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
still_looping = forward_stream_chunk(&stream);
|
|
||||||
}while(still_looping);
|
|
||||||
double_break1:;
|
|
||||||
still_looping = true;
|
|
||||||
do{
|
|
||||||
for (; pos < stream.end; ++pos){
|
|
||||||
u8 c = stream.data[pos];
|
|
||||||
if (!(c != '_' && character_is_alpha_numeric_unicode(c))){
|
|
||||||
goto double_break2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
still_looping = forward_stream_chunk(&stream);
|
|
||||||
}while(still_looping);
|
|
||||||
double_break2:;
|
|
||||||
}
|
|
||||||
return(pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static i32
|
static i32
|
||||||
buffer_seek_alphanumeric_left(Application_Links *app, Buffer_ID buffer_id, i32 pos){
|
buffer_seek_alphanumeric_left(Application_Links *app, Buffer_ID buffer, i32 pos){
|
||||||
char data_chunk[1024];
|
return(buffer_seek_character_class_change_0_1(app, buffer, &character_predicate_alpha_numeric,
|
||||||
Stream_Chunk stream = {};
|
Scan_Backward, pos));
|
||||||
--pos;
|
|
||||||
if (pos > 0){
|
|
||||||
if (init_stream_chunk(&stream, app, buffer_id, pos, data_chunk, sizeof(data_chunk))){
|
|
||||||
b32 still_looping = true;
|
|
||||||
do{
|
|
||||||
for (; pos >= stream.start; --pos){
|
|
||||||
u8 c = stream.data[pos];
|
|
||||||
if (c != '_' && character_is_alpha_numeric_unicode(c)){
|
|
||||||
goto double_break1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
still_looping = backward_stream_chunk(&stream);
|
|
||||||
}while(still_looping);
|
|
||||||
double_break1:;
|
|
||||||
still_looping = true;
|
|
||||||
do{
|
|
||||||
for (; pos >= stream.start; --pos){
|
|
||||||
u8 c = stream.data[pos];
|
|
||||||
if (!(c != '_' && character_is_alpha_numeric_unicode(c))){
|
|
||||||
++pos;
|
|
||||||
goto double_break2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
still_looping = backward_stream_chunk(&stream);
|
|
||||||
}while(still_looping);
|
|
||||||
double_break2:;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
pos = 0;
|
|
||||||
}
|
|
||||||
return(pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static i32
|
static i32
|
||||||
buffer_seek_alphanumeric_or_underscore_right(Application_Links *app, Buffer_ID buffer_id, i32 pos){
|
buffer_seek_alphanumeric_or_underscore_right(Application_Links *app, Buffer_ID buffer, i32 pos){
|
||||||
char data_chunk[1024];
|
return(buffer_seek_character_class_change_1_0(app, buffer,
|
||||||
Stream_Chunk stream = {};
|
&character_predicate_alpha_numeric_underscore,
|
||||||
if (init_stream_chunk(&stream, app, buffer_id, pos, data_chunk, sizeof(data_chunk))){
|
Scan_Forward, pos));
|
||||||
b32 still_looping = true;
|
|
||||||
do{
|
|
||||||
for (; pos < stream.end; ++pos){
|
|
||||||
u8 c = stream.data[pos];
|
|
||||||
if (character_is_alpha_numeric_unicode(c)){
|
|
||||||
goto double_break1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
still_looping = forward_stream_chunk(&stream);
|
|
||||||
}while(still_looping);
|
|
||||||
double_break1:;
|
|
||||||
still_looping = true;
|
|
||||||
do{
|
|
||||||
for (; pos < stream.end; ++pos){
|
|
||||||
u8 c = stream.data[pos];
|
|
||||||
if (!character_is_alpha_numeric_unicode(c)){
|
|
||||||
goto double_break2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
still_looping = forward_stream_chunk(&stream);
|
|
||||||
}while(still_looping);
|
|
||||||
double_break2:;
|
|
||||||
}
|
|
||||||
return(pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static i32
|
static i32
|
||||||
buffer_seek_alphanumeric_or_underscore_left(Application_Links *app, Buffer_ID buffer_id, i32 pos){
|
buffer_seek_alphanumeric_or_underscore_left(Application_Links *app, Buffer_ID buffer, i32 pos){
|
||||||
char data_chunk[1024];
|
return(buffer_seek_character_class_change_0_1(app, buffer,
|
||||||
Stream_Chunk stream = {};
|
&character_predicate_alpha_numeric_underscore,
|
||||||
--pos;
|
Scan_Backward, pos));
|
||||||
if (pos > 0){
|
|
||||||
if (init_stream_chunk(&stream, app, buffer_id, pos, data_chunk, sizeof(data_chunk))){
|
|
||||||
b32 still_looping = true;
|
|
||||||
do{
|
|
||||||
for (; pos >= stream.start; --pos){
|
|
||||||
u8 c = stream.data[pos];
|
|
||||||
if (character_is_alpha_numeric_unicode(c)){
|
|
||||||
goto double_break1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
still_looping = backward_stream_chunk(&stream);
|
|
||||||
}while(still_looping);
|
|
||||||
double_break1:;
|
|
||||||
still_looping = true;
|
|
||||||
do{
|
|
||||||
for (; pos >= stream.start; --pos){
|
|
||||||
u8 c = stream.data[pos];
|
|
||||||
if (!character_is_alpha_numeric_unicode(c)){
|
|
||||||
++pos;
|
|
||||||
goto double_break2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
still_looping = backward_stream_chunk(&stream);
|
|
||||||
}while(still_looping);
|
|
||||||
double_break2:;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
pos = 0;
|
|
||||||
}
|
|
||||||
return(pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static i32
|
static i32
|
||||||
buffer_seek_range_camel_right(Application_Links *app, Buffer_ID buffer_id, i32 pos, i32 an_pos){
|
buffer_seek_alphanumeric_or_camel_right(Application_Links *app, Buffer_ID buffer, i32 pos){
|
||||||
char data_chunk[1024];
|
i32 an_pos = buffer_seek_alphanumeric_right(app, buffer, pos);
|
||||||
Stream_Chunk stream = {};
|
i32 an_left_pos = buffer_seek_alphanumeric_left(app, buffer, an_pos);
|
||||||
++pos;
|
i32 cap_pos = 0;
|
||||||
if (pos < an_pos){
|
buffer_seek_character_class(app, buffer, &character_predicate_uppercase,
|
||||||
stream.max_end = an_pos;
|
Scan_Forward, pos, &cap_pos);
|
||||||
if (init_stream_chunk(&stream, app, buffer_id, pos, data_chunk, sizeof(data_chunk))){
|
if (cap_pos == an_left_pos){
|
||||||
u8 c = 0;
|
buffer_seek_character_class(app, buffer, &character_predicate_uppercase,
|
||||||
u8 pc = stream.data[pos];
|
Scan_Forward, cap_pos, &cap_pos);
|
||||||
++pos;
|
|
||||||
b32 still_looping = false;
|
|
||||||
do{
|
|
||||||
for (; pos < stream.end; ++pos){
|
|
||||||
c = stream.data[pos];
|
|
||||||
if (character_is_upper(c) && character_is_lower_unicode(pc)){
|
|
||||||
goto double_break1;
|
|
||||||
}
|
|
||||||
pc = c;
|
|
||||||
}
|
|
||||||
still_looping = forward_stream_chunk(&stream);
|
|
||||||
}while(still_looping);
|
|
||||||
double_break1:;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
return(Min(an_pos, cap_pos));
|
||||||
pos = an_pos;
|
|
||||||
}
|
|
||||||
return(pos);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static i32
|
static i32
|
||||||
buffer_seek_range_camel_left(Application_Links *app, Buffer_ID buffer_id, i32 pos, i32 an_pos){
|
buffer_seek_alphanumeric_or_camel_left(Application_Links *app, Buffer_ID buffer, i32 pos){
|
||||||
char data_chunk[1024];
|
i32 an_pos = buffer_seek_alphanumeric_left(app, buffer, pos);
|
||||||
Stream_Chunk stream = {};
|
i32 cap_pos = 0;
|
||||||
--pos;
|
buffer_seek_character_class(app, buffer, &character_predicate_uppercase,
|
||||||
if (pos > 0){
|
Scan_Backward, pos, &cap_pos);
|
||||||
stream.min_start = an_pos+1;
|
return(Max(cap_pos, an_pos));
|
||||||
if (init_stream_chunk(&stream, app, buffer_id, pos, data_chunk, sizeof(data_chunk))){
|
|
||||||
u8 c = 0;
|
|
||||||
u8 pc = stream.data[pos];
|
|
||||||
b32 still_looping = false;
|
|
||||||
do{
|
|
||||||
for (; pos >= stream.start; --pos){
|
|
||||||
c = stream.data[pos];
|
|
||||||
if (character_is_upper(c) && character_is_lower_unicode(pc)){
|
|
||||||
goto double_break1;
|
|
||||||
}
|
|
||||||
pc = c;
|
|
||||||
}
|
|
||||||
still_looping = backward_stream_chunk(&stream);
|
|
||||||
}while(still_looping);
|
|
||||||
double_break1:;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
pos = 0;
|
|
||||||
}
|
|
||||||
return(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
static i32
|
|
||||||
buffer_seek_alphanumeric_or_camel_right(Application_Links *app, Buffer_ID buffer_id, i32 pos){
|
|
||||||
i32 an_pos = buffer_seek_alphanumeric_right(app, buffer_id, pos);
|
|
||||||
i32 result = buffer_seek_range_camel_right(app, buffer_id, pos, an_pos);
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
static i32
|
|
||||||
buffer_seek_alphanumeric_or_camel_left(Application_Links *app, Buffer_ID buffer_id, i32 pos){
|
|
||||||
i32 an_pos = buffer_seek_alphanumeric_left(app, buffer_id, pos);
|
|
||||||
i32 result = buffer_seek_range_camel_left(app, buffer_id, pos, an_pos);
|
|
||||||
return(result);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static i32
|
static i32
|
||||||
|
@ -356,14 +130,9 @@ buffer_boundary_seek(Application_Links *app, Buffer_ID buffer_id, Arena *scratch
|
||||||
|
|
||||||
if (flags & BoundaryAlphanumeric){
|
if (flags & BoundaryAlphanumeric){
|
||||||
pos[2] = buffer_seek_alphanumeric_right(app, buffer_id, start_pos);
|
pos[2] = buffer_seek_alphanumeric_right(app, buffer_id, start_pos);
|
||||||
if (flags & BoundaryCamelCase){
|
|
||||||
pos[3] = buffer_seek_range_camel_right(app, buffer_id, start_pos, pos[2]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
if (flags & BoundaryCamelCase){
|
||||||
if (flags & BoundaryCamelCase){
|
pos[3] = buffer_seek_alphanumeric_or_camel_right(app, buffer_id, start_pos);
|
||||||
pos[3] = buffer_seek_alphanumeric_or_camel_right(app, buffer_id, start_pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new_pos = size + 1;
|
new_pos = size + 1;
|
||||||
|
@ -394,14 +163,9 @@ buffer_boundary_seek(Application_Links *app, Buffer_ID buffer_id, Arena *scratch
|
||||||
|
|
||||||
if (flags & BoundaryAlphanumeric){
|
if (flags & BoundaryAlphanumeric){
|
||||||
pos[2] = buffer_seek_alphanumeric_left(app, buffer_id, start_pos);
|
pos[2] = buffer_seek_alphanumeric_left(app, buffer_id, start_pos);
|
||||||
if (flags & BoundaryCamelCase){
|
|
||||||
pos[3] = buffer_seek_range_camel_left(app, buffer_id, start_pos, pos[2]);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
else{
|
if (flags & BoundaryCamelCase){
|
||||||
if (flags & BoundaryCamelCase){
|
pos[3] = buffer_seek_alphanumeric_or_camel_left(app, buffer_id, start_pos);
|
||||||
pos[3] = buffer_seek_alphanumeric_or_camel_left(app, buffer_id, start_pos);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
new_pos = -1;
|
new_pos = -1;
|
||||||
|
@ -418,6 +182,8 @@ buffer_boundary_seek(Application_Links *app, Buffer_ID buffer_id, Arena *scratch
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// TODO(allen): --END--
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
void
|
void
|
||||||
|
@ -630,8 +396,6 @@ buffer_seek_string_insensitive_backward(Application_Links *app, Buffer_ID buffer
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
|
|
||||||
static void
|
static void
|
||||||
buffer_seek_string(Application_Links *app, Buffer_ID buffer_id, i32 pos, i32 end, i32 min, String_Const_u8 str, i32 *result, Buffer_Seek_String_Flags flags){
|
buffer_seek_string(Application_Links *app, Buffer_ID buffer_id, i32 pos, i32 end, i32 min, String_Const_u8 str, i32 *result, Buffer_Seek_String_Flags flags){
|
||||||
switch (flags & 3){
|
switch (flags & 3){
|
||||||
|
@ -780,11 +544,11 @@ internal void
|
||||||
seek_blank_line(Application_Links *app, Scan_Direction direction){
|
seek_blank_line(Application_Links *app, Scan_Direction direction){
|
||||||
View_ID view = 0;
|
View_ID view = 0;
|
||||||
get_active_view(app, AccessProtected, &view);
|
get_active_view(app, AccessProtected, &view);
|
||||||
Buffer_ID buffer_id = 0;
|
Buffer_ID buffer = 0;
|
||||||
view_get_buffer(app, view, AccessProtected, &buffer_id);
|
view_get_buffer(app, view, AccessProtected, &buffer);
|
||||||
i32 pos = 0;
|
i32 pos = 0;
|
||||||
view_get_cursor_pos(app, view, &pos);
|
view_get_cursor_pos(app, view, &pos);
|
||||||
i32 new_pos = get_pos_of_blank_line(app, buffer_id, direction, pos);
|
i32 new_pos = get_pos_of_blank_line_grouped(app, buffer, direction, pos);
|
||||||
view_set_cursor(app, view, seek_pos(new_pos), true);
|
view_set_cursor(app, view, seek_pos(new_pos), true);
|
||||||
no_mark_snap_to_cursor_if_shift(app, view);
|
no_mark_snap_to_cursor_if_shift(app, view);
|
||||||
}
|
}
|
||||||
|
@ -797,7 +561,7 @@ seek_blank_line_skip_leading_whitespace(Application_Links *app, Scan_Direction d
|
||||||
view_get_buffer(app, view, AccessProtected, &buffer_id);
|
view_get_buffer(app, view, AccessProtected, &buffer_id);
|
||||||
i32 pos = 0;
|
i32 pos = 0;
|
||||||
view_get_cursor_pos(app, view, &pos);
|
view_get_cursor_pos(app, view, &pos);
|
||||||
i32 new_pos = get_pos_of_blank_line(app, buffer_id, direction, pos);
|
i32 new_pos = get_pos_of_blank_line_grouped(app, buffer_id, direction, pos);
|
||||||
new_pos = get_pos_past_lead_whitespace(app, buffer_id, new_pos);
|
new_pos = get_pos_past_lead_whitespace(app, buffer_id, new_pos);
|
||||||
view_set_cursor(app, view, seek_pos(new_pos), true);
|
view_set_cursor(app, view, seek_pos(new_pos), true);
|
||||||
no_mark_snap_to_cursor_if_shift(app, view);
|
no_mark_snap_to_cursor_if_shift(app, view);
|
||||||
|
|
|
@ -420,6 +420,74 @@ DOC_SEE(Buffer_Batch_Edit_Type)
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#define character_predicate_check_character(p, c) (((p).b[(c)/8] & (1 << ((c)%8))) != 0)
|
||||||
|
|
||||||
|
API_EXPORT b32
|
||||||
|
Buffer_Seek_Character_Class(Application_Links *app, Buffer_ID buffer_id, Character_Predicate *predicate, Scan_Direction direction, i32 start_pos, i32 *pos_out){
|
||||||
|
Models *models = (Models*)app->cmd_context;
|
||||||
|
Editing_File *file = imp_get_file(models, buffer_id);
|
||||||
|
b32 result = false;
|
||||||
|
if (api_check_buffer(file)){
|
||||||
|
String_Const_u8 chunks_space[2];
|
||||||
|
Cursor chunks_cursor = make_cursor(chunks_space, sizeof(chunks_space));
|
||||||
|
Gap_Buffer *gap_buffer = &file->state.buffer;
|
||||||
|
String_Const_u8_Array chunks = buffer_get_chunks(&chunks_cursor, gap_buffer, BufferGetChunk_Basic);
|
||||||
|
|
||||||
|
i32 size = buffer_size(gap_buffer);
|
||||||
|
start_pos = clamp(-1, start_pos, size);
|
||||||
|
if (chunks.count > 0){
|
||||||
|
i32 real_pos = start_pos;
|
||||||
|
i32 chunk_index = 0;
|
||||||
|
i32 chunk_pos = start_pos;
|
||||||
|
if (start_pos != size){
|
||||||
|
for (;(imem)(chunks.vals[chunk_index].size) < chunk_pos;){
|
||||||
|
Assert(chunk_index < chunks.count);
|
||||||
|
chunk_pos -= (i32)chunks.vals[chunk_index].size;
|
||||||
|
chunk_index += 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
chunk_index = chunks.count - 1;
|
||||||
|
chunk_pos = (i32)chunks.vals[chunk_index].size;
|
||||||
|
}
|
||||||
|
for (;;){
|
||||||
|
real_pos += direction;
|
||||||
|
chunk_pos += direction;
|
||||||
|
if (chunk_pos < 0){
|
||||||
|
if (chunk_index == 0){
|
||||||
|
*pos_out = 0;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
chunk_index -= 1;
|
||||||
|
chunk_pos = (i32)chunks.vals[chunk_index].size - 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else if (chunk_pos >= (imem)(chunks.vals[chunk_index].size)){
|
||||||
|
chunk_index += 1;
|
||||||
|
if (chunk_index == chunks.count){
|
||||||
|
*pos_out = size;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
chunk_pos = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
u8 v = chunks.vals[chunk_index].str[chunk_pos];
|
||||||
|
if (character_predicate_check_character(*predicate, v)){
|
||||||
|
result = true;
|
||||||
|
*pos_out = real_pos;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
*pos_out = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
// TODO(allen): redocument
|
// TODO(allen): redocument
|
||||||
API_EXPORT b32
|
API_EXPORT b32
|
||||||
Buffer_Compute_Cursor(Application_Links *app, Buffer_ID buffer_id, Buffer_Seek seek, Partial_Cursor *cursor_out)
|
Buffer_Compute_Cursor(Application_Links *app, Buffer_ID buffer_id, Buffer_Seek seek, Partial_Cursor *cursor_out)
|
||||||
|
|
|
@ -593,9 +593,12 @@ generate_remapping_code_and_data(Arena *arena){
|
||||||
|
|
||||||
inherit_map(arena, mappings, mapid_file);
|
inherit_map(arena, mappings, mapid_file);
|
||||||
|
|
||||||
bind(arena, mappings, key_left, MDFR_CTRL, seek_alphanumeric_or_camel_left);
|
bind(arena, mappings, key_left , MDFR_CTRL, seek_alphanumeric_or_camel_left);
|
||||||
bind(arena, mappings, key_right, MDFR_CTRL, seek_alphanumeric_or_camel_right);
|
bind(arena, mappings, key_right, MDFR_CTRL, seek_alphanumeric_or_camel_right);
|
||||||
|
|
||||||
|
bind(arena, mappings, key_left , MDFR_ALT, seek_alphanumeric_left);
|
||||||
|
bind(arena, mappings, key_right, MDFR_ALT, seek_alphanumeric_right);
|
||||||
|
|
||||||
bind(arena, mappings, '\n', MDFR_NONE, write_and_auto_tab);
|
bind(arena, mappings, '\n', MDFR_NONE, write_and_auto_tab);
|
||||||
bind(arena, mappings, '\n', MDFR_SHIFT, write_and_auto_tab);
|
bind(arena, mappings, '\n', MDFR_SHIFT, write_and_auto_tab);
|
||||||
bind(arena, mappings, '}', MDFR_NONE, write_and_auto_tab);
|
bind(arena, mappings, '}', MDFR_NONE, write_and_auto_tab);
|
||||||
|
@ -817,9 +820,12 @@ generate_remapping_code_and_data(Arena *arena){
|
||||||
|
|
||||||
inherit_map(arena, mappings, mapid_file);
|
inherit_map(arena, mappings, mapid_file);
|
||||||
|
|
||||||
bind(arena, mappings, key_left, MDFR_CMND, seek_alphanumeric_or_camel_left);
|
bind(arena, mappings, key_left , MDFR_CMND, seek_alphanumeric_or_camel_left);
|
||||||
bind(arena, mappings, key_right, MDFR_CMND, seek_alphanumeric_or_camel_right);
|
bind(arena, mappings, key_right, MDFR_CMND, seek_alphanumeric_or_camel_right);
|
||||||
|
|
||||||
|
bind(arena, mappings, key_left , MDFR_CTRL, seek_alphanumeric_left);
|
||||||
|
bind(arena, mappings, key_right, MDFR_CTRL, seek_alphanumeric_right);
|
||||||
|
|
||||||
bind(arena, mappings, '\n', MDFR_NONE, write_and_auto_tab);
|
bind(arena, mappings, '\n', MDFR_NONE, write_and_auto_tab);
|
||||||
bind(arena, mappings, '\n', MDFR_SHIFT, write_and_auto_tab);
|
bind(arena, mappings, '\n', MDFR_SHIFT, write_and_auto_tab);
|
||||||
bind(arena, mappings, '}', MDFR_NONE, write_and_auto_tab);
|
bind(arena, mappings, '}', MDFR_NONE, write_and_auto_tab);
|
||||||
|
|
|
@ -79,6 +79,6 @@ fkey_command[3] = "build x86";
|
||||||
fkey_command[4] = "build metadata";
|
fkey_command[4] = "build metadata";
|
||||||
fkey_command[5] = "build config parser generator";
|
fkey_command[5] = "build config parser generator";
|
||||||
fkey_command[6] = "generate config parser";
|
fkey_command[6] = "generate config parser";
|
||||||
fkey_command[9] = "build pinky one time";
|
fkey_command[9] = "build one time";
|
||||||
fkey_command[10] = "run pinky one time";
|
fkey_command[10] = "run one time";
|
||||||
fkey_command[12] = "package";
|
fkey_command[12] = "package";
|
||||||
|
|
Loading…
Reference in New Issue