2017-01-29 00:03:23 +00:00
/*
4 coder_default_include . cpp - Default set of commands and setup used in 4 coder .
*/
2016-06-28 22:58:50 +00:00
2017-01-29 00:03:23 +00:00
// TOP
2016-03-15 14:12:06 +00:00
2017-01-29 00:03:23 +00:00
# if !defined(FCODER_DEFAULT_INCLUDE_CPP)
# define FCODER_DEFAULT_INCLUDE_CPP
2016-03-15 14:12:06 +00:00
2017-01-29 00:03:23 +00:00
# include "4coder_API/custom.h"
2017-11-21 21:30:40 +00:00
# include "4coder_os_comp_cracking.h"
2018-05-09 07:10:07 +00:00
# include "4coder_helper/4coder_helper.h"
# include "4coder_helper/4coder_streaming.h"
# include "4coder_helper/4coder_long_seek.h"
# include "4coder_lib/4coder_mem.h"
# include "4coder_lib/4coder_utf8.h"
2017-01-23 06:19:43 +00:00
# include "4coder_default_framework.h"
2018-05-09 07:10:07 +00:00
# include "4coder_auto_indent.h"
# include "4coder_build_commands.h"
# include "4coder_jumping.h"
# include "4coder_jump_sticky.h"
# include "4coder_project_commands.h"
# include "4coder_function_list.h"
# include "4coder_scope_commands.h"
2017-01-23 06:19:43 +00:00
# include "4coder_base_commands.cpp"
2018-05-09 07:10:07 +00:00
# include "4coder_default_framework.cpp"
2017-01-23 06:19:43 +00:00
# include "4coder_auto_indent.cpp"
# include "4coder_search.cpp"
2018-05-09 07:10:07 +00:00
# include "4coder_jumping.cpp"
2017-11-15 23:57:21 +00:00
# include "4coder_jump_direct.cpp"
# include "4coder_jump_sticky.cpp"
2017-01-29 00:03:23 +00:00
# include "4coder_clipboard.cpp"
# include "4coder_system_command.cpp"
# include "4coder_build_commands.cpp"
# include "4coder_project_commands.cpp"
2017-02-24 16:48:56 +00:00
# include "4coder_function_list.cpp"
2017-11-21 18:25:19 +00:00
# include "4coder_scope_commands.cpp"
2016-05-27 14:51:12 +00:00
2017-11-15 23:57:21 +00:00
// NOTE(allen): Define USE_OLD_STYLE_JUMPS before 4coder_default_include.cpp to get
// the direct jumps (instead of sticky jumps).
# if defined(USE_OLD_STYLE_JUMPS)
# define goto_jump_at_cursor CUSTOM_ALIAS(goto_jump_at_cursor_direct)
# define goto_jump_at_cursor_same_panel CUSTOM_ALIAS(goto_jump_at_cursor_same_panel_direct)
# define goto_next_jump CUSTOM_ALIAS(goto_next_jump_direct)
# define goto_prev_jump CUSTOM_ALIAS(goto_prev_jump_direct)
# define goto_next_jump_no_skips CUSTOM_ALIAS(goto_next_jump_no_skips_direct)
# define goto_prev_jump_no_skips CUSTOM_ALIAS(goto_prev_jump_no_skips_direct)
# define goto_first_jump CUSTOM_ALIAS(goto_first_jump_direct)
# define newline_or_goto_position CUSTOM_ALIAS(newline_or_goto_position_direct)
# define newline_or_goto_position_same_panel CUSTOM_ALIAS(newline_or_goto_position_same_panel_direct)
# else
# define goto_jump_at_cursor CUSTOM_ALIAS(goto_jump_at_cursor_sticky)
# define goto_jump_at_cursor_same_panel CUSTOM_ALIAS(goto_jump_at_cursor_same_panel_sticky)
# define goto_next_jump CUSTOM_ALIAS(goto_next_jump_sticky)
# define goto_prev_jump CUSTOM_ALIAS(goto_prev_jump_sticky)
# define goto_next_jump_no_skips CUSTOM_ALIAS(goto_next_jump_no_skips_sticky)
# define goto_prev_jump_no_skips CUSTOM_ALIAS(goto_prev_jump_no_skips_sticky)
# define goto_first_jump CUSTOM_ALIAS(goto_first_jump_sticky)
# define newline_or_goto_position CUSTOM_ALIAS(newline_or_goto_position_sticky)
# define newline_or_goto_position_same_panel CUSTOM_ALIAS(newline_or_goto_position_same_panel_sticky)
2017-05-29 18:43:59 +00:00
# endif
2017-05-27 20:04:13 +00:00
2017-11-15 23:57:21 +00:00
# define seek_error CUSTOM_ALIAS(seek_jump)
# define goto_next_error CUSTOM_ALIAS(goto_next_jump)
# define goto_prev_error CUSTOM_ALIAS(goto_prev_jump)
# define goto_next_error_no_skips CUSTOM_ALIAS(goto_next_jump_no_skips)
# define goto_prev_error_no_skips CUSTOM_ALIAS(goto_prev_jump_no_skips)
# define goto_first_error CUSTOM_ALIAS(goto_first_jump)
2017-06-16 23:10:50 +00:00
# include "4coder_default_hooks.cpp"
2017-01-23 06:19:43 +00:00
# include "4coder_helper/4coder_bind_helper.h"
# include "4coder_helper/4coder_helper.h"
# include "4coder_helper/4coder_streaming.h"
# include "4coder_helper/4coder_long_seek.h"
2016-07-13 23:19:42 +00:00
2017-01-23 06:19:43 +00:00
# define FSTRING_IMPLEMENTATION
# include "4coder_lib/4coder_string.h"
# include "4coder_lib/4coder_table.h"
# include "4coder_lib/4coder_mem.h"
2017-02-18 01:04:41 +00:00
# include "4coder_lib/4coder_utf8.h"
2017-01-23 06:19:43 +00:00
2017-11-21 00:35:35 +00:00
# include "4coder_lib/4cpp_lexer.h"
2017-01-23 06:19:43 +00:00
2016-09-01 00:26:52 +00:00
//
2017-01-23 06:19:43 +00:00
// Seeks Using Default Framework Memory
2016-09-01 00:26:52 +00:00
//
2017-03-23 19:15:33 +00:00
static int32_t
buffer_boundary_seek ( Application_Links * app , Buffer_Summary * buffer , int32_t start_pos , bool32 seek_forward , Seek_Boundary_Flag flags ) {
int32_t result = buffer_boundary_seek ( app , buffer , & global_part , start_pos , seek_forward , flags ) ;
2016-09-01 00:26:52 +00:00
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
static void
2017-03-29 16:32:06 +00:00
basic_seek ( Application_Links * app , bool32 seek_forward , uint32_t flags ) {
View_Summary view = get_active_view ( app , AccessProtected ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , AccessProtected ) ;
int32_t pos = buffer_boundary_seek ( app , & buffer , view . cursor . pos , seek_forward , flags ) ;
2017-01-23 06:19:43 +00:00
view_set_cursor ( app , & view , seek_pos ( pos ) , true ) ;
2016-07-11 16:15:37 +00:00
}
2016-07-10 05:49:11 +00:00
2017-01-23 06:19:43 +00:00
# define right true
# define left false
2016-09-15 15:01:52 +00:00
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( seek_whitespace_right )
CUSTOM_DOC ( " Seek right for the next boundary between whitespace and non-whitespace. " )
{ basic_seek ( app , right , BoundaryWhitespace ) ; }
CUSTOM_COMMAND_SIG ( seek_whitespace_left )
CUSTOM_DOC ( " Seek left for the next boundary between whitespace and non-whitespace. " )
{ basic_seek ( app , left , BoundaryWhitespace ) ; }
CUSTOM_COMMAND_SIG ( seek_token_right )
CUSTOM_DOC ( " Seek right for the next end of a token. " )
{ basic_seek ( app , right , BoundaryToken ) ; }
CUSTOM_COMMAND_SIG ( seek_token_left )
CUSTOM_DOC ( " Seek left for the next beginning of a token. " )
{ basic_seek ( app , left , BoundaryToken ) ; }
CUSTOM_COMMAND_SIG ( seek_white_or_token_right )
CUSTOM_DOC ( " Seek right for the next end of a token or boundary between whitespace and non-whitespace. " )
{ basic_seek ( app , right , BoundaryToken | BoundaryWhitespace ) ; }
CUSTOM_COMMAND_SIG ( seek_white_or_token_left )
CUSTOM_DOC ( " Seek left for the next end of a token or boundary between whitespace and non-whitespace. " )
{ basic_seek ( app , left , BoundaryToken | BoundaryWhitespace ) ; }
CUSTOM_COMMAND_SIG ( seek_alphanumeric_right )
CUSTOM_DOC ( " Seek right for boundary between alphanumeric characters and non-alphanumeric characters. " )
{ basic_seek ( app , right , BoundaryAlphanumeric ) ; }
CUSTOM_COMMAND_SIG ( seek_alphanumeric_left )
CUSTOM_DOC ( " Seek left for boundary between alphanumeric characters and non-alphanumeric characters. " )
{ basic_seek ( app , left , BoundaryAlphanumeric ) ; }
CUSTOM_COMMAND_SIG ( seek_alphanumeric_or_camel_right )
CUSTOM_DOC ( " Seek right for boundary between alphanumeric characters or camel case word and non-alphanumeric characters. " )
{ basic_seek ( app , right , BoundaryAlphanumeric | BoundaryCamelCase ) ; }
CUSTOM_COMMAND_SIG ( seek_alphanumeric_or_camel_left )
CUSTOM_DOC ( " Seek left for boundary between alphanumeric characters or camel case word and non-alphanumeric characters. " )
{ basic_seek ( app , left , BoundaryAlphanumeric | BoundaryCamelCase ) ; }
2016-09-15 15:01:52 +00:00
2017-01-23 06:19:43 +00:00
# undef right
# undef left
2016-10-05 06:08:23 +00:00
2016-07-10 05:49:11 +00:00
//
2017-01-29 00:03:23 +00:00
// Fast Deletes
2016-07-10 05:49:11 +00:00
//
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( backspace_word )
CUSTOM_DOC ( " Delete characters between the cursor position and the first alphanumeric boundary to the left. " )
{
2017-01-29 00:03:23 +00:00
uint32_t access = AccessOpen ;
2017-01-23 06:19:43 +00:00
View_Summary view = get_active_view ( app , access ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
2016-07-10 05:49:11 +00:00
2017-01-23 06:19:43 +00:00
if ( buffer . exists ) {
2017-03-23 19:15:33 +00:00
int32_t pos2 = 0 , pos1 = 0 ;
pos2 = view . cursor . pos ;
2017-01-29 00:03:23 +00:00
exec_command ( app , seek_alphanumeric_left ) ;
refresh_view ( app , & view ) ;
2017-03-23 19:15:33 +00:00
pos1 = view . cursor . pos ;
2017-01-29 00:03:23 +00:00
buffer_replace_range ( app , & buffer , pos1 , pos2 , 0 , 0 ) ;
2016-09-15 15:01:52 +00:00
}
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( delete_word )
CUSTOM_DOC ( " Delete characters between the cursor position and the first alphanumeric boundary to the right. " )
{
2017-01-23 06:19:43 +00:00
uint32_t access = AccessOpen ;
2017-01-29 00:03:23 +00:00
2017-01-23 06:19:43 +00:00
View_Summary view = get_active_view ( app , access ) ;
2017-01-29 00:03:23 +00:00
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
if ( buffer . exists ) {
2017-03-23 19:15:33 +00:00
int32_t pos2 = 0 , pos1 = 0 ;
pos1 = view . cursor . pos ;
2017-01-29 00:03:23 +00:00
exec_command ( app , seek_alphanumeric_right ) ;
refresh_view ( app , & view ) ;
2017-03-23 19:15:33 +00:00
pos2 = view . cursor . pos ;
2016-07-10 05:49:11 +00:00
2017-01-29 00:03:23 +00:00
buffer_replace_range ( app , & buffer , pos1 , pos2 , 0 , 0 ) ;
2016-07-10 05:49:11 +00:00
}
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( snipe_token_or_word )
2017-11-29 23:00:14 +00:00
CUSTOM_DOC ( " Delete a single, whole token on or to the left of the cursor and post it to the clipboard. " )
2017-11-15 23:57:21 +00:00
{
2017-01-23 06:19:43 +00:00
uint32_t access = AccessOpen ;
2017-03-23 19:15:33 +00:00
2017-01-29 00:03:23 +00:00
View_Summary view = get_active_view ( app , access ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
2017-11-29 23:00:14 +00:00
int32_t pos1 = buffer_boundary_seek ( app , & buffer , view . cursor . pos , false , BoundaryToken | BoundaryWhitespace ) ;
int32_t pos2 = buffer_boundary_seek ( app , & buffer , pos1 , true , BoundaryToken | BoundaryWhitespace ) ;
2017-01-29 00:03:23 +00:00
Range range = make_range ( pos1 , pos2 ) ;
2017-11-29 23:00:14 +00:00
Partition * part = & global_part ;
Temp_Memory temp = begin_temp_memory ( part ) ;
int32_t len = range . end - range . start ;
char * space = push_array ( part , char , len ) ;
buffer_read_range ( app , & buffer , range . start , range . end , space ) ;
clipboard_post ( app , 0 , space , len ) ;
end_temp_memory ( temp ) ;
2017-01-29 00:03:23 +00:00
buffer_replace_range ( app , & buffer , range . start , range . end , 0 , 0 ) ;
2016-09-08 22:03:43 +00:00
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( snipe_token_or_word_right )
2017-11-29 23:00:14 +00:00
CUSTOM_DOC ( " Delete a single, whole token on or to the right of the cursor and post it to the clipboard. " )
2017-11-15 23:57:21 +00:00
{
2017-11-07 21:35:26 +00:00
uint32_t access = AccessOpen ;
View_Summary view = get_active_view ( app , access ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
2017-11-29 23:00:14 +00:00
int32_t pos2 = buffer_boundary_seek ( app , & buffer , view . cursor . pos , true , BoundaryToken | BoundaryWhitespace ) ;
int32_t pos1 = buffer_boundary_seek ( app , & buffer , pos2 , false , BoundaryToken | BoundaryWhitespace ) ;
2017-11-07 21:35:26 +00:00
Range range = make_range ( pos1 , pos2 ) ;
2017-11-29 23:00:14 +00:00
Partition * part = & global_part ;
Temp_Memory temp = begin_temp_memory ( part ) ;
int32_t len = range . end - range . start ;
char * space = push_array ( part , char , len ) ;
buffer_read_range ( app , & buffer , range . start , range . end , space ) ;
clipboard_post ( app , 0 , space , len ) ;
end_temp_memory ( temp ) ;
2017-11-07 21:35:26 +00:00
buffer_replace_range ( app , & buffer , range . start , range . end , 0 , 0 ) ;
}
2017-01-29 00:03:23 +00:00
2017-11-21 18:25:19 +00:00
//
2017-11-29 23:00:14 +00:00
// Query Replace Selection
2017-11-21 18:25:19 +00:00
//
CUSTOM_COMMAND_SIG ( query_replace_selection )
CUSTOM_DOC ( " Queries the user for a string, and incrementally replace every occurence of the string found in the selected range with the specified string. " )
{
View_Summary view = get_active_view ( app , AccessOpen ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , AccessOpen ) ;
if ( ! buffer . exists ) {
return ;
}
Partition * part = & global_part ;
Temp_Memory temp = begin_temp_memory ( part ) ;
Range range = get_range ( & view ) ;
int32_t replace_length = range . max - range . min ;
if ( replace_length ! = 0 ) {
char * replace_space = push_array ( part , char , replace_length ) ;
if ( buffer_read_range ( app , & buffer , range . min , range . max , replace_space ) ) {
String replace = make_string ( replace_space , replace_length ) ;
query_replace_parameter ( app , replace , range . min , true ) ;
}
}
end_temp_memory ( temp ) ;
}
2017-02-12 23:04:50 +00:00
//
// Line Manipulation
//
2017-11-21 18:25:19 +00:00
CUSTOM_COMMAND_SIG ( move_line_up )
CUSTOM_DOC ( " Swaps the line under the cursor with the line above it, and moves the cursor up with it. " )
{
View_Summary view = get_active_view ( app , AccessOpen ) ;
if ( view . cursor . line < = 1 ) {
return ;
}
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , AccessOpen ) ;
if ( ! buffer . exists ) {
return ;
}
Full_Cursor prev_line_cursor = { 0 } ;
Full_Cursor this_line_cursor = { 0 } ;
Full_Cursor next_line_cursor = { 0 } ;
int32_t this_line = view . cursor . line ;
int32_t prev_line = this_line - 1 ;
int32_t next_line = this_line + 1 ;
if ( view_compute_cursor ( app , & view , seek_line_char ( prev_line , 1 ) , & prev_line_cursor ) & &
view_compute_cursor ( app , & view , seek_line_char ( this_line , 1 ) , & this_line_cursor ) & &
view_compute_cursor ( app , & view , seek_line_char ( next_line , 1 ) , & next_line_cursor ) ) {
int32_t prev_line_pos = prev_line_cursor . pos ;
int32_t this_line_pos = this_line_cursor . pos ;
int32_t next_line_pos = next_line_cursor . pos ;
Partition * part = & global_part ;
Temp_Memory temp = begin_temp_memory ( part ) ;
int32_t length = next_line_pos - prev_line_pos ;
2018-05-07 02:47:22 +00:00
char * swap = push_array ( part , char , length + 1 ) ;
2017-11-21 18:25:19 +00:00
int32_t first_len = next_line_pos - this_line_pos ;
2018-05-07 02:47:22 +00:00
if ( buffer_read_range ( app , & buffer , this_line_pos , next_line_pos , swap ) ) {
2018-05-07 20:05:27 +00:00
bool32 second_line_didnt_have_newline = true ;
for ( int32_t i = first_len - 1 ; i > = 0 ; - - i ) {
if ( swap [ i ] = = ' \n ' ) {
second_line_didnt_have_newline = false ;
break ;
}
}
if ( second_line_didnt_have_newline ) {
2018-05-07 02:47:22 +00:00
swap [ first_len ] = ' \n ' ;
first_len + = 1 ;
// NOTE(allen): Don't increase "length" because then we will be including
// the original newline and addignt this new one, making the file longer
// which shouldn't be possible for this command!
}
if ( buffer_read_range ( app , & buffer , prev_line_pos , this_line_pos , swap + first_len ) ) {
buffer_replace_range ( app , & buffer , prev_line_pos , next_line_pos , swap , length ) ;
view_set_cursor ( app , & view , seek_line_char ( prev_line , 1 ) , true ) ;
}
2017-11-21 18:25:19 +00:00
}
end_temp_memory ( temp ) ;
}
}
CUSTOM_COMMAND_SIG ( move_down_textual )
CUSTOM_DOC ( " Moves down to the next line of actual text, regardless of line wrapping. " )
{
View_Summary view = get_active_view ( app , AccessOpen ) ;
if ( ! view . exists ) {
return ;
}
int32_t next_line = view . cursor . line + 1 ;
view_set_cursor ( app , & view , seek_line_char ( next_line , 1 ) , true ) ;
}
CUSTOM_COMMAND_SIG ( move_line_down )
CUSTOM_DOC ( " Swaps the line under the cursor with the line below it, and moves the cursor down with it. " )
{
View_Summary view = get_active_view ( app , AccessOpen ) ;
if ( ! view . exists ) {
return ;
}
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , AccessOpen ) ;
if ( ! buffer . exists ) {
return ;
}
2018-05-07 02:47:22 +00:00
int32_t next_line = view . cursor . line + 1 ;
Full_Cursor new_cursor = { 0 } ;
if ( view_compute_cursor ( app , & view , seek_line_char ( next_line , 1 ) , & new_cursor ) ) {
if ( new_cursor . line = = next_line ) {
view_set_cursor ( app , & view , seek_pos ( new_cursor . pos ) , true ) ;
move_line_up ( app ) ;
move_down_textual ( app ) ;
}
}
2017-11-21 18:25:19 +00:00
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( duplicate_line )
CUSTOM_DOC ( " Create a copy of the line on which the cursor sits. " )
{
2017-02-12 23:04:50 +00:00
View_Summary view = get_active_view ( app , AccessOpen ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , AccessOpen ) ;
Partition * part = & global_part ;
Temp_Memory temp = begin_temp_memory ( part ) ;
String line_string = { 0 } ;
2018-03-24 10:06:45 +00:00
char * before_line = push_array ( part , char , 1 ) ;
if ( read_line ( app , part , & buffer , view . cursor . line , & line_string ) ) {
* before_line = ' \n ' ;
line_string . str = before_line ;
line_string . size + = 1 ;
int32_t pos = buffer_get_line_end ( app , & buffer , view . cursor . line ) ;
buffer_replace_range ( app , & buffer , pos , pos , line_string . str , line_string . size ) ;
}
2017-02-12 23:04:50 +00:00
end_temp_memory ( temp ) ;
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( delete_line )
CUSTOM_DOC ( " Delete the line the on which the cursor sits. " )
{
2017-02-12 23:04:50 +00:00
View_Summary view = get_active_view ( app , AccessOpen ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , AccessOpen ) ;
Partition * part = & global_part ;
Temp_Memory temp = begin_temp_memory ( part ) ;
2017-03-23 19:15:33 +00:00
int32_t start = buffer_get_line_start ( app , & buffer , view . cursor . line ) ;
int32_t end = buffer_get_line_end ( app , & buffer , view . cursor . line ) + 1 ;
2018-05-07 02:47:22 +00:00
if ( end > buffer . size ) {
end = buffer . size ;
}
if ( start = = end | | buffer_get_char ( app , & buffer , end - 1 ) ! = ' \n ' ) {
start - = 1 ;
if ( start < 0 ) {
start = 0 ;
}
}
2017-02-12 23:04:50 +00:00
buffer_replace_range ( app , & buffer , start , end , 0 , 0 ) ;
end_temp_memory ( temp ) ;
}
2017-01-29 00:03:23 +00:00
//
// Clipboard + Indent Combo Command
//
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( paste_and_indent )
CUSTOM_DOC ( " Paste from the top of clipboard and run auto-indent on the newly pasted text. " )
{
2017-01-23 06:19:43 +00:00
exec_command ( app , paste ) ;
exec_command ( app , auto_tab_range ) ;
2016-09-13 23:59:48 +00:00
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( paste_next_and_indent )
CUSTOM_DOC ( " Paste the next item on the clipboard and run auto-indent on the newly pasted text. " )
{
2017-01-23 06:19:43 +00:00
exec_command ( app , paste_next ) ;
exec_command ( app , auto_tab_range ) ;
2016-03-15 14:12:06 +00:00
}
2017-01-29 00:03:23 +00:00
2017-11-29 23:00:14 +00:00
//
// Approximate Definition Search
//
static void
get_search_definition ( Application_Links * app , Query_Bar * bar , char * string_space , int32_t space_size ) {
bar - > prompt = make_lit_string ( " List Definitions For: " ) ;
bar - > string = make_string_cap ( string_space , 0 , space_size ) ;
if ( ! query_user_string ( app , bar ) ) {
bar - > string . size = 0 ;
}
}
static String
build_string ( Partition * part , char * s1 , char * s2 , char * s3 ) {
String sr = { 0 } ;
sr . memory_size = str_size ( s1 ) + str_size ( s2 ) + str_size ( s3 ) ;
sr . str = push_array ( part , char , sr . memory_size ) ;
append ( & sr , s1 ) ;
append ( & sr , s2 ) ;
append ( & sr , s3 ) ;
return ( sr ) ;
}
static void
list_all_locations_of_type_definition_parameters ( Application_Links * app , char * str ) {
Partition * part = & global_part ;
Temp_Memory temp = begin_temp_memory ( part ) ;
String match_strings [ 6 ] ;
match_strings [ 0 ] = build_string ( part , " struct " , str , " { " ) ;
match_strings [ 1 ] = build_string ( part , " struct " , str , " \n { " ) ;
match_strings [ 2 ] = build_string ( part , " union " , str , " { " ) ;
match_strings [ 3 ] = build_string ( part , " union " , str , " \n { " ) ;
match_strings [ 4 ] = build_string ( part , " enum " , str , " { " ) ;
match_strings [ 5 ] = build_string ( part , " enum " , str , " \n { " ) ;
list_all_locations_parameters ( app , & global_general , part , match_strings , ArrayCount ( match_strings ) , 0 ) ;
end_temp_memory ( temp ) ;
Buffer_Summary buffer = get_buffer_by_name ( app , literal ( " *search* " ) , AccessAll ) ;
if ( buffer . line_count = = 2 ) {
goto_first_jump_same_panel_sticky ( app ) ;
}
}
CUSTOM_COMMAND_SIG ( list_all_locations_of_type_definition )
CUSTOM_DOC ( " Queries user for string, lists all locations of strings that appear to define a type whose name matches the input string. " )
{
char string_space [ 1024 ] ;
Query_Bar bar ;
get_search_definition ( app , & bar , string_space , sizeof ( string_space ) ) ;
if ( bar . string . size = = 0 ) return ;
if ( ! terminate_with_null ( & bar . string ) ) return ;
list_all_locations_of_type_definition_parameters ( app , bar . string . str ) ;
}
CUSTOM_COMMAND_SIG ( list_all_locations_of_type_definition_of_identifier )
CUSTOM_DOC ( " Reads a token or word under the cursor and lists all locations of strings that appear to define a type whose name matches it. " )
{
View_Summary view = get_active_view ( app , AccessProtected ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , AccessProtected ) ;
char space [ 512 ] ;
String str = get_token_or_word_under_pos ( app , & buffer , view . cursor . pos , space , sizeof ( space ) - 1 ) ;
2018-05-07 02:47:22 +00:00
if ( str . size > 0 ) {
str . str [ str . size ] = 0 ;
change_active_panel ( app ) ;
list_all_locations_of_type_definition_parameters ( app , str . str ) ;
}
2017-11-29 23:00:14 +00:00
}
2017-01-29 00:03:23 +00:00
//
// Combined Write Commands
//
2016-06-03 16:20:45 +00:00
2016-10-25 02:45:34 +00:00
static void
write_string ( Application_Links * app , View_Summary * view , Buffer_Summary * buffer , String string ) {
buffer_replace_range ( app , buffer , view - > cursor . pos , view - > cursor . pos , string . str , string . size ) ;
view_set_cursor ( app , view , seek_pos ( view - > cursor . pos + string . size ) , 1 ) ;
}
2016-06-03 16:20:45 +00:00
static void
write_string ( Application_Links * app , String string ) {
2016-08-29 01:03:26 +00:00
uint32_t access = AccessOpen ;
2016-09-17 00:03:09 +00:00
View_Summary view = get_active_view ( app , access ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
2016-10-25 02:45:34 +00:00
write_string ( app , & view , & buffer , string ) ;
2016-06-03 16:20:45 +00:00
}
2016-03-15 14:12:06 +00:00
static void
2016-08-29 01:03:26 +00:00
long_braces ( Application_Links * app , char * text , int32_t size ) {
uint32_t access = AccessOpen ;
2016-09-17 00:03:09 +00:00
View_Summary view = get_active_view ( app , access ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
2017-03-23 19:15:33 +00:00
int32_t pos = view . cursor . pos ;
2016-06-13 16:56:33 +00:00
2016-09-17 00:03:09 +00:00
buffer_replace_range ( app , & buffer , pos , pos , text , size ) ;
view_set_cursor ( app , & view , seek_pos ( pos + 2 ) , true ) ;
2016-06-13 16:56:33 +00:00
2017-11-28 23:31:10 +00:00
buffer_auto_indent ( app , & global_part , & buffer , pos , pos + size , DEF_TAB_WIDTH , DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens ) ;
2016-06-24 03:11:24 +00:00
move_past_lead_whitespace ( app , & view , & buffer ) ;
2016-03-15 14:12:06 +00:00
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( open_long_braces )
CUSTOM_DOC ( " At the cursor, insert a '{' and '}' separated by a blank line. " )
{
2016-03-15 14:12:06 +00:00
char text [ ] = " { \n \n } " ;
2016-08-29 01:03:26 +00:00
int32_t size = sizeof ( text ) - 1 ;
2016-03-15 14:12:06 +00:00
long_braces ( app , text , size ) ;
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( open_long_braces_semicolon )
CUSTOM_DOC ( " At the cursor, insert a '{' and '};' separated by a blank line. " )
{
2016-03-15 14:12:06 +00:00
char text [ ] = " { \n \n }; " ;
2016-08-29 01:03:26 +00:00
int32_t size = sizeof ( text ) - 1 ;
2016-03-15 14:12:06 +00:00
long_braces ( app , text , size ) ;
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( open_long_braces_break )
CUSTOM_DOC ( " At the cursor, insert a '{' and '}break;' separated by a blank line. " )
{
2016-03-15 14:12:06 +00:00
char text [ ] = " { \n \n }break; " ;
2016-08-29 01:03:26 +00:00
int32_t size = sizeof ( text ) - 1 ;
2016-03-15 14:12:06 +00:00
long_braces ( app , text , size ) ;
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( if0_off )
CUSTOM_DOC ( " Surround the range between the cursor and mark with an '#if 0' and an '#endif' " )
{
2017-11-29 23:00:14 +00:00
place_begin_and_end_on_own_lines ( app , & global_part , " #if 0 " , " #endif " ) ;
2016-03-15 14:12:06 +00:00
}
2017-07-11 21:41:25 +00:00
static void
write_named_comment_string ( Application_Links * app , char * type_string ) {
2017-01-29 00:03:23 +00:00
char space [ 512 ] ;
String str = make_fixed_width_string ( space ) ;
2016-06-20 20:34:48 +00:00
2017-01-29 00:03:23 +00:00
char * name = 0 ;
int32_t name_len = 0 ;
if ( get_current_name ( & name , & name_len ) ) {
2017-07-11 21:41:25 +00:00
append ( & str , " // " ) ;
append ( & str , type_string ) ;
append ( & str , " ( " ) ;
2017-01-29 00:03:23 +00:00
append ( & str , make_string ( name , name_len ) ) ;
append ( & str , " ): " ) ;
}
else {
2017-07-11 21:41:25 +00:00
append ( & str , " // " ) ;
append ( & str , type_string ) ;
append ( & str , " : " ) ;
2017-01-23 06:19:43 +00:00
}
2017-01-29 00:03:23 +00:00
write_string ( app , str ) ;
2016-03-15 14:12:06 +00:00
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( write_todo )
CUSTOM_DOC ( " At the cursor, insert a '// TODO' comment, includes user name if it was specified in config.4coder. " )
{
2017-07-11 21:41:25 +00:00
write_named_comment_string ( app , " TODO " ) ;
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( write_hack )
CUSTOM_DOC ( " At the cursor, insert a '// HACK' comment, includes user name if it was specified in config.4coder. " )
{
2017-07-11 21:41:25 +00:00
write_named_comment_string ( app , " HACK " ) ;
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( write_note )
CUSTOM_DOC ( " At the cursor, insert a '// NOTE' comment, includes user name if it was specified in config.4coder. " )
{
2017-07-11 21:41:25 +00:00
write_named_comment_string ( app , " NOTE " ) ;
2016-03-15 14:12:06 +00:00
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( write_block )
CUSTOM_DOC ( " At the cursor, insert a block comment. " )
{
2017-01-29 00:03:23 +00:00
write_string ( app , make_lit_string ( " /* */ " ) ) ;
2017-01-23 06:19:43 +00:00
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( write_zero_struct )
CUSTOM_DOC ( " At the cursor, insert a ' = {0};'. " )
{
2017-01-29 00:03:23 +00:00
write_string ( app , make_lit_string ( " = {0}; " ) ) ;
}
2017-01-23 06:19:43 +00:00
//
// Open File In Quotes
//
2017-02-12 06:01:01 +00:00
static bool32
2017-01-23 06:19:43 +00:00
file_name_in_quotes ( Application_Links * app , String * file_name ) {
2017-02-12 06:01:01 +00:00
bool32 result = false ;
2017-01-23 06:19:43 +00:00
uint32_t access = AccessProtected ;
2016-06-20 20:34:48 +00:00
2017-02-12 06:01:01 +00:00
View_Summary view = get_active_view ( app , access ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
2017-01-23 06:19:43 +00:00
2017-02-12 06:01:01 +00:00
if ( buffer . file_name ! = 0 ) {
2017-03-23 19:15:33 +00:00
int32_t pos = view . cursor . pos ;
int32_t start = 0 , end = 0 ;
2017-02-12 06:01:01 +00:00
buffer_seek_delimiter_forward ( app , & buffer , pos , ' " ' , & end ) ;
buffer_seek_delimiter_backward ( app , & buffer , pos , ' " ' , & start ) ;
+ + start ;
2017-03-23 19:15:33 +00:00
int32_t size = end - start ;
2017-02-12 06:01:01 +00:00
char short_file_name [ 128 ] ;
// NOTE(allen): This check is necessary because buffer_read_range
// requiers that the output buffer you provide is at least (end - start) bytes long.
if ( size < sizeof ( short_file_name ) ) {
if ( buffer_read_range ( app , & buffer , start , end , short_file_name ) ) {
result = true ;
copy_ss ( file_name , make_string ( buffer . file_name , buffer . file_name_len ) ) ;
remove_last_folder ( file_name ) ;
2017-03-23 19:15:33 +00:00
append_ss ( file_name , make_string ( short_file_name , size ) ) ;
2017-02-12 06:01:01 +00:00
}
2016-03-15 14:12:06 +00:00
}
}
2016-06-20 20:34:48 +00:00
2017-01-23 06:19:43 +00:00
return ( result ) ;
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( open_file_in_quotes )
CUSTOM_DOC ( " Reads a filename from surrounding ' \" ' characters and attempts to open the corresponding file. " )
{
2017-01-23 06:19:43 +00:00
char file_name_ [ 256 ] ;
String file_name = make_fixed_width_string ( file_name_ ) ;
2016-06-20 20:34:48 +00:00
2017-01-23 06:19:43 +00:00
if ( file_name_in_quotes ( app , & file_name ) ) {
exec_command ( app , change_active_panel ) ;
View_Summary view = get_active_view ( app , AccessAll ) ;
view_open_file ( app , & view , expand_str ( file_name ) , true ) ;
}
}
2017-11-29 23:00:14 +00:00
//
// File Navigating
//
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( open_in_other )
CUSTOM_DOC ( " Reads a filename from surrounding ' \" ' characters and attempts to open the corresponding file, displaying it in the other view. " )
{
2017-01-23 06:19:43 +00:00
exec_command ( app , change_active_panel ) ;
2017-11-10 18:56:17 +00:00
exec_command ( app , interactive_open_or_new ) ;
2016-03-15 14:12:06 +00:00
}
2017-02-06 13:49:00 +00:00
static bool32
get_cpp_matching_file ( Application_Links * app , Buffer_Summary buffer , Buffer_Summary * buffer_out ) {
bool32 result = false ;
2017-02-12 06:01:01 +00:00
if ( buffer . file_name ! = 0 ) {
char space [ 512 ] ;
String file_name = make_string_cap ( space , 0 , sizeof ( space ) ) ;
append ( & file_name , make_string ( buffer . file_name , buffer . file_name_len ) ) ;
String extension = file_extension ( file_name ) ;
String new_extensions [ 2 ] = { 0 } ;
int32_t new_extensions_count = 0 ;
if ( match ( extension , " cpp " ) | | match ( extension , " cc " ) ) {
new_extensions [ 0 ] = make_lit_string ( " h " ) ;
new_extensions [ 1 ] = make_lit_string ( " hpp " ) ;
new_extensions_count = 2 ;
}
else if ( match ( extension , " c " ) ) {
new_extensions [ 0 ] = make_lit_string ( " h " ) ;
new_extensions_count = 1 ;
}
else if ( match ( extension , " h " ) ) {
new_extensions [ 0 ] = make_lit_string ( " c " ) ;
new_extensions [ 1 ] = make_lit_string ( " cpp " ) ;
new_extensions_count = 2 ;
}
else if ( match ( extension , " hpp " ) ) {
new_extensions [ 0 ] = make_lit_string ( " cpp " ) ;
new_extensions_count = 1 ;
}
2017-02-06 13:49:00 +00:00
2017-02-12 06:01:01 +00:00
remove_extension ( & file_name ) ;
int32_t base_pos = file_name . size ;
for ( int32_t i = 0 ; i < new_extensions_count ; + + i ) {
String ext = new_extensions [ i ] ;
file_name . size = base_pos ;
append ( & file_name , ext ) ;
if ( open_file ( app , buffer_out , file_name . str , file_name . size , false , true ) ) {
result = true ;
break ;
}
2017-02-06 13:49:00 +00:00
}
}
return ( result ) ;
}
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( open_matching_file_cpp )
CUSTOM_DOC ( " If the current file is a *.cpp or *.h, attempts to open the corresponding *.h or *.cpp file in the other view. " )
{
2017-02-06 13:49:00 +00:00
View_Summary view = get_active_view ( app , AccessAll ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , AccessAll ) ;
Buffer_Summary new_buffer = { 0 } ;
if ( get_cpp_matching_file ( app , buffer , & new_buffer ) ) {
get_view_next_looped ( app , & view , AccessAll ) ;
view_set_buffer ( app , & view , new_buffer . buffer_id , 0 ) ;
set_active_view ( app , & view ) ;
}
}
2017-11-29 23:00:14 +00:00
CUSTOM_COMMAND_SIG ( view_buffer_other_panel )
CUSTOM_DOC ( " Set the other non-active panel to view the buffer that the active panel views, and switch to that panel. " )
{
View_Summary view = get_active_view ( app , AccessAll ) ;
int32_t buffer_id = view . buffer_id ;
change_active_panel ( app ) ;
view = get_active_view ( app , AccessAll ) ;
view_set_buffer ( app , & view , buffer_id , 0 ) ;
}
CUSTOM_COMMAND_SIG ( swap_buffers_between_panels )
CUSTOM_DOC ( " Set the other non-active panel to view the buffer that the active panel views, and switch to that panel. " )
{
View_Summary view1 = get_active_view ( app , AccessAll ) ;
change_active_panel ( app ) ;
View_Summary view2 = get_active_view ( app , AccessAll ) ;
if ( view1 . view_id ! = view2 . view_id ) {
int32_t buffer_id1 = view1 . buffer_id ;
int32_t buffer_id2 = view2 . buffer_id ;
view_set_buffer ( app , & view1 , buffer_id2 , 0 ) ;
view_set_buffer ( app , & view2 , buffer_id1 , 0 ) ;
}
}
2017-02-06 13:49:00 +00:00
2016-07-10 05:49:11 +00:00
//
2017-01-29 00:03:23 +00:00
// Execute Arbitrary Command
2016-09-01 19:40:25 +00:00
//
2017-11-15 23:57:21 +00:00
CUSTOM_COMMAND_SIG ( execute_arbitrary_command )
CUSTOM_DOC ( " Execute a 'long form' command. " )
{
2017-01-29 00:03:23 +00:00
// NOTE(allen): This isn't a super powerful version of this command, I will expand
// upon it so that it has all the cmdid_* commands by default. However, with this
// as an example you have everything you need to make it work already. You could
// even use app->memory to create a hash table in the start hook.
2017-11-08 21:28:44 +00:00
Query_Bar bar = { 0 } ;
2017-01-29 00:03:23 +00:00
char space [ 1024 ] ;
bar . prompt = make_lit_string ( " Command: " ) ;
bar . string = make_fixed_width_string ( space ) ;
2016-09-01 19:40:25 +00:00
2017-01-29 00:03:23 +00:00
if ( ! query_user_string ( app , & bar ) ) return ;
2016-09-01 19:40:25 +00:00
2017-01-29 00:03:23 +00:00
// NOTE(allen): Here I chose to end this query bar because when I call another
// command it might ALSO have query bars and I don't want this one hanging
// around at that point. Since the bar exists on my stack the result of the query
// is still available in bar.string though.
end_query_bar ( app , & bar , 0 ) ;
2016-09-01 19:40:25 +00:00
2017-01-29 00:03:23 +00:00
if ( match_ss ( bar . string , make_lit_string ( " load project " ) ) ) {
2017-11-21 19:48:04 +00:00
load_project ( app ) ;
2016-09-01 19:40:25 +00:00
}
2017-01-29 00:03:23 +00:00
else if ( match_ss ( bar . string , make_lit_string ( " open all code " ) ) ) {
2017-11-21 19:48:04 +00:00
open_all_code ( app ) ;
2016-09-01 19:40:25 +00:00
}
2017-02-06 13:49:00 +00:00
else if ( match_ss ( bar . string , make_lit_string ( " open all code recursive " ) ) ) {
2017-11-21 19:48:04 +00:00
open_all_code_recursive ( app ) ;
2017-02-06 13:49:00 +00:00
}
2017-01-29 00:03:23 +00:00
else if ( match_ss ( bar . string , make_lit_string ( " close all code " ) ) ) {
2017-11-21 19:48:04 +00:00
close_all_code ( app ) ;
2016-09-01 19:40:25 +00:00
}
2017-03-03 23:57:11 +00:00
else if ( match_ss ( bar . string , make_lit_string ( " dos lines " ) ) | |
match_ss ( bar . string , make_lit_string ( " dosify " ) ) ) {
2017-11-21 19:48:04 +00:00
eol_dosify ( app ) ;
2016-09-01 19:40:25 +00:00
}
2017-03-03 23:57:11 +00:00
else if ( match_ss ( bar . string , make_lit_string ( " nix lines " ) ) | |
match_ss ( bar . string , make_lit_string ( " nixify " ) ) ) {
2017-11-21 19:48:04 +00:00
eol_nixify ( app ) ;
2016-12-24 21:09:53 +00:00
}
2017-11-08 21:28:44 +00:00
else if ( match_ss ( bar . string , make_lit_string ( " remap " ) ) ) {
2017-11-21 19:48:04 +00:00
remap_interactive ( app ) ;
2017-11-08 21:28:44 +00:00
}
2017-11-09 18:30:24 +00:00
else if ( match_ss ( bar . string , make_lit_string ( " new project " ) ) ) {
2017-11-21 19:48:04 +00:00
setup_new_project ( app ) ;
}
else if ( match_ss ( bar . string , make_lit_string ( " delete file " ) ) ) {
2017-11-21 21:30:40 +00:00
delete_file_query ( app ) ;
}
else if ( match_ss ( bar . string , make_lit_string ( " rename file " ) ) ) {
rename_file_query ( app ) ;
2017-11-09 18:30:24 +00:00
}
2017-11-21 21:47:40 +00:00
else if ( match_ss ( bar . string , make_lit_string ( " mkdir " ) ) ) {
make_directory_query ( app ) ;
}
2016-12-24 21:09:53 +00:00
else {
2017-01-29 00:03:23 +00:00
print_message ( app , literal ( " unrecognized command \n " ) ) ;
2016-12-26 22:49:01 +00:00
}
}
2017-11-08 18:24:30 +00:00
# include "4coder_remapping_commands.cpp"
2016-12-26 22:49:01 +00:00
# endif
2017-01-23 06:19:43 +00:00
2017-01-29 00:03:23 +00:00
// BOTTOM
2016-08-22 19:31:19 +00:00