2019-02-24 07:22:16 +00:00
|
|
|
/*
|
|
|
|
* Serial inserts helpers
|
|
|
|
*/
|
|
|
|
|
|
|
|
// TOP
|
|
|
|
|
|
|
|
static Buffer_Insertion
|
2019-02-26 23:17:53 +00:00
|
|
|
begin_buffer_insertion_at(Application_Links *app, Buffer_ID buffer_id, i32 at){
|
2019-02-24 07:22:16 +00:00
|
|
|
Buffer_Insertion result = {};
|
|
|
|
result.app = app;
|
|
|
|
result.buffer = buffer_id;
|
|
|
|
result.at = at;
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
2019-04-02 20:06:49 +00:00
|
|
|
static Buffer_Insertion
|
|
|
|
begin_buffer_insertion_at_buffered(Application_Links *app, Buffer_ID buffer_id, i32 at, Partition *part){
|
|
|
|
Buffer_Insertion result = begin_buffer_insertion_at(app, buffer_id, at);
|
|
|
|
result.buffering = true;
|
|
|
|
result.part = part;
|
|
|
|
result.temp = begin_temp_memory(part);
|
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
2019-02-24 07:22:16 +00:00
|
|
|
static Buffer_Insertion
|
|
|
|
begin_buffer_insertion(Application_Links *app){
|
2019-04-02 20:06:49 +00:00
|
|
|
View_ID view = 0;
|
|
|
|
get_active_view(app, AccessAll, &view);
|
|
|
|
Buffer_ID buffer = 0;
|
|
|
|
view_get_buffer(app, view, AccessAll, &buffer);
|
|
|
|
i32 cursor_pos = 0;
|
|
|
|
view_get_cursor_pos(app, view, &cursor_pos);
|
|
|
|
Buffer_Insertion result = begin_buffer_insertion_at(app, buffer, cursor_pos);
|
2019-02-24 07:22:16 +00:00
|
|
|
return(result);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
2019-04-02 20:06:49 +00:00
|
|
|
insert_string__no_buffering(Buffer_Insertion *insertion, String string){
|
2019-02-24 07:22:16 +00:00
|
|
|
buffer_replace_range(insertion->app, insertion->buffer, insertion->at, insertion->at, string);
|
|
|
|
insertion->at += string.size;
|
|
|
|
}
|
|
|
|
|
2019-04-02 20:06:49 +00:00
|
|
|
static void
|
|
|
|
insert__flush(Buffer_Insertion *insertion){
|
|
|
|
Partition *part = insertion->part;
|
|
|
|
i32 pos = insertion->temp.pos;
|
|
|
|
String string = make_string(part->base + pos, part->pos - pos);
|
|
|
|
insert_string__no_buffering(insertion, string);
|
|
|
|
end_temp_memory(insertion->temp);
|
|
|
|
}
|
|
|
|
|
|
|
|
static char*
|
|
|
|
insert__reserve(Buffer_Insertion *insertion, i32 size){
|
|
|
|
char *space = push_array(insertion->part, char, size);
|
|
|
|
if (space == 0){
|
|
|
|
insert__flush(insertion);
|
|
|
|
space = push_array(insertion->part, char, size);
|
|
|
|
}
|
|
|
|
return(space);
|
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
insert_string(Buffer_Insertion *insertion, String string){
|
|
|
|
if (!insertion->buffering){
|
|
|
|
insert_string__no_buffering(insertion, string);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
char *space = insert__reserve(insertion, string.size);
|
|
|
|
if (space != 0){
|
|
|
|
memcpy(space, string.str, string.size);
|
|
|
|
}
|
|
|
|
else{
|
|
|
|
insert_string__no_buffering(insertion, string);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2019-02-26 23:17:53 +00:00
|
|
|
static i32
|
2019-02-24 07:22:16 +00:00
|
|
|
insertf(Buffer_Insertion *insertion, char *format, ...){
|
2019-04-01 06:14:31 +00:00
|
|
|
Arena *arena = context_get_arena(insertion->app);
|
|
|
|
Temp_Memory_Arena temp = begin_temp_memory(arena);
|
2019-02-24 07:22:16 +00:00
|
|
|
va_list args;
|
|
|
|
va_start(args, format);
|
2019-04-01 06:14:31 +00:00
|
|
|
String string = string_push_fv(arena, format, args);
|
2019-02-24 07:22:16 +00:00
|
|
|
va_end(args);
|
2019-04-01 06:14:31 +00:00
|
|
|
insert_string(insertion, string);
|
|
|
|
end_temp_memory(temp);
|
|
|
|
return(string.size);
|
2019-02-24 07:22:16 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
static void
|
|
|
|
insertc(Buffer_Insertion *insertion, char C){
|
2019-04-02 20:06:49 +00:00
|
|
|
insert_string(insertion, make_string(&C, 1));
|
2019-02-24 07:22:16 +00:00
|
|
|
}
|
|
|
|
|
2019-02-26 23:08:42 +00:00
|
|
|
static b32
|
2019-02-26 23:17:53 +00:00
|
|
|
insert_line_from_buffer(Buffer_Insertion *insertion, Buffer_ID buffer_id, i32 line, i32 truncate_at){
|
2019-02-24 07:22:16 +00:00
|
|
|
Partition *part = &global_part;
|
|
|
|
Temp_Memory temp = begin_temp_memory(part);
|
|
|
|
|
|
|
|
Partial_Cursor begin = {};
|
|
|
|
Partial_Cursor end = {};
|
|
|
|
|
2019-02-26 23:08:42 +00:00
|
|
|
b32 success = false;
|
2019-04-05 02:03:36 +00:00
|
|
|
if (buffer_compute_cursor(insertion->app, buffer_id, seek_line_char(line, 1), &begin)){
|
|
|
|
if (buffer_compute_cursor(insertion->app, buffer_id, seek_line_char(line, -1), &end)){
|
2019-02-24 07:22:16 +00:00
|
|
|
if (begin.line == line){
|
2019-04-05 02:03:36 +00:00
|
|
|
i32 buffer_size = 0;
|
|
|
|
buffer_get_size(insertion->app, buffer_id, &buffer_size);
|
|
|
|
if (0 <= begin.pos && begin.pos <= end.pos && end.pos <= buffer_size){
|
2019-02-26 23:17:53 +00:00
|
|
|
i32 size = (end.pos - begin.pos);
|
2019-02-24 07:22:16 +00:00
|
|
|
if(truncate_at && (size > truncate_at))
|
|
|
|
{
|
|
|
|
size = truncate_at;
|
|
|
|
}
|
|
|
|
|
|
|
|
char *memory = push_array(part, char, size);
|
|
|
|
if (memory != 0){
|
|
|
|
String str = make_string(memory, 0, size);
|
|
|
|
success = true;
|
2019-04-05 02:03:36 +00:00
|
|
|
buffer_read_range(insertion->app, buffer_id, begin.pos, end.pos, str.str);
|
2019-02-24 07:22:16 +00:00
|
|
|
str.size = size;
|
|
|
|
insert_string(insertion, str);
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
end_temp_memory(temp);
|
|
|
|
return(success);
|
|
|
|
}
|
|
|
|
|
2019-02-26 23:08:42 +00:00
|
|
|
static b32
|
2019-02-26 23:17:53 +00:00
|
|
|
insert_line_from_buffer(Buffer_Insertion *insertion, Buffer_ID buffer_id, i32 line){
|
2019-02-24 07:22:16 +00:00
|
|
|
return(insert_line_from_buffer(insertion, buffer_id, line, 0));
|
|
|
|
}
|
|
|
|
|
|
|
|
// BOTTOM
|
|
|
|
|