fixes around saving, work towards updating current project on file change, more changes
This commit is contained in:
parent
d3abcbc146
commit
6982121429
2
src/dlib
2
src/dlib
@ -1 +1 @@
|
||||
Subproject commit a12e8c21e21b65e16af06675b6c2d1696e23bfa7
|
||||
Subproject commit 253be45581567c9108f9d2d686850c8862ab6168
|
||||
@ -1,7 +1,7 @@
|
||||
import dlib;
|
||||
import dlib.alloc : Reset;
|
||||
import core.stdc.stdio : EOF;
|
||||
import core.stdc.string : memcpy;
|
||||
import core.stdc.string : memcpy, strlen;
|
||||
import parsing;
|
||||
import std.format : sformat;
|
||||
import std.math.algebraic : abs;
|
||||
@ -68,9 +68,9 @@ struct FlatBuffer
|
||||
|
||||
this.arena = CreateArena(MB(1));
|
||||
this.line_start_arena = CreateArena(KB(512));
|
||||
this.file_name = file_name;
|
||||
this.file_name = AllocTerminated(file_name);
|
||||
this.line_count = CountLF(data);
|
||||
this.length = data.length;
|
||||
this.length = data.ptr ? strlen(cast(char*)data.ptr) : 0;
|
||||
this.linebufs = CreateLineBuffers(MB(1));
|
||||
this.data = buffer;
|
||||
this.tokenizer = CreateTokenizer(&this);
|
||||
@ -218,11 +218,7 @@ OpenFile(Editor* editor, string file_name)
|
||||
}
|
||||
else
|
||||
{
|
||||
char[] file_name_buffer = Alloc!(char)(file_path.length+1);
|
||||
file_name_buffer[0 .. file_path.length] = file_path[0 .. $];
|
||||
file_name_buffer[file_name_buffer.length-1] = '\0';
|
||||
|
||||
file_path = Str(file_name_buffer);
|
||||
file_path = AllocTerminated(file_path);
|
||||
|
||||
u8[] file_data;
|
||||
auto file = fopen(file_path.ptr, "rb");
|
||||
@ -238,7 +234,7 @@ OpenFile(Editor* editor, string file_name)
|
||||
fread(file_data.ptr, u8.sizeof, length, file);
|
||||
}
|
||||
|
||||
editor.buffer = CreateFlatBuffer(ctx, file_data, Str(file_name_buffer));
|
||||
editor.buffer = CreateFlatBuffer(ctx, file_data, file_path);
|
||||
}
|
||||
else
|
||||
{
|
||||
|
||||
@ -11,6 +11,7 @@ import parsing;
|
||||
|
||||
import std.algorithm.comparison : clamp;
|
||||
import std.format;
|
||||
import std.array;
|
||||
import std.stdio;
|
||||
import std.exception;
|
||||
import std.file;
|
||||
@ -95,6 +96,7 @@ struct Ctx
|
||||
u64 editor_id_incr;
|
||||
Timer timer;
|
||||
CmdPalette cmd;
|
||||
Arena file_name_arena;
|
||||
string[] file_names;
|
||||
u64 panel_id;
|
||||
Editor[] editors;
|
||||
@ -105,6 +107,8 @@ struct Ctx
|
||||
FlatBuffer* free_text_buffers;
|
||||
u64 new_buffer_count; // files that are not yet files (you know)
|
||||
|
||||
Watcher directory_watcher;
|
||||
|
||||
@property ref DescSet desc_set() => this.rd_ctx.desc_sets[this.frame_index];
|
||||
|
||||
debug bool dbg;
|
||||
@ -255,12 +259,9 @@ __gshared UIInput* g_UI_NIL_INPUT = &g_ui_nil_input;
|
||||
__gshared UIPanel* g_NIL_PANEL = &g_nil_panel;
|
||||
__gshared Notification* g_NIL_NOTIF = &g_nil_notif;
|
||||
|
||||
const Command NO_CMD = {
|
||||
name: [],
|
||||
type: CT.None,
|
||||
};
|
||||
immutable Command NO_CMD;
|
||||
|
||||
Command[22] CMD_LIST = [
|
||||
Command[8] CMD_LIST = [
|
||||
{
|
||||
name: "Open",
|
||||
cmd: "open",
|
||||
@ -277,7 +278,7 @@ Command[22] CMD_LIST = [
|
||||
},
|
||||
{
|
||||
name: "Save As",
|
||||
cmd: "save as",
|
||||
cmd: "saveas",
|
||||
desc: "Save the current file as a specified name.",
|
||||
type: CT.Callback,
|
||||
fn: &CmdSaveFileWindow,
|
||||
@ -311,109 +312,11 @@ Command[22] CMD_LIST = [
|
||||
fn: &ClosePanelCmd,
|
||||
},
|
||||
{
|
||||
name: "Test Option 1",
|
||||
cmd: "testopt1",
|
||||
desc: "This is a test option",
|
||||
name: "Quit",
|
||||
cmd: "quit",
|
||||
desc: "Close the program.",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 2",
|
||||
cmd: "testopt2",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 3",
|
||||
cmd: "testopt3",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 4",
|
||||
cmd: "testopt4",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 5",
|
||||
cmd: "testopt5",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 6",
|
||||
cmd: "testopt6",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 7",
|
||||
cmd: "testopt7",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 8",
|
||||
cmd: "testopt8",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 9",
|
||||
cmd: "testopt9",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 10",
|
||||
cmd: "testopt10",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 11",
|
||||
cmd: "testopt11",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 12",
|
||||
cmd: "testopt12",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 13",
|
||||
cmd: "testopt13",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 14",
|
||||
cmd: "testopt14",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
},
|
||||
{
|
||||
name: "Test Option 15",
|
||||
cmd: "testopt15",
|
||||
desc: "This is a test option",
|
||||
type: CT.Callback,
|
||||
fn: &NotImplementedCallback,
|
||||
fn: &CmdClose,
|
||||
},
|
||||
];
|
||||
|
||||
@ -525,11 +428,24 @@ Cycle(Inputs* inputs)
|
||||
{
|
||||
ResetScratch(MB(4));
|
||||
|
||||
g_delta = DeltaTime(&g_ctx.timer);
|
||||
ref Ctx ctx = GetCtx();
|
||||
|
||||
WatchEvent[] watch_events = ViewChanges(&ctx.directory_watcher);
|
||||
foreach(ref event; watch_events)
|
||||
{
|
||||
Logf("type %s", event.type);
|
||||
if(event.type & WET.File && event.type & (WET.Created | WET.Moved | WET.Deleted))
|
||||
{
|
||||
Logf("scanning...");
|
||||
ScanCurrentDirectory(ctx);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
g_delta = DeltaTime(&g_ctx.timer);
|
||||
|
||||
BeginUI(inputs);
|
||||
|
||||
ref Ctx ctx = GetCtx();
|
||||
|
||||
Panel(ctx, ctx.base_panel);
|
||||
|
||||
@ -559,7 +475,8 @@ InitCtx(PlatformWindow* window)
|
||||
ref Ctx ctx = GetCtx();
|
||||
|
||||
ctx.window = window;
|
||||
ctx.arena = CreateArena(MB(2));
|
||||
ctx.arena = CreateArena(MB(1));
|
||||
ctx.file_name_arena = CreateArena(MB(1));
|
||||
ctx.cmd.text_input.data = Alloc!(u8)(1024);
|
||||
ctx.cmd.exec_cmd_input.data = Alloc!(u8)(1024);
|
||||
ctx.cmd.exec_cmd_arena = CreateArena(MB(1));
|
||||
@ -573,29 +490,118 @@ InitCtx(PlatformWindow* window)
|
||||
ctx.base_panel = CreatePanel();
|
||||
Focus(ctx.base_panel);
|
||||
|
||||
ScanCurrentDirectory(ctx);
|
||||
|
||||
ctx.directory_watcher = WatchDirectory(".", WT.Create|WT.Delete|WT.Moved);
|
||||
}
|
||||
|
||||
u8[]
|
||||
OpenFile(string file_name) nothrow @nogc
|
||||
{
|
||||
File* file;
|
||||
u8[] data;
|
||||
|
||||
file = FOpen(file_name.ptr, "rb");
|
||||
if(file)
|
||||
{
|
||||
FSeek(file, 0, SeekEnd);
|
||||
u64 size = FTell(file);
|
||||
FSeek(file, 0, SeekSet);
|
||||
|
||||
data = Alloc!(u8)(size);
|
||||
|
||||
FRead(data.ptr, 1, size, file);
|
||||
|
||||
FClose(file);
|
||||
}
|
||||
|
||||
return data;
|
||||
}
|
||||
|
||||
void
|
||||
ScanCurrentDirectory(ref Ctx ctx)
|
||||
{
|
||||
Reset(&ctx.file_name_arena);
|
||||
ctx.file_names = [];
|
||||
|
||||
if(getcwd() != "/")
|
||||
{
|
||||
string[] ignore_lines;
|
||||
u8[] ignore_file = OpenFile(".ignore");
|
||||
if(ignore_file.length)
|
||||
{
|
||||
u64 ignore_line_count = 1;
|
||||
for(u64 i = 0; i < ignore_file.length; i += 1)
|
||||
{
|
||||
if(ignore_file[i] == '\n')
|
||||
{
|
||||
ignore_line_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
ignore_lines = Alloc!(string)(&ctx.file_name_arena, ignore_line_count);
|
||||
|
||||
u64 current_count;
|
||||
u64 start;
|
||||
for(u64 i = 0; i < ignore_file.length; i += 1)
|
||||
{
|
||||
if(ignore_file[i] == '\n')
|
||||
{
|
||||
ignore_lines[current_count++] = Str(ignore_file[start .. i]);
|
||||
start = ++i;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// TODO: replace this with something nogc/nothrow
|
||||
try
|
||||
{
|
||||
u64 count = 0;
|
||||
foreach(DirEntry e; dirEntries(".", SpanMode.breadth))
|
||||
foreach(ref DirEntry e; dirEntries(".", SpanMode.breadth))
|
||||
{
|
||||
if(indexOf(e.name, ".git") != -1 || e.isDir) continue;
|
||||
if(e.isDir) continue;
|
||||
|
||||
u64 start = indexOf(e.name, "./") == 0 ? 2 : 0;
|
||||
count += 1;
|
||||
|
||||
bool ignored;
|
||||
foreach(ref ignore_line; ignore_lines)
|
||||
{
|
||||
if(ignore_line.length && StrContains!(true)(e.name[start .. $], ignore_line))
|
||||
{
|
||||
ignored = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ignored)
|
||||
{
|
||||
count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
ctx.file_names = Alloc!(string)(&ctx.arena, count);
|
||||
|
||||
count = 0;
|
||||
foreach(DirEntry e; dirEntries(".", SpanMode.breadth))
|
||||
foreach(ref DirEntry e; dirEntries(".", SpanMode.breadth))
|
||||
{
|
||||
if(indexOf(e.name, ".git") != -1 || e.isDir) continue;
|
||||
if(e.isDir) continue;
|
||||
|
||||
u64 start = indexOf(e.name, "./") == 0 ? 2 : 0;
|
||||
ctx.file_names[count++] = Alloc(&ctx.arena, e.name);
|
||||
u64 start = indexOf(e.name, "./") == 0 ? 2 : 0;
|
||||
|
||||
bool ignored;
|
||||
foreach(ref ignore_line; ignore_lines)
|
||||
{
|
||||
if(ignore_line.length && StrContains!(true)(e.name[start .. $], ignore_line))
|
||||
{
|
||||
ignored = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if(!ignored)
|
||||
{
|
||||
ctx.file_names[count++] = Alloc(&ctx.arena, e.name[start .. $]);
|
||||
}
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
|
||||
@ -34,7 +34,7 @@ void main(string[] argv)
|
||||
import vulkan;
|
||||
|
||||
u64 no_ev_count;
|
||||
while (true)
|
||||
while(true)
|
||||
{
|
||||
Inputs* inputs = GetEvents(&window);
|
||||
if(window.close)
|
||||
|
||||
@ -409,13 +409,9 @@ InitUI(ref Ctx ctx)
|
||||
}
|
||||
}
|
||||
|
||||
Arena arena = CreateArena(MB(4));
|
||||
|
||||
UIBuffer[FRAME_OVERLAP] buffers;
|
||||
|
||||
ctx.items = CreateHashTable!(UIHash, UIItem*)(12);
|
||||
ctx.arena = arena;
|
||||
ctx.temp_arena = CreateArena(MB(1));
|
||||
ctx.font = OpenFont(cast(u8[])FONT_BYTES);
|
||||
ctx.tab_width = 2;
|
||||
ctx.syntax_colors = [DEFAULT_COLORS, SYNTAX_COLORS];
|
||||
@ -1056,6 +1052,12 @@ SearchInputWindow(T)(string hash_text, SearchWindowCtx!(T)* window_ctx, bool rea
|
||||
}
|
||||
}
|
||||
|
||||
bool
|
||||
CmdClose(ref Ctx ctx)
|
||||
{
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
CmdSaveFile(ref Ctx ctx)
|
||||
{
|
||||
@ -1103,7 +1105,7 @@ CmdSaveFileWindow(ref Ctx ctx)
|
||||
f32 inner_x = x + PAD;
|
||||
f32 inner_y = y + PAD;
|
||||
|
||||
Rect window_rect = Rect(p0: Vec2(x, y), p1: Vec2(x+w, y+h));
|
||||
Rect window_rect = Rect(p0: Vec2(x, y), p1: Vec2(x+w, y+h));
|
||||
Rect inner_rect = Rect(p0: Vec2(inner_x, inner_y), p1: Vec2(inner_x+inner_w, inner_y+inner_h));
|
||||
|
||||
DrawRect(ctx, window_rect, &CMD_STYLE);
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user