2017-01-29 00:03:23 +00:00
/*
4 coder_default_include . cpp - Default set of commands and setup used in 4 coder .
2016-03-15 14:12:06 +00:00
2017-01-29 00:03:23 +00:00
TYPE : ' major - system - include '
*/
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"
2016-03-15 14:12:06 +00:00
2017-01-23 06:19:43 +00:00
# include "4coder_default_framework.h"
# include "4coder_base_commands.cpp"
# include "4coder_auto_indent.cpp"
# include "4coder_search.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 )
CUSTOM_DOC ( " Delete a single, whole token on or to the left of the cursor. " )
{
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-07 21:35:26 +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 ) ;
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 )
CUSTOM_DOC ( " Delete a single, whole token on or to the right of the cursor. " )
{
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 ) ;
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 ) ;
Range range = make_range ( pos1 , pos2 ) ;
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
//
// Quer Replace Selection
//
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 ;
char * swap = push_array ( part , char , length ) ;
int32_t first_len = next_line_pos - this_line_pos ;
if ( buffer_read_range ( app , & buffer , this_line_pos , next_line_pos , swap ) & &
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 ) ;
}
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 ;
}
move_down_textual ( app ) ;
move_line_up ( app ) ;
move_down_textual ( app ) ;
}
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 } ;
read_line ( app , part , & buffer , view . cursor . line , & line_string ) ;
push_array ( part , char , 1 ) ;
+ + line_string . memory_size ;
append_s_char ( & line_string , ' \n ' ) ;
2017-03-23 19:15:33 +00:00
int32_t pos = buffer_get_line_end ( app , & buffer , view . cursor . line ) + 1 ;
2017-02-12 23:04:50 +00:00
buffer_replace_range ( app , & buffer , pos , pos , line_string . str , line_string . size ) ;
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 ;
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
//
// 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
2016-12-18 20:42:11 +00:00
buffer_auto_indent ( app , & 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' " )
{
2016-05-23 14:41:39 +00:00
char text1 [ ] = " \n #if 0 " ;
2016-08-29 01:03:26 +00:00
int32_t size1 = sizeof ( text1 ) - 1 ;
2016-06-21 14:00:07 +00:00
2016-05-23 14:41:39 +00:00
char text2 [ ] = " #endif \n " ;
2016-08-29 01:03:26 +00:00
int32_t size2 = sizeof ( text2 ) - 1 ;
2016-06-21 14:00:07 +00:00
2016-09-17 00:03:09 +00:00
View_Summary view = get_active_view ( app , AccessOpen ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , AccessOpen ) ;
2016-06-10 15:19:29 +00:00
2016-07-13 23:19:42 +00:00
Range range = get_range ( & view ) ;
2016-06-10 15:19:29 +00:00
2016-07-13 23:19:42 +00:00
if ( range . min < range . max ) {
Buffer_Edit edits [ 2 ] ;
char * str = 0 ;
char * base = ( char * ) partition_current ( & global_part ) ;
str = push_array ( & global_part , char , size1 ) ;
memcpy ( str , text1 , size1 ) ;
2016-08-29 01:03:26 +00:00
edits [ 0 ] . str_start = ( int32_t ) ( str - base ) ;
2016-07-13 23:19:42 +00:00
edits [ 0 ] . len = size1 ;
edits [ 0 ] . start = range . min ;
edits [ 0 ] . end = range . min ;
str = push_array ( & global_part , char , size2 ) ;
memcpy ( str , text2 , size2 ) ;
2016-08-29 01:03:26 +00:00
edits [ 1 ] . str_start = ( int32_t ) ( str - base ) ;
2016-07-13 23:19:42 +00:00
edits [ 1 ] . len = size2 ;
edits [ 1 ] . start = range . max ;
edits [ 1 ] . end = range . max ;
2017-01-14 03:01:35 +00:00
buffer_batch_edit ( app , & buffer , base , global_part . pos , edits , ArrayCount ( edits ) , BatchEdit_Normal ) ;
2016-07-13 23:19:42 +00:00
2016-09-17 00:03:09 +00:00
view = get_view ( app , view . view_id , AccessAll ) ;
2016-07-13 23:19:42 +00:00
if ( view . cursor . pos > view . mark . pos ) {
2016-12-18 20:42:11 +00:00
view_set_cursor ( app , & view , seek_line_char ( view . cursor . line + 1 , view . cursor . character ) , 1 ) ;
2016-07-13 23:19:42 +00:00
}
else {
2016-12-18 20:42:11 +00:00
view_set_mark ( app , & view , seek_line_char ( view . mark . line + 1 , view . mark . character ) ) ;
2016-07-13 23:19:42 +00:00
}
range = get_range ( & view ) ;
2016-12-18 20:42:11 +00:00
buffer_auto_indent ( app , & buffer , range . min , range . max , DEF_TAB_WIDTH , DEFAULT_INDENT_FLAGS | AutoIndent_FullTokens ) ;
2016-07-13 23:19:42 +00:00
move_past_lead_whitespace ( app , & view , & buffer ) ;
}
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-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
//
// File Navigating
//
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 ) ;
}
}
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 " ) ) ) {
delete_file ( app ) ;
2017-11-09 18:30:24 +00:00
}
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