4.0.8 almost ready to go
							parent
							
								
									c8fcd07d16
								
							
						
					
					
						commit
						7f05551216
					
				
							
								
								
									
										113
									
								
								4coder_custom.h
								
								
								
								
							
							
						
						
									
										113
									
								
								4coder_custom.h
								
								
								
								
							|  | @ -162,30 +162,10 @@ enum Command_ID{ | |||
|     cmdid_count | ||||
| }; | ||||
| 
 | ||||
| enum{ | ||||
|     CLI_OverlapWithConflict = 0x1, | ||||
|     CLI_AlwaysBindToView = 0x2, | ||||
|     CLI_CursorAtEnd = 0x4, | ||||
| }; | ||||
| 
 | ||||
| enum{ | ||||
|     BufferSetting_Null, | ||||
|     BufferSetting_Lex, | ||||
|     BufferSetting_WrapLine, | ||||
|     BufferSetting_MapID, | ||||
| }; | ||||
| 
 | ||||
| enum{ | ||||
|     AutoTab_ClearLine = 0x1, | ||||
|     AutoTab_UseTab = 0x2 | ||||
| }; | ||||
| 
 | ||||
| // These are regular hooks, any of them can be set to any function
 | ||||
| // that matches the HOOK_SIG pattern.
 | ||||
| enum Hook_ID{ | ||||
|     hook_start, | ||||
|     hook_open_file, | ||||
|     hook_new_file, | ||||
|     hook_file_out_of_sync, | ||||
|     // never below this
 | ||||
|     hook_type_count | ||||
|  | @ -195,6 +175,8 @@ enum Hook_ID{ | |||
| // that do not necessarily have access to the app pointer.
 | ||||
| enum Special_Hook_ID{ | ||||
|     _hook_scroll_rule = hook_type_count, | ||||
|     _hook_new_file, | ||||
|     _hook_open_file, | ||||
| }; | ||||
| 
 | ||||
| // None of the members of *_Summary structs nor any of the data pointed
 | ||||
|  | @ -245,11 +227,6 @@ view_summary_zero(){ | |||
|     return(summary); | ||||
| } | ||||
| 
 | ||||
| enum User_Input_Type{ | ||||
|     UserInputNone, | ||||
|     UserInputKey, | ||||
|     UserInputMouse | ||||
| }; | ||||
| struct User_Input{ | ||||
|     int type; | ||||
|     int abort; | ||||
|  | @ -267,12 +244,6 @@ struct Query_Bar{ | |||
|     String string; | ||||
| }; | ||||
| 
 | ||||
| enum Event_Message_Type{ | ||||
|     EM_No_Message, | ||||
|     EM_Open_View, | ||||
|     EM_Frame, | ||||
|     EM_Close_View | ||||
| }; | ||||
| struct Event_Message{ | ||||
|     int type; | ||||
| }; | ||||
|  | @ -282,18 +253,73 @@ struct Theme_Color{ | |||
|     unsigned int color; | ||||
| }; | ||||
| 
 | ||||
| enum Access_Types{ | ||||
| // Flags and enum values
 | ||||
| // TODO(allen): auto generate this and the docs for it
 | ||||
| enum User_Input_Type_ID{ | ||||
|     UserInputNone, | ||||
|     UserInputKey, | ||||
|     UserInputMouse | ||||
| }; | ||||
| 
 | ||||
| enum Event_Message_Type_ID{ | ||||
|     EventMessage_NoMessage, | ||||
|     EventMessage_OpenView, | ||||
|     EventMessage_Frame, | ||||
|     EventMessage_CloseView | ||||
| }; | ||||
| 
 | ||||
| enum Buffer_Setting_ID{ | ||||
|     BufferSetting_Null, | ||||
|     BufferSetting_Lex, | ||||
|     BufferSetting_WrapLine, | ||||
|     BufferSetting_MapID, | ||||
| }; | ||||
| 
 | ||||
| enum Access_Flag{ | ||||
|     AccessOpen      = 0x0, | ||||
|     AccessProtected = 0x1, | ||||
|     AccessHidden    = 0x2, | ||||
|     AccessAll       = 0xFF | ||||
| }; | ||||
| 
 | ||||
| enum Seek_Boundry_Flag{ | ||||
|     BoundryWhitespace   = 0x1, | ||||
|     BoundryToken        = 0x2, | ||||
|     BoundryAlphanumeric = 0x4, | ||||
|     BoundryCamelCase    = 0x8 | ||||
| }; | ||||
| 
 | ||||
| enum Command_Line_Input_Flag{ | ||||
|     CLI_OverlapWithConflict = 0x1, | ||||
|     CLI_AlwaysBindToView    = 0x2, | ||||
|     CLI_CursorAtEnd         = 0x4, | ||||
| }; | ||||
| 
 | ||||
| enum Auto_Tab_Flag{ | ||||
|     AutoTab_ClearLine = 0x1, | ||||
|     AutoTab_UseTab    = 0x2 | ||||
| }; | ||||
| 
 | ||||
| enum Input_Type_Flag{ | ||||
|     EventOnAnyKey      = 0x1, | ||||
|     EventOnEsc         = 0x2, | ||||
|     EventOnLeftButton  = 0x4, | ||||
|     EventOnRightButton = 0x8, | ||||
|     EventOnWheel       = 0x10, | ||||
|     EventOnButton      = (EventOnLeftButton | EventOnRightButton | EventOnWheel), | ||||
|      | ||||
|     // NOTE(allen): These don't work so much, so let's pretend they're not here for now.
 | ||||
|     EventOnMouseMove   = 0x20, | ||||
|     EventOnMouse       = (EventOnButton | EventOnMouseMove), | ||||
|      | ||||
|     EventAll           = 0xFF | ||||
| }; | ||||
| 
 | ||||
| #define VIEW_ROUTINE_SIG(name) void name(struct Application_Links *app, int view_id) | ||||
| #define GET_BINDING_DATA(name) int name(void *data, int size) | ||||
| #define CUSTOM_COMMAND_SIG(name) void name(struct Application_Links *app) | ||||
| #define HOOK_SIG(name) int name(struct Application_Links *app) | ||||
| #define OPEN_FILE_HOOK_SIG(name) int name(struct Application_Links *app, int buffer_id) | ||||
| #define SCROLL_RULE_SIG(name) int name(float target_x, float target_y, float *scroll_x, float *scroll_y, int view_id, int is_new_target, float dt) | ||||
| 
 | ||||
| extern "C"{ | ||||
|  | @ -301,6 +327,8 @@ extern "C"{ | |||
|     typedef CUSTOM_COMMAND_SIG(Custom_Command_Function); | ||||
|     typedef GET_BINDING_DATA(Get_Binding_Data_Function); | ||||
|     typedef HOOK_SIG(Hook_Function); | ||||
|      | ||||
|     typedef OPEN_FILE_HOOK_SIG(Open_File_Hook_Function); | ||||
|     typedef SCROLL_RULE_SIG(Scroll_Rule_Function); | ||||
| } | ||||
| 
 | ||||
|  | @ -308,27 +336,6 @@ struct Application_Links; | |||
| #include "4coder_custom_api.h" | ||||
| 
 | ||||
| 
 | ||||
| // Boundry type flags
 | ||||
| #define BoundryWhitespace 0x1 | ||||
| #define BoundryToken 0x2 | ||||
| #define BoundryAlphanumeric 0x4 | ||||
| #define BoundryCamelCase 0x8 | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // Input type flags
 | ||||
| #define EventOnAnyKey 0x1 | ||||
| #define EventOnEsc 0x2 | ||||
| #define EventOnLeftButton 0x4 | ||||
| #define EventOnRightButton 0x8 | ||||
| #define EventOnWheel 0x10 | ||||
| #define EventOnButton (EventOnLeftButton | EventOnRightButton | EventOnWheel) | ||||
| 
 | ||||
| // NOTE(allen): These don't work so much, so let's pretend they're not here for now.
 | ||||
| #define EventOnMouseMove 0x20 | ||||
| #define EventOnMouse (EventOnButton | EventOnMouseMove) | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| #define _GET_VERSION_SIG(n) int n(int maj, int min, int patch) | ||||
| typedef _GET_VERSION_SIG(_Get_Version_Function); | ||||
|  |  | |||
|  | @ -6,17 +6,15 @@ | |||
| #define DIRECTORY_CD_SIG(n) int n(Application_Links *app, char *dir, int *len, int capacity, char *rel_path, int rel_len) | ||||
| #define GET_FILE_LIST_SIG(n) File_List n(Application_Links *app, char *dir, int len) | ||||
| #define FREE_FILE_LIST_SIG(n) void n(Application_Links *app, File_List list) | ||||
| #define CLIPBOARD_POST_SIG(n) int n(Application_Links *app, char *str, int len) | ||||
| #define CLIPBOARD_POST_SIG(n) void n(Application_Links *app, char *str, int len) | ||||
| #define CLIPBOARD_COUNT_SIG(n) int n(Application_Links *app) | ||||
| #define CLIPBOARD_INDEX_SIG(n) int n(Application_Links *app, int index, char *out, int len) | ||||
| #define GET_BUFFER_FIRST_SIG(n) Buffer_Summary n(Application_Links *app, unsigned int access) | ||||
| #define GET_BUFFER_NEXT_SIG(n) void n(Application_Links *app, Buffer_Summary *buffer, unsigned int access) | ||||
| #define GET_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, int index, unsigned int access) | ||||
| #define GET_PARAMETER_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, int param_index, unsigned int access) | ||||
| #define GET_BUFFER_BY_NAME_SIG(n) Buffer_Summary n(Application_Links *app, char *filename, int len, unsigned int access) | ||||
| #define REFRESH_BUFFER_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer) | ||||
| #define BUFFER_READ_RANGE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *out) | ||||
| #define GET_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, int buffer_id, unsigned int access) | ||||
| #define GET_BUFFER_BY_NAME_SIG(n) Buffer_Summary n(Application_Links *app, char *name, int len, unsigned int access) | ||||
| #define BUFFER_SEEK_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start_pos, int seek_forward, unsigned int flags) | ||||
| #define BUFFER_READ_RANGE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *out) | ||||
| #define BUFFER_REPLACE_RANGE_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *str, int len) | ||||
| #define BUFFER_SET_SETTING_SIG(n) int n(Application_Links *app, Buffer_Summary *buffer, int setting, int value) | ||||
| #define CREATE_BUFFER_SIG(n) Buffer_Summary n(Application_Links *app, char *filename, int filename_len, int do_in_background) | ||||
|  | @ -26,7 +24,6 @@ | |||
| #define GET_VIEW_NEXT_SIG(n) void n(Application_Links *app, View_Summary *view, unsigned int access) | ||||
| #define GET_VIEW_SIG(n) View_Summary n(Application_Links *app, int index, unsigned int access) | ||||
| #define GET_ACTIVE_VIEW_SIG(n) View_Summary n(Application_Links *app, unsigned int access) | ||||
| #define REFRESH_VIEW_SIG(n) int n(Application_Links *app, View_Summary *view) | ||||
| #define VIEW_AUTO_TAB_SIG(n) int n(Application_Links *app, View_Summary *view, int start, int end, int tab_width, unsigned int flags) | ||||
| #define VIEW_COMPUTE_CURSOR_SIG(n) Full_Cursor n(Application_Links *app, View_Summary *view, Buffer_Seek seek) | ||||
| #define VIEW_SET_CURSOR_SIG(n) int n(Application_Links *app, View_Summary *view, Buffer_Seek seek, int set_preferred_x) | ||||
|  | @ -62,11 +59,9 @@ extern "C"{ | |||
|     typedef GET_BUFFER_FIRST_SIG(Get_Buffer_First_Function); | ||||
|     typedef GET_BUFFER_NEXT_SIG(Get_Buffer_Next_Function); | ||||
|     typedef GET_BUFFER_SIG(Get_Buffer_Function); | ||||
|     typedef GET_PARAMETER_BUFFER_SIG(Get_Parameter_Buffer_Function); | ||||
|     typedef GET_BUFFER_BY_NAME_SIG(Get_Buffer_By_Name_Function); | ||||
|     typedef REFRESH_BUFFER_SIG(Refresh_Buffer_Function); | ||||
|     typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function); | ||||
|     typedef BUFFER_SEEK_SIG(Buffer_Seek_Function); | ||||
|     typedef BUFFER_READ_RANGE_SIG(Buffer_Read_Range_Function); | ||||
|     typedef BUFFER_REPLACE_RANGE_SIG(Buffer_Replace_Range_Function); | ||||
|     typedef BUFFER_SET_SETTING_SIG(Buffer_Set_Setting_Function); | ||||
|     typedef CREATE_BUFFER_SIG(Create_Buffer_Function); | ||||
|  | @ -76,7 +71,6 @@ extern "C"{ | |||
|     typedef GET_VIEW_NEXT_SIG(Get_View_Next_Function); | ||||
|     typedef GET_VIEW_SIG(Get_View_Function); | ||||
|     typedef GET_ACTIVE_VIEW_SIG(Get_Active_View_Function); | ||||
|     typedef REFRESH_VIEW_SIG(Refresh_View_Function); | ||||
|     typedef VIEW_AUTO_TAB_SIG(View_Auto_Tab_Function); | ||||
|     typedef VIEW_COMPUTE_CURSOR_SIG(View_Compute_Cursor_Function); | ||||
|     typedef VIEW_SET_CURSOR_SIG(View_Set_Cursor_Function); | ||||
|  | @ -115,11 +109,9 @@ struct Application_Links{ | |||
|     Get_Buffer_First_Function *get_buffer_first; | ||||
|     Get_Buffer_Next_Function *get_buffer_next; | ||||
|     Get_Buffer_Function *get_buffer; | ||||
|     Get_Parameter_Buffer_Function *get_parameter_buffer; | ||||
|     Get_Buffer_By_Name_Function *get_buffer_by_name; | ||||
|     Refresh_Buffer_Function *refresh_buffer; | ||||
|     Buffer_Read_Range_Function *buffer_read_range; | ||||
|     Buffer_Seek_Function *buffer_seek; | ||||
|     Buffer_Read_Range_Function *buffer_read_range; | ||||
|     Buffer_Replace_Range_Function *buffer_replace_range; | ||||
|     Buffer_Set_Setting_Function *buffer_set_setting; | ||||
|     Create_Buffer_Function *create_buffer; | ||||
|  | @ -129,7 +121,6 @@ struct Application_Links{ | |||
|     Get_View_Next_Function *get_view_next; | ||||
|     Get_View_Function *get_view; | ||||
|     Get_Active_View_Function *get_active_view; | ||||
|     Refresh_View_Function *refresh_view; | ||||
|     View_Auto_Tab_Function *view_auto_tab; | ||||
|     View_Compute_Cursor_Function *view_compute_cursor; | ||||
|     View_Set_Cursor_Function *view_set_cursor; | ||||
|  | @ -170,11 +161,9 @@ app_links->clipboard_index = external_clipboard_index;\ | |||
| app_links->get_buffer_first = external_get_buffer_first;\ | ||||
| app_links->get_buffer_next = external_get_buffer_next;\ | ||||
| app_links->get_buffer = external_get_buffer;\ | ||||
| app_links->get_parameter_buffer = external_get_parameter_buffer;\ | ||||
| app_links->get_buffer_by_name = external_get_buffer_by_name;\ | ||||
| app_links->refresh_buffer = external_refresh_buffer;\ | ||||
| app_links->buffer_read_range = external_buffer_read_range;\ | ||||
| app_links->buffer_seek = external_buffer_seek;\ | ||||
| app_links->buffer_read_range = external_buffer_read_range;\ | ||||
| app_links->buffer_replace_range = external_buffer_replace_range;\ | ||||
| app_links->buffer_set_setting = external_buffer_set_setting;\ | ||||
| app_links->create_buffer = external_create_buffer;\ | ||||
|  | @ -184,7 +173,6 @@ app_links->get_view_first = external_get_view_first;\ | |||
| app_links->get_view_next = external_get_view_next;\ | ||||
| app_links->get_view = external_get_view;\ | ||||
| app_links->get_active_view = external_get_active_view;\ | ||||
| app_links->refresh_view = external_refresh_view;\ | ||||
| app_links->view_auto_tab = external_view_auto_tab;\ | ||||
| app_links->view_compute_cursor = external_view_compute_cursor;\ | ||||
| app_links->view_set_cursor = external_view_set_cursor;\ | ||||
|  |  | |||
|  | @ -60,11 +60,11 @@ CUSTOM_COMMAND_SIG(rewrite_as_single_caps){ | |||
|     cursor = view.cursor; | ||||
|      | ||||
|     exec_command(app, seek_token_left); | ||||
|     app->refresh_view(app, &view); | ||||
|     refresh_view(app, &view); | ||||
|     range.min = view.cursor.pos; | ||||
|      | ||||
|     exec_command(app, seek_token_right); | ||||
|     app->refresh_view(app, &view); | ||||
|     refresh_view(app, &view); | ||||
|     range.max = view.cursor.pos; | ||||
|      | ||||
|     string.str = (char*)app->memory; | ||||
|  | @ -137,13 +137,14 @@ HOOK_SIG(my_start){ | |||
|     return(0); | ||||
| } | ||||
| 
 | ||||
| HOOK_SIG(my_file_settings){ | ||||
| OPEN_FILE_HOOK_SIG(my_file_settings){ | ||||
|     // NOTE(allen|a4): In hooks that want parameters, such as this file
 | ||||
|     // opened hook.  The file created hook is guaranteed to have only
 | ||||
|     // and exactly one buffer parameter.  In normal command callbacks
 | ||||
|     // there are no parameter buffers.
 | ||||
|     unsigned int access = AccessProtected|AccessHidden; | ||||
|     Buffer_Summary buffer = app->get_parameter_buffer(app, 0, access); | ||||
|     //Buffer_Summary buffer = app->get_parameter_buffer(app, 0, access);
 | ||||
|     Buffer_Summary buffer = app->get_buffer(app, buffer_id, access); | ||||
|     assert(buffer.exists); | ||||
|      | ||||
|     int treat_as_code = 0; | ||||
|  | @ -330,8 +331,8 @@ get_bindings(void *data, int size){ | |||
|     // NOTE(allen|a3.1): Hooks have no loyalties to maps. All hooks are global
 | ||||
|     // and once set they always apply, regardless of what map is active.
 | ||||
|     set_hook(context, hook_start, my_start); | ||||
|     set_hook(context, hook_open_file, my_file_settings); | ||||
|      | ||||
|     set_open_file_hook(context, my_file_settings); | ||||
|     set_scroll_rule(context, smooth_scroll_rule); | ||||
|      | ||||
|     default_keys(context); | ||||
|  |  | |||
|  | @ -710,7 +710,7 @@ CUSTOM_COMMAND_SIG(if0_off){ | |||
|                        DEF_TAB_WIDTH, | ||||
|                        0); | ||||
|      | ||||
|     app->refresh_view(app, &view); | ||||
|     refresh_view(app, &view); | ||||
|     range = get_range(&view); | ||||
|     pos = range.max; | ||||
|      | ||||
|  | @ -733,7 +733,7 @@ CUSTOM_COMMAND_SIG(backspace_word){ | |||
|      | ||||
|     pos2 = view.cursor.pos; | ||||
|     exec_command(app, seek_alphanumeric_left); | ||||
|     app->refresh_view(app, &view); | ||||
|     refresh_view(app, &view); | ||||
|     pos1 = view.cursor.pos; | ||||
|      | ||||
|     buffer = app->get_buffer(app, view.buffer_id, access); | ||||
|  | @ -751,7 +751,7 @@ CUSTOM_COMMAND_SIG(delete_word){ | |||
|      | ||||
|     pos1 = view.cursor.pos; | ||||
|     exec_command(app, seek_alphanumeric_right); | ||||
|     app->refresh_view(app, &view); | ||||
|     refresh_view(app, &view); | ||||
|     pos2 = view.cursor.pos; | ||||
|      | ||||
|     buffer = app->get_buffer(app, view.buffer_id, access); | ||||
|  | @ -992,7 +992,7 @@ CUSTOM_COMMAND_SIG(replace_in_range){ | |||
|      | ||||
|     while (new_pos + r.size <= range.end){ | ||||
|         app->buffer_replace_range(app, &buffer, new_pos, new_pos + r.size, w.str, w.size); | ||||
|         app->refresh_view(app, &view); | ||||
|         refresh_view(app, &view); | ||||
|         range = get_range(&view); | ||||
|         pos = new_pos + w.size; | ||||
|         buffer_seek_string_forward(app, &buffer, pos, r.str, r.size, &new_pos); | ||||
|  |  | |||
							
								
								
									
										10
									
								
								4coder_gui.h
								
								
								
								
							
							
						
						
									
										10
									
								
								4coder_gui.h
								
								
								
								
							|  | @ -15,13 +15,13 @@ gui_id_zero(){ | |||
| 
 | ||||
| struct GUI_Scroll_Vars{ | ||||
|     float scroll_y; | ||||
|     float target_y; | ||||
|     float prev_target_y; | ||||
|     float max_y; | ||||
|     int  target_y; | ||||
|     int  prev_target_y; | ||||
|     int  max_y; | ||||
|      | ||||
|     float scroll_x; | ||||
|     float target_x; | ||||
|     float prev_target_x; | ||||
|     int target_x; | ||||
|     int  prev_target_x; | ||||
| }; | ||||
| 
 | ||||
| typedef struct GUI GUI; | ||||
|  |  | |||
|  | @ -173,6 +173,26 @@ set_hook(Bind_Helper *helper, int hook_id, Hook_Function *func){ | |||
|     write_unit(helper, unit); | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
| set_open_file_hook(Bind_Helper *helper, Open_File_Hook_Function *func){ | ||||
|     Binding_Unit unit; | ||||
|     unit.type = unit_hook; | ||||
|     unit.hook.hook_id = _hook_open_file; | ||||
|     unit.hook.func = (void*) func; | ||||
|      | ||||
|     write_unit(helper, unit); | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
| set_new_file_hook(Bind_Helper *helper, Open_File_Hook_Function *func){ | ||||
|     Binding_Unit unit; | ||||
|     unit.type = unit_hook; | ||||
|     unit.hook.hook_id = _hook_new_file; | ||||
|     unit.hook.func = (void*) func; | ||||
|      | ||||
|     write_unit(helper, unit); | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
| set_scroll_rule(Bind_Helper *helper, Scroll_Rule_Function *func){ | ||||
|     Binding_Unit unit; | ||||
|  | @ -392,13 +412,23 @@ round_up(int x, int b){ | |||
|     return(r); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| refresh_buffer(Application_Links *app, Buffer_Summary *buffer){ | ||||
|     *buffer = app->get_buffer(app, buffer->buffer_id, AccessAll); | ||||
| } | ||||
| 
 | ||||
| void | ||||
| refresh_view(Application_Links *app, View_Summary *view){ | ||||
|     *view = app->get_view(app, view->view_id, AccessAll); | ||||
| } | ||||
| 
 | ||||
| int | ||||
| init_stream_chunk(Stream_Chunk *chunk, | ||||
|                   Application_Links *app, Buffer_Summary *buffer, | ||||
|                   int pos, char *data, int size){ | ||||
|     int result = 0; | ||||
|      | ||||
|     app->refresh_buffer(app, buffer); | ||||
|     refresh_buffer(app, buffer); | ||||
|     if (pos >= 0 && pos < buffer->size && size > 0){ | ||||
|         result = 1; | ||||
|         chunk->app = app; | ||||
|  | @ -422,7 +452,7 @@ forward_stream_chunk(Stream_Chunk *chunk){ | |||
|     Buffer_Summary *buffer = chunk->buffer; | ||||
|     int result = 0; | ||||
|      | ||||
|     app->refresh_buffer(app, buffer); | ||||
|     refresh_buffer(app, buffer); | ||||
|     if (chunk->end < buffer->size){ | ||||
|         result = 1; | ||||
|         chunk->start = chunk->end; | ||||
|  | @ -442,7 +472,7 @@ backward_stream_chunk(Stream_Chunk *chunk){ | |||
|     Buffer_Summary *buffer = chunk->buffer; | ||||
|     int result = 0; | ||||
|      | ||||
|     app->refresh_buffer(app, buffer); | ||||
|     refresh_buffer(app, buffer); | ||||
|     if (chunk->start > 0){ | ||||
|         result = 1; | ||||
|         chunk->end = chunk->start; | ||||
|  |  | |||
							
								
								
									
										37
									
								
								4ed.cpp
								
								
								
								
							
							
						
						
									
										37
									
								
								4ed.cpp
								
								
								
								
							|  | @ -242,7 +242,7 @@ do_feedback_message(System_Functions *system, Models *models, String value){ | |||
|     Editing_File *file = models->message_buffer; | ||||
|      | ||||
|     if (file){ | ||||
|         output_file_append(system, models, file, value, 1); | ||||
|         output_file_append(system, models, file, value, true); | ||||
|         i32 pos = buffer_size(&file->state.buffer); | ||||
|         for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); | ||||
|              file_view_iter_good(iter); | ||||
|  | @ -318,7 +318,7 @@ COMMAND_DECL(center_view){ | |||
|     REQ_READABLE_VIEW(view); | ||||
|     REQ_FILE(file, view); | ||||
|      | ||||
|     f32 y, h; | ||||
|     f32 y = 0, h = 0; | ||||
|     if (view->file_data.unwrapped_lines){ | ||||
|         y = view->recent->cursor.unwrapped_y; | ||||
|     } | ||||
|  | @ -329,14 +329,14 @@ COMMAND_DECL(center_view){ | |||
|     h = view_file_height(view); | ||||
|     y = clamp_bottom(0.f, y - h*.5f); | ||||
|      | ||||
|     view->recent->scroll.target_y = y; | ||||
|     view->recent->scroll.target_y = ROUND32(y); | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(left_adjust_view){ | ||||
|     REQ_READABLE_VIEW(view); | ||||
|     REQ_FILE(file, view); | ||||
|      | ||||
|     f32 x; | ||||
|     f32 x = 0; | ||||
|     if (view->file_data.unwrapped_lines){ | ||||
|         x = view->recent->cursor.unwrapped_x; | ||||
|     } | ||||
|  | @ -345,7 +345,7 @@ COMMAND_DECL(left_adjust_view){ | |||
|     } | ||||
|      | ||||
|     x = clamp_bottom(0.f, x - 30.f); | ||||
|     view->recent->scroll.target_x = x; | ||||
|     view->recent->scroll.target_x = ROUND32(x); | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(set_cursor){ | ||||
|  | @ -918,8 +918,8 @@ COMMAND_DECL(close_panel){ | |||
| COMMAND_DECL(page_down){ | ||||
|     REQ_READABLE_VIEW(view); | ||||
|      | ||||
|     f32 height = view_file_height(view); | ||||
|     f32 max_target_y = view->recent->scroll.max_y; | ||||
|     i32 height = CEIL32(view_file_height(view)); | ||||
|     i32 max_target_y = view->recent->scroll.max_y; | ||||
|      | ||||
|     view->recent->scroll.target_y = | ||||
|         clamp_top(view->recent->scroll.target_y + height, max_target_y); | ||||
|  | @ -931,10 +931,10 @@ COMMAND_DECL(page_down){ | |||
| COMMAND_DECL(page_up){ | ||||
|     REQ_READABLE_VIEW(view); | ||||
|      | ||||
|     f32 height = view_file_height(view); | ||||
|     i32 height = CEIL32(view_file_height(view)); | ||||
|      | ||||
|     view->recent->scroll.target_y = | ||||
|         clamp_bottom(0.f, view->recent->scroll.target_y - height); | ||||
|         clamp_bottom(0, view->recent->scroll.target_y - height); | ||||
|      | ||||
|     view->recent->cursor = | ||||
|         view_compute_cursor_from_xy(view, 0, view->recent->scroll.target_y + (height - view->line_height)*.5f); | ||||
|  | @ -1624,6 +1624,8 @@ App_Init_Sig(app_init){ | |||
|         b32 did_file = 0; | ||||
|          | ||||
|         models->scroll_rule = fallback_scroll_rule; | ||||
|         models->hook_open_file = 0; | ||||
|         models->hook_new_file = 0; | ||||
|          | ||||
|         setup_command_table(); | ||||
|          | ||||
|  | @ -1754,7 +1756,19 @@ App_Init_Sig(app_init){ | |||
|                                     models->hooks[hook_id] = (Hook_Function*)unit->hook.func; | ||||
|                                 } | ||||
|                                 else{ | ||||
|                                     switch (hook_id){ | ||||
|                                         case _hook_open_file: | ||||
|                                         models->hook_open_file = (Open_File_Hook_Function*)unit->hook.func; | ||||
|                                         break; | ||||
|                                          | ||||
|                                         case _hook_new_file: | ||||
|                                         models->hook_new_file = (Open_File_Hook_Function*)unit->hook.func; | ||||
|                                         break; | ||||
|                                          | ||||
|                                         case _hook_scroll_rule: | ||||
|                                         models->scroll_rule = (Scroll_Rule_Function*)unit->hook.func; | ||||
|                                         break; | ||||
|                                     } | ||||
|                                 } | ||||
|                             } | ||||
|                         }break; | ||||
|  | @ -1861,11 +1875,6 @@ App_Init_Sig(app_init){ | |||
|     vars->cli_processes.procs = push_array(partition, CLI_Process, max_children); | ||||
|     vars->cli_processes.max = max_children; | ||||
|     vars->cli_processes.count = 0; | ||||
|      | ||||
|     // NOTE(allen): parameter setup
 | ||||
|     models->buffer_param_max = 1; | ||||
|     models->buffer_param_count = 0; | ||||
|     models->buffer_param_indices = push_array(partition, i32, models->buffer_param_max); | ||||
| } | ||||
| 
 | ||||
| internal i32 | ||||
|  |  | |||
|  | @ -100,16 +100,6 @@ get_file_from_identifier(System_Functions *system, Working_Set *working_set, Buf | |||
|     return(file); | ||||
| } | ||||
| 
 | ||||
| internal String | ||||
| make_string_terminated(Partition *part, char *str, int len){ | ||||
|     char *space = (char*)push_array(part, char, len + 1); | ||||
|     String string = make_string(str, len, len+1); | ||||
|     copy_fast_unsafe(space, string); | ||||
|     string.str = space; | ||||
|     terminate_with_null(&string); | ||||
|     return(string); | ||||
| } | ||||
| 
 | ||||
| internal Editing_File* | ||||
| imp_get_file(Command_Data *cmd, Buffer_Summary *buffer){ | ||||
|     Editing_File *file = 0; | ||||
|  | @ -149,7 +139,10 @@ imp_get_view(Command_Data *cmd, View_Summary *view){ | |||
|     return(vptr); | ||||
| } | ||||
| 
 | ||||
| EXEC_COMMAND_SIG(external_exec_command){ | ||||
| EXEC_COMMAND_SIG(external_exec_command)/*
 | ||||
| DOC_PARAM(command_id, an integer id enumerated in 4coder_custom.h starting with cmdid) | ||||
| DOC(Executes the command associated with the command_id passed in) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Command_Function function = command_table[command_id]; | ||||
|     Command_Binding binding = {}; | ||||
|  | @ -160,7 +153,35 @@ EXEC_COMMAND_SIG(external_exec_command){ | |||
| } | ||||
| 
 | ||||
| // TODO(allen): This is a bit of a mess and needs to be fixed soon
 | ||||
| EXEC_SYSTEM_COMMAND_SIG(external_exec_system_command){ | ||||
| EXEC_SYSTEM_COMMAND_SIG(external_exec_system_command)/*
 | ||||
| DOC_PARAM(view, the target view that will display the output buffer, may be NULL, see description for details) | ||||
| DOC_PARAM(buffer, a buffer identifier for the buffer that will be filled with the output from the command) | ||||
| DOC_PARAM(path, the path from which the command is executed) | ||||
| DOC_PARAM(path_len, the length of the path string) | ||||
| DOC_PARAM(command, the command to be executed) | ||||
| DOC_PARAM(command_len, the length of the command string) | ||||
| DOC_PARAM(flags, may be zero or one or more CLI flags ORed together) | ||||
| DOC_RETURN(returns non-zero if the command is successfully started, returns zero otherwise) | ||||
| DOC | ||||
| ( | ||||
| Executes a system command as if called from the command line, and sends the output to a buffer. The buffer | ||||
| identifier can either name a new buffer that does not exist, name a buffer that does exist, or provide the | ||||
| id of a buffer that does exist.  If the buffer already exists the command will fail, unless | ||||
| CLI_OverlapWithConflict is set in the flags. | ||||
| 
 | ||||
| If the buffer is not already in an active view, and the view parameter is no NULL, then the provided view | ||||
| will display the output buffer.  If the view parameter is NULL, no view will display the output. | ||||
| 
 | ||||
| If CLI_OverlapWithConflict is set in the flags, the command will always be executed even if another command | ||||
| was outputting to the same buffer still. | ||||
| 
 | ||||
| If CLI_AlwaysBindToView is set and the view parameter is not NULL, then the specified view will always | ||||
| begin displaying the output buffer, even if another active view already displays that buffer. | ||||
| 
 | ||||
| If CLI_CursorAtEnd is set the cursor in the output buffer will be placed at the end of the buffer instead | ||||
| of at the beginning. | ||||
| ) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     System_Functions *system = cmd->system; | ||||
|     App_Vars *vars = cmd->vars; | ||||
|  | @ -178,22 +199,9 @@ EXEC_SYSTEM_COMMAND_SIG(external_exec_system_command){ | |||
|     Partition *part = &models->mem.part; | ||||
|     Temp_Memory temp = begin_temp_memory(part); | ||||
|      | ||||
|     View *vptr = 0; | ||||
|      | ||||
|     int result = true; | ||||
|      | ||||
|     if (view->exists){ | ||||
|         Live_Views *live_set = cmd->live_set; | ||||
|         i32 view_id = view->view_id - 1; | ||||
|         if (view_id >= 0 && view_id < live_set->max){ | ||||
|             vptr = live_set->views + view_id; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     if (vptr == 0){ | ||||
|         result = false; | ||||
|         goto done; | ||||
|     } | ||||
|     View *vptr = imp_get_view(cmd, view); | ||||
|      | ||||
|     if (vars->cli_processes.count < vars->cli_processes.max){ | ||||
|         file = get_file_from_identifier(system, working_set, buffer); | ||||
|  | @ -248,7 +256,7 @@ EXEC_SYSTEM_COMMAND_SIG(external_exec_system_command){ | |||
|                 if (!(flags & CLI_AlwaysBindToView)){ | ||||
|                     View_Iter iter = file_view_iter_init(&models->layout, file, 0); | ||||
|                     if (file_view_iter_good(iter)){ | ||||
|                         bind_to_new_view = 0; | ||||
|                         bind_to_new_view = false; | ||||
|                     } | ||||
|                 } | ||||
|             } | ||||
|  | @ -282,7 +290,7 @@ EXEC_SYSTEM_COMMAND_SIG(external_exec_system_command){ | |||
|                 command_string = make_string_terminated(part, command, command_len); | ||||
|             } | ||||
|              | ||||
|             if (bind_to_new_view){ | ||||
|             if (vptr && bind_to_new_view){ | ||||
|                 view_set_file(vptr, file, models); | ||||
|                 view_show_file(vptr); | ||||
|             } | ||||
|  | @ -313,7 +321,19 @@ EXEC_SYSTEM_COMMAND_SIG(external_exec_system_command){ | |||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| DIRECTORY_GET_HOT_SIG(external_directory_get_hot){ | ||||
| DIRECTORY_GET_HOT_SIG(external_directory_get_hot)/*
 | ||||
| DOC_PARAM(out, a buffer that receives the 4coder 'hot directory') | ||||
| DOC_PARAM(capacity, the maximum size to be output to the output buffer) | ||||
| DOC_RETURN(returns the size of the string written into the buffer) | ||||
| DOC | ||||
| ( | ||||
| 4coder has a concept of a 'hot directory' which is the directory most recently | ||||
| accessed in the GUI.  Whenever the GUI is opened it shows the hot directory. | ||||
| 
 | ||||
| In the future this will be deprecated and eliminated in favor of more flexible | ||||
| directories controlled by the custom side. | ||||
| ) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Hot_Directory *hot = &cmd->models->hot_directory; | ||||
|     i32 copy_max = capacity - 1; | ||||
|  | @ -331,7 +351,16 @@ DIRECTORY_GET_HOT_SIG(external_directory_get_hot){ | |||
| 
 | ||||
| #define external_directory_cd system->directory_cd | ||||
| 
 | ||||
| GET_FILE_LIST_SIG(external_get_file_list){ | ||||
| GET_FILE_LIST_SIG(external_get_file_list)/*
 | ||||
| DOC_PARAM(dir, the directory whose files will be enumerated in the returned list) | ||||
| DOC_PARAM(len, the length of the dir string) | ||||
| DOC_RETURN | ||||
| ( | ||||
| returns a File_List struct containing pointers to the names of the files in | ||||
| the specified directory.  The File_List returned should be passed to free_file_list | ||||
| when it is no longer in use. | ||||
| ) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     System_Functions *system = cmd->system; | ||||
|     File_List result = {}; | ||||
|  | @ -339,35 +368,61 @@ GET_FILE_LIST_SIG(external_get_file_list){ | |||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| FREE_FILE_LIST_SIG(external_free_file_list){ | ||||
| FREE_FILE_LIST_SIG(external_free_file_list)/*
 | ||||
| DOC_PARAM(list, the file list to be freed) | ||||
| DOC(after this call the file list passed in should not be read or written to) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     System_Functions *system = cmd->system; | ||||
|     system->set_file_list(&list, make_string(0, 0)); | ||||
| } | ||||
| 
 | ||||
| CLIPBOARD_POST_SIG(external_clipboard_post){ | ||||
| CLIPBOARD_POST_SIG(external_clipboard_post)/*
 | ||||
| DOC_PARAM(str, the string to post to the clipboard) | ||||
| DOC_PARAM(len, the length of the string str) | ||||
| DOC | ||||
| ( | ||||
| Stores the string str in the clipboard initially with index 0. | ||||
| Also reports the copy to the operating system, so that it may | ||||
| be pasted into other applications. | ||||
| ) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     System_Functions *system = cmd->system; | ||||
|     Models *models = cmd->models; | ||||
|     General_Memory *general = &models->mem.general; | ||||
|     Working_Set *working = &models->working_set; | ||||
|     int result = false; | ||||
|      | ||||
|     String *dest = working_set_next_clipboard_string(general, working, len); | ||||
|     copy(dest, make_string(str, len)); | ||||
|     system->post_clipboard(*dest); | ||||
|      | ||||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| CLIPBOARD_COUNT_SIG(external_clipboard_count){ | ||||
| CLIPBOARD_COUNT_SIG(external_clipboard_count)/*
 | ||||
| DOC(returns the number of items in the clipboard) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Working_Set *working = &cmd->models->working_set; | ||||
|     int count = working->clipboard_size; | ||||
|     return(count); | ||||
| } | ||||
| 
 | ||||
| CLIPBOARD_INDEX_SIG(external_clipboard_index){ | ||||
| CLIPBOARD_INDEX_SIG(external_clipboard_index)/*
 | ||||
| DOC_PARAM(index, the index of the item to be read) | ||||
| DOC_PARAM(out, a buffer where the clipboard contents are written or NULL) | ||||
| DOC_PARAM(len, the length of the out buffer) | ||||
| DOC_RETURN(returns the size of the item on the clipboard associated with the given index) | ||||
| DOC | ||||
| ( | ||||
| There are multiple items on the 4coder clipboard.  The most recent copy is always at | ||||
| index 0.  The second most recent is at index 1, and so on for all the stored clipboard items. | ||||
| This function reads one of the clipboard items and stores it into the out buffer, if the out | ||||
| buffer is not NULL.  This function always returns the size of the clipboard item specified | ||||
| even if the output buffer is NULL.  If the output buffer is too small to contain the whole | ||||
| string, it is filled with the first len character of the clipboard contents.  The output | ||||
| string is not null terminated. | ||||
| ) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Working_Set *working = &cmd->models->working_set; | ||||
|      | ||||
|  | @ -405,7 +460,19 @@ internal_get_buffer_next(Working_Set *working_set, Buffer_Summary *buffer){ | |||
|     } | ||||
| } | ||||
| 
 | ||||
| GET_BUFFER_FIRST_SIG(external_get_buffer_first){ | ||||
| GET_BUFFER_FIRST_SIG(external_get_buffer_first)/*
 | ||||
| DOC_PARAM(access, the access flags for the access) | ||||
| DOC_RETURN(returns the summary of the first buffer in a buffer loop) | ||||
| DOC | ||||
| ( | ||||
| Begins a loop across all the buffers. | ||||
| 
 | ||||
| If the buffer returned does not exist, the loop is finished.  Buffers | ||||
| should not be killed durring a buffer loop. | ||||
| ) | ||||
| DOC_SEE(Access_Flag) | ||||
| DOC_SEE(get_buffer_next) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Working_Set *working_set = &cmd->models->working_set; | ||||
|     Buffer_Summary result = {}; | ||||
|  | @ -418,7 +485,21 @@ GET_BUFFER_FIRST_SIG(external_get_buffer_first){ | |||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| GET_BUFFER_NEXT_SIG(external_get_buffer_next){ | ||||
| GET_BUFFER_NEXT_SIG(external_get_buffer_next)/*
 | ||||
| DOC_PARAM(buffer, pointer to the loop buffer originally returned by get_buffer_first) | ||||
| DOC_PARAM(access, the access flags for the access) | ||||
| DOC | ||||
| ( | ||||
| Writes the next buffer into the buffer struct.  To get predictable results every | ||||
| call to get_buffer_first and get_buffer_next in the loop should have the same | ||||
| access flags. | ||||
| 
 | ||||
| If the buffer returned does not exist, the loop is finished.  Buffers | ||||
| should not be killed durring a buffer loop. | ||||
| ) | ||||
| DOC_SEE(Access_Flag) | ||||
| DOC_SEE(get_buffer_first) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Working_Set *working_set = &cmd->models->working_set; | ||||
|      | ||||
|  | @ -428,13 +509,17 @@ GET_BUFFER_NEXT_SIG(external_get_buffer_next){ | |||
|     } | ||||
| } | ||||
| 
 | ||||
| GET_BUFFER_SIG(external_get_buffer){ | ||||
| GET_BUFFER_SIG(external_get_buffer)/*
 | ||||
| DOC_PARAM(buffer_id, the id of the buffer to get) | ||||
| DOC_PARAM(access, the access flags for the access) | ||||
| DOC_RETURN(returns a summary that describes the indicated buffer if it exists and is accessible) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Working_Set *working_set = &cmd->models->working_set; | ||||
|     Buffer_Summary buffer = {}; | ||||
|     Editing_File *file; | ||||
|      | ||||
|     file = working_set_get_active_file(working_set, index); | ||||
|     file = working_set_get_active_file(working_set, buffer_id); | ||||
|     if (file){ | ||||
|         fill_buffer_summary(&buffer, file, working_set); | ||||
|         if (!access_test(buffer.lock_flags, access)){ | ||||
|  | @ -445,25 +530,18 @@ GET_BUFFER_SIG(external_get_buffer){ | |||
|     return(buffer); | ||||
| } | ||||
| 
 | ||||
| GET_PARAMETER_BUFFER_SIG(external_get_parameter_buffer){ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Models *models = cmd->models; | ||||
|     Buffer_Summary buffer = {}; | ||||
|      | ||||
|     if (param_index >= 0 && param_index < models->buffer_param_count){ | ||||
|         buffer = external_get_buffer(app, models->buffer_param_indices[param_index], access); | ||||
|     } | ||||
|      | ||||
|     return(buffer); | ||||
| } | ||||
| 
 | ||||
| GET_BUFFER_BY_NAME_SIG(external_get_buffer_by_name){ | ||||
| GET_BUFFER_BY_NAME_SIG(external_get_buffer_by_name)/*
 | ||||
| DOC_PARAM(name, the name of the buffer) | ||||
| DOC_PARAM(len, the length of the name string) | ||||
| DOC_PARAM(access, the access flags for the access) | ||||
| DOC_RETURN(returns a summary that describes the indicated buffer if it exists and is accessible) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Buffer_Summary buffer = {}; | ||||
|     Editing_File *file; | ||||
|     Working_Set *working_set = &cmd->models->working_set; | ||||
|      | ||||
|     file = working_set_contains(cmd->system, working_set, make_string(filename, len)); | ||||
|     file = working_set_contains(cmd->system, working_set, make_string(name, len)); | ||||
|     if (file && !file->is_dummy){ | ||||
|         fill_buffer_summary(&buffer, file, working_set); | ||||
|         if (!access_test(buffer.lock_flags, access)){ | ||||
|  | @ -474,14 +552,14 @@ GET_BUFFER_BY_NAME_SIG(external_get_buffer_by_name){ | |||
|     return(buffer); | ||||
| } | ||||
| 
 | ||||
| REFRESH_BUFFER_SIG(external_refresh_buffer){ | ||||
|     int result; | ||||
|     *buffer = external_get_buffer(app, buffer->buffer_id, AccessAll); | ||||
|     result = buffer->exists; | ||||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| BUFFER_SEEK_SIG(external_buffer_seek){ | ||||
| BUFFER_SEEK_SIG(external_buffer_seek)/*
 | ||||
| DOC_PARAM(buffer, the buffer to seek through) | ||||
| DOC_PARAM(start_pos, the absolute position in the buffer to begin the seek) | ||||
| DOC_PARAM(seek_forward, non-zero indicates to seek forward otherwise the seek goes backward) | ||||
| DOC_PARAM(flags, one or more types of boundaries to use for stopping the seek) | ||||
| DOC_RETURN(returns the position where the seek stops) | ||||
| DOC_SEE(Seek_Boundary_Flag) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Editing_File *file; | ||||
|     int result = false; | ||||
|  | @ -573,7 +651,18 @@ BUFFER_SEEK_SIG(external_buffer_seek){ | |||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| BUFFER_READ_RANGE_SIG(external_buffer_read_range){ | ||||
| BUFFER_READ_RANGE_SIG(external_buffer_read_range)/*
 | ||||
| DOC_PARAM(buffer, the buffer to read out of) | ||||
| DOC_PARAM(start, the beginning of the read range) | ||||
| DOC_PARAM(end, one past the end of the read range) | ||||
| DOC_PARAM(out, the output buffer to fill with the result of the read) | ||||
| DOC_RETURN(returns non-zero on success) | ||||
| DOC | ||||
| ( | ||||
| The output buffer might have a capacity of at least (end - start) | ||||
| The output is not null terminated. | ||||
| ) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Editing_File *file = imp_get_file(cmd, buffer); | ||||
|     int result = false; | ||||
|  | @ -591,7 +680,21 @@ BUFFER_READ_RANGE_SIG(external_buffer_read_range){ | |||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| BUFFER_REPLACE_RANGE_SIG(external_buffer_replace_range){ | ||||
| BUFFER_REPLACE_RANGE_SIG(external_buffer_replace_range)/*
 | ||||
| DOC_PARAM(buffer, the buffer to edit) | ||||
| DOC_PARAM(start, the start of the range to edit) | ||||
| DOC_PARAM(end, the end of the range to edit) | ||||
| DOC_PARAM(str, the string to write into the range) | ||||
| DOC_PARAM(len, the length of the str string) | ||||
| DOC_RETURN(returns non-zero if the replacement succeeds) | ||||
| DOC | ||||
| ( | ||||
| Replace simultaneously deletes the range from start to end and writes str | ||||
| in the same position.  If end == start then this call is equivalent to | ||||
| inserting the string at start.  If len == 0 this call is equivalent to | ||||
| deleteing the range from start to end. | ||||
| ) | ||||
| */{ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Editing_File *file = imp_get_file(cmd, buffer); | ||||
|      | ||||
|  | @ -602,7 +705,7 @@ BUFFER_REPLACE_RANGE_SIG(external_buffer_replace_range){ | |||
|     if (file){ | ||||
|         size = buffer_size(&file->state.buffer); | ||||
|         if (0 <= start && start <= end && end <= size){ | ||||
|             result = 1; | ||||
|             result = true; | ||||
|              | ||||
|             pos = file->state.cursor_pos; | ||||
|             if (pos < start) next_cursor = pos; | ||||
|  | @ -688,21 +791,18 @@ SAVE_BUFFER_SIG(external_save_buffer){ | |||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     System_Functions *system = cmd->system; | ||||
|     Models *models = cmd->models; | ||||
|      | ||||
|     Editing_File *file = imp_get_file(cmd, buffer); | ||||
|      | ||||
|     int result = false; | ||||
|      | ||||
|     Editing_File *file = imp_get_file(cmd, buffer); | ||||
|     if (file){ | ||||
|         result = true; | ||||
|         String name = make_string(filename, filename_len); | ||||
|         view_save_file(system, models, file, 0, name, 0); | ||||
|         view_save_file(system, models, file, 0, name, false); | ||||
|     } | ||||
|      | ||||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| // TODO(allen): REPLACE THIS WITH CREATE_BUFFER!!!
 | ||||
| CREATE_BUFFER_SIG(external_create_buffer){ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     System_Functions *system = cmd->system; | ||||
|  | @ -715,10 +815,10 @@ CREATE_BUFFER_SIG(external_create_buffer){ | |||
|      | ||||
|     Temp_Memory temp = begin_temp_memory(part); | ||||
|     if (filename != 0){ | ||||
|         String filename_string = make_string(filename, filename_len); | ||||
|         String filename_string = make_string_terminated(part, filename, filename_len); | ||||
|         Editing_File *file = working_set_contains(system, working_set, filename_string); | ||||
|         if (file == 0){ | ||||
|             File_Loading loading = system->file_load_begin(filename); | ||||
|             File_Loading loading = system->file_load_begin(filename_string.str); | ||||
|             if (loading.exists){ | ||||
|                 b32 in_general_mem = false; | ||||
|                 char *buffer = push_array(part, char, loading.size); | ||||
|  | @ -874,13 +974,6 @@ GET_ACTIVE_VIEW_SIG(external_get_active_view){ | |||
|     return(view); | ||||
| } | ||||
| 
 | ||||
| REFRESH_VIEW_SIG(external_refresh_view){ | ||||
|     int result; | ||||
|     *view = external_get_view(app, view->view_id, AccessAll); | ||||
|     result = view->exists; | ||||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| VIEW_AUTO_TAB_SIG(external_view_auto_tab){ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     System_Functions *system = cmd->system; | ||||
|  | @ -1133,29 +1226,15 @@ PRINT_MESSAGE_SIG(external_print_message){ | |||
|     do_feedback_message(cmd->system, models, make_string(string, len)); | ||||
| } | ||||
| 
 | ||||
| #if 0 | ||||
| GET_GUI_FUNCTIONS_SIG(external_get_gui_functions){ | ||||
|     GUI_Functions *guifn = 0; | ||||
|     NotImplemented; | ||||
|     return(guifn); | ||||
| } | ||||
| 
 | ||||
| GET_GUI_SIG(external_get_gui){ | ||||
|     GUI *gui = 0; | ||||
|     NotImplemented; | ||||
|     return(gui); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| CHANGE_THEME_SIG(external_change_theme){ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Style_Library *styles = &cmd->models->styles; | ||||
|     String theme_name = make_string(name, len); | ||||
|     Style *s; | ||||
|     i32 i, count; | ||||
|      | ||||
|     count = styles->count; | ||||
|     s = styles->styles; | ||||
|     i32 i = 0; | ||||
|     i32 count = styles->count; | ||||
|     Style *s = styles->styles; | ||||
|      | ||||
|     for (i = 0; i < count; ++i, ++s){ | ||||
|         if (match(s->name, theme_name)){ | ||||
|             style_copy(main_style(cmd->models), s); | ||||
|  | @ -1169,7 +1248,7 @@ CHANGE_FONT_SIG(external_change_font){ | |||
|     Font_Set *set = cmd->models->font_set; | ||||
|     Style_Font *global_font = &cmd->models->global_font; | ||||
|     String font_name = make_string(name, len); | ||||
|     i16 font_id; | ||||
|     i16 font_id = 0; | ||||
|      | ||||
|     if (font_set_extract(set, font_name, &font_id)){ | ||||
|         global_font->font_id = font_id; | ||||
|  | @ -1180,11 +1259,11 @@ CHANGE_FONT_SIG(external_change_font){ | |||
| SET_THEME_COLORS_SIG(external_set_theme_colors){ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Style *style = main_style(cmd->models); | ||||
|     Theme_Color *theme_color; | ||||
|     u32 *color; | ||||
|     i32 i; | ||||
|      | ||||
|     theme_color = colors; | ||||
|     u32 *color = 0; | ||||
|     i32 i = 0; | ||||
|     Theme_Color *theme_color = colors; | ||||
|      | ||||
|     for (i = 0; i < count; ++i, ++theme_color){ | ||||
|         color = style_index_by_tag(&style->main, theme_color->tag); | ||||
|         if (color) *color = theme_color->color | 0xFF000000; | ||||
|  | @ -1194,11 +1273,11 @@ SET_THEME_COLORS_SIG(external_set_theme_colors){ | |||
| GET_THEME_COLORS_SIG(external_get_theme_colors){ | ||||
|     Command_Data *cmd = (Command_Data*)app->cmd_context; | ||||
|     Style *style = main_style(cmd->models); | ||||
|     Theme_Color *theme_color; | ||||
|     u32 *color; | ||||
|     i32 i; | ||||
|      | ||||
|     theme_color = colors; | ||||
|     u32 *color = 0; | ||||
|     i32 i = 0; | ||||
|     Theme_Color *theme_color = colors; | ||||
|      | ||||
|     for (i = 0; i < count; ++i, ++theme_color){ | ||||
|         color = style_index_by_tag(&style->main, theme_color->tag); | ||||
|         if (color){ | ||||
|  |  | |||
|  | @ -58,9 +58,6 @@ struct Models{ | |||
|     Hook_Function *hooks[hook_type_count]; | ||||
|     Application_Links app_links; | ||||
|      | ||||
|     i32 *buffer_param_indices; | ||||
|     i32 buffer_param_count, buffer_param_max; | ||||
|      | ||||
|     Font_Set *font_set; | ||||
|     Style_Font global_font; | ||||
|     Style_Library styles; | ||||
|  | @ -78,6 +75,9 @@ struct Models{ | |||
|     Panel *prev_mouse_panel; | ||||
|      | ||||
|     Custom_API config_api; | ||||
|      | ||||
|     Open_File_Hook_Function *hook_open_file; | ||||
|     Open_File_Hook_Function *hook_new_file; | ||||
|     Scroll_Rule_Function *scroll_rule; | ||||
|      | ||||
|     b32 keep_playing; | ||||
|  |  | |||
							
								
								
									
										46
									
								
								4ed_file.cpp
								
								
								
								
							
							
						
						
									
										46
									
								
								4ed_file.cpp
								
								
								
								
							|  | @ -414,8 +414,8 @@ working_set__entry_comp(System_Functions *system, String filename, File_Entry_Co | |||
| 
 | ||||
| inline Editing_File* | ||||
| working_set_contains(System_Functions *system, Working_Set *working_set, String filename){ | ||||
|     File_Entry_Comparison entry_comp; | ||||
|     File_Entry *entry; | ||||
|     File_Entry_Comparison entry_comp = {0}; | ||||
|     File_Entry *entry = 0; | ||||
|     Editing_File *result = 0; | ||||
|     working_set__entry_comp(system, filename, &entry_comp); | ||||
|     entry = (File_Entry*)table_find_item(&working_set->table, &entry_comp, system, tbl_string_hash, tbl_file_compare); | ||||
|  | @ -582,48 +582,6 @@ filename_match(String query, Absolutes *absolutes, String filename, b32 case_sen | |||
|     return result; | ||||
| } | ||||
| 
 | ||||
| #if 0 | ||||
| internal Hot_Directory_Match | ||||
| hot_directory_first_match(Hot_Directory *hot_directory, | ||||
|                           String str, | ||||
| 						  b32 include_files, | ||||
|                           b32 exact_match, | ||||
|                           b32 case_sensitive){ | ||||
|     Hot_Directory_Match result = {}; | ||||
|      | ||||
|     Absolutes absolutes; | ||||
|     if (!exact_match) | ||||
|         get_absolutes(str, &absolutes, 1, 1); | ||||
|      | ||||
|     File_List *files = &hot_directory->file_list; | ||||
|     File_Info *info, *end; | ||||
|     end = files->infos + files->count; | ||||
|     for (info = files->infos; info != end; ++info){ | ||||
|         String filename = info->filename; | ||||
|         b32 is_match = 0; | ||||
|         if (exact_match){ | ||||
|             if (case_sensitive){ | ||||
|                 if (match(filename, str)) is_match = 1; | ||||
|             } | ||||
|             else{ | ||||
|                 if (match_insensitive(filename, str)) is_match = 1; | ||||
|             } | ||||
|         } | ||||
|         else{ | ||||
|             if (filename_match(str, &absolutes, filename, case_sensitive)) is_match = 1; | ||||
|         } | ||||
|          | ||||
|         if (is_match){ | ||||
|             result.is_folder = info->folder; | ||||
|             result.filename = filename; | ||||
|             break; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     return result; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| inline File_Sync_State | ||||
| buffer_get_sync(Editing_File *file){ | ||||
|     File_Sync_State result = SYNC_GOOD; | ||||
|  |  | |||
|  | @ -333,6 +333,8 @@ view_lock_level(View *view){ | |||
|     return(result); | ||||
| } | ||||
| 
 | ||||
| // TODO(allen): Switch over to using an i32 instead of
 | ||||
| // an f32 for these.
 | ||||
| inline f32 | ||||
| view_file_width(View *view){ | ||||
|     i32_Rect file_rect = view->file_region; | ||||
|  | @ -475,9 +477,9 @@ internal b32 | |||
| file_save(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename){ | ||||
|     b32 result = 0; | ||||
|      | ||||
|     i32 max, size; | ||||
|     i32 max = 0, size = 0; | ||||
|     b32 dos_write_mode = file->settings.dos_write_mode; | ||||
|     char *data; | ||||
|     char *data = 0; | ||||
|     Buffer_Type *buffer = &file->state.buffer; | ||||
|      | ||||
|     if (dos_write_mode){ | ||||
|  | @ -668,19 +670,19 @@ view_compute_lowest_line(View *view){ | |||
|     return lowest_line; | ||||
| } | ||||
| 
 | ||||
| inline f32 | ||||
| inline i32 | ||||
| view_compute_max_target_y(i32 lowest_line, i32 line_height, f32 view_height){ | ||||
|     f32 max_target_y = ((lowest_line+.5f)*line_height) - view_height*.5f; | ||||
|     max_target_y = clamp_bottom(0.f, max_target_y); | ||||
|     return(max_target_y); | ||||
|     return(CEIL32(max_target_y)); | ||||
| } | ||||
| 
 | ||||
| inline f32 | ||||
| inline i32 | ||||
| view_compute_max_target_y(View *view){ | ||||
|     i32 lowest_line = view_compute_lowest_line(view); | ||||
|     i32 line_height = view->line_height; | ||||
|     f32 view_height = view_file_height(view); | ||||
|     f32 max_target_y = view_compute_max_target_y(lowest_line, line_height, view_height); | ||||
|     i32 max_target_y = view_compute_max_target_y(lowest_line, line_height, view_height); | ||||
|     return(max_target_y); | ||||
| } | ||||
| 
 | ||||
|  | @ -785,11 +787,10 @@ file_create_from_string(System_Functions *system, Models *models, | |||
|         file->state.undo.current_block_normal = 1; | ||||
|     } | ||||
|      | ||||
|     Hook_Function *open_hook = models->hooks[hook_open_file]; | ||||
|     models->buffer_param_indices[0] = file->id.id; | ||||
|     models->buffer_param_count = 1; | ||||
|     open_hook(&models->app_links); | ||||
|     models->buffer_param_count = 0; | ||||
|     Open_File_Hook_Function *open_hook = models->hook_open_file; | ||||
|     if (open_hook){ | ||||
|         open_hook(&models->app_links, file->id.id); | ||||
|     } | ||||
|     file->settings.is_initialized = 1; | ||||
| } | ||||
| 
 | ||||
|  | @ -1614,25 +1615,25 @@ view_move_view_to_cursor(View *view, GUI_Scroll_Vars *scroll){ | |||
|     f32 cursor_x = view_get_cursor_x(view); | ||||
|      | ||||
|     GUI_Scroll_Vars scroll_vars = *scroll; | ||||
|     f32 target_y = scroll_vars.target_y; | ||||
|     f32 target_x = scroll_vars.target_x; | ||||
|     i32 target_y = scroll_vars.target_y; | ||||
|     i32 target_x = scroll_vars.target_x; | ||||
|     | ||||
|     Cursor_Limits limits = view_cursor_limits(view); | ||||
|      | ||||
|     if (cursor_y > target_y + limits.max){ | ||||
|         target_y = cursor_y - limits.max + limits.delta; | ||||
|         target_y = CEIL32(cursor_y - limits.max + limits.delta); | ||||
|     } | ||||
|     if (cursor_y < target_y + limits.min){ | ||||
|         target_y = cursor_y - limits.delta - limits.min; | ||||
|         target_y = FLOOR32(cursor_y - limits.delta - limits.min); | ||||
|     } | ||||
|      | ||||
|     target_y = clamp(0.f, target_y, scroll_vars.max_y); | ||||
|     target_y = clamp(0, target_y, scroll_vars.max_y); | ||||
|      | ||||
|     if (cursor_x < target_x){ | ||||
|         target_x = (f32)Max(0, cursor_x - max_x/2); | ||||
|     if (cursor_x >= target_x + max_x){ | ||||
|         target_x = CEIL32(cursor_x - max_x/2); | ||||
|     } | ||||
|     else if (cursor_x >= target_x + max_x){ | ||||
|         target_x = (f32)(cursor_x - max_x/2); | ||||
|     else if (cursor_x < target_x){ | ||||
|         target_x = FLOOR32(Max(0, cursor_x - max_x/2)); | ||||
|     } | ||||
|      | ||||
|     if (target_x != scroll_vars.target_x || target_y != scroll_vars.target_y){ | ||||
|  | @ -1724,8 +1725,7 @@ struct Relative_Scrolling{ | |||
| internal Relative_Scrolling | ||||
| view_get_relative_scrolling(View *view){ | ||||
|     Relative_Scrolling result; | ||||
|     f32 cursor_y; | ||||
|     cursor_y = view_get_cursor_y(view); | ||||
|     f32 cursor_y = view_get_cursor_y(view); | ||||
|     result.scroll_y = cursor_y - view->recent->scroll.scroll_y; | ||||
|     result.target_y = cursor_y - view->recent->scroll.target_y; | ||||
|     return(result); | ||||
|  | @ -1733,11 +1733,10 @@ view_get_relative_scrolling(View *view){ | |||
| 
 | ||||
| internal void | ||||
| view_set_relative_scrolling(View *view, Relative_Scrolling scrolling){ | ||||
|     f32 cursor_y; | ||||
|     cursor_y = view_get_cursor_y(view); | ||||
|     f32 cursor_y = view_get_cursor_y(view); | ||||
|     view->recent->scroll.scroll_y = cursor_y - scrolling.scroll_y; | ||||
|     view->recent->scroll.target_y = | ||||
|         clamp_bottom(0.f, cursor_y - scrolling.target_y); | ||||
|         ROUND32(clamp_bottom(0.f, cursor_y - scrolling.target_y)); | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
|  | @ -2031,12 +2030,12 @@ file_edit_cursor_fix(System_Functions *system, | |||
|                      | ||||
|                     if (view->file_data.unwrapped_lines){ | ||||
|                         y_position = temp_cursor.unwrapped_y + y_offset; | ||||
|                         view->recent->scroll.target_y += (y_position - view->recent->scroll.scroll_y); | ||||
|                         view->recent->scroll.target_y += ROUND32(y_position - view->recent->scroll.scroll_y); | ||||
|                         view->recent->scroll.scroll_y = y_position; | ||||
|                     } | ||||
|                     else{ | ||||
|                         y_position = temp_cursor.wrapped_y + y_offset; | ||||
|                         view->recent->scroll.target_y += (y_position - view->recent->scroll.scroll_y); | ||||
|                         view->recent->scroll.target_y += ROUND32(y_position - view->recent->scroll.scroll_y); | ||||
|                         view->recent->scroll.scroll_y = y_position; | ||||
|                     } | ||||
|                 } | ||||
|  | @ -3146,22 +3145,29 @@ view_save_file(System_Functions *system, Models *models, | |||
|     Mem_Options *mem = &models->mem; | ||||
|     Working_Set *working_set = &models->working_set; | ||||
|      | ||||
|     Temp_Memory temp = begin_temp_memory(&mem->part); | ||||
|      | ||||
|     String filename_string = | ||||
|         make_string_terminated(&mem->part, filename.str, filename.size); | ||||
|      | ||||
|     if (!file){ | ||||
|         if (view){ | ||||
|             file = view->file_data.file; | ||||
|         } | ||||
|         else{ | ||||
|             file = working_set_lookup_file(working_set, filename); | ||||
|             file = working_set_lookup_file(working_set, filename_string); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     if (file && buffer_get_sync(file) != SYNC_GOOD){ | ||||
|         if (file_save(system, mem, file, filename.str)){ | ||||
|         if (file_save(system, mem, file, filename_string.str)){ | ||||
|             if (save_as){ | ||||
|                 file_set_name(working_set, file, filename.str); | ||||
|                 file_set_name(working_set, file, filename_string.str); | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     end_temp_memory(temp); | ||||
| } | ||||
| 
 | ||||
| internal void | ||||
|  | @ -3178,13 +3184,11 @@ view_new_file(System_Functions *system, Models *models, | |||
|     view_show_file(view); | ||||
|     view->map = get_map(models, file->settings.base_map_id); | ||||
|      | ||||
|     Hook_Function *new_file_fnc = models->hooks[hook_new_file]; | ||||
|     Open_File_Hook_Function *new_file_fnc = models->hook_new_file; | ||||
|     if (new_file_fnc){ | ||||
|         models->buffer_param_indices[models->buffer_param_count++] = file->id.id; | ||||
|         new_file_fnc(&models->app_links); | ||||
|         models->buffer_param_count = 0; | ||||
|         file->settings.is_initialized = 1; | ||||
|         new_file_fnc(&models->app_links, file->id.id); | ||||
|     } | ||||
|     file->settings.is_initialized = 1; | ||||
|      | ||||
| #if BUFFER_EXPERIMENT_SCALPEL <= 0 | ||||
|     if (file->settings.tokens_exist){ | ||||
|  | @ -3518,15 +3522,12 @@ intbar_draw_string(Render_Target *target, File_Bar *bar, String str, u32 char_co | |||
| internal void | ||||
| view_reinit_scrolling(View *view){ | ||||
|     Editing_File *file = view->file_data.file; | ||||
|     f32 w, h; | ||||
|     f32 cursor_x, cursor_y; | ||||
|     f32 target_x, target_y; | ||||
|     f32 w = 0, h = 0; | ||||
|     f32 cursor_x = 0, cursor_y = 0; | ||||
|     i32 target_x = 0, target_y = 0; | ||||
|      | ||||
|     view->reinit_scrolling = 0; | ||||
|      | ||||
|     target_x = 0; | ||||
|     target_y = 0; | ||||
|      | ||||
|     if (file && file_is_ready(file)){ | ||||
|         cursor_x = view_get_cursor_x(view); | ||||
|         cursor_y = view_get_cursor_y(view); | ||||
|  | @ -3535,19 +3536,19 @@ view_reinit_scrolling(View *view){ | |||
|         h = view_file_height(view); | ||||
|          | ||||
|         if (cursor_x >= target_x + w){ | ||||
|             target_x = (f32)(cursor_x - w*.5f); | ||||
|             target_x = ROUND32(cursor_x - w*.5f); | ||||
|         } | ||||
|          | ||||
|         target_y = clamp_bottom(0.f, (f32)FLOOR32(cursor_y - h*.5f)); | ||||
|         target_y = clamp_bottom(0, FLOOR32(cursor_y - h*.5f)); | ||||
|     } | ||||
|      | ||||
|     view->recent->scroll.target_y = target_y; | ||||
|     view->recent->scroll.scroll_y = target_y; | ||||
|     view->recent->scroll.prev_target_y = -1000.f; | ||||
|     view->recent->scroll.scroll_y = (f32)target_y; | ||||
|     view->recent->scroll.prev_target_y = -1000; | ||||
|      | ||||
|     view->recent->scroll.target_x = target_x; | ||||
|     view->recent->scroll.scroll_x = target_x; | ||||
|     view->recent->scroll.prev_target_x = -1000.f; | ||||
|     view->recent->scroll.scroll_x = (f32)target_x; | ||||
|     view->recent->scroll.prev_target_x = -1000; | ||||
| } | ||||
| 
 | ||||
| enum CursorScroll_State{ | ||||
|  | @ -3623,8 +3624,8 @@ view_end_cursor_scroll_updates(View *view){ | |||
|     } | ||||
|      | ||||
|     if (cursor_scroll_state & CursorScroll_ContextChange){ | ||||
|         view->current_scroll->scroll_y = view->current_scroll->target_y; | ||||
|         view->current_scroll->scroll_x = view->current_scroll->target_x; | ||||
|         view->current_scroll->scroll_y = (f32)view->current_scroll->target_y; | ||||
|         view->current_scroll->scroll_x = (f32)view->current_scroll->target_x; | ||||
|         gui_post_scroll_vars(&view->gui_target, view->current_scroll, view->scroll_region); | ||||
|     } | ||||
|      | ||||
|  | @ -3989,12 +3990,12 @@ show_gui_scroll(GUI_Target *target, String *string, | |||
|                 GUI_Scroll_Vars scroll){ | ||||
|     show_gui_line (target, string, indent_level, 0, message, 0); | ||||
|     show_gui_float(target, string, indent_level+1, h_align, " scroll_y ", scroll.scroll_y); | ||||
|     show_gui_float(target, string, indent_level+1, h_align, " target_y ", scroll.target_y); | ||||
|     show_gui_float(target, string, indent_level+1, h_align, " prev_target_y ", scroll.prev_target_y); | ||||
|     show_gui_float(target, string, indent_level+1, h_align, " max_y ", scroll.max_y); | ||||
|     show_gui_int  (target, string, indent_level+1, h_align, " target_y ", scroll.target_y); | ||||
|     show_gui_int  (target, string, indent_level+1, h_align, " prev_target_y ", scroll.prev_target_y); | ||||
|     show_gui_int  (target, string, indent_level+1, h_align, " max_y ", scroll.max_y); | ||||
|     show_gui_float(target, string, indent_level+1, h_align, " scroll_x ", scroll.scroll_x); | ||||
|     show_gui_float(target, string, indent_level+1, h_align, " target_x ", scroll.target_x); | ||||
|     show_gui_float(target, string, indent_level+1, h_align, " prev_target_x ", scroll.prev_target_x); | ||||
|     show_gui_int  (target, string, indent_level+1, h_align, " target_x ", scroll.target_x); | ||||
|     show_gui_int  (target, string, indent_level+1, h_align, " prev_target_x ", scroll.prev_target_x); | ||||
| } | ||||
| 
 | ||||
| internal void | ||||
|  | @ -4081,7 +4082,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su | |||
|              | ||||
|             gui_begin_serial_section(target); | ||||
|             { | ||||
|                 f32 delta = 9.f * view->line_height; | ||||
|                 i32 delta = 9 * view->line_height; | ||||
|                 GUI_id scroll_context = {0}; | ||||
|                 scroll_context.id[1] = view->showing_ui; | ||||
|                 scroll_context.id[0] = (u64)(view->file_data.file); | ||||
|  | @ -4181,7 +4182,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su | |||
|                         view->current_scroll = &view->gui_scroll; | ||||
|                         gui_get_scroll_vars(target, scroll_context, &view->gui_scroll, &view->scroll_region); | ||||
|                         gui_begin_scrollable(target, scroll_context, view->gui_scroll, | ||||
|                                              9.f * view->line_height, show_scrollbar); | ||||
|                                              9 * view->line_height, show_scrollbar); | ||||
|                          | ||||
|                         { | ||||
|                             i32 count = models->styles.count; | ||||
|  | @ -4255,7 +4256,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su | |||
|                             view->current_scroll = &view->gui_scroll; | ||||
|                             gui_get_scroll_vars(target, scroll_context, &view->gui_scroll, &view->scroll_region); | ||||
|                             gui_begin_scrollable(target, scroll_context, view->gui_scroll, | ||||
|                                                  9.f * view->line_height, show_scrollbar); | ||||
|                                                  9 * view->line_height, show_scrollbar); | ||||
|                              | ||||
|                             i32 next_color_editing = view->current_color_editing; | ||||
|                              | ||||
|  | @ -4402,7 +4403,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su | |||
|                                 snap_into_view = 1; | ||||
|                             } | ||||
|                             gui_begin_scrollable(target, scroll_context, view->gui_scroll, | ||||
|                                                  9.f * view->line_height, show_scrollbar); | ||||
|                                                  9 * view->line_height, show_scrollbar); | ||||
|                              | ||||
|                             id.id[0] = (u64)(hdir) + 1; | ||||
|                              | ||||
|  | @ -4491,7 +4492,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su | |||
|                                 snap_into_view = 1; | ||||
|                             } | ||||
|                             gui_begin_scrollable(target, scroll_context, view->gui_scroll, | ||||
|                                                  9.f * view->line_height, show_scrollbar); | ||||
|                                                  9 * view->line_height, show_scrollbar); | ||||
|                              | ||||
|                             id.id[0] = (u64)(working_set) + 1; | ||||
|                             if (gui_begin_list(target, id, view->list_i, | ||||
|  | @ -4699,7 +4700,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su | |||
|                     } | ||||
|                      | ||||
|                     gui_begin_scrollable(target, scroll_context, view->gui_scroll, | ||||
|                                          9.f * view->line_height, show_scrollbar); | ||||
|                                          9 * view->line_height, show_scrollbar); | ||||
|                      | ||||
|                     switch (view->debug_vars.mode) | ||||
|                     { | ||||
|  | @ -5096,7 +5097,7 @@ do_step_file_view(System_Functions *system, | |||
|     GUI_Target *target = &view->gui_target; | ||||
|     GUI_Interpret_Result interpret_result = {0}; | ||||
|      | ||||
|     vars.target_y = clamp(0.f, vars.target_y, vars.max_y); | ||||
|     vars.target_y = clamp(0, vars.target_y, vars.max_y); | ||||
|      | ||||
|     result.vars = vars; | ||||
|     result.region = region; | ||||
|  | @ -5143,7 +5144,7 @@ do_step_file_view(System_Functions *system, | |||
|                      | ||||
|                     case guicom_file: | ||||
|                     { | ||||
|                         f32 new_max_y = view_compute_max_target_y(view); | ||||
|                         i32 new_max_y = view_compute_max_target_y(view); | ||||
|                          | ||||
|                         view->file_region = gui_session.rect; | ||||
|                         result.vars.max_y = new_max_y; | ||||
|  | @ -5233,7 +5234,7 @@ do_step_file_view(System_Functions *system, | |||
|                             v = unlerp(gui_session.scroll_top, (f32)my, | ||||
|                                        gui_session.scroll_bottom); | ||||
|                             v = clamp(0.f, v, 1.f); | ||||
|                             result.vars.target_y = lerp(0.f, v, result.vars.max_y); | ||||
|                             result.vars.target_y = ROUND32(lerp(0.f, v, (f32)result.vars.max_y)); | ||||
|                              | ||||
|                             gui_activate_scrolling(target); | ||||
|                             result.is_animating = true; | ||||
|  | @ -5247,7 +5248,7 @@ do_step_file_view(System_Functions *system, | |||
|                             result.vars.target_y += user_input->mouse.wheel*target->delta; | ||||
|                              | ||||
|                             result.vars.target_y = | ||||
|                                 clamp(0.f, result.vars.target_y, result.vars.max_y); | ||||
|                                 clamp(0, result.vars.target_y, result.vars.max_y); | ||||
|                             gui_activate_scrolling(target); | ||||
|                             result.is_animating = true; | ||||
|                         } | ||||
|  | @ -5258,8 +5259,8 @@ do_step_file_view(System_Functions *system, | |||
|                         GUI_id id = gui_id_scrollbar_top(); | ||||
|                          | ||||
|                         if (scroll_button_input(target, &gui_session, user_input, id, &result.is_animating)){ | ||||
|                             result.vars.target_y -= target->delta * 0.25f; | ||||
|                             result.vars.target_y = clamp_bottom(0.f, result.vars.target_y); | ||||
|                             result.vars.target_y -= clamp_bottom(1, target->delta >> 2); | ||||
|                             result.vars.target_y = clamp_bottom(0, result.vars.target_y); | ||||
|                             result.consumed_l = true; | ||||
|                         } | ||||
|                     }break; | ||||
|  | @ -5269,7 +5270,7 @@ do_step_file_view(System_Functions *system, | |||
|                         GUI_id id = gui_id_scrollbar_bottom(); | ||||
|                          | ||||
|                         if (scroll_button_input(target, &gui_session, user_input, id, &result.is_animating)){ | ||||
|                             result.vars.target_y += target->delta * 0.25f; | ||||
|                             result.vars.target_y += clamp_bottom(1, target->delta >> 2); | ||||
|                             result.vars.target_y = clamp_top(result.vars.target_y, result.vars.max_y); | ||||
|                             result.consumed_l = true; | ||||
|                         } | ||||
|  | @ -5278,8 +5279,7 @@ do_step_file_view(System_Functions *system, | |||
|                     case guicom_end_scrollable_section: | ||||
|                     { | ||||
|                         if (!is_file_scroll){ | ||||
|                             f32 new_max_y = gui_session.suggested_max_y; | ||||
|                             result.vars.max_y = new_max_y; | ||||
|                             result.vars.max_y = gui_session.suggested_max_y; | ||||
|                         } | ||||
|                     }break; | ||||
|                 } | ||||
|  | @ -5299,7 +5299,10 @@ do_step_file_view(System_Functions *system, | |||
|             if (scroll_vars.target_x != scroll_vars.prev_target_x) is_new_target = true; | ||||
|             if (scroll_vars.target_y != scroll_vars.prev_target_y) is_new_target = true; | ||||
|              | ||||
|             if (view->persistent.models->scroll_rule(scroll_vars.target_x, scroll_vars.target_y, | ||||
|             f32 target_x = (f32)scroll_vars.target_x; | ||||
|             f32 target_y = (f32)scroll_vars.target_y; | ||||
|              | ||||
|             if (view->persistent.models->scroll_rule(target_x, target_y, | ||||
|                                                      &scroll_vars.scroll_x, &scroll_vars.scroll_y, | ||||
|                                                      (view->persistent.id) + 1, is_new_target, user_input->dt)){ | ||||
|                 result.is_animating = true; | ||||
|  |  | |||
							
								
								
									
										37
									
								
								4ed_gui.cpp
								
								
								
								
							
							
						
						
									
										37
									
								
								4ed_gui.cpp
								
								
								
								
							|  | @ -137,7 +137,7 @@ struct GUI_Target{ | |||
|     i32 list_view_max; | ||||
|      | ||||
|     GUI_id scroll_id;  | ||||
|     f32 delta; | ||||
|     i32 delta; | ||||
|     b32 has_keys; | ||||
|     b32 animating; | ||||
|     b32 did_file; | ||||
|  | @ -662,7 +662,7 @@ gui_get_scroll_vars(GUI_Target *target, GUI_id scroll_context_id, GUI_Scroll_Var | |||
|         *vars_out = target->scroll_updated; | ||||
|         *region_out = target->region_updated; | ||||
|          | ||||
|         vars_out->target_y = clamp(0.f, vars_out->target_y, vars_out->max_y); | ||||
|         vars_out->target_y = clamp(0, vars_out->target_y, vars_out->max_y); | ||||
|          | ||||
|         if (gui_id_eq(target->active, gui_id_scrollbar())){ | ||||
|             result = 1; | ||||
|  | @ -685,7 +685,7 @@ gui_post_scroll_vars(GUI_Target *target, GUI_Scroll_Vars *vars_in, i32_Rect regi | |||
| 
 | ||||
| internal void | ||||
| gui_begin_scrollable(GUI_Target *target, GUI_id scroll_context_id, | ||||
|                      GUI_Scroll_Vars scroll_vars, f32 delta, b32 show_bar){ | ||||
|                      GUI_Scroll_Vars scroll_vars, i32 delta, b32 show_bar){ | ||||
|     GUI_Header *h; | ||||
|      | ||||
|     gui_begin_serial_section(target); | ||||
|  | @ -735,7 +735,7 @@ struct GUI_Session{ | |||
|     i32_Rect full_rect; | ||||
|     i32_Rect rect; | ||||
|      | ||||
|     f32 suggested_max_y; | ||||
|     i32 suggested_max_y; | ||||
|     i32 clip_y; | ||||
|      | ||||
|     i32 line_height; | ||||
|  | @ -833,17 +833,14 @@ gui_scrollbar_top(i32_Rect bar, i32_Rect *top){ | |||
| } | ||||
| 
 | ||||
| internal void | ||||
| gui_scrollbar_slider(i32_Rect bar, i32_Rect *slider, f32 s, f32 *min_out, f32 *max_out, f32 target_min, f32 target_max){ | ||||
|     i32 h, w = (bar.x1 - bar.x0); | ||||
|     i32 min, max, pos; | ||||
| gui_scrollbar_slider(i32_Rect bar, i32_Rect *slider, f32 s, f32 *min_out, f32 *max_out, i32 target_min, i32 target_max){ | ||||
|     i32 h = 0, w = (bar.x1 - bar.x0); | ||||
|     i32 min = 0, max = 0, pos = 0; | ||||
|      | ||||
|     f32 screen_size; | ||||
|     f32 full_size; | ||||
|     f32 ratio; | ||||
|     f32 screen_size = (f32)(bar.y1 - bar.y0); | ||||
|     f32 full_size = (f32)(target_max - target_min + screen_size); | ||||
|     f32 ratio = 1.f; | ||||
|      | ||||
|     screen_size = (f32)(bar.y1 - bar.y0); | ||||
|     full_size = (f32)(target_max - target_min + screen_size); | ||||
|     ratio = 1.f; | ||||
|     if (full_size > screen_size){ | ||||
|         ratio = screen_size/full_size; | ||||
|     } | ||||
|  | @ -1158,7 +1155,7 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, | |||
|         case guicom_end_scrollable_section: | ||||
|         always_give_to_user = 1; | ||||
|         session->suggested_max_y = | ||||
|             (f32)(session->scrollable_items_bottom - | ||||
|             CEIL32(session->scrollable_items_bottom - | ||||
|                   (session->full_rect.y0 + session->full_rect.y1)*.5f); | ||||
|         if (session->suggested_max_y < 0){ | ||||
|             session->suggested_max_y = 0; | ||||
|  | @ -1218,16 +1215,16 @@ gui_interpret(GUI_Target *target, GUI_Session *session, GUI_Header *h, | |||
| } | ||||
| 
 | ||||
| struct GUI_View_Jump{ | ||||
|     f32 view_min; | ||||
|     f32 view_max; | ||||
|     i32 view_min; | ||||
|     i32 view_max; | ||||
| }; | ||||
| 
 | ||||
| internal GUI_View_Jump | ||||
| gui_compute_view_jump(i32_Rect scroll_region, i32_Rect position){ | ||||
|     GUI_View_Jump jump = {0}; | ||||
|     i32 region_h = scroll_region.y1 - scroll_region.y0; | ||||
|     jump.view_min = (f32)position.y1 - scroll_region.y0 - region_h; | ||||
|     jump.view_max = (f32)position.y0 - scroll_region.y0; | ||||
|     jump.view_min = position.y1 - scroll_region.y0 - region_h; | ||||
|     jump.view_max = position.y0 - scroll_region.y0; | ||||
|     return(jump); | ||||
| } | ||||
| 
 | ||||
|  | @ -1253,8 +1250,8 @@ gui_standard_list(GUI_Target *target, GUI_id id, GUI_Scroll_Vars *vars, i32_Rect | |||
|     if (update->has_index_position){ | ||||
|         GUI_View_Jump jump = | ||||
|             gui_compute_view_jump(scroll_region, update->index_position); | ||||
|         jump.view_min = jump.view_min + 45.f; | ||||
|         jump.view_max = jump.view_max - 45.f; | ||||
|         jump.view_min = jump.view_min + 45; | ||||
|         jump.view_max = jump.view_max - 45; | ||||
|         *vars = gui_do_jump(target, jump, *vars); | ||||
|     } | ||||
|      | ||||
|  |  | |||
							
								
								
									
										19
									
								
								4ed_math.cpp
								
								
								
								
							
							
						
						
									
										19
									
								
								4ed_math.cpp
								
								
								
								
							|  | @ -483,6 +483,25 @@ clamp(f32 a, f32 n, f32 z){ | |||
|     return (n); | ||||
| } | ||||
| 
 | ||||
| inline i32 | ||||
| clamp_bottom(i32 a, i32 n){ | ||||
|     if (n < a) n = a; | ||||
|     return (n); | ||||
| } | ||||
| 
 | ||||
| inline i32 | ||||
| clamp_top(i32 n, i32 z){ | ||||
|     if (n  > z) n = z; | ||||
|     return (n); | ||||
| } | ||||
| 
 | ||||
| inline i32 | ||||
| clamp(i32 a, i32 n, i32 z){ | ||||
|     if (n < a) n = a; | ||||
|     else if (n  > z) n = z; | ||||
|     return (n); | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Color | ||||
|  */ | ||||
|  |  | |||
							
								
								
									
										10
									
								
								4ed_mem.cpp
								
								
								
								
							
							
						
						
									
										10
									
								
								4ed_mem.cpp
								
								
								
								
							|  | @ -191,5 +191,15 @@ general_memory_reallocate_nocopy(General_Memory *general, void *old, i32 size, u | |||
| #define gen_array(g, T, size) (T*)general_memory_allocate(g, sizeof(T)*(size), 0) | ||||
| #define gen_block(g, size) general_memory_open(g, size, 0) | ||||
| 
 | ||||
| internal String | ||||
| make_string_terminated(Partition *part, char *str, int len){ | ||||
|     char *space = (char*)push_array(part, char, len + 1); | ||||
|     String string = make_string(str, len, len+1); | ||||
|     copy_fast_unsafe(space, string); | ||||
|     string.str = space; | ||||
|     terminate_with_null(&string); | ||||
|     return(string); | ||||
| } | ||||
| 
 | ||||
| // BOTTOM
 | ||||
| 
 | ||||
|  |  | |||
|  | @ -157,4 +157,3 @@ LargeRoundUp(i32 x, i32 granularity){ | |||
| #define Tbytes(n) (((u64)n) << 40) | ||||
| 
 | ||||
| #endif | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| Distribution Date: 21.6.2016 (dd.mm.yyyy) | ||||
| Distribution Date: 23.6.2016 (dd.mm.yyyy) | ||||
| 
 | ||||
| Thank you for contributing to the 4coder project! | ||||
| 
 | ||||
|  |  | |||
|  | @ -1,4 +1,4 @@ | |||
| Distribution Date: 21.6.2016 (dd.mm.yyyy) | ||||
| Distribution Date: 23.6.2016 (dd.mm.yyyy) | ||||
| 
 | ||||
| Thank you for contributing to the 4coder project! | ||||
| 
 | ||||
|  |  | |||
|  | @ -23,7 +23,7 @@ popd | |||
| 
 | ||||
| pushd ..\build | ||||
| REM call "..\code\buildsuper.bat" ..\code\4coder_default_bindings.cpp | ||||
| call "..\code\buildsuper.bat" ..\code\power\4coder_experiments.cpp | ||||
|  call "..\code\buildsuper.bat" ..\code\power\4coder_experiments.cpp | ||||
| REM call "..\code\buildsuper.bat" ..\code\power\4coder_casey.cpp | ||||
| REM call "..\code\buildsuper.bat" ..\4vim\4coder_chronal.cpp | ||||
| if %ERRORLEVEL% neq 0 (set FirstError=1) | ||||
|  |  | |||
|  | @ -12,7 +12,9 @@ File_List Get_File_List(Application_Links *app, char *dir, int len); | |||
| void Free_File_List(Application_Links *app, File_List list); | ||||
| 
 | ||||
| // Clipboard
 | ||||
| int Clipboard_Post(Application_Links *app, char *str, int len); | ||||
| 
 | ||||
| // TODO(allen): extend this API out a little bit to allow for future expansion.
 | ||||
| void Clipboard_Post(Application_Links *app, char *str, int len); | ||||
| int  Clipboard_Count(Application_Links *app); | ||||
| int  Clipboard_Index(Application_Links *app, int index, char *out, int len); | ||||
| 
 | ||||
|  | @ -20,14 +22,11 @@ int Clipboard_Index(Application_Links *app, int index, char *out, int len); | |||
| Buffer_Summary Get_Buffer_First(Application_Links *app, unsigned int access); | ||||
| void Get_Buffer_Next(Application_Links *app, Buffer_Summary *buffer, unsigned int access); | ||||
| 
 | ||||
| Buffer_Summary Get_Buffer(Application_Links *app, int index, unsigned int access); | ||||
| Buffer_Summary Get_Parameter_Buffer(Application_Links *app, int param_index, unsigned int access); | ||||
| Buffer_Summary Get_Buffer_By_Name(Application_Links *app, char *filename, int len, unsigned int access); | ||||
| Buffer_Summary Get_Buffer(Application_Links *app, int buffer_id, unsigned int access); | ||||
| Buffer_Summary Get_Buffer_By_Name(Application_Links *app, char *name, int len, unsigned int access); | ||||
| 
 | ||||
| int Refresh_Buffer(Application_Links *app, Buffer_Summary *buffer); | ||||
| 
 | ||||
| int Buffer_Read_Range(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *out); | ||||
| int Buffer_Seek(Application_Links *app, Buffer_Summary *buffer, int start_pos, int seek_forward, unsigned int flags); | ||||
| int Buffer_Read_Range(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *out); | ||||
| 
 | ||||
| int Buffer_Replace_Range(Application_Links *app, Buffer_Summary *buffer, int start, int end, char *str, int len); | ||||
| int Buffer_Set_Setting(Application_Links *app, Buffer_Summary *buffer, int setting, int value); | ||||
|  | @ -43,8 +42,6 @@ void Get_View_Next(Application_Links *app, View_Summary *view, unsigned int acce | |||
| View_Summary Get_View(Application_Links *app, int index, unsigned int access); | ||||
| View_Summary Get_Active_View(Application_Links *app, unsigned int access); | ||||
| 
 | ||||
| int Refresh_View(Application_Links *app, View_Summary *view); | ||||
| 
 | ||||
| int         View_Auto_Tab       (Application_Links *app, View_Summary *view, int start, int end, int tab_width, unsigned int flags); | ||||
| Full_Cursor View_Compute_Cursor (Application_Links *app, View_Summary *view, Buffer_Seek seek); | ||||
| int         View_Set_Cursor     (Application_Links *app, View_Summary *view, Buffer_Seek seek, int set_preferred_x); | ||||
|  |  | |||
|  | @ -412,7 +412,7 @@ DeleteAfterCommand(struct Application_Links *app, unsigned long long CommandID) | |||
|     else{ | ||||
|         exec_command(app, (Custom_Command_Function*)CommandID); | ||||
|     } | ||||
|     app->refresh_view(app, &view); | ||||
|     refresh_view(app, &view); | ||||
|     int pos1 = view.cursor.pos; | ||||
| 
 | ||||
|     Range range = make_range(pos1, pos2); | ||||
|  | @ -438,7 +438,7 @@ CUSTOM_COMMAND_SIG(casey_kill_to_end_of_line) | |||
| 
 | ||||
|     int pos2 = view.cursor.pos; | ||||
|     exec_command(app, seek_end_of_line); | ||||
|     app->refresh_view(app, &view); | ||||
|     refresh_view(app, &view); | ||||
|     int pos1 = view.cursor.pos; | ||||
| 
 | ||||
|     Range range = make_range(pos1, pos2); | ||||
|  | @ -761,19 +761,18 @@ casey_parse_error(Application_Links *app, Buffer_Summary buffer, View_Summary vi | |||
| { | ||||
|     Parsed_Error result = {}; | ||||
| 
 | ||||
|     app->refresh_view(app, &view); | ||||
|     refresh_view(app, &view); | ||||
|     int restore_pos = view.cursor.pos; | ||||
| 
 | ||||
|     // TODO(allen): view_compute_cursor can get these
 | ||||
|     // positions without ever changing the position of the cursor.
 | ||||
|     app->view_set_cursor(app, &view, seek_line_char(view.cursor.line, 1), 1); | ||||
|     app->refresh_view(app, &view); | ||||
|     int start = view.cursor.pos; | ||||
| 
 | ||||
|     app->view_set_cursor(app, &view, seek_line_char(view.cursor.line, 65536), 1); | ||||
|     app->refresh_view(app, &view); | ||||
|     int end = view.cursor.pos; | ||||
| 
 | ||||
|     app->view_set_cursor(app, &view, seek_pos(restore_pos), 1); | ||||
|     app->refresh_view(app, &view); | ||||
| 
 | ||||
|     int size = end - start; | ||||
| 
 | ||||
|  | @ -861,7 +860,6 @@ casey_seek_error_dy(Application_Links *app, int dy) | |||
|     { | ||||
|         int prev_pos = compilation_view.cursor.pos; | ||||
|         app->view_set_cursor(app, &compilation_view, seek_line_char(compilation_view.cursor.line + dy, 0), 1); | ||||
|         app->refresh_view(app, &compilation_view); | ||||
|         if(compilation_view.cursor.pos != prev_pos) | ||||
|         { | ||||
|             Parsed_Error Error = casey_parse_error(app, Buffer, compilation_view); | ||||
|  | @ -1333,14 +1331,15 @@ DEFINE_BIMODAL_KEY(modal_page_up, cmdid_page_up, seek_whitespace_up); | |||
| DEFINE_BIMODAL_KEY(modal_page_down, cmdid_page_down, seek_whitespace_down); | ||||
| DEFINE_BIMODAL_KEY(modal_tab, cmdid_word_complete, cmdid_word_complete); | ||||
| 
 | ||||
| HOOK_SIG(casey_file_settings) | ||||
| OPEN_FILE_HOOK_SIG(casey_file_settings) | ||||
| { | ||||
|     // NOTE(allen|a4): As of alpha 4 hooks can have parameters which are
 | ||||
|     // received through functions like this app->get_parameter_buffer.
 | ||||
|     // This is different from the past where this hook got a buffer
 | ||||
|     // from app->get_active_buffer.
 | ||||
|     unsigned int access = AccessAll; | ||||
|     Buffer_Summary buffer = app->get_parameter_buffer(app, 0, access); | ||||
|     //Buffer_Summary buffer = app->get_parameter_buffer(app, 0, access);
 | ||||
|     Buffer_Summary buffer = app->get_buffer(app, buffer_id, access); | ||||
| 
 | ||||
|     int treat_as_code = 0; | ||||
|     int treat_as_project = 0; | ||||
|  | @ -1566,7 +1565,7 @@ extern "C" GET_BINDING_DATA(get_bindings) | |||
|     Bind_Helper *context = &context_actual; | ||||
| 
 | ||||
|     set_hook(context, hook_start, casey_start); | ||||
|     set_hook(context, hook_open_file, casey_file_settings); | ||||
|     set_open_file_hook(context, casey_file_settings); | ||||
|     set_scroll_rule(context, casey_smooth_scroll_rule); | ||||
| 
 | ||||
|     EnumWindows(win32_find_4coder_window, 0); | ||||
|  |  | |||
|  | @ -1,304 +0,0 @@ | |||
| 
 | ||||
| // TOP
 | ||||
| #include "4coder_default.cpp" | ||||
| 
 | ||||
| //#include "chr_winutils.h"
 | ||||
| 
 | ||||
| #ifndef literal | ||||
| #define literal(s) (s), (sizeof(s)-1) | ||||
| #endif | ||||
| 
 | ||||
| #define rgb_color(r, g, b) (r << 16 + g << 8 + b << 0) | ||||
| #define hex_color(hex) hex | ||||
| 
 | ||||
| const int color_margin_normal = 0x341313; | ||||
| const int color_margin_insert = 0x5a3619; | ||||
| 
 | ||||
| enum Vim_Maps { | ||||
|     mapid_normal = mapid_global, | ||||
|     mapid_insert = 0, | ||||
|     mapid_replace, | ||||
|     mapid_visual, | ||||
| 
 | ||||
|     // There are a bunch of different chord "starters" that result in keys having
 | ||||
|     // different behaviors. There's no better way to handle this right now than
 | ||||
|     // just explicitly creating maps for each one.
 | ||||
| 
 | ||||
|     //TODO(chronister): Chords can be built up, so this can have potentially huge
 | ||||
|     //combinatorics... what I *want* is a way to build up an actual stack of commands
 | ||||
|     //...
 | ||||
| 
 | ||||
|     mapid_chord_delete, | ||||
|     mapid_chord_yank, | ||||
|     mapid_chord_g, | ||||
| }; | ||||
| 
 | ||||
| HOOK_SIG(chronal_init){ | ||||
|     exec_command(app, cmdid_open_panel_vsplit); | ||||
|     exec_command(app, cmdid_change_active_panel); | ||||
| 
 | ||||
|     app->change_theme(app, literal("4coder")); | ||||
|     app->change_font(app, literal("Hack")); | ||||
| 
 | ||||
|     const int color_bg = 0x15100f; | ||||
|     const int color_bar = 0x1c1212; | ||||
|     const int color_bar_hover = 0x261414; | ||||
|     const int color_bar_active = 0x341313; | ||||
|     const int color_text = 0x916550; | ||||
|     const int color_comment = 0x9d5b25; | ||||
|     const int color_string_literal = 0x9c2d21; | ||||
|     const int color_num_literals = 0xc56211; | ||||
|     const int color_keyword = 0xf74402; | ||||
|     Theme_Color colors[] = { | ||||
|         { Stag_Back, color_bg }, | ||||
|         { Stag_Margin, color_bar }, | ||||
|         { Stag_Margin_Hover, color_bar_hover }, | ||||
|         { Stag_Margin_Active, color_margin_normal }, | ||||
|         { Stag_Bar, color_bar }, | ||||
|         { Stag_Bar_Active, color_bar_active }, | ||||
|         { Stag_Base, color_text }, | ||||
|         { Stag_Default, color_text }, | ||||
|         { Stag_Comment, color_comment }, | ||||
|         { Stag_Int_Constant, color_num_literals }, | ||||
|         { Stag_Float_Constant, color_num_literals }, | ||||
|         { Stag_Str_Constant, color_string_literal }, | ||||
|         { Stag_Char_Constant, color_string_literal }, | ||||
|         { Stag_Bool_Constant, color_keyword }, | ||||
|         { Stag_Keyword, color_keyword }, | ||||
|         { Stag_Special_Character, color_keyword }, | ||||
|         { Stag_Preproc, color_keyword }, | ||||
|     }; | ||||
| 
 | ||||
|     app->set_theme_colors(app, colors, ArrayCount(colors)); | ||||
| 
 | ||||
|     push_parameter(app, par_key_mapid, mapid_normal); | ||||
|     exec_command(app, cmdid_set_settings); | ||||
| 
 | ||||
|     // no meaning for return
 | ||||
|     return(0); | ||||
| } | ||||
| 
 | ||||
| HOOK_SIG(chronal_file_settings){ | ||||
|     // NOTE(allen|a4): In hooks that want parameters, such as this file
 | ||||
|     // created hook.  The file created hook is guaranteed to have only
 | ||||
|     // and exactly one buffer parameter.  In normal command callbacks
 | ||||
|     // there are no parameter buffers.
 | ||||
|     Buffer_Summary buffer = app->get_parameter_buffer(app, 0); | ||||
|     assert(buffer.exists); | ||||
| 
 | ||||
|     int treat_as_code = 0; | ||||
| 
 | ||||
|     if (buffer.file_name && buffer.size < (16 << 20)){ | ||||
|         String ext = file_extension(make_string(buffer.file_name, buffer.file_name_len)); | ||||
|         if (match(ext, make_lit_string("cpp"))) treat_as_code = 1; | ||||
|         else if (match(ext, make_lit_string("h"))) treat_as_code = 1; | ||||
|         else if (match(ext, make_lit_string("c"))) treat_as_code = 1; | ||||
|         else if (match(ext, make_lit_string("hpp"))) treat_as_code = 1; | ||||
|     } | ||||
| 
 | ||||
|     push_parameter(app, par_lex_as_cpp_file, treat_as_code); | ||||
|     push_parameter(app, par_wrap_lines, !treat_as_code); | ||||
|     push_parameter(app, par_key_mapid, mapid_normal); | ||||
|     exec_command(app, cmdid_set_settings); | ||||
| 
 | ||||
|     // no meaning for return
 | ||||
|     return(0); | ||||
| } | ||||
| 
 | ||||
| /*                 *
 | ||||
|  * Custom commands * | ||||
|  *                 */ | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| CUSTOM_COMMAND_SIG(do_nothing){ | ||||
| } | ||||
| 
 | ||||
| CUSTOM_COMMAND_SIG(enter_insert_mode){ | ||||
|     push_parameter(app, par_key_mapid, mapid_insert); | ||||
|     exec_command(app, cmdid_set_settings); | ||||
| 
 | ||||
|     Theme_Color colors[] = { | ||||
|         { Stag_Bar_Active, color_margin_insert }, | ||||
|         { Stag_Margin_Active, color_margin_insert }, | ||||
|     }; | ||||
|     app->set_theme_colors(app, colors, ArrayCount(colors)); | ||||
| } | ||||
| 
 | ||||
| CUSTOM_COMMAND_SIG(enter_normal_mode){ | ||||
|     push_parameter(app, par_key_mapid, mapid_normal); | ||||
|     exec_command(app, cmdid_set_settings); | ||||
| 
 | ||||
|     Theme_Color colors[] = { | ||||
|         { Stag_Bar_Active, color_margin_normal }, | ||||
|         { Stag_Margin_Active, color_margin_normal }, | ||||
|     }; | ||||
|     app->set_theme_colors(app, colors, ArrayCount(colors)); | ||||
| } | ||||
| 
 | ||||
| CUSTOM_COMMAND_SIG(seek_forward_word_start){ | ||||
|     View_Summary view; | ||||
|     view = app->get_active_view(app); | ||||
|     push_parameter(app, par_flags, BoundryToken); | ||||
|     exec_command(app, cmdid_seek_right); | ||||
|     app->refresh_view(app, &view); | ||||
| } | ||||
| 
 | ||||
| CUSTOM_COMMAND_SIG(seek_backward_word_start){ | ||||
|     View_Summary view; | ||||
|     view = app->get_active_view(app); | ||||
|     push_parameter(app, par_flags, BoundryToken | BoundryWhitespace); | ||||
|     exec_command(app, cmdid_seek_left); | ||||
|     app->refresh_view(app, &view); | ||||
| } | ||||
| 
 | ||||
| CUSTOM_COMMAND_SIG(seek_forward_word_end){ | ||||
|     View_Summary view; | ||||
|     view = app->get_active_view(app); | ||||
|     push_parameter(app, par_flags, BoundryToken | BoundryWhitespace); | ||||
|     exec_command(app, cmdid_seek_right); | ||||
|     app->refresh_view(app, &view); | ||||
| } | ||||
| 
 | ||||
| CUSTOM_COMMAND_SIG(newline_then_insert_before){ | ||||
|     exec_command(app, cmdid_seek_beginning_of_line); | ||||
|     write_string(app, make_lit_string("\n")); | ||||
|     exec_command(app, cmdid_move_left); | ||||
|     exec_command(app, enter_insert_mode); | ||||
| } | ||||
| 
 | ||||
| CUSTOM_COMMAND_SIG(newline_then_insert_after){ | ||||
|     exec_command(app, cmdid_seek_end_of_line); | ||||
|     write_string(app, make_lit_string("\n")); | ||||
|     exec_command(app, enter_insert_mode); | ||||
| } | ||||
| 
 | ||||
| CUSTOM_COMMAND_SIG(begin_chord_delete){ | ||||
|     push_parameter(app, par_key_mapid, mapid_chord_delete); | ||||
|     exec_command(app, cmdid_set_settings); | ||||
| } | ||||
| 
 | ||||
| CUSTOM_COMMAND_SIG(delete_line){ | ||||
|     View_Summary view; | ||||
|     Buffer_Summary buffer; | ||||
|     int pos1, pos2; | ||||
|     view = app->get_active_view(app); | ||||
| 
 | ||||
|     exec_command(app, cmdid_seek_beginning_of_line); | ||||
|     app->refresh_view(app, &view); | ||||
|     pos1 = view.cursor.pos; | ||||
| 
 | ||||
|     exec_command(app, cmdid_seek_end_of_line); | ||||
|     app->refresh_view(app, &view); | ||||
|     pos2 = view.cursor.pos; | ||||
|      | ||||
|     Range range = make_range(pos1, pos2); | ||||
|     buffer = app->get_buffer(app, view.buffer_id); | ||||
|     app->buffer_replace_range(app, &buffer, range.start, range.end, 0, 0); | ||||
| } | ||||
| 
 | ||||
| CUSTOM_COMMAND_SIG(delete_word){ | ||||
|     View_Summary view; | ||||
|     Buffer_Summary buffer; | ||||
|     int pos1, pos2; | ||||
|     view = app->get_active_view(app); | ||||
| 
 | ||||
|     exec_command(app, seek_backward_word_start); | ||||
|     app->refresh_view(app, &view); | ||||
|     pos1 = view.cursor.pos; | ||||
| 
 | ||||
|     exec_command(app, seek_forward_word_end); | ||||
|     app->refresh_view(app, &view); | ||||
|     pos2 = view.cursor.pos; | ||||
|      | ||||
|     Range range = make_range(pos1, pos2); | ||||
|     buffer = app->get_buffer(app, view.buffer_id); | ||||
|     app->buffer_replace_range(app, &buffer, range.start, range.end, 0, 0); | ||||
|      | ||||
| } | ||||
| 
 | ||||
| void | ||||
| chronal_get_bindings(Bind_Helper *context){ | ||||
|     set_hook(context, hook_start, chronal_init); | ||||
|     set_hook(context, hook_open_file, chronal_file_settings); | ||||
| 
 | ||||
|     set_scroll_rule(context, smooth_scroll_rule); | ||||
| 
 | ||||
|     /*                          *
 | ||||
|      * SECTION: Vim keybindings * | ||||
|      *                          */ | ||||
| 
 | ||||
|     /* Normal mode.
 | ||||
|      * aka "It's eating all my input, help!" mode. | ||||
|      * Shortcuts for navigation, entering various modes, | ||||
|      * dealing with the editor. | ||||
|      */ | ||||
|     begin_map(context, mapid_normal); | ||||
| 
 | ||||
|     bind_vanilla_keys(context, do_nothing); | ||||
| 
 | ||||
|     bind(context, 'w', MDFR_NONE, seek_forward_word_start); | ||||
|     bind(context, 'e', MDFR_NONE, seek_forward_word_end); | ||||
|     bind(context, 'b', MDFR_NONE, seek_backward_word_start); | ||||
|     bind(context, '$', MDFR_NONE, cmdid_seek_end_of_line); | ||||
|     bind(context, '0', MDFR_NONE, cmdid_seek_beginning_of_line); | ||||
| 
 | ||||
|     bind(context, 'h', MDFR_NONE, cmdid_move_left); | ||||
|     bind(context, 'j', MDFR_NONE, cmdid_move_down); | ||||
|     bind(context, 'k', MDFR_NONE, cmdid_move_up); | ||||
|     bind(context, 'l', MDFR_NONE, cmdid_move_right); | ||||
| 
 | ||||
|     bind(context, 'u', MDFR_CTRL, cmdid_page_up); | ||||
|     bind(context, 'd', MDFR_CTRL, cmdid_page_down); | ||||
| 
 | ||||
|     bind(context, 'x', MDFR_NONE, cmdid_delete); | ||||
| 
 | ||||
|     bind(context, 'u', MDFR_NONE, cmdid_undo); | ||||
|     bind(context, 'r', MDFR_CTRL, cmdid_redo); | ||||
| 
 | ||||
|     bind(context, '/', MDFR_NONE, search); | ||||
| 
 | ||||
|     bind(context, 'i', MDFR_NONE, enter_insert_mode); | ||||
|     bind(context, 'o', MDFR_NONE, newline_then_insert_after); | ||||
|     bind(context, 'O', MDFR_NONE, newline_then_insert_before); | ||||
| 
 | ||||
|     bind(context, 'n', MDFR_CTRL, cmdid_word_complete); | ||||
| 
 | ||||
|     // TEMP (will be replaced later by :statusbar commands)
 | ||||
|     bind(context, 'o', MDFR_CTRL, cmdid_interactive_open); | ||||
|     bind(context, 'c', MDFR_CTRL, cmdid_open_color_tweaker); | ||||
|     end_map(context); | ||||
| 
 | ||||
|     /* Insert mode
 | ||||
|      * You type and it goes into the buffer. Nice and simple. | ||||
|      * Escape to exit. | ||||
|      */ | ||||
|     begin_map(context, mapid_insert); | ||||
|     inherit_map(context, mapid_nomap); | ||||
| 
 | ||||
|     bind_vanilla_keys(context, cmdid_write_character); | ||||
|     bind(context, key_back, MDFR_NONE, cmdid_backspace); | ||||
| 
 | ||||
|     bind(context, key_esc, MDFR_NONE, enter_normal_mode); | ||||
| 
 | ||||
|     end_map(context); | ||||
| 
 | ||||
| #if 1 | ||||
| 
 | ||||
|     /* Chord "modes".
 | ||||
|      * They're not really an explicit mode per-say, but the meaning of key presses | ||||
|      * does change once a chord starts, and is context-dependent. | ||||
|      * TODO(chronister): I want these to properly build on each other. | ||||
|      */ | ||||
|     begin_map(context, mapid_chord_delete); | ||||
|     inherit_map(context, mapid_nomap); | ||||
| 
 | ||||
|     bind(context, 'd', MDFR_NONE, delete_line); | ||||
|     bind(context, 'w', MDFR_NONE, delete_word); | ||||
| 
 | ||||
|     end_map(context); | ||||
| 
 | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
|  | @ -263,7 +263,7 @@ get_bindings(void *data, int size){ | |||
|     Bind_Helper *context = &context_; | ||||
|      | ||||
|     set_hook(context, hook_start, experimental_start_hook); | ||||
|     set_hook(context, hook_open_file, my_file_settings); | ||||
|     set_open_file_hook(context, my_file_settings); | ||||
|      | ||||
|     set_scroll_rule(context, smooth_scroll_rule); | ||||
|      | ||||
|  |  | |||
|  | @ -830,12 +830,10 @@ Sys_Set_File_List_Sig(system_set_file_list){ | |||
| } | ||||
| 
 | ||||
| internal | ||||
| Sys_File_Track_Sig(system_file_track){ | ||||
| } | ||||
| Sys_File_Track_Sig(system_file_track){} | ||||
| 
 | ||||
| internal | ||||
| Sys_File_Untrack_Sig(system_file_untrack){ | ||||
| } | ||||
| Sys_File_Untrack_Sig(system_file_untrack){} | ||||
| 
 | ||||
| internal | ||||
| Sys_File_Unique_Hash_Sig(system_file_unique_hash){ | ||||
|  | @ -871,7 +869,11 @@ Sys_File_Unique_Hash_Sig(system_file_unique_hash){ | |||
| 
 | ||||
| // NOTE(allen): Exposed to the custom layer.
 | ||||
| internal | ||||
| FILE_EXISTS_SIG(system_file_exists){ | ||||
| FILE_EXISTS_SIG(system_file_exists)/*
 | ||||
| DOC_PARAM(filename, the full path to a file) | ||||
| DOC_PARAM(len, the number of characters in the filename string) | ||||
| DOC_RETURN(returns non-zero if the file exists, returns zero if the file does not exist) | ||||
| */{ | ||||
|     char full_filename_space[1024]; | ||||
|     String full_filename; | ||||
|     HANDLE file; | ||||
|  | @ -904,11 +906,33 @@ b32 Win32DirectoryExists(char *path){ | |||
| 
 | ||||
| // NOTE(allen): Exposed to the custom layer.
 | ||||
| internal | ||||
| DIRECTORY_CD_SIG(system_directory_cd){ | ||||
| DIRECTORY_CD_SIG(system_directory_cd)/*
 | ||||
| DOC_PARAM(dir, a string buffer containing a directory) | ||||
| DOC_PARAM(len, the length of the string in the string buffer) | ||||
| DOC_PARAM(capacity, the maximum size of the string buffer) | ||||
| DOC_PARAM(rel_path, the path to change to, may include '.' or '..') | ||||
| DOC_PARAM(rel_len, the length of the rel_path string) | ||||
| DOC_RETURN(returns non-zero if the call succeeds, returns zero otherwise) | ||||
| DOC | ||||
| ( | ||||
| This call succeeds if the directory exists and the new directory fits inside the dir buffer. | ||||
| If the call succeeds the dir buffer is filled with the new directory and len contains the | ||||
| length of the string in the buffer. | ||||
| 
 | ||||
| For instance if dir contains "C:/Users/MySelf" and rel is "Documents" the buffer will contain | ||||
| "C:/Users/MySelf/Documents" and len will contain the length of that string.  This call can | ||||
| also be used with rel as ".." to traverse to parent folders. | ||||
| ) | ||||
| */{ | ||||
|     String directory = make_string(dir, *len, capacity); | ||||
|     b32 result = 0; | ||||
|     i32 old_size; | ||||
|      | ||||
|     char rel_path_space[1024]; | ||||
|     String rel_path_string = make_fixed_width_string(rel_path_space); | ||||
|     copy(&rel_path_string, make_string(rel_path, rel_len)); | ||||
|     terminate_with_null(&rel_path_string); | ||||
|      | ||||
|     if (rel_path[0] != 0){ | ||||
|         if (rel_path[0] == '.' && rel_path[1] == 0){ | ||||
|             result = 1; | ||||
|  | @ -951,7 +975,11 @@ Sys_Get_Binary_Path_Sig(system_get_binary_path){ | |||
| } | ||||
| 
 | ||||
| // NOTE(allen): Exposed to the custom layer.
 | ||||
| GET_4ED_PATH_SIG(system_get_4ed_path){ | ||||
| GET_4ED_PATH_SIG(system_get_4ed_path)/*
 | ||||
| DOC_PARAM(out, a buffer that receives the path to the 4ed executable file) | ||||
| DOC_PARAM(capacity, the maximum capacity of the output buffer) | ||||
| DOC_RETURN(returns non-zero on success, returns zero on failure) | ||||
| */{ | ||||
|     String str = make_string(out, 0, capacity); | ||||
|     return(system_get_binary_path(&str)); | ||||
| } | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Allen Webster
						Allen Webster