new feedback message buffer
parent
4bdd20f36d
commit
dabc85b393
117
4ed.cpp
117
4ed.cpp
|
@ -131,6 +131,32 @@ app_get_map(Models *models, i32 mapid){
|
||||||
return map;
|
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
|
// Commands
|
||||||
|
|
||||||
globalvar Application_Links app_links;
|
globalvar Application_Links app_links;
|
||||||
|
@ -983,7 +1009,7 @@ COMMAND_DECL(reopen){
|
||||||
models->hooks[hook_open_file], &app_links);
|
models->hooks[hook_open_file], &app_links);
|
||||||
}
|
}
|
||||||
else{
|
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;
|
i32 script_len = 0;
|
||||||
u32 flags = CLI_OverlapWithConflict;
|
u32 flags = CLI_OverlapWithConflict;
|
||||||
b32 do_in_background = 0;
|
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 *end = param_stack_end(&command->part);
|
||||||
Command_Parameter *param = param_stack_first(&command->part, end);
|
Command_Parameter *param = param_stack_first(&command->part, end);
|
||||||
|
@ -1756,7 +1785,17 @@ COMMAND_DECL(command_line){
|
||||||
if (buffer_id){
|
if (buffer_id){
|
||||||
file = working_set_get_active_file(working_set, buffer_id);
|
file = working_set_get_active_file(working_set, buffer_id);
|
||||||
if (file && file->settings.read_only == 0){
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1764,28 +1803,37 @@ COMMAND_DECL(command_line){
|
||||||
file = working_set_contains(system, working_set, make_string(buffer_name, buffer_name_len));
|
file = working_set_contains(system, working_set, make_string(buffer_name, buffer_name_len));
|
||||||
if (file){
|
if (file){
|
||||||
if (file->settings.read_only == 0){
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
file = working_set_alloc_always(working_set, general);
|
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){
|
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;
|
return;
|
||||||
}
|
}
|
||||||
|
file_create_read_only(system, models, file, buffer_name);
|
||||||
|
working_set_add(system, working_set, file, general);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file){
|
if (file){
|
||||||
i32 proc_count = vars->cli_processes.count;
|
i32 proc_count = vars->cli_processes.count;
|
||||||
View_Iter iter;
|
View_Iter iter;
|
||||||
i32 i;
|
i32 i;
|
||||||
|
|
||||||
for (i = 0; i < proc_count; ++i){
|
for (i = 0; i < proc_count; ++i){
|
||||||
if (procs[i].out_file == file){
|
if (procs[i].out_file == file){
|
||||||
if (flags & CLI_OverlapWithConflict)
|
if (flags & CLI_OverlapWithConflict)
|
||||||
|
@ -1795,7 +1843,7 @@ COMMAND_DECL(command_line){
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file){
|
if (file){
|
||||||
file_clear(system, models, file, 1);
|
file_clear(system, models, file, 1);
|
||||||
file->settings.unimportant = 1;
|
file->settings.unimportant = 1;
|
||||||
|
@ -1808,11 +1856,12 @@ COMMAND_DECL(command_line){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!path){
|
if (!path){
|
||||||
path = models->hot_directory.string.str;
|
path = models->hot_directory.string.str;
|
||||||
terminate_with_null(&models->hot_directory.string);
|
terminate_with_null(&models->hot_directory.string);
|
||||||
|
@ -1853,7 +1902,8 @@ COMMAND_DECL(command_line){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else{
|
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;
|
return;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -3415,7 +3465,7 @@ App_Step_Sig(app_step){
|
||||||
dest->size = eol_convert_in(dest->str, clipboard.str, clipboard.size);
|
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
|
// NOTE(allen): check files are up to date
|
||||||
{
|
{
|
||||||
File_Node *node, *used_nodes;
|
File_Node *node, *used_nodes;
|
||||||
|
@ -3453,20 +3503,15 @@ App_Step_Sig(app_step){
|
||||||
i32 count = vars->cli_processes.count;
|
i32 count = vars->cli_processes.count;
|
||||||
for (i32 i = 0; i < count; ++i){
|
for (i32 i = 0; i < count; ++i){
|
||||||
CLI_Process *proc = vars->cli_processes.procs + 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){
|
if (file != 0){
|
||||||
i32 new_cursor = out_file->state.cursor_pos;
|
|
||||||
|
|
||||||
for (system->cli_begin_update(&proc->cli);
|
for (system->cli_begin_update(&proc->cli);
|
||||||
system->cli_update_step(&proc->cli, dest, max, &amount);){
|
system->cli_update_step(&proc->cli, dest, max, &amount);){
|
||||||
amount = eol_in_place_convert_in(dest, amount);
|
amount = eol_in_place_convert_in(dest, amount);
|
||||||
|
output_file_append(system, models, file, make_string(dest, amount), 0);
|
||||||
i32 end = buffer_size(&out_file->state.buffer);
|
|
||||||
file_replace_range(system, models, out_file,
|
|
||||||
end, end, dest, amount, end + amount, 1);
|
|
||||||
app_result.redraw = 1;
|
app_result.redraw = 1;
|
||||||
new_cursor = end + amount;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (system->cli_end_update(&proc->cli)){
|
if (system->cli_end_update(&proc->cli)){
|
||||||
|
@ -3478,16 +3523,13 @@ App_Step_Sig(app_step){
|
||||||
append(&str, "exited with code ");
|
append(&str, "exited with code ");
|
||||||
append_int_to_str(proc->cli.exit, &str);
|
append_int_to_str(proc->cli.exit, &str);
|
||||||
|
|
||||||
i32 end = buffer_size(&out_file->state.buffer);
|
output_file_append(system, models, file, str, 0);
|
||||||
file_replace_range(system, models, out_file,
|
|
||||||
end, end, str.str, str.size, end + str.size, 1);
|
|
||||||
app_result.redraw = 1;
|
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);
|
file_view_iter_good(iter);
|
||||||
iter = file_view_iter_next(iter)){
|
iter = file_view_iter_next(iter)){
|
||||||
view_cursor_move(iter.view, new_cursor);
|
view_cursor_move(iter.view, new_cursor);
|
||||||
|
@ -3664,6 +3706,15 @@ App_Step_Sig(app_step){
|
||||||
delayed_open_background(&models->delay1, file_name);
|
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);
|
ProfileEnd(prepare_commands);
|
||||||
|
|
||||||
|
@ -4384,11 +4435,11 @@ App_Step_Sig(app_step){
|
||||||
file = working_set_contains(system, working_set, string);
|
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);
|
working_set_remove(system, working_set, file->name.source_path);
|
||||||
kill_file(system, exchange, models, file,
|
kill_file(system, exchange, models, file,
|
||||||
models->hooks[hook_open_file], &app_links);
|
models->hooks[hook_open_file], &app_links);
|
||||||
}
|
}
|
||||||
}break;
|
}break;
|
||||||
|
|
||||||
|
@ -4410,7 +4461,7 @@ App_Step_Sig(app_step){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (file){
|
if (file && !file->settings.never_kill){
|
||||||
if (buffer_needs_save(file)){
|
if (buffer_needs_save(file)){
|
||||||
view_show_interactive(system, view, &models->map_ui,
|
view_show_interactive(system, view, &models->map_ui,
|
||||||
IAct_Sure_To_Kill, IInt_Sure_To_Kill, make_lit_string("Are you sure?"));
|
IAct_Sure_To_Kill, IInt_Sure_To_Kill, make_lit_string("Are you sure?"));
|
||||||
|
|
|
@ -51,6 +51,7 @@ struct Models{
|
||||||
|
|
||||||
Editing_Layout layout;
|
Editing_Layout layout;
|
||||||
Working_Set working_set;
|
Working_Set working_set;
|
||||||
|
Editing_File *message_buffer;
|
||||||
|
|
||||||
char hot_dir_base_[256];
|
char hot_dir_base_[256];
|
||||||
Hot_Directory hot_directory;
|
Hot_Directory hot_directory;
|
||||||
|
|
90
4ed_file.cpp
90
4ed_file.cpp
|
@ -105,6 +105,7 @@ struct Editing_File_Settings{
|
||||||
b8 is_initialized;
|
b8 is_initialized;
|
||||||
b8 unimportant;
|
b8 unimportant;
|
||||||
b8 read_only;
|
b8 read_only;
|
||||||
|
b8 never_kill;
|
||||||
};
|
};
|
||||||
|
|
||||||
// NOTE(allen): This part of the Editing_File is cleared whenever
|
// NOTE(allen): This part of the Editing_File is cleared whenever
|
||||||
|
@ -175,95 +176,6 @@ struct Editing_File{
|
||||||
File_ID id;
|
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{
|
struct Non_File_Table_Entry{
|
||||||
String name;
|
String name;
|
||||||
File_ID id;
|
File_ID id;
|
||||||
|
|
Loading…
Reference in New Issue