diff --git a/4ed.cpp b/4ed.cpp index 18ad9c85..43a93757 100644 --- a/4ed.cpp +++ b/4ed.cpp @@ -131,6 +131,32 @@ app_get_map(Models *models, i32 mapid){ return map; } +inline void +output_file_append(System_Functions *system, Models *models, Editing_File *file, String value, b32 cursor_at_end){ + i32 end = buffer_size(&file->state.buffer); + i32 next_cursor = 0; + if (cursor_at_end){ + next_cursor = end + value.size; + } + file_replace_range(system, models, file, end, end, value.str, value.size, next_cursor, 1); +} + +inline void +do_feedback_message(System_Functions *system, Models *models, String value){ + Editing_File *file = models->message_buffer; + + if (file){ + output_file_append(system, models, file, value, 1); + + i32 pos = buffer_size(&file->state.buffer); + for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); + file_view_iter_good(iter); + iter = file_view_iter_next(iter)){ + view_cursor_move(iter.view, pos); + } + } +} + // Commands globalvar Application_Links app_links; @@ -983,7 +1009,7 @@ COMMAND_DECL(reopen){ models->hooks[hook_open_file], &app_links); } else{ - // TODO(allen): feedback message + do_feedback_message(system, models, make_lit_string("ERROR: no file load slot available\n")); } } @@ -1698,6 +1724,9 @@ COMMAND_DECL(command_line){ i32 script_len = 0; u32 flags = CLI_OverlapWithConflict; b32 do_in_background = 0; + + char feedback_space[256]; + String feedback_str = make_fixed_width_string(feedback_space); Command_Parameter *end = param_stack_end(&command->part); Command_Parameter *param = param_stack_first(&command->part, end); @@ -1756,7 +1785,17 @@ COMMAND_DECL(command_line){ if (buffer_id){ file = working_set_get_active_file(working_set, buffer_id); if (file && file->settings.read_only == 0){ - // TODO(allen): feedback message - file not read only + append(&feedback_str, "ERROR: "); + append(&feedback_str, file->name.live_name); + append(&feedback_str, " is not a read-only buffer\n"); + do_feedback_message(system, models, feedback_str); + return; + } + if (file->settings.never_kill){ + append(&feedback_str, "The buffer "); + append(&feedback_str, file->name.live_name); + append(&feedback_str, " is not killable"); + do_feedback_message(system, models, feedback_str); return; } } @@ -1764,28 +1803,37 @@ COMMAND_DECL(command_line){ file = working_set_contains(system, working_set, make_string(buffer_name, buffer_name_len)); if (file){ if (file->settings.read_only == 0){ - // TODO(allen): feedback message - file not read only + append(&feedback_str, "ERROR: "); + append(&feedback_str, file->name.live_name); + append(&feedback_str, " is not a read-only buffer\n"); + do_feedback_message(system, models, feedback_str); + return; + } + if (file->settings.never_kill){ + append(&feedback_str, "The buffer "); + append(&feedback_str, file->name.live_name); + append(&feedback_str, " is not killable"); + do_feedback_message(system, models, feedback_str); return; } } else{ file = working_set_alloc_always(working_set, general); - - file_create_read_only(system, models, file, buffer_name); - working_set_add(system, working_set, file, general); - if (file == 0){ - // TODO(allen): feedback message - no available file + append(&feedback_str, "ERROR: unable to allocate a new buffer\n"); + do_feedback_message(system, models, feedback_str); return; } + file_create_read_only(system, models, file, buffer_name); + working_set_add(system, working_set, file, general); } } - + if (file){ i32 proc_count = vars->cli_processes.count; View_Iter iter; i32 i; - + for (i = 0; i < proc_count; ++i){ if (procs[i].out_file == file){ if (flags & CLI_OverlapWithConflict) @@ -1795,7 +1843,7 @@ COMMAND_DECL(command_line){ break; } } - + if (file){ file_clear(system, models, file, 1); file->settings.unimportant = 1; @@ -1808,11 +1856,12 @@ COMMAND_DECL(command_line){ } } else{ - // TODO(allen): feedback message - file conflict + append(&feedback_str, "did not begin command-line command because the target buffer is already in use\n"); + do_feedback_message(system, models, feedback_str); return; } } - + if (!path){ path = models->hot_directory.string.str; terminate_with_null(&models->hot_directory.string); @@ -1853,7 +1902,8 @@ COMMAND_DECL(command_line){ } } else{ - // TODO(allen): feedback message - no available process slot + append(&feedback_str, "ERROR: no available process slot\n"); + do_feedback_message(system, models, feedback_str); return; } } @@ -3415,7 +3465,7 @@ App_Step_Sig(app_step){ dest->size = eol_convert_in(dest->str, clipboard.str, clipboard.size); } - // TODO(allen): profile this make sure it's not costing me too much power. + // TODO(allen): profile this see if it's costing me lots of power (I think it is). // NOTE(allen): check files are up to date { File_Node *node, *used_nodes; @@ -3453,20 +3503,15 @@ App_Step_Sig(app_step){ i32 count = vars->cli_processes.count; for (i32 i = 0; i < count; ++i){ CLI_Process *proc = vars->cli_processes.procs + i; - Editing_File *out_file = proc->out_file; + Editing_File *file = proc->out_file; - if (out_file != 0){ - i32 new_cursor = out_file->state.cursor_pos; + if (file != 0){ for (system->cli_begin_update(&proc->cli); system->cli_update_step(&proc->cli, dest, max, &amount);){ amount = eol_in_place_convert_in(dest, amount); - - i32 end = buffer_size(&out_file->state.buffer); - file_replace_range(system, models, out_file, - end, end, dest, amount, end + amount, 1); + output_file_append(system, models, file, make_string(dest, amount), 0); app_result.redraw = 1; - new_cursor = end + amount; } if (system->cli_end_update(&proc->cli)){ @@ -3478,16 +3523,13 @@ App_Step_Sig(app_step){ append(&str, "exited with code "); append_int_to_str(proc->cli.exit, &str); - i32 end = buffer_size(&out_file->state.buffer); - file_replace_range(system, models, out_file, - end, end, str.str, str.size, end + str.size, 1); + output_file_append(system, models, file, str, 0); app_result.redraw = 1; - new_cursor = end + str.size; } - new_cursor = 0; + i32 new_cursor = 0; - for (View_Iter iter = file_view_iter_init(&models->layout, out_file, 0); + for (View_Iter iter = file_view_iter_init(&models->layout, file, 0); file_view_iter_good(iter); iter = file_view_iter_next(iter)){ view_cursor_move(iter.view, new_cursor); @@ -3664,6 +3706,15 @@ App_Step_Sig(app_step){ delayed_open_background(&models->delay1, file_name); } } + + General_Memory *general = &models->mem.general; + Editing_File *file = working_set_alloc_always(&models->working_set, general); + file_create_read_only(system, models, file, "*messages*"); + working_set_add(system, &models->working_set, file, general); + file->settings.never_kill = 1; + file->settings.unimportant = 1; + + models->message_buffer = file; } ProfileEnd(prepare_commands); @@ -4384,11 +4435,11 @@ App_Step_Sig(app_step){ file = working_set_contains(system, working_set, string); } } - - if (file){ + + if (file && !file->settings.never_kill){ working_set_remove(system, working_set, file->name.source_path); kill_file(system, exchange, models, file, - models->hooks[hook_open_file], &app_links); + models->hooks[hook_open_file], &app_links); } }break; @@ -4410,7 +4461,7 @@ App_Step_Sig(app_step){ } } - if (file){ + if (file && !file->settings.never_kill){ if (buffer_needs_save(file)){ view_show_interactive(system, view, &models->map_ui, IAct_Sure_To_Kill, IInt_Sure_To_Kill, make_lit_string("Are you sure?")); diff --git a/4ed_app_settings.h b/4ed_app_settings.h index c2774766..edafdb18 100644 --- a/4ed_app_settings.h +++ b/4ed_app_settings.h @@ -51,6 +51,7 @@ struct Models{ Editing_Layout layout; Working_Set working_set; + Editing_File *message_buffer; char hot_dir_base_[256]; Hot_Directory hot_directory; diff --git a/4ed_file.cpp b/4ed_file.cpp index e7aa13c4..37856703 100644 --- a/4ed_file.cpp +++ b/4ed_file.cpp @@ -105,6 +105,7 @@ struct Editing_File_Settings{ b8 is_initialized; b8 unimportant; b8 read_only; + b8 never_kill; }; // NOTE(allen): This part of the Editing_File is cleared whenever @@ -175,95 +176,6 @@ struct Editing_File{ File_ID id; }; -#if 0 -struct File_Table_Entry{ - String name; - u32 hash; - File_ID id; -}; - -// TODO(allen): -// Remove this File_Table and instead use the table in 4tech_table.cpp -// Instead of hashing by file name use the new Unique_Hash in the system. -struct File_Table{ - File_Table_Entry *table; - i32 count, max; -}; - -internal u32 -get_file_hash(String name){ - u32 x = 5381; - int i = 0; - char c; - while (i < name.size){ - c = name.str[i++]; - x = ((x << 5) + x) + c; - } - return x; -} - -internal b32 -table_add(File_Table *table, String name, i32 id){ - Assert(table->count * 3 < table->max * 2); - - File_Table_Entry entry, e; - i32 i; - - entry.name = name; - entry.id.id = id; - entry.hash = get_file_hash(name); - i = entry.hash % table->max; - while ((e = table->table[i]).name.str){ - if (e.hash == entry.hash && match(e.name, entry.name)){ - return 1; - } - i = (i + 1) % table->max; - } - table->table[i] = entry; - ++table->count; - - return 0; -} - -internal b32 -table_find_pos(File_Table *table, String name, i32 *index){ - File_Table_Entry e; - i32 i; - u32 hash; - - hash = get_file_hash(name); - i = hash % table->max; - while ((e = table->table[i]).name.size){ - if (e.name.str && e.hash == hash && match(e.name, name)){ - *index = i; - return 1; - } - i = (i + 1) % table->max; - } - - return 0; -} - -inline b32 -table_find(File_Table *table, String name, File_ID *id){ - i32 pos; - b32 r = table_find_pos(table, name, &pos); - if (r) *id = table->table[pos].id; - return r; -} - -inline b32 -table_remove(File_Table *table, String name){ - i32 pos; - b32 r = table_find_pos(table, name, &pos); - if (r){ - table->table[pos].name.str = 0; - --table->count; - } - return r; -} -#endif - struct Non_File_Table_Entry{ String name; File_ID id;