new feedback message buffer

master
Allen Webster 2016-03-20 17:51:58 -04:00
parent 4bdd20f36d
commit dabc85b393
3 changed files with 86 additions and 122 deletions

117
4ed.cpp
View File

@ -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?"));

View File

@ -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;

View File

@ -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;