setting up better organization for file system
This commit is contained in:
parent
5f00639970
commit
1ef304558e
162
4coder_string.h
162
4coder_string.h
|
@ -2019,102 +2019,110 @@ typedef struct Absolutes{
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_bool implicit_last){
|
get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_bool implicit_last){
|
||||||
int32_t count = 0;
|
if (name.size != 0){
|
||||||
int32_t max = ArrayCount(absolutes->a) - 1;
|
int32_t count = 0;
|
||||||
if (implicit_last) --max;
|
int32_t max = ArrayCount(absolutes->a) - 1;
|
||||||
|
if (implicit_last) --max;
|
||||||
String str;
|
|
||||||
str.str = name.str;
|
String str;
|
||||||
str.size = 0;
|
str.str = name.str;
|
||||||
str.memory_size = 0;
|
|
||||||
fstr_bool prev_was_wild = 0;
|
|
||||||
|
|
||||||
if (implicit_first){
|
|
||||||
absolutes->a[count++] = str;
|
|
||||||
prev_was_wild = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t i;
|
|
||||||
for (i = 0; i < name.size; ++i){
|
|
||||||
if (name.str[i] == '*' && count < max){
|
|
||||||
if (!prev_was_wild){
|
|
||||||
str.memory_size = str.size;
|
|
||||||
absolutes->a[count++] = str;
|
|
||||||
str.size = 0;
|
|
||||||
}
|
|
||||||
str.str = name.str + i + 1;
|
|
||||||
prev_was_wild = 1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
++str.size;
|
|
||||||
prev_was_wild = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
str.memory_size = str.size;
|
|
||||||
absolutes->a[count++] = str;
|
|
||||||
|
|
||||||
if (implicit_last){
|
|
||||||
str.size = 0;
|
str.size = 0;
|
||||||
str.memory_size = 0;
|
str.memory_size = 0;
|
||||||
|
fstr_bool prev_was_wild = 0;
|
||||||
|
|
||||||
|
if (implicit_first){
|
||||||
|
absolutes->a[count++] = str;
|
||||||
|
prev_was_wild = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t i;
|
||||||
|
for (i = 0; i < name.size; ++i){
|
||||||
|
if (name.str[i] == '*' && count < max){
|
||||||
|
if (!prev_was_wild){
|
||||||
|
str.memory_size = str.size;
|
||||||
|
absolutes->a[count++] = str;
|
||||||
|
str.size = 0;
|
||||||
|
}
|
||||||
|
str.str = name.str + i + 1;
|
||||||
|
prev_was_wild = 1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
++str.size;
|
||||||
|
prev_was_wild = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
str.memory_size = str.size;
|
||||||
absolutes->a[count++] = str;
|
absolutes->a[count++] = str;
|
||||||
|
|
||||||
|
if (implicit_last){
|
||||||
|
str.size = 0;
|
||||||
|
str.memory_size = 0;
|
||||||
|
absolutes->a[count++] = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
absolutes->count = count;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
absolutes->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
absolutes->count = count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static fstr_bool
|
static fstr_bool
|
||||||
wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){
|
wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){
|
||||||
fstr_bool r = 1;
|
fstr_bool r = 1;
|
||||||
String *a = absolutes->a;
|
|
||||||
|
|
||||||
fstr_bool (*match_func)(char*, String);
|
if (absolutes->count > 0){
|
||||||
fstr_bool (*match_part_func)(char*, String);
|
String *a = absolutes->a;
|
||||||
|
|
||||||
if (case_sensitive){
|
fstr_bool (*match_func)(char*, String);
|
||||||
match_func = match_cs;
|
fstr_bool (*match_part_func)(char*, String);
|
||||||
match_part_func = match_part_cs;
|
|
||||||
}
|
if (case_sensitive){
|
||||||
else{
|
match_func = match_cs;
|
||||||
match_func = match_insensitive_cs;
|
match_part_func = match_part_cs;
|
||||||
match_part_func = match_part_insensitive_cs;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (absolutes->count == 1){
|
|
||||||
r = match_func(x, *a);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (!match_part_func(x, *a)){
|
|
||||||
r = 0;
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
String *max = a + absolutes->count - 1;
|
match_func = match_insensitive_cs;
|
||||||
x += a->size;
|
match_part_func = match_part_insensitive_cs;
|
||||||
++a;
|
}
|
||||||
while (a < max){
|
|
||||||
if (*x == 0){
|
if (absolutes->count == 1){
|
||||||
r = 0;
|
r = match_func(x, *a);
|
||||||
break;
|
}
|
||||||
}
|
else{
|
||||||
if (match_part_func(x, *a)){
|
if (!match_part_func(x, *a)){
|
||||||
x += a->size;
|
|
||||||
++a;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
++x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (r && a->size > 0){
|
|
||||||
r = 0;
|
r = 0;
|
||||||
while (*x != 0){
|
}
|
||||||
if (match_part_func(x, *a) && *(x + a->size) == 0){
|
else{
|
||||||
r = 1;
|
String *max = a + absolutes->count - 1;
|
||||||
|
x += a->size;
|
||||||
|
++a;
|
||||||
|
while (a < max){
|
||||||
|
if (*x == 0){
|
||||||
|
r = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (match_part_func(x, *a)){
|
||||||
|
x += a->size;
|
||||||
|
++a;
|
||||||
|
}
|
||||||
else{
|
else{
|
||||||
++x;
|
++x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (r && a->size > 0){
|
||||||
|
r = 0;
|
||||||
|
while (*x != 0){
|
||||||
|
if (match_part_func(x, *a) && *(x + a->size) == 0){
|
||||||
|
r = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
4
4ed.cpp
4
4ed.cpp
|
@ -1732,7 +1732,7 @@ App_Init_Sig(app_init){
|
||||||
models->layout.active_panel = p.id;
|
models->layout.active_panel = p.id;
|
||||||
|
|
||||||
String hdbase = make_fixed_width_string(models->hot_dir_base_);
|
String hdbase = make_fixed_width_string(models->hot_dir_base_);
|
||||||
hot_directory_init(&models->hot_directory, hdbase, current_directory, system->slash);
|
hot_directory_init(&models->hot_directory, hdbase, current_directory);
|
||||||
|
|
||||||
// NOTE(allen): child proc list setup
|
// NOTE(allen): child proc list setup
|
||||||
i32 max_children = 16;
|
i32 max_children = 16;
|
||||||
|
@ -2870,7 +2870,7 @@ App_Step_Sig(app_step){
|
||||||
// end-of-app_step
|
// end-of-app_step
|
||||||
}
|
}
|
||||||
|
|
||||||
external App_Get_Functions_Sig(app_get_functions){
|
extern "C" App_Get_Functions_Sig(app_get_functions){
|
||||||
App_Functions result = {};
|
App_Functions result = {};
|
||||||
|
|
||||||
result.read_command_line = app_read_command_line;
|
result.read_command_line = app_read_command_line;
|
||||||
|
|
|
@ -45,7 +45,10 @@
|
||||||
#include "buffer/4coder_gap_buffer.cpp"
|
#include "buffer/4coder_gap_buffer.cpp"
|
||||||
#define Buffer_Type Gap_Buffer
|
#define Buffer_Type Gap_Buffer
|
||||||
#include "buffer/4coder_buffer_abstract.cpp"
|
#include "buffer/4coder_buffer_abstract.cpp"
|
||||||
#include "4ed_file.cpp"
|
|
||||||
|
#include "file/4coder_file.cpp"
|
||||||
|
#include "file/4coder_working_set.cpp"
|
||||||
|
#include "file/4coder_hot_directory.cpp"
|
||||||
|
|
||||||
#include "4ed_gui.cpp"
|
#include "4ed_gui.cpp"
|
||||||
#include "4ed_layout.cpp"
|
#include "4ed_layout.cpp"
|
||||||
|
|
|
@ -11,8 +11,10 @@
|
||||||
#define FRED_DEFINES_H
|
#define FRED_DEFINES_H
|
||||||
|
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
|
#if !defined (FRED_TYPES)
|
||||||
|
#include <stdint.h>
|
||||||
|
#define FRED_TYPES
|
||||||
typedef uint8_t u8;
|
typedef uint8_t u8;
|
||||||
typedef uint16_t u16;
|
typedef uint16_t u16;
|
||||||
typedef uint32_t u32;
|
typedef uint32_t u32;
|
||||||
|
@ -34,12 +36,12 @@ typedef double real64;
|
||||||
typedef float f32;
|
typedef float f32;
|
||||||
typedef double f64;
|
typedef double f64;
|
||||||
|
|
||||||
#define external extern "C"
|
|
||||||
#define internal static
|
#define internal static
|
||||||
#define globalvar static
|
#define globalvar static
|
||||||
#define persist static
|
#define persist static
|
||||||
|
|
||||||
#define globalconst static const
|
#define globalconst static const
|
||||||
|
#endif
|
||||||
|
|
||||||
#define COMP_ID_(a,b,c,d) (d << 24) | (c << 16) | (b << 8) | a
|
#define COMP_ID_(a,b,c,d) (d << 24) | (c << 16) | (b << 8) | a
|
||||||
#define COMPOSE_ID(a,b,c,d) (COMP_ID_((a),(b),(c),(d)))
|
#define COMPOSE_ID(a,b,c,d) (COMP_ID_((a),(b),(c),(d)))
|
||||||
|
@ -97,13 +99,13 @@ TMin(i64, -9223372036854775807-1);
|
||||||
|
|
||||||
internal i32
|
internal i32
|
||||||
LargeRoundUp(i32 x, i32 granularity){
|
LargeRoundUp(i32 x, i32 granularity){
|
||||||
i32 original_x = x;
|
i32 original_x = x;
|
||||||
x /= granularity;
|
x /= granularity;
|
||||||
x *= granularity;
|
x *= granularity;
|
||||||
if (x < original_x){
|
if (x < original_x){
|
||||||
x += granularity;
|
x += granularity;
|
||||||
}
|
}
|
||||||
return x;
|
return x;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define Bit_0 (1 << 0)
|
#define Bit_0 (1 << 0)
|
||||||
|
|
|
@ -596,11 +596,9 @@ view_move_cursor_to_view(View *view, GUI_Scroll_Vars scroll,
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
view_set_cursor(View *view, Full_Cursor cursor,
|
view_set_cursor(View *view, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines){
|
||||||
b32 set_preferred_x, b32 unwrapped_lines){
|
|
||||||
if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){
|
if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){
|
||||||
edit_pos_set_cursor_(view->edit_pos, cursor, set_preferred_x, unwrapped_lines);
|
edit_pos_set_cursor(view->edit_pos, cursor, set_preferred_x, unwrapped_lines);
|
||||||
|
|
||||||
GUI_Scroll_Vars scroll = view->edit_pos->scroll;
|
GUI_Scroll_Vars scroll = view->edit_pos->scroll;
|
||||||
if (view_move_view_to_cursor(view, &scroll, 0)){
|
if (view_move_view_to_cursor(view, &scroll, 0)){
|
||||||
view->edit_pos->scroll = scroll;
|
view->edit_pos->scroll = scroll;
|
||||||
|
@ -609,11 +607,9 @@ view_set_cursor(View *view, Full_Cursor cursor,
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
view_set_scroll(View *view,
|
view_set_scroll(View *view, GUI_Scroll_Vars scroll){
|
||||||
GUI_Scroll_Vars scroll){
|
|
||||||
if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){
|
if (edit_pos_move_to_front(view->file_data.file, view->edit_pos)){
|
||||||
edit_pos_set_scroll_(view->edit_pos, scroll);
|
edit_pos_set_scroll(view->edit_pos, scroll);
|
||||||
|
|
||||||
Full_Cursor cursor = view->edit_pos->cursor;
|
Full_Cursor cursor = view->edit_pos->cursor;
|
||||||
if (view_move_cursor_to_view(view, view->edit_pos->scroll,
|
if (view_move_cursor_to_view(view, view->edit_pos->scroll,
|
||||||
&cursor, view->edit_pos->preferred_x)){
|
&cursor, view->edit_pos->preferred_x)){
|
||||||
|
@ -623,15 +619,11 @@ view_set_scroll(View *view,
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
view_set_cursor_and_scroll(View *view,
|
view_set_cursor_and_scroll(View *view, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines, GUI_Scroll_Vars scroll){
|
||||||
Full_Cursor cursor,
|
|
||||||
b32 set_preferred_x,
|
|
||||||
b32 unwrapped_lines,
|
|
||||||
GUI_Scroll_Vars scroll){
|
|
||||||
File_Edit_Positions *edit_pos = view->edit_pos;
|
File_Edit_Positions *edit_pos = view->edit_pos;
|
||||||
if (edit_pos_move_to_front(view->file_data.file, edit_pos)){
|
if (edit_pos_move_to_front(view->file_data.file, edit_pos)){
|
||||||
edit_pos_set_cursor_(edit_pos, cursor, set_preferred_x, unwrapped_lines);
|
edit_pos_set_cursor(edit_pos, cursor, set_preferred_x, unwrapped_lines);
|
||||||
edit_pos_set_scroll_(edit_pos, scroll);
|
edit_pos_set_scroll(edit_pos, scroll);
|
||||||
edit_pos->last_set_type = EditPos_None;
|
edit_pos->last_set_type = EditPos_None;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1251,12 +1243,15 @@ stickieness_guess(Cpp_Token_Type type, Cpp_Token_Type other_type, u16 flags, u16
|
||||||
}
|
}
|
||||||
else if (type == CPP_TOKEN_PARENTHESE_OPEN){
|
else if (type == CPP_TOKEN_PARENTHESE_OPEN){
|
||||||
if (on_left){
|
if (on_left){
|
||||||
guess = 0;
|
guess = 100;
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
if (other_is_words){
|
if (other_is_words){
|
||||||
guess = 100;
|
guess = 100;
|
||||||
}
|
}
|
||||||
|
else{
|
||||||
|
guess = 0;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else if (type == CPP_TOKEN_SEMICOLON){
|
else if (type == CPP_TOKEN_SEMICOLON){
|
||||||
|
@ -3700,7 +3695,7 @@ view_show_interactive(System_Functions *system, View *view,
|
||||||
view->map = &models->map_ui;
|
view->map = &models->map_ui;
|
||||||
|
|
||||||
hot_directory_clean_end(&models->hot_directory);
|
hot_directory_clean_end(&models->hot_directory);
|
||||||
hot_directory_reload(system, &models->hot_directory, &models->working_set);
|
hot_directory_reload(system, &models->hot_directory);
|
||||||
view->changed_context_in_step = 1;
|
view->changed_context_in_step = 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4271,11 +4266,10 @@ get_exhaustive_info(System_Functions *system, Working_Set *working_set, Exhausti
|
||||||
file = working_set_canon_contains(working_set, canon_name.name);
|
file = working_set_canon_contains(working_set, canon_name.name);
|
||||||
}
|
}
|
||||||
|
|
||||||
String filename = make_string_cap(result.info->filename,
|
String filename = make_string_cap(result.info->filename, result.info->filename_len, result.info->filename_len+1);
|
||||||
result.info->filename_len, result.info->filename_len+1);
|
|
||||||
|
|
||||||
result.is_folder = (result.info->folder != 0);
|
result.is_folder = (result.info->folder != 0);
|
||||||
result.name_match = (filename_match(loop->front_name, &loop->absolutes, filename) != 0);
|
result.name_match = (wildcard_match_s(&loop->absolutes, filename, 0) != 0);
|
||||||
result.is_loaded = (file != 0 && file_is_ready(file));
|
result.is_loaded = (file != 0 && file_is_ready(file));
|
||||||
|
|
||||||
result.message = null_string;
|
result.message = null_string;
|
||||||
|
@ -4379,7 +4373,7 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set, K
|
||||||
if (char_is_slash(end_character)){
|
if (char_is_slash(end_character)){
|
||||||
mode.string->size = reverse_seek_slash(*mode.string) + 1;
|
mode.string->size = reverse_seek_slash(*mode.string) + 1;
|
||||||
mode.string->str[mode.string->size] = 0;
|
mode.string->str[mode.string->size] = 0;
|
||||||
hot_directory_set(system, mode.hot_directory, *mode.string, working_set);
|
hot_directory_set(system, mode.hot_directory, *mode.string);
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
mode.string->str[mode.string->size] = 0;
|
mode.string->str[mode.string->size] = 0;
|
||||||
|
@ -4411,7 +4405,7 @@ app_single_line_input_core(System_Functions *system, Working_Set *working_set, K
|
||||||
mode.string->size++;
|
mode.string->size++;
|
||||||
mode.string->str[mode.string->size] = 0;
|
mode.string->str[mode.string->size] = 0;
|
||||||
if (mode.type == SINGLE_LINE_FILE && char_is_slash(new_character)){
|
if (mode.type == SINGLE_LINE_FILE && char_is_slash(new_character)){
|
||||||
hot_directory_set(system, mode.hot_directory, *mode.string, working_set);
|
hot_directory_set(system, mode.hot_directory, *mode.string);
|
||||||
}
|
}
|
||||||
result.made_a_change = 1;
|
result.made_a_change = 1;
|
||||||
}
|
}
|
||||||
|
@ -5021,7 +5015,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
|
||||||
}
|
}
|
||||||
|
|
||||||
if (do_new_directory){
|
if (do_new_directory){
|
||||||
hot_directory_reload(system, hdir, &models->working_set);
|
hot_directory_reload(system, hdir);
|
||||||
}
|
}
|
||||||
|
|
||||||
gui_end_scrollable(target);
|
gui_end_scrollable(target);
|
||||||
|
@ -5088,7 +5082,7 @@ step_file_view(System_Functions *system, View *view, View *active_view, Input_Su
|
||||||
Editing_File *file = (Editing_File*)node;
|
Editing_File *file = (Editing_File*)node;
|
||||||
Assert(!file->is_dummy);
|
Assert(!file->is_dummy);
|
||||||
|
|
||||||
if (filename_match(view->dest, &absolutes, file->name.live_name)){
|
if (wildcard_match_s(&absolutes, file->name.live_name, 0) != 0){
|
||||||
View_Iter iter = file_view_iter_init(layout, file, 0);
|
View_Iter iter = file_view_iter_init(layout, file, 0);
|
||||||
if (file_view_iter_good(iter)){
|
if (file_view_iter_good(iter)){
|
||||||
reserved_files[reserved_top++] = file;
|
reserved_files[reserved_top++] = file;
|
||||||
|
@ -6530,7 +6524,7 @@ do_render_file_view(System_Functions *system, View *view, GUI_Scroll_Vars *scrol
|
||||||
String m = gui_read_string(&ptr);
|
String m = gui_read_string(&ptr);
|
||||||
|
|
||||||
if (folder){
|
if (folder){
|
||||||
append_s_char(&f, system->slash);
|
append_s_char(&f, '/');
|
||||||
}
|
}
|
||||||
|
|
||||||
draw_fat_option_block(gui_target, target, view, font_id, gui_session.rect, b->id, f, m);
|
draw_fat_option_block(gui_target, target, view, font_id, gui_session.rect, b->id, f, m);
|
||||||
|
|
11
4ed_system.h
11
4ed_system.h
|
@ -146,10 +146,10 @@ struct Thread_Exchange;
|
||||||
struct System_Functions;
|
struct System_Functions;
|
||||||
|
|
||||||
#define Job_Callback_Sig(name) void name( \
|
#define Job_Callback_Sig(name) void name( \
|
||||||
System_Functions *system, \
|
System_Functions *system, \
|
||||||
Thread_Context *thread, \
|
Thread_Context *thread, \
|
||||||
Thread_Memory *memory, \
|
Thread_Memory *memory, \
|
||||||
void *data[2])
|
void *data[2])
|
||||||
typedef Job_Callback_Sig(Job_Callback);
|
typedef Job_Callback_Sig(Job_Callback);
|
||||||
|
|
||||||
struct Job_Data{
|
struct Job_Data{
|
||||||
|
@ -258,9 +258,6 @@ struct System_Functions{
|
||||||
|
|
||||||
// debug: 1
|
// debug: 1
|
||||||
INTERNAL_System_Get_Thread_States *internal_get_thread_states;
|
INTERNAL_System_Get_Thread_States *internal_get_thread_states;
|
||||||
|
|
||||||
// non-function details
|
|
||||||
char slash;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
|
@ -0,0 +1,434 @@
|
||||||
|
/*
|
||||||
|
* Mr. 4th Dimention - Allen Webster
|
||||||
|
*
|
||||||
|
* 03.01.2017
|
||||||
|
*
|
||||||
|
* File layer for 4coder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TOP
|
||||||
|
|
||||||
|
//
|
||||||
|
// Edit Position Basics
|
||||||
|
//
|
||||||
|
|
||||||
|
enum Edit_Pos_Set_Type{
|
||||||
|
EditPos_None,
|
||||||
|
EditPos_CursorSet,
|
||||||
|
EditPos_ScrollSet
|
||||||
|
};
|
||||||
|
struct File_Edit_Positions{
|
||||||
|
GUI_Scroll_Vars scroll;
|
||||||
|
Full_Cursor cursor;
|
||||||
|
i32 mark;
|
||||||
|
f32 preferred_x;
|
||||||
|
i32 scroll_i;
|
||||||
|
i32 last_set_type;
|
||||||
|
b32 in_view;
|
||||||
|
};
|
||||||
|
static File_Edit_Positions null_edit_pos = {0};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
edit_pos_set_cursor(File_Edit_Positions *edit_pos, Full_Cursor cursor, b32 set_preferred_x, b32 unwrapped_lines){
|
||||||
|
edit_pos->cursor = cursor;
|
||||||
|
if (set_preferred_x){
|
||||||
|
edit_pos->preferred_x = cursor.wrapped_x;
|
||||||
|
if (unwrapped_lines){
|
||||||
|
edit_pos->preferred_x = cursor.unwrapped_x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
edit_pos->last_set_type = EditPos_CursorSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
edit_pos_set_scroll(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll){
|
||||||
|
edit_pos->scroll = scroll;
|
||||||
|
edit_pos->last_set_type = EditPos_ScrollSet;
|
||||||
|
}
|
||||||
|
|
||||||
|
//
|
||||||
|
// Undo Basics
|
||||||
|
//
|
||||||
|
|
||||||
|
enum Edit_Type{
|
||||||
|
ED_NORMAL,
|
||||||
|
ED_REVERSE_NORMAL,
|
||||||
|
ED_UNDO,
|
||||||
|
ED_REDO,
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Edit_Step{
|
||||||
|
Edit_Type type;
|
||||||
|
union{
|
||||||
|
struct{
|
||||||
|
b32 can_merge;
|
||||||
|
Buffer_Edit edit;
|
||||||
|
i32 next_block;
|
||||||
|
i32 prev_block;
|
||||||
|
};
|
||||||
|
struct{
|
||||||
|
i32 first_child;
|
||||||
|
i32 inverse_first_child;
|
||||||
|
i32 inverse_child_count;
|
||||||
|
i32 special_type;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
i32 child_count;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Edit_Stack{
|
||||||
|
u8 *strings;
|
||||||
|
i32 size, max;
|
||||||
|
|
||||||
|
Edit_Step *edits;
|
||||||
|
i32 edit_count, edit_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Small_Edit_Stack{
|
||||||
|
u8 *strings;
|
||||||
|
i32 size, max;
|
||||||
|
|
||||||
|
Buffer_Edit *edits;
|
||||||
|
i32 edit_count, edit_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Undo_Data{
|
||||||
|
Edit_Stack undo;
|
||||||
|
Edit_Stack redo;
|
||||||
|
Edit_Stack history;
|
||||||
|
Small_Edit_Stack children;
|
||||||
|
|
||||||
|
i32 history_block_count, history_head_block;
|
||||||
|
i32 edit_history_cursor;
|
||||||
|
b32 current_block_normal;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Highlighting Information
|
||||||
|
//
|
||||||
|
|
||||||
|
struct Text_Effect{
|
||||||
|
i32 start, end;
|
||||||
|
u32 color;
|
||||||
|
f32 seconds_down, seconds_max;
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Editing_File
|
||||||
|
//
|
||||||
|
|
||||||
|
struct Editing_File_Settings{
|
||||||
|
i32 base_map_id;
|
||||||
|
i32 display_width;
|
||||||
|
i32 minimum_base_display_width;
|
||||||
|
i32 wrap_indicator;
|
||||||
|
b32 dos_write_mode;
|
||||||
|
b32 virtual_white;
|
||||||
|
i16 font_id;
|
||||||
|
b8 unwrapped_lines;
|
||||||
|
b8 tokens_exist;
|
||||||
|
b8 is_initialized;
|
||||||
|
b8 unimportant;
|
||||||
|
b8 read_only;
|
||||||
|
b8 never_kill;
|
||||||
|
};
|
||||||
|
static Editing_File_Settings null_editing_file_settings = {0};
|
||||||
|
|
||||||
|
struct Editing_File_State{
|
||||||
|
Buffer_Type buffer;
|
||||||
|
|
||||||
|
i32 *wrap_line_index;
|
||||||
|
i32 wrap_max;
|
||||||
|
|
||||||
|
i32 *character_starts;
|
||||||
|
i32 character_start_max;
|
||||||
|
|
||||||
|
f32 *line_indents;
|
||||||
|
i32 line_indent_max;
|
||||||
|
|
||||||
|
i32 wrap_line_count;
|
||||||
|
|
||||||
|
i32 *wrap_positions;
|
||||||
|
i32 wrap_position_count;
|
||||||
|
i32 wrap_position_max;
|
||||||
|
|
||||||
|
Undo_Data undo;
|
||||||
|
|
||||||
|
Cpp_Token_Array token_array;
|
||||||
|
Cpp_Token_Array swap_array;
|
||||||
|
u32 lex_job;
|
||||||
|
b32 tokens_complete;
|
||||||
|
b32 still_lexing;
|
||||||
|
|
||||||
|
Text_Effect paste_effect;
|
||||||
|
|
||||||
|
Dirty_State dirty;
|
||||||
|
u32 ignore_behind_os;
|
||||||
|
|
||||||
|
File_Edit_Positions edit_pos_space[16];
|
||||||
|
File_Edit_Positions *edit_poss[16];
|
||||||
|
i32 edit_poss_count;
|
||||||
|
};
|
||||||
|
static Editing_File_State null_editing_file_state = {0};
|
||||||
|
|
||||||
|
struct Editing_File_Name{
|
||||||
|
char live_name_[256];
|
||||||
|
char source_path_[256];
|
||||||
|
char extension_[16];
|
||||||
|
String live_name;
|
||||||
|
String source_path;
|
||||||
|
String extension;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct Editing_File_Canon_Name{
|
||||||
|
char name_[256];
|
||||||
|
String name;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct File_Node{
|
||||||
|
File_Node *next, *prev;
|
||||||
|
};
|
||||||
|
|
||||||
|
union Buffer_Slot_ID{
|
||||||
|
i32 id;
|
||||||
|
i16 part[2];
|
||||||
|
};
|
||||||
|
|
||||||
|
inline Buffer_Slot_ID
|
||||||
|
to_file_id(i32 id){
|
||||||
|
Buffer_Slot_ID result;
|
||||||
|
result.id = id;
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
struct Editing_File{
|
||||||
|
// NOTE(allen): node must be the first member of Editing_File!
|
||||||
|
File_Node node;
|
||||||
|
Editing_File_Settings settings;
|
||||||
|
struct{
|
||||||
|
b32 is_loading;
|
||||||
|
b32 is_dummy;
|
||||||
|
Editing_File_State state;
|
||||||
|
};
|
||||||
|
Editing_File_Name name;
|
||||||
|
Editing_File_Canon_Name canon;
|
||||||
|
Buffer_Slot_ID id;
|
||||||
|
u64 unique_buffer_id;
|
||||||
|
};
|
||||||
|
static Editing_File null_editing_file = {0};
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Manipulating a file's Edit_Pos array
|
||||||
|
//
|
||||||
|
|
||||||
|
internal i32
|
||||||
|
edit_pos_get_index(Editing_File *file, File_Edit_Positions *edit_pos){
|
||||||
|
i32 edit_pos_index = -1;
|
||||||
|
|
||||||
|
i32 count = file->state.edit_poss_count;
|
||||||
|
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
||||||
|
for (i32 i = 0; i < count; ++i){
|
||||||
|
if (edit_poss[i] == edit_pos){
|
||||||
|
edit_pos_index = i;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return(edit_pos_index);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
edit_pos_move_to_front(Editing_File *file, File_Edit_Positions *edit_pos){
|
||||||
|
b32 result = false;
|
||||||
|
|
||||||
|
if (file && edit_pos){
|
||||||
|
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
|
||||||
|
Assert(edit_pos_index != -1);
|
||||||
|
|
||||||
|
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
||||||
|
|
||||||
|
memmove(edit_poss + 1, edit_poss, edit_pos_index*sizeof(*edit_poss));
|
||||||
|
|
||||||
|
edit_poss[0] = edit_pos;
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal b32
|
||||||
|
edit_pos_unset(Editing_File *file, File_Edit_Positions *edit_pos){
|
||||||
|
b32 result = false;
|
||||||
|
|
||||||
|
if (file && edit_pos){
|
||||||
|
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
|
||||||
|
Assert(edit_pos_index != -1);
|
||||||
|
|
||||||
|
i32 count = file->state.edit_poss_count;
|
||||||
|
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
||||||
|
|
||||||
|
memmove(edit_poss + edit_pos_index,
|
||||||
|
edit_poss + edit_pos_index + 1,
|
||||||
|
(count - edit_pos_index - 1)*sizeof(*edit_poss));
|
||||||
|
|
||||||
|
edit_pos->in_view = false;
|
||||||
|
|
||||||
|
if (file->state.edit_poss_count > 1){
|
||||||
|
file->state.edit_poss_count -= 1;
|
||||||
|
}
|
||||||
|
result = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal File_Edit_Positions*
|
||||||
|
edit_pos_get_new(Editing_File *file, i32 index){
|
||||||
|
File_Edit_Positions *result = 0;
|
||||||
|
|
||||||
|
if (file && 0 <= index && index < 16){
|
||||||
|
result = file->state.edit_pos_space + index;
|
||||||
|
i32 edit_pos_index = edit_pos_get_index(file, result);
|
||||||
|
|
||||||
|
if (edit_pos_index == -1){
|
||||||
|
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
||||||
|
i32 count = file->state.edit_poss_count;
|
||||||
|
|
||||||
|
if (count > 0){
|
||||||
|
if (edit_poss[0]->in_view){
|
||||||
|
memcpy(result, edit_poss[0], sizeof(*result));
|
||||||
|
memmove(edit_poss+1, edit_poss, sizeof(*edit_poss)*count);
|
||||||
|
file->state.edit_poss_count = count + 1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
Assert(count == 1);
|
||||||
|
memcpy(result, edit_poss[0], sizeof(*result));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
memset(result, 0, sizeof(*result));
|
||||||
|
file->state.edit_poss_count = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
edit_poss[0] = result;
|
||||||
|
}
|
||||||
|
|
||||||
|
result->in_view = true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Cursor Seeking
|
||||||
|
//
|
||||||
|
|
||||||
|
inline Partial_Cursor
|
||||||
|
file_compute_cursor_from_pos(Editing_File *file, i32 pos){
|
||||||
|
Partial_Cursor result = buffer_partial_from_pos(&file->state.buffer, pos);
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Partial_Cursor
|
||||||
|
file_compute_cursor_from_line_character(Editing_File *file, i32 line, i32 character){
|
||||||
|
Partial_Cursor result = buffer_partial_from_line_character(&file->state.buffer, line, character);
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline b32
|
||||||
|
file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek, Partial_Cursor *cursor){
|
||||||
|
b32 result = 1;
|
||||||
|
switch (seek.type){
|
||||||
|
case buffer_seek_pos:
|
||||||
|
{
|
||||||
|
*cursor = file_compute_cursor_from_pos(file, seek.pos);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
case buffer_seek_line_char:
|
||||||
|
{
|
||||||
|
*cursor = file_compute_cursor_from_line_character(file, seek.line, seek.character);
|
||||||
|
}break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
{
|
||||||
|
result = 0;
|
||||||
|
}break;
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
//
|
||||||
|
// Dirty Flags
|
||||||
|
//
|
||||||
|
|
||||||
|
inline b32
|
||||||
|
buffer_needs_save(Editing_File *file){
|
||||||
|
b32 result = 0;
|
||||||
|
if (!file->settings.unimportant){
|
||||||
|
if (file->state.dirty == DirtyState_UnsavedChanges){
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline b32
|
||||||
|
buffer_can_save(Editing_File *file){
|
||||||
|
b32 result = 0;
|
||||||
|
if (!file->settings.unimportant){
|
||||||
|
if (file->state.dirty == DirtyState_UnsavedChanges ||
|
||||||
|
file->state.dirty == DirtyState_UnloadedChanges){
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline b32
|
||||||
|
file_is_ready(Editing_File *file){
|
||||||
|
b32 result = 0;
|
||||||
|
if (file && file->is_loading == 0){
|
||||||
|
result = 1;
|
||||||
|
}
|
||||||
|
return(result);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
file_set_to_loading(Editing_File *file){
|
||||||
|
file->state = null_editing_file_state;
|
||||||
|
file->settings = null_editing_file_settings;
|
||||||
|
file->is_loading = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
file_mark_clean(Editing_File *file){
|
||||||
|
if (file->state.dirty != DirtyState_UnloadedChanges){
|
||||||
|
file->state.dirty = DirtyState_UpToDate;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
file_mark_dirty(Editing_File *file){
|
||||||
|
if (file->state.dirty != DirtyState_UnloadedChanges){
|
||||||
|
file->state.dirty = DirtyState_UnsavedChanges;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
file_mark_behind_os(Editing_File *file){
|
||||||
|
file->state.dirty = DirtyState_UnloadedChanges;
|
||||||
|
}
|
||||||
|
|
||||||
|
inline Dirty_State
|
||||||
|
file_get_sync(Editing_File *file){
|
||||||
|
return (file->state.dirty);
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
// BOTTOM
|
|
@ -0,0 +1,19 @@
|
||||||
|
/*
|
||||||
|
* Mr. 4th Dimention - Allen Webster
|
||||||
|
*
|
||||||
|
* 03.01.2017
|
||||||
|
*
|
||||||
|
* File layer for 4coder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TOP
|
||||||
|
|
||||||
|
#include "4coder_file.cpp"
|
||||||
|
|
||||||
|
int main(){
|
||||||
|
return(0);
|
||||||
|
}
|
||||||
|
|
||||||
|
// BOTTOM
|
||||||
|
|
|
@ -0,0 +1,93 @@
|
||||||
|
/*
|
||||||
|
* Mr. 4th Dimention - Allen Webster
|
||||||
|
*
|
||||||
|
* 03.01.2017
|
||||||
|
*
|
||||||
|
* Hot_Directory data structure for 4coder
|
||||||
|
*
|
||||||
|
*/
|
||||||
|
|
||||||
|
// TOP
|
||||||
|
|
||||||
|
struct Hot_Directory{
|
||||||
|
String string;
|
||||||
|
File_List file_list;
|
||||||
|
};
|
||||||
|
|
||||||
|
internal void
|
||||||
|
hot_directory_clean_end(Hot_Directory *hot_directory){
|
||||||
|
String *str = &hot_directory->string;
|
||||||
|
if (str->size != 0 && str->str[str->size-1] != '/'){
|
||||||
|
str->size = reverse_seek_slash(*str) + 1;
|
||||||
|
str->str[str->size] = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
internal i32
|
||||||
|
hot_directory_quick_partition(File_Info *infos, i32 start, i32 pivot){
|
||||||
|
File_Info *p = infos + pivot;
|
||||||
|
File_Info *a = infos + start;
|
||||||
|
for (i32 i = start; i < pivot; ++i, ++a){
|
||||||
|
i32 comp = 0;
|
||||||
|
comp = p->folder - a->folder;
|
||||||
|
if (comp == 0){
|
||||||
|
comp = compare_cc(a->filename, p->filename);
|
||||||
|
}
|
||||||
|
if (comp < 0){
|
||||||
|
Swap(File_Info, *a, infos[start]);
|
||||||
|
++start;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
Swap(File_Info, *p, infos[start]);
|
||||||
|
return start;
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
hot_directory_quick_sort(File_Info *infos, i32 start, i32 pivot){
|
||||||
|
i32 mid = hot_directory_quick_partition(infos, start, pivot);
|
||||||
|
if (start < mid-1) hot_directory_quick_sort(infos, start, mid-1);
|
||||||
|
if (mid+1 < pivot) hot_directory_quick_sort(infos, mid+1, pivot);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
hot_directory_fixup(Hot_Directory *hot_directory){
|
||||||
|
File_List *files = &hot_directory->file_list;
|
||||||
|
if (files->count >= 2){
|
||||||
|
hot_directory_quick_sort(files->infos, 0, files->count - 1);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
hot_directory_set(System_Functions *system, Hot_Directory *hot_directory, String str){
|
||||||
|
b32 success = copy_checked_ss(&hot_directory->string, str);
|
||||||
|
terminate_with_null(&hot_directory->string);
|
||||||
|
if (success){
|
||||||
|
if (str.size > 0){
|
||||||
|
system->set_file_list(&hot_directory->file_list, str);
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
system->set_file_list(&hot_directory->file_list, make_string((char*)1, 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
hot_directory_fixup(hot_directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
inline void
|
||||||
|
hot_directory_reload(System_Functions *system, Hot_Directory *hot_directory){
|
||||||
|
system->set_file_list(&hot_directory->file_list, hot_directory->string);
|
||||||
|
hot_directory_fixup(hot_directory);
|
||||||
|
}
|
||||||
|
|
||||||
|
internal void
|
||||||
|
hot_directory_init(Hot_Directory *hot_directory, String base, String dir){
|
||||||
|
hot_directory->string = base;
|
||||||
|
hot_directory->string.str[255] = 0;
|
||||||
|
hot_directory->string.size = 0;
|
||||||
|
copy_ss(&hot_directory->string, dir);
|
||||||
|
if (hot_directory->string.str[hot_directory->string.size-1] != '/'){
|
||||||
|
append_s_char(&hot_directory->string, '/');
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// BOTTOM
|
||||||
|
|
|
@ -1,193 +1,17 @@
|
||||||
/*
|
/*
|
||||||
* Mr. 4th Dimention - Allen Webster
|
* Mr. 4th Dimention - Allen Webster
|
||||||
*
|
*
|
||||||
* 20.02.2016
|
* 03.01.2017
|
||||||
*
|
*
|
||||||
* File editing view for 4coder
|
* Working_Set data structure for 4coder
|
||||||
*
|
*
|
||||||
*/
|
*/
|
||||||
|
|
||||||
// TOP
|
// TOP
|
||||||
|
|
||||||
enum Edit_Pos_Set_Type{
|
//
|
||||||
EditPos_None,
|
// Working_Set of files
|
||||||
EditPos_CursorSet,
|
//
|
||||||
EditPos_ScrollSet
|
|
||||||
};
|
|
||||||
struct File_Edit_Positions{
|
|
||||||
GUI_Scroll_Vars scroll;
|
|
||||||
Full_Cursor cursor;
|
|
||||||
i32 mark;
|
|
||||||
f32 preferred_x;
|
|
||||||
i32 scroll_i;
|
|
||||||
i32 last_set_type;
|
|
||||||
b32 in_view;
|
|
||||||
};
|
|
||||||
static File_Edit_Positions null_edit_pos = {0};
|
|
||||||
|
|
||||||
enum Edit_Type{
|
|
||||||
ED_NORMAL,
|
|
||||||
ED_REVERSE_NORMAL,
|
|
||||||
ED_UNDO,
|
|
||||||
ED_REDO,
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Edit_Step{
|
|
||||||
Edit_Type type;
|
|
||||||
union{
|
|
||||||
struct{
|
|
||||||
b32 can_merge;
|
|
||||||
Buffer_Edit edit;
|
|
||||||
i32 next_block;
|
|
||||||
i32 prev_block;
|
|
||||||
};
|
|
||||||
struct{
|
|
||||||
i32 first_child;
|
|
||||||
i32 inverse_first_child;
|
|
||||||
i32 inverse_child_count;
|
|
||||||
i32 special_type;
|
|
||||||
};
|
|
||||||
};
|
|
||||||
i32 child_count;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Edit_Stack{
|
|
||||||
u8 *strings;
|
|
||||||
i32 size, max;
|
|
||||||
|
|
||||||
Edit_Step *edits;
|
|
||||||
i32 edit_count, edit_max;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Small_Edit_Stack{
|
|
||||||
u8 *strings;
|
|
||||||
i32 size, max;
|
|
||||||
|
|
||||||
Buffer_Edit *edits;
|
|
||||||
i32 edit_count, edit_max;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Undo_Data{
|
|
||||||
Edit_Stack undo;
|
|
||||||
Edit_Stack redo;
|
|
||||||
Edit_Stack history;
|
|
||||||
Small_Edit_Stack children;
|
|
||||||
|
|
||||||
i32 history_block_count, history_head_block;
|
|
||||||
i32 edit_history_cursor;
|
|
||||||
b32 current_block_normal;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Text_Effect{
|
|
||||||
i32 start, end;
|
|
||||||
u32 color;
|
|
||||||
f32 seconds_down, seconds_max;
|
|
||||||
};
|
|
||||||
|
|
||||||
// NOTE(allen): The Editing_File struct is now divided into two
|
|
||||||
// parts. Variables in the Settings part can be set even when the
|
|
||||||
// file is still streaming in, and persists thorugh all operations except
|
|
||||||
// for the initial allocation of the file.
|
|
||||||
struct Editing_File_Settings{
|
|
||||||
i32 base_map_id;
|
|
||||||
i32 display_width;
|
|
||||||
i32 minimum_base_display_width;
|
|
||||||
i32 wrap_indicator;
|
|
||||||
b32 dos_write_mode;
|
|
||||||
b32 virtual_white;
|
|
||||||
i16 font_id;
|
|
||||||
b8 unwrapped_lines;
|
|
||||||
b8 tokens_exist;
|
|
||||||
b8 is_initialized;
|
|
||||||
b8 unimportant;
|
|
||||||
b8 read_only;
|
|
||||||
b8 never_kill;
|
|
||||||
};
|
|
||||||
static Editing_File_Settings null_editing_file_settings = {0};
|
|
||||||
|
|
||||||
// NOTE(allen): This part of the Editing_File is cleared whenever
|
|
||||||
// the contents of the file is set.
|
|
||||||
struct Editing_File_State{
|
|
||||||
Buffer_Type buffer;
|
|
||||||
|
|
||||||
i32 *wrap_line_index;
|
|
||||||
i32 wrap_max;
|
|
||||||
|
|
||||||
i32 *character_starts;
|
|
||||||
i32 character_start_max;
|
|
||||||
|
|
||||||
f32 *line_indents;
|
|
||||||
i32 line_indent_max;
|
|
||||||
|
|
||||||
i32 wrap_line_count;
|
|
||||||
|
|
||||||
i32 *wrap_positions;
|
|
||||||
i32 wrap_position_count;
|
|
||||||
i32 wrap_position_max;
|
|
||||||
|
|
||||||
Undo_Data undo;
|
|
||||||
|
|
||||||
Cpp_Token_Array token_array;
|
|
||||||
Cpp_Token_Array swap_array;
|
|
||||||
u32 lex_job;
|
|
||||||
b32 tokens_complete;
|
|
||||||
b32 still_lexing;
|
|
||||||
|
|
||||||
Text_Effect paste_effect;
|
|
||||||
|
|
||||||
Dirty_State dirty;
|
|
||||||
u32 ignore_behind_os;
|
|
||||||
|
|
||||||
File_Edit_Positions edit_pos_space[16];
|
|
||||||
File_Edit_Positions *edit_poss[16];
|
|
||||||
i32 edit_poss_count;
|
|
||||||
};
|
|
||||||
static Editing_File_State null_editing_file_state = {0};
|
|
||||||
|
|
||||||
struct Editing_File_Name{
|
|
||||||
char live_name_[256];
|
|
||||||
char source_path_[256];
|
|
||||||
char extension_[16];
|
|
||||||
String live_name;
|
|
||||||
String source_path;
|
|
||||||
String extension;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Editing_File_Canon_Name{
|
|
||||||
char name_[256];
|
|
||||||
String name;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct File_Node{
|
|
||||||
File_Node *next, *prev;
|
|
||||||
};
|
|
||||||
|
|
||||||
union Buffer_Slot_ID{
|
|
||||||
i32 id;
|
|
||||||
i16 part[2];
|
|
||||||
};
|
|
||||||
|
|
||||||
inline Buffer_Slot_ID
|
|
||||||
to_file_id(i32 id){
|
|
||||||
Buffer_Slot_ID result;
|
|
||||||
result.id = id;
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Editing_File{
|
|
||||||
// NOTE(allen): node must be the first member of Editing_File!
|
|
||||||
File_Node node;
|
|
||||||
Editing_File_Settings settings;
|
|
||||||
struct{
|
|
||||||
b32 is_loading;
|
|
||||||
b32 is_dummy;
|
|
||||||
Editing_File_State state;
|
|
||||||
};
|
|
||||||
Editing_File_Name name;
|
|
||||||
Editing_File_Canon_Name canon;
|
|
||||||
Buffer_Slot_ID id;
|
|
||||||
u64 unique_buffer_id;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct Non_File_Table_Entry{
|
struct Non_File_Table_Entry{
|
||||||
String name;
|
String name;
|
||||||
|
@ -204,15 +28,15 @@ struct Working_Set{
|
||||||
i32 file_count, file_max;
|
i32 file_count, file_max;
|
||||||
i16 array_count, array_max;
|
i16 array_count, array_max;
|
||||||
|
|
||||||
File_Node free_sentinel;
|
File_Node free_sentinel;
|
||||||
File_Node used_sentinel;
|
File_Node used_sentinel;
|
||||||
|
|
||||||
Table canon_table;
|
Table canon_table;
|
||||||
Table name_table;
|
Table name_table;
|
||||||
|
|
||||||
String clipboards[64];
|
String clipboards[64];
|
||||||
i32 clipboard_size, clipboard_max_size;
|
i32 clipboard_size, clipboard_max_size;
|
||||||
i32 clipboard_current, clipboard_rolling;
|
i32 clipboard_current, clipboard_rolling;
|
||||||
|
|
||||||
u64 unique_file_counter;
|
u64 unique_file_counter;
|
||||||
|
|
||||||
|
@ -222,176 +46,12 @@ struct Working_Set{
|
||||||
i32 default_minimum_base_display_width;
|
i32 default_minimum_base_display_width;
|
||||||
};
|
};
|
||||||
|
|
||||||
//
|
|
||||||
// File_Edit_Positions stuff
|
|
||||||
//
|
|
||||||
|
|
||||||
internal void
|
|
||||||
edit_pos_set_cursor_(File_Edit_Positions *edit_pos,
|
|
||||||
Full_Cursor cursor,
|
|
||||||
b32 set_preferred_x,
|
|
||||||
b32 unwrapped_lines){
|
|
||||||
edit_pos->cursor = cursor;
|
|
||||||
if (set_preferred_x){
|
|
||||||
edit_pos->preferred_x = cursor.wrapped_x;
|
|
||||||
if (unwrapped_lines){
|
|
||||||
edit_pos->preferred_x = cursor.unwrapped_x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
edit_pos->last_set_type = EditPos_CursorSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
edit_pos_set_scroll_(File_Edit_Positions *edit_pos, GUI_Scroll_Vars scroll){
|
|
||||||
edit_pos->scroll = scroll;
|
|
||||||
edit_pos->last_set_type = EditPos_ScrollSet;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal i32
|
|
||||||
edit_pos_get_index(Editing_File *file, File_Edit_Positions *edit_pos){
|
|
||||||
i32 edit_pos_index = -1;
|
|
||||||
|
|
||||||
i32 count = file->state.edit_poss_count;
|
|
||||||
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
|
||||||
for (i32 i = 0; i < count; ++i){
|
|
||||||
if (edit_poss[i] == edit_pos){
|
|
||||||
edit_pos_index = i;
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
return(edit_pos_index);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal b32
|
|
||||||
edit_pos_move_to_front(Editing_File *file, File_Edit_Positions *edit_pos){
|
|
||||||
b32 result = false;
|
|
||||||
|
|
||||||
if (file && edit_pos){
|
|
||||||
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
|
|
||||||
Assert(edit_pos_index != -1);
|
|
||||||
|
|
||||||
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
|
||||||
|
|
||||||
memmove(edit_poss + 1, edit_poss, edit_pos_index*sizeof(*edit_poss));
|
|
||||||
|
|
||||||
edit_poss[0] = edit_pos;
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal b32
|
|
||||||
edit_pos_unset(Editing_File *file, File_Edit_Positions *edit_pos){
|
|
||||||
b32 result = false;
|
|
||||||
|
|
||||||
if (file && edit_pos){
|
|
||||||
i32 edit_pos_index = edit_pos_get_index(file, edit_pos);
|
|
||||||
Assert(edit_pos_index != -1);
|
|
||||||
|
|
||||||
i32 count = file->state.edit_poss_count;
|
|
||||||
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
|
||||||
|
|
||||||
memmove(edit_poss + edit_pos_index,
|
|
||||||
edit_poss + edit_pos_index + 1,
|
|
||||||
(count - edit_pos_index - 1)*sizeof(*edit_poss));
|
|
||||||
|
|
||||||
edit_pos->in_view = false;
|
|
||||||
|
|
||||||
if (file->state.edit_poss_count > 1){
|
|
||||||
file->state.edit_poss_count -= 1;
|
|
||||||
}
|
|
||||||
result = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal File_Edit_Positions*
|
|
||||||
edit_pos_get_new(Editing_File *file, i32 index){
|
|
||||||
File_Edit_Positions *result = 0;
|
|
||||||
|
|
||||||
if (file && 0 <= index && index < 16){
|
|
||||||
result = file->state.edit_pos_space + index;
|
|
||||||
i32 edit_pos_index = edit_pos_get_index(file, result);
|
|
||||||
|
|
||||||
if (edit_pos_index == -1){
|
|
||||||
File_Edit_Positions **edit_poss = file->state.edit_poss;
|
|
||||||
i32 count = file->state.edit_poss_count;
|
|
||||||
|
|
||||||
if (count > 0){
|
|
||||||
if (edit_poss[0]->in_view){
|
|
||||||
memcpy(result, edit_poss[0], sizeof(*result));
|
|
||||||
memmove(edit_poss+1, edit_poss, sizeof(*edit_poss)*count);
|
|
||||||
file->state.edit_poss_count = count + 1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
Assert(count == 1);
|
|
||||||
memcpy(result, edit_poss[0], sizeof(*result));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
memset(result, 0, sizeof(*result));
|
|
||||||
file->state.edit_poss_count = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
edit_poss[0] = result;
|
|
||||||
}
|
|
||||||
|
|
||||||
result->in_view = true;
|
|
||||||
}
|
|
||||||
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// File Cursor Seeking
|
|
||||||
//
|
|
||||||
|
|
||||||
inline Partial_Cursor
|
|
||||||
file_compute_cursor_from_pos(Editing_File *file, i32 pos){
|
|
||||||
Partial_Cursor result = buffer_partial_from_pos(&file->state.buffer, pos);
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Partial_Cursor
|
|
||||||
file_compute_cursor_from_line_character(Editing_File *file, i32 line, i32 character){
|
|
||||||
Partial_Cursor result = buffer_partial_from_line_character(&file->state.buffer, line, character);
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline b32
|
|
||||||
file_compute_partial_cursor(Editing_File *file, Buffer_Seek seek, Partial_Cursor *cursor){
|
|
||||||
b32 result = 1;
|
|
||||||
switch (seek.type){
|
|
||||||
case buffer_seek_pos:
|
|
||||||
{
|
|
||||||
*cursor = file_compute_cursor_from_pos(file, seek.pos);
|
|
||||||
}break;
|
|
||||||
|
|
||||||
case buffer_seek_line_char:
|
|
||||||
{
|
|
||||||
*cursor = file_compute_cursor_from_line_character(file, seek.line, seek.character);
|
|
||||||
}break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
{
|
|
||||||
result = 0;
|
|
||||||
}break;
|
|
||||||
}
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
//
|
|
||||||
// Working_Set stuff
|
|
||||||
//
|
|
||||||
|
|
||||||
struct File_Name_Entry{
|
struct File_Name_Entry{
|
||||||
String name;
|
String name;
|
||||||
Buffer_Slot_ID id;
|
Buffer_Slot_ID id;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
internal i32
|
internal i32
|
||||||
tbl_name_compare(void *a, void *b, void *arg){
|
tbl_name_compare(void *a, void *b, void *arg){
|
||||||
String *fa = (String*)a;
|
String *fa = (String*)a;
|
||||||
|
@ -431,12 +91,6 @@ working_set_extend_memory(Working_Set *working_set, Editing_File *new_space, i16
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
inline Editing_File
|
|
||||||
editing_file_zero(){
|
|
||||||
Editing_File file = {0};
|
|
||||||
return(file);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal Editing_File*
|
internal Editing_File*
|
||||||
working_set_alloc(Working_Set *working_set){
|
working_set_alloc(Working_Set *working_set){
|
||||||
Editing_File *result = 0;
|
Editing_File *result = 0;
|
||||||
|
@ -448,7 +102,7 @@ working_set_alloc(Working_Set *working_set){
|
||||||
|
|
||||||
dll_remove(node);
|
dll_remove(node);
|
||||||
Buffer_Slot_ID id = result->id;
|
Buffer_Slot_ID id = result->id;
|
||||||
*result = editing_file_zero();
|
*result = null_editing_file;
|
||||||
result->id = id;
|
result->id = id;
|
||||||
result->unique_buffer_id = ++working_set->unique_file_counter;
|
result->unique_buffer_id = ++working_set->unique_file_counter;
|
||||||
dll_insert(&working_set->used_sentinel, node);
|
dll_insert(&working_set->used_sentinel, node);
|
||||||
|
@ -626,7 +280,7 @@ working_set_canon_contains(Working_Set *working_set, String name){
|
||||||
|
|
||||||
internal b32
|
internal b32
|
||||||
working_set_canon_add(System_Functions *system, General_Memory *general, Working_Set *working_set,
|
working_set_canon_add(System_Functions *system, General_Memory *general, Working_Set *working_set,
|
||||||
Editing_File *file, String name){
|
Editing_File *file, String name){
|
||||||
b32 result = working_set_add_basic(system, general,working_set, &working_set->canon_table, file, name);
|
b32 result = working_set_add_basic(system, general,working_set, &working_set->canon_table, file, name);
|
||||||
return(result);
|
return(result);
|
||||||
}
|
}
|
||||||
|
@ -673,8 +327,8 @@ working_set_lookup_file(Working_Set *working_set, String string){
|
||||||
}
|
}
|
||||||
if (node == used_nodes) file = 0;
|
if (node == used_nodes) file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!file){
|
if (!file){
|
||||||
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)){
|
||||||
|
@ -684,9 +338,9 @@ working_set_lookup_file(Working_Set *working_set, String string){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (node == used_nodes) file = 0;
|
if (node == used_nodes) file = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (file);
|
return (file);
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -698,164 +352,10 @@ touch_file(Working_Set *working_set, Editing_File *file){
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// Hot Directory
|
|
||||||
|
|
||||||
struct Hot_Directory{
|
//
|
||||||
String string;
|
// Name Binding
|
||||||
File_List file_list;
|
//
|
||||||
// TODO(allen): eliminate slash
|
|
||||||
char slash;
|
|
||||||
};
|
|
||||||
|
|
||||||
internal void
|
|
||||||
hot_directory_clean_end(Hot_Directory *hot_directory){
|
|
||||||
String *str = &hot_directory->string;
|
|
||||||
if (str->size != 0 && str->str[str->size-1] != hot_directory->slash){
|
|
||||||
str->size = reverse_seek_slash(*str) + 1;
|
|
||||||
str->str[str->size] = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
internal i32
|
|
||||||
hot_directory_quick_partition(File_Info *infos, i32 start, i32 pivot){
|
|
||||||
File_Info *p = infos + pivot;
|
|
||||||
File_Info *a = infos + start;
|
|
||||||
for (i32 i = start; i < pivot; ++i, ++a){
|
|
||||||
i32 comp = 0;
|
|
||||||
comp = p->folder - a->folder;
|
|
||||||
if (comp == 0){
|
|
||||||
comp = compare_cc(a->filename, p->filename);
|
|
||||||
}
|
|
||||||
if (comp < 0){
|
|
||||||
Swap(File_Info, *a, infos[start]);
|
|
||||||
++start;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
Swap(File_Info, *p, infos[start]);
|
|
||||||
return start;
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
hot_directory_quick_sort(File_Info *infos, i32 start, i32 pivot){
|
|
||||||
i32 mid = hot_directory_quick_partition(infos, start, pivot);
|
|
||||||
if (start < mid-1) hot_directory_quick_sort(infos, start, mid-1);
|
|
||||||
if (mid+1 < pivot) hot_directory_quick_sort(infos, mid+1, pivot);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
hot_directory_fixup(Hot_Directory *hot_directory, Working_Set *working_set){
|
|
||||||
File_List *files = &hot_directory->file_list;
|
|
||||||
if (files->count >= 2)
|
|
||||||
hot_directory_quick_sort(files->infos, 0, files->count - 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
hot_directory_set(System_Functions *system, Hot_Directory *hot_directory,
|
|
||||||
String str, Working_Set *working_set){
|
|
||||||
b32 success = copy_checked_ss(&hot_directory->string, str);
|
|
||||||
terminate_with_null(&hot_directory->string);
|
|
||||||
if (success){
|
|
||||||
if (str.size > 0){
|
|
||||||
system->set_file_list(&hot_directory->file_list, str);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
system->set_file_list(&hot_directory->file_list, make_string((char*)1, 0));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
hot_directory_fixup(hot_directory, working_set);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
hot_directory_reload(System_Functions *system, Hot_Directory *hot_directory, Working_Set *working_set){
|
|
||||||
system->set_file_list(&hot_directory->file_list, hot_directory->string);
|
|
||||||
hot_directory_fixup(hot_directory, working_set);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
|
||||||
hot_directory_init(Hot_Directory *hot_directory, String base, String dir, char slash){
|
|
||||||
hot_directory->string = base;
|
|
||||||
hot_directory->string.str[255] = 0;
|
|
||||||
hot_directory->string.size = 0;
|
|
||||||
copy_ss(&hot_directory->string, dir);
|
|
||||||
append_s_char(&hot_directory->string, slash);
|
|
||||||
hot_directory->slash = slash;
|
|
||||||
}
|
|
||||||
|
|
||||||
struct Hot_Directory_Match{
|
|
||||||
String filename;
|
|
||||||
b32 is_folder;
|
|
||||||
};
|
|
||||||
|
|
||||||
internal b32
|
|
||||||
filename_match(String query, Absolutes *absolutes, String filename){
|
|
||||||
b32 result;
|
|
||||||
result = (query.size == 0);
|
|
||||||
if (!result) result = wildcard_match_s(absolutes, filename, 0);
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline b32
|
|
||||||
buffer_needs_save(Editing_File *file){
|
|
||||||
b32 result = 0;
|
|
||||||
if (!file->settings.unimportant){
|
|
||||||
if (file->state.dirty == DirtyState_UnsavedChanges){
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline b32
|
|
||||||
buffer_can_save(Editing_File *file){
|
|
||||||
b32 result = 0;
|
|
||||||
if (!file->settings.unimportant){
|
|
||||||
if (file->state.dirty == DirtyState_UnsavedChanges ||
|
|
||||||
file->state.dirty == DirtyState_UnloadedChanges){
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline b32
|
|
||||||
file_is_ready(Editing_File *file){
|
|
||||||
b32 result = 0;
|
|
||||||
if (file && file->is_loading == 0){
|
|
||||||
result = 1;
|
|
||||||
}
|
|
||||||
return(result);
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
file_set_to_loading(Editing_File *file){
|
|
||||||
file->state = null_editing_file_state;
|
|
||||||
file->settings = null_editing_file_settings;
|
|
||||||
file->is_loading = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
file_mark_clean(Editing_File *file){
|
|
||||||
if (file->state.dirty != DirtyState_UnloadedChanges){
|
|
||||||
file->state.dirty = DirtyState_UpToDate;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
file_mark_dirty(Editing_File *file){
|
|
||||||
if (file->state.dirty != DirtyState_UnloadedChanges){
|
|
||||||
file->state.dirty = DirtyState_UnsavedChanges;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
inline void
|
|
||||||
file_mark_behind_os(Editing_File *file){
|
|
||||||
file->state.dirty = DirtyState_UnloadedChanges;
|
|
||||||
}
|
|
||||||
|
|
||||||
inline Dirty_State
|
|
||||||
file_get_sync(Editing_File *file){
|
|
||||||
return (file->state.dirty);
|
|
||||||
}
|
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
editing_file_name_init(Editing_File_Name *name){
|
editing_file_name_init(Editing_File_Name *name){
|
||||||
|
@ -868,9 +368,7 @@ internal b32
|
||||||
get_canon_name(System_Functions *system, Editing_File_Canon_Name *canon_name, String filename){
|
get_canon_name(System_Functions *system, Editing_File_Canon_Name *canon_name, String filename){
|
||||||
canon_name->name = make_fixed_width_string(canon_name->name_);
|
canon_name->name = make_fixed_width_string(canon_name->name_);
|
||||||
|
|
||||||
canon_name->name.size =
|
canon_name->name.size = system->get_canonical(filename.str, filename.size, canon_name->name.str, canon_name->name.memory_size);
|
||||||
system->get_canonical(filename.str, filename.size,
|
|
||||||
canon_name->name.str, canon_name->name.memory_size);
|
|
||||||
terminate_with_null(&canon_name->name);
|
terminate_with_null(&canon_name->name);
|
||||||
|
|
||||||
b32 result = (canon_name->name.size != 0);
|
b32 result = (canon_name->name.size != 0);
|
||||||
|
@ -928,8 +426,7 @@ buffer_get_new_name(Working_Set *working_set, Editing_File_Name *name, char *fil
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set *working_set,
|
buffer_bind_file(System_Functions *system, General_Memory *general, Working_Set *working_set, Editing_File *file, String canon_filename){
|
||||||
Editing_File *file, String canon_filename){
|
|
||||||
Assert(file->name.live_name.size == 0 &&
|
Assert(file->name.live_name.size == 0 &&
|
||||||
file->name.source_path.size == 0 &&
|
file->name.source_path.size == 0 &&
|
||||||
file->name.extension.size == 0);
|
file->name.extension.size == 0);
|
||||||
|
@ -956,8 +453,7 @@ buffer_unbind_file(System_Functions *system, Working_Set *working_set, Editing_F
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
buffer_bind_name(System_Functions *system, General_Memory *general, Working_Set *working_set,
|
buffer_bind_name(System_Functions *system, General_Memory *general, Working_Set *working_set, Editing_File *file, String filename){
|
||||||
Editing_File *file, String filename){
|
|
||||||
Assert(file->name.live_name.size == 0 &&
|
Assert(file->name.live_name.size == 0 &&
|
||||||
file->name.source_path.size == 0 &&
|
file->name.source_path.size == 0 &&
|
||||||
file->name.extension.size == 0);
|
file->name.extension.size == 0);
|
||||||
|
@ -984,5 +480,6 @@ buffer_unbind_name(Working_Set *working_set, Editing_File *file){
|
||||||
file->name.extension.size = 0;
|
file->name.extension.size = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
|
@ -0,0 +1,11 @@
|
||||||
|
@echo off
|
||||||
|
|
||||||
|
SET OPTS=/W4 /wd4310 /wd4100 /wd4201 /wd4505 /wd4996 /wd4127 /wd4510 /wd4512 /wd4610 /wd4390 /WX
|
||||||
|
SET OPTS=%OPTS% /GR- /EHa- /nologo /FC
|
||||||
|
|
||||||
|
pushd ..\build
|
||||||
|
cl %OPTS% ..\code\file\4coder_file_tests.cpp /Zi /Fefile_test
|
||||||
|
popd
|
||||||
|
|
||||||
|
if %ERRORLEVEL% eq 0 (..\build\file_test)
|
||||||
|
|
|
@ -1903,102 +1903,110 @@ typedef struct Absolutes{
|
||||||
|
|
||||||
static void
|
static void
|
||||||
get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_bool implicit_last){
|
get_absolutes(String name, Absolutes *absolutes, fstr_bool implicit_first, fstr_bool implicit_last){
|
||||||
int32_t count = 0;
|
if (name.size != 0){
|
||||||
int32_t max = ArrayCount(absolutes->a) - 1;
|
int32_t count = 0;
|
||||||
if (implicit_last) --max;
|
int32_t max = ArrayCount(absolutes->a) - 1;
|
||||||
|
if (implicit_last) --max;
|
||||||
String str;
|
|
||||||
str.str = name.str;
|
String str;
|
||||||
str.size = 0;
|
str.str = name.str;
|
||||||
str.memory_size = 0;
|
|
||||||
fstr_bool prev_was_wild = 0;
|
|
||||||
|
|
||||||
if (implicit_first){
|
|
||||||
absolutes->a[count++] = str;
|
|
||||||
prev_was_wild = 1;
|
|
||||||
}
|
|
||||||
|
|
||||||
int32_t i;
|
|
||||||
for (i = 0; i < name.size; ++i){
|
|
||||||
if (name.str[i] == '*' && count < max){
|
|
||||||
if (!prev_was_wild){
|
|
||||||
str.memory_size = str.size;
|
|
||||||
absolutes->a[count++] = str;
|
|
||||||
str.size = 0;
|
|
||||||
}
|
|
||||||
str.str = name.str + i + 1;
|
|
||||||
prev_was_wild = 1;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
++str.size;
|
|
||||||
prev_was_wild = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
str.memory_size = str.size;
|
|
||||||
absolutes->a[count++] = str;
|
|
||||||
|
|
||||||
if (implicit_last){
|
|
||||||
str.size = 0;
|
str.size = 0;
|
||||||
str.memory_size = 0;
|
str.memory_size = 0;
|
||||||
|
fstr_bool prev_was_wild = 0;
|
||||||
|
|
||||||
|
if (implicit_first){
|
||||||
|
absolutes->a[count++] = str;
|
||||||
|
prev_was_wild = 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
int32_t i;
|
||||||
|
for (i = 0; i < name.size; ++i){
|
||||||
|
if (name.str[i] == '*' && count < max){
|
||||||
|
if (!prev_was_wild){
|
||||||
|
str.memory_size = str.size;
|
||||||
|
absolutes->a[count++] = str;
|
||||||
|
str.size = 0;
|
||||||
|
}
|
||||||
|
str.str = name.str + i + 1;
|
||||||
|
prev_was_wild = 1;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
++str.size;
|
||||||
|
prev_was_wild = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
str.memory_size = str.size;
|
||||||
absolutes->a[count++] = str;
|
absolutes->a[count++] = str;
|
||||||
|
|
||||||
|
if (implicit_last){
|
||||||
|
str.size = 0;
|
||||||
|
str.memory_size = 0;
|
||||||
|
absolutes->a[count++] = str;
|
||||||
|
}
|
||||||
|
|
||||||
|
absolutes->count = count;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
absolutes->count = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
absolutes->count = count;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
static fstr_bool
|
static fstr_bool
|
||||||
wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){
|
wildcard_match_c(Absolutes *absolutes, char *x, int32_t case_sensitive){
|
||||||
fstr_bool r = 1;
|
fstr_bool r = 1;
|
||||||
String *a = absolutes->a;
|
|
||||||
|
|
||||||
fstr_bool (*match_func)(char*, String);
|
if (absolutes->count > 0){
|
||||||
fstr_bool (*match_part_func)(char*, String);
|
String *a = absolutes->a;
|
||||||
|
|
||||||
if (case_sensitive){
|
fstr_bool (*match_func)(char*, String);
|
||||||
match_func = match_cs;
|
fstr_bool (*match_part_func)(char*, String);
|
||||||
match_part_func = match_part_cs;
|
|
||||||
}
|
if (case_sensitive){
|
||||||
else{
|
match_func = match_cs;
|
||||||
match_func = match_insensitive_cs;
|
match_part_func = match_part_cs;
|
||||||
match_part_func = match_part_insensitive_cs;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (absolutes->count == 1){
|
|
||||||
r = match_func(x, *a);
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
if (!match_part_func(x, *a)){
|
|
||||||
r = 0;
|
|
||||||
}
|
}
|
||||||
else{
|
else{
|
||||||
String *max = a + absolutes->count - 1;
|
match_func = match_insensitive_cs;
|
||||||
x += a->size;
|
match_part_func = match_part_insensitive_cs;
|
||||||
++a;
|
}
|
||||||
while (a < max){
|
|
||||||
if (*x == 0){
|
if (absolutes->count == 1){
|
||||||
r = 0;
|
r = match_func(x, *a);
|
||||||
break;
|
}
|
||||||
}
|
else{
|
||||||
if (match_part_func(x, *a)){
|
if (!match_part_func(x, *a)){
|
||||||
x += a->size;
|
|
||||||
++a;
|
|
||||||
}
|
|
||||||
else{
|
|
||||||
++x;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (r && a->size > 0){
|
|
||||||
r = 0;
|
r = 0;
|
||||||
while (*x != 0){
|
}
|
||||||
if (match_part_func(x, *a) && *(x + a->size) == 0){
|
else{
|
||||||
r = 1;
|
String *max = a + absolutes->count - 1;
|
||||||
|
x += a->size;
|
||||||
|
++a;
|
||||||
|
while (a < max){
|
||||||
|
if (*x == 0){
|
||||||
|
r = 0;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (match_part_func(x, *a)){
|
||||||
|
x += a->size;
|
||||||
|
++a;
|
||||||
|
}
|
||||||
else{
|
else{
|
||||||
++x;
|
++x;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
if (r && a->size > 0){
|
||||||
|
r = 0;
|
||||||
|
while (*x != 0){
|
||||||
|
if (match_part_func(x, *a) && *(x + a->size) == 0){
|
||||||
|
r = 1;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else{
|
||||||
|
++x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
1136
linux_4ed.cpp
1136
linux_4ed.cpp
File diff suppressed because it is too large
Load Diff
|
@ -4,7 +4,7 @@ extensions=".c.cpp.h.hpp.bat.sh";
|
||||||
fkey_command_win[1] = {"build.bat", "*compilation*", true};
|
fkey_command_win[1] = {"build.bat", "*compilation*", true};
|
||||||
fkey_command_win[2] = {"..\\misc\\run.bat", "*run*"};
|
fkey_command_win[2] = {"..\\misc\\run.bat", "*run*"};
|
||||||
fkey_command_win[3] = {"site\\build.bat", "*compilation*", true};
|
fkey_command_win[3] = {"site\\build.bat", "*compilation*", true};
|
||||||
fkey_command_win[4] = {0, 0};
|
fkey_command_win[4] = {"file\\run_tests.bat", "*tests*"};
|
||||||
fkey_command_win[5] = {0, 0};
|
fkey_command_win[5] = {0, 0};
|
||||||
fkey_command_win[6] = {0, 0};
|
fkey_command_win[6] = {0, 0};
|
||||||
fkey_command_win[7] = {0, 0};
|
fkey_command_win[7] = {0, 0};
|
||||||
|
|
|
@ -1047,19 +1047,19 @@ Win32ToggleFullscreen(void){
|
||||||
|
|
||||||
internal
|
internal
|
||||||
Sys_Post_Clipboard_Sig(system_post_clipboard){
|
Sys_Post_Clipboard_Sig(system_post_clipboard){
|
||||||
if (OpenClipboard(win32vars.window_handle)){
|
if (OpenClipboard(win32vars.window_handle)){
|
||||||
EmptyClipboard();
|
EmptyClipboard();
|
||||||
HANDLE memory_handle;
|
HANDLE memory_handle;
|
||||||
memory_handle = GlobalAlloc(GMEM_MOVEABLE, str.size+1);
|
memory_handle = GlobalAlloc(GMEM_MOVEABLE, str.size+1);
|
||||||
if (memory_handle){
|
if (memory_handle){
|
||||||
char *dest = (char*)GlobalLock(memory_handle);
|
char *dest = (char*)GlobalLock(memory_handle);
|
||||||
copy_fast_unsafe_cs(dest, str);
|
copy_fast_unsafe_cs(dest, str);
|
||||||
GlobalUnlock(memory_handle);
|
GlobalUnlock(memory_handle);
|
||||||
SetClipboardData(CF_TEXT, memory_handle);
|
SetClipboardData(CF_TEXT, memory_handle);
|
||||||
win32vars.next_clipboard_is_self = 1;
|
win32vars.next_clipboard_is_self = 1;
|
||||||
}
|
}
|
||||||
CloseClipboard();
|
CloseClipboard();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
internal b32
|
internal b32
|
||||||
|
@ -1320,7 +1320,7 @@ Win32LoadAppCode(){
|
||||||
result = 1;
|
result = 1;
|
||||||
win32vars.app = get_funcs();
|
win32vars.app = get_funcs();
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1374,8 +1374,6 @@ Win32LoadSystemCode(){
|
||||||
#if FRED_INTERNAL
|
#if FRED_INTERNAL
|
||||||
win32vars.system.internal_get_thread_states = INTERNAL_get_thread_states;
|
win32vars.system.internal_get_thread_states = INTERNAL_get_thread_states;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
win32vars.system.slash = '/';
|
|
||||||
}
|
}
|
||||||
|
|
||||||
internal void
|
internal void
|
||||||
|
@ -1973,7 +1971,7 @@ WinMain(HINSTANCE hInstance,
|
||||||
GetProcAddress(win32vars.custom, "get_alpha_4coder_version");
|
GetProcAddress(win32vars.custom, "get_alpha_4coder_version");
|
||||||
|
|
||||||
if (win32vars.custom_api.get_alpha_4coder_version == 0 ||
|
if (win32vars.custom_api.get_alpha_4coder_version == 0 ||
|
||||||
win32vars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
|
win32vars.custom_api.get_alpha_4coder_version(MAJOR, MINOR, PATCH) == 0){
|
||||||
MessageBoxA(0,"Error: The application and custom version numbers don't match.\n", "Error",0);
|
MessageBoxA(0,"Error: The application and custom version numbers don't match.\n", "Error",0);
|
||||||
exit(1);
|
exit(1);
|
||||||
}
|
}
|
||||||
|
@ -2052,8 +2050,7 @@ WinMain(HINSTANCE hInstance,
|
||||||
}
|
}
|
||||||
|
|
||||||
win32vars.window_handle =
|
win32vars.window_handle =
|
||||||
CreateWindowA(window_class.lpszClassName,
|
CreateWindowA(window_class.lpszClassName, WINDOW_NAME, window_style,
|
||||||
WINDOW_NAME, window_style,
|
|
||||||
window_x, window_y,
|
window_x, window_y,
|
||||||
window_rect.right - window_rect.left,
|
window_rect.right - window_rect.left,
|
||||||
window_rect.bottom - window_rect.top,
|
window_rect.bottom - window_rect.top,
|
||||||
|
@ -2370,7 +2367,7 @@ WinMain(HINSTANCE hInstance,
|
||||||
int main(int argc, char **argv){
|
int main(int argc, char **argv){
|
||||||
HINSTANCE hInstance = GetModuleHandle(0);
|
HINSTANCE hInstance = GetModuleHandle(0);
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// BOTTOM
|
// BOTTOM
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue