Compare commits
35 Commits
fix_projec
...
master
Author | SHA1 | Date |
---|---|---|
PS | be632574e6 | |
PS | 46a0466ff4 | |
PS | 24f7f66a24 | |
PS | 001cf5fa57 | |
Peter Slattery | 2142ef2ce9 | |
PS | 120c6ceaad | |
PS | 5842d13294 | |
PS | 2c82233524 | |
Peter Slattery | 3f1c591196 | |
Peter Slattery | f1d6ac0e53 | |
Peter Slattery | e33bdffc7d | |
Peter Slattery | cba2574e8a | |
Peter Slattery | 58a4314177 | |
Peter Slattery | 8675d371a4 | |
Peter Slattery | 41d0d07b5c | |
Peter Slattery | 7f2a414182 | |
Peter Slattery | ad189e911a | |
PS | 24c8370f75 | |
PS | 5aebe18778 | |
PS | 18e608a152 | |
PS | ca075e7392 | |
PS | 22fa2794e7 | |
PS | e3ba01570a | |
PS | 8552305ecc | |
PS | 7aa033783c | |
PS | 0a03ea05f1 | |
PS | 80b780278a | |
PS | 2a35691111 | |
PS | 0d840d128e | |
PS | 832a7b4b80 | |
PS | 5bfb737720 | |
PS | 61a079b0ae | |
PS | 28da33cb6e | |
PS | 9d6067bd4c | |
Jack Punter | aa14f6c620 |
|
@ -1,3 +1,4 @@
|
||||||
build/
|
build/
|
||||||
current_dist*/
|
current_dist*/
|
||||||
distributions/
|
distributions/
|
||||||
|
build_stable/
|
||||||
|
|
|
@ -0,0 +1,26 @@
|
||||||
|
# TODO
|
||||||
|
|
||||||
|
PRIME DIRECTIVE: SIMPLIFY
|
||||||
|
|
||||||
|
## Necessary
|
||||||
|
[] figure out why the built version has a different font size than this one.
|
||||||
|
|
||||||
|
## Nice to Have
|
||||||
|
[] 4coder projects should have a startup script - so you can do things like add cl to the path
|
||||||
|
[] Look into removing *keyboard* buffer - seems like over long sessions, that could get out of hand
|
||||||
|
- good first step: print out the memory footprint of this buffer when we exit 4coder, just so we can see what it's taking up
|
||||||
|
[] multi cursor editing
|
||||||
|
|
||||||
|
[] yeet sheet
|
||||||
|
|
||||||
|
## Investigations
|
||||||
|
[] What are fade ranges? Do we need them?
|
||||||
|
|
||||||
|
# DONE
|
||||||
|
[x] matching curly brace highlight
|
||||||
|
[x] when buffers have the same filename, a short name is appended. I'd prefer to append the path relative to the project, and if the file is outside the project, append the full path.
|
||||||
|
[x] reload dirty files if there are no local edits to them automatically
|
||||||
|
[x] remove audio (search @Remove)
|
||||||
|
[x] backspace through entire filename in navigation strip at top
|
||||||
|
[x] fix project creation - this should just work out of the box
|
||||||
|
[x] remove automatic code layout for now
|
|
@ -19,13 +19,11 @@ string_from_file_name(Editing_File_Name *name){
|
||||||
internal void
|
internal void
|
||||||
file_edit_positions_set_cursor(File_Edit_Positions *edit_pos, i64 pos){
|
file_edit_positions_set_cursor(File_Edit_Positions *edit_pos, i64 pos){
|
||||||
edit_pos->cursor_pos = pos;
|
edit_pos->cursor_pos = pos;
|
||||||
edit_pos->last_set_type = EditPos_CursorSet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
file_edit_positions_set_scroll(File_Edit_Positions *edit_pos, Buffer_Scroll scroll){
|
file_edit_positions_set_scroll(File_Edit_Positions *edit_pos, Buffer_Scroll scroll){
|
||||||
edit_pos->scroll = scroll;
|
edit_pos->scroll = scroll;
|
||||||
edit_pos->last_set_type = EditPos_ScrollSet;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -124,13 +122,13 @@ internal b32
|
||||||
save_file_to_name(Thread_Context *tctx, Models *models, Editing_File *file, u8 *file_name){
|
save_file_to_name(Thread_Context *tctx, Models *models, Editing_File *file, u8 *file_name){
|
||||||
b32 result = false;
|
b32 result = false;
|
||||||
b32 using_actual_file_name = false;
|
b32 using_actual_file_name = false;
|
||||||
|
|
||||||
if (file_name == 0){
|
if (file_name == 0){
|
||||||
file_name_terminate(&file->canon);
|
file_name_terminate(&file->canon);
|
||||||
file_name = file->canon.name_space;
|
file_name = file->canon.name_space;
|
||||||
using_actual_file_name = true;
|
using_actual_file_name = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file_name != 0){
|
if (file_name != 0){
|
||||||
if (models->save_file != 0){
|
if (models->save_file != 0){
|
||||||
Application_Links app = {};
|
Application_Links app = {};
|
||||||
|
@ -138,12 +136,12 @@ save_file_to_name(Thread_Context *tctx, Models *models, Editing_File *file, u8 *
|
||||||
app.cmd_context = models;
|
app.cmd_context = models;
|
||||||
models->save_file(&app, file->id);
|
models->save_file(&app, file->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
Gap_Buffer *buffer = &file->state.buffer;
|
Gap_Buffer *buffer = &file->state.buffer;
|
||||||
b32 dos_write_mode = file->settings.dos_write_mode;
|
b32 dos_write_mode = file->settings.dos_write_mode;
|
||||||
|
|
||||||
Scratch_Block scratch(tctx);
|
Scratch_Block scratch(tctx);
|
||||||
|
|
||||||
if (!using_actual_file_name){
|
if (!using_actual_file_name){
|
||||||
String_Const_u8 s_file_name = SCu8(file_name);
|
String_Const_u8 s_file_name = SCu8(file_name);
|
||||||
String_Const_u8 canonical_file_name = system_get_canonical(scratch, s_file_name);
|
String_Const_u8 canonical_file_name = system_get_canonical(scratch, s_file_name);
|
||||||
|
@ -151,9 +149,9 @@ save_file_to_name(Thread_Context *tctx, Models *models, Editing_File *file, u8 *
|
||||||
using_actual_file_name = true;
|
using_actual_file_name = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
String_Const_u8 saveable_string = buffer_stringify(scratch, buffer, Ii64(0, buffer_size(buffer)));
|
String_Const_u8 saveable_string = buffer_stringify(scratch, buffer, Ii64(0, buffer_size(buffer)));
|
||||||
|
|
||||||
File_Attributes new_attributes = system_save_file(scratch, (char*)file_name, saveable_string);
|
File_Attributes new_attributes = system_save_file(scratch, (char*)file_name, saveable_string);
|
||||||
if (new_attributes.last_write_time > 0 &&
|
if (new_attributes.last_write_time > 0 &&
|
||||||
using_actual_file_name){
|
using_actual_file_name){
|
||||||
|
@ -163,7 +161,7 @@ save_file_to_name(Thread_Context *tctx, Models *models, Editing_File *file, u8 *
|
||||||
LogEventF(log_string(M), scratch, file->id, 0, system_thread_get_id(),
|
LogEventF(log_string(M), scratch, file->id, 0, system_thread_get_id(),
|
||||||
"save file [last_write_time=0x%llx]", new_attributes.last_write_time);
|
"save file [last_write_time=0x%llx]", new_attributes.last_write_time);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -195,30 +193,30 @@ file_get_layout_func(Editing_File *file){
|
||||||
internal void
|
internal void
|
||||||
file_create_from_string(Thread_Context *tctx, Models *models, Editing_File *file, String_Const_u8 val, File_Attributes attributes){
|
file_create_from_string(Thread_Context *tctx, Models *models, Editing_File *file, String_Const_u8 val, File_Attributes attributes){
|
||||||
Scratch_Block scratch(tctx);
|
Scratch_Block scratch(tctx);
|
||||||
|
|
||||||
Base_Allocator *allocator = tctx->allocator;
|
Base_Allocator *allocator = tctx->allocator;
|
||||||
block_zero_struct(&file->state);
|
block_zero_struct(&file->state);
|
||||||
buffer_init(&file->state.buffer, val.str, val.size, allocator);
|
buffer_init(&file->state.buffer, val.str, val.size, allocator);
|
||||||
|
|
||||||
if (buffer_size(&file->state.buffer) < (i64)val.size){
|
if (buffer_size(&file->state.buffer) < (i64)val.size){
|
||||||
file->settings.dos_write_mode = true;
|
file->settings.dos_write_mode = true;
|
||||||
}
|
}
|
||||||
file_clear_dirty_flags(file);
|
file_clear_dirty_flags(file);
|
||||||
file->attributes = attributes;
|
file->attributes = attributes;
|
||||||
|
|
||||||
file->settings.layout_func = models->layout_func;
|
file->settings.layout_func = models->layout_func;
|
||||||
file->settings.face_id = models->global_face_id;
|
file->settings.face_id = models->global_face_id;
|
||||||
|
|
||||||
buffer_measure_starts(scratch, &file->state.buffer);
|
buffer_measure_starts(scratch, &file->state.buffer);
|
||||||
|
|
||||||
file->lifetime_object = lifetime_alloc_object(&models->lifetime_allocator, DynamicWorkspace_Buffer, file);
|
file->lifetime_object = lifetime_alloc_object(&models->lifetime_allocator, DynamicWorkspace_Buffer, file);
|
||||||
history_init(tctx, models, &file->state.history);
|
history_init(tctx, models, &file->state.history);
|
||||||
|
|
||||||
file->state.cached_layouts_arena = make_arena(allocator);
|
file->state.cached_layouts_arena = make_arena(allocator);
|
||||||
file->state.line_layout_table = make_table_Data_u64(allocator, 500);
|
file->state.line_layout_table = make_table_Data_u64(allocator, 500);
|
||||||
|
|
||||||
file->settings.is_initialized = true;
|
file->settings.is_initialized = true;
|
||||||
|
|
||||||
{
|
{
|
||||||
Temp_Memory temp = begin_temp(scratch);
|
Temp_Memory temp = begin_temp(scratch);
|
||||||
String_Const_u8 name = SCu8(file->unique_name.name_space, file->unique_name.name_size);
|
String_Const_u8 name = SCu8(file->unique_name.name_space, file->unique_name.name_size);
|
||||||
|
@ -228,9 +226,9 @@ file_create_from_string(Thread_Context *tctx, Models *models, Editing_File *file
|
||||||
attributes.last_write_time, string_expand(name));
|
attributes.last_write_time, string_expand(name));
|
||||||
end_temp(temp);
|
end_temp(temp);
|
||||||
}
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
if (models->begin_buffer != 0){
|
if (models->begin_buffer != 0){
|
||||||
Application_Links app = {};
|
Application_Links app = {};
|
||||||
app.tctx = tctx;
|
app.tctx = tctx;
|
||||||
|
@ -243,17 +241,17 @@ internal void
|
||||||
file_free(Thread_Context *tctx, Models *models, Editing_File *file){
|
file_free(Thread_Context *tctx, Models *models, Editing_File *file){
|
||||||
Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator;
|
Lifetime_Allocator *lifetime_allocator = &models->lifetime_allocator;
|
||||||
Working_Set *working_set = &models->working_set;
|
Working_Set *working_set = &models->working_set;
|
||||||
|
|
||||||
lifetime_free_object(lifetime_allocator, file->lifetime_object);
|
lifetime_free_object(lifetime_allocator, file->lifetime_object);
|
||||||
|
|
||||||
Gap_Buffer *buffer = &file->state.buffer;
|
Gap_Buffer *buffer = &file->state.buffer;
|
||||||
if (buffer->data){
|
if (buffer->data){
|
||||||
base_free(buffer->allocator, buffer->data);
|
base_free(buffer->allocator, buffer->data);
|
||||||
base_free(buffer->allocator, buffer->line_starts);
|
base_free(buffer->allocator, buffer->line_starts);
|
||||||
}
|
}
|
||||||
|
|
||||||
history_free(tctx, &file->state.history);
|
history_free(tctx, &file->state.history);
|
||||||
|
|
||||||
linalloc_clear(&file->state.cached_layouts_arena);
|
linalloc_clear(&file->state.cached_layouts_arena);
|
||||||
table_free(&file->state.line_layout_table);
|
table_free(&file->state.line_layout_table);
|
||||||
}
|
}
|
||||||
|
@ -281,7 +279,7 @@ internal Layout_Item_List
|
||||||
file_get_line_layout(Thread_Context *tctx, Models *models, Editing_File *file,
|
file_get_line_layout(Thread_Context *tctx, Models *models, Editing_File *file,
|
||||||
Layout_Function *layout_func, f32 width, Face *face, i64 line_number){
|
Layout_Function *layout_func, f32 width, Face *face, i64 line_number){
|
||||||
Layout_Item_List result = {};
|
Layout_Item_List result = {};
|
||||||
|
|
||||||
i64 line_count = buffer_line_count(&file->state.buffer);
|
i64 line_count = buffer_line_count(&file->state.buffer);
|
||||||
if (1 <= line_number && line_number <= line_count){
|
if (1 <= line_number && line_number <= line_count){
|
||||||
Line_Layout_Key key = {};
|
Line_Layout_Key key = {};
|
||||||
|
@ -289,11 +287,11 @@ file_get_line_layout(Thread_Context *tctx, Models *models, Editing_File *file,
|
||||||
key.face_version_number = face->version_number;
|
key.face_version_number = face->version_number;
|
||||||
key.width = width;
|
key.width = width;
|
||||||
key.line_number = line_number;
|
key.line_number = line_number;
|
||||||
|
|
||||||
String_Const_u8 key_data = make_data_struct(&key);
|
String_Const_u8 key_data = make_data_struct(&key);
|
||||||
|
|
||||||
Layout_Item_List *list = 0;
|
Layout_Item_List *list = 0;
|
||||||
|
|
||||||
Table_Lookup lookup = table_lookup(&file->state.line_layout_table, key_data);
|
Table_Lookup lookup = table_lookup(&file->state.line_layout_table, key_data);
|
||||||
if (lookup.found_match){
|
if (lookup.found_match){
|
||||||
u64 val = 0;
|
u64 val = 0;
|
||||||
|
@ -303,7 +301,7 @@ file_get_line_layout(Thread_Context *tctx, Models *models, Editing_File *file,
|
||||||
else{
|
else{
|
||||||
list = push_array(&file->state.cached_layouts_arena, Layout_Item_List, 1);
|
list = push_array(&file->state.cached_layouts_arena, Layout_Item_List, 1);
|
||||||
Range_i64 line_range = buffer_get_pos_range_from_line_number(&file->state.buffer, line_number);
|
Range_i64 line_range = buffer_get_pos_range_from_line_number(&file->state.buffer, line_number);
|
||||||
|
|
||||||
Application_Links app = {};
|
Application_Links app = {};
|
||||||
app.tctx = tctx;
|
app.tctx = tctx;
|
||||||
app.cmd_context = models;
|
app.cmd_context = models;
|
||||||
|
@ -314,7 +312,7 @@ file_get_line_layout(Thread_Context *tctx, Models *models, Editing_File *file,
|
||||||
}
|
}
|
||||||
block_copy_struct(&result, list);
|
block_copy_struct(&result, list);
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -329,9 +327,9 @@ file_line_shift_y(Thread_Context *tctx, Models *models, Editing_File *file,
|
||||||
Layout_Function *layout_func, f32 width, Face *face,
|
Layout_Function *layout_func, f32 width, Face *face,
|
||||||
i64 line_number, f32 y_delta){
|
i64 line_number, f32 y_delta){
|
||||||
Line_Shift_Vertical result = {};
|
Line_Shift_Vertical result = {};
|
||||||
|
|
||||||
f32 line_y = 0.f;
|
f32 line_y = 0.f;
|
||||||
|
|
||||||
if (y_delta < 0.f){
|
if (y_delta < 0.f){
|
||||||
// NOTE(allen): Iterating upward
|
// NOTE(allen): Iterating upward
|
||||||
b32 has_result = false;
|
b32 has_result = false;
|
||||||
|
@ -380,7 +378,7 @@ file_line_shift_y(Thread_Context *tctx, Models *models, Editing_File *file,
|
||||||
result.y_delta = line_y;
|
result.y_delta = line_y;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -419,11 +417,11 @@ file_relative_box_of_pos(Thread_Context *tctx, Models *models, Editing_File *fil
|
||||||
i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1;
|
i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1;
|
||||||
Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, line_number);
|
Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, line_number);
|
||||||
Rect_f32 result = layout_box_of_pos(line, pos);
|
Rect_f32 result = layout_box_of_pos(line, pos);
|
||||||
|
|
||||||
f32 y_difference = file_line_y_difference(tctx, models, file, layout_func, width, face, line_number, base_line);
|
f32 y_difference = file_line_y_difference(tctx, models, file, layout_func, width, face, line_number, base_line);
|
||||||
result.y0 += y_difference;
|
result.y0 += y_difference;
|
||||||
result.y1 += y_difference;
|
result.y1 += y_difference;
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -442,11 +440,11 @@ file_padded_box_of_pos(Thread_Context *tctx, Models *models, Editing_File *file,
|
||||||
i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1;
|
i64 line_number = buffer_get_line_index(&file->state.buffer, pos) + 1;
|
||||||
Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, line_number);
|
Layout_Item_List line = file_get_line_layout(tctx, models, file, layout_func, width, face, line_number);
|
||||||
Rect_f32 result = layout_padded_box_of_pos(line, pos);
|
Rect_f32 result = layout_padded_box_of_pos(line, pos);
|
||||||
|
|
||||||
f32 y_difference = file_line_y_difference(tctx, models, file, layout_func, width, face, line_number, base_line);
|
f32 y_difference = file_line_y_difference(tctx, models, file, layout_func, width, face, line_number, base_line);
|
||||||
result.y0 += y_difference;
|
result.y0 += y_difference;
|
||||||
result.y1 += y_difference;
|
result.y1 += y_difference;
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -475,9 +473,9 @@ file_buffer_point_difference(Thread_Context *tctx, Models *models, Editing_File
|
||||||
internal Line_Shift_Character
|
internal Line_Shift_Character
|
||||||
file_line_shift_characters(Thread_Context *tctx, Models *models, Editing_File *file, Layout_Function *layout_func, f32 width, Face *face, i64 line_number, i64 character_delta){
|
file_line_shift_characters(Thread_Context *tctx, Models *models, Editing_File *file, Layout_Function *layout_func, f32 width, Face *face, i64 line_number, i64 character_delta){
|
||||||
Line_Shift_Character result = {};
|
Line_Shift_Character result = {};
|
||||||
|
|
||||||
i64 line_character = 0;
|
i64 line_character = 0;
|
||||||
|
|
||||||
if (character_delta < 0){
|
if (character_delta < 0){
|
||||||
// NOTE(allen): Iterating upward
|
// NOTE(allen): Iterating upward
|
||||||
b32 has_result = false;
|
b32 has_result = false;
|
||||||
|
@ -524,7 +522,7 @@ file_line_shift_characters(Thread_Context *tctx, Models *models, Editing_File *f
|
||||||
result.character_delta = line_character;
|
result.character_delta = line_character;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -12,14 +12,7 @@
|
||||||
#if !defined(FRED_FILE_H)
|
#if !defined(FRED_FILE_H)
|
||||||
#define FRED_FILE_H
|
#define FRED_FILE_H
|
||||||
|
|
||||||
typedef i32 Edit_Pos_Set_Type;
|
|
||||||
enum{
|
|
||||||
EditPos_None,
|
|
||||||
EditPos_CursorSet,
|
|
||||||
EditPos_ScrollSet
|
|
||||||
};
|
|
||||||
struct File_Edit_Positions{
|
struct File_Edit_Positions{
|
||||||
Edit_Pos_Set_Type last_set_type;
|
|
||||||
Buffer_Scroll scroll;
|
Buffer_Scroll scroll;
|
||||||
i64 cursor_pos;
|
i64 cursor_pos;
|
||||||
};
|
};
|
||||||
|
@ -50,19 +43,19 @@ enum{
|
||||||
|
|
||||||
struct Editing_File_State{
|
struct Editing_File_State{
|
||||||
Gap_Buffer buffer;
|
Gap_Buffer buffer;
|
||||||
|
|
||||||
History history;
|
History history;
|
||||||
i32 current_record_index;
|
i32 current_record_index;
|
||||||
|
|
||||||
Dirty_State dirty;
|
Dirty_State dirty;
|
||||||
File_Save_State save_state;
|
File_Save_State save_state;
|
||||||
|
|
||||||
File_Edit_Positions edit_pos_most_recent;
|
File_Edit_Positions edit_pos_most_recent;
|
||||||
File_Edit_Positions edit_pos_stack[16];
|
File_Edit_Positions edit_pos_stack[16];
|
||||||
i32 edit_pos_stack_top;
|
i32 edit_pos_stack_top;
|
||||||
|
|
||||||
Child_Process_ID attached_child_process;
|
Child_Process_ID attached_child_process;
|
||||||
|
|
||||||
Arena cached_layouts_arena;
|
Arena cached_layouts_arena;
|
||||||
Table_Data_u64 line_layout_table;
|
Table_Data_u64 line_layout_table;
|
||||||
};
|
};
|
||||||
|
|
|
@ -42,12 +42,12 @@ internal void
|
||||||
free_query_slot(Query_Set *set, Query_Bar *match_bar){
|
free_query_slot(Query_Set *set, Query_Bar *match_bar){
|
||||||
Query_Slot *slot = 0;
|
Query_Slot *slot = 0;
|
||||||
Query_Slot *prev = 0;
|
Query_Slot *prev = 0;
|
||||||
|
|
||||||
for (slot = set->used_slot; slot != 0; slot = slot->next){
|
for (slot = set->used_slot; slot != 0; slot = slot->next){
|
||||||
if (slot->query_bar == match_bar) break;
|
if (slot->query_bar == match_bar) break;
|
||||||
prev = slot;
|
prev = slot;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slot){
|
if (slot){
|
||||||
if (prev){
|
if (prev){
|
||||||
prev->next = slot->next;
|
prev->next = slot->next;
|
||||||
|
@ -97,17 +97,17 @@ internal View*
|
||||||
live_set_alloc_view(Lifetime_Allocator *lifetime_allocator, Live_Views *live_set, Panel *panel){
|
live_set_alloc_view(Lifetime_Allocator *lifetime_allocator, Live_Views *live_set, Panel *panel){
|
||||||
Assert(live_set->count < live_set->max);
|
Assert(live_set->count < live_set->max);
|
||||||
++live_set->count;
|
++live_set->count;
|
||||||
|
|
||||||
View *result = live_set->free_sentinel.next;
|
View *result = live_set->free_sentinel.next;
|
||||||
dll_remove(result);
|
dll_remove(result);
|
||||||
block_zero_struct(result);
|
block_zero_struct(result);
|
||||||
|
|
||||||
result->in_use = true;
|
result->in_use = true;
|
||||||
init_query_set(&result->query_set);
|
init_query_set(&result->query_set);
|
||||||
result->lifetime_object = lifetime_alloc_object(lifetime_allocator, DynamicWorkspace_View, result);
|
result->lifetime_object = lifetime_alloc_object(lifetime_allocator, DynamicWorkspace_View, result);
|
||||||
panel->view = result;
|
panel->view = result;
|
||||||
result->panel = panel;
|
result->panel = panel;
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -115,13 +115,13 @@ internal void
|
||||||
live_set_free_view(Lifetime_Allocator *lifetime_allocator, Live_Views *live_set, View *view){
|
live_set_free_view(Lifetime_Allocator *lifetime_allocator, Live_Views *live_set, View *view){
|
||||||
Assert(live_set->count > 0);
|
Assert(live_set->count > 0);
|
||||||
--live_set->count;
|
--live_set->count;
|
||||||
|
|
||||||
view->next = live_set->free_sentinel.next;
|
view->next = live_set->free_sentinel.next;
|
||||||
view->prev = &live_set->free_sentinel;
|
view->prev = &live_set->free_sentinel;
|
||||||
live_set->free_sentinel.next = view;
|
live_set->free_sentinel.next = view;
|
||||||
view->next->prev = view;
|
view->next->prev = view;
|
||||||
view->in_use = false;
|
view->in_use = false;
|
||||||
|
|
||||||
lifetime_free_object(lifetime_allocator, view->lifetime_object);
|
lifetime_free_object(lifetime_allocator, view->lifetime_object);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -335,31 +335,31 @@ view_move_view_to_cursor(Thread_Context *tctx, Models *models, View *view, Buffe
|
||||||
Face *face = file_get_face(models, file);
|
Face *face = file_get_face(models, file);
|
||||||
Rect_f32 rect = view_get_buffer_rect(tctx, models, view);
|
Rect_f32 rect = view_get_buffer_rect(tctx, models, view);
|
||||||
Vec2_f32 view_dim = rect_dim(rect);
|
Vec2_f32 view_dim = rect_dim(rect);
|
||||||
|
|
||||||
Layout_Function *layout_func = file_get_layout_func(file);
|
Layout_Function *layout_func = file_get_layout_func(file);
|
||||||
|
|
||||||
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
File_Edit_Positions edit_pos = view_get_edit_pos(view);
|
||||||
Vec2_f32 p = file_relative_xy_of_pos(tctx, models, file,
|
Vec2_f32 p = file_relative_xy_of_pos(tctx, models, file,
|
||||||
layout_func, view_dim.x, face,
|
layout_func, view_dim.x, face,
|
||||||
scroll->target.line_number, edit_pos.cursor_pos);
|
scroll->target.line_number, edit_pos.cursor_pos);
|
||||||
p -= scroll->target.pixel_shift;
|
p -= scroll->target.pixel_shift;
|
||||||
|
|
||||||
f32 line_height = face->metrics.line_height;
|
f32 line_height = face->metrics.line_height;
|
||||||
f32 normal_advance = face->metrics.normal_advance;
|
f32 normal_advance = face->metrics.normal_advance;
|
||||||
|
|
||||||
Vec2_f32 margin = view->cursor_margin;
|
Vec2_f32 margin = view->cursor_margin;
|
||||||
Vec2_f32 push_in = view->cursor_push_in_multiplier;
|
Vec2_f32 push_in = view->cursor_push_in_multiplier;
|
||||||
|
|
||||||
Vec2_f32 lim_dim = view_dim*0.45f;
|
Vec2_f32 lim_dim = view_dim*0.45f;
|
||||||
margin.x = clamp_top(margin.x, lim_dim.x);
|
margin.x = clamp_top(margin.x, lim_dim.x);
|
||||||
margin.y = clamp_top(margin.y, lim_dim.y);
|
margin.y = clamp_top(margin.y, lim_dim.y);
|
||||||
|
|
||||||
Vec2_f32 push_in_lim_dim = hadamard(lim_dim, V2f32(1.f/line_height, 1.f/normal_advance)) - margin;
|
Vec2_f32 push_in_lim_dim = hadamard(lim_dim, V2f32(1.f/line_height, 1.f/normal_advance)) - margin;
|
||||||
push_in_lim_dim.x = clamp_bot(0.f, push_in_lim_dim.x);
|
push_in_lim_dim.x = clamp_bot(0.f, push_in_lim_dim.x);
|
||||||
push_in_lim_dim.y = clamp_bot(0.f, push_in_lim_dim.y);
|
push_in_lim_dim.y = clamp_bot(0.f, push_in_lim_dim.y);
|
||||||
push_in.x = clamp_top(push_in.x, push_in_lim_dim.x);
|
push_in.x = clamp_top(push_in.x, push_in_lim_dim.x);
|
||||||
push_in.y = clamp_top(push_in.y, push_in_lim_dim.y);
|
push_in.y = clamp_top(push_in.y, push_in_lim_dim.y);
|
||||||
|
|
||||||
Vec2_f32 target_p_relative = {};
|
Vec2_f32 target_p_relative = {};
|
||||||
if (p.y < margin.y){
|
if (p.y < margin.y){
|
||||||
target_p_relative.y = p.y - margin.y - line_height*push_in.y;
|
target_p_relative.y = p.y - margin.y - line_height*push_in.y;
|
||||||
|
@ -377,7 +377,7 @@ view_move_view_to_cursor(Thread_Context *tctx, Models *models, View *view, Buffe
|
||||||
scroll->target = view_normalize_buffer_point(tctx, models, view, scroll->target);
|
scroll->target = view_normalize_buffer_point(tctx, models, view, scroll->target);
|
||||||
scroll->target.pixel_shift.x = f32_round32(scroll->target.pixel_shift.x);
|
scroll->target.pixel_shift.x = f32_round32(scroll->target.pixel_shift.x);
|
||||||
scroll->target.pixel_shift.y = f32_round32(scroll->target.pixel_shift.y);
|
scroll->target.pixel_shift.y = f32_round32(scroll->target.pixel_shift.y);
|
||||||
|
|
||||||
return(target_p_relative != V2f32(0.f, 0.f));
|
return(target_p_relative != V2f32(0.f, 0.f));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -387,16 +387,16 @@ view_move_cursor_to_view(Thread_Context *tctx, Models *models, View *view, Buffe
|
||||||
Face *face = file_get_face(models, file);
|
Face *face = file_get_face(models, file);
|
||||||
Rect_f32 rect = view_get_buffer_rect(tctx, models, view);
|
Rect_f32 rect = view_get_buffer_rect(tctx, models, view);
|
||||||
Vec2_f32 view_dim = rect_dim(rect);
|
Vec2_f32 view_dim = rect_dim(rect);
|
||||||
|
|
||||||
Layout_Function *layout_func = file_get_layout_func(file);
|
Layout_Function *layout_func = file_get_layout_func(file);
|
||||||
|
|
||||||
Vec2_f32 p = file_relative_xy_of_pos(tctx, models, file,
|
Vec2_f32 p = file_relative_xy_of_pos(tctx, models, file,
|
||||||
layout_func, view_dim.x, face,
|
layout_func, view_dim.x, face,
|
||||||
scroll.target.line_number, *pos_in_out);
|
scroll.target.line_number, *pos_in_out);
|
||||||
p -= scroll.target.pixel_shift;
|
p -= scroll.target.pixel_shift;
|
||||||
|
|
||||||
f32 line_height = face->metrics.line_height;
|
f32 line_height = face->metrics.line_height;
|
||||||
|
|
||||||
b32 adjusted_y = true;
|
b32 adjusted_y = true;
|
||||||
if (p.y < 0.f){
|
if (p.y < 0.f){
|
||||||
p.y = line_height*1.5f;
|
p.y = line_height*1.5f;
|
||||||
|
@ -407,7 +407,7 @@ view_move_cursor_to_view(Thread_Context *tctx, Models *models, View *view, Buffe
|
||||||
else{
|
else{
|
||||||
adjusted_y = false;
|
adjusted_y = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
b32 result = false;
|
b32 result = false;
|
||||||
if (adjusted_y){
|
if (adjusted_y){
|
||||||
p += scroll.target.pixel_shift;
|
p += scroll.target.pixel_shift;
|
||||||
|
@ -416,7 +416,7 @@ view_move_cursor_to_view(Thread_Context *tctx, Models *models, View *view, Buffe
|
||||||
scroll.target.line_number, p);
|
scroll.target.line_number, p);
|
||||||
result = true;
|
result = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -450,7 +450,6 @@ view_set_cursor_and_scroll(Thread_Context *tctx, Models *models, View *view, i64
|
||||||
Vec2_f32 p = view_relative_xy_of_pos(tctx, models, view, cursor.line, pos);
|
Vec2_f32 p = view_relative_xy_of_pos(tctx, models, view, cursor.line, pos);
|
||||||
view->preferred_x = p.x;
|
view->preferred_x = p.x;
|
||||||
file_edit_positions_set_scroll(&edit_pos, scroll);
|
file_edit_positions_set_scroll(&edit_pos, scroll);
|
||||||
edit_pos.last_set_type = EditPos_None;
|
|
||||||
view_set_edit_pos(view, edit_pos);
|
view_set_edit_pos(view, edit_pos);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -459,9 +458,9 @@ view_set_cursor_and_scroll(Thread_Context *tctx, Models *models, View *view, i64
|
||||||
internal void
|
internal void
|
||||||
view_set_file(Thread_Context *tctx, Models *models, View *view, Editing_File *file){
|
view_set_file(Thread_Context *tctx, Models *models, View *view, Editing_File *file){
|
||||||
Assert(file != 0);
|
Assert(file != 0);
|
||||||
|
|
||||||
Editing_File *old_file = view->file;
|
Editing_File *old_file = view->file;
|
||||||
|
|
||||||
if (models->view_change_buffer != 0){
|
if (models->view_change_buffer != 0){
|
||||||
Application_Links app = {};
|
Application_Links app = {};
|
||||||
app.tctx = tctx;
|
app.tctx = tctx;
|
||||||
|
@ -469,21 +468,21 @@ view_set_file(Thread_Context *tctx, Models *models, View *view, Editing_File *fi
|
||||||
models->view_change_buffer(&app, view_get_id(&models->view_set, view),
|
models->view_change_buffer(&app, view_get_id(&models->view_set, view),
|
||||||
(old_file != 0)?old_file->id:0, file->id);
|
(old_file != 0)?old_file->id:0, file->id);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (old_file != 0){
|
if (old_file != 0){
|
||||||
file_touch(&models->working_set, old_file);
|
file_touch(&models->working_set, old_file);
|
||||||
file_edit_positions_push(old_file, view_get_edit_pos(view));
|
file_edit_positions_push(old_file, view_get_edit_pos(view));
|
||||||
}
|
}
|
||||||
|
|
||||||
view->file = file;
|
view->file = file;
|
||||||
|
|
||||||
File_Edit_Positions edit_pos = file_edit_positions_pop(file);
|
File_Edit_Positions edit_pos = file_edit_positions_pop(file);
|
||||||
view_set_edit_pos(view, edit_pos);
|
view_set_edit_pos(view, edit_pos);
|
||||||
view->mark = edit_pos.cursor_pos;
|
view->mark = edit_pos.cursor_pos;
|
||||||
Buffer_Cursor cursor = view_compute_cursor(view, seek_pos(edit_pos.cursor_pos));
|
Buffer_Cursor cursor = view_compute_cursor(view, seek_pos(edit_pos.cursor_pos));
|
||||||
Vec2_f32 p = view_relative_xy_of_pos(tctx, models, view, cursor.line, edit_pos.cursor_pos);
|
Vec2_f32 p = view_relative_xy_of_pos(tctx, models, view, cursor.line, edit_pos.cursor_pos);
|
||||||
view->preferred_x = p.x;
|
view->preferred_x = p.x;
|
||||||
|
|
||||||
models->layout.panel_state_dirty = true;
|
models->layout.panel_state_dirty = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -544,7 +543,7 @@ co_handle_request(Thread_Context *tctx, Models *models, Coroutine *co, Co_Out *o
|
||||||
in.face_id = (face != 0)?face->id:0;
|
in.face_id = (face != 0)?face->id:0;
|
||||||
result = coroutine_run(&models->coroutines, co, &in, out);
|
result = coroutine_run(&models->coroutines, co, &in, out);
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case CoRequest_ModifyFace:
|
case CoRequest_ModifyFace:
|
||||||
{
|
{
|
||||||
Face_Description *description = out->face_description;
|
Face_Description *description = out->face_description;
|
||||||
|
@ -553,13 +552,13 @@ co_handle_request(Thread_Context *tctx, Models *models, Coroutine *co, Co_Out *o
|
||||||
in.success = font_set_modify_face(&models->font_set, face_id, description);
|
in.success = font_set_modify_face(&models->font_set, face_id, description);
|
||||||
result = coroutine_run(&models->coroutines, co, &in, out);
|
result = coroutine_run(&models->coroutines, co, &in, out);
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case CoRequest_AcquireGlobalFrameMutex:
|
case CoRequest_AcquireGlobalFrameMutex:
|
||||||
{
|
{
|
||||||
system_acquire_global_frame_mutex(tctx);
|
system_acquire_global_frame_mutex(tctx);
|
||||||
result = coroutine_run(&models->coroutines, co, 0, out);
|
result = coroutine_run(&models->coroutines, co, 0, out);
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case CoRequest_ReleaseGlobalFrameMutex:
|
case CoRequest_ReleaseGlobalFrameMutex:
|
||||||
{
|
{
|
||||||
system_release_global_frame_mutex(tctx);
|
system_release_global_frame_mutex(tctx);
|
||||||
|
@ -594,18 +593,18 @@ function void
|
||||||
view_init(Thread_Context *tctx, Models *models, View *view, Editing_File *initial_buffer,
|
view_init(Thread_Context *tctx, Models *models, View *view, Editing_File *initial_buffer,
|
||||||
Custom_Command_Function *event_context_base){
|
Custom_Command_Function *event_context_base){
|
||||||
view_set_file(tctx, models, view, initial_buffer);
|
view_set_file(tctx, models, view, initial_buffer);
|
||||||
|
|
||||||
view->node_arena = make_arena_system();
|
view->node_arena = make_arena_system();
|
||||||
|
|
||||||
View_Context first_ctx = {};
|
View_Context first_ctx = {};
|
||||||
first_ctx.render_caller = models->render_caller;
|
first_ctx.render_caller = models->render_caller;
|
||||||
first_ctx.delta_rule = models->delta_rule;
|
first_ctx.delta_rule = models->delta_rule;
|
||||||
first_ctx.delta_rule_memory_size = models->delta_rule_memory_size;
|
first_ctx.delta_rule_memory_size = models->delta_rule_memory_size;
|
||||||
view_push_context(view, &first_ctx);
|
view_push_context(view, &first_ctx);
|
||||||
|
|
||||||
view->cursor_margin = V2f32(0.f, 0.f);
|
view->cursor_margin = V2f32(0.f, 0.f);
|
||||||
view->cursor_push_in_multiplier = V2f32(1.5f, 1.5f);
|
view->cursor_push_in_multiplier = V2f32(1.5f, 1.5f);
|
||||||
|
|
||||||
view->co = coroutine_create(&models->coroutines, view_event_context_base__inner);
|
view->co = coroutine_create(&models->coroutines, view_event_context_base__inner);
|
||||||
view->co->user_data = view;
|
view->co->user_data = view;
|
||||||
Co_In in = {};
|
Co_In in = {};
|
||||||
|
@ -678,10 +677,10 @@ co_full_abort(Thread_Context *tctx, Models *models, View *view){
|
||||||
function b32
|
function b32
|
||||||
co_send_event(Thread_Context *tctx, Models *models, View *view, Input_Event *event){
|
co_send_event(Thread_Context *tctx, Models *models, View *view, Input_Event *event){
|
||||||
b32 event_was_handled = false;
|
b32 event_was_handled = false;
|
||||||
|
|
||||||
Coroutine *co = view->co;
|
Coroutine *co = view->co;
|
||||||
Co_Out *co_out = &view->co_out;
|
Co_Out *co_out = &view->co_out;
|
||||||
|
|
||||||
{
|
{
|
||||||
models->current_input_unhandled = false;
|
models->current_input_unhandled = false;
|
||||||
Co_In in = {};
|
Co_In in = {};
|
||||||
|
@ -695,7 +694,7 @@ co_send_event(Thread_Context *tctx, Models *models, View *view, Input_Event *eve
|
||||||
}
|
}
|
||||||
event_was_handled = !models->current_input_unhandled;
|
event_was_handled = !models->current_input_unhandled;
|
||||||
}
|
}
|
||||||
|
|
||||||
return(event_was_handled);
|
return(event_was_handled);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -62,27 +62,27 @@ struct View{
|
||||||
View *prev;
|
View *prev;
|
||||||
struct Panel *panel;
|
struct Panel *panel;
|
||||||
b32 in_use;
|
b32 in_use;
|
||||||
|
|
||||||
Editing_File *file;
|
Editing_File *file;
|
||||||
Lifetime_Object *lifetime_object;
|
Lifetime_Object *lifetime_object;
|
||||||
|
|
||||||
File_Edit_Positions edit_pos_;
|
File_Edit_Positions edit_pos_;
|
||||||
i64 mark;
|
i64 mark;
|
||||||
f32 preferred_x;
|
f32 preferred_x;
|
||||||
Vec2_f32 cursor_margin;
|
Vec2_f32 cursor_margin;
|
||||||
Vec2_f32 cursor_push_in_multiplier;
|
Vec2_f32 cursor_push_in_multiplier;
|
||||||
|
|
||||||
b8 new_scroll_target;
|
b8 new_scroll_target;
|
||||||
b8 hide_scrollbar;
|
b8 hide_scrollbar;
|
||||||
b8 hide_file_bar;
|
b8 hide_file_bar;
|
||||||
b8 show_whitespace;
|
b8 show_whitespace;
|
||||||
|
|
||||||
Coroutine *co;
|
Coroutine *co;
|
||||||
Co_Out co_out;
|
Co_Out co_out;
|
||||||
|
|
||||||
Arena node_arena;
|
Arena node_arena;
|
||||||
View_Context_Node *ctx;
|
View_Context_Node *ctx;
|
||||||
|
|
||||||
Query_Set query_set;
|
Query_Set query_set;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
@ -395,7 +395,7 @@ buffer_bind_name(Thread_Context *tctx, Models *models, Arena *scratch, Working_S
|
||||||
node != used_nodes;
|
node != used_nodes;
|
||||||
node = node->next){
|
node = node->next){
|
||||||
Editing_File *file_ptr = CastFromMember(Editing_File, main_chain_node, node);
|
Editing_File *file_ptr = CastFromMember(Editing_File, main_chain_node, node);
|
||||||
if (file_ptr != 0 && string_match(base_name, string_from_file_name(&file_ptr->base_name))){
|
if (file_ptr != 0 && string_match(base_name, string_from_file_name(&file_ptr->unique_name))){
|
||||||
Node_Ptr *new_node = push_array(scratch, Node_Ptr, 1);
|
Node_Ptr *new_node = push_array(scratch, Node_Ptr, 1);
|
||||||
sll_queue_push(conflict_first, conflict_last, new_node);
|
sll_queue_push(conflict_first, conflict_last, new_node);
|
||||||
new_node->file_ptr = file_ptr;
|
new_node->file_ptr = file_ptr;
|
||||||
|
|
|
@ -17,11 +17,7 @@ BIN_ROOT="$SRC_ROOT/bin"
|
||||||
CUSTOM_ROOT="$SRC_ROOT/custom"
|
CUSTOM_ROOT="$SRC_ROOT/custom"
|
||||||
CUSTOM_BIN="$CUSTOM_ROOT/bin"
|
CUSTOM_BIN="$CUSTOM_ROOT/bin"
|
||||||
|
|
||||||
# Get the build mode
|
BUILD_MODE="-DDEV_BUILD"
|
||||||
BUILD_MODE="$1"
|
|
||||||
if [ -z "$BUILD_MODE" ]; then
|
|
||||||
BUILD_MODE="-DDEV_BUILD"
|
|
||||||
fi
|
|
||||||
|
|
||||||
WARNINGS="-Wno-write-strings -Wno-comment -Wno-null-dereference -Wno-logical-op-parentheses -Wno-switch"
|
WARNINGS="-Wno-write-strings -Wno-comment -Wno-null-dereference -Wno-logical-op-parentheses -Wno-switch"
|
||||||
|
|
|
@ -0,0 +1,31 @@
|
||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
# If any command errors, stop the script
|
||||||
|
set -e
|
||||||
|
|
||||||
|
# Set up directories
|
||||||
|
# NOTE(yuval): Replaced readlink with realpath which works for both macOS and Linux
|
||||||
|
ME="$(realpath "$0")"
|
||||||
|
LOCATION="$(dirname "$ME")"
|
||||||
|
SRC_ROOT="$(dirname "$LOCATION")"
|
||||||
|
PROJECT_ROOT="$(dirname "$SRC_ROOT")"
|
||||||
|
if [ ! -d "$PROJECT_ROOT/build" ]; then
|
||||||
|
mkdir "$PROJECT_ROOT/build"
|
||||||
|
fi
|
||||||
|
BUILD_ROOT="$PROJECT_ROOT/build"
|
||||||
|
BIN_ROOT="$SRC_ROOT/bin"
|
||||||
|
CUSTOM_ROOT="$SRC_ROOT/custom"
|
||||||
|
CUSTOM_BIN="$CUSTOM_ROOT/bin"
|
||||||
|
|
||||||
|
BUILD_MODE="-DOPT_BUILD"
|
||||||
|
|
||||||
|
WARNINGS="-Wno-write-strings -Wno-comment -Wno-null-dereference -Wno-logical-op-parentheses -Wno-switch"
|
||||||
|
|
||||||
|
FLAGS="-D_GNU_SOURCE -fPIC -fpermissive $BUILD_MODE"
|
||||||
|
INCLUDES="-I$SRC_ROOT -I$CUSTOM_ROOT"
|
||||||
|
|
||||||
|
# Execute
|
||||||
|
clang++ $WARNINGS $FLAGS $INCLUDES "$BIN_ROOT/4ed_build.cpp" -g -o "$BUILD_ROOT/build"
|
||||||
|
pushd "$SRC_ROOT"
|
||||||
|
"$BUILD_ROOT/build"
|
||||||
|
popd
|
|
@ -1,10 +1,11 @@
|
||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
set location=%cd%
|
set location=%cd%
|
||||||
set me="%~dp0"
|
set me=%~dp0
|
||||||
|
|
||||||
REM 4cc\code\bin
|
:: REM 4cc\code\bin
|
||||||
cd %me%
|
cd %me%
|
||||||
|
REM ..\code\bin
|
||||||
|
|
||||||
REM 4cc
|
REM 4cc
|
||||||
cd ..\..
|
cd ..\..
|
||||||
|
@ -34,6 +35,7 @@ if %ERRORLEVEL% neq 0 (set FirstError=1)
|
||||||
if %ERRORLEVEL% neq 0 (goto END)
|
if %ERRORLEVEL% neq 0 (goto END)
|
||||||
popd
|
popd
|
||||||
|
|
||||||
|
cd %me%\..
|
||||||
%build_root%\build
|
%build_root%\build
|
||||||
:END
|
:END
|
||||||
if %ERRORLEVEL% neq 0 (set FirstError=1)
|
if %ERRORLEVEL% neq 0 (set FirstError=1)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
|
pushd $(dirname "${BASH_SOURCE[0]}")/.. > /dev/null > /dev/null
|
||||||
chmod +x bin/build-mac.sh
|
chmod +x bin/build-mac.sh
|
||||||
bin/build-mac.sh "-DPACKAGE_SUPER_X64"
|
bin/build-mac.sh "-DPACKAGE_SUPER_X64"
|
||||||
|
popd > /dev/null
|
||||||
|
|
|
@ -1,3 +1,4 @@
|
||||||
@echo off
|
@echo off
|
||||||
|
|
||||||
call bin\build.bat /DPACKAGE_SUPER_X64
|
SET mypath=%~dp0
|
||||||
|
call %mypath:~0,-1%\build.bat /DPACKAGE_SUPER_X64
|
||||||
|
|
|
@ -1,276 +0,0 @@
|
||||||
////////////////////////////////
|
|
||||||
// NOTE(allen): Default Mixer Helpers
|
|
||||||
|
|
||||||
// TODO(allen): intrinsics wrappers
|
|
||||||
#if OS_LINUX
|
|
||||||
#include <immintrin.h>
|
|
||||||
#define _InterlockedExchangeAdd __sync_fetch_and_add
|
|
||||||
#elif OS_MAC
|
|
||||||
#include <immintrin.h>
|
|
||||||
#define _InterlockedExchangeAdd __sync_fetch_and_add
|
|
||||||
#else
|
|
||||||
#include <intrin.h>
|
|
||||||
#endif
|
|
||||||
|
|
||||||
function u32
|
|
||||||
AtomicAddU32AndReturnOriginal(u32 volatile *Value, u32 Addend)
|
|
||||||
{
|
|
||||||
// NOTE(casey): Returns the original value _prior_ to adding
|
|
||||||
u32 Result = _InterlockedExchangeAdd((long volatile*)Value, (long)Addend);
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
|
||||||
def_audio_begin_ticket_mutex(Audio_System *Crunky)
|
|
||||||
{
|
|
||||||
u32 Ticket = AtomicAddU32AndReturnOriginal(&Crunky->ticket, 1);
|
|
||||||
while(Ticket != Crunky->serving) {_mm_pause();}
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
|
||||||
def_audio_end_ticket_mutex(Audio_System *Crunky)
|
|
||||||
{
|
|
||||||
AtomicAddU32AndReturnOriginal(&Crunky->serving, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
// NOTE(allen): Default Mixer
|
|
||||||
|
|
||||||
global Audio_System def_audio_system = {};
|
|
||||||
|
|
||||||
function void
|
|
||||||
def_audio_init(void){
|
|
||||||
block_zero_struct(&def_audio_system);
|
|
||||||
system_set_source_mixer(&def_audio_system, def_audio_mix_sources);
|
|
||||||
system_set_destination_mixer(def_audio_mix_destination);
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
|
||||||
def_audio_play_clip(Audio_Clip clip, Audio_Control *control){
|
|
||||||
clip.control = control;
|
|
||||||
Audio_System *Crunky = &def_audio_system;
|
|
||||||
def_audio_begin_ticket_mutex(Crunky);
|
|
||||||
if (Crunky->pending_clip_count < ArrayCount(Crunky->pending_clips))
|
|
||||||
{
|
|
||||||
Crunky->pending_clips[Crunky->pending_clip_count++] = clip;
|
|
||||||
}
|
|
||||||
def_audio_end_ticket_mutex(Crunky);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal b32
|
|
||||||
def_audio_is_playing(Audio_Control *control){
|
|
||||||
Audio_System *Crunky = &def_audio_system;
|
|
||||||
b32 result = (Crunky->generation - control->generation < 2);
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
def_audio_stop(Audio_Control *control){
|
|
||||||
Audio_System *Crunky = &def_audio_system;
|
|
||||||
def_audio_begin_ticket_mutex(Crunky);
|
|
||||||
|
|
||||||
Audio_Clip *clip = Crunky->playing_clips;
|
|
||||||
for(u32 i = 0;
|
|
||||||
i < ArrayCount(Crunky->playing_clips);
|
|
||||||
i += 1, clip += 1){
|
|
||||||
if (clip->control == control){
|
|
||||||
clip->at_sample_index = clip->sample_count;
|
|
||||||
clip->control = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
control->loop = false;
|
|
||||||
|
|
||||||
def_audio_end_ticket_mutex(Crunky);
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
|
||||||
def_audio_mix_sources(void *ctx, f32 *mix_buffer, u32 sample_count){
|
|
||||||
Audio_System *Crunky = (Audio_System*)ctx;
|
|
||||||
def_audio_begin_ticket_mutex(Crunky);
|
|
||||||
// NOTE(casey): Move pending sounds into the playing list
|
|
||||||
{
|
|
||||||
Crunky->generation += 1;
|
|
||||||
u32 PendIndex = 0;
|
|
||||||
Audio_Clip *clip = Crunky->playing_clips;
|
|
||||||
for(u32 DestIndex = 0;
|
|
||||||
(DestIndex < ArrayCount(Crunky->playing_clips)) && (PendIndex < Crunky->pending_clip_count);
|
|
||||||
DestIndex += 1, clip += 1)
|
|
||||||
{
|
|
||||||
if (clip->at_sample_index == clip->sample_count)
|
|
||||||
{
|
|
||||||
Audio_Control *control = clip->control;
|
|
||||||
if (control == 0 || !control->loop){
|
|
||||||
*clip = Crunky->pending_clips[PendIndex++];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Crunky->pending_clip_count = 0;
|
|
||||||
}
|
|
||||||
def_audio_end_ticket_mutex(Crunky);
|
|
||||||
|
|
||||||
// NOTE(casey): Mix all sounds into the output buffer
|
|
||||||
{
|
|
||||||
Audio_Clip *clip = Crunky->playing_clips;
|
|
||||||
for(u32 SoundIndex = 0;
|
|
||||||
SoundIndex < ArrayCount(Crunky->playing_clips);
|
|
||||||
SoundIndex += 1, clip += 1)
|
|
||||||
{
|
|
||||||
// NOTE(allen): Determine starting point
|
|
||||||
Audio_Control *control = clip->control;
|
|
||||||
if (control != 0 && control->loop && clip->at_sample_index == clip->sample_count){
|
|
||||||
clip->at_sample_index = 0;
|
|
||||||
}
|
|
||||||
u32 base_sample_index = clip->at_sample_index;
|
|
||||||
|
|
||||||
// NOTE(casey): Determine how many samples are left to play in this
|
|
||||||
// sound (possible none)
|
|
||||||
u32 SamplesToMix = clamp_top((clip->sample_count - clip->at_sample_index), sample_count);
|
|
||||||
clip->at_sample_index += SamplesToMix;
|
|
||||||
|
|
||||||
// NOTE(casey): Load the volume out of the control if there is one,
|
|
||||||
// and if there is, update the generation and sample index so
|
|
||||||
// external controllers can take action
|
|
||||||
f32 LeftVol = clip->channel_volume[0];
|
|
||||||
f32 RightVol = clip->channel_volume[1];
|
|
||||||
if(SamplesToMix && control != 0)
|
|
||||||
{
|
|
||||||
LeftVol *= control->channel_volume[0];
|
|
||||||
RightVol *= control->channel_volume[1];
|
|
||||||
control->generation = Crunky->generation;
|
|
||||||
control->last_played_sample_index = clip->at_sample_index;
|
|
||||||
}
|
|
||||||
|
|
||||||
// NOTE(casey): Mix samples
|
|
||||||
for(u32 SampleIndex = 0;
|
|
||||||
SampleIndex < SamplesToMix;
|
|
||||||
++SampleIndex)
|
|
||||||
{
|
|
||||||
u32 src_index = 2*(base_sample_index + SampleIndex);
|
|
||||||
f32 Left = LeftVol *(f32)clip->samples[src_index + 0];
|
|
||||||
f32 Right = RightVol*(f32)clip->samples[src_index + 1];
|
|
||||||
|
|
||||||
u32 dst_index = 2*SampleIndex;
|
|
||||||
mix_buffer[dst_index + 0] += Left;
|
|
||||||
mix_buffer[dst_index + 1] += Right;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
function void
|
|
||||||
def_audio_mix_destination(i16 *dst, f32 *src, u32 sample_count){
|
|
||||||
u32 opl = sample_count*2;
|
|
||||||
for(u32 i = 0; i < opl; i += 1){
|
|
||||||
f32 sample = src[i];
|
|
||||||
f32 sat_sample = clamp(-32768.f, sample, 32767.f);
|
|
||||||
dst[i] = (i16)sat_sample;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
// NOTE(allen): Loading Clip
|
|
||||||
|
|
||||||
#if !defined(FCODER_SKIP_WAV)
|
|
||||||
#define FCODER_SKIP_WAV
|
|
||||||
#pragma pack(push, 1)
|
|
||||||
struct wave_fmt_data
|
|
||||||
{
|
|
||||||
u16 wFormatTag;
|
|
||||||
u16 wChannels;
|
|
||||||
u32 dwSamplesPerSec;
|
|
||||||
u32 dwAvgBytesPerSec;
|
|
||||||
u16 wBlockAlign;
|
|
||||||
u16 wBitsPerSample;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct riff_header
|
|
||||||
{
|
|
||||||
u32 ID;
|
|
||||||
u32 DataSize;
|
|
||||||
};
|
|
||||||
#pragma pack(pop)
|
|
||||||
#endif
|
|
||||||
|
|
||||||
function Audio_Clip
|
|
||||||
audio_clip_from_wav_data(String_Const_u8 data){
|
|
||||||
Audio_Clip Result = {};
|
|
||||||
|
|
||||||
if (data.size >= 4 && *(u32 *)data.str == *(u32 *)"RIFF"){
|
|
||||||
// NOTE(casey): This ROM is in WAV format
|
|
||||||
|
|
||||||
riff_header *RootHeader = (riff_header *)data.str;
|
|
||||||
|
|
||||||
wave_fmt_data *Format = 0;
|
|
||||||
u32 SampleDataSize = 0;
|
|
||||||
i16 *Samples = 0;
|
|
||||||
|
|
||||||
u32 At = sizeof(riff_header);
|
|
||||||
u32 LastAt = At + ((RootHeader->DataSize + 1) & ~1);
|
|
||||||
if ((*(u32 *)(data.str + At) == *(u32 *)"WAVE") &&
|
|
||||||
(LastAt <= data.size)){
|
|
||||||
At += sizeof(u32);
|
|
||||||
while (At < LastAt){
|
|
||||||
riff_header *Header = (riff_header *)(data.str + At);
|
|
||||||
u32 DataAt = At + sizeof(riff_header);
|
|
||||||
u32 EndAt = DataAt + ((Header->DataSize + 1) & ~1);
|
|
||||||
if(EndAt <= data.size)
|
|
||||||
{
|
|
||||||
void *Data = (data.str + DataAt);
|
|
||||||
if(Header->ID == *(u32 *)"fmt ")
|
|
||||||
{
|
|
||||||
Format = (wave_fmt_data *)Data;
|
|
||||||
}
|
|
||||||
else if(Header->ID == *(u32 *)"data")
|
|
||||||
{
|
|
||||||
SampleDataSize = Header->DataSize;
|
|
||||||
Samples = (i16 *)Data;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
At = EndAt;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (Format &&
|
|
||||||
Samples &&
|
|
||||||
(Format->wFormatTag == 1) &&
|
|
||||||
(Format->wChannels == 2) &&
|
|
||||||
(Format->wBitsPerSample == 16) &&
|
|
||||||
(Format->dwSamplesPerSec == 48000)){
|
|
||||||
for (u32 i = 0; i < 2; i += 1){
|
|
||||||
Result.channel_volume[i] = 1.f;
|
|
||||||
}
|
|
||||||
Result.sample_count = SampleDataSize / (Format->wChannels*Format->wBitsPerSample/8);
|
|
||||||
Result.samples = (i16 *)Samples;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
// TODO(casey): This is where you would output an error - to 4coder somehow?
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
// TODO(casey): This is where you would output an error - to 4coder somehow?
|
|
||||||
}
|
|
||||||
|
|
||||||
return(Result);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Audio_Clip
|
|
||||||
audio_clip_from_wav_FILE(Arena *arena, FILE *file){
|
|
||||||
String_Const_u8 data = data_from_file(arena, file);
|
|
||||||
Audio_Clip result = audio_clip_from_wav_data(data);
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
function Audio_Clip
|
|
||||||
audio_clip_from_wav_file_name(Arena *arena, char *file_name){
|
|
||||||
Audio_Clip result = {};
|
|
||||||
String_Const_u8 data = {};
|
|
||||||
FILE *file = fopen(file_name, "rb");
|
|
||||||
if (file != 0){
|
|
||||||
result = audio_clip_from_wav_FILE(arena, file);
|
|
||||||
fclose(file);
|
|
||||||
}
|
|
||||||
return(result);
|
|
||||||
}
|
|
|
@ -1,56 +0,0 @@
|
||||||
/* date = November 23rd 2020 1:18 pm */
|
|
||||||
|
|
||||||
#ifndef FCODER_AUDIO_H
|
|
||||||
#define FCODER_AUDIO_H
|
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
// NOTE(allen): Default Mixer Types
|
|
||||||
|
|
||||||
struct Audio_Control{
|
|
||||||
volatile f32 channel_volume[2];
|
|
||||||
volatile u32 generation;
|
|
||||||
volatile u32 last_played_sample_index;
|
|
||||||
volatile b32 loop;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Audio_Clip{
|
|
||||||
i16 *samples;
|
|
||||||
Audio_Control *control;
|
|
||||||
f32 channel_volume[2];
|
|
||||||
|
|
||||||
u32 sample_count;
|
|
||||||
u32 at_sample_index;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Audio_System{
|
|
||||||
volatile u32 quit;
|
|
||||||
volatile u32 ticket;
|
|
||||||
volatile u32 serving;
|
|
||||||
volatile u32 generation;
|
|
||||||
|
|
||||||
Audio_Clip playing_clips[64];
|
|
||||||
|
|
||||||
// NOTE(casey): Requests to play sounds are written to a pending array to avoid long locking
|
|
||||||
volatile u32 pending_clip_count;
|
|
||||||
Audio_Clip pending_clips[64];
|
|
||||||
};
|
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
// NOTE(allen): Default Mixer
|
|
||||||
|
|
||||||
function void def_audio_init(void);
|
|
||||||
function void def_audio_play_clip(Audio_Clip clip, Audio_Control *control);
|
|
||||||
function b32 def_audio_is_playing(Audio_Control *control);
|
|
||||||
function void def_audio_stop(Audio_Control *control);
|
|
||||||
|
|
||||||
function void def_audio_mix_sources(void *ctx, f32 *mix_buffer, u32 sample_count);
|
|
||||||
function void def_audio_mix_destination(i16 *dst, f32 *src, u32 sample_count);
|
|
||||||
|
|
||||||
////////////////////////////////
|
|
||||||
// NOTE(allen): Loading Clip
|
|
||||||
|
|
||||||
function Audio_Clip audio_clip_from_wav_data(String_Const_u8 data);
|
|
||||||
function Audio_Clip audio_clip_from_wav_FILE(Arena *arena, FILE *file);
|
|
||||||
function Audio_Clip audio_clip_from_wav_file_name(Arena *arena, char *file_name);
|
|
||||||
|
|
||||||
#endif //4CODER_AUDIO_H
|
|
|
@ -437,14 +437,84 @@ CUSTOM_DOC("Auto-indents the range between the cursor and the mark.")
|
||||||
move_past_lead_whitespace(app, view, buffer);
|
move_past_lead_whitespace(app, view, buffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function i64
|
||||||
|
get_line_indent_level(Application_Links *app, View_ID view, Buffer_ID buffer, i64 line)
|
||||||
|
{
|
||||||
|
Scratch_Block scratch(app);
|
||||||
|
|
||||||
|
String_Const_u8 line_string = push_buffer_line(app, scratch, buffer, line);
|
||||||
|
i64 line_start_pos = get_line_start_pos(app, buffer, line);
|
||||||
|
|
||||||
|
Range_i64 line_indent_range = Ii64(0, 0);
|
||||||
|
i64 tabs_at_beginning = 0;
|
||||||
|
i64 spaces_at_beginning = 0;
|
||||||
|
for(u64 i = 0; i < line_string.size; i += 1)
|
||||||
|
{
|
||||||
|
if(line_string.str[i] == '\t')
|
||||||
|
{
|
||||||
|
tabs_at_beginning += 1;
|
||||||
|
}
|
||||||
|
else if(character_is_whitespace(line_string.str[i]))
|
||||||
|
{
|
||||||
|
spaces_at_beginning += 1;
|
||||||
|
}
|
||||||
|
else if(!character_is_whitespace(line_string.str[i]))
|
||||||
|
{
|
||||||
|
line_indent_range.max = (i64)i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(PS): This is in the event that we are unindenting a line that
|
||||||
|
// is JUST tabs or spaces - rather than unindenting nothing
|
||||||
|
// and then reindenting the proper amount, this should cause
|
||||||
|
// the removal of all leading tabs and spaces on an otherwise
|
||||||
|
// empty line
|
||||||
|
bool place_cursor_at_end = false;
|
||||||
|
if (line_indent_range.max == 0 && line_string.size > 0)
|
||||||
|
{
|
||||||
|
line_indent_range.max = line_string.size;
|
||||||
|
place_cursor_at_end = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
Range_i64 indent_range =
|
||||||
|
{
|
||||||
|
line_indent_range.min + line_start_pos,
|
||||||
|
line_indent_range.max + line_start_pos,
|
||||||
|
};
|
||||||
|
|
||||||
|
i64 indent_width = (i64)def_get_config_u64(app, vars_save_string_lit("indent_width"));
|
||||||
|
i64 spaces_per_indent_level = indent_width;
|
||||||
|
i64 indent_level = spaces_at_beginning / spaces_per_indent_level + tabs_at_beginning;
|
||||||
|
|
||||||
|
return indent_level;
|
||||||
|
}
|
||||||
|
|
||||||
|
function String_Const_u8
|
||||||
|
get_indent_string(Application_Links* app, Arena* scratch)
|
||||||
|
{
|
||||||
|
i64 indent_width = (i64)def_get_config_u64(app, vars_save_string_lit("indent_width"));
|
||||||
|
b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs"));
|
||||||
|
String_Const_u8 result;
|
||||||
|
if (indent_with_tabs) {
|
||||||
|
result = string_u8_litexpr("\t");
|
||||||
|
} else {
|
||||||
|
result = push_stringf(scratch, "%.*s", Min(indent_width, 16), " ");
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
CUSTOM_COMMAND_SIG(write_text_and_auto_indent)
|
CUSTOM_COMMAND_SIG(write_text_and_auto_indent)
|
||||||
CUSTOM_DOC("Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.")
|
CUSTOM_DOC("Inserts text and auto-indents the line on which the cursor sits if any of the text contains 'layout punctuation' such as ;:{}()[]# and new lines.")
|
||||||
{
|
{
|
||||||
ProfileScope(app, "write and auto indent");
|
ProfileScope(app, "write and auto indent");
|
||||||
|
Scratch_Block scratch(app);
|
||||||
User_Input in = get_current_input(app);
|
User_Input in = get_current_input(app);
|
||||||
String_Const_u8 insert = to_writable(&in);
|
String_Const_u8 insert = to_writable(&in);
|
||||||
if (insert.str != 0 && insert.size > 0){
|
if (insert.str != 0 && insert.size > 0){
|
||||||
b32 do_auto_indent = false;
|
b32 do_auto_indent = false;
|
||||||
|
b32 only_indent_next_line = true;
|
||||||
|
b32 is_newline = false;
|
||||||
for (u64 i = 0; !do_auto_indent && i < insert.size; i += 1){
|
for (u64 i = 0; !do_auto_indent && i < insert.size; i += 1){
|
||||||
switch (insert.str[i]){
|
switch (insert.str[i]){
|
||||||
case ';': case ':':
|
case ';': case ':':
|
||||||
|
@ -452,16 +522,30 @@ CUSTOM_DOC("Inserts text and auto-indents the line on which the cursor sits if a
|
||||||
case '(': case ')':
|
case '(': case ')':
|
||||||
case '[': case ']':
|
case '[': case ']':
|
||||||
case '#':
|
case '#':
|
||||||
case '\n': case '\t':
|
|
||||||
{
|
{
|
||||||
do_auto_indent = true;
|
do_auto_indent = true;
|
||||||
}break;
|
}break;
|
||||||
|
case '\n': case '\t':
|
||||||
|
{
|
||||||
|
do_auto_indent = true;
|
||||||
|
is_newline = true;
|
||||||
|
}break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
View_ID view = get_active_view(app, Access_ReadWriteVisible);
|
||||||
|
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||||
|
|
||||||
|
String_Const_u8 file_name = push_buffer_file_name(app, scratch, buffer);
|
||||||
|
String_Const_u8 ext = string_file_extension(file_name);
|
||||||
|
if (string_match(ext, string_u8_litexpr("js")) ||
|
||||||
|
string_match(ext, string_u8_litexpr("css")))
|
||||||
|
{
|
||||||
|
only_indent_next_line = do_auto_indent;
|
||||||
|
}
|
||||||
|
|
||||||
if (do_auto_indent){
|
if (do_auto_indent){
|
||||||
View_ID view = get_active_view(app, Access_ReadWriteVisible);
|
History_Group group = history_group_begin(app, buffer);
|
||||||
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
|
||||||
|
|
||||||
Range_i64 pos = {};
|
Range_i64 pos = {};
|
||||||
if (view_has_highlighted_range(app, view)){
|
if (view_has_highlighted_range(app, view)){
|
||||||
pos = get_view_range(app, view);
|
pos = get_view_range(app, view);
|
||||||
|
@ -473,11 +557,29 @@ CUSTOM_DOC("Inserts text and auto-indents the line on which the cursor sits if a
|
||||||
write_text_input(app);
|
write_text_input(app);
|
||||||
|
|
||||||
i64 end_pos = view_get_cursor_pos(app, view);
|
i64 end_pos = view_get_cursor_pos(app, view);
|
||||||
pos.min = Min(pos.min, end_pos);
|
if (!only_indent_next_line) {
|
||||||
pos.max = Max(pos.max, end_pos);
|
pos.min = Min(pos.min, end_pos);
|
||||||
|
pos.max = Max(pos.max, end_pos);
|
||||||
auto_indent_buffer(app, buffer, pos, 0);
|
auto_indent_buffer(app, buffer, pos, 0);
|
||||||
move_past_lead_whitespace(app, view, buffer);
|
move_past_lead_whitespace(app, view, buffer);
|
||||||
|
} else if (only_indent_next_line && is_newline) {
|
||||||
|
String_Const_u8 indent_string = get_indent_string(app, scratch);
|
||||||
|
|
||||||
|
// getting the indent from the PREVIOUS line, not the line
|
||||||
|
// the cursor is about to be on - since that line is new,
|
||||||
|
// and therefore, empty
|
||||||
|
i64 line = get_line_number_from_pos(app, buffer, pos.min);
|
||||||
|
i64 indent_level = get_line_indent_level(app, view, buffer, line);
|
||||||
|
|
||||||
|
pos.min = pos.max = end_pos;
|
||||||
|
|
||||||
|
for(i64 i = 0; i < indent_level; i += 1)
|
||||||
|
{
|
||||||
|
buffer_replace_range(app, buffer, Ii64(pos.max), indent_string);
|
||||||
|
}
|
||||||
|
move_past_lead_whitespace(app, view, buffer);
|
||||||
|
}
|
||||||
|
history_group_end(group);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
write_text_input(app);
|
write_text_input(app);
|
||||||
|
|
|
@ -159,6 +159,139 @@ CUSTOM_DOC("Delete characters between the cursor position and the first alphanum
|
||||||
push_boundary_list(scratch, boundary_alpha_numeric_unicode));
|
push_boundary_list(scratch, boundary_alpha_numeric_unicode));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function i64
|
||||||
|
get_boundary_token_or_whitespace(Application_Links *app, Buffer_ID buffer,
|
||||||
|
Side side, Scan_Direction direction, i64 pos)
|
||||||
|
{
|
||||||
|
// NOTE(PS): originally this was F4_Boundary_TokenAndWhitespace
|
||||||
|
i64 result = boundary_non_whitespace(app, buffer, side, direction, pos);
|
||||||
|
Token_Array tokens = get_token_array_from_buffer(app, buffer);
|
||||||
|
if (tokens.tokens != 0){
|
||||||
|
switch (direction){
|
||||||
|
case Scan_Forward:
|
||||||
|
{
|
||||||
|
i64 buffer_size = buffer_get_size(app, buffer);
|
||||||
|
result = buffer_size;
|
||||||
|
if(tokens.count > 0)
|
||||||
|
{
|
||||||
|
Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos);
|
||||||
|
Token *token = token_it_read(&it);
|
||||||
|
|
||||||
|
if(token == 0)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(rjf): Comments/Strings
|
||||||
|
if(token->kind == TokenBaseKind_Comment ||
|
||||||
|
token->kind == TokenBaseKind_LiteralString)
|
||||||
|
{
|
||||||
|
result = boundary_non_whitespace(app, buffer, side, direction, pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(rjf): All other cases.
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (token->kind == TokenBaseKind_Whitespace)
|
||||||
|
{
|
||||||
|
// token_it_inc_non_whitespace(&it);
|
||||||
|
// token = token_it_read(&it);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (side == Side_Max){
|
||||||
|
result = token->pos + token->size;
|
||||||
|
|
||||||
|
token_it_inc_all(&it);
|
||||||
|
Token *ws = token_it_read(&it);
|
||||||
|
if(ws != 0 && ws->kind == TokenBaseKind_Whitespace &&
|
||||||
|
get_line_number_from_pos(app, buffer, ws->pos + ws->size) ==
|
||||||
|
get_line_number_from_pos(app, buffer, token->pos))
|
||||||
|
{
|
||||||
|
result = ws->pos + ws->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (token->pos <= pos){
|
||||||
|
token_it_inc_non_whitespace(&it);
|
||||||
|
token = token_it_read(&it);
|
||||||
|
}
|
||||||
|
if (token != 0){
|
||||||
|
result = token->pos;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case Scan_Backward:
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
if (tokens.count > 0){
|
||||||
|
Token_Iterator_Array it = token_iterator_pos(0, &tokens, pos);
|
||||||
|
Token *token = token_it_read(&it);
|
||||||
|
|
||||||
|
Token_Iterator_Array it2 = it;
|
||||||
|
token_it_dec_non_whitespace(&it2);
|
||||||
|
Token *token2 = token_it_read(&it2);
|
||||||
|
|
||||||
|
// NOTE(rjf): Comments/Strings
|
||||||
|
if(token->kind == TokenBaseKind_Comment ||
|
||||||
|
token->kind == TokenBaseKind_LiteralString ||
|
||||||
|
(token2 &&
|
||||||
|
token2->kind == TokenBaseKind_Comment ||
|
||||||
|
token2->kind == TokenBaseKind_LiteralString))
|
||||||
|
{
|
||||||
|
result = boundary_non_whitespace(app, buffer, side, direction, pos);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (token->kind == TokenBaseKind_Whitespace){
|
||||||
|
token_it_dec_non_whitespace(&it);
|
||||||
|
token = token_it_read(&it);
|
||||||
|
}
|
||||||
|
if (token != 0){
|
||||||
|
if (side == Side_Min){
|
||||||
|
if (token->pos >= pos){
|
||||||
|
token_it_dec_non_whitespace(&it);
|
||||||
|
token = token_it_read(&it);
|
||||||
|
}
|
||||||
|
result = token->pos;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
if (token->pos + token->size >= pos){
|
||||||
|
token_it_dec_non_whitespace(&it);
|
||||||
|
token = token_it_read(&it);
|
||||||
|
}
|
||||||
|
result = token->pos + token->size;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(backspace_alpha_numeric_or_camel_boundary)
|
||||||
|
CUSTOM_DOC("Deletes left to a alphanumeric or camel boundary.")
|
||||||
|
{
|
||||||
|
Scratch_Block scratch(app);
|
||||||
|
current_view_boundary_delete(app, Scan_Backward, push_boundary_list(scratch,
|
||||||
|
boundary_line,
|
||||||
|
boundary_alpha_numeric,
|
||||||
|
boundary_alpha_numeric_camel));
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(backspace_token_boundary)
|
||||||
|
CUSTOM_DOC("Deletes left to a token boundary.")
|
||||||
|
{
|
||||||
|
Scratch_Block scratch(app);
|
||||||
|
Boundary_Function_List boundary_list = push_boundary_list(scratch, get_boundary_token_or_whitespace);
|
||||||
|
current_view_boundary_delete(app, Scan_Backward, boundary_list);
|
||||||
|
}
|
||||||
|
|
||||||
CUSTOM_COMMAND_SIG(delete_alpha_numeric_boundary)
|
CUSTOM_COMMAND_SIG(delete_alpha_numeric_boundary)
|
||||||
CUSTOM_DOC("Delete characters between the cursor position and the first alphanumeric boundary to the right.")
|
CUSTOM_DOC("Delete characters between the cursor position and the first alphanumeric boundary to the right.")
|
||||||
{
|
{
|
||||||
|
@ -1573,6 +1706,31 @@ CUSTOM_DOC("Delete the line the on which the cursor sits.")
|
||||||
buffer_replace_range(app, buffer, range, string_u8_litexpr(""));
|
buffer_replace_range(app, buffer, range, string_u8_litexpr(""));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(delete_to_end_of_line)
|
||||||
|
CUSTOM_DOC("Deletes all text from the cursor to the end of the line")
|
||||||
|
{
|
||||||
|
View_ID view = get_active_view(app, Access_ReadWriteVisible);
|
||||||
|
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||||
|
i64 pos = view_get_cursor_pos(app, view);
|
||||||
|
i64 line_number = get_line_number_from_pos(app, buffer, pos);
|
||||||
|
Range_Cursor line_range = get_line_range(app, buffer, line_number);
|
||||||
|
Range_i64 delete_range = {};
|
||||||
|
|
||||||
|
if (line_range.start.line != 0 && line_range.end.line != 0)
|
||||||
|
{
|
||||||
|
delete_range = Ii64(pos, line_range.end.pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (range_size(delete_range) == 0)
|
||||||
|
{
|
||||||
|
delete_range.end += 1;
|
||||||
|
i32 buffer_size = (i32)buffer_get_size(app, buffer);
|
||||||
|
delete_range.end = clamp_top(delete_range.end, buffer_size);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer_replace_range(app, buffer, delete_range, string_u8_litexpr(""));
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
CUSTOM_COMMAND_SIG(open_file_in_quotes)
|
CUSTOM_COMMAND_SIG(open_file_in_quotes)
|
||||||
|
@ -2077,5 +2235,284 @@ CUSTOM_DOC("Notes the external modification of attached files by printing a mess
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(toggle_compilation_view)
|
||||||
|
{
|
||||||
|
Buffer_ID buffer = view_get_buffer(app, global_compilation_view, Access_Always);
|
||||||
|
Face_ID face_id = get_face_id(app, buffer);
|
||||||
|
Face_Metrics metrics = get_face_metrics(app, face_id);
|
||||||
|
if(global_compilation_view_expanded ^= 1)
|
||||||
|
{
|
||||||
|
view_set_split_pixel_size(app, global_compilation_view, (i32)(metrics.line_height*32.f));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
view_set_split_pixel_size(app, global_compilation_view, (i32)(metrics.line_height*4.f));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
////////////////////////////////////////
|
||||||
|
// Indentation
|
||||||
|
|
||||||
|
|
||||||
|
function void
|
||||||
|
reindent_line(Application_Links *app, Buffer_ID buffer, i64 line, i64 indent_delta)
|
||||||
|
{
|
||||||
|
Scratch_Block scratch(app);
|
||||||
|
View_ID view = get_active_view(app, Access_ReadWriteVisible);
|
||||||
|
|
||||||
|
String_Const_u8 line_string = push_buffer_line(app, scratch, buffer, line);
|
||||||
|
i64 line_start_pos = get_line_start_pos(app, buffer, line);
|
||||||
|
|
||||||
|
Range_i64 line_indent_range = Ii64(0, 0);
|
||||||
|
i64 tabs_at_beginning = 0;
|
||||||
|
i64 spaces_at_beginning = 0;
|
||||||
|
for(u64 i = 0; i < line_string.size; i += 1)
|
||||||
|
{
|
||||||
|
if(line_string.str[i] == '\t')
|
||||||
|
{
|
||||||
|
tabs_at_beginning += 1;
|
||||||
|
}
|
||||||
|
else if(character_is_whitespace(line_string.str[i]))
|
||||||
|
{
|
||||||
|
spaces_at_beginning += 1;
|
||||||
|
}
|
||||||
|
else if(!character_is_whitespace(line_string.str[i]))
|
||||||
|
{
|
||||||
|
line_indent_range.max = (i64)i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(PS): This is in the event that we are unindenting a line that
|
||||||
|
// is JUST tabs or spaces - rather than unindenting nothing
|
||||||
|
// and then reindenting the proper amount, this should cause
|
||||||
|
// the removal of all leading tabs and spaces on an otherwise
|
||||||
|
// empty line
|
||||||
|
bool place_cursor_at_end = false;
|
||||||
|
if (line_indent_range.max == 0 && line_string.size == (u64)(spaces_at_beginning + tabs_at_beginning))
|
||||||
|
{
|
||||||
|
line_indent_range.max = line_string.size;
|
||||||
|
place_cursor_at_end = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(rjf): Indent lines.
|
||||||
|
{
|
||||||
|
Range_i64 indent_range =
|
||||||
|
{
|
||||||
|
line_indent_range.min + line_start_pos,
|
||||||
|
line_indent_range.max + line_start_pos,
|
||||||
|
};
|
||||||
|
|
||||||
|
i64 indent_width = (i64)def_get_config_u64(app, vars_save_string_lit("indent_width"));
|
||||||
|
b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs"));
|
||||||
|
i64 spaces_per_indent_level = indent_width;
|
||||||
|
i64 indent_level = spaces_at_beginning / spaces_per_indent_level + tabs_at_beginning;
|
||||||
|
i64 new_indent_level = indent_level + indent_delta;
|
||||||
|
|
||||||
|
String_Const_u8 indent_string;
|
||||||
|
if (indent_with_tabs) {
|
||||||
|
indent_string = str8_lit("\t");
|
||||||
|
} else {
|
||||||
|
indent_string = push_stringf(scratch, "%.*s", Min(indent_width, 16), " ");
|
||||||
|
}
|
||||||
|
buffer_replace_range(app, buffer, indent_range, str8_lit(""));
|
||||||
|
for(i64 i = 0; i < new_indent_level; i += 1)
|
||||||
|
{
|
||||||
|
buffer_replace_range(app, buffer, Ii64(line_start_pos), indent_string);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (place_cursor_at_end)
|
||||||
|
{
|
||||||
|
// update line_string now that we've edited the line
|
||||||
|
line_string = push_buffer_line(app, scratch, buffer, line);
|
||||||
|
|
||||||
|
line_start_pos = get_line_start_pos(app, buffer, line);
|
||||||
|
i64 line_end_pos = line_start_pos + line_string.size;
|
||||||
|
view_set_cursor(app, view, seek_pos(line_end_pos));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
reindent_line_range(Application_Links *app, Buffer_ID buffer, Range_i64 range, i64 indent_delta)
|
||||||
|
{
|
||||||
|
for(i64 i = range.min; i <= range.max; i += 1)
|
||||||
|
{
|
||||||
|
reindent_line(app, buffer, i, indent_delta);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(PS): @F4Layer - it's unclear why we need these, when there's existing, similarly named functions
|
||||||
|
// already in the codebase. (Just remove the f4_ and the compiler will show you where).
|
||||||
|
internal Range_i64
|
||||||
|
f4_get_line_range_from_pos_range(Application_Links *app, Buffer_ID buffer, Range_i64 pos_range)
|
||||||
|
{
|
||||||
|
Range_i64 lines_range =
|
||||||
|
Ii64(get_line_number_from_pos(app, buffer, pos_range.min),
|
||||||
|
get_line_number_from_pos(app, buffer, pos_range.max));
|
||||||
|
return lines_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO(PS): @F4Layer
|
||||||
|
internal Range_i64
|
||||||
|
f4_get_pos_range_from_line_range(Application_Links *app, Buffer_ID buffer, Range_i64 line_range)
|
||||||
|
{
|
||||||
|
if(line_range.min > line_range.max)
|
||||||
|
{
|
||||||
|
i64 swap = line_range.max;
|
||||||
|
line_range.max = line_range.min;
|
||||||
|
line_range.min = swap;
|
||||||
|
}
|
||||||
|
Range_i64 pos_range =
|
||||||
|
Ii64(get_line_start_pos(app, buffer, line_range.min),
|
||||||
|
get_line_end_pos(app, buffer, line_range.max));
|
||||||
|
return pos_range;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
reindent_pos_range(Application_Links *app, Buffer_ID buffer, Range_i64 range, i64 indent_delta)
|
||||||
|
{
|
||||||
|
reindent_line_range(app, buffer,
|
||||||
|
f4_get_line_range_from_pos_range(app, buffer, range),
|
||||||
|
indent_delta);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(unindent_line)
|
||||||
|
{
|
||||||
|
View_ID view = get_active_view(app, Access_ReadWrite);
|
||||||
|
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||||
|
i64 pos = view_get_cursor_pos(app, view);
|
||||||
|
i64 line = get_line_number_from_pos(app, buffer, pos);
|
||||||
|
reindent_line(app, buffer, line, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
adjust_cursor_and_mark_for_indentation(Application_Links *app, View_ID view, i64 original_cursor, i64 original_mark, Range_i64 original_line_range)
|
||||||
|
{
|
||||||
|
Buffer_ID buffer = view_get_buffer(app, view, Access_Read);
|
||||||
|
Scratch_Block scratch(app);
|
||||||
|
if(original_cursor == original_mark)
|
||||||
|
{
|
||||||
|
i64 start_pos = get_line_start_pos(app, buffer, original_line_range.min);
|
||||||
|
i64 new_pos = start_pos;
|
||||||
|
String_Const_u8 line = push_buffer_line(app, scratch, buffer, original_line_range.min);
|
||||||
|
for(u64 i = 0; i < line.size; i += 1)
|
||||||
|
{
|
||||||
|
if(!character_is_whitespace(line.str[i]))
|
||||||
|
{
|
||||||
|
new_pos = start_pos + (i64)i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
view_set_cursor(app, view, seek_pos(new_pos));
|
||||||
|
view_set_mark(app, view, seek_pos(new_pos));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
Range_i64 range = f4_get_pos_range_from_line_range(app, buffer, original_line_range);
|
||||||
|
view_set_cursor(app, view, seek_pos(original_cursor > original_mark ? range.max : range.min));
|
||||||
|
view_set_mark(app, view, seek_pos(original_cursor > original_mark ? range.min : range.max));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
update_range_indentation(Application_Links* app, i32 indent_offset)
|
||||||
|
{
|
||||||
|
Scratch_Block scratch(app);
|
||||||
|
View_ID view = get_active_view(app, Access_ReadWrite);
|
||||||
|
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWrite);
|
||||||
|
i64 pos = view_get_cursor_pos(app, view);
|
||||||
|
i64 mark = view_get_mark_pos(app, view);
|
||||||
|
Range_i64 pos_range = Ii64(pos, mark);
|
||||||
|
Range_i64 line_range = get_line_range_from_pos_range(app, buffer, pos_range);
|
||||||
|
History_Group group = history_group_begin(app, buffer);
|
||||||
|
reindent_pos_range(app, buffer, Ii64(pos, mark), indent_offset);
|
||||||
|
adjust_cursor_and_mark_for_indentation(app, view, pos, mark, line_range);
|
||||||
|
history_group_end(group);
|
||||||
|
no_mark_snap_to_cursor(app, view);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(indent_range)
|
||||||
|
{
|
||||||
|
update_range_indentation(app, 1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(unindent_range)
|
||||||
|
{
|
||||||
|
update_range_indentation(app, -1);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(indent_or_autocomplete)
|
||||||
|
{
|
||||||
|
Scratch_Block scratch(app);
|
||||||
|
|
||||||
|
View_ID view = get_active_view(app, Access_ReadVisible);
|
||||||
|
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||||
|
if (buffer != 0)
|
||||||
|
{
|
||||||
|
i64 pos = view_get_cursor_pos(app, view);
|
||||||
|
Buffer_Cursor buffer_cursor = buffer_compute_cursor(app, buffer, seek_pos(pos));
|
||||||
|
Buffer_Cursor line_start_cursor = get_line_start(app, buffer, buffer_cursor.line);
|
||||||
|
u8 char_before = buffer_get_char(app, buffer, pos - 1);
|
||||||
|
if ((buffer_cursor.pos == line_start_cursor.pos) || character_is_whitespace(char_before))
|
||||||
|
{
|
||||||
|
i64 indent_width = (i64)def_get_config_u64(app, vars_save_string_lit("indent_width"));
|
||||||
|
b32 indent_with_tabs = def_get_config_b32(vars_save_string_lit("indent_with_tabs"));
|
||||||
|
String_Const_u8 indent_string;
|
||||||
|
if (indent_with_tabs) {
|
||||||
|
indent_string = str8_lit("\t");
|
||||||
|
} else {
|
||||||
|
indent_string = push_stringf(scratch, "%.*s", Min(indent_width, 16), " ");
|
||||||
|
}
|
||||||
|
write_text(app, indent_string);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
word_complete(app);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
///////////////////////////////////////////
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(input_enter_behavior)
|
||||||
|
{
|
||||||
|
View_ID view = get_active_view(app, Access_ReadVisible);
|
||||||
|
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||||
|
if (buffer == 0)
|
||||||
|
{
|
||||||
|
buffer = view_get_buffer(app, view, Access_ReadVisible);
|
||||||
|
if (buffer != 0)
|
||||||
|
{
|
||||||
|
goto_jump_at_cursor(app);
|
||||||
|
lock_jump_buffer(app, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
|
||||||
|
leave_current_input_unhandled(app);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(input_alt_enter_behavior)
|
||||||
|
{
|
||||||
|
View_ID view = get_active_view(app, Access_ReadVisible);
|
||||||
|
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||||
|
if (buffer == 0){
|
||||||
|
buffer = view_get_buffer(app, view, Access_ReadVisible);
|
||||||
|
if (buffer != 0){
|
||||||
|
goto_jump_at_cursor_same_panel(app);
|
||||||
|
lock_jump_buffer(app, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
leave_current_input_unhandled(app);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
||||||
|
|
|
@ -4990,6 +4990,27 @@ string_find_first_insensitive(String_Const_u32 str, String_Const_u32 needle){
|
||||||
return(string_find_first(str, needle, StringMatch_CaseInsensitive));
|
return(string_find_first(str, needle, StringMatch_CaseInsensitive));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
function u64
|
||||||
|
string_find_first_of_set(String_Const_u8 str, String_Const_u8 needle)
|
||||||
|
{
|
||||||
|
u64 i = 0;
|
||||||
|
if (needle.size > 0){
|
||||||
|
i = 0;
|
||||||
|
for (;i < str.size; i += 1){
|
||||||
|
bool found = false;
|
||||||
|
for (u64 j = 0; j < needle.size; j++)
|
||||||
|
{
|
||||||
|
if (str.str[i] == needle.str[j]) {
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (found) break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(i);
|
||||||
|
}
|
||||||
|
|
||||||
function b32
|
function b32
|
||||||
string_has_substr(String_Const_u8 str, String_Const_u8 needle, String_Match_Rule rule){
|
string_has_substr(String_Const_u8 str, String_Const_u8 needle, String_Match_Rule rule){
|
||||||
return(string_find_first(str, needle, rule) < str.size);
|
return(string_find_first(str, needle, rule) < str.size);
|
||||||
|
|
|
@ -95,5 +95,95 @@ CUSTOM_DOC("Jump to the first definition in the code index matching an identifie
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
global String_Const_u8 code_index_note_strs[] = {
|
||||||
|
str8_lit("Type"),
|
||||||
|
str8_lit("Function"),
|
||||||
|
str8_lit("Macro"),
|
||||||
|
str8_lit("None"),
|
||||||
|
};
|
||||||
|
|
||||||
|
function bool
|
||||||
|
note_is_of_kind(Code_Index_Note_Kind* kinds, i32 kinds_count, Code_Index_Note* note)
|
||||||
|
{
|
||||||
|
bool result = false;
|
||||||
|
for (i32 i = 0; i < kinds_count; i++)
|
||||||
|
{
|
||||||
|
if (kinds[i] == note->note_kind)
|
||||||
|
{
|
||||||
|
result = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
lister_add_from_buffer_code_index_filtered(Lister* lister, Buffer_ID buffer, Arena* scratch, Code_Index_Note_Kind* kinds, i32 kinds_count, bool filter_all_but_last)
|
||||||
|
{
|
||||||
|
Code_Index_File* file_notes = code_index_get_file(buffer);
|
||||||
|
if (!file_notes) return;
|
||||||
|
|
||||||
|
for (Code_Index_Note* note = file_notes->note_list.first;
|
||||||
|
note != 0;
|
||||||
|
note = note->next)
|
||||||
|
{
|
||||||
|
if (!note_is_of_kind(kinds, kinds_count, note)) continue;
|
||||||
|
if (filter_all_but_last && note->next_in_hash) continue;
|
||||||
|
|
||||||
|
String_Const_u8 sort = code_index_note_strs[note->note_kind];
|
||||||
|
|
||||||
|
Tiny_Jump *jump = push_array(scratch, Tiny_Jump, 1);
|
||||||
|
jump->buffer = buffer;
|
||||||
|
jump->pos = note->pos.start;
|
||||||
|
|
||||||
|
lister_add_item(lister, note->text, sort, jump, 0);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
run_jump_lister(Application_Links* app, Lister* lister)
|
||||||
|
{
|
||||||
|
Lister_Result l_result = run_lister(app, lister);
|
||||||
|
Tiny_Jump result = {};
|
||||||
|
if (!l_result.canceled && l_result.user_data != 0){
|
||||||
|
block_copy_struct(&result, (Tiny_Jump*)l_result.user_data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (result.buffer != 0)
|
||||||
|
{
|
||||||
|
View_ID view = get_this_ctx_view(app, Access_Always);
|
||||||
|
point_stack_push_view_cursor(app, view);
|
||||||
|
jump_to_location(app, view, result.buffer, result.pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
lister_search_filtered(Application_Links* app, char* query, Code_Index_Note_Kind* allowed, i32 allowed_count, bool filter_all_but_last)
|
||||||
|
{
|
||||||
|
Scratch_Block scratch(app);
|
||||||
|
Lister_Block lister(app, scratch);
|
||||||
|
lister_set_query(lister, query);
|
||||||
|
lister_set_default_handlers(lister);
|
||||||
|
|
||||||
|
for (Buffer_ID buffer = get_buffer_next(app, 0, Access_Always);
|
||||||
|
buffer != 0; buffer = get_buffer_next(app, buffer, Access_Always))
|
||||||
|
{
|
||||||
|
lister_add_from_buffer_code_index_filtered(lister, buffer, scratch, allowed, allowed_count, filter_all_but_last);
|
||||||
|
}
|
||||||
|
run_jump_lister(app, lister);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_UI_COMMAND_SIG(lister_search_all)
|
||||||
|
CUSTOM_DOC("Runs a search lister on all code indices of the project")
|
||||||
|
{
|
||||||
|
char *query = "Search:";
|
||||||
|
Code_Index_Note_Kind allowed[] = {
|
||||||
|
CodeIndexNote_Macro,
|
||||||
|
CodeIndexNote_Function,
|
||||||
|
CodeIndexNote_Type,
|
||||||
|
};
|
||||||
|
lister_search_filtered(app, query, allowed, 3, false);
|
||||||
|
}
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
||||||
|
|
|
@ -296,7 +296,6 @@ map_get_binding_non_recursive(Command_Map *map, Input_Event *event, Binding_Matc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
case BindingMatchRule_Loose:
|
case BindingMatchRule_Loose:
|
||||||
{
|
{
|
||||||
for (SNode *node = list->first;
|
for (SNode *node = list->first;
|
||||||
|
@ -310,7 +309,7 @@ map_get_binding_non_recursive(Command_Map *map, Input_Event *event, Binding_Matc
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
}
|
}
|
||||||
done:;
|
done:;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
|
|
|
@ -39,8 +39,7 @@ def_search_normal_fopen(Arena *arena, char *file_name, char *opt){
|
||||||
// NOTE(allen): Extension List
|
// NOTE(allen): Extension List
|
||||||
|
|
||||||
function String_Const_u8_Array
|
function String_Const_u8_Array
|
||||||
parse_extension_line_to_extension_list(Application_Links *app, Arena *arena, String_Const_u8 str){
|
parse_extension_line_to_extension_list(Arena *arena, String_Const_u8 str){
|
||||||
ProfileScope(app, "parse extension line to extension list");
|
|
||||||
i32 count = 0;
|
i32 count = 0;
|
||||||
for (u64 i = 0; i < str.size; i += 1){
|
for (u64 i = 0; i < str.size; i += 1){
|
||||||
if (str.str[i] == '.'){
|
if (str.str[i] == '.'){
|
||||||
|
@ -65,6 +64,13 @@ parse_extension_line_to_extension_list(Application_Links *app, Arena *arena, Str
|
||||||
return(array);
|
return(array);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function String_Const_u8_Array
|
||||||
|
parse_extension_line_to_extension_list(Application_Links *app, Arena *arena, String_Const_u8 str){
|
||||||
|
ProfileScope(app, "parse extension line to extension list");
|
||||||
|
return parse_extension_line_to_extension_list(arena, str);
|
||||||
|
}
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
// NOTE(allen): Token Array
|
// NOTE(allen): Token Array
|
||||||
|
|
||||||
|
|
|
@ -15,15 +15,276 @@
|
||||||
#include "generated/managed_id_metadata.cpp"
|
#include "generated/managed_id_metadata.cpp"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#define EXTERNAL_KEYBOARD 0
|
||||||
|
#if OS_MAC && !EXTERNAL_KEYBOARD
|
||||||
|
global u32 key_alt = KeyCode_Command;
|
||||||
|
#else
|
||||||
|
global u32 key_alt = KeyCode_Alt;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
function String_Const_u8
|
||||||
|
get_lexeme_under_cursor(Application_Links* app, View_ID view, Buffer_ID buffer, Arena* arena)
|
||||||
|
{
|
||||||
|
String_Const_u8 lexeme = {0};
|
||||||
|
i64 pos = view_get_cursor_pos(app, view);
|
||||||
|
Token* token = get_token_from_pos(app, buffer, pos);
|
||||||
|
if (token != 0) {
|
||||||
|
lexeme = push_token_lexeme(app, arena, buffer, token);
|
||||||
|
}
|
||||||
|
return lexeme;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
go_to_definition(Application_Links* app, String_Const_u8 lexeme, View_ID view)
|
||||||
|
{
|
||||||
|
Code_Index_Note* note = 0;
|
||||||
|
|
||||||
|
// if we're trying to go to the definition of the same lexeme as last time
|
||||||
|
// then there are probably a typedef + declaration in different locations so
|
||||||
|
// we want to advance to the next code index note that matches this lexeme
|
||||||
|
// and then loop
|
||||||
|
if (string_match(go_to_definition_last_lexeme, lexeme))
|
||||||
|
{
|
||||||
|
Code_Index_Note_List* list = code_index__list_from_string(lexeme);
|
||||||
|
u64 i = 0;
|
||||||
|
for (Code_Index_Note *it = list->first;
|
||||||
|
it != 0;
|
||||||
|
it = it->next_in_hash, i++){
|
||||||
|
if (string_match(lexeme, it->text) && i > go_to_definition_last_lexeme_index){
|
||||||
|
note = it;
|
||||||
|
go_to_definition_last_lexeme_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!note)
|
||||||
|
{
|
||||||
|
note = code_index_note_from_string(lexeme);
|
||||||
|
go_to_definition_last_lexeme = lexeme;
|
||||||
|
go_to_definition_last_lexeme_index = 0;
|
||||||
|
}
|
||||||
|
if (note == 0) return;
|
||||||
|
|
||||||
|
Buffer_ID buffer = note->file->buffer;
|
||||||
|
view_set_buffer(app, view, buffer, 0);
|
||||||
|
|
||||||
|
switch (note->note_kind)
|
||||||
|
{
|
||||||
|
case CodeIndexNote_Type:
|
||||||
|
case CodeIndexNote_Function:
|
||||||
|
case CodeIndexNote_Macro:
|
||||||
|
{
|
||||||
|
jump_to_location(app, view, note->file->buffer, note->pos.start);
|
||||||
|
} break;
|
||||||
|
|
||||||
|
default: {} break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(cmd_enter_behavior)
|
||||||
|
{
|
||||||
|
View_ID view = get_active_view(app, Access_ReadVisible);
|
||||||
|
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||||
|
if (buffer == 0){
|
||||||
|
buffer = view_get_buffer(app, view, Access_ReadVisible);
|
||||||
|
if (buffer != 0){
|
||||||
|
goto_jump_at_cursor(app);
|
||||||
|
lock_jump_buffer(app, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Scratch_Block scratch(app);
|
||||||
|
String_Const_u8 lexeme = get_lexeme_under_cursor(app, view, buffer, scratch);
|
||||||
|
if (lexeme.size > 0) {
|
||||||
|
go_to_definition(app, lexeme, view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(cmd_alt_enter_behavior)
|
||||||
|
{
|
||||||
|
View_ID view = get_active_view(app, Access_ReadVisible);
|
||||||
|
Buffer_ID buffer = view_get_buffer(app, view, Access_ReadWriteVisible);
|
||||||
|
if (buffer == 0){
|
||||||
|
buffer = view_get_buffer(app, view, Access_ReadVisible);
|
||||||
|
if (buffer != 0){
|
||||||
|
goto_jump_at_cursor_same_panel(app);
|
||||||
|
lock_jump_buffer(app, buffer);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Scratch_Block scratch(app);
|
||||||
|
String_Const_u8 lexeme = get_lexeme_under_cursor(app, view, buffer, scratch);
|
||||||
|
if (lexeme.size > 0) {
|
||||||
|
view = get_next_view_looped_primary_panels(app, view, Access_Always);
|
||||||
|
go_to_definition(app, lexeme, view);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
function void
|
||||||
|
bindings_cmd_misc(Mapping* m, Command_Map* map)
|
||||||
|
{
|
||||||
|
Bind(command_lister, KeyCode_W);
|
||||||
|
Bind(change_active_panel, KeyCode_E);
|
||||||
|
Bind(toggle_compilation_view, KeyCode_Minus);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
bindings_cmd_file_ops(Mapping* m, Command_Map* map)
|
||||||
|
{
|
||||||
|
Bind(set_mark, KeyCode_Space);
|
||||||
|
Bind(interactive_open_or_new, KeyCode_Comma);
|
||||||
|
Bind(interactive_switch_buffer, KeyCode_Period);
|
||||||
|
Bind(save, KeyCode_Semicolon);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
bindings_cmd_search(Mapping* m, Command_Map* map)
|
||||||
|
{
|
||||||
|
Bind(query_replace, KeyCode_S);
|
||||||
|
Bind(search, KeyCode_F);
|
||||||
|
Bind(list_all_locations_of_identifier, KeyCode_D);
|
||||||
|
Bind(list_all_substring_locations_case_insensitive, KeyCode_D, key_alt);
|
||||||
|
Bind(goto_next_jump, KeyCode_T);
|
||||||
|
Bind(goto_prev_jump, KeyCode_R);
|
||||||
|
|
||||||
|
// Listers
|
||||||
|
Bind(lister_search_all, KeyCode_1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
bindings_cmd_nav(Mapping* m, Command_Map* map)
|
||||||
|
{
|
||||||
|
Bind(seek_beginning_of_line, KeyCode_Y);
|
||||||
|
Bind(seek_end_of_line, KeyCode_P);
|
||||||
|
Bind(move_left_token_boundary, KeyCode_U);
|
||||||
|
Bind(move_right_token_boundary, KeyCode_O);
|
||||||
|
|
||||||
|
Bind(move_up, KeyCode_I);
|
||||||
|
Bind(move_left, KeyCode_J);
|
||||||
|
Bind(move_down, KeyCode_K);
|
||||||
|
Bind(move_right, KeyCode_L);
|
||||||
|
|
||||||
|
|
||||||
|
Bind(move_up_to_blank_line_end, KeyCode_H);
|
||||||
|
Bind(move_down_to_blank_line_end, KeyCode_N);
|
||||||
|
|
||||||
|
Bind(cmd_enter_behavior, KeyCode_Return);
|
||||||
|
Bind(cmd_alt_enter_behavior, KeyCode_Return, key_alt);
|
||||||
|
Bind(jump_to_last_point, KeyCode_Semicolon, KeyCode_Control);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
custom_keyboard_bindings()
|
||||||
|
{
|
||||||
|
modal_set_cursor_color_u32(modal_mode_input, 0xFF00FF00);
|
||||||
|
modal_set_cursor_color_u32(modal_mode_cmd, 0xFFFF0000);
|
||||||
|
modal_set_cursor_color_u32(modal_mode_debug, 0xFF00F0FF);
|
||||||
|
|
||||||
|
MappingScope();
|
||||||
|
|
||||||
|
// Global commands
|
||||||
|
modal_bind_all(modal_map_id_global, modal_set_mode_toggle, KeyCode_F, key_alt, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, modal_set_mode_next, KeyCode_F, KeyCode_Control, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, exit_4coder, KeyCode_F4, key_alt, 0);
|
||||||
|
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F1, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F2, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F3, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F4, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F5, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F6, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F7, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F8, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F9, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F10, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F11, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F12, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F13, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F14, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F15, 0, 0);
|
||||||
|
modal_bind_all(modal_map_id_global, project_fkey_command, KeyCode_F16, 0, 0);
|
||||||
|
|
||||||
|
SelectMapping(&modal_get_mode(modal_mode_cmd)->map);
|
||||||
|
SelectMap(modal_map_id_global);
|
||||||
|
{
|
||||||
|
bindings_cmd_file_ops(m, map);
|
||||||
|
bindings_cmd_misc(m, map);
|
||||||
|
bindings_cmd_search(m, map);
|
||||||
|
bindings_cmd_nav(m, map);
|
||||||
|
|
||||||
|
// Text Editing
|
||||||
|
Bind(delete_to_end_of_line, KeyCode_A);
|
||||||
|
Bind(undo, KeyCode_Z);
|
||||||
|
Bind(redo, KeyCode_B);
|
||||||
|
Bind(copy, KeyCode_C);
|
||||||
|
Bind(paste, KeyCode_V);
|
||||||
|
Bind(cut, KeyCode_X);
|
||||||
|
Bind(backspace_char, KeyCode_Backspace);
|
||||||
|
Bind(backspace_alpha_numeric_or_camel_boundary, KeyCode_Backspace, key_alt);
|
||||||
|
Bind(backspace_token_boundary, KeyCode_Backspace, KeyCode_Control);
|
||||||
|
Bind(unindent_range, KeyCode_Tab, KeyCode_Shift);
|
||||||
|
Bind(indent_range, KeyCode_Tab);
|
||||||
|
|
||||||
|
// Macros
|
||||||
|
Bind(keyboard_macro_start_recording, KeyCode_1, key_alt);
|
||||||
|
Bind(keyboard_macro_finish_recording, KeyCode_2, key_alt);
|
||||||
|
Bind(keyboard_macro_replay, KeyCode_3, key_alt);
|
||||||
|
|
||||||
|
// Yeet Sheet
|
||||||
|
Bind(loco_yeet_selected_range_or_jump, KeyCode_G);
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectMapping(&modal_get_mode(modal_mode_input)->map);
|
||||||
|
SelectMap(modal_map_id_global);
|
||||||
|
{
|
||||||
|
BindMouse(click_set_cursor_and_mark, MouseCode_Left);
|
||||||
|
BindMouseRelease(click_set_cursor, MouseCode_Left);
|
||||||
|
BindCore(click_set_cursor_and_mark, CoreCode_ClickActivateView);
|
||||||
|
BindMouseMove(click_set_cursor_if_lbutton);
|
||||||
|
|
||||||
|
Bind(delete_char, KeyCode_Delete);
|
||||||
|
Bind(backspace_char, KeyCode_Backspace);
|
||||||
|
Bind(backspace_alpha_numeric_or_camel_boundary, KeyCode_Backspace, key_alt);
|
||||||
|
Bind(backspace_token_boundary, KeyCode_Backspace, KeyCode_Control);
|
||||||
|
|
||||||
|
Bind(move_up, KeyCode_I, key_alt);
|
||||||
|
Bind(move_down, KeyCode_K, key_alt);
|
||||||
|
|
||||||
|
BindTextInput(write_text_and_auto_indent);
|
||||||
|
Bind(indent_or_autocomplete, KeyCode_Tab);
|
||||||
|
Bind(unindent_line, KeyCode_Tab, KeyCode_Shift);
|
||||||
|
Bind(write_todo, KeyCode_T, key_alt);
|
||||||
|
Bind(write_note, KeyCode_G, key_alt);
|
||||||
|
|
||||||
|
Bind(input_enter_behavior, KeyCode_Return);
|
||||||
|
Bind(input_alt_enter_behavior, KeyCode_Return, key_alt);
|
||||||
|
}
|
||||||
|
|
||||||
|
SelectMapping(&modal_get_mode(modal_mode_debug)->map);
|
||||||
|
SelectMap(modal_map_id_global);
|
||||||
|
{
|
||||||
|
bindings_cmd_file_ops(m, map);
|
||||||
|
bindings_cmd_misc(m, map);
|
||||||
|
bindings_cmd_search(m, map);
|
||||||
|
bindings_cmd_nav(m, map);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
custom_layer_init(Application_Links *app){
|
custom_layer_init(Application_Links *app){
|
||||||
Thread_Context *tctx = get_thread_context(app);
|
Thread_Context *tctx = get_thread_context(app);
|
||||||
|
|
||||||
// NOTE(allen): setup for default framework
|
|
||||||
default_framework_init(app);
|
default_framework_init(app);
|
||||||
|
|
||||||
// NOTE(allen): default hooks and command maps
|
|
||||||
set_all_default_hooks(app);
|
set_all_default_hooks(app);
|
||||||
|
modal_init(3, tctx);
|
||||||
|
|
||||||
|
custom_keyboard_bindings();
|
||||||
|
|
||||||
|
#if 0
|
||||||
mapping_init(tctx, &framework_mapping);
|
mapping_init(tctx, &framework_mapping);
|
||||||
String_ID global_map_id = vars_save_string_lit("keys_global");
|
String_ID global_map_id = vars_save_string_lit("keys_global");
|
||||||
String_ID file_map_id = vars_save_string_lit("keys_file");
|
String_ID file_map_id = vars_save_string_lit("keys_file");
|
||||||
|
@ -34,6 +295,8 @@ custom_layer_init(Application_Links *app){
|
||||||
setup_default_mapping(&framework_mapping, global_map_id, file_map_id, code_map_id);
|
setup_default_mapping(&framework_mapping, global_map_id, file_map_id, code_map_id);
|
||||||
#endif
|
#endif
|
||||||
setup_essential_mapping(&framework_mapping, global_map_id, file_map_id, code_map_id);
|
setup_essential_mapping(&framework_mapping, global_map_id, file_map_id, code_map_id);
|
||||||
|
#endif
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#endif //FCODER_DEFAULT_BINDINGS
|
#endif //FCODER_DEFAULT_BINDINGS
|
||||||
|
|
|
@ -45,6 +45,10 @@ CUSTOM_ID(colors, defcolor_back_cycle);
|
||||||
CUSTOM_ID(colors, defcolor_text_cycle);
|
CUSTOM_ID(colors, defcolor_text_cycle);
|
||||||
CUSTOM_ID(colors, defcolor_line_numbers_back);
|
CUSTOM_ID(colors, defcolor_line_numbers_back);
|
||||||
CUSTOM_ID(colors, defcolor_line_numbers_text);
|
CUSTOM_ID(colors, defcolor_line_numbers_text);
|
||||||
|
CUSTOM_ID(colors, defcolor_function);
|
||||||
|
CUSTOM_ID(colors, defcolor_operator);
|
||||||
|
CUSTOM_ID(colors, defcolor_type);
|
||||||
|
CUSTOM_ID(colors, defcolor_macro);
|
||||||
|
|
||||||
struct Color_Table_Node{
|
struct Color_Table_Node{
|
||||||
Color_Table_Node *next;
|
Color_Table_Node *next;
|
||||||
|
|
|
@ -58,7 +58,8 @@ global b32 auto_center_after_jumps = AUTO_CENTER_AFTER_JUMPS;
|
||||||
global u8 locked_buffer_space[256];
|
global u8 locked_buffer_space[256];
|
||||||
global String_Const_u8 locked_buffer = {};
|
global String_Const_u8 locked_buffer = {};
|
||||||
|
|
||||||
|
global View_ID global_compilation_view = 0;
|
||||||
|
global b32 global_compilation_view_expanded = 0;
|
||||||
global View_ID build_footer_panel_view_id = 0;
|
global View_ID build_footer_panel_view_id = 0;
|
||||||
|
|
||||||
global u8 out_buffer_space[1024];
|
global u8 out_buffer_space[1024];
|
||||||
|
@ -111,5 +112,31 @@ global Point_Stack point_stack = {};
|
||||||
|
|
||||||
global Clipboard clipboard0 = {};
|
global Clipboard clipboard0 = {};
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
// Modal System Maps
|
||||||
|
global String_ID modal_map_id_global;
|
||||||
|
global String_ID modal_map_id_file;
|
||||||
|
global String_ID modal_map_id_code;
|
||||||
|
|
||||||
|
// Modal system modes
|
||||||
|
global Modal_Mode* modal_modes;
|
||||||
|
global u32 modal_modes_cap;
|
||||||
|
|
||||||
|
// State Tracking
|
||||||
|
global u32 modal_last_mode;
|
||||||
|
global u32 modal_curr_mode;
|
||||||
|
|
||||||
|
// Mode Ids
|
||||||
|
global u32 modal_mode_input = 0;
|
||||||
|
global u32 modal_mode_cmd = 1;
|
||||||
|
global u32 modal_mode_debug = 2;
|
||||||
|
|
||||||
|
////////////////////////////////
|
||||||
|
|
||||||
|
static String_Const_u8 go_to_definition_last_lexeme = {};
|
||||||
|
static u64 go_to_definition_last_lexeme_index = 0;
|
||||||
|
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
|
@ -34,7 +34,6 @@
|
||||||
#include "generated/lexer_cpp.h"
|
#include "generated/lexer_cpp.h"
|
||||||
|
|
||||||
#include "4coder_variables.h"
|
#include "4coder_variables.h"
|
||||||
#include "4coder_audio.h"
|
|
||||||
#include "4coder_profile.h"
|
#include "4coder_profile.h"
|
||||||
#include "4coder_async_tasks.h"
|
#include "4coder_async_tasks.h"
|
||||||
#include "4coder_string_match.h"
|
#include "4coder_string_match.h"
|
||||||
|
@ -64,6 +63,7 @@
|
||||||
#include "4coder_profile_inspect.h"
|
#include "4coder_profile_inspect.h"
|
||||||
#include "4coder_tutorial.h"
|
#include "4coder_tutorial.h"
|
||||||
#include "4coder_search_list.h"
|
#include "4coder_search_list.h"
|
||||||
|
#include "4coder_modal.h"
|
||||||
|
|
||||||
////////////////////////////////
|
////////////////////////////////
|
||||||
|
|
||||||
|
@ -139,8 +139,9 @@
|
||||||
#include "4coder_doc_commands.cpp"
|
#include "4coder_doc_commands.cpp"
|
||||||
#include "4coder_docs.cpp"
|
#include "4coder_docs.cpp"
|
||||||
#include "4coder_variables.cpp"
|
#include "4coder_variables.cpp"
|
||||||
#include "4coder_audio.cpp"
|
|
||||||
#include "4coder_search_list.cpp"
|
#include "4coder_search_list.cpp"
|
||||||
|
#include "4coder_modal.cpp"
|
||||||
|
#include "4coder_yeet.cpp"
|
||||||
|
|
||||||
#include "4coder_examples.cpp"
|
#include "4coder_examples.cpp"
|
||||||
|
|
||||||
|
|
|
@ -850,21 +850,15 @@ draw_original_4coder_style_cursor_mark_highlight(Application_Links *app, View_ID
|
||||||
i64 cursor_pos = view_get_cursor_pos(app, view_id);
|
i64 cursor_pos = view_get_cursor_pos(app, view_id);
|
||||||
i64 mark_pos = view_get_mark_pos(app, view_id);
|
i64 mark_pos = view_get_mark_pos(app, view_id);
|
||||||
if (is_active_view){
|
if (is_active_view){
|
||||||
draw_character_block(app, text_layout_id, cursor_pos, roundness,
|
Modal_Mode* mode_curr = modal_get_mode_curr();
|
||||||
fcolor_id(defcolor_cursor, cursor_sub_id));
|
FColor c0 = mode_curr->cursor_color;
|
||||||
paint_text_color_pos(app, text_layout_id, cursor_pos,
|
FColor c1 = fcolor_id(defcolor_at_cursor);
|
||||||
fcolor_id(defcolor_at_cursor));
|
draw_character_block(app, text_layout_id, cursor_pos, roundness, c0);
|
||||||
draw_character_wire_frame(app, text_layout_id, mark_pos,
|
paint_text_color_pos(app, text_layout_id, cursor_pos, c1);
|
||||||
roundness, outline_thickness,
|
draw_character_wire_frame(app, text_layout_id, mark_pos, roundness, outline_thickness, c0);
|
||||||
fcolor_id(defcolor_mark));
|
} else {
|
||||||
}
|
draw_character_wire_frame(app, text_layout_id, mark_pos, roundness, outline_thickness, fcolor_id(defcolor_mark));
|
||||||
else{
|
draw_character_wire_frame(app, text_layout_id, cursor_pos, roundness, outline_thickness, fcolor_id(defcolor_cursor, cursor_sub_id));
|
||||||
draw_character_wire_frame(app, text_layout_id, mark_pos,
|
|
||||||
roundness, outline_thickness,
|
|
||||||
fcolor_id(defcolor_mark));
|
|
||||||
draw_character_wire_frame(app, text_layout_id, cursor_pos,
|
|
||||||
roundness, outline_thickness,
|
|
||||||
fcolor_id(defcolor_cursor, cursor_sub_id));
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -208,61 +208,6 @@ CUSTOM_DOC("Example of query_user_string and query_user_number")
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
global Audio_Control the_music_control = {};
|
|
||||||
|
|
||||||
CUSTOM_COMMAND_SIG(music_start)
|
|
||||||
CUSTOM_DOC("Starts the music.")
|
|
||||||
{
|
|
||||||
local_persist Audio_Clip the_music_clip = {};
|
|
||||||
if (the_music_clip.sample_count == 0){
|
|
||||||
Scratch_Block scratch(app);
|
|
||||||
FILE *file = def_search_normal_fopen(scratch, "audio_test/chtulthu.wav", "rb");
|
|
||||||
if (file != 0){
|
|
||||||
the_music_clip = audio_clip_from_wav_FILE(&global_permanent_arena, file);
|
|
||||||
fclose(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!def_audio_is_playing(&the_music_control)){
|
|
||||||
the_music_control.loop = true;
|
|
||||||
the_music_control.channel_volume[0] = 1.f;
|
|
||||||
the_music_control.channel_volume[1] = 1.f;
|
|
||||||
def_audio_play_clip(the_music_clip, &the_music_control);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
CUSTOM_COMMAND_SIG(music_stop)
|
|
||||||
CUSTOM_DOC("Stops the music.")
|
|
||||||
{
|
|
||||||
def_audio_stop(&the_music_control);
|
|
||||||
}
|
|
||||||
|
|
||||||
CUSTOM_COMMAND_SIG(hit_sfx)
|
|
||||||
CUSTOM_DOC("Play the hit sound effect")
|
|
||||||
{
|
|
||||||
local_persist Audio_Clip the_hit_clip = {};
|
|
||||||
if (the_hit_clip.sample_count == 0){
|
|
||||||
Scratch_Block scratch(app);
|
|
||||||
FILE *file = def_search_normal_fopen(scratch, "audio_test/hit.wav", "rb");
|
|
||||||
if (file != 0){
|
|
||||||
the_hit_clip = audio_clip_from_wav_FILE(&global_permanent_arena, file);
|
|
||||||
fclose(file);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
local_persist u32 index = 0;
|
|
||||||
local_persist Audio_Control controls[8] = {};
|
|
||||||
|
|
||||||
Audio_Control *control = &controls[index%8];
|
|
||||||
if (!def_audio_is_playing(control)){
|
|
||||||
control->loop = false;
|
|
||||||
control->channel_volume[0] = 1.f;
|
|
||||||
control->channel_volume[1] = 1.f;
|
|
||||||
def_audio_play_clip(the_hit_clip, control);
|
|
||||||
index += 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
||||||
|
|
|
@ -55,7 +55,7 @@ parse_buffer_to_jump_array(Application_Links *app, Arena *arena, Buffer_ID buffe
|
||||||
Temp_Memory_Block line_auto_closer(arena);
|
Temp_Memory_Block line_auto_closer(arena);
|
||||||
if (is_valid_line(app, buffer, line)){
|
if (is_valid_line(app, buffer, line)){
|
||||||
String_Const_u8 line_str = push_buffer_line(app, arena, buffer, line);
|
String_Const_u8 line_str = push_buffer_line(app, arena, buffer, line);
|
||||||
Parsed_Jump parsed_jump = parse_jump_location(line_str);
|
Parsed_Jump parsed_jump = gs_parse_jump_location(line_str);
|
||||||
if (parsed_jump.success){
|
if (parsed_jump.success){
|
||||||
Buffer_ID jump_buffer = {};
|
Buffer_ID jump_buffer = {};
|
||||||
if (open_file(app, &jump_buffer, parsed_jump.location.file, false, true)){
|
if (open_file(app, &jump_buffer, parsed_jump.location.file, false, true)){
|
||||||
|
|
|
@ -59,6 +59,119 @@ check_is_note(String_Const_u8 line, u64 colon_pos){
|
||||||
return(is_note);
|
return(is_note);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/* ERROR EXAMPLES
|
||||||
|
These are the cases that gs_parse_jump_location is designed to parse.
|
||||||
|
|
||||||
|
############################# JAVASCRIPT / NODE ERROR ##########################
|
||||||
|
|
||||||
|
C:\psjr\blackbird\test.js:2
|
||||||
|
console.error("Foo);
|
||||||
|
^^^^^^
|
||||||
|
|
||||||
|
SyntaxError: Invalid or unexpected token
|
||||||
|
at Object.compileFunction (node:vm:352:18)
|
||||||
|
at wrapSafe (node:internal/modules/cjs/loader:1031:15)
|
||||||
|
at Module._compile (node:internal/modules/cjs/loader:1065:27)
|
||||||
|
at Object.Module._extensions..js (node:internal/modules/cjs/loader:1153:10)
|
||||||
|
at Module.load (node:internal/modules/cjs/loader:981:32)
|
||||||
|
at Function.Module._load (node:internal/modules/cjs/loader:822:12)
|
||||||
|
at Function.executeUserEntryPoint [as runMain] (node:internal/modules/run_main:81:12)
|
||||||
|
at node:internal/main/run_main_module:17:47
|
||||||
|
|
||||||
|
############################# MSVC ERROR #######################################
|
||||||
|
|
||||||
|
test.c(4): error C2632: 'int' followed by 'int' is illegal
|
||||||
|
|
||||||
|
############################# CLANG ERROR ######################################
|
||||||
|
|
||||||
|
test.c:4:1: error: cannot combine with previous 'int' declaration specifier
|
||||||
|
int main(int argc, char** args) {
|
||||||
|
|
||||||
|
############################# JAI ERROR ########################################
|
||||||
|
|
||||||
|
C:/projects/games/atof//src/cards.jai:106,48: Error: Semicolon expected after expression.
|
||||||
|
|
||||||
|
}
|
||||||
|
return card_index, (<< collection)[card_index]
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
|
function Parsed_Jump
|
||||||
|
gs_parse_jump_location(String_Const_u8 line)
|
||||||
|
{
|
||||||
|
Parsed_Jump jump = {};
|
||||||
|
jump.sub_jump_indented = (string_get_character(line, 0) == ' ');
|
||||||
|
|
||||||
|
String_Const_u8 reduced_line = string_skip_chop_whitespace(line);
|
||||||
|
u64 whitespace_length = (u64)(reduced_line.str - line.str);
|
||||||
|
line = reduced_line;
|
||||||
|
|
||||||
|
String_Const_u8 separators = str8_lit(":(),"); // characters used to separate paths, indices, and notes
|
||||||
|
u64 sep1 = string_find_first_of_set(line, separators);
|
||||||
|
|
||||||
|
// on windows, paths might have a colon in them. ie. C:\some\path\file.cpp
|
||||||
|
// we want to skip this first colon - so check if there's a slash after it
|
||||||
|
// and skip in that case.
|
||||||
|
if (sep1 + 1 < line.size)
|
||||||
|
{
|
||||||
|
if (character_is_slash(string_get_character(line, sep1 + 1))){
|
||||||
|
u64 next_sep = string_find_first_of_set(
|
||||||
|
string_skip(line, sep1 + 1),
|
||||||
|
separators
|
||||||
|
);
|
||||||
|
sep1 = next_sep + sep1 + 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
u64 sep2 = string_find_first_of_set(
|
||||||
|
string_skip(line, sep1 + 1),
|
||||||
|
separators
|
||||||
|
) + sep1 + 1;
|
||||||
|
u64 sep3 = string_find_first_of_set(
|
||||||
|
string_skip(line, sep2 + 1),
|
||||||
|
separators
|
||||||
|
) + sep2 + 1;
|
||||||
|
|
||||||
|
// TODO(PS): check_is_note? - seems to be checking for test.c(4): note
|
||||||
|
// ^^^^
|
||||||
|
// and setting jump.sub_jump_note = true. Not sure what this is for yet
|
||||||
|
|
||||||
|
if (sep1 < line.size) {
|
||||||
|
String_Const_u8 file_name = string_prefix(line, sep1);
|
||||||
|
if (file_name.size > 0) {
|
||||||
|
jump.location.file = file_name;
|
||||||
|
|
||||||
|
if (sep2 < line.size) {
|
||||||
|
String_Const_u8 line_number = string_skip(string_prefix(line, sep2), sep1 + 1);
|
||||||
|
if (string_is_integer(line_number, 10)) {
|
||||||
|
jump.location.line = (i32)string_to_integer(line_number, 10);
|
||||||
|
|
||||||
|
// NOTE(PS): we must at least get a line number to consider the line
|
||||||
|
// to contain a valid jump location
|
||||||
|
jump.success = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// NOTE(PS): columns are optional since MSVC doesn't output them
|
||||||
|
if (sep3 < line.size) {
|
||||||
|
String_Const_u8 column_number = string_skip(string_prefix(line, sep3), sep2 + 1);
|
||||||
|
if (string_is_integer(column_number, 10)) {
|
||||||
|
jump.location.column = (i32)string_to_integer(column_number, 10);
|
||||||
|
}
|
||||||
|
jump.colon_position = (i32)(sep3 + whitespace_length);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!jump.success){
|
||||||
|
block_zero_struct(&jump);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
jump.is_sub_jump = (jump.sub_jump_indented || jump.sub_jump_note);
|
||||||
|
}
|
||||||
|
return(jump);
|
||||||
|
}
|
||||||
|
|
||||||
function Parsed_Jump
|
function Parsed_Jump
|
||||||
parse_jump_location(String_Const_u8 line){
|
parse_jump_location(String_Const_u8 line){
|
||||||
Parsed_Jump jump = {};
|
Parsed_Jump jump = {};
|
||||||
|
@ -133,7 +246,11 @@ parse_jump_location(String_Const_u8 line){
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 colon_pos2 = string_find_first(string_skip(line, colon_pos1 + 1), ':') + colon_pos1 + 1;
|
u64 colon_pos2 = string_find_first(string_skip(line, colon_pos1 + 1), ':') + colon_pos1 + 1;
|
||||||
u64 colon_pos3 = string_find_first(string_skip(line, colon_pos2 + 1), ':') + colon_pos2 + 1;
|
u64 comma_pos2 = string_find_first(string_skip(line, colon_pos1 + 1), ',') + colon_pos1 + 1;
|
||||||
|
if (comma_pos2 < colon_pos2) {
|
||||||
|
colon_pos2 = comma_pos2;
|
||||||
|
}
|
||||||
|
u64 colon_pos3 = string_find_first(string_skip(line, colon_pos2 + 1), ':') + colon_pos2 + 1;
|
||||||
|
|
||||||
if (colon_pos3 < line.size){
|
if (colon_pos3 < line.size){
|
||||||
if (check_is_note(line, colon_pos3)){
|
if (check_is_note(line, colon_pos3)){
|
||||||
|
|
|
@ -274,12 +274,7 @@ lister__backspace_text_field__file_path(Application_Links *app){
|
||||||
User_Input input = get_current_input(app);
|
User_Input input = get_current_input(app);
|
||||||
String_Const_u8 text_field = lister->text_field.string;
|
String_Const_u8 text_field = lister->text_field.string;
|
||||||
String_Const_u8 new_hot = string_remove_last_folder(text_field);
|
String_Const_u8 new_hot = string_remove_last_folder(text_field);
|
||||||
b32 is_modified = has_modifier(&input, KeyCode_Control);
|
lister->text_field.size = new_hot.size;
|
||||||
b32 whole_word_when_mod = def_get_config_b32(vars_save_string_lit("lister_whole_word_backspace_when_modified"));
|
|
||||||
b32 whole_word_backspace = (is_modified == whole_word_when_mod);
|
|
||||||
if (whole_word_backspace){
|
|
||||||
lister->text_field.size = new_hot.size;
|
|
||||||
}
|
|
||||||
set_hot_directory(app, new_hot);
|
set_hot_directory(app, new_hot);
|
||||||
// TODO(allen): We have to protect against lister_call_refresh_handler
|
// TODO(allen): We have to protect against lister_call_refresh_handler
|
||||||
// changing the text_field here. Clean this up.
|
// changing the text_field here. Clean this up.
|
||||||
|
|
|
@ -0,0 +1,105 @@
|
||||||
|
|
||||||
|
function void
|
||||||
|
modal_init(u32 mode_cap, Thread_Context* tctx){
|
||||||
|
Assert(mode_cap > 0);
|
||||||
|
modal_modes_cap = mode_cap;
|
||||||
|
modal_modes = base_array(tctx->allocator, Modal_Mode, mode_cap);
|
||||||
|
|
||||||
|
modal_map_id_global = vars_save_string_lit("keys_global");
|
||||||
|
modal_map_id_file = vars_save_string_lit("keys_file");
|
||||||
|
modal_map_id_code = vars_save_string_lit("keys_code");
|
||||||
|
|
||||||
|
for (u32 i = 0; i < modal_modes_cap; i++){
|
||||||
|
Modal_Mode* mode = modal_modes + i;
|
||||||
|
mapping_init(tctx, &mode->map);
|
||||||
|
setup_essential_mapping(&mode->map, modal_map_id_global, modal_map_id_file, modal_map_id_code);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Modal_Mode*
|
||||||
|
modal_get_mode(u32 mode_id)
|
||||||
|
{
|
||||||
|
if (mode_id >= modal_modes_cap) return 0;
|
||||||
|
return modal_modes + mode_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
modal_bind(Mapping* mode, Command_Map* map, custom_cmd* proc, u32 key_code, u32 mod_key_code0, u32 mod_key_code1)
|
||||||
|
{
|
||||||
|
map_set_binding_l(mode, map, BindFWrap_(proc), InputEventKind_KeyStroke, key_code, mod_key_code0, mod_key_code1, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
modal_bind(u32 mode_id, String_ID map_id, custom_cmd* proc, u32 key_code, u32 mod_key_code0, u32 mod_key_code1)
|
||||||
|
{
|
||||||
|
Assert(mode_id < modal_modes_cap);
|
||||||
|
|
||||||
|
Modal_Mode* mode = modal_get_mode(mode_id);
|
||||||
|
Mapping* m = &mode->map;
|
||||||
|
Command_Map* map = mapping_get_or_make_map(m, map_id);
|
||||||
|
|
||||||
|
modal_bind(m, map, proc, key_code, mod_key_code0, mod_key_code1);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
modal_bind_all(String_ID map_id, custom_cmd* proc, u32 key_code, u32 mod_key_code0, u32 mod_key_code1)
|
||||||
|
{
|
||||||
|
for (u32 i = 0; i < modal_modes_cap; i++)
|
||||||
|
{
|
||||||
|
Mapping* m = &modal_modes[i].map;
|
||||||
|
Command_Map* map = mapping_get_or_make_map(m, map_id);
|
||||||
|
modal_bind(m, map, proc, key_code, mod_key_code0, mod_key_code1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
function Modal_Mode*
|
||||||
|
modal_get_mode_curr()
|
||||||
|
{
|
||||||
|
return modal_get_mode(modal_curr_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
modal_set_mode(u32 mode_id)
|
||||||
|
{
|
||||||
|
modal_last_mode = modal_curr_mode;
|
||||||
|
modal_curr_mode = mode_id;
|
||||||
|
}
|
||||||
|
|
||||||
|
function u32
|
||||||
|
modal_get_next_mode(u32 base)
|
||||||
|
{
|
||||||
|
u32 result = (base + 1) % modal_modes_cap;
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
modal_set_cursor_color(u32 mode_id, FColor color)
|
||||||
|
{
|
||||||
|
Modal_Mode* mode = modal_get_mode(mode_id);
|
||||||
|
mode->cursor_color = color;
|
||||||
|
}
|
||||||
|
|
||||||
|
function void
|
||||||
|
modal_set_cursor_color_u32(u32 mode_id, u32 color)
|
||||||
|
{
|
||||||
|
FColor fc = {};
|
||||||
|
fc.argb = color;
|
||||||
|
modal_set_cursor_color(mode_id, fc);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(modal_set_mode_toggle)
|
||||||
|
{
|
||||||
|
u32 next_mode = modal_last_mode;
|
||||||
|
if (next_mode == modal_curr_mode)
|
||||||
|
{
|
||||||
|
next_mode = modal_get_next_mode(next_mode);
|
||||||
|
}
|
||||||
|
modal_set_mode(next_mode);
|
||||||
|
}
|
||||||
|
|
||||||
|
CUSTOM_COMMAND_SIG(modal_set_mode_next)
|
||||||
|
{
|
||||||
|
u32 next_mode = modal_get_next_mode(modal_curr_mode);
|
||||||
|
modal_set_mode(next_mode);
|
||||||
|
}
|
||||||
|
|
|
@ -0,0 +1,17 @@
|
||||||
|
/* date = February 10th 2024 3:00 pm */
|
||||||
|
|
||||||
|
#ifndef FRED_MODAL_H
|
||||||
|
#define FRED_MODAL_H
|
||||||
|
|
||||||
|
struct Modal_Mode
|
||||||
|
{
|
||||||
|
Mapping map;
|
||||||
|
FColor cursor_color;
|
||||||
|
String_Const_u8 name;
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef CUSTOM_COMMAND_SIG(custom_cmd);
|
||||||
|
|
||||||
|
function Modal_Mode* modal_get_mode_curr();
|
||||||
|
|
||||||
|
#endif //FRED_MODAL_H
|
|
@ -459,17 +459,23 @@ prj_generate_project(Arena *scratch, String8 script_path, String8 script_file, S
|
||||||
|
|
||||||
String8 file_name = push_u8_stringf(scratch, "%.*s/project.4coder", string_expand(script_path));
|
String8 file_name = push_u8_stringf(scratch, "%.*s/project.4coder", string_expand(script_path));
|
||||||
|
|
||||||
|
String8 treat_as_code = def_get_config_string(scratch, vars_save_string_lit("treat_as_code"));
|
||||||
|
String8Array extensions = parse_extension_line_to_extension_list(scratch, treat_as_code);
|
||||||
|
|
||||||
FILE *out = fopen((char*)file_name.str, "wb");
|
FILE *out = fopen((char*)file_name.str, "wb");
|
||||||
if (out != 0){
|
if (out != 0){
|
||||||
fprintf(out, "version(2);\n");
|
fprintf(out, "version(2);\n");
|
||||||
fprintf(out, "project_name = \"%.*s\";\n", string_expand(binary_file));
|
fprintf(out, "project_name = \"%.*s\";\n", string_expand(binary_file));
|
||||||
fprintf(out, "patterns = {\n");
|
fprintf(out, "patterns = {\n");
|
||||||
fprintf(out, "\"*.c\",\n");
|
for (i32 i = 0; i < extensions.count; i++) {
|
||||||
fprintf(out, "\"*.cpp\",\n");
|
fprintf(out, "\"*.%.*s\",\n", string_expand(extensions.strings[i]));
|
||||||
fprintf(out, "\"*.h\",\n");
|
}
|
||||||
fprintf(out, "\"*.m\",\n");
|
// fprintf(out, "\"*.c\",\n");
|
||||||
fprintf(out, "\"*.bat\",\n");
|
// fprintf(out, "\"*.cpp\",\n");
|
||||||
fprintf(out, "\"*.sh\",\n");
|
// fprintf(out, "\"*.h\",\n");
|
||||||
|
// fprintf(out, "\"*.m\",\n");
|
||||||
|
// fprintf(out, "\"*.bat\",\n");
|
||||||
|
// fprintf(out, "\"*.sh\",\n");
|
||||||
fprintf(out, "\"*.4coder\",\n");
|
fprintf(out, "\"*.4coder\",\n");
|
||||||
fprintf(out, "};\n");
|
fprintf(out, "};\n");
|
||||||
fprintf(out, "blacklist_patterns = {\n");
|
fprintf(out, "blacklist_patterns = {\n");
|
||||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -38,6 +38,10 @@ defcolor_back_cycle = managed_id_declare(app, string_u8_litexpr("colors"), strin
|
||||||
defcolor_text_cycle = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_text_cycle"));
|
defcolor_text_cycle = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_text_cycle"));
|
||||||
defcolor_line_numbers_back = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_line_numbers_back"));
|
defcolor_line_numbers_back = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_line_numbers_back"));
|
||||||
defcolor_line_numbers_text = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_line_numbers_text"));
|
defcolor_line_numbers_text = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_line_numbers_text"));
|
||||||
|
defcolor_function = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_function"));
|
||||||
|
defcolor_operator = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_operator"));
|
||||||
|
defcolor_type = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_type"));
|
||||||
|
defcolor_macro = managed_id_declare(app, string_u8_litexpr("colors"), string_u8_litexpr("defcolor_macro"));
|
||||||
view_rewrite_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_rewrite_loc"));
|
view_rewrite_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_rewrite_loc"));
|
||||||
view_next_rewrite_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_next_rewrite_loc"));
|
view_next_rewrite_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_next_rewrite_loc"));
|
||||||
view_paste_index_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_paste_index_loc"));
|
view_paste_index_loc = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("view_paste_index_loc"));
|
||||||
|
@ -56,4 +60,6 @@ buffer_lex_task = managed_id_declare(app, string_u8_litexpr("attachment"), strin
|
||||||
buffer_wrap_lines = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("buffer_wrap_lines"));
|
buffer_wrap_lines = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("buffer_wrap_lines"));
|
||||||
sticky_jump_marker_handle = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("sticky_jump_marker_handle"));
|
sticky_jump_marker_handle = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("sticky_jump_marker_handle"));
|
||||||
attachment_tokens = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("attachment_tokens"));
|
attachment_tokens = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("attachment_tokens"));
|
||||||
|
loco_marker_handle = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("loco_marker_handle"));
|
||||||
|
loco_marker_pair_handle = managed_id_declare(app, string_u8_litexpr("attachment"), string_u8_litexpr("loco_marker_pair_handle"));
|
||||||
}
|
}
|
||||||
|
|
|
@ -348,7 +348,7 @@ os_popup_error(char *title, char *message){
|
||||||
#if defined(FRED_INTERNAL)
|
#if defined(FRED_INTERNAL)
|
||||||
function inline void
|
function inline void
|
||||||
mac_profile(char *name, u64 begin, u64 end){
|
mac_profile(char *name, u64 begin, u64 end){
|
||||||
printf("%s Time: %fs\n", name, ((end - begin) / 1000000.0f));
|
//printf("%s Time: %fs\n", name, ((end - begin) / 1000000.0f));
|
||||||
}
|
}
|
||||||
|
|
||||||
#define MacProfileScope(name) for (u64 glue(_i_, __LINE__) = 0, glue(_begin_, __LINE__) = system_now_time();\
|
#define MacProfileScope(name) for (u64 glue(_i_, __LINE__) = 0, glue(_begin_, __LINE__) = system_now_time();\
|
||||||
|
@ -909,7 +909,7 @@ mac_toggle_fullscreen(void){
|
||||||
|
|
||||||
mac_profile("Frame", prev_timer_start, mac_vars.timer_start);
|
mac_profile("Frame", prev_timer_start, mac_vars.timer_start);
|
||||||
#if FRED_INTERNAL
|
#if FRED_INTERNAL
|
||||||
printf("\n");
|
//printf("\n");
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -946,7 +946,7 @@ mac_toggle_fullscreen(void){
|
||||||
- (void)keyDown:(NSEvent*)event{
|
- (void)keyDown:(NSEvent*)event{
|
||||||
// NOTE(yuval): Process keyboard event
|
// NOTE(yuval): Process keyboard event
|
||||||
[self process_keyboard_event:event down:true];
|
[self process_keyboard_event:event down:true];
|
||||||
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
|
[self interpretKeyEvents:[NSArray arrayWithObject:event]];
|
||||||
|
|
||||||
// TODO(allen): Deduplicate with insertText version
|
// TODO(allen): Deduplicate with insertText version
|
||||||
// NOTE(allen): We need to manually send text for '\n' and '\t'
|
// NOTE(allen): We need to manually send text for '\n' and '\t'
|
||||||
|
@ -961,9 +961,9 @@ mac_toggle_fullscreen(void){
|
||||||
}
|
}
|
||||||
if ((c == '\t') || (c == '\n')){
|
if ((c == '\t') || (c == '\n')){
|
||||||
u8 *str = push_array(&mac_vars.frame_arena, u8, 1);
|
u8 *str = push_array(&mac_vars.frame_arena, u8, 1);
|
||||||
str[0] = (u8)c;
|
str[0] = (u8)c;
|
||||||
|
|
||||||
Input_Event *event = push_input_event(&mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list);
|
Input_Event *event = push_input_event(&mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list);
|
||||||
event->kind = InputEventKind_TextInsert;
|
event->kind = InputEventKind_TextInsert;
|
||||||
event->text.string = SCu8(str, 1);
|
event->text.string = SCu8(str, 1);
|
||||||
event->text.next_text = 0;
|
event->text.next_text = 0;
|
||||||
|
@ -1206,11 +1206,17 @@ Input_Event *event = push_input_event(&mac_vars.frame_arena, &mac_vars.input_chu
|
||||||
|
|
||||||
system_signal_step(0);
|
system_signal_step(0);
|
||||||
}
|
}
|
||||||
} else{
|
} else {
|
||||||
mac_vars.active_key_stroke = 0;
|
mac_vars.active_key_stroke = 0;
|
||||||
mac_vars.active_text_input = 0;
|
mac_vars.active_text_input = 0;
|
||||||
|
|
||||||
if (key != 0){
|
if (key != 0){
|
||||||
|
// NOTE(PS): when releasing the command key, assume all keys being pressed
|
||||||
|
// are released
|
||||||
|
if (key == KeyCode_Command) {
|
||||||
|
mods->count = 0;
|
||||||
|
}
|
||||||
|
|
||||||
Input_Event *event = push_input_event(&mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list);
|
Input_Event *event = push_input_event(&mac_vars.frame_arena, &mac_vars.input_chunk.trans.event_list);
|
||||||
event->kind = InputEventKind_KeyRelease;
|
event->kind = InputEventKind_KeyRelease;
|
||||||
event->key.code = key;
|
event->key.code = key;
|
||||||
|
|
|
@ -16,7 +16,7 @@ struct Mac_Metal{
|
||||||
function
|
function
|
||||||
mac_render_sig(mac_metal__render){
|
mac_render_sig(mac_metal__render){
|
||||||
#if defined(FRED_INTERNAL)
|
#if defined(FRED_INTERNAL)
|
||||||
printf("Redering using Metal!\n");
|
//printf("Redering using Metal!\n");
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
Mac_Metal *metal = (Mac_Metal*)renderer;
|
Mac_Metal *metal = (Mac_Metal*)renderer;
|
||||||
|
|
|
@ -1697,7 +1697,6 @@ WinMain(HINSTANCE hInstance, HINSTANCE hPrevInstance, LPSTR lpCmdLine, int nCmdS
|
||||||
|
|
||||||
log_os("Initializing thread context...\n");
|
log_os("Initializing thread context...\n");
|
||||||
|
|
||||||
// NOTE(allen): This thing
|
|
||||||
InitializeCriticalSection(&memory_tracker_mutex);
|
InitializeCriticalSection(&memory_tracker_mutex);
|
||||||
|
|
||||||
// NOTE(allen): context setup
|
// NOTE(allen): context setup
|
||||||
|
|
|
@ -20,10 +20,10 @@ use_scope_highlight = true;
|
||||||
use_paren_helper = true;
|
use_paren_helper = true;
|
||||||
use_comment_keywords = true;
|
use_comment_keywords = true;
|
||||||
lister_whole_word_backspace_when_modified = true;
|
lister_whole_word_backspace_when_modified = true;
|
||||||
show_line_number_margins = false;
|
show_line_number_margins = true;
|
||||||
enable_output_wrapping = false;
|
enable_output_wrapping = false;
|
||||||
|
|
||||||
enable_undo_fade_out = true;
|
enable_undo_fade_out = false;
|
||||||
|
|
||||||
// cursor_roundess is a value [0,50] setting the radius of
|
// cursor_roundess is a value [0,50] setting the radius of
|
||||||
// the cursor and mark's roundness as a percentage of their width
|
// the cursor and mark's roundness as a percentage of their width
|
||||||
|
@ -40,14 +40,14 @@ mark_thickness = 2;
|
||||||
lister_roundness = 20;
|
lister_roundness = 20;
|
||||||
|
|
||||||
// Code Wrapping
|
// Code Wrapping
|
||||||
treat_as_code = ".cpp.c.hpp.h.cc.cs.java.rs.glsl.m.mm";
|
treat_as_code = ".cpp.c.hpp.h.cc.cs.java.rs.glsl.m.mm.js.ts.tsx.css.html.jai.json.mm.metal.glsl.hlsl";
|
||||||
enable_virtual_whitespace = true;
|
enable_virtual_whitespace = false;
|
||||||
virtual_whitespace_regular_indent = 4;
|
virtual_whitespace_regular_indent = 2;
|
||||||
enable_code_wrapping = true;
|
enable_code_wrapping = false;
|
||||||
|
|
||||||
// This only applies to code files in code-wrapping mode.
|
// This only applies to code files in code-wrapping mode.
|
||||||
// Plain text and code files without virtual-whitespace will not be effected.
|
// Plain text and code files without virtual-whitespace will not be effected.
|
||||||
automatically_indent_text_on_save = true;
|
automatically_indent_text_on_save = false;
|
||||||
|
|
||||||
// When set to true, all unsaved changes will be saved on a build.
|
// When set to true, all unsaved changes will be saved on a build.
|
||||||
automatically_save_changes_on_build = true;
|
automatically_save_changes_on_build = true;
|
||||||
|
@ -57,16 +57,16 @@ automatically_load_project = false;
|
||||||
|
|
||||||
// Indentation
|
// Indentation
|
||||||
indent_with_tabs = false;
|
indent_with_tabs = false;
|
||||||
indent_width = 4;
|
indent_width = 2;
|
||||||
default_tab_width = 4;
|
default_tab_width = 2;
|
||||||
|
|
||||||
// Theme
|
// Theme
|
||||||
default_theme_name = "4coder";
|
default_theme_name = "theme-gs";
|
||||||
|
|
||||||
// Font
|
// Font
|
||||||
default_font_name = "liberation-mono.ttf";
|
default_font_name = "liberation-mono.ttf";
|
||||||
default_font_size = 16;
|
default_font_size = 14;
|
||||||
default_font_hinting = false;
|
default_font_hinting = true;
|
||||||
|
|
||||||
// aa modes:
|
// aa modes:
|
||||||
// 8bit - mono-chrome 0-255 opacity channel per pixel
|
// 8bit - mono-chrome 0-255 opacity channel per pixel
|
||||||
|
@ -74,7 +74,7 @@ default_font_hinting = false;
|
||||||
default_font_aa_mode = "8bit";
|
default_font_aa_mode = "8bit";
|
||||||
|
|
||||||
// User
|
// User
|
||||||
user_name = "not-set";
|
user_name = "PS";
|
||||||
|
|
||||||
// Keyboard AltGr setting
|
// Keyboard AltGr setting
|
||||||
lalt_lctrl_is_altgr = false;
|
lalt_lctrl_is_altgr = false;
|
||||||
|
|
|
@ -0,0 +1,69 @@
|
||||||
|
defcolor_bar = 0xFF1e1e1e;
|
||||||
|
defcolor_base = 0xFFfcaa05;
|
||||||
|
defcolor_pop1 = 0xffde8150;
|
||||||
|
defcolor_pop2 = 0xFFFF0000;
|
||||||
|
defcolor_back = 0xFF1e1e1e;
|
||||||
|
defcolor_margin = 0xFF222425;
|
||||||
|
defcolor_margin_hover = 0xff63523d;
|
||||||
|
defcolor_margin_active = 0xff63523d;
|
||||||
|
defcolor_list_item = { 0xFF222425, defcolor_back};
|
||||||
|
defcolor_list_item_hover = { 0xff362e25, defcolor_margin};
|
||||||
|
defcolor_list_item_active = { 0xff63523d, defcolor_margin};
|
||||||
|
defcolor_cursor = { 0xFF00EE00, 0xffe0741b, 0xff1be094, 0xffba60c4 };
|
||||||
|
defcolor_at_cursor = 0xFF0C0C0C;
|
||||||
|
defcolor_highlight_cursor_line = 0xFF1E1E1E;
|
||||||
|
defcolor_highlight = 0xFF303040;
|
||||||
|
defcolor_at_highlight = 0xFFFF44DD;
|
||||||
|
defcolor_mark = 0xFF494949;
|
||||||
|
defcolor_text_default = 0xffd4d4d4;
|
||||||
|
defcolor_comment = 0xff6a9956;
|
||||||
|
defcolor_comment_pop = { 0xff2ab34f, 0xFFdb2828 };
|
||||||
|
defcolor_keyword = 0xffc586c0;
|
||||||
|
defcolor_str_constant = 0xffa77864;
|
||||||
|
defcolor_char_constant = 0xffa77864;
|
||||||
|
defcolor_int_constant = 0xffb4cda7;
|
||||||
|
defcolor_float_constant = 0xffb4cda7;
|
||||||
|
defcolor_bool_constant = 0xffb4cda7;
|
||||||
|
defcolor_preproc = 0xFFc485bf;
|
||||||
|
defcolor_include = 0xffc485bf;
|
||||||
|
defcolor_special_character = 0xFFFF0000;
|
||||||
|
defcolor_ghost_character = 0xFF4E5E46;
|
||||||
|
defcolor_highlight_junk = 0xFF3A0000;
|
||||||
|
defcolor_highlight_white = 0xFF003A3A;
|
||||||
|
defcolor_paste = 0xFFDDEE00;
|
||||||
|
defcolor_undo = 0xFF00DDEE;
|
||||||
|
defcolor_back_cycle = { 0xff282828, 0xff323232, 0xff3C3C3C, defcolor_back, };
|
||||||
|
defcolor_text_cycle = { 0xFFA00000, 0xFF00A000, 0xFF0030B0, 0xFFA0A000 };
|
||||||
|
defcolor_line_numbers_back = defcolor_back;
|
||||||
|
defcolor_line_numbers_text = 0xFF404040;
|
||||||
|
|
||||||
|
fleury_color_syntax_crap = 0xff5c4d3c;
|
||||||
|
fleury_color_operators = 0xFFbd2d2d;
|
||||||
|
fleury_color_inactive_pane_overlay = 0x44000000;
|
||||||
|
fleury_color_inactive_pane_background = 0xff1e1e1e;
|
||||||
|
fleury_color_file_progress_bar = 0x60634323;
|
||||||
|
fleury_color_brace_highlight = { 0xff8ffff2 };
|
||||||
|
fleury_color_brace_line = { 0x809ba290 };
|
||||||
|
fleury_color_brace_annotation = { 0x809ba290 };
|
||||||
|
fleury_color_index_product_type = 0xFFedb211;
|
||||||
|
fleury_color_index_sum_type = 0xFFa7eb13;
|
||||||
|
fleury_color_index_function = 0xFFde451f;
|
||||||
|
fleury_color_index_macro = 0xFF2895c7;
|
||||||
|
fleury_color_index_constant = 0xff6eb535;
|
||||||
|
fleury_color_index_comment_tag = 0xffffae00;
|
||||||
|
fleury_color_index_decl = 0xffc9598a;
|
||||||
|
fleury_color_cursor_macro = 0xffde2368;
|
||||||
|
fleury_color_cursor_power_mode = 0xffefaf2f;
|
||||||
|
fleury_color_cursor_inactive = 0xFF880000;
|
||||||
|
fleury_color_plot_cycle = { 0xff03d3fc, 0xff22b80b, 0xfff0bb0c, 0xfff0500c };
|
||||||
|
fleury_color_token_highlight = 0x88f2d357;
|
||||||
|
fleury_color_token_minor_highlight = 0x44d19045;
|
||||||
|
fleury_color_error_annotation = 0xffff0000;
|
||||||
|
fleury_color_lego_grab = 0xffefaf6f;
|
||||||
|
fleury_color_lego_splat = 0xffefaaef;
|
||||||
|
fleury_color_comment_user_name = 0xffffdd23;
|
||||||
|
|
||||||
|
defcolor_function = 0xffdadaa9;
|
||||||
|
defcolor_operator = 0xffc5c5c5;
|
||||||
|
defcolor_type = 0xff4dc5ac;
|
||||||
|
defcolor_macro = 0xff5190c5;
|
Binary file not shown.
Binary file not shown.
Binary file not shown.
|
@ -0,0 +1,37 @@
|
||||||
|
version(2);
|
||||||
|
project_name = "4ed.exe";
|
||||||
|
patterns = {
|
||||||
|
"*.c",
|
||||||
|
"*.cpp",
|
||||||
|
"*.h",
|
||||||
|
"*.m",
|
||||||
|
"*.bat",
|
||||||
|
"*.sh",
|
||||||
|
"*.4coder",
|
||||||
|
};
|
||||||
|
blacklist_patterns = {
|
||||||
|
".*",
|
||||||
|
};
|
||||||
|
load_paths_base = {
|
||||||
|
{ ".", .relative = true, .recursive = true, },
|
||||||
|
};
|
||||||
|
load_paths = {
|
||||||
|
.win = load_paths_base,
|
||||||
|
.linux = load_paths_base,
|
||||||
|
.mac = load_paths_base,
|
||||||
|
};
|
||||||
|
|
||||||
|
commands = {
|
||||||
|
.build = { .out = "*compilation*", .footer_panel = true, .save_dirty_files = true,
|
||||||
|
.win = "code\\bin\\build.bat",
|
||||||
|
.linux = "./code/bin/package.sh",
|
||||||
|
.mac = "./code/bin/package-mac.sh", },
|
||||||
|
.run = { .out = "*run*", .footer_panel = false, .save_dirty_files = false,
|
||||||
|
.win = "build\\4ed.exe",
|
||||||
|
.linux = "build/4ed",
|
||||||
|
.mac = "build/4ed", },
|
||||||
|
};
|
||||||
|
fkey_command = {
|
||||||
|
.F1 = "build",
|
||||||
|
.F2 = "run",
|
||||||
|
};
|
Loading…
Reference in New Issue