2016-03-15 14:12:06 +00:00
2016-06-28 22:58:50 +00:00
# ifndef FCODER_DEFAULT_INCLUDE
# define FCODER_DEFAULT_INCLUDE
2017-01-23 06:19:43 +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_jump_parsing.cpp"
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"
2016-05-27 14:51:12 +00:00
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"
# include "4cpp/4cpp_lexer.h"
# include <assert.h>
2016-07-17 02:24:13 +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
//
static int32_t
2017-01-23 06:19:43 +00:00
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
basic_seek ( Application_Links * app , int32_t seek_type , uint32_t flags ) {
uint32_t access = AccessProtected ;
View_Summary view = get_active_view ( app , access ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
int32_t pos = buffer_boundary_seek ( app , & buffer , view . cursor . pos , seek_type , flags ) ;
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 seek_command(n, dir, flags) CUSTOM_COMMAND_SIG(seek_##n##_##dir){ basic_seek(app, dir, flags); }
2016-10-05 06:08:23 +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-01-23 06:19:43 +00:00
seek_command ( whitespace , right , BoundaryWhitespace )
seek_command ( whitespace , left , BoundaryWhitespace )
seek_command ( token , right , BoundaryToken )
seek_command ( token , left , BoundaryToken )
seek_command ( white_or_token , right , BoundaryToken | BoundaryWhitespace )
seek_command ( white_or_token , left , BoundaryToken | BoundaryWhitespace )
seek_command ( alphanumeric , right , BoundaryAlphanumeric )
seek_command ( alphanumeric , left , BoundaryAlphanumeric )
seek_command ( alphanumeric_or_camel , right , BoundaryAlphanumeric | BoundaryCamelCase )
seek_command ( alphanumeric_or_camel , 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-23 06:19:43 +00:00
// Clipboard
2016-07-10 05:49:11 +00:00
//
2016-09-15 15:01:52 +00:00
static bool32
2017-01-23 06:19:43 +00:00
clipboard_copy ( Application_Links * app , int32_t start , int32_t end , Buffer_Summary * buffer_out ,
uint32_t access ) {
View_Summary view = get_active_view ( app , access ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
2016-09-15 15:01:52 +00:00
bool32 result = 0 ;
2016-07-10 05:49:11 +00:00
2017-01-23 06:19:43 +00:00
if ( buffer . exists ) {
if ( 0 < = start & & start < = end & & end < = buffer . size ) {
int32_t size = ( end - start ) ;
char * str = ( char * ) app - > memory ;
if ( size < = app - > memory_size ) {
buffer_read_range ( app , & buffer , start , end , str ) ;
clipboard_post ( app , 0 , str , size ) ;
if ( buffer_out ) { * buffer_out = buffer ; }
result = 1 ;
}
2016-07-10 05:49:11 +00:00
}
}
2016-09-08 00:32:31 +00:00
2016-09-15 15:01:52 +00:00
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
static int32_t
clipboard_cut ( Application_Links * app , int32_t start , int32_t end , Buffer_Summary * buffer_out , uint32_t access ) {
Buffer_Summary buffer = { 0 } ;
int32_t result = false ;
2016-09-15 15:01:52 +00:00
2017-01-23 06:19:43 +00:00
if ( clipboard_copy ( app , start , end , & buffer , access ) ) {
buffer_replace_range ( app , & buffer , start , end , 0 , 0 ) ;
if ( buffer_out ) { * buffer_out = buffer ; }
2016-09-15 15:01:52 +00:00
}
return ( result ) ;
}
2017-01-23 06:19:43 +00:00
CUSTOM_COMMAND_SIG ( copy ) {
uint32_t access = AccessProtected ;
View_Summary view = get_active_view ( app , access ) ;
Range range = get_range ( & view ) ;
clipboard_copy ( app , range . min , range . max , 0 , access ) ;
2016-09-16 14:10:45 +00:00
}
2017-01-23 06:19:43 +00:00
CUSTOM_COMMAND_SIG ( cut ) {
uint32_t access = AccessOpen ;
View_Summary view = get_active_view ( app , access ) ;
Range range = get_range ( & view ) ;
clipboard_cut ( app , range . min , range . max , 0 , access ) ;
2016-09-16 14:10:45 +00:00
}
2017-01-23 06:19:43 +00:00
CUSTOM_COMMAND_SIG ( paste ) {
uint32_t access = AccessOpen ;
int32_t count = clipboard_count ( app , 0 ) ;
if ( count > 0 ) {
View_Summary view = get_active_view ( app , access ) ;
2016-09-15 15:01:52 +00:00
2017-01-23 06:19:43 +00:00
view_paste_index [ view . view_id ] . next_rewrite = RewritePaste ;
2016-09-15 15:01:52 +00:00
2017-01-23 06:19:43 +00:00
int32_t paste_index = 0 ;
view_paste_index [ view . view_id ] . index = paste_index ;
2016-09-15 15:01:52 +00:00
2017-01-23 06:19:43 +00:00
int32_t len = clipboard_index ( app , 0 , paste_index , 0 , 0 ) ;
char * str = 0 ;
2016-09-15 15:01:52 +00:00
2017-01-23 06:19:43 +00:00
if ( len < = app - > memory_size ) {
str = ( char * ) app - > memory ;
2016-09-15 15:01:52 +00:00
}
2016-07-10 05:49:11 +00:00
2017-01-23 06:19:43 +00:00
if ( str ) {
clipboard_index ( app , 0 , paste_index , str , len ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
int32_t pos = view . cursor . pos ;
buffer_replace_range ( app , & buffer , pos , pos , str , len ) ;
view_set_mark ( app , & view , seek_pos ( pos ) ) ;
view_set_cursor ( app , & view , seek_pos ( pos + len ) , true ) ;
// TODO(allen): Send this to all views.
Theme_Color paste ;
paste . tag = Stag_Paste ;
get_theme_colors ( app , & paste , 1 ) ;
view_post_fade ( app , & view , 0.667f , pos , pos + len , paste . color ) ;
2016-07-10 05:49:11 +00:00
}
}
}
2017-01-23 06:19:43 +00:00
CUSTOM_COMMAND_SIG ( paste_next ) {
uint32_t access = AccessOpen ;
int32_t count = clipboard_count ( app , 0 ) ;
if ( count > 0 ) {
View_Summary view = get_active_view ( app , access ) ;
2016-07-10 05:49:11 +00:00
2017-01-23 06:19:43 +00:00
if ( view_paste_index [ view . view_id ] . rewrite = = RewritePaste ) {
view_paste_index [ view . view_id ] . next_rewrite = RewritePaste ;
2016-07-10 05:49:11 +00:00
2017-01-23 06:19:43 +00:00
int32_t paste_index = view_paste_index [ view . view_id ] . index + 1 ;
view_paste_index [ view . view_id ] . index = paste_index ;
2016-09-08 22:03:43 +00:00
2017-01-23 06:19:43 +00:00
int32_t len = clipboard_index ( app , 0 , paste_index , 0 , 0 ) ;
char * str = 0 ;
if ( len < = app - > memory_size ) {
str = ( char * ) app - > memory ;
2016-09-08 22:03:43 +00:00
}
2017-01-23 06:19:43 +00:00
if ( str ) {
clipboard_index ( app , 0 , paste_index , str , len ) ;
Buffer_Summary buffer = get_buffer ( app , view . buffer_id , access ) ;
Range range = get_range ( & view ) ;
int32_t pos = range . min ;
buffer_replace_range ( app , & buffer , range . min , range . max , str , len ) ;
view_set_cursor ( app , & view , seek_pos ( pos + len ) , true ) ;
// TODO(allen): Send this to all views.
Theme_Color paste ;
paste . tag = Stag_Paste ;
get_theme_colors ( app , & paste , 1 ) ;
view_post_fade ( app , & view , 0.667f , pos , pos + len , paste . color ) ;
2016-09-08 22:03:43 +00:00
}
}
2017-01-23 06:19:43 +00:00
else {
exec_command ( app , paste ) ;
}
2016-09-08 22:03:43 +00:00
}
}
2017-01-23 06:19:43 +00:00
CUSTOM_COMMAND_SIG ( paste_and_indent ) {
exec_command ( app , paste ) ;
exec_command ( app , auto_tab_range ) ;
2016-09-13 23:59:48 +00:00
}
2017-01-23 06:19:43 +00:00
CUSTOM_COMMAND_SIG ( paste_next_and_indent ) {
exec_command ( app , paste_next ) ;
exec_command ( app , auto_tab_range ) ;
2016-03-15 14:12:06 +00:00
}
2017-01-23 06:19:43 +00:00
//////////////////////////
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 ) ;
2016-08-29 01:03:26 +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
}
CUSTOM_COMMAND_SIG ( open_long_braces ) {
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 ) ;
}
CUSTOM_COMMAND_SIG ( open_long_braces_semicolon ) {
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 ) ;
}
CUSTOM_COMMAND_SIG ( open_long_braces_break ) {
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 ) ;
}
CUSTOM_COMMAND_SIG ( if0_off ) {
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
}
2016-07-10 05:49:11 +00:00
2016-06-28 19:48:12 +00:00
//
2016-07-10 05:49:11 +00:00
// Fast Deletes
2016-06-28 19:48:12 +00:00
//
2016-03-15 14:12:06 +00:00
CUSTOM_COMMAND_SIG ( backspace_word ) {
2016-08-29 01:03:26 +00:00
uint32_t access = AccessOpen ;
2016-06-20 20:34:48 +00:00
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-06-10 15:19:29 +00:00
2016-07-14 17:18:40 +00:00
if ( buffer . exists ) {
2016-08-29 01:03:26 +00:00
int32_t pos2 = 0 , pos1 = 0 ;
2016-07-14 17:18:40 +00:00
pos2 = view . cursor . pos ;
exec_command ( app , seek_alphanumeric_left ) ;
refresh_view ( app , & view ) ;
pos1 = view . cursor . pos ;
2016-08-29 01:03:26 +00:00
2016-09-17 00:03:09 +00:00
buffer_replace_range ( app , & buffer , pos1 , pos2 , 0 , 0 ) ;
2017-01-23 06:19:43 +00:00
}
2016-03-15 14:12:06 +00:00
}
2017-01-23 06:19:43 +00:00
CUSTOM_COMMAND_SIG ( delete_word ) {
2016-08-29 01:03:26 +00:00
uint32_t access = AccessOpen ;
2017-01-23 06:19:43 +00:00
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-06-20 20:34:48 +00:00
2017-01-23 06:19:43 +00:00
if ( buffer . exists ) {
int32_t pos2 = 0 , pos1 = 0 ;
pos1 = view . cursor . pos ;
exec_command ( app , seek_alphanumeric_right ) ;
2016-06-23 23:11:09 +00:00
refresh_view ( app , & view ) ;
2017-01-23 06:19:43 +00:00
pos2 = view . cursor . pos ;
buffer_replace_range ( app , & buffer , pos1 , pos2 , 0 , 0 ) ;
2016-03-15 14:12:06 +00:00
}
}
2017-01-23 06:19:43 +00:00
CUSTOM_COMMAND_SIG ( snipe_token_or_word ) {
uint32_t access = AccessOpen ;
2016-06-20 20:34:48 +00:00
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-06-20 20:34:48 +00:00
2017-01-23 06:19:43 +00:00
int32_t pos1 = buffer_boundary_seek ( app , & buffer , view . cursor . pos , 0 , BoundaryToken | BoundaryWhitespace ) ;
int32_t pos2 = buffer_boundary_seek ( app , & buffer , pos1 , 1 , BoundaryToken | BoundaryWhitespace ) ;
2016-06-20 20:34:48 +00:00
2017-01-23 06:19:43 +00:00
Range range = make_range ( pos1 , pos2 ) ;
buffer_replace_range ( app , & buffer , range . start , range . end , 0 , 0 ) ;
}
//
// Open File In Quotes
//
static int32_t
file_name_in_quotes ( Application_Links * app , String * file_name ) {
int32_t result = false ;
uint32_t access = AccessProtected ;
2016-06-20 20:34:48 +00:00
2016-03-15 14:12:06 +00:00
View_Summary view ;
2017-01-23 06:19:43 +00:00
Buffer_Summary buffer ;
char short_file_name [ 128 ] ;
int32_t pos , start , end , size ;
2016-06-20 20:34:48 +00:00
2016-09-17 00:03:09 +00:00
view = get_active_view ( app , access ) ;
buffer = get_buffer ( app , view . buffer_id , access ) ;
2016-03-15 14:12:06 +00:00
pos = view . cursor . pos ;
2017-01-23 06:19:43 +00:00
buffer_seek_delimiter_forward ( app , & buffer , pos , ' " ' , & end ) ;
buffer_seek_delimiter_backward ( app , & buffer , pos , ' " ' , & start ) ;
2016-06-20 20:34:48 +00:00
2017-01-23 06:19:43 +00:00
+ + start ;
size = end - start ;
// 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 ) ;
append_ss ( file_name , make_string ( short_file_name , size ) ) ;
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 ) ;
}
CUSTOM_COMMAND_SIG ( open_file_in_quotes ) {
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 ) ;
}
}
CUSTOM_COMMAND_SIG ( open_in_other ) {
exec_command ( app , change_active_panel ) ;
exec_command ( app , interactive_open ) ;
2016-03-15 14:12:06 +00:00
}
2017-01-23 06:19:43 +00:00
2016-07-10 05:49:11 +00:00
//
2017-01-23 06:19:43 +00:00
// System Commands
2016-07-10 05:49:11 +00:00
//
2016-12-26 22:49:01 +00:00
static char out_buffer_space [ 1024 ] ;
static char command_space [ 1024 ] ;
static char hot_directory_space [ 1024 ] ;
2016-05-10 17:36:53 +00:00
2016-03-15 14:12:06 +00:00
CUSTOM_COMMAND_SIG ( execute_any_cli ) {
2016-07-10 05:49:11 +00:00
Query_Bar bar_out = { 0 } ;
Query_Bar bar_cmd = { 0 } ;
2016-06-13 16:56:33 +00:00
2016-03-15 14:12:06 +00:00
bar_out . prompt = make_lit_string ( " Output Buffer: " ) ;
2016-05-10 17:36:53 +00:00
bar_out . string = make_fixed_width_string ( out_buffer_space ) ;
2016-03-15 14:12:06 +00:00
if ( ! query_user_string ( app , & bar_out ) ) return ;
2016-06-13 16:56:33 +00:00
2016-03-15 14:12:06 +00:00
bar_cmd . prompt = make_lit_string ( " Command: " ) ;
2016-05-10 17:36:53 +00:00
bar_cmd . string = make_fixed_width_string ( command_space ) ;
2016-03-15 14:12:06 +00:00
if ( ! query_user_string ( app , & bar_cmd ) ) return ;
2016-06-13 16:56:33 +00:00
2016-07-10 05:49:11 +00:00
String hot_directory = make_fixed_width_string ( hot_directory_space ) ;
2016-09-17 00:03:09 +00:00
hot_directory . size = directory_get_hot ( app , hot_directory . str , hot_directory . memory_size ) ;
2016-05-10 17:36:53 +00:00
2016-08-29 01:03:26 +00:00
uint32_t access = AccessAll ;
2016-09-17 00:03:09 +00:00
View_Summary view = get_active_view ( app , access ) ;
2016-06-13 16:56:33 +00:00
2016-12-26 22:49:01 +00:00
exec_system_command ( app , & view , buffer_identifier ( bar_out . string . str , bar_out . string . size ) , hot_directory . str , hot_directory . size , bar_cmd . string . str , bar_cmd . string . size , CLI_OverlapWithConflict | CLI_CursorAtEnd ) ;
2016-05-10 17:36:53 +00:00
}
CUSTOM_COMMAND_SIG ( execute_previous_cli ) {
2016-07-10 05:49:11 +00:00
String out_buffer = make_string_slowly ( out_buffer_space ) ;
String cmd = make_string_slowly ( command_space ) ;
String hot_directory = make_string_slowly ( hot_directory_space ) ;
2016-05-10 17:36:53 +00:00
if ( out_buffer . size > 0 & & cmd . size > 0 & & hot_directory . size > 0 ) {
2016-08-29 01:03:26 +00:00
uint32_t access = AccessAll ;
2016-09-17 00:03:09 +00:00
View_Summary view = get_active_view ( app , access ) ;
2016-06-13 16:56:33 +00:00
2016-12-26 22:49:01 +00:00
exec_system_command ( app , & view , buffer_identifier ( out_buffer . str , out_buffer . size ) , hot_directory . str , hot_directory . size , cmd . str , cmd . size , CLI_OverlapWithConflict | CLI_CursorAtEnd ) ;
2016-05-10 17:36:53 +00:00
}
2016-03-15 14:12:06 +00:00
}
2016-09-01 19:40:25 +00:00
//
// Default Building Stuff
//
// NOTE(allen|a4.0.9): This is provided to establish a default method of getting
// a "build directory". This function tries to setup the build directory in the
// directory of the given buffer, if it cannot get that information it get's the
// 4coder hot directory.
2016-07-10 05:49:11 +00:00
//
2016-09-01 19:40:25 +00:00
// There is no requirement that a custom build system in 4coder actually use the
// directory given by this function.
enum Get_Build_Directory_Result {
BuildDir_None ,
BuildDir_AtFile ,
BuildDir_AtHot
} ;
static int32_t
get_build_directory ( Application_Links * app , Buffer_Summary * buffer , String * dir_out ) {
int32_t result = BuildDir_None ;
if ( buffer & & buffer - > file_name ) {
if ( ! match_cc ( buffer - > file_name , buffer - > buffer_name ) ) {
String dir = make_string_cap ( buffer - > file_name ,
buffer - > file_name_len ,
buffer - > file_name_len + 1 ) ;
remove_last_folder ( & dir ) ;
append_ss ( dir_out , dir ) ;
result = BuildDir_AtFile ;
}
}
if ( ! result ) {
2016-09-17 00:03:09 +00:00
int32_t len = directory_get_hot ( app , dir_out - > str ,
2016-12-08 17:16:50 +00:00
dir_out - > memory_size - dir_out - > size ) ;
2016-09-01 19:40:25 +00:00
if ( len + dir_out - > size < dir_out - > memory_size ) {
dir_out - > size + = len ;
result = BuildDir_AtHot ;
}
}
return ( result ) ;
}
// TODO(allen): Better names for the "standard build search" family.
static int32_t
2016-11-12 21:33:54 +00:00
standard_build_search ( Application_Links * app , View_Summary * view , Buffer_Summary * active_buffer , String * dir , String * command , int32_t perform_backup , int32_t use_path_in_command , String filename , String commandname ) {
2016-09-01 19:40:25 +00:00
int32_t result = false ;
for ( ; ; ) {
int32_t old_size = dir - > size ;
append_ss ( dir , filename ) ;
2016-09-17 00:03:09 +00:00
if ( file_exists ( app , dir - > str , dir - > size ) ) {
2016-09-01 19:40:25 +00:00
dir - > size = old_size ;
if ( use_path_in_command ) {
append_s_char ( command , ' " ' ) ;
append_ss ( command , * dir ) ;
append_ss ( command , commandname ) ;
append_s_char ( command , ' " ' ) ;
}
else {
append_ss ( command , commandname ) ;
}
char space [ 512 ] ;
String message = make_fixed_width_string ( space ) ;
append_ss ( & message , make_lit_string ( " Building with: " ) ) ;
append_ss ( & message , * command ) ;
append_s_char ( & message , ' \n ' ) ;
2016-09-17 00:03:09 +00:00
print_message ( app , message . str , message . size ) ;
2016-09-01 19:40:25 +00:00
2016-12-26 22:49:01 +00:00
exec_system_command ( app , view , buffer_identifier ( literal ( " *compilation* " ) ) , dir - > str , dir - > size , command - > str , command - > size , CLI_OverlapWithConflict ) ;
2016-09-01 19:40:25 +00:00
result = true ;
break ;
}
dir - > size = old_size ;
2016-09-17 00:03:09 +00:00
if ( directory_cd ( app , dir - > str , & dir - > size , dir - > memory_size , literal ( " .. " ) ) = = 0 ) {
2016-09-01 19:40:25 +00:00
if ( perform_backup ) {
2016-09-17 00:03:09 +00:00
dir - > size = directory_get_hot ( app , dir - > str , dir - > memory_size ) ;
2016-09-01 19:40:25 +00:00
char backup_space [ 256 ] ;
String backup_command = make_fixed_width_string ( backup_space ) ;
append_ss ( & backup_command , make_lit_string ( " echo could not find " ) ) ;
append_ss ( & backup_command , filename ) ;
2016-12-26 22:49:01 +00:00
exec_system_command ( app , view , buffer_identifier ( literal ( " *compilation* " ) ) , dir - > str , dir - > size , backup_command . str , backup_command . size , CLI_OverlapWithConflict ) ;
2016-09-01 19:40:25 +00:00
}
break ;
}
}
return ( result ) ;
}
# if defined(_WIN32)
// NOTE(allen): Build search rule for windows.
static int32_t
execute_standard_build_search ( Application_Links * app , View_Summary * view ,
Buffer_Summary * active_buffer ,
String * dir , String * command , int32_t perform_backup ) {
2016-12-26 22:49:01 +00:00
int32_t result = standard_build_search ( app , view , active_buffer , dir , command , perform_backup , true , make_lit_string ( " build.bat " ) , make_lit_string ( " build " ) ) ;
2016-09-01 19:40:25 +00:00
return ( result ) ;
}
# elif defined(__linux__)
// NOTE(allen): Build search rule for linux.
static int32_t
2016-11-23 03:37:28 +00:00
execute_standard_build_search ( Application_Links * app , View_Summary * view , Buffer_Summary * active_buffer , String * dir , String * command , bool32 perform_backup ) {
2016-09-01 19:40:25 +00:00
char dir_space [ 512 ] ;
String dir_copy = make_fixed_width_string ( dir_space ) ;
copy ( & dir_copy , * dir ) ;
2016-11-23 03:37:28 +00:00
int32_t result = standard_build_search ( app , view , active_buffer , dir , command , 0 , 1 , make_lit_string ( " build.sh " ) , make_lit_string ( " build.sh " ) ) ;
2016-09-01 19:40:25 +00:00
if ( ! result ) {
2016-11-23 03:37:28 +00:00
result = standard_build_search ( app , view , active_buffer , & dir_copy , command , perform_backup , 0 , make_lit_string ( " Makefile " ) , make_lit_string ( " make " ) ) ;
2016-09-01 19:40:25 +00:00
}
return ( result ) ;
}
# else
# error No build search rule for this platform.
# endif
// NOTE(allen): This searches first using the active file's directory,
// then if no build script is found, it searches from 4coders hot directory.
static void
2016-12-26 22:49:01 +00:00
execute_standard_build ( Application_Links * app , View_Summary * view , Buffer_Summary * active_buffer ) {
2016-09-01 19:40:25 +00:00
char dir_space [ 512 ] ;
String dir = make_fixed_width_string ( dir_space ) ;
char command_str_space [ 512 ] ;
String command = make_fixed_width_string ( command_str_space ) ;
int32_t build_dir_type = get_build_directory ( app , active_buffer , & dir ) ;
if ( build_dir_type = = BuildDir_AtFile ) {
2016-12-26 22:49:01 +00:00
if ( ! execute_standard_build_search ( app , view , active_buffer , & dir , & command , false ) ) {
2016-09-01 19:40:25 +00:00
dir . size = 0 ;
command . size = 0 ;
build_dir_type = get_build_directory ( app , 0 , & dir ) ;
}
}
if ( build_dir_type = = BuildDir_AtHot ) {
2016-12-26 22:49:01 +00:00
execute_standard_build_search ( app , view , active_buffer , & dir , & command , true ) ;
2016-09-01 19:40:25 +00:00
}
}
CUSTOM_COMMAND_SIG ( build_search ) {
uint32_t access = AccessAll ;
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-09-01 19:40:25 +00:00
execute_standard_build ( app , & view , & buffer ) ;
prev_location = null_location ;
lock_jump_buffer ( literal ( " *compilation* " ) ) ;
}
2016-09-17 00:03:09 +00:00
# define GET_COMP_BUFFER(app) get_buffer_by_name(app, literal("*compilation*"), AccessAll)
2016-09-01 19:40:25 +00:00
static View_Summary
get_or_open_build_panel ( Application_Links * app ) {
View_Summary view = { 0 } ;
Buffer_Summary buffer = GET_COMP_BUFFER ( app ) ;
if ( buffer . exists ) {
view = get_first_view_with_buffer ( app , buffer . buffer_id ) ;
}
if ( ! view . exists ) {
view = open_special_note_view ( app ) ;
}
return ( view ) ;
}
static void
set_fancy_compilation_buffer_font ( Application_Links * app ) {
2016-09-17 00:03:09 +00:00
Buffer_Summary comp_buffer = get_buffer_by_name ( app , literal ( " *compilation* " ) , AccessAll ) ;
buffer_set_font ( app , & comp_buffer , literal ( " Inconsolata " ) ) ;
2016-10-05 06:08:23 +00:00
}
CUSTOM_COMMAND_SIG ( build_in_build_panel ) {
uint32_t access = AccessAll ;
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-05 06:08:23 +00:00
2016-09-01 19:40:25 +00:00
View_Summary build_view = get_or_open_build_panel ( app ) ;
2016-10-05 06:08:23 +00:00
2016-09-01 19:40:25 +00:00
execute_standard_build ( app , & build_view , & buffer ) ;
set_fancy_compilation_buffer_font ( app ) ;
prev_location = null_location ;
lock_jump_buffer ( literal ( " *compilation* " ) ) ;
}
CUSTOM_COMMAND_SIG ( close_build_panel ) {
close_special_note_view ( app ) ;
}
CUSTOM_COMMAND_SIG ( change_to_build_panel ) {
View_Summary view = open_special_note_view ( app , false ) ;
if ( ! view . exists ) {
Buffer_Summary buffer = GET_COMP_BUFFER ( app ) ;
if ( buffer . exists ) {
view = open_special_note_view ( app ) ;
2016-09-17 00:03:09 +00:00
view_set_buffer ( app , & view , buffer . buffer_id , 0 ) ;
2016-09-01 19:40:25 +00:00
}
}
if ( view . exists ) {
2016-09-17 00:03:09 +00:00
set_active_view ( app , & view ) ;
2016-09-01 19:40:25 +00:00
}
}
2016-03-15 14:12:06 +00:00
// NOTE(allen|a4): scroll rule information
//
// The parameters:
// target_x, target_y
// This is where the view would like to be for the purpose of
// following the cursor, doing mouse wheel work, etc.
//
// scroll_x, scroll_y
// These are pointers to where the scrolling actually is. If you bind
// the scroll rule it is you have to update these in some way to move
// the actual location of the scrolling.
//
// view_id
// This corresponds to which view is computing it's new scrolling position.
// This id DOES correspond to the views that View_Summary contains.
// This will always be between 1 and 16 (0 is a null id).
// See below for an example of having state that carries across scroll udpates.
//
// is_new_target
// If the target of the view is different from the last target in either x or y
// this is true, otherwise it is false.
//
// The return:
// Should be true if and only if scroll_x or scroll_y are changed.
//
// Don't try to use the app pointer in a scroll rule, you're asking for trouble.
//
// If you don't bind scroll_rule, nothing bad will happen, yo will get default
// 4coder scrolling behavior.
//
struct Scroll_Velocity {
float x , y ;
} ;
Scroll_Velocity scroll_velocity_ [ 16 ] = { 0 } ;
Scroll_Velocity * scroll_velocity = scroll_velocity_ - 1 ;
2016-08-29 01:03:26 +00:00
static int32_t
2016-03-15 14:12:06 +00:00
smooth_camera_step ( float target , float * current , float * vel , float S , float T ) {
2016-08-29 01:03:26 +00:00
int32_t result = 0 ;
2016-03-15 14:12:06 +00:00
float curr = * current ;
float v = * vel ;
if ( curr ! = target ) {
if ( curr > target - .1f & & curr < target + .1f ) {
curr = target ;
v = 1.f ;
}
else {
float L = curr + T * ( target - curr ) ;
2016-08-29 01:03:26 +00:00
int32_t sign = ( target > curr ) - ( target < curr ) ;
2016-03-15 14:12:06 +00:00
float V = curr + sign * v ;
2016-08-29 01:03:26 +00:00
2016-03-15 14:12:06 +00:00
if ( sign > 0 ) curr = ( L < V ) ? ( L ) : ( V ) ;
else curr = ( L > V ) ? ( L ) : ( V ) ;
2016-08-29 01:03:26 +00:00
2016-03-15 14:12:06 +00:00
if ( curr = = V ) {
v * = S ;
}
}
2016-08-29 01:03:26 +00:00
2016-03-15 14:12:06 +00:00
* current = curr ;
* vel = v ;
result = 1 ;
}
2016-08-29 01:03:26 +00:00
return ( result ) ;
2016-03-15 14:12:06 +00:00
}
SCROLL_RULE_SIG ( smooth_scroll_rule ) {
Scroll_Velocity * velocity = scroll_velocity + view_id ;
2016-08-29 01:03:26 +00:00
int32_t result = 0 ;
2016-03-15 14:12:06 +00:00
if ( velocity - > x = = 0.f ) {
velocity - > x = 1.f ;
velocity - > y = 1.f ;
}
2016-12-08 17:16:50 +00:00
2016-03-31 17:13:40 +00:00
if ( smooth_camera_step ( target_y , scroll_y , & velocity - > y , 80.f , 1.f / 2.f ) ) {
2016-03-15 14:12:06 +00:00
result = 1 ;
}
2016-03-31 17:13:40 +00:00
if ( smooth_camera_step ( target_x , scroll_x , & velocity - > x , 80.f , 1.f / 2.f ) ) {
2016-03-15 14:12:06 +00:00
result = 1 ;
}
2016-12-08 17:16:50 +00:00
2016-03-15 14:12:06 +00:00
return ( result ) ;
}
2016-07-13 19:59:42 +00:00
// NOTE(allen|a4.0.9): All command calls can now go through this hook
// If this hook is not implemented a default behavior of calling the
// command is used. It is important to note that paste_next does not
// work without this hook.
2016-08-22 19:31:19 +00:00
// NOTE(allen|a4.0.10): As of this version the word_complete command
// also relies on this particular command caller hook.
2016-07-13 19:59:42 +00:00
COMMAND_CALLER_HOOK ( default_command_caller ) {
2016-09-17 00:03:09 +00:00
View_Summary view = get_active_view ( app , AccessAll ) ;
2016-07-13 19:59:42 +00:00
2016-12-14 16:09:54 +00:00
view_paste_index [ view . view_id ] . next_rewrite = 0 ;
2016-07-13 19:59:42 +00:00
exec_command ( app , cmd ) ;
2016-12-14 16:09:54 +00:00
view_paste_index [ view . view_id ] . rewrite = view_paste_index [ view . view_id ] . next_rewrite ;
2016-07-13 19:59:42 +00:00
return ( 0 ) ;
}
2016-12-24 21:09:53 +00:00
struct Config_Line {
Cpp_Token id_token ;
Cpp_Token subscript_token ;
Cpp_Token eq_token ;
Cpp_Token val_token ;
int32_t val_array_start ;
int32_t val_array_end ;
int32_t val_array_count ;
bool32 read_success ;
} ;
struct Config_Item {
Config_Line line ;
2016-12-26 22:49:01 +00:00
Cpp_Token_Array array ;
2016-12-24 21:09:53 +00:00
char * mem ;
String id ;
int32_t subscript_index ;
bool32 has_subscript ;
} ;
struct Config_Array_Reader {
2016-12-26 22:49:01 +00:00
Cpp_Token_Array array ;
2016-12-24 21:09:53 +00:00
char * mem ;
int32_t i ;
int32_t val_array_end ;
bool32 good ;
} ;
static Cpp_Token
read_config_token ( Cpp_Token_Array array , int32_t * i_ptr ) {
Cpp_Token token = { 0 } ;
int32_t i = * i_ptr ;
for ( ; i < array . count ; + + i ) {
Cpp_Token comment_token = array . tokens [ i ] ;
if ( comment_token . type ! = CPP_TOKEN_COMMENT ) {
break ;
}
}
if ( i < array . count ) {
token = array . tokens [ i ] ;
}
2016-12-26 22:49:01 +00:00
* i_ptr = i ;
2016-12-24 21:09:53 +00:00
return ( token ) ;
}
static Config_Line
read_config_line ( Cpp_Token_Array array , int32_t * i_ptr ) {
Config_Line config_line = { 0 } ;
int32_t i = * i_ptr ;
config_line . id_token = read_config_token ( array , & i ) ;
if ( config_line . id_token . type = = CPP_TOKEN_IDENTIFIER ) {
+ + i ;
if ( i < array . count ) {
Cpp_Token token = read_config_token ( array , & i ) ;
bool32 subscript_success = 1 ;
2016-12-26 22:49:01 +00:00
if ( token . type = = CPP_TOKEN_BRACKET_OPEN ) {
2016-12-24 21:09:53 +00:00
subscript_success = 0 ;
+ + i ;
if ( i < array . count ) {
config_line . subscript_token = read_config_token ( array , & i ) ;
if ( config_line . subscript_token . type = = CPP_TOKEN_INTEGER_CONSTANT ) {
+ + i ;
if ( i < array . count ) {
token = read_config_token ( array , & i ) ;
2016-12-26 22:49:01 +00:00
if ( token . type = = CPP_TOKEN_BRACKET_CLOSE ) {
2016-12-24 21:09:53 +00:00
+ + i ;
if ( i < array . count ) {
token = read_config_token ( array , & i ) ;
subscript_success = 1 ;
}
}
}
}
}
}
if ( subscript_success ) {
2017-01-07 02:59:55 +00:00
if ( token . type = = CPP_TOKEN_EQ ) {
config_line . eq_token = read_config_token ( array , & i ) ;
+ + i ;
if ( i < array . count ) {
Cpp_Token val_token = read_config_token ( array , & i ) ;
bool32 array_success = 1 ;
if ( val_token . type = = CPP_TOKEN_BRACE_OPEN ) {
array_success = 0 ;
+ + i ;
if ( i < array . count ) {
config_line . val_array_start = i ;
bool32 expecting_array_item = 1 ;
for ( ; i < array . count ; + + i ) {
Cpp_Token array_token = read_config_token ( array , & i ) ;
if ( array_token . size = = 0 ) {
break ;
}
if ( array_token . type = = CPP_TOKEN_BRACE_CLOSE ) {
config_line . val_array_end = i ;
array_success = 1 ;
break ;
2016-12-24 21:09:53 +00:00
}
else {
2017-01-07 02:59:55 +00:00
if ( array_token . type = = CPP_TOKEN_COMMA ) {
if ( ! expecting_array_item ) {
expecting_array_item = 1 ;
}
else {
break ;
}
}
else {
if ( expecting_array_item ) {
expecting_array_item = 0 ;
+ + config_line . val_array_count ;
}
2016-12-24 21:09:53 +00:00
}
}
}
}
}
2017-01-07 02:59:55 +00:00
if ( array_success ) {
config_line . val_token = val_token ;
+ + i ;
if ( i < array . count ) {
Cpp_Token semicolon_token = read_config_token ( array , & i ) ;
if ( semicolon_token . type = = CPP_TOKEN_SEMICOLON ) {
config_line . read_success = 1 ;
}
}
2016-12-24 21:09:53 +00:00
}
}
}
}
}
}
if ( ! config_line . read_success ) {
for ( ; i < array . count ; + + i ) {
Cpp_Token token = read_config_token ( array , & i ) ;
if ( token . type = = CPP_TOKEN_SEMICOLON ) {
break ;
}
}
}
* i_ptr = i ;
return ( config_line ) ;
}
static Config_Item
2016-12-26 22:49:01 +00:00
get_config_item ( Config_Line line , char * mem , Cpp_Token_Array array ) {
2016-12-24 21:09:53 +00:00
Config_Item item = { 0 } ;
item . line = line ;
2016-12-26 22:49:01 +00:00
item . array = array ;
2016-12-24 21:09:53 +00:00
item . mem = mem ;
2016-12-26 22:49:01 +00:00
if ( line . id_token . size ! = 0 ) {
2017-01-07 02:59:55 +00:00
item . id = make_string ( mem + line . id_token . start , line . id_token . size ) ;
2016-12-26 22:49:01 +00:00
}
2016-12-24 21:09:53 +00:00
if ( line . subscript_token . size ! = 0 ) {
String subscript_str = make_string ( mem + line . subscript_token . start , line . subscript_token . size ) ;
item . subscript_index = str_to_int_s ( subscript_str ) ;
item . has_subscript = 1 ;
}
return ( item ) ;
}
static bool32
config_var ( Config_Item item , char * var_name , int32_t * subscript , uint32_t token_type , void * var_out ) {
bool32 result = 0 ;
bool32 subscript_succes = 1 ;
if ( item . line . val_token . type = = token_type ) {
if ( ( var_name = = 0 & & item . id . size = = 0 ) | | match ( item . id , var_name ) ) {
if ( subscript ) {
2017-01-07 02:59:55 +00:00
if ( item . has_subscript ) {
* subscript = item . subscript_index ;
}
else {
subscript_succes = 0 ;
}
2016-12-24 21:09:53 +00:00
}
2017-01-07 02:59:55 +00:00
if ( subscript_succes ) {
if ( var_out ) {
switch ( token_type ) {
case CPP_TOKEN_BOOLEAN_CONSTANT :
{
* ( bool32 * ) var_out = ( item . mem [ item . line . val_token . start ] = = ' t ' ) ;
} break ;
case CPP_TOKEN_INTEGER_CONSTANT :
{
String val = make_string ( item . mem + item . line . val_token . start , item . line . val_token . size ) ;
* ( int32_t * ) var_out = str_to_int ( val ) ;
} break ;
case CPP_TOKEN_STRING_CONSTANT :
{
* ( String * ) var_out = make_string ( item . mem + item . line . val_token . start + 1 , item . line . val_token . size - 2 ) ;
} break ;
case CPP_TOKEN_BRACE_OPEN :
{
Config_Array_Reader * array_reader = ( Config_Array_Reader * ) var_out ;
array_reader - > array = item . array ;
array_reader - > mem = item . mem ;
array_reader - > i = item . line . val_array_start ;
array_reader - > val_array_end = item . line . val_array_end ;
array_reader - > good = 1 ;
} break ;
}
2016-12-24 21:09:53 +00:00
}
2017-01-07 02:59:55 +00:00
result = 1 ;
2016-12-24 21:09:53 +00:00
}
}
}
return ( result ) ;
}
static bool32
config_bool_var ( Config_Item item , char * var_name , int32_t * subscript , bool32 * var_out ) {
bool32 result = config_var ( item , var_name , subscript , CPP_TOKEN_BOOLEAN_CONSTANT , var_out ) ;
return ( result ) ;
}
static bool32
config_int_var ( Config_Item item , char * var_name , int32_t * subscript , int32_t * var_out ) {
bool32 result = config_var ( item , var_name , subscript , CPP_TOKEN_INTEGER_CONSTANT , var_out ) ;
return ( result ) ;
}
static bool32
config_string_var ( Config_Item item , char * var_name , int32_t * subscript , String * var_out ) {
bool32 result = config_var ( item , var_name , subscript , CPP_TOKEN_STRING_CONSTANT , var_out ) ;
return ( result ) ;
}
static bool32
config_array_var ( Config_Item item , char * var_name , int32_t * subscript , Config_Array_Reader * array_reader ) {
bool32 result = config_var ( item , var_name , subscript , CPP_TOKEN_BRACE_OPEN , array_reader ) ;
return ( result ) ;
}
static bool32
config_array_next_item ( Config_Array_Reader * array_reader , Config_Item * item ) {
2016-12-26 22:49:01 +00:00
bool32 result = 0 ;
2016-12-24 21:09:53 +00:00
2016-12-26 22:49:01 +00:00
for ( ; array_reader - > i < array_reader - > val_array_end ;
+ + array_reader - > i ) {
Cpp_Token array_token = read_config_token ( array_reader - > array , & array_reader - > i ) ;
if ( array_token . size = = 0 | | array_reader - > i > = array_reader - > val_array_end ) {
break ;
}
if ( array_token . type = = CPP_TOKEN_BRACE_CLOSE ) {
break ;
}
switch ( array_token . type ) {
case CPP_TOKEN_BOOLEAN_CONSTANT :
case CPP_TOKEN_INTEGER_CONSTANT :
case CPP_TOKEN_STRING_CONSTANT :
{
Config_Line line = { 0 } ;
line . val_token = array_token ;
line . read_success = 1 ;
* item = get_config_item ( line , array_reader - > mem , array_reader - > array ) ;
result = 1 ;
+ + array_reader - > i ;
goto doublebreak ;
} break ;
}
2017-01-07 02:59:55 +00:00
}
doublebreak : ;
2016-12-24 21:09:53 +00:00
2016-12-26 22:49:01 +00:00
array_reader - > good = result ;
2016-12-24 21:09:53 +00:00
return ( result ) ;
}
static bool32
config_array_good ( Config_Array_Reader * array_reader ) {
bool32 result = ( array_reader - > good ) ;
return ( result ) ;
}
2016-11-12 21:33:54 +00:00
// NOTE(allen|a4.0.12): A primordial config system (actually really hate this but it seems best at least right now... arg)
2016-10-28 14:11:56 +00:00
static bool32 enable_code_wrapping = 1 ;
2016-12-24 21:09:53 +00:00
static bool32 automatically_adjust_wrapping = 1 ;
2016-10-28 14:11:56 +00:00
static int32_t default_wrap_width = 672 ;
2016-11-12 21:33:54 +00:00
static int32_t default_min_base_width = 550 ;
2016-12-26 22:49:01 +00:00
static bool32 automatically_indent_text_on_save = 1 ;
2016-12-24 21:09:53 +00:00
static String default_theme_name = make_lit_string ( " 4coder " ) ;
static String default_font_name = make_lit_string ( " Liberation Sans " ) ;
2016-10-28 14:11:56 +00:00
# include <stdio.h>
2016-12-18 20:42:11 +00:00
static void
adjust_all_buffer_wrap_widths ( Application_Links * app , int32_t wrap_widths , int32_t min_base_width ) {
for ( Buffer_Summary buffer = get_buffer_first ( app , AccessAll ) ;
buffer . exists ;
get_buffer_next ( app , & buffer , AccessAll ) ) {
buffer_set_setting ( app , & buffer , BufferSetting_WrapPosition , wrap_widths ) ;
buffer_set_setting ( app , & buffer , BufferSetting_MinimumBaseWrapPosition , min_base_width ) ;
}
default_wrap_width = wrap_widths ;
default_min_base_width = min_base_width ;
}
2016-12-24 21:09:53 +00:00
static bool32
file_handle_dump ( Partition * part , FILE * file , char * * mem_ptr , int32_t * size_ptr ) {
bool32 success = 0 ;
fseek ( file , 0 , SEEK_END ) ;
int32_t size = ftell ( file ) ;
char * mem = ( char * ) push_block ( part , size + 1 ) ;
fseek ( file , 0 , SEEK_SET ) ;
int32_t check_size = ( int32_t ) fread ( mem , 1 , size , file ) ;
if ( check_size = = size ) {
mem [ size ] = 0 ;
success = 1 ;
}
* mem_ptr = mem ;
* size_ptr = size ;
return ( success ) ;
}
2016-10-28 14:11:56 +00:00
static void
process_config_file ( Application_Links * app ) {
2016-12-24 21:09:53 +00:00
Partition * part = & global_part ;
2016-10-28 14:11:56 +00:00
FILE * file = fopen ( " config.4coder " , " rb " ) ;
2016-12-14 16:09:54 +00:00
if ( ! file ) {
char space [ 256 ] ;
int32_t size = get_4ed_path ( app , space , sizeof ( space ) ) ;
String str = make_string_cap ( space , size , sizeof ( space ) ) ;
append_sc ( & str , " /config.4coder " ) ;
terminate_with_null ( & str ) ;
file = fopen ( str . str , " rb " ) ;
}
2016-10-28 14:11:56 +00:00
if ( file ) {
2016-12-24 21:09:53 +00:00
Temp_Memory temp = begin_temp_memory ( part ) ;
char * mem = 0 ;
int32_t size = 0 ;
bool32 file_read_success = file_handle_dump ( part , file , & mem , & size ) ;
if ( file_read_success ) {
2016-12-08 17:16:50 +00:00
fclose ( file ) ;
2016-10-28 14:11:56 +00:00
2016-12-08 17:16:50 +00:00
Cpp_Token_Array array ;
array . count = 0 ;
array . max_count = ( 1 < < 20 ) / sizeof ( Cpp_Token ) ;
array . tokens = push_array ( & global_part , Cpp_Token , array . max_count ) ;
Cpp_Lex_Data S = cpp_lex_data_init ( ) ;
Cpp_Lex_Result result = cpp_lex_step ( & S , mem , size + 1 , HAS_NULL_TERM , & array , NO_OUT_LIMIT ) ;
if ( result = = LexResult_Finished ) {
2016-12-18 20:42:11 +00:00
int32_t new_wrap_width = default_wrap_width ;
int32_t new_min_base_width = default_min_base_width ;
2016-12-08 17:16:50 +00:00
for ( int32_t i = 0 ; i < array . count ; + + i ) {
2016-12-24 21:09:53 +00:00
Config_Line config_line = read_config_line ( array , & i ) ;
if ( config_line . read_success ) {
2016-12-26 22:49:01 +00:00
Config_Item item = get_config_item ( config_line , mem , array ) ;
2016-12-24 21:09:53 +00:00
config_bool_var ( item , " enable_code_wrapping " , 0 , & enable_code_wrapping ) ;
config_bool_var ( item , " automatically_adjust_wrapping " , 0 , & automatically_adjust_wrapping ) ;
2016-12-26 22:49:01 +00:00
config_bool_var ( item , " automatically_indent_text_on_save " , 0 , & automatically_indent_text_on_save ) ;
2017-01-07 02:59:55 +00:00
2016-12-24 21:09:53 +00:00
config_int_var ( item , " default_wrap_width " , 0 , & new_wrap_width ) ;
config_int_var ( item , " default_min_base_width " , 0 , & new_min_base_width ) ;
2017-01-07 02:59:55 +00:00
2016-12-24 21:09:53 +00:00
config_string_var ( item , " default_theme_name " , 0 , & default_theme_name ) ;
config_string_var ( item , " default_font_name " , 0 , & default_font_name ) ;
2017-01-07 02:59:55 +00:00
}
}
adjust_all_buffer_wrap_widths ( app , new_wrap_width , new_min_base_width ) ;
}
2016-12-24 21:09:53 +00:00
}
end_temp_memory ( temp ) ;
}
else {
2017-01-14 03:01:35 +00:00
print_message ( app , literal ( " Did not find config.4coder, using default settings \n " ) ) ;
2016-12-24 21:09:53 +00:00
}
}
// NOTE(allen): Project system setup
2016-12-26 22:49:01 +00:00
static char * default_extensions [ ] = {
" cpp " ,
" hpp " ,
" c " ,
" h " ,
" cc "
} ;
struct Fkey_Command {
char command [ 128 ] ;
char out [ 128 ] ;
bool32 use_build_panel ;
} ;
struct Project {
char dir_space [ 256 ] ;
char * dir ;
int32_t dir_len ;
char extension_space [ 256 ] ;
char * extensions [ 94 ] ;
int32_t extension_count ;
Fkey_Command fkey_commands [ 16 ] ;
bool32 close_all_code_when_this_project_closes ;
bool32 close_all_files_when_project_opens ;
} ;
static Project null_project = { } ;
static Project current_project = { } ;
static void
set_project_extensions ( Project * project , String src ) {
int32_t mode = 0 ;
int32_t j = 0 , k = 0 ;
for ( int32_t i = 0 ; i < src . size ; + + i ) {
switch ( mode ) {
2017-01-07 02:59:55 +00:00
case 0 :
2016-12-26 22:49:01 +00:00
{
if ( src . str [ i ] = = ' . ' ) {
mode = 1 ;
project - > extensions [ k + + ] = & project - > extension_space [ j ] ;
}
} break ;
case 1 :
{
if ( src . str [ i ] = = ' . ' ) {
project - > extension_space [ j + + ] = 0 ;
project - > extensions [ k + + ] = & project - > extension_space [ j ] ;
}
else {
project - > extension_space [ j + + ] = src . str [ i ] ;
}
} break ;
2017-01-07 02:59:55 +00:00
}
2016-12-26 22:49:01 +00:00
}
project - > extension_space [ j + + ] = 0 ;
project - > extension_count = k ;
}
// TODO(allen): make this a string operation or a lexer operation or something
static void
interpret_escaped_string ( char * dst , String src ) {
int32_t mode = 0 ;
int32_t j = 0 ;
for ( int32_t i = 0 ; i < src . size ; + + i ) {
2017-01-07 02:59:55 +00:00
switch ( mode ) {
2016-12-26 22:49:01 +00:00
case 0 :
{
2017-01-07 02:59:55 +00:00
if ( src . str [ i ] = = ' \\ ' ) {
mode = 1 ;
}
else {
dst [ j + + ] = src . str [ i ] ;
}
} break ;
case 1 :
{
switch ( src . str [ i ] ) {
case ' \\ ' : { dst [ j + + ] = ' \\ ' ; mode = 0 ; } break ;
case ' n ' : { dst [ j + + ] = ' \n ' ; mode = 0 ; } break ;
case ' t ' : { dst [ j + + ] = ' \t ' ; mode = 0 ; } break ;
case ' " ' : { dst [ j + + ] = ' " ' ; mode = 0 ; } break ;
case ' 0 ' : { dst [ j + + ] = ' \0 ' ; mode = 0 ; } break ;
}
} break ;
2016-12-26 22:49:01 +00:00
}
}
dst [ j ] = 0 ;
}
static void
close_all_files_with_extension ( Application_Links * app , Partition * scratch_part , char * * extension_list , int32_t extension_count ) {
Temp_Memory temp = begin_temp_memory ( scratch_part ) ;
int32_t buffers_to_close_max = partition_remaining ( scratch_part ) / sizeof ( int32_t ) ;
int32_t * buffers_to_close = push_array ( scratch_part , int32_t , buffers_to_close_max ) ;
int32_t buffers_to_close_count = 0 ;
bool32 do_repeat = 0 ;
do {
buffers_to_close_count = 0 ;
do_repeat = 0 ;
2017-01-07 02:59:55 +00:00
uint32_t access = AccessAll ;
Buffer_Summary buffer = { 0 } ;
for ( buffer = get_buffer_first ( app , access ) ;
buffer . exists ;
get_buffer_next ( app , & buffer , access ) ) {
bool32 is_match = 1 ;
if ( extension_count > 0 ) {
String extension = file_extension ( make_string ( buffer . file_name , buffer . file_name_len ) ) ;
is_match = 0 ;
for ( int32_t i = 0 ; i < extension_count ; + + i ) {
if ( match ( extension , extension_list [ i ] ) ) {
is_match = 1 ;
break ;
}
}
}
if ( is_match ) {
if ( buffers_to_close_count > = buffers_to_close_max ) {
do_repeat = 1 ;
2016-12-26 22:49:01 +00:00
break ;
}
2017-01-07 02:59:55 +00:00
buffers_to_close [ buffers_to_close_count + + ] = buffer . buffer_id ;
2016-12-26 22:49:01 +00:00
}
}
2017-01-07 02:59:55 +00:00
for ( int32_t i = 0 ; i < buffers_to_close_count ; + + i ) {
kill_buffer ( app , buffer_identifier ( buffers_to_close [ i ] ) , true , 0 ) ;
2016-12-26 22:49:01 +00:00
}
}
while ( do_repeat ) ;
end_temp_memory ( temp ) ;
}
static void
open_all_files_with_extension ( Application_Links * app , Partition * scratch_part , char * * extension_list , int32_t extension_count ) {
Temp_Memory temp = begin_temp_memory ( scratch_part ) ;
int32_t max_size = partition_remaining ( scratch_part ) ;
char * memory = push_array ( scratch_part , char , max_size ) ;
String dir = make_string_cap ( memory , 0 , max_size ) ;
dir . size = directory_get_hot ( app , dir . str , dir . memory_size ) ;
int32_t dir_size = dir . size ;
// NOTE(allen|a3.4.4): Here we get the list of files in this directory.
// Notice that we free_file_list at the end.
File_List list = get_file_list ( app , dir . str , dir . size ) ;
for ( int32_t i = 0 ; i < list . count ; + + i ) {
File_Info * info = list . infos + i ;
if ( ! info - > folder ) {
bool32 is_match = 1 ;
if ( extension_count > 0 ) {
is_match = 0 ;
2017-01-07 02:59:55 +00:00
String extension = make_string_cap ( info - > filename , info - > filename_len , info - > filename_len + 1 ) ;
extension = file_extension ( extension ) ;
2016-12-26 22:49:01 +00:00
for ( int32_t j = 0 ; j < extension_count ; + + j ) {
if ( match ( extension , extension_list [ j ] ) ) {
is_match = 1 ;
break ;
}
2017-01-07 02:59:55 +00:00
}
if ( is_match ) {
// NOTE(allen): There's no way in the 4coder API to use relative
// paths at the moment, so everything should be full paths. Which is
// managable. Here simply set the dir string size back to where it
// was originally, so that new appends overwrite old ones.
dir . size = dir_size ;
append_sc ( & dir , info - > filename ) ;
create_buffer ( app , dir . str , dir . size , 0 ) ;
}
}
2016-12-26 22:49:01 +00:00
}
}
free_file_list ( app , list ) ;
2017-01-07 02:59:55 +00:00
end_temp_memory ( temp ) ;
2016-12-26 22:49:01 +00:00
}
static char * *
get_standard_code_extensions ( int32_t * extension_count_out ) {
char * * extension_list = default_extensions ;
int32_t extension_count = ArrayCount ( default_extensions ) ;
if ( current_project . dir ! = 0 ) {
extension_list = current_project . extensions ;
extension_count = current_project . extension_count ;
}
* extension_count_out = extension_count ;
return ( extension_list ) ;
}
// NOTE(allen|a4.0.14): open_all_code and close_all_code now use the extensions set in the loaded project. If there is no project loaded the extensions ".cpp.hpp.c.h.cc" are used.
CUSTOM_COMMAND_SIG ( open_all_code ) {
int32_t extension_count = 0 ;
char * * extension_list = get_standard_code_extensions ( & extension_count ) ;
open_all_files_with_extension ( app , & global_part , extension_list , extension_count ) ;
}
CUSTOM_COMMAND_SIG ( close_all_code ) {
int32_t extension_count = 0 ;
char * * extension_list = get_standard_code_extensions ( & extension_count ) ;
close_all_files_with_extension ( app , & global_part , extension_list , extension_count ) ;
}
2016-12-24 21:09:53 +00:00
CUSTOM_COMMAND_SIG ( load_project ) {
Partition * part = & global_part ;
char project_file_space [ 512 ] ;
String project_name = make_fixed_width_string ( project_file_space ) ;
project_name . size = directory_get_hot ( app , project_name . str , project_name . memory_size ) ;
if ( project_name . size > = project_name . memory_size ) {
project_name . size = 0 ;
}
if ( project_name . size ! = 0 ) {
2016-12-26 22:49:01 +00:00
int32_t original_size = project_name . size ;
append_sc ( & project_name , " project.4coder " ) ;
terminate_with_null ( & project_name ) ;
2016-12-24 21:09:53 +00:00
2016-12-26 22:49:01 +00:00
// TODO(allen): make sure we do nothing when this project is already open
FILE * file = fopen ( project_name . str , " rb " ) ;
if ( file ) {
project_name . size = original_size ;
terminate_with_null ( & project_name ) ;
Temp_Memory temp = begin_temp_memory ( part ) ;
2016-12-24 21:09:53 +00:00
2016-12-26 22:49:01 +00:00
char * mem = 0 ;
int32_t size = 0 ;
bool32 file_read_success = file_handle_dump ( part , file , & mem , & size ) ;
if ( file_read_success ) {
fclose ( file ) ;
Cpp_Token_Array array ;
array . count = 0 ;
array . max_count = ( 1 < < 20 ) / sizeof ( Cpp_Token ) ;
array . tokens = push_array ( & global_part , Cpp_Token , array . max_count ) ;
Cpp_Lex_Data S = cpp_lex_data_init ( ) ;
Cpp_Lex_Result result = cpp_lex_step ( & S , mem , size + 1 , HAS_NULL_TERM , & array , NO_OUT_LIMIT ) ;
if ( result = = LexResult_Finished ) {
// Clear out current project
2017-01-07 02:59:55 +00:00
if ( current_project . close_all_code_when_this_project_closes ) {
exec_command ( app , close_all_code ) ;
}
current_project = null_project ;
2016-12-24 21:09:53 +00:00
2016-12-26 22:49:01 +00:00
// Set new project directory
2016-12-24 21:09:53 +00:00
{
2016-12-26 22:49:01 +00:00
current_project . dir = current_project . dir_space ;
String str = make_fixed_width_string ( current_project . dir_space ) ;
copy ( & str , project_name ) ;
terminate_with_null ( & str ) ;
current_project . dir_len = str . size ;
2016-10-28 14:11:56 +00:00
}
2016-12-08 17:16:50 +00:00
2016-12-26 22:49:01 +00:00
// Read the settings from project.4coder
for ( int32_t i = 0 ; i < array . count ; + + i ) {
Config_Line config_line = read_config_line ( array , & i ) ;
if ( config_line . read_success ) {
Config_Item item = get_config_item ( config_line , mem , array ) ;
2016-12-24 21:09:53 +00:00
2016-12-26 22:49:01 +00:00
{
String str = { 0 } ;
if ( config_string_var ( item , " extensions " , 0 , & str ) ) {
if ( str . size < sizeof ( current_project . extension_space ) ) {
2017-01-07 02:59:55 +00:00
set_project_extensions ( & current_project , str ) ;
print_message ( app , str . str , str . size ) ;
print_message ( app , " \n " , 1 ) ;
2016-12-24 21:09:53 +00:00
}
2016-12-26 22:49:01 +00:00
else {
print_message ( app , literal ( " STRING TOO LONG! \n " ) ) ;
2016-12-24 21:09:53 +00:00
}
2016-12-26 22:49:01 +00:00
}
}
{
# if defined(_WIN32)
# define FKEY_COMMAND "fkey_command_win"
# elif defined(__linux__)
# define FKEY_COMMAND "fkey_command_linux"
# else
# error no project configuration names for this platform
# endif
2016-12-24 21:09:53 +00:00
2016-12-26 22:49:01 +00:00
int32_t index = 0 ;
Config_Array_Reader array_reader = { 0 } ;
if ( config_array_var ( item , FKEY_COMMAND , & index , & array_reader ) ) {
if ( index > = 1 & & index < = 16 ) {
Config_Item array_item = { 0 } ;
int32_t item_index = 0 ;
char space [ 256 ] ;
String msg = make_fixed_width_string ( space ) ;
append ( & msg , FKEY_COMMAND " [ " ) ;
append_int_to_str ( & msg , index ) ;
append ( & msg , " ] = { " ) ;
for ( config_array_next_item ( & array_reader , & array_item ) ;
config_array_good ( & array_reader ) ;
config_array_next_item ( & array_reader , & array_item ) ) {
if ( item_index > = 3 ) {
break ;
}
append ( & msg , " [ " ) ;
append_int_to_str ( & msg , item_index ) ;
append ( & msg , " ] = " ) ;
bool32 read_string = 0 ;
bool32 read_bool = 0 ;
char * dest_str = 0 ;
int32_t dest_str_size = 0 ;
bool32 * dest_bool = 0 ;
switch ( item_index ) {
case 0 :
{
dest_str = current_project . fkey_commands [ index - 1 ] . command ;
dest_str_size = sizeof ( current_project . fkey_commands [ index - 1 ] . command ) ;
read_string = 1 ;
} break ;
case 1 :
{
dest_str = current_project . fkey_commands [ index - 1 ] . out ;
dest_str_size = sizeof ( current_project . fkey_commands [ index - 1 ] . out ) ;
read_string = 1 ;
} break ;
case 2 :
{
dest_bool = & current_project . fkey_commands [ index - 1 ] . use_build_panel ;
read_bool = 1 ;
} break ;
}
if ( read_string ) {
2017-01-07 02:59:55 +00:00
if ( config_int_var ( array_item , 0 , 0 , 0 ) ) {
append ( & msg , " NULL, " ) ;
dest_str [ 0 ] = 0 ;
2016-12-26 22:49:01 +00:00
}
2017-01-07 02:59:55 +00:00
String str = { 0 } ;
if ( config_string_var ( array_item , 0 , 0 , & str ) ) {
if ( str . size < dest_str_size ) {
interpret_escaped_string ( dest_str , str ) ;
append ( & msg , dest_str ) ;
append ( & msg , " , " ) ;
}
else {
append ( & msg , " STRING TOO LONG!, " ) ;
}
2016-12-26 22:49:01 +00:00
}
}
2017-01-07 02:59:55 +00:00
if ( read_bool ) {
if ( config_bool_var ( array_item , 0 , 0 , dest_bool ) ) {
if ( dest_bool ) {
append ( & msg , " true, " ) ;
}
else {
append ( & msg , " false, " ) ;
}
2016-12-26 22:49:01 +00:00
}
}
2017-01-07 02:59:55 +00:00
2016-12-26 22:49:01 +00:00
item_index + + ;
}
append ( & msg , " } \n " ) ;
print_message ( app , msg . str , msg . size ) ;
}
}
2016-12-24 21:09:53 +00:00
}
2016-10-28 14:11:56 +00:00
}
}
2017-01-07 02:59:55 +00:00
2016-12-26 22:49:01 +00:00
if ( current_project . close_all_files_when_project_opens ) {
close_all_files_with_extension ( app , & global_part , 0 , 0 ) ;
2016-12-24 21:09:53 +00:00
}
2016-12-26 22:49:01 +00:00
// Open all project files
exec_command ( app , open_all_code ) ;
2016-10-28 14:11:56 +00:00
}
}
2016-12-26 22:49:01 +00:00
end_temp_memory ( temp ) ;
2016-12-08 17:16:50 +00:00
}
else {
2016-12-26 22:49:01 +00:00
char message_space [ 512 ] ;
String message = make_fixed_width_string ( message_space ) ;
append_sc ( & message , " Did not find project.4coder. " ) ;
if ( current_project . dir ! = 0 ) {
append_sc ( & message , " Continuing with: " ) ;
append_sc ( & message , current_project . dir ) ;
}
else {
append_sc ( & message , " Continuing without a project " ) ;
}
print_message ( app , message . str , message . size ) ;
2016-10-28 14:11:56 +00:00
}
2016-12-26 22:49:01 +00:00
}
else {
print_message ( app , literal ( " Failed trying to get project file name " ) ) ;
2016-10-28 14:11:56 +00:00
}
}
2016-12-26 22:49:01 +00:00
CUSTOM_COMMAND_SIG ( project_fkey_command ) {
User_Input input = get_command_input ( app ) ;
if ( input . type = = UserInputKey ) {
if ( input . key . keycode > = key_f1 & & input . key . keycode < = key_f16 ) {
int32_t ind = ( input . key . keycode - key_f1 ) ;
char * command = current_project . fkey_commands [ ind ] . command ;
char * out = current_project . fkey_commands [ ind ] . out ;
bool32 use_build_panel = current_project . fkey_commands [ ind ] . use_build_panel ;
if ( command [ 0 ] ! = 0 ) {
int32_t command_len = str_size ( command ) ;
View_Summary view_ = { 0 } ;
View_Summary * view = 0 ;
Buffer_Identifier buffer_id = { 0 } ;
uint32_t flags = 0 ;
bool32 set_fancy_font = 0 ;
if ( out [ 0 ] ! = 0 ) {
int32_t out_len = str_size ( out ) ;
buffer_id = buffer_identifier ( out , out_len ) ;
view = & view_ ;
if ( use_build_panel ) {
view_ = get_or_open_build_panel ( app ) ;
if ( match ( out , " *compilation* " ) ) {
set_fancy_font = 1 ;
}
}
else {
view_ = get_active_view ( app , AccessAll ) ;
}
prev_location = null_location ;
lock_jump_buffer ( out , out_len ) ;
}
else {
// TODO(allen): fix the exec_system_command call so it can take a null buffer_id.
buffer_id = buffer_identifier ( literal ( " *dump* " ) ) ;
}
exec_system_command ( app , view , buffer_id , current_project . dir , current_project . dir_len , command , command_len , flags ) ;
if ( set_fancy_font ) {
set_fancy_compilation_buffer_font ( app ) ;
}
}
}
}
2016-12-24 21:09:53 +00:00
}
2016-10-28 14:11:56 +00:00
2017-01-23 06:19:43 +00:00
//
// Default Framework
//
void
init_memory ( Application_Links * app ) {
int32_t part_size = ( 32 < < 20 ) ;
int32_t general_size = ( 4 < < 20 ) ;
void * part_mem = memory_allocate ( app , part_size ) ;
global_part = make_part ( part_mem , part_size ) ;
void * general_mem = memory_allocate ( app , general_size ) ;
general_memory_open ( & global_general , general_mem , general_size ) ;
}
static void
default_4coder_initialize ( Application_Links * app ) {
init_memory ( app ) ;
process_config_file ( app ) ;
change_theme ( app , default_theme_name . str , default_theme_name . size ) ;
change_font ( app , default_font_name . str , default_font_name . size , 1 ) ;
}
static void
default_4coder_side_by_side_panels ( Application_Links * app ) {
exec_command ( app , open_panel_vsplit ) ;
exec_command ( app , hide_scrollbar ) ;
exec_command ( app , change_active_panel ) ;
exec_command ( app , hide_scrollbar ) ;
}
2016-06-28 22:58:50 +00:00
# endif
2016-08-22 19:31:19 +00:00