style-system
							parent
							
								
									fb91a10918
								
							
						
					
					
						commit
						852a7fd71c
					
				
							
								
								
									
										128
									
								
								4ed.cpp
								
								
								
								
							
							
						
						
									
										128
									
								
								4ed.cpp
								
								
								
								
							|  | @ -12,8 +12,6 @@ | |||
| // 
 | ||||
| // BUGS & PROBLEMS
 | ||||
| // 
 | ||||
| // - LOGGING SYSTEM FOR ALL BUILD CONFIGS
 | ||||
| // 
 | ||||
| // - line_wrap_ys remeasurement optimization
 | ||||
| // 
 | ||||
| // GENERAL
 | ||||
|  | @ -31,8 +29,6 @@ | |||
| // 
 | ||||
| // - configuration / GUI for generating configuration
 | ||||
| // 
 | ||||
| // - no scroll on line wrap/line mode change
 | ||||
| // 
 | ||||
| // - travel packaging
 | ||||
| // 
 | ||||
| // - multiple live name conflicts
 | ||||
|  | @ -63,8 +59,6 @@ | |||
| // 
 | ||||
| // - select token
 | ||||
| // 
 | ||||
| // - seek token or whitespace within token
 | ||||
| // 
 | ||||
| // - reprogrammable lexing / auto indent
 | ||||
| // 
 | ||||
| // - bracket match / mismatch highlighting
 | ||||
|  | @ -89,9 +83,7 @@ | |||
| // - generate header
 | ||||
| // 
 | ||||
| 
 | ||||
| /*
 | ||||
|  * App Structs | ||||
|  */ | ||||
| // App Structs
 | ||||
| 
 | ||||
| enum App_State{ | ||||
|     APP_STATE_EDIT, | ||||
|  | @ -142,9 +134,7 @@ struct App_Vars{ | |||
|     Panel *prev_mouse_panel; | ||||
| }; | ||||
| 
 | ||||
| /*
 | ||||
|  * Commands | ||||
|  */ | ||||
| // Commands
 | ||||
| 
 | ||||
| globalvar Application_Links app_links; | ||||
| 
 | ||||
|  | @ -235,7 +225,7 @@ COMMAND_DECL(write_character){ | |||
|             current_view->preferred_x = view_get_cursor_x(current_view); | ||||
|         } | ||||
|     } | ||||
|     file->cursor.pos = view->cursor.pos; | ||||
|     file->cursor_pos = view->cursor.pos; | ||||
| } | ||||
| 
 | ||||
| internal i32 | ||||
|  | @ -732,11 +722,8 @@ COMMAND_DECL(paste_next){ | |||
|                                  (u8*)src->str, src->size); | ||||
|              | ||||
|             view_measure_wraps(&mem->general, view); | ||||
|              | ||||
|             view->cursor = view_compute_cursor_from_pos(view, range.smaller+src->size); | ||||
|             view->preferred_x = view_get_cursor_x(view); | ||||
|             view->file->cursor.pos = view->cursor.pos; | ||||
|              | ||||
| 
 | ||||
|             view_cursor_move(view, range.smaller+src->size); | ||||
|             view->mark = pos_universal_fix(range.smaller, | ||||
|                                            file->data, file->size, | ||||
|                                            file->endline_mode); | ||||
|  | @ -792,11 +779,10 @@ COMMAND_DECL(delete_chunk){ | |||
|         } | ||||
|         buffer_delete_range(mem, file, range); | ||||
|         view_measure_wraps(&mem->general, view); | ||||
|         view->cursor = view_compute_cursor_from_pos(view, range.smaller); | ||||
|         view_cursor_move(view, range.smaller); | ||||
|         view->mark = pos_universal_fix(range.smaller, | ||||
|                                        file->data, file->size, | ||||
|                                        file->endline_mode); | ||||
|         view->file->cursor.pos = view->cursor.pos; | ||||
|          | ||||
|         Editing_Layout *layout = command->layout; | ||||
|         Panel *panels = layout->panels; | ||||
|  | @ -828,6 +814,49 @@ COMMAND_DECL(delete_chunk){ | |||
|     } | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(undo){ | ||||
|     ProfileMomentFunction(); | ||||
|     REQ_FILE_VIEW(view); | ||||
|     REQ_FILE(file, view); | ||||
|     USE_MEM(mem); | ||||
|      | ||||
|     if (file->undo.edit_count > 0){ | ||||
|         Edit_Step step = file->undo.edits[--file->undo.edit_count]; | ||||
|          | ||||
|         buffer_post_redo(&mem->general, file, step.range.start, step.range.end, step.replaced.size); | ||||
|         buffer_replace_range(mem, file, step.range.start, step.range.end, | ||||
|                              (u8*)step.replaced.str, step.replaced.size, 0); | ||||
|         view_cursor_move(view, step.cursor_pos); | ||||
|         view->mark = view->cursor.pos; | ||||
|          | ||||
|         view_post_paste_effect(view, 10, step.range.start, step.replaced.size, | ||||
|                                view->style->main.undo_color); | ||||
|          | ||||
|         file->undo.str_size -= step.replaced.size; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(redo){ | ||||
|     ProfileMomentFunction(); | ||||
|     REQ_FILE_VIEW(view); | ||||
|     REQ_FILE(file, view); | ||||
|     USE_MEM(mem); | ||||
|      | ||||
|     if (file->undo.edit_redo < file->undo.edit_max){ | ||||
|         Edit_Step step = file->undo.edits[file->undo.edit_redo++]; | ||||
|          | ||||
|         buffer_replace_range(mem, file, step.range.start, step.range.end, | ||||
|                              (u8*)step.replaced.str, step.replaced.size, 2); | ||||
|         view_cursor_move(view, step.cursor_pos); | ||||
|         view->mark = view->cursor.pos; | ||||
|          | ||||
|         view_post_paste_effect(view, 10, step.range.start, step.replaced.size, | ||||
|                                view->style->main.undo_color); | ||||
|          | ||||
|         file->undo.str_redo += step.replaced.size; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(interactive_new){ | ||||
|     ProfileMomentFunction(); | ||||
|     USE_VARS(vars); | ||||
|  | @ -1132,6 +1161,7 @@ COMMAND_DECL(to_lowercase){ | |||
|     } | ||||
| } | ||||
| 
 | ||||
| #if 0 | ||||
| internal void | ||||
| view_clean_line(Mem_Options *mem, File_View *view, Editing_File *file, i32 line_start){ | ||||
|     u8 *data = file->data; | ||||
|  | @ -1188,8 +1218,10 @@ view_clean_line(Mem_Options *mem, File_View *view, Editing_File *file, i32 line_ | |||
|         //view_auto_tab(mem, view, pos, pos);
 | ||||
|     } | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| COMMAND_DECL(clean_line){ | ||||
| #if 0 | ||||
|     ProfileMomentFunction(); | ||||
|     REQ_FILE_VIEW(view); | ||||
|     REQ_FILE(file, view); | ||||
|  | @ -1198,9 +1230,11 @@ COMMAND_DECL(clean_line){ | |||
|     i32 line_start = view_find_beginning_of_line(view, view->cursor.pos); | ||||
|     view_clean_line(mem, view, file, line_start); | ||||
|     view_measure_wraps(&mem->general, view); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(clean_all_lines){ | ||||
| #if 0 | ||||
|     ProfileMomentFunction(); | ||||
|     REQ_FILE_VIEW(view); | ||||
|     REQ_FILE(file, view); | ||||
|  | @ -1213,9 +1247,11 @@ COMMAND_DECL(clean_all_lines){ | |||
|      | ||||
|     view_measure_wraps(&mem->general, view); | ||||
|     view->cursor = view_compute_cursor_from_pos(view, view->cursor.pos); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(eol_dosify){ | ||||
| #if 0 | ||||
|     ProfileMomentFunction(); | ||||
|     REQ_FILE_VIEW(view); | ||||
|     REQ_FILE(file, view); | ||||
|  | @ -1223,9 +1259,11 @@ COMMAND_DECL(eol_dosify){ | |||
|      | ||||
|     view_endline_convert(mem, view, ENDLINE_RN, ENDLINE_ERASE, ENDLINE_RN); | ||||
|     view_measure_wraps(&mem->general, view); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(eol_nixify){ | ||||
| #if 0 | ||||
|     ProfileMomentFunction(); | ||||
|     REQ_FILE_VIEW(view); | ||||
|     REQ_FILE(file, view); | ||||
|  | @ -1233,17 +1271,19 @@ COMMAND_DECL(eol_nixify){ | |||
|      | ||||
|     view_endline_convert(mem, view, ENDLINE_N, ENDLINE_ERASE, ENDLINE_N); | ||||
|     view_measure_wraps(&mem->general, view); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(auto_tab){ | ||||
| #if 0 | ||||
|     ProfileMomentFunction(); | ||||
|     REQ_FILE_VIEW(view); | ||||
|     REQ_FILE(file, view); | ||||
|     USE_MEM(mem); | ||||
|      | ||||
|     Range range = get_range(view->cursor.pos, view->mark); | ||||
|     view_auto_tab(mem, view, range.smaller, range.larger); | ||||
|     view_measure_wraps(&mem->general, view); | ||||
| #endif | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(open_panel_vsplit){ | ||||
|  | @ -1541,7 +1581,7 @@ COMMAND_DECL(move_up){ | |||
|     real32 px = view->preferred_x; | ||||
|     if (cy >= 0){ | ||||
|         view->cursor = view_compute_cursor_from_xy(view, px, cy); | ||||
|         view->file->cursor.pos = view->cursor.pos; | ||||
|         view->file->cursor_pos = view->cursor.pos; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -1553,7 +1593,7 @@ COMMAND_DECL(move_down){ | |||
|     real32 cy = view_get_cursor_y(view)+view->style->font->height; | ||||
|     real32 px = view->preferred_x; | ||||
|     view->cursor = view_compute_cursor_from_xy(view, px, cy); | ||||
|     view->file->cursor.pos = view->cursor.pos; | ||||
|     view->file->cursor_pos = view->cursor.pos; | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(seek_end_of_line){ | ||||
|  | @ -1709,12 +1749,15 @@ COMMAND_DECL(cursor_mark_swap){ | |||
|     view->mark = pos; | ||||
| } | ||||
| 
 | ||||
| internal void | ||||
| fulfill_interaction(Command_Data *command, char *data, bool32 full_set){ | ||||
| internal bool32 | ||||
| fulfill_interaction_intview(Command_Data *command, char *data, bool32 full_set){ | ||||
|     bool32 result = 0; | ||||
|     Panel *panel = command->panel; | ||||
|     View *view = panel->view; | ||||
|     Interactive_View *int_view = view_to_interactive_view(view); | ||||
|     if (int_view){ | ||||
|         result = 1; | ||||
|          | ||||
|         String *dest = 0; | ||||
|         switch (int_view->interaction){ | ||||
|         case INTV_SYS_FILE_LIST: | ||||
|  | @ -1726,9 +1769,11 @@ fulfill_interaction(Command_Data *command, char *data, bool32 full_set){ | |||
|         } | ||||
|         if (full_set) dest->size = 0; | ||||
|         append(dest, data); | ||||
|          | ||||
|         interactive_view_complete(int_view); | ||||
|     } | ||||
|      | ||||
|     interactive_view_complete(int_view); | ||||
| 
 | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| COMMAND_DECL(user_callback){ | ||||
|  | @ -1766,7 +1811,8 @@ extern "C"{ | |||
|      | ||||
|     FULFILL_INTERACTION_SIG(fulfill_interaction_external){ | ||||
|         Command_Data *cmd = (Command_Data*)cmd_context; | ||||
|         fulfill_interaction(cmd, data, full_set); | ||||
|         bool32 handled = 0; | ||||
|         handled = fulfill_interaction_intview(cmd, data, full_set); | ||||
|     } | ||||
| } | ||||
| 
 | ||||
|  | @ -1829,6 +1875,8 @@ setup_file_commands(Command_Map *commands, Key_Codes *codes){ | |||
|     map_add(commands, 'x', MDFR_CTRL, command_cut); | ||||
|     map_add(commands, 'v', MDFR_CTRL, command_paste); | ||||
|     map_add(commands, 'V', MDFR_CTRL, command_paste_next); | ||||
|     map_add(commands, 'z', MDFR_CTRL, command_undo); | ||||
|     map_add(commands, 'y', MDFR_CTRL, command_redo); | ||||
|     map_add(commands, 'd', MDFR_CTRL, command_delete_chunk); | ||||
|     map_add(commands, 'l', MDFR_CTRL, command_toggle_line_wrap); | ||||
|     map_add(commands, 'L', MDFR_CTRL, command_toggle_endline_mode); | ||||
|  | @ -1956,9 +2004,7 @@ setup_command_table(){ | |||
| #undef SET | ||||
| } | ||||
| 
 | ||||
| /*
 | ||||
|  * Interactive Bar | ||||
|  */ | ||||
| // Interactive Bar
 | ||||
| 
 | ||||
| internal void | ||||
| hot_directory_draw_helper(Render_Target *target, | ||||
|  | @ -2074,12 +2120,14 @@ app_hardcode_styles(App_Vars *vars){ | |||
|     style->main.special_character_color = 0xFFFF0000; | ||||
|      | ||||
|     style->main.paste_color = 0xFFDDEE00; | ||||
|     style->main.undo_color = 0xFF00DDEE; | ||||
|     style->main.next_undo_color = 0xFF006E77; | ||||
|      | ||||
|     style->main.highlight_junk_color = 0xff3a0000; | ||||
|     style->main.highlight_white_color = 0xff003a3a; | ||||
|      | ||||
|     file_info_style.bar_color = 0xFF888888; | ||||
|     file_info_style.bar_active_color = 0xFF888888; | ||||
|     file_info_style.bar_active_color = 0xFF666666; | ||||
|     file_info_style.base_color = 0xFF000000; | ||||
|     file_info_style.pop1_color = 0xFF4444AA; | ||||
|     file_info_style.pop2_color = 0xFFFF0000; | ||||
|  | @ -2119,12 +2167,14 @@ app_hardcode_styles(App_Vars *vars){ | |||
|     style->main.special_character_color = 0xFFFF0000; | ||||
|      | ||||
|     style->main.paste_color = 0xFFFFBB00; | ||||
|     style->main.undo_color = 0xFFFF00BB; | ||||
|     style->main.undo_color = 0xFF80005D; | ||||
|      | ||||
|     style->main.highlight_junk_color = 0xFF3A0000; | ||||
|     style->main.highlight_white_color = 0xFF003A3A; | ||||
|      | ||||
|     file_info_style.bar_color = 0xFFCACACA; | ||||
|     file_info_style.bar_active_color = 0xFFCACACA; | ||||
|     file_info_style.bar_active_color = 0xFFA8A8A8; | ||||
|     file_info_style.base_color = 0xFF000000; | ||||
|     file_info_style.pop1_color = 0xFF1504CF; | ||||
|     file_info_style.pop2_color = 0xFFFF0000; | ||||
|  | @ -2158,12 +2208,14 @@ app_hardcode_styles(App_Vars *vars){ | |||
|     style->main.special_character_color = 0xFFFF0000; | ||||
|      | ||||
|     style->main.paste_color = 0xFFDDEE00; | ||||
|     style->main.undo_color = 0xFF00DDEE; | ||||
|     style->main.next_undo_color = 0xFF006E77; | ||||
|      | ||||
|     style->main.highlight_junk_color = 0xff3a0000; | ||||
|     style->main.highlight_white_color = 0xFF151F2A; | ||||
|      | ||||
|     file_info_style.bar_color = 0xFF315E68; | ||||
|     file_info_style.bar_active_color = 0xFF315E68; | ||||
|     file_info_style.bar_active_color = 0xFF0F3C46; | ||||
|     file_info_style.base_color = 0xFF000000; | ||||
|     file_info_style.pop1_color = 0xFF1BFF0C; | ||||
|     file_info_style.pop2_color = 0xFFFF200D; | ||||
|  | @ -2197,12 +2249,14 @@ app_hardcode_styles(App_Vars *vars){ | |||
|     style->main.special_character_color = 0xFFFF0000; | ||||
|      | ||||
|     style->main.paste_color = 0xFF900090; | ||||
|     style->main.undo_color = 0xFF606090; | ||||
|     style->main.next_undo_color = 0xFF404070; | ||||
|      | ||||
|     style->main.highlight_junk_color = 0xff3a0000; | ||||
|     style->main.highlight_white_color = 0xff003a3a; | ||||
|      | ||||
|     file_info_style.bar_color = 0xFF7082F9; | ||||
|     file_info_style.bar_active_color = 0xFF7082F9; | ||||
|     file_info_style.bar_active_color = 0xFF4E60D7; | ||||
|     file_info_style.base_color = 0xFF000000; | ||||
|     file_info_style.pop1_color = 0xFFFAFA15; | ||||
|     file_info_style.pop2_color = 0xFFD20000; | ||||
|  | @ -2236,12 +2290,14 @@ app_hardcode_styles(App_Vars *vars){ | |||
|     style->main.special_character_color = 0xFF9A0000; | ||||
|      | ||||
|     style->main.paste_color = 0xFF00B8B8; | ||||
|     style->main.undo_color = 0xFFB800B8; | ||||
|     style->main.next_undo_color = 0xFF5C005C; | ||||
|      | ||||
|     style->main.highlight_junk_color = 0xFFFF7878; | ||||
|     style->main.highlight_white_color = 0xFFBCBCBC; | ||||
|      | ||||
|     file_info_style.bar_color = 0xFF606060; | ||||
|     file_info_style.bar_active_color = 0xFF888888; | ||||
|     file_info_style.bar_active_color = 0xFF3E3E3E; | ||||
|     file_info_style.base_color = 0xFF000000; | ||||
|     file_info_style.pop1_color = 0xFF1111DC; | ||||
|     file_info_style.pop2_color = 0xFFE80505; | ||||
|  |  | |||
|  | @ -60,6 +60,8 @@ draw_general_memory(Debug_View *view, i32_Rect rect, Render_Target *target, i32 | |||
|             case BUBBLE_WIDTHS: append(&s, "widths"); break; | ||||
|             case BUBBLE_WRAPS: append(&s, "wraps"); break; | ||||
|             case BUBBLE_TOKENS: append(&s, "tokens"); break; | ||||
|             case BUBBLE_UNDO_STRING: append(&s, "undo string"); break; | ||||
|             case BUBBLE_UNDO: append(&s, "undo"); break; | ||||
|             default: append(&s, "unknown"); break; | ||||
|             } | ||||
|         } | ||||
|  |  | |||
|  | @ -9,20 +9,45 @@ | |||
| 
 | ||||
| // TOP
 | ||||
| 
 | ||||
| struct Cursor_Data{ | ||||
| 	i32 pos; | ||||
| }; | ||||
| 
 | ||||
| enum Endline_Mode{ | ||||
| 	ENDLINE_RN_COMBINED, | ||||
| 	ENDLINE_RN_SEPARATE, | ||||
| 	ENDLINE_RN_SHOWALLR | ||||
| }; | ||||
| 
 | ||||
| struct Range{ | ||||
| 	union{ | ||||
| 		struct{ | ||||
| 			i32 smaller, larger; | ||||
| 		}; | ||||
| 		struct{ | ||||
| 			i32 start, end; | ||||
| 		}; | ||||
| 	}; | ||||
| 	bool32 swapped; | ||||
| }; | ||||
| 
 | ||||
| struct Edit_Step{ | ||||
|     String replaced; | ||||
|     Range range; | ||||
|     i32 cursor_pos; | ||||
|     bool32 can_merge; | ||||
| }; | ||||
| 
 | ||||
| struct Undo_Data{ | ||||
|     i32 str_size, str_redo, str_max; | ||||
|     u8 *strings; | ||||
|      | ||||
|     i32 edit_count, edit_redo, edit_max; | ||||
|     Edit_Step *edits; | ||||
| }; | ||||
| 
 | ||||
| struct Editing_File{ | ||||
|     i32 size, max_size; | ||||
|     u8 *data; | ||||
|      | ||||
|     Undo_Data undo; | ||||
|      | ||||
|     i32 line_count, line_max; | ||||
|     i32 *line_starts; | ||||
|      | ||||
|  | @ -31,7 +56,7 @@ struct Editing_File{ | |||
|     real32 *line_width; | ||||
|      | ||||
|     Endline_Mode endline_mode; | ||||
|     Cursor_Data cursor; | ||||
|     i32 cursor_pos; | ||||
|     bool32 is_dummy; | ||||
|      | ||||
|     char source_path_[256]; | ||||
|  | @ -215,18 +240,6 @@ struct File_View{ | |||
|     Text_Effect paste_effect; | ||||
| }; | ||||
| 
 | ||||
| struct Range{ | ||||
| 	union{ | ||||
| 		struct{ | ||||
| 			i32 smaller, larger; | ||||
| 		}; | ||||
| 		struct{ | ||||
| 			i32 start, end; | ||||
| 		}; | ||||
| 	}; | ||||
| 	bool32 swapped; | ||||
| }; | ||||
| 
 | ||||
| inline File_View* | ||||
| view_to_file_view(View *view){ | ||||
|     File_View* result = 0; | ||||
|  | @ -388,6 +401,8 @@ enum File_Bubble_Type{ | |||
|     BUBBLE_WIDTHS, | ||||
|     BUBBLE_WRAPS, | ||||
|     BUBBLE_TOKENS, | ||||
|     BUBBLE_UNDO_STRING, | ||||
|     BUBBLE_UNDO, | ||||
|     //
 | ||||
|     FILE_BUBBLE_TYPE_END, | ||||
| }; | ||||
|  | @ -689,7 +704,7 @@ view_measure_wraps(General_Memory *general, File_View *view){ | |||
| 
 | ||||
| internal void | ||||
| buffer_create_from_string(General_Memory *general, Editing_File *file, u8 *filename, Font *font, String val){ | ||||
|     i32 request_size = LargeRoundUp(1+val.size*2, Kbytes(256)); | ||||
|     i32 request_size = LargeRoundUp(1+val.size*2, Kbytes(64)); | ||||
|     u8 *data = (u8*)general_memory_allocate(general, request_size, BUBBLE_BUFFER); | ||||
|      | ||||
|     // TODO(allen): if we didn't get the memory what is going on?
 | ||||
|  | @ -713,6 +728,14 @@ buffer_create_from_string(General_Memory *general, Editing_File *file, u8 *filen | |||
|     buffer_measure_starts(general, file); | ||||
|     buffer_measure_widths(general, file, font); | ||||
|     file->font = font; | ||||
| 
 | ||||
|     file->undo.str_max = request_size; | ||||
|     file->undo.str_redo = file->undo.str_max; | ||||
|     file->undo.strings = (u8*)general_memory_allocate(general, request_size, BUBBLE_UNDO_STRING); | ||||
|      | ||||
|     file->undo.edit_max = request_size / sizeof(Edit_Step); | ||||
|     file->undo.edit_redo = file->undo.edit_max; | ||||
|     file->undo.edits = (Edit_Step*)general_memory_allocate(general, request_size, BUBBLE_UNDO); | ||||
|      | ||||
|     if (!match(file->extension, make_lit_string("txt"))){ | ||||
|         file->tokens_exist = 1; | ||||
|  | @ -789,12 +812,6 @@ buffer_get_dummy(Editing_File *buffer){ | |||
| 	buffer->is_dummy = 1; | ||||
| } | ||||
| 
 | ||||
| enum Replace_Operation_Type{ | ||||
| 	REP_UNKNOWN, | ||||
| 	REP_REGULAR, | ||||
| 	REP_WHITESPACE | ||||
| }; | ||||
| 
 | ||||
| struct Shift_Information{ | ||||
| 	i32 start, end, amount; | ||||
| }; | ||||
|  | @ -955,7 +972,6 @@ buffer_relex_parallel(Mem_Options *mem, Editing_File *file, | |||
|         } | ||||
|          | ||||
|         if (!inline_lex){ | ||||
|             // TODO(allen): duplicated see REP_WHITESPACE
 | ||||
|             i32 end_token_i = cpp_get_end_token(&file->token_stack, end_i); | ||||
|             cpp_shift_token_starts(&file->token_stack, end_token_i, amount); | ||||
|             --end_token_i; | ||||
|  | @ -997,73 +1013,171 @@ buffer_grow_as_needed(General_Memory *general, Editing_File *file, i32 additiona | |||
|     return result; | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
| buffer_grow_undo_string(General_Memory *general, Editing_File *file, i32 extra_size){ | ||||
|     i32 old_max = file->undo.str_max; | ||||
|     u8 *old_str = file->undo.strings; | ||||
|     i32 redo_size = old_max - file->undo.str_redo; | ||||
|     i32 new_max = old_max*2 + extra_size; | ||||
|     u8 *new_str = (u8*) | ||||
|         general_memory_allocate(general, new_max, BUBBLE_UNDO_STRING); | ||||
|     i32 new_redo = new_max - redo_size; | ||||
|      | ||||
|     memcpy(new_str, old_str, file->undo.str_size); | ||||
|     memcpy(new_str + new_redo, old_str + file->undo.str_redo, redo_size); | ||||
|      | ||||
|     general_memory_free(general, old_str); | ||||
|      | ||||
|     file->undo.strings = new_str; | ||||
|     file->undo.str_max = new_max; | ||||
|     file->undo.str_redo = new_redo; | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
| buffer_grow_undo_edits(General_Memory *general, Editing_File *file){ | ||||
|     i32 old_max = file->undo.edit_max; | ||||
|     Edit_Step *old_eds = file->undo.edits; | ||||
|     i32 redo_size = old_max - file->undo.edit_redo; | ||||
|     i32 new_max = old_max*2 + 2; | ||||
|     Edit_Step *new_eds = (Edit_Step*) | ||||
|         general_memory_allocate(general, new_max*sizeof(Edit_Step), BUBBLE_UNDO); | ||||
|     i32 new_redo = new_max - redo_size; | ||||
|      | ||||
|     memcpy(new_eds, old_eds, file->undo.edit_count*sizeof(Edit_Step)); | ||||
|     memcpy(new_eds + new_redo, old_eds, redo_size*sizeof(Edit_Step)); | ||||
|      | ||||
|     general_memory_free(general, old_eds); | ||||
|      | ||||
|     file->undo.edits = new_eds; | ||||
|     file->undo.edit_max = new_max; | ||||
|     file->undo.edit_redo = new_redo; | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
| buffer_post_undo(General_Memory *general, Editing_File *file, | ||||
|                  i32 start, i32 end, i32 str_len, bool32 do_merge, bool32 can_merge, | ||||
|                  bool32 clear_redo){ | ||||
|     String replaced = make_string((char*)file->data + start, end - start); | ||||
| 
 | ||||
|     if (clear_redo){ | ||||
|         file->undo.str_redo = file->undo.str_max; | ||||
|         file->undo.edit_redo = file->undo.edit_max; | ||||
|     } | ||||
|      | ||||
|     if (file->undo.str_redo < file->undo.str_size + replaced.size) | ||||
|         buffer_grow_undo_string(general, file, replaced.size); | ||||
|      | ||||
|     Edit_Step edit; | ||||
|     edit.replaced = make_string((char*)file->undo.strings + file->undo.str_size, replaced.size); | ||||
|     file->undo.str_size += replaced.size; | ||||
|     copy(&edit.replaced, replaced); | ||||
|     edit.range = {start, start + str_len, 0}; | ||||
|     edit.cursor_pos = file->cursor_pos; | ||||
|     edit.can_merge = can_merge; | ||||
|      | ||||
|     bool32 did_merge = 0; | ||||
|     if (do_merge && file->undo.edit_count > 0){ | ||||
|         Edit_Step prev = file->undo.edits[file->undo.edit_count-1]; | ||||
|         if (prev.can_merge && edit.replaced.size == 0 && prev.replaced.size == 0){ | ||||
|             if (prev.range.end == edit.range.start){ | ||||
|                 did_merge = 1; | ||||
|                 edit.range.start = prev.range.start; | ||||
|                 edit.cursor_pos = prev.cursor_pos; | ||||
|             } | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     if (did_merge){ | ||||
|         file->undo.edits[file->undo.edit_count-1] = edit; | ||||
|     } | ||||
|     else{ | ||||
|         if (file->undo.edit_redo <= file->undo.edit_count) | ||||
|             buffer_grow_undo_edits(general, file); | ||||
|         file->undo.edits[file->undo.edit_count++] = edit; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
| buffer_post_redo(General_Memory *general, Editing_File *file, | ||||
|                  i32 start, i32 end, i32 str_len){ | ||||
|     String replaced = make_string((char*)file->data + start, end - start); | ||||
|      | ||||
|     if (file->undo.str_redo - replaced.size < file->undo.str_size) | ||||
|         buffer_grow_undo_string(general, file, replaced.size); | ||||
|      | ||||
|     file->undo.str_redo -= replaced.size; | ||||
|     TentativeAssert(file->undo.str_redo >= file->undo.str_size); | ||||
|      | ||||
|     Edit_Step edit; | ||||
|     edit.replaced = make_string((char*)file->undo.strings + file->undo.str_redo, replaced.size); | ||||
|     copy(&edit.replaced, replaced); | ||||
|     edit.range = {start, start + str_len, 0}; | ||||
|     edit.cursor_pos = file->cursor_pos; | ||||
|      | ||||
|     if (file->undo.edit_redo <= file->undo.edit_count) | ||||
|         buffer_grow_undo_edits(general, file); | ||||
|     --file->undo.edit_redo; | ||||
|     file->undo.edits[file->undo.edit_redo] = edit; | ||||
| } | ||||
| 
 | ||||
| inline i32 | ||||
| buffer_text_replace(General_Memory *general, Editing_File *file, | ||||
|                     i32 start, i32 end, u8 *str, i32 str_len){ | ||||
| 	i32 shift_amount = (str_len - (end - start)); | ||||
|      | ||||
|     buffer_grow_as_needed(general, file, shift_amount); | ||||
| 	Assert(shift_amount + file->size < file->max_size); | ||||
| 	 | ||||
|     i32 size = file->size; | ||||
|     u8 *data = (u8*)file->data; | ||||
|     memmove(data + end + shift_amount, data + end, size - end); | ||||
|     file->size += shift_amount; | ||||
|      | ||||
|     memcpy(data + start, str, str_len); | ||||
|      | ||||
|     return shift_amount; | ||||
| } | ||||
| 
 | ||||
| // TODO(allen): Proper strings?
 | ||||
| internal Shift_Information | ||||
| buffer_replace_range(Mem_Options *mem, Editing_File *file, | ||||
|                      i32 start, i32 end, u8 *str, i32 str_len, | ||||
| 					 Replace_Operation_Type op_type = REP_UNKNOWN){ | ||||
|                      i32 save_undo = 1){ | ||||
|     ProfileMomentFunction(); | ||||
|     General_Memory *general = &mem->general; | ||||
|      | ||||
| 	Shift_Information shift = {}; | ||||
| 	shift.start = start; | ||||
| 	shift.end = end; | ||||
| 	shift.amount = (str_len - (end - start)); | ||||
| 	 | ||||
|     // TODO(allen): Quickly figure out which op type is appropriate?
 | ||||
|     // Or just assume REGULAR, as that is always correct?
 | ||||
|      | ||||
|     buffer_grow_as_needed(general, file, shift.amount); | ||||
| 	Assert(shift.amount + file->size < file->max_size); | ||||
| 	 | ||||
|     if (file->still_lexing){ | ||||
|     if (file->still_lexing) | ||||
|         system_cancel_job(BACKGROUND_THREADS, file->lex_job); | ||||
|     } | ||||
|      | ||||
|     file->last_4ed_edit_time = system_get_now(); | ||||
|      | ||||
|     i32 size = file->size; | ||||
|     u8 *data = (u8*)file->data; | ||||
|     memmove(data + shift.end + shift.amount, data + shift.end, size - end); | ||||
|     file->size += shift.amount; | ||||
|      | ||||
|     memcpy(data + start, str, str_len); | ||||
|      | ||||
|     if (file->tokens_exist){ | ||||
|         switch (op_type){ | ||||
|         case REP_UNKNOWN: | ||||
|         case REP_REGULAR: | ||||
|         { | ||||
|             buffer_relex_parallel(mem, file, start, end, shift.amount); | ||||
|         }break; | ||||
|          | ||||
|         case REP_WHITESPACE: | ||||
|         { | ||||
|             // TODO(allen): duplicated see buffer_relex_parallel
 | ||||
|             i32 end_token_i = cpp_get_end_token(&file->token_stack, end); | ||||
|             cpp_shift_token_starts(&file->token_stack, end_token_i, shift.amount); | ||||
|             --end_token_i; | ||||
|             if (end_token_i >= 0){ | ||||
|                 Cpp_Token *token = file->token_stack.tokens + end_token_i; | ||||
|                 if (token->start < end && token->start + token->size > end){ | ||||
|                     token->size += shift.amount; | ||||
|                 } | ||||
|             } | ||||
|         }break; | ||||
|         } | ||||
|     General_Memory *general = &mem->general; | ||||
|     if (save_undo){ | ||||
|         bool32 can_merge = 0, do_merge = 0; | ||||
|         if (str_len == 1 && char_is_alpha_numeric(*str)) can_merge = 1; | ||||
|         if (str_len == 1 && (can_merge || char_is_whitespace(*str))) do_merge = 1; | ||||
|         buffer_post_undo(general, file, start, end, str_len, do_merge, can_merge, save_undo == 1); | ||||
|     } | ||||
|      | ||||
|     i32 line_start = buffer_get_line_index(file, shift.start); | ||||
|     i32 line_end = buffer_get_line_index(file, shift.end); | ||||
|     i32 shift_amount = buffer_text_replace(general, file, start, end, str, str_len); | ||||
|      | ||||
|     if (file->tokens_exist) | ||||
|         buffer_relex_parallel(mem, file, start, end, shift_amount); | ||||
|      | ||||
|     i32 line_start = buffer_get_line_index(file, start); | ||||
|     i32 line_end = buffer_get_line_index(file, end); | ||||
|     i32 replaced_line_count = line_end - line_start; | ||||
|     i32 new_line_count = buffer_count_newlines(file, shift.start, shift.start+str_len); | ||||
|     i32 new_line_count = buffer_count_newlines(file, start, start+str_len); | ||||
|     i32 line_shift =  new_line_count - replaced_line_count; | ||||
|      | ||||
|     buffer_remeasure_starts(general, file, line_start, line_end, line_shift, shift.amount); | ||||
|     buffer_remeasure_starts(general, file, line_start, line_end, line_shift, shift_amount); | ||||
|      | ||||
|     // TODO(allen): Can we "remeasure" widths now!?
 | ||||
|     buffer_measure_widths(general, file, file->font); | ||||
|      | ||||
|     Shift_Information shift; | ||||
|     shift.start = start; | ||||
|     shift.end = end; | ||||
|     shift.amount = shift_amount; | ||||
| 	return shift; | ||||
| } | ||||
| 
 | ||||
|  | @ -1490,7 +1604,7 @@ view_set_file(File_View *view, Editing_File *file, Style *style){ | |||
|     view_measure_wraps(general, view); | ||||
|      | ||||
|     view->cursor = {}; | ||||
|     view->cursor = view_compute_cursor_from_pos(view, file->cursor.pos); | ||||
|     view->cursor = view_compute_cursor_from_pos(view, file->cursor_pos); | ||||
|      | ||||
|     real32 cursor_x, cursor_y; | ||||
|     real32 w, h; | ||||
|  | @ -1555,7 +1669,7 @@ inline void | |||
| view_cursor_move(File_View *view, View_Cursor_Data cursor){ | ||||
| 	view->cursor = cursor; | ||||
|     view->preferred_x = view_get_cursor_x(view); | ||||
| 	view->file->cursor.pos = view->cursor.pos; | ||||
| 	view->file->cursor_pos = view->cursor.pos; | ||||
|     view->show_temp_highlight = 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -1563,7 +1677,7 @@ inline void | |||
| view_cursor_move(File_View *view, i32 pos){ | ||||
| 	view->cursor = view_compute_cursor_from_pos(view, pos); | ||||
|     view->preferred_x = view_get_cursor_x(view); | ||||
| 	view->file->cursor.pos = view->cursor.pos; | ||||
| 	view->file->cursor_pos = view->cursor.pos; | ||||
|     view->show_temp_highlight = 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -1576,7 +1690,7 @@ view_cursor_move(File_View *view, real32 x, real32 y, bool32 round_down = 0){ | |||
|         view->cursor = view_compute_cursor_from_wrapped_xy(view, x, y, round_down); | ||||
|     } | ||||
|     view->preferred_x = view_get_cursor_x(view); | ||||
| 	view->file->cursor.pos = view->cursor.pos; | ||||
| 	view->file->cursor_pos = view->cursor.pos; | ||||
|     view->show_temp_highlight = 0; | ||||
| } | ||||
| 
 | ||||
|  | @ -1721,6 +1835,7 @@ clipboard_copy(General_Memory *general, Working_Set *working, u8 *data, Range ra | |||
| 	system_post_clipboard(*dest); | ||||
| } | ||||
| 
 | ||||
| #if 0 | ||||
| internal void | ||||
| view_endline_convert(Mem_Options *mem, File_View *view, | ||||
|                      Endline_Convert_Type rn_to, | ||||
|  | @ -1766,8 +1881,7 @@ view_endline_convert(Mem_Options *mem, File_View *view, | |||
| 				if (rn_to != ENDLINE_RN){ | ||||
| 					buffer_replace_range(mem, file, i, i+2, | ||||
| 										 eol_strings[rn_to].str, | ||||
| 										 eol_strings[rn_to].size, | ||||
| 										 REP_WHITESPACE); | ||||
| 										 eol_strings[rn_to].size); | ||||
| 					i32 shift = eol_strings[rn_to].size - 2; | ||||
| 					if (cursor >= i){ | ||||
| 						cursor += shift; | ||||
|  | @ -1785,8 +1899,7 @@ view_endline_convert(Mem_Options *mem, File_View *view, | |||
| 				if (r_to != ENDLINE_R){ | ||||
| 					buffer_replace_range(mem, file, i, i+1, | ||||
| 										 eol_strings[r_to].str, | ||||
| 										 eol_strings[r_to].size, | ||||
| 										 REP_WHITESPACE); | ||||
| 										 eol_strings[r_to].size); | ||||
| 					i32 shift = eol_strings[r_to].size - 1; | ||||
| 					if (cursor >= i){ | ||||
| 						cursor += shift; | ||||
|  | @ -1803,8 +1916,7 @@ view_endline_convert(Mem_Options *mem, File_View *view, | |||
| 				if (n_to != ENDLINE_N){ | ||||
| 					buffer_replace_range(mem, file, i, i+1, | ||||
| 										 eol_strings[n_to].str, | ||||
| 										 eol_strings[n_to].size, | ||||
| 										 REP_WHITESPACE); | ||||
| 										 eol_strings[n_to].size); | ||||
| 					i32 shift = eol_strings[n_to].size - 1; | ||||
| 					if (cursor >= i){ | ||||
| 						cursor += shift; | ||||
|  | @ -1821,6 +1933,7 @@ view_endline_convert(Mem_Options *mem, File_View *view, | |||
| 	view->cursor = view_compute_cursor_from_pos(view, cursor); | ||||
| 	view->mark = mark; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| struct Indent_Definition{ | ||||
| 	i32 tabs, spaces; | ||||
|  | @ -1860,6 +1973,7 @@ buffer_find_hard_start(Editing_File *file, i32 line_start){ | |||
| 	return result; | ||||
| } | ||||
| 
 | ||||
| #if 0 | ||||
| // NOTE(allen): Assumes that whitespace_buffer has at least
 | ||||
| // indent.tabs*4 + indent.spaces bytes available.
 | ||||
| internal Shift_Information | ||||
|  | @ -1885,7 +1999,7 @@ buffer_set_indent_whitespace(Mem_Options *mem, Editing_File *file, | |||
|     if (leading_white.smaller < leading_white.larger){ | ||||
|         shift = buffer_replace_range(mem, file, | ||||
|                                      leading_white.smaller, leading_white.larger, | ||||
|                                      whitespace_buffer, i, REP_WHITESPACE); | ||||
|                                      whitespace_buffer, i); | ||||
|     } | ||||
|      | ||||
| 	return shift; | ||||
|  | @ -2005,7 +2119,9 @@ buffer_compute_nest_level_tokens(Editing_File *file, i32 pos, Nest_Level_Hint hi | |||
| 	} | ||||
| 	return result; | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| #if 0 | ||||
| internal void | ||||
| view_auto_tab(Mem_Options *mem, File_View *view, i32 start, i32 end){ | ||||
| 	Editing_File *file = view->file; | ||||
|  | @ -2258,6 +2374,7 @@ view_auto_tab(Mem_Options *mem, File_View *view, i32 start, i32 end){ | |||
| 	view_cursor_move(view, cursor); | ||||
| 	view->mark = pos_adjust_to_self(mark, data, file->size); | ||||
| } | ||||
| #endif | ||||
| 
 | ||||
| internal u32* | ||||
| style_get_color(Style *style, Cpp_Token token){ | ||||
|  | @ -2458,62 +2575,6 @@ step_file_view(Thread_Context *thread, View *view_, i32_Rect rect, | |||
|     return result; | ||||
| } | ||||
| 
 | ||||
| internal void | ||||
| file_view_intbar(Thread_Context *thread, Render_Target *target, | ||||
|                  Interactive_Bar *bar, File_View *view, | ||||
|                  Editing_File *file, Style *style){ | ||||
|     i32 w, h; | ||||
|     w = bar->rect.x1 - bar->rect.x0; | ||||
|     h = bar->rect.y1 - bar->rect.y0; | ||||
|     u32 back_color = bar->style.bar_color; | ||||
|     draw_rectangle(target, bar->rect, back_color); | ||||
|      | ||||
|     u32 base_color = bar->style.base_color; | ||||
|     intbar_draw_string(target, bar, file->live_name, base_color); | ||||
|     intbar_draw_string(target, bar, make_lit_string(" - "), base_color); | ||||
|      | ||||
|     char line_number_space[30]; | ||||
|     String line_number = make_string(line_number_space, 0, 30); | ||||
|     append(&line_number, "L#"); | ||||
|     append_int_to_str(view->cursor.line, &line_number); | ||||
|      | ||||
|     intbar_draw_string(target, bar, line_number, base_color); | ||||
|      | ||||
|     switch (view->state){ | ||||
|     case FVIEW_STATE_EDIT: | ||||
|     { | ||||
|         if (file->last_4ed_write_time != file->last_sys_write_time){ | ||||
|             persist String out_of_sync = make_lit_string(" BEHIND OS"); | ||||
|             intbar_draw_string(target, bar, out_of_sync, bar->style.pop2_color); | ||||
|         } | ||||
|         else if (file->last_4ed_edit_time > file->last_sys_write_time){ | ||||
|             persist String out_of_sync = make_lit_string(" *"); | ||||
|             intbar_draw_string(target, bar, out_of_sync, bar->style.pop2_color); | ||||
|         } | ||||
|     }break; | ||||
|      | ||||
|     case FVIEW_STATE_SEARCH: | ||||
|     { | ||||
|         persist String search_str = make_lit_string(" I-Search: "); | ||||
|         persist String rsearch_str = make_lit_string(" Reverse-I-Search: "); | ||||
|         if (view->isearch.reverse){ | ||||
|             intbar_draw_string(target, bar, rsearch_str, bar->style.pop1_color); | ||||
|         } | ||||
|         else{ | ||||
|             intbar_draw_string(target, bar, search_str, bar->style.pop1_color); | ||||
|         } | ||||
|         intbar_draw_string(target, bar, view->isearch.str, bar->style.base_color); | ||||
|     }break; | ||||
|      | ||||
|     case FVIEW_STATE_GOTO_LINE: | ||||
|     { | ||||
|         persist String gotoline_str = make_lit_string(" Goto Line: "); | ||||
|         intbar_draw_string(target, bar, gotoline_str, bar->style.pop1_color); | ||||
|         intbar_draw_string(target, bar, view->isearch.str, bar->style.base_color); | ||||
|     }break; | ||||
|     } | ||||
| } | ||||
| 
 | ||||
| internal i32 | ||||
| draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_active, | ||||
|                Render_Target *target){ | ||||
|  | @ -2601,7 +2662,7 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act | |||
|             real32 fade_amount = 0.f; | ||||
|             if (view->paste_effect.tick_down > 0 && | ||||
|                 view->paste_effect.start <= i && i < view->paste_effect.end){ | ||||
|                 fade_color = style->main.paste_color; | ||||
|                 fade_color = view->paste_effect.color; | ||||
|                 fade_amount = (real32)(view->paste_effect.tick_down) / view->paste_effect.tick_max; | ||||
|             } | ||||
|              | ||||
|  | @ -2765,7 +2826,69 @@ draw_file_view(Thread_Context *thread, View *view_, i32_Rect rect, bool32 is_act | |||
|         } | ||||
|     } | ||||
|      | ||||
|     file_view_intbar(thread, target, &bar, view, file, style); | ||||
|     { | ||||
|         Interactive_Bar bar2; | ||||
|         bar2.style = style->main.file_info_style; | ||||
|         bar2.font = style->font; | ||||
|         bar2.pos_x = (real32)rect.x0; | ||||
|         bar2.pos_y = (real32)rect.y0 + 3; | ||||
|         bar2.text_shift_y = 0; | ||||
|         bar2.text_shift_x = 0; | ||||
|         bar2.rect = rect; | ||||
|         bar2.rect.y1 = bar2.rect.y0 + font->height + 2; | ||||
|          | ||||
|         switch (view->state){ | ||||
|         case FVIEW_STATE_SEARCH: | ||||
|         { | ||||
|             draw_rectangle(target, bar2.rect, bar2.style.bar_active_color); | ||||
|              | ||||
|             persist String search_str = make_lit_string("I-Search: "); | ||||
|             persist String rsearch_str = make_lit_string("Reverse-I-Search: "); | ||||
|             if (view->isearch.reverse){ | ||||
|                 intbar_draw_string(target, &bar2, rsearch_str, bar2.style.pop1_color); | ||||
|             } | ||||
|             else{ | ||||
|                 intbar_draw_string(target, &bar2, search_str, bar2.style.pop1_color); | ||||
|             } | ||||
|             intbar_draw_string(target, &bar2, view->isearch.str, bar2.style.base_color); | ||||
|         }break; | ||||
|          | ||||
|         case FVIEW_STATE_GOTO_LINE: | ||||
|         { | ||||
|             draw_rectangle(target, bar2.rect, bar2.style.bar_active_color); | ||||
|              | ||||
|             persist String gotoline_str = make_lit_string("Goto Line: "); | ||||
|             intbar_draw_string(target, &bar2, gotoline_str, bar2.style.pop1_color); | ||||
|             intbar_draw_string(target, &bar2, view->isearch.str, bar2.style.base_color); | ||||
|         }break; | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     { | ||||
|         u32 back_color = bar.style.bar_color; | ||||
|         draw_rectangle(target, bar.rect, back_color); | ||||
|          | ||||
|         u32 base_color = bar.style.base_color; | ||||
|         intbar_draw_string(target, &bar, file->live_name, base_color); | ||||
|         intbar_draw_string(target, &bar, make_lit_string(" - "), base_color); | ||||
|          | ||||
|         char line_number_space[30]; | ||||
|         String line_number = make_string(line_number_space, 0, 30); | ||||
|         append(&line_number, "L#"); | ||||
|         append_int_to_str(view->cursor.line, &line_number); | ||||
|          | ||||
|         intbar_draw_string(target, &bar, line_number, base_color); | ||||
|          | ||||
|         if (file->last_4ed_write_time != file->last_sys_write_time){ | ||||
|             persist String out_of_sync = make_lit_string(" BEHIND OS"); | ||||
|             intbar_draw_string(target, &bar, out_of_sync, bar.style.pop2_color); | ||||
|         } | ||||
|         else if (file->last_4ed_edit_time > file->last_sys_write_time){ | ||||
|             persist String out_of_sync = make_lit_string(" *"); | ||||
|             intbar_draw_string(target, &bar, out_of_sync, bar.style.pop2_color); | ||||
|         } | ||||
|     } | ||||
|      | ||||
|     return 0; | ||||
| } | ||||
| 
 | ||||
|  |  | |||
							
								
								
									
										264
									
								
								4ed_style.cpp
								
								
								
								
							
							
						
						
									
										264
									
								
								4ed_style.cpp
								
								
								
								
							|  | @ -118,11 +118,97 @@ struct Style_File_Format_v3{ | |||
|     Style_Main_Data_v3 main; | ||||
| }; | ||||
| 
 | ||||
| struct Style_Main_Data{ | ||||
|     u32 back_color; | ||||
| 	u32 margin_color; | ||||
| 	u32 margin_hover_color; | ||||
| 	u32 margin_active_color; | ||||
| 	u32 cursor_color; | ||||
| 	u32 at_cursor_color; | ||||
| 	u32 highlight_color; | ||||
| 	u32 at_highlight_color; | ||||
| 	u32 mark_color; | ||||
| 	u32 default_color; | ||||
| 	u32 comment_color; | ||||
| 	u32 keyword_color; | ||||
| 	u32 str_constant_color; | ||||
| 	u32 char_constant_color; | ||||
| 	u32 int_constant_color; | ||||
| 	u32 float_constant_color; | ||||
| 	u32 bool_constant_color; | ||||
|     u32 preproc_color; | ||||
| 	u32 include_color; | ||||
| 	u32 special_character_color; | ||||
| 	u32 highlight_junk_color; | ||||
| 	u32 highlight_white_color; | ||||
|     u32 paste_color; | ||||
|     u32 undo_color; | ||||
|     u32 next_undo_color; | ||||
|     Interactive_Style file_info_style; | ||||
| }; | ||||
| 
 | ||||
| struct Style_File_Format_v4{ | ||||
|     i32 name_size; | ||||
|     char name[24]; | ||||
|     i32 font_name_size; | ||||
|     char font_name[24]; | ||||
|     Style_Main_Data main; | ||||
| }; | ||||
| 
 | ||||
| enum Style_Color_Tag{ | ||||
|     STAG_BAR_COLOR, | ||||
|     STAG_BAR_ACTIVE_COLOR, | ||||
|     STAG_BAR_BASE_COLOR, | ||||
|     STAG_BAR_POP1_COLOR, | ||||
|     STAG_BAR_POP2_COLOR, | ||||
|     STAG_BACK_COLOR, | ||||
| 	STAG_MARGIN_COLOR, | ||||
| 	STAG_MARGIN_HOVER_COLOR, | ||||
| 	STAG_MARGIN_ACTIVE_COLOR, | ||||
| 	STAG_CURSOR_COLOR, | ||||
| 	STAG_AT_CURSOR_COLOR, | ||||
| 	STAG_HIGHLIGHT_COLOR, | ||||
| 	STAG_AT_HIGHLIGHT_COLOR, | ||||
| 	STAG_MARK_COLOR, | ||||
| 	STAG_DEFAULT_COLOR, | ||||
| 	STAG_COMMENT_COLOR, | ||||
| 	STAG_KEYWORD_COLOR, | ||||
| 	STAG_STR_CONSTANT_COLOR, | ||||
| 	STAG_CHAR_CONSTANT_COLOR, | ||||
| 	STAG_INT_CONSTANT_COLOR, | ||||
| 	STAG_FLOAT_CONSTANT_COLOR, | ||||
| 	STAG_BOOL_CONSTANT_COLOR, | ||||
|     STAG_PREPROC_COLOR, | ||||
| 	STAG_INCLUDE_COLOR, | ||||
| 	STAG_SPECIAL_CHARACTER_COLOR, | ||||
| 	STAG_HIGHLIGHT_JUNK_COLOR, | ||||
| 	STAG_HIGHLIGHT_WHITE_COLOR, | ||||
|     STAG_PASTE_COLOR, | ||||
|     STAG_UNDO_COLOR, | ||||
|     STAG_NEXT_UNDO_COLOR, | ||||
|     // never below this
 | ||||
|     STAG_COUNT | ||||
| }; | ||||
| 
 | ||||
| struct Style_Color_Specifier{ | ||||
|     u32 tag; | ||||
|     u32 color; | ||||
| }; | ||||
| 
 | ||||
| struct Style_File_Format{ | ||||
|     i32 name_size; | ||||
|     char name[24]; | ||||
|     i32 font_name_size; | ||||
|     char font_name[24]; | ||||
|      | ||||
|     i32 color_specifier_count; | ||||
| }; | ||||
| 
 | ||||
| struct Style{ | ||||
|     char name_[24]; | ||||
|     String name; | ||||
| 	Font *font; | ||||
|     Style_Main_Data_v3 main; | ||||
|     Style_Main_Data main; | ||||
|     bool32 font_changed; | ||||
| }; | ||||
| 
 | ||||
|  | @ -232,30 +318,148 @@ style_form_convert(Style_File_Format_v3 *o, Style_File_Format_v2 *i){ | |||
|     o->main.file_info_style = i->main.file_info_style; | ||||
| } | ||||
| 
 | ||||
| typedef Style_Main_Data_v3 Style_Main_Data; | ||||
| typedef Style_File_Format_v3 Style_File_Format; | ||||
| 
 | ||||
| internal void | ||||
| style_form_convert(Style_File_Format_v4 *o, Style_File_Format_v3 *i){ | ||||
|     o->name_size = i->name_size; | ||||
|     memcpy(o->name, i->name, i->name_size); | ||||
|     o->font_name_size = i->font_name_size; | ||||
|     memcpy(o->font_name, i->font_name, i->font_name_size); | ||||
|      | ||||
|     o->main.back_color = i->main.back_color; | ||||
|     o->main.margin_color = i->main.margin_color; | ||||
|     o->main.margin_hover_color = i->main.margin_hover_color; | ||||
|     o->main.margin_active_color = i->main.margin_active_color; | ||||
|      | ||||
|     o->main.cursor_color = i->main.cursor_color; | ||||
|     o->main.at_cursor_color = i->main.at_cursor_color; | ||||
|     o->main.highlight_color = i->main.highlight_color; | ||||
|     o->main.at_highlight_color = i->main.at_highlight_color; | ||||
|     o->main.mark_color = i->main.mark_color; | ||||
|     o->main.default_color = i->main.default_color; | ||||
|     o->main.comment_color = i->main.comment_color; | ||||
|     o->main.keyword_color = i->main.keyword_color; | ||||
|     o->main.str_constant_color = i->main.str_constant_color; | ||||
|     o->main.char_constant_color = i->main.char_constant_color; | ||||
|     o->main.int_constant_color = i->main.int_constant_color; | ||||
|     o->main.float_constant_color = i->main.float_constant_color; | ||||
|     o->main.bool_constant_color = i->main.bool_constant_color; | ||||
|     o->main.include_color = i->main.include_color; | ||||
|     o->main.preproc_color = i->main.preproc_color; | ||||
|     o->main.special_character_color = i->main.special_character_color; | ||||
|     o->main.highlight_junk_color = i->main.highlight_junk_color; | ||||
|     o->main.highlight_white_color = i->main.highlight_white_color; | ||||
|     o->main.paste_color = i->main.paste_color; | ||||
|     o->main.undo_color = i->main.paste_color ^ 0x00FFFFFF; | ||||
|     o->main.next_undo_color = i->main.paste_color ^ 0x00FFFFFF; | ||||
|     o->main.file_info_style = i->main.file_info_style; | ||||
|     o->main.file_info_style.bar_active_color = i->main.file_info_style.bar_color; | ||||
| } | ||||
| 
 | ||||
| inline u32* | ||||
| style_index_by_tag(Style *s, u32 tag){ | ||||
|     u32 *result = 0; | ||||
|     switch (tag){ | ||||
|     case STAG_BAR_COLOR: result = &s->main.file_info_style.bar_color; break; | ||||
|     case STAG_BAR_ACTIVE_COLOR: result = &s->main.file_info_style.bar_active_color; break; | ||||
|     case STAG_BAR_BASE_COLOR: result = &s->main.file_info_style.base_color; break; | ||||
|     case STAG_BAR_POP1_COLOR: result = &s->main.file_info_style.pop1_color; break; | ||||
|     case STAG_BAR_POP2_COLOR: result = &s->main.file_info_style.pop2_color; break; | ||||
|              | ||||
|     case STAG_BACK_COLOR: result = &s->main.back_color; break; | ||||
|     case STAG_MARGIN_COLOR: result = &s->main.margin_color; break; | ||||
|     case STAG_MARGIN_HOVER_COLOR: result = &s->main.margin_hover_color; break; | ||||
|     case STAG_MARGIN_ACTIVE_COLOR: result = &s->main.margin_active_color; break; | ||||
|              | ||||
|     case STAG_CURSOR_COLOR: result = &s->main.cursor_color; break; | ||||
|     case STAG_AT_CURSOR_COLOR: result = &s->main.at_cursor_color; break; | ||||
|     case STAG_HIGHLIGHT_COLOR: result = &s->main.highlight_color; break; | ||||
|     case STAG_AT_HIGHLIGHT_COLOR: result = &s->main.at_highlight_color; break; | ||||
|     case STAG_MARK_COLOR: result = &s->main.mark_color; break; | ||||
|          | ||||
|     case STAG_DEFAULT_COLOR: result = &s->main.default_color; break; | ||||
|     case STAG_COMMENT_COLOR: result = &s->main.comment_color; break; | ||||
|     case STAG_KEYWORD_COLOR: result = &s->main.keyword_color; break; | ||||
|     case STAG_STR_CONSTANT_COLOR: result = &s->main.str_constant_color; break; | ||||
|     case STAG_CHAR_CONSTANT_COLOR: result = &s->main.char_constant_color; break; | ||||
|     case STAG_INT_CONSTANT_COLOR: result = &s->main.int_constant_color; break; | ||||
|     case STAG_FLOAT_CONSTANT_COLOR: result = &s->main.float_constant_color; break; | ||||
|     case STAG_BOOL_CONSTANT_COLOR: result = &s->main.bool_constant_color; break; | ||||
|          | ||||
|     case STAG_PREPROC_COLOR: result = &s->main.preproc_color; break; | ||||
|     case STAG_INCLUDE_COLOR: result = &s->main.include_color; break; | ||||
|          | ||||
|     case STAG_SPECIAL_CHARACTER_COLOR: result = &s->main.special_character_color; break; | ||||
|          | ||||
|     case STAG_HIGHLIGHT_JUNK_COLOR: result = &s->main.highlight_junk_color; break; | ||||
|     case STAG_HIGHLIGHT_WHITE_COLOR: result = &s->main.highlight_white_color; break; | ||||
|          | ||||
|     case STAG_PASTE_COLOR: result = &s->main.paste_color; break; | ||||
|     case STAG_UNDO_COLOR: result = &s->main.undo_color; break; | ||||
|     case STAG_NEXT_UNDO_COLOR: result = &s->main.next_undo_color; break; | ||||
|     } | ||||
|     return result; | ||||
| } | ||||
| 
 | ||||
| internal Style_File_Format* | ||||
| style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format *style){ | ||||
|     out->name = make_string(out->name_, 0, ArrayCount(out->name_) - 1); | ||||
|     out->name_[ArrayCount(out->name_) - 1] = 0; | ||||
|     copy(&out->name, style->name); | ||||
|     out->font = font_set_extract(fonts, style->font_name, style->font_name_size); | ||||
| 
 | ||||
|     i32 spec_count = style->color_specifier_count; | ||||
|     Style_Color_Specifier *spec = (Style_Color_Specifier*)(style + 1); | ||||
|      | ||||
|     for (i32 i = 0; i < spec_count; ++i, ++spec){ | ||||
|         u32 *color = style_index_by_tag(out, spec->tag); | ||||
|         if (color) *color = spec->color; | ||||
|     } | ||||
|      | ||||
| #if 0 // TODO(allen): when new colors are introduced, derive them here.
 | ||||
|     for (u32 i = 0; i < STAG_COUNT; ++i){ | ||||
|         u32 *color = style_index_by_tag(out, i); | ||||
|         if (color && (*color >> 24) == 0){ | ||||
|             switch (i){ | ||||
|             } | ||||
|         } | ||||
|     } | ||||
| #endif | ||||
|      | ||||
|     return (Style_File_Format*)(spec); | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
| style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v4 *style){ | ||||
|     out->name = make_string(out->name_, 0, ArrayCount(out->name_) - 1); | ||||
|     out->name_[ArrayCount(out->name_) - 1] = 0; | ||||
|     copy(&out->name, style->name); | ||||
|     out->font = font_set_extract(fonts, style->font_name, style->font_name_size); | ||||
|     out->main = style->main; | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
| style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v1 *style){ | ||||
|     Style_File_Format_v2 form2; | ||||
|     Style_File_Format form; | ||||
|     Style_File_Format_v3 form3; | ||||
|     Style_File_Format_v4 form; | ||||
|     style_form_convert(&form2, style); | ||||
|     style_form_convert(&form, &form2); | ||||
|     style_form_convert(&form3, &form2); | ||||
|     style_form_convert(&form, &form3); | ||||
|     style_format_for_use(fonts, out, &form); | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
| style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v2 *style){ | ||||
|     Style_File_Format form; | ||||
|     Style_File_Format_v3 form3; | ||||
|     Style_File_Format_v4 form; | ||||
|     style_form_convert(&form3, style); | ||||
|     style_form_convert(&form, &form3); | ||||
|     style_format_for_use(fonts, out, &form); | ||||
| } | ||||
| 
 | ||||
| inline void | ||||
| style_format_for_use(Font_Set *fonts, Style *out, Style_File_Format_v3 *style){ | ||||
|     Style_File_Format_v4 form; | ||||
|     style_form_convert(&form, style); | ||||
|     style_format_for_use(fonts, out, &form); | ||||
| } | ||||
|  | @ -304,6 +508,7 @@ style_library_import(u8 *filename, Font_Set *fonts, Style *out, i32 max, | |||
|                 style_format_for_use(fonts, out++, in++); | ||||
|             } | ||||
|         }break; | ||||
|          | ||||
|         case 3: | ||||
|         { | ||||
|             Style_File_Format_v3 *in = (Style_File_Format_v3*)cursor; | ||||
|  | @ -311,6 +516,14 @@ style_library_import(u8 *filename, Font_Set *fonts, Style *out, i32 max, | |||
|                 style_format_for_use(fonts, out++, in++); | ||||
|             } | ||||
|         }break; | ||||
|         case 4: | ||||
|         { | ||||
|             Style_File_Format *in = (Style_File_Format*)cursor; | ||||
|             for (i32 i = 0; i < to_read; ++i){ | ||||
|                 in = style_format_for_use(fonts, out++, in); | ||||
|             } | ||||
|         }break; | ||||
|          | ||||
|         default: result = 0; break; | ||||
|         } | ||||
|          | ||||
|  | @ -345,21 +558,34 @@ style_library_add(Style_Library *library, Style *style){ | |||
|     return result; | ||||
| } | ||||
| 
 | ||||
| internal Style_File_Format | ||||
| style_format_for_file(Style *style){ | ||||
|     Style_File_Format result; | ||||
| internal Style_File_Format* | ||||
| style_format_for_file(Style *style, Style_File_Format *out){ | ||||
|     Font *font = style->font; | ||||
|     result.name_size = style->name.size; | ||||
|     memcpy(result.name, style->name.str, ArrayCount(result.name)); | ||||
|     result.font_name_size = font->name.size; | ||||
|     memcpy(result.font_name, font->name.str, ArrayCount(result.font_name)); | ||||
|     result.main = style->main; | ||||
|     return result; | ||||
|     out->name_size = style->name.size; | ||||
|     memcpy(out->name, style->name.str, ArrayCount(out->name)); | ||||
|     out->font_name_size = font->name.size; | ||||
|     memcpy(out->font_name, font->name.str, ArrayCount(out->font_name)); | ||||
|      | ||||
|     Style_Color_Specifier *spec = (Style_Color_Specifier*)(out + 1); | ||||
|     i32 count = 0; | ||||
|      | ||||
|     for (u32 i = 0; i < STAG_COUNT; ++i){ | ||||
|         u32 *color = style_index_by_tag(style, i); | ||||
|         if (color){ | ||||
|             spec->tag = i; | ||||
|             spec->color = *color; | ||||
|             ++count; | ||||
|             ++spec; | ||||
|         } | ||||
|     } | ||||
|     out->color_specifier_count = count; | ||||
|      | ||||
|     return (Style_File_Format*)spec; | ||||
| } | ||||
| 
 | ||||
| internal void | ||||
| style_library_export(u8 *filename, Style **styles, i32 count){ | ||||
|     i32 size = count*sizeof(Style_File_Format) + | ||||
|     i32 size = count*(sizeof(Style_File_Format) + STAG_COUNT*sizeof(Style_Color_Specifier)) + | ||||
|         sizeof(P4C_Page_Header) + sizeof(Style_Page_Header); | ||||
|     void *data = system_get_memory(size); | ||||
|     void *cursor = data; | ||||
|  | @ -373,7 +599,7 @@ style_library_export(u8 *filename, Style **styles, i32 count){ | |||
|      | ||||
|     { | ||||
|         Style_Page_Header *h = (Style_Page_Header*)cursor; | ||||
|         h->version = 1; | ||||
|         h->version = 4; | ||||
|         h->count = count; | ||||
|         cursor = h+1; | ||||
|     } | ||||
|  | @ -381,7 +607,7 @@ style_library_export(u8 *filename, Style **styles, i32 count){ | |||
|     Style_File_Format *out = (Style_File_Format*)cursor; | ||||
|     Style **in = styles; | ||||
|     for (i32 i = 0; i < count; ++i){ | ||||
|         *out++ = style_format_for_file(*in++); | ||||
|         out = style_format_for_file(*in++, out); | ||||
|     } | ||||
|     system_save_file(filename, data, size); | ||||
|     system_free_memory(data); | ||||
|  |  | |||
		Loading…
	
		Reference in New Issue
	
	 Allen Webster
						Allen Webster