4ed_file_view.cpp now compiles

master
Allen Webster 2016-08-24 10:36:29 -04:00
parent 904f72a065
commit 25fba14574
4 changed files with 468 additions and 350 deletions

View File

@ -1654,6 +1654,7 @@ isearch(Application_Links *app, int start_reversed){
int reverse = start_reversed; int reverse = start_reversed;
int pos = view.cursor.pos; int pos = view.cursor.pos;
int start_pos = pos; int start_pos = pos;
int first_pos = pos;
Range match = make_range(pos, pos); Range match = make_range(pos, pos);
char bar_string_space[256]; char bar_string_space[256];
@ -1756,7 +1757,7 @@ isearch(Application_Links *app, int start_reversed){
} }
app->view_set_highlight(app, &view, 0, 0, false); app->view_set_highlight(app, &view, 0, 0, false);
if (in.abort){ if (in.abort){
app->view_set_cursor(app, &view, seek_pos(start_pos), true); app->view_set_cursor(app, &view, seek_pos(first_pos), true);
return; return;
} }

View File

@ -170,15 +170,12 @@ table_rehash(Table *src, Table *dst, void *arg, Hash_Function *hash_func, Compar
static uint32_t static uint32_t
tbl_string_hash(void *item, void *arg){ tbl_string_hash(void *item, void *arg){
String *string = (String*)item; String *string = (String*)item;
char *str; char *str = string->str;
int32_t i,len; int32_t i = 0, len = string->size;
uint32_t x = 5381; uint32_t x = 5381;
char c; char c;
(void)arg; (void)arg;
str = string->str;
len = string->size;
i = 0;
while (i < len){ while (i < len){
c = str[i++]; c = str[i++];
x = ((x << 5) + x) + c; x = ((x << 5) + x) + c;

View File

@ -188,6 +188,7 @@ struct Editing_File{
Editing_File_Name name; Editing_File_Name name;
Buffer_Slot_ID id; Buffer_Slot_ID id;
u64 unique_buffer_id; u64 unique_buffer_id;
Unique_Hash file_index;
}; };
struct Non_File_Table_Entry{ struct Non_File_Table_Entry{
@ -208,7 +209,8 @@ struct Working_Set{
File_Node free_sentinel; File_Node free_sentinel;
File_Node used_sentinel; File_Node used_sentinel;
Table table; Table uhash_table;
Table name_table;
String clipboards[64]; String clipboards[64];
i32 clipboard_size, clipboard_max_size; i32 clipboard_size, clipboard_max_size;
@ -219,42 +221,6 @@ struct Working_Set{
File_Node *sync_check_iter; File_Node *sync_check_iter;
}; };
struct File_Entry{
String short_name;
String long_name;
Buffer_Slot_ID id;
};
struct File_Entry_Comparison{
File_Entry entry;
Unique_Hash hash;
b32 use_hash;
};
internal i32
tbl_file_compare(void *a, void *b, void *arg){
File_Entry_Comparison *fa = (File_Entry_Comparison*)a;
File_Entry *fb = (File_Entry*)b;
System_Functions *system = (System_Functions*)arg;
Unique_Hash uhash;
i32 result = 1;
b32 success;
if (fa->use_hash){
uhash = system->file_unique_hash(fb->long_name, &success);
if (success && uhash_equal(uhash, fa->hash)){
result = 0;
}
}
else{
if (match(fa->entry.short_name, fb->short_name)){
result = 0;
}
}
return(result);
}
// //
// File_Edit_Positions stuff // File_Edit_Positions stuff
// //
@ -382,6 +348,48 @@ edit_pos_get_new(Editing_File *file, i32 index){
// Working_Set stuff // Working_Set stuff
// //
struct File_Uhash_Entry{
Unique_Hash hash;
Buffer_Slot_ID id;
};
struct File_Name_Entry{
String name;
Buffer_Slot_ID id;
};
internal u32
tbl_uhash_hash(void *item, void *arg){
Unique_Hash *hash = (Unique_Hash*)item;
return(hash->d[0] ^ (hash->d[1] << 24));
}
internal i32
tbl_uhash_compare(void *a, void *b, void *arg){
Unique_Hash *fa = (Unique_Hash*)a;
File_Uhash_Entry *fb = (File_Uhash_Entry*)b;
i32 result = 1;
if (uhash_equal(fb->hash, *fa)){
result = 0;
}
return(result);
}
internal i32
tbl_name_compare(void *a, void *b, void *arg){
String *fa = (String*)a;
File_Name_Entry *fb = (File_Name_Entry*)b;
i32 result = 1;
if (match(*fa, fb->name)){
result = 0;
}
return(result);
}
internal void internal void
working_set_extend_memory(Working_Set *working_set, Editing_File *new_space, i16 number_of_files){ working_set_extend_memory(Working_Set *working_set, Editing_File *new_space, i16 number_of_files){
Buffer_Slot_ID id; Buffer_Slot_ID id;
@ -434,7 +442,7 @@ working_set_alloc(Working_Set *working_set){
++working_set->file_count; ++working_set->file_count;
} }
return result; return(result);
} }
internal Editing_File* internal Editing_File*
@ -472,7 +480,7 @@ working_set_free_file(Working_Set *working_set, Editing_File *file){
inline Editing_File* inline Editing_File*
working_set_index(Working_Set *working_set, Buffer_Slot_ID id){ working_set_index(Working_Set *working_set, Buffer_Slot_ID id){
Editing_File *result = 0; Editing_File *result = 0;
File_Array *array; File_Array *array = 0;
if (id.part[1] >= 0 && id.part[1] < working_set->array_count){ if (id.part[1] >= 0 && id.part[1] < working_set->array_count){
array = working_set->file_arrays + id.part[1]; array = working_set->file_arrays + id.part[1];
@ -486,8 +494,7 @@ working_set_index(Working_Set *working_set, Buffer_Slot_ID id){
inline Editing_File* inline Editing_File*
working_set_index(Working_Set *working_set, i32 id){ working_set_index(Working_Set *working_set, i32 id){
Editing_File *result; Editing_File *result = working_set_index(working_set, to_file_id(id));
result = working_set_index(working_set, to_file_id(id));
return(result); return(result);
} }
@ -510,11 +517,6 @@ working_set_get_active_file(Working_Set *working_set, i32 id){
internal void internal void
working_set_init(Working_Set *working_set, Partition *partition, General_Memory *general){ working_set_init(Working_Set *working_set, Partition *partition, General_Memory *general){
Editing_File *files, *null_file;
void *mem;
i32 mem_size, table_size;
i32 item_size = sizeof(File_Entry);
i16 init_count = 16; i16 init_count = 16;
i16 array_init_count = 256; i16 array_init_count = 256;
@ -524,31 +526,45 @@ working_set_init(Working_Set *working_set, Partition *partition, General_Memory
working_set->array_max = array_init_count; working_set->array_max = array_init_count;
working_set->file_arrays = push_array(partition, File_Array, array_init_count); working_set->file_arrays = push_array(partition, File_Array, array_init_count);
files = push_array(partition, Editing_File, init_count); Editing_File *files = push_array(partition, Editing_File, init_count);
working_set_extend_memory(working_set, files, init_count); working_set_extend_memory(working_set, files, init_count);
null_file = working_set_index(working_set, 0); // NOTE(allen): init null file
dll_remove(&null_file->node); {
null_file->is_dummy = 1; Editing_File *null_file = working_set_index(working_set, 0);
++working_set->file_count; dll_remove(&null_file->node);
null_file->is_dummy = 1;
++working_set->file_count;
}
table_size = working_set->file_max; // NOTE(allen): init uhash table
mem_size = table_required_mem_size(table_size, item_size); {
mem = general_memory_allocate(general, mem_size); i32 item_size = sizeof(File_Uhash_Entry);
memset(mem, 0, mem_size); i32 table_size = working_set->file_max;
table_init_memory(&working_set->table, mem, table_size, item_size); i32 mem_size = table_required_mem_size(table_size, item_size);
void *mem = general_memory_allocate(general, mem_size);
memset(mem, 0, mem_size);
table_init_memory(&working_set->uhash_table, mem, table_size, item_size);
}
// NOTE(allen): init name table
{
i32 item_size = sizeof(File_Name_Entry);
i32 table_size = working_set->file_max;
i32 mem_size = table_required_mem_size(table_size, item_size);
void *mem = general_memory_allocate(general, mem_size);
memset(mem, 0, mem_size);
table_init_memory(&working_set->name_table, mem, table_size, item_size);
}
} }
inline void inline void
working_set__grow_if_needed(Table *table, General_Memory *general, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){ working_set__grow_if_needed(Table *table, General_Memory *general, void *arg, Hash_Function *hash_func, Compare_Function *comp_func){
Table btable;
i32 new_max, mem_size;
void *mem;
if (table_at_capacity(table)){ if (table_at_capacity(table)){
new_max = table->max * 2; Table btable = {0};
mem_size = table_required_mem_size(new_max, table->item_size); i32 new_max = table->max * 2;
mem = general_memory_allocate(general, mem_size); i32 mem_size = table_required_mem_size(new_max, table->item_size);
void *mem = general_memory_allocate(general, mem_size);
table_init_memory(&btable, mem, new_max, table->item_size); table_init_memory(&btable, mem, new_max, table->item_size);
table_clear(&btable); table_clear(&btable);
table_rehash(table, &btable, 0, hash_func, comp_func); table_rehash(table, &btable, 0, hash_func, comp_func);
@ -557,6 +573,80 @@ working_set__grow_if_needed(Table *table, General_Memory *general, void *arg, Ha
} }
} }
internal Editing_File*
working_set_uhash_contains(Working_Set *working_set, Unique_Hash index){
Editing_File *result = 0;
File_Uhash_Entry *entry = (File_Uhash_Entry*)
table_find_item(&working_set->uhash_table, &index, 0, tbl_uhash_hash, tbl_uhash_compare);
if (entry){
result = working_set_index(working_set, entry->id);
}
return(result);
}
internal Editing_File*
working_set_uhash_contains(System_Functions *system, Working_Set *working_set, String name){
Editing_File *file = 0;
Unique_Hash index = {0};
if (system->get_file_index(name.str, &index)){
if (!uhash_equal(index, uhash_zero())){
file = working_set_uhash_contains(working_set, index);
}
}
return(file);
}
internal void
working_set_uhash_add(General_Memory *general, Working_Set *working_set,
Editing_File *file, Unique_Hash hash){
working_set__grow_if_needed(&working_set->uhash_table, general,
0, tbl_uhash_hash, tbl_uhash_compare);
File_Uhash_Entry entry;
entry.hash = hash;
entry.id = file->id;
table_add(&working_set->uhash_table, &entry, 0, tbl_uhash_hash, tbl_uhash_compare);
}
internal void
working_set_uhash_remove(Working_Set *working_set, Unique_Hash hash){
table_remove_match(&working_set->uhash_table, &hash, 0, tbl_uhash_hash, tbl_uhash_compare);
}
internal Editing_File*
working_set_name_contains(Working_Set *working_set, String name){
Editing_File *result = 0;
File_Name_Entry *entry = (File_Name_Entry*)
table_find_item(&working_set->name_table, &name, 0, tbl_string_hash, tbl_string_compare);
if (entry){
result = working_set_index(working_set, entry->id);
}
return(result);
}
internal void
working_set_name_add(General_Memory *general, Working_Set *working_set,
Editing_File *file, String name){
working_set__grow_if_needed(&working_set->name_table, general,
0, tbl_string_hash, tbl_string_compare);
File_Name_Entry entry;
entry.name = name;
entry.id = file->id;
table_add(&working_set->name_table, &entry, 0, tbl_string_hash, tbl_string_compare);
}
internal void
working_set_name_remove(Working_Set *working_set, String name){
table_remove_match(&working_set->name_table, &name, 0, tbl_string_hash, tbl_string_compare);
}
#if 0
inline void inline void
working_set__entry_comp(System_Functions *system, String filename, File_Entry_Comparison *out){ working_set__entry_comp(System_Functions *system, String filename, File_Entry_Comparison *out){
out->entry.long_name = filename; out->entry.long_name = filename;
@ -572,7 +662,6 @@ working_set_contains(System_Functions *system, Working_Set *working_set, String
working_set__entry_comp(system, filename, &entry_comp); working_set__entry_comp(system, filename, &entry_comp);
entry = (File_Entry*)table_find_item(&working_set->table, &entry_comp, system, tbl_string_hash, tbl_file_compare); entry = (File_Entry*)table_find_item(&working_set->table, &entry_comp, system, tbl_string_hash, tbl_file_compare);
if (entry){ if (entry){
result = working_set_index(working_set, entry->id); result = working_set_index(working_set, entry->id);
} }
@ -602,6 +691,7 @@ working_set_remove(System_Functions *system, Working_Set *working_set, String fi
system->file_untrack(filename); system->file_untrack(filename);
} }
} }
#endif
// TODO(allen): Pick better first options. // TODO(allen): Pick better first options.
internal Editing_File* internal Editing_File*
@ -609,6 +699,7 @@ working_set_lookup_file(Working_Set *working_set, String string){
Editing_File *file = 0; Editing_File *file = 0;
{ {
// TODO(allen): use the name table for this
File_Node *node, *used_nodes; File_Node *node, *used_nodes;
used_nodes = &working_set->used_sentinel; used_nodes = &working_set->used_sentinel;
for (dll_items(node, used_nodes)){ for (dll_items(node, used_nodes)){
@ -800,5 +891,130 @@ file_get_sync(Editing_File *file){
return (file->state.sync); return (file->state.sync);
} }
internal void
editing_file_name_init(Editing_File_Name *name){
name->live_name = make_fixed_width_string(name->live_name_);
name->source_path = make_fixed_width_string(name->source_path_);
name->extension = make_fixed_width_string(name->extension_);
}
internal void
buffer_get_new_name(Working_Set *working_set, Editing_File_Name *name, String filename){
Assert(name->live_name.str != 0);
copy_checked(&name->source_path, filename);
copy(&name->live_name, front_of_directory(filename));
if (name->source_path.size == name->live_name.size){
name->extension.size = 0;
}
else{
String ext = file_extension(filename);
copy(&name->extension, ext);
}
{
i32 original_len = name->live_name.size;
i32 file_x = 0;
b32 hit_conflict = 1;
while (hit_conflict){
hit_conflict = 0;
File_Node *used_nodes = &working_set->used_sentinel, *node;
for (dll_items(node, used_nodes)){
Editing_File *file_ptr = (Editing_File*)node;
if (file_is_ready(file_ptr)){
if (match(name->live_name, file_ptr->name.live_name)){
++file_x;
hit_conflict = 1;
break;
}
}
}
if (hit_conflict){
name->live_name.size = original_len;
append(&name->live_name, " <");
append_int_to_str(&name->live_name, file_x);
append(&name->live_name, ">");
}
}
}
}
inline void
buffer_get_new_name(Working_Set *working_set, Editing_File_Name *name, char *filename){
String f = make_string_slowly(filename);
buffer_get_new_name(working_set, name, f);
}
internal void
buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set *working_set,
Editing_File *file, Unique_Hash index){
Assert(file->name.live_name.size == 0 &&
file->name.source_path.size == 0 &&
file->name.extension.size == 0);
Assert(uhash_equal(file->file_index, uhash_zero()));
Assert(!uhash_equal(index, uhash_zero()));
working_set_uhash_add(general, working_set, file, index);
file->file_index = index;
}
internal void
buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set *working_set,
Editing_File *file, char *filename, u32 flags){
Assert(file->name.live_name.size == 0 &&
file->name.source_path.size == 0 &&
file->name.extension.size == 0);
Assert(uhash_equal(file->file_index, uhash_zero()));
Unique_Hash index = system->track_file(filename, flags);
if (!uhash_equal(index, uhash_zero())){
working_set_uhash_add(general, working_set, file, index);
file->file_index = index;
}
}
internal void
buffer_unbind_file(System_Functions *system, Working_Set *working_set, Editing_File *file){
Assert(file->name.live_name.size == 0 &&
file->name.source_path.size == 0 &&
file->name.extension.size == 0);
Assert(!uhash_equal(file->file_index, uhash_zero()));
system->untrack_file(file->file_index);
working_set_uhash_remove(working_set, file->file_index);
file->file_index = uhash_zero();
}
internal void
buffer_bind_name(General_Memory *general, Working_Set *working_set,
Editing_File *file, char *filename){
Assert(file->name.live_name.size == 0 &&
file->name.source_path.size == 0 &&
file->name.extension.size == 0);
Editing_File_Name new_name;
editing_file_name_init(&new_name);
buffer_get_new_name(working_set, &new_name, filename);
editing_file_name_init(&file->name);
copy(&file->name.live_name, new_name.live_name);
copy(&file->name.source_path, new_name.source_path);
copy(&file->name.extension, new_name.extension);
working_set_name_add(general, working_set, file, file->name.live_name);
}
internal void
buffer_unbind_name(Working_Set *working_set, Editing_File *file){
Assert(file->name.live_name.size != 0);
working_set_name_remove(working_set, file->name.live_name);
file->name.live_name.size = 0;
file->name.source_path.size = 0;
file->name.extension.size = 0;
}
// BOTTOM // BOTTOM

View File

@ -780,71 +780,6 @@ starts_new_line(u8 character){
return (character == '\n'); return (character == '\n');
} }
inline void
file_init_strings(Editing_File *file){
file->name.source_path = make_fixed_width_string(file->name.source_path_);
file->name.live_name = make_fixed_width_string(file->name.live_name_);
file->name.extension = make_fixed_width_string(file->name.extension_);
}
internal void
file_set_name(Working_Set *working_set, Editing_File *file, String filename){
String ext;
Assert(file->name.live_name.str != 0);
copy_checked(&file->name.source_path, filename);
copy(&file->name.live_name, front_of_directory(filename));
if (file->name.source_path.size == file->name.live_name.size){
file->name.extension.size = 0;
}
else{
ext = file_extension(filename);
copy(&file->name.extension, ext);
}
{
File_Node *node, *used_nodes;
Editing_File *file_ptr;
i32 file_x, original_len;
b32 hit_conflict;
used_nodes = &working_set->used_sentinel;
original_len = file->name.live_name.size;
hit_conflict = 1;
file_x = 0;
while (hit_conflict){
hit_conflict = 0;
for (dll_items(node, used_nodes)){
file_ptr = (Editing_File*)node;
if (file_ptr != file && file_is_ready(file_ptr)){
if (match(file->name.live_name, file_ptr->name.live_name)){
++file_x;
hit_conflict = 1;
break;
}
}
}
if (hit_conflict){
file->name.live_name.size = original_len;
append(&file->name.live_name, " <");
append_int_to_str(&file->name.live_name, file_x);
append(&file->name.live_name, ">");
}
}
}
}
inline void
file_set_name(Working_Set *working_set, Editing_File *file, char *filename){
String f = make_string_slowly(filename);
file_set_name(working_set, file, f);
}
#if 0 #if 0
inline void inline void
file_synchronize_times(System_Functions *system, Editing_File *file, char *filename){ file_synchronize_times(System_Functions *system, Editing_File *file, char *filename){
@ -860,61 +795,80 @@ file_synchronize_times(System_Functions *system, Editing_File *file, char *filen
inline void inline void
file_synchronize_times(System_Functions *system, Editing_File *file){ file_synchronize_times(System_Functions *system, Editing_File *file){
file->state.last_sync = system->now_time_stamp(); system->now_file_time(&file->state.last_sync);
file->state.sync = SYNC_GOOD; file->state.sync = SYNC_GOOD;
} }
internal b32 internal b32
file_save(System_Functions *system, Mem_Options *mem, Editing_File *file, char *filename){ file_save(System_Functions *system, Mem_Options *mem, Editing_File *file){
b32 result = 0; b32 result = 0;
i32 max = 0, size = 0; if (!uhash_equal(file->file_index, uhash_zero())){
b32 dos_write_mode = file->settings.dos_write_mode; i32 max = 0, size = 0;
char *data = 0; b32 dos_write_mode = file->settings.dos_write_mode;
Buffer_Type *buffer = &file->state.buffer; char *data = 0;
Buffer_Type *buffer = &file->state.buffer;
if (dos_write_mode){ if (dos_write_mode){
max = buffer_size(buffer) + buffer->line_count + 1; max = buffer_size(buffer) + buffer->line_count + 1;
} }
else{ else{
max = buffer_size(buffer); max = buffer_size(buffer);
}
b32 used_general = 0;
Temp_Memory temp = begin_temp_memory(&mem->part);
char empty = 0;
if (max == 0){
data = &empty;
}
else{
data = (char*)push_array(&mem->part, char, max);
if (!data){
used_general = 1;
data = (char*)general_memory_allocate(&mem->general, max);
} }
}
Assert(data);
if (dos_write_mode){ b32 used_general = 0;
size = buffer_convert_out(buffer, data, max); Temp_Memory temp = begin_temp_memory(&mem->part);
} char empty = 0;
else{ if (max == 0){
size = max; data = &empty;
buffer_stringify(buffer, 0, size, data); }
else{
data = (char*)push_array(&mem->part, char, max);
if (!data){
used_general = 1;
data = (char*)general_memory_allocate(&mem->general, max);
}
}
Assert(data);
if (dos_write_mode){
size = buffer_convert_out(buffer, data, max);
}
else{
size = max;
buffer_stringify(buffer, 0, size, data);
}
result = system->save_file(file->file_index, data, size);
file_mark_clean(file);
if (used_general){
general_memory_free(&mem->general, data);
}
end_temp_memory(temp);
file_synchronize_times(system, file);
} }
result = system->file_save(filename, data, size); return(result);
}
file_mark_clean(file); internal b32
buffer_link_to_new_file(System_Functions *system, General_Memory *general, Working_Set *working_set,
if (used_general){ Editing_File *file, char *filename){
general_memory_free(&mem->general, data); b32 result = 0;
Unique_Hash index = system->track_file(filename, TrackFileFlag_ExistingOrNew);
if (!uhash_equal(index, uhash_zero())){
buffer_unbind_name(working_set, file);
if (!uhash_equal(file->file_index, uhash_zero())){
buffer_unbind_file(system, working_set, file);
}
buffer_bind_file(system, general, working_set, file, filename, TrackFileFlag_ExistingOrNew);
buffer_bind_name(general, working_set, file, filename);
result = 1;
} }
end_temp_memory(temp);
file_synchronize_times(system, file);
return(result); return(result);
} }
@ -922,12 +876,11 @@ inline b32
file_save_and_set_names(System_Functions *system, Mem_Options *mem, file_save_and_set_names(System_Functions *system, Mem_Options *mem,
Working_Set *working_set, Editing_File *file, Working_Set *working_set, Editing_File *file,
char *filename){ char *filename){
b32 result = 0; b32 result = buffer_link_to_new_file(system, &mem->general, working_set, file, filename);
result = file_save(system, mem, file, filename);
if (result){ if (result){
file_set_name(working_set, file, filename); result = file_save(system, mem, file);
} }
return result; return(result);
} }
enum{ enum{
@ -1054,7 +1007,6 @@ file_create_from_string(System_Functions *system, Models *models,
String val, b8 read_only = 0){ String val, b8 read_only = 0){
Font_Set *font_set = models->font_set; Font_Set *font_set = models->font_set;
Working_Set *working_set = &models->working_set;
General_Memory *general = &models->mem.general; General_Memory *general = &models->mem.general;
Partition *part = &models->mem.part; Partition *part = &models->mem.part;
Buffer_Init_Type init; Buffer_Init_Type init;
@ -1074,16 +1026,12 @@ file_create_from_string(System_Functions *system, Models *models,
Assert(scratch_size > 0); Assert(scratch_size > 0);
b32 init_success = buffer_end_init(&init, part->base + part->pos, scratch_size); b32 init_success = buffer_end_init(&init, part->base + part->pos, scratch_size);
AllowLocal(init_success); AllowLocal(init_success); Assert(init_success);
Assert(init_success);
if (buffer_size(&file->state.buffer) < val.size){ if (buffer_size(&file->state.buffer) < val.size){
file->settings.dos_write_mode = 1; file->settings.dos_write_mode = 1;
} }
file_init_strings(file);
file_set_name(working_set, file, (char*)name);
file_synchronize_times(system, file); file_synchronize_times(system, file);
i16 font_id = models->global_font.font_id; i16 font_id = models->global_font.font_id;
@ -1129,15 +1077,6 @@ file_create_from_string(System_Functions *system, Models *models,
file->settings.is_initialized = 1; file->settings.is_initialized = 1;
} }
#undef TEST_TIME_MAX
internal b32
file_create_empty(System_Functions *system,
Models *models, Editing_File *file, char *filename){
file_create_from_string(system, models, file, filename, string_zero());
return (1);
}
internal b32 internal b32
file_create_read_only(System_Functions *system, file_create_read_only(System_Functions *system,
Models *models, Editing_File *file, char *filename){ Models *models, Editing_File *file, char *filename){
@ -3232,7 +3171,6 @@ view_show_file(View *view){
} }
} }
internal String internal String
make_string_terminated(Partition *part, char *str, i32 len){ make_string_terminated(Partition *part, char *str, i32 len){
char *space = (char*)push_array(part, char, len + 1); char *space = (char*)push_array(part, char, len + 1);
@ -3243,68 +3181,9 @@ make_string_terminated(Partition *part, char *str, i32 len){
return(string); return(string);
} }
internal void
view_save_file(System_Functions *system, Models *models,
Editing_File *file, View *view, String filename, b32 save_as){
Mem_Options *mem = &models->mem;
Working_Set *working_set = &models->working_set;
Temp_Memory temp = begin_temp_memory(&mem->part);
String filename_string =
make_string_terminated(&mem->part, filename.str, filename.size);
if (!file){
if (view){
file = view->file_data.file;
}
else{
file = working_set_lookup_file(working_set, filename_string);
}
}
if (file && (file_get_sync(file) != SYNC_GOOD || save_as)){
if (file_save(system, mem, file, filename_string.str)){
if (save_as){
file_set_name(working_set, file, filename_string.str);
}
}
}
end_temp_memory(temp);
}
internal void
view_new_file(System_Functions *system, Models *models,
View *view, String string){
Working_Set *working_set = &models->working_set;
General_Memory *general = &models->mem.general;
Editing_File *file = working_set_alloc_always(working_set, general);
file_create_empty(system, models, file, string.str);
working_set_add(system, working_set, file, general);
view_set_file(view, file, models);
view_show_file(view);
view->map = get_map(models, file->settings.base_map_id);
Open_File_Hook_Function *new_file_fnc = models->hook_new_file;
if (new_file_fnc){
new_file_fnc(&models->app_links, file->id.id);
}
file->settings.is_initialized = 1;
#if BUFFER_EXPERIMENT_SCALPEL <= 0
if (file->settings.tokens_exist && file->state.token_stack.tokens == 0){
file_first_lex_parallel(system, general, file);
}
#endif
}
internal void internal void
init_normal_file(System_Functions *system, Models *models, Editing_File *file, init_normal_file(System_Functions *system, Models *models, Editing_File *file,
char *buffer, i32 size){ char *buffer, i32 size){
General_Memory *general = &models->mem.general; General_Memory *general = &models->mem.general;
String val = make_string(buffer, size); String val = make_string(buffer, size);
@ -3322,77 +3201,106 @@ init_normal_file(System_Functions *system, Models *models, Editing_File *file,
} }
internal void internal void
view_open_file(System_Functions *system, Models *models, view_interactive_open_file(System_Functions *system, Models *models, View *view, String filename){
View *view, String filename){
Working_Set *working_set = &models->working_set; Working_Set *working_set = &models->working_set;
General_Memory *general = &models->mem.general; Editing_File *file = 0;
Partition *part = &models->mem.part; Unique_Hash index = {0};
Editing_File *file = working_set_contains(system, working_set, filename); if (terminate_with_null(&filename)){
if (system->get_file_index(filename.str, &index)){
file = working_set_uhash_contains(working_set, index);
}
else{
index = system->track_file(filename.str, TrackFileFlag_ExistingOrFail);
if (!uhash_equal(index, uhash_zero())){
Mem_Options *mem = &models->mem;
General_Memory *general = &mem->general;
if (file == 0){
File_Loading loading = system->file_load_begin(filename.str);
if (loading.exists){
b32 in_general_mem = 0;
Temp_Memory temp = begin_temp_memory(part);
char *buffer = push_array(part, char, loading.size);
// TODO(allen): How will we get temporary space for large
// buffers? The main partition isn't always big enough
// but getting a general block this large and copying it
// then freeing it is *super* dumb!
if (buffer == 0){
buffer = (char*)general_memory_allocate(general, loading.size);
if (buffer != 0){
in_general_mem = 1;
}
}
if (system->file_load_end(loading, buffer)){
file = working_set_alloc_always(working_set, general); file = working_set_alloc_always(working_set, general);
if (file){
file_init_strings(file);
file_set_name(working_set, file, filename.str);
working_set_add(system, working_set, file, general);
init_normal_file(system, models, file, buffer_bind_file(system, general, working_set, file, index);
buffer, loading.size); buffer_bind_name(general, working_set, file, filename.str);
i32 size = system->file_size(index);
Partition *part = &mem->part;
char *buffer = 0;
b32 gen_buffer = 0;
Temp_Memory temp = begin_temp_memory(part);
buffer = push_array(part, char, size);
if (buffer == 0){
buffer = (char*)general_memory_allocate(general, size);
Assert(buffer);
gen_buffer = 1;
} }
}
if (in_general_mem){ system->load_file(index, buffer, size);
general_memory_free(general, buffer);
}
end_temp_memory(temp); init_normal_file(system, models, file, buffer, size);
if (gen_buffer){
general_memory_free(general, buffer);
}
end_temp_memory(temp);
}
} }
} }
if (file){ if (file){
if (view){ view_set_file(view, file, models);
view_set_file(view, file, models);
view_show_file(view);
}
} }
} }
internal void internal void
kill_file(System_Functions *system, Models *models, view_interactive_save_as(System_Functions *system, Models *models, Editing_File *file, String filename){
Editing_File *file, String string){ if (terminate_with_null(&filename)){
Working_Set *working_set = &models->working_set; file_save_and_set_names(system, &models->mem, &models->working_set, file, filename.str);
}
}
if (!file && string.str){ internal void
file = working_set_lookup_file(working_set, string); view_interactive_new_file(System_Functions *system, Models *models, View *view, String filename){
if (!file){ Working_Set *working_set = &models->working_set;
file = working_set_contains(system, working_set, string); Editing_File *file = 0;
Unique_Hash index = {0};
if (terminate_with_null(&filename)){
if (system->get_file_index(filename.str, &index)){
file = working_set_uhash_contains(working_set, index);
file_clear(system, models, file);
}
else{
index = system->track_file(filename.str, TrackFileFlag_NewAlways);
if (!uhash_equal(index, uhash_zero())){
Mem_Options *mem = &models->mem;
General_Memory *general = &mem->general;
file = working_set_alloc_always(working_set, general);
buffer_bind_file(system, general, working_set, file, index);
buffer_bind_name(general, working_set, file, filename.str);
init_normal_file(system, models, file, 0, 0);
}
} }
} }
if (file){
view_set_file(view, file, models);
}
}
internal void
kill_file(System_Functions *system, Models *models, Editing_File *file){
Working_Set *working_set = &models->working_set;
if (file && !file->settings.never_kill){ if (file && !file->settings.never_kill){
working_set_remove(system, working_set, file->name.source_path); buffer_unbind_name(working_set, file);
buffer_unbind_file(system, working_set, file);
file_close(system, &models->mem.general, file); file_close(system, &models->mem.general, file);
working_set_free_file(&models->working_set, file); working_set_free_file(working_set, file);
File_Node *used = &models->working_set.used_sentinel; File_Node *used = &models->working_set.used_sentinel;
File_Node *node = used->next; File_Node *node = used->next;
@ -3412,25 +3320,29 @@ kill_file(System_Functions *system, Models *models,
} }
} }
internal b32 internal void
try_kill_file(System_Functions *system, Models *models, kill_file_by_name(System_Functions *system, Models *models, String name){
Editing_File *file, View *view, String string){ Editing_File *file = working_set_name_contains(&models->working_set, name);
if (file){
b32 kill_dialogue = false; kill_file(system, models, file);
Working_Set *working_set = &models->working_set;
if (!file && string.str){
file = working_set_lookup_file(working_set, string);
if (!file){
file = working_set_contains(system, working_set, string);
}
} }
}
internal void
save_file_by_name(System_Functions *system, Models *models, String name){
Editing_File *file = working_set_name_contains(&models->working_set, name);
if (file){
file_save(system, &models->mem, file);
}
}
internal b32
interactive_try_kill_file(System_Functions *system, Models *models, View *view, String name){
b32 kill_dialogue = false;
Editing_File *file = working_set_name_contains(&models->working_set, name);
if (file && !file->settings.never_kill){ if (file && !file->settings.never_kill){
if (buffer_needs_save(file)){ if (buffer_needs_save(file)){
if (view == 0){
view = models->layout.panels[models->layout.active_panel].view;
}
view_show_interactive(system, view, view_show_interactive(system, view,
IAct_Sure_To_Kill, IInt_Sure_To_Kill, IAct_Sure_To_Kill, IInt_Sure_To_Kill,
make_lit_string("Are you sure?")); make_lit_string("Are you sure?"));
@ -3438,7 +3350,7 @@ try_kill_file(System_Functions *system, Models *models,
kill_dialogue = true; kill_dialogue = true;
} }
else{ else{
kill_file(system, models, file, string_zero()); kill_file(system, models, file);
} }
} }
@ -3448,37 +3360,28 @@ try_kill_file(System_Functions *system, Models *models,
internal void internal void
interactive_view_complete(System_Functions *system, View *view, String dest, i32 user_action){ interactive_view_complete(System_Functions *system, View *view, String dest, i32 user_action){
Models *models = view->persistent.models; Models *models = view->persistent.models;
//Editing_File *old_file = view->file_data.file;
switch (view->action){ switch (view->action){
case IAct_Open: case IAct_Open:
view_open_file(system, models, view, dest); view_interactive_open_file(system, models, view, dest);
//touch_file(&models->working_set, old_file);
view_show_file(view); view_show_file(view);
break; break;
case IAct_Save_As: case IAct_Save_As:
view_save_file(system, models, 0, view, dest, 1); view_interactive_save_as(system, models, view->file_data.file, dest);
view_show_file(view); view_show_file(view);
break; break;
case IAct_New: case IAct_New:
if (dest.size > 0 && !char_is_slash(dest.str[dest.size-1])){ if (dest.size > 0 && !char_is_slash(dest.str[dest.size-1])){
view_new_file(system, models, view, dest); view_interactive_new_file(system, models, view, dest);
view_show_file(view); view_show_file(view);
}break; }
break;
case IAct_Switch: case IAct_Switch:
{ {
//touch_file(&models->working_set, old_file); Editing_File *file = working_set_name_contains(&models->working_set, dest);
Editing_File *file = 0;
String string = dest;
file = working_set_lookup_file(&models->working_set, string);
if (!file){
file = working_set_contains(system, &models->working_set, string);
}
if (file){ if (file){
view_set_file(view, file, models); view_set_file(view, file, models);
} }
@ -3487,7 +3390,7 @@ interactive_view_complete(System_Functions *system, View *view, String dest, i32
break; break;
case IAct_Kill: case IAct_Kill:
if (!try_kill_file(system, models, 0, 0, dest)){ if (!interactive_try_kill_file(system, models, view, dest)){
view_show_file(view); view_show_file(view);
} }
break; break;
@ -3511,7 +3414,7 @@ interactive_view_complete(System_Functions *system, View *view, String dest, i32
case IAct_Sure_To_Kill: case IAct_Sure_To_Kill:
switch (user_action){ switch (user_action){
case 0: case 0:
kill_file(system, models, 0, dest); kill_file_by_name(system, models, dest);
view_show_file(view); view_show_file(view);
break; break;
@ -3520,8 +3423,8 @@ interactive_view_complete(System_Functions *system, View *view, String dest, i32
break; break;
case 2: case 2:
view_save_file(system, models, 0, 0, dest, 0); save_file_by_name(system, models, dest);
kill_file(system, models, 0, dest); kill_file_by_name(system, models, dest);
view_show_file(view); view_show_file(view);
break; break;
} }
@ -3746,7 +3649,7 @@ get_exhaustive_info(System_Functions *system, Working_Set *working_set, Exhausti
loop->full_path.size = loop->r; loop->full_path.size = loop->r;
append(&loop->full_path, result.info->filename); append(&loop->full_path, result.info->filename);
terminate_with_null(&loop->full_path); terminate_with_null(&loop->full_path);
file = working_set_contains(system, working_set, loop->full_path); file = working_set_uhash_contains(system, working_set, loop->full_path);
String filename = make_string(result.info->filename, String filename = make_string(result.info->filename,
result.info->filename_len, result.info->filename_len+1); result.info->filename_len, result.info->filename_len+1);
@ -4715,7 +4618,8 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
// Time Watcher // Time Watcher
{ {
string.size = 0; string.size = 0;
u64 time = system->now_time_stamp(); u64 time = 0;
system->now_file_time(&time);
append(&string, "last redraw: "); append(&string, "last redraw: ");
append_u64_to_str(&string, time); append_u64_to_str(&string, time);