more cleaning up
This commit is contained in:
parent
5261118dd0
commit
d3abcbc146
2
src/dlib
2
src/dlib
@ -1 +1 @@
|
|||||||
Subproject commit f3d1f551ccfa37de73d626479252bada0fc17cb2
|
Subproject commit a12e8c21e21b65e16af06675b6c2d1696e23bfa7
|
||||||
@ -8,23 +8,75 @@ import std.math.algebraic : abs;
|
|||||||
import editor;
|
import editor;
|
||||||
import buffer : Reset;
|
import buffer : Reset;
|
||||||
|
|
||||||
|
enum BufferFlags
|
||||||
|
{
|
||||||
|
None = 0x0000,
|
||||||
|
NoFile = 0x0001,
|
||||||
|
Modified = 0x0002,
|
||||||
|
Fixed = 0x0004,
|
||||||
|
} alias BFRF = BufferFlags;
|
||||||
|
|
||||||
struct FlatBuffer
|
struct FlatBuffer
|
||||||
{
|
{
|
||||||
Tokenizer tokenizer;
|
Tokenizer tokenizer;
|
||||||
Arena arena;
|
Arena arena;
|
||||||
Arena line_start_arena;
|
Arena line_start_arena;
|
||||||
LineBuffers linebufs;
|
LineBuffers linebufs;
|
||||||
|
|
||||||
string file_name;
|
string file_name;
|
||||||
u8[] data;
|
u8[] data;
|
||||||
u64 length;
|
u64 length;
|
||||||
|
|
||||||
Line[] lines;
|
Line[] lines;
|
||||||
u64 line_count;
|
u64 line_count;
|
||||||
|
|
||||||
bool fixed;
|
BufferFlags flags;
|
||||||
bool changed;
|
FlatBuffer* list_next;
|
||||||
FlatBuffer* list_next;
|
|
||||||
|
void
|
||||||
|
FreeBuffer()
|
||||||
|
{
|
||||||
|
Free(this.data);
|
||||||
|
Free(&this.arena);
|
||||||
|
Free(&this.line_start_arena);
|
||||||
|
Free(cast(char*)this.file_name.ptr);
|
||||||
|
|
||||||
|
Free(&this.linebufs.arena);
|
||||||
|
|
||||||
|
Free(this.tokenizer.tokens);
|
||||||
|
Free(&this.tokenizer.arena);
|
||||||
|
|
||||||
|
memset(&this, 0, FlatBuffer.sizeof);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
Overwrite(FlatBuffer* src)
|
||||||
|
{
|
||||||
|
string file_name = ScratchAlloc(this.file_name);
|
||||||
|
|
||||||
|
this.FreeBuffer();
|
||||||
|
this.LoadBuffer(src.data, file_name);
|
||||||
|
}
|
||||||
|
|
||||||
|
void
|
||||||
|
LoadBuffer(u8[] data, string file_name)
|
||||||
|
{
|
||||||
|
u64 capacity = data.length > 0 ? RoundUp(cast(u64)(data.length)*2, KB(4)) : KB(4);
|
||||||
|
u8[] buffer = Alloc!(u8)(capacity);
|
||||||
|
|
||||||
|
MemCpy(buffer.ptr, data.ptr, data.length);
|
||||||
|
|
||||||
|
this.arena = CreateArena(MB(1));
|
||||||
|
this.line_start_arena = CreateArena(KB(512));
|
||||||
|
this.file_name = file_name;
|
||||||
|
this.line_count = CountLF(data);
|
||||||
|
this.length = data.length;
|
||||||
|
this.linebufs = CreateLineBuffers(MB(1));
|
||||||
|
this.data = buffer;
|
||||||
|
this.tokenizer = CreateTokenizer(&this);
|
||||||
|
|
||||||
|
Fix(&this);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
struct BufferViewInfo
|
struct BufferViewInfo
|
||||||
@ -116,32 +168,20 @@ const u64 BUF_START = 1;
|
|||||||
FlatBuffer*
|
FlatBuffer*
|
||||||
CreateFlatBuffer(ref Ctx ctx, u8[] data = [], string file_name = "")
|
CreateFlatBuffer(ref Ctx ctx, u8[] data = [], string file_name = "")
|
||||||
{
|
{
|
||||||
if(ctx.text_buffer_count == ctx.text_buffers.length)
|
FlatBuffer* buffer = ctx.free_text_buffers;
|
||||||
|
if(!buffer)
|
||||||
{
|
{
|
||||||
ctx.text_buffers = Realloc(ctx.text_buffers, ctx.text_buffers.length+ARRAY_COUNT_INCREMENT);
|
if(ctx.text_buffer_count == ctx.text_buffers.length)
|
||||||
|
{
|
||||||
|
ctx.text_buffers = Realloc(ctx.text_buffers, ctx.text_buffers.length+ARRAY_COUNT_INCREMENT);
|
||||||
|
}
|
||||||
|
|
||||||
|
buffer = &ctx.text_buffers[ctx.text_buffer_count++];
|
||||||
}
|
}
|
||||||
|
|
||||||
FlatBuffer* fb = &ctx.text_buffers[ctx.text_buffer_count++];
|
buffer.LoadBuffer(data, file_name);
|
||||||
|
|
||||||
fb.arena = CreateArena(MB(1));
|
return buffer;
|
||||||
fb.line_start_arena = CreateArena(KB(512));
|
|
||||||
|
|
||||||
u64 capacity = data.length > 0 ? RoundUp(cast(u64)(data.length)*2, KB(4)) : KB(4);
|
|
||||||
|
|
||||||
u8[] buffer = Alloc!(u8)(capacity);
|
|
||||||
|
|
||||||
MemCpy(buffer.ptr, data.ptr, data.length);
|
|
||||||
|
|
||||||
fb.file_name = file_name;
|
|
||||||
fb.line_count = CountLF(data);
|
|
||||||
fb.length = data.length;
|
|
||||||
fb.linebufs = CreateLineBuffers(MB(1));
|
|
||||||
fb.data = buffer;
|
|
||||||
fb.tokenizer = CreateTokenizer(fb);
|
|
||||||
|
|
||||||
Fix(fb);
|
|
||||||
|
|
||||||
return fb;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
void
|
||||||
@ -216,31 +256,19 @@ ResetViewInfo(BufferViewInfo* info)
|
|||||||
info.selection_mode = SM.None;
|
info.selection_mode = SM.None;
|
||||||
info.pos = 0;
|
info.pos = 0;
|
||||||
info.column_position = 0;
|
info.column_position = 0;
|
||||||
|
info.line_offset = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
|
||||||
void
|
|
||||||
Change(FlatBuffer* fb, u8[] data, string file_name)
|
|
||||||
{
|
|
||||||
Free(fb.data);
|
|
||||||
Reset(&fb.linebufs.arena);
|
|
||||||
|
|
||||||
Init(fb, data, file_name);
|
|
||||||
ResetTokenizer(&fb.tk, fb.data.length);
|
|
||||||
Fix(fb);
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
|
|
||||||
u64
|
u64
|
||||||
CountLF(u8[] data)
|
CountLF(u8[] data)
|
||||||
{
|
{
|
||||||
u64 lf_count = 1;
|
u64 line_feed_count = 1;
|
||||||
for(u64 i = 0; i < data.length; i += 1)
|
for(u64 i = 0; i < data.length; i += 1)
|
||||||
{
|
{
|
||||||
lf_count += u64(data.ptr[i] == '\n');
|
line_feed_count += u64(data.ptr[i] == '\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
return lf_count;
|
return line_feed_count;
|
||||||
}
|
}
|
||||||
|
|
||||||
pragma(inline, true) bool
|
pragma(inline, true) bool
|
||||||
@ -330,7 +358,7 @@ Fix(T)(T* buffer)
|
|||||||
|
|
||||||
buffer.lines[buffer.line_count-1].length = buffer.length - buffer.lines[buffer.line_count-1].pos;
|
buffer.lines[buffer.line_count-1].length = buffer.length - buffer.lines[buffer.line_count-1].pos;
|
||||||
|
|
||||||
buffer.fixed = true;
|
buffer.flags &= BFRF.Fixed;
|
||||||
|
|
||||||
TokenizeD(buffer);
|
TokenizeD(buffer);
|
||||||
}
|
}
|
||||||
@ -344,7 +372,7 @@ CreateLineBuffers(u64 arena_size)
|
|||||||
void
|
void
|
||||||
Insert(Editor* editor, u8[] insert, u64 length, u64 insert_position)
|
Insert(Editor* editor, u8[] insert, u64 length, u64 insert_position)
|
||||||
{
|
{
|
||||||
editor.changed = true;
|
editor.flags &= BFRF.Modified;
|
||||||
|
|
||||||
if(editor.length + length > editor.data.length-SPACING)
|
if(editor.length + length > editor.data.length-SPACING)
|
||||||
{
|
{
|
||||||
|
|||||||
@ -15,7 +15,9 @@ import std.stdio;
|
|||||||
import std.exception;
|
import std.exception;
|
||||||
import std.file;
|
import std.file;
|
||||||
import std.string;
|
import std.string;
|
||||||
import core.stdc.stdio;
|
import core.stdc.stdio : File = FILE, FOpen = fopen, FFlush = fflush, FWrite = fwrite, FSeek = fseek, FTell = ftell, FClose = fclose, FRead = fread, SeekSet = SEEK_SET, SeekEnd = SEEK_END;
|
||||||
|
|
||||||
|
// TODO: add function for moving data within text buffer using SIMD and moving in batches that fit within CPU cache
|
||||||
|
|
||||||
const u64 ARRAY_COUNT_INCREMENT = 32;
|
const u64 ARRAY_COUNT_INCREMENT = 32;
|
||||||
|
|
||||||
@ -101,8 +103,9 @@ struct Ctx
|
|||||||
FlatBuffer[] text_buffers;
|
FlatBuffer[] text_buffers;
|
||||||
u64 text_buffer_count;
|
u64 text_buffer_count;
|
||||||
FlatBuffer* free_text_buffers;
|
FlatBuffer* free_text_buffers;
|
||||||
|
u64 new_buffer_count; // files that are not yet files (you know)
|
||||||
|
|
||||||
@property ref DescSet desc_set() => this.rd_ctx.desc_sets[this.frame_index];
|
@property ref DescSet desc_set() => this.rd_ctx.desc_sets[this.frame_index];
|
||||||
|
|
||||||
debug bool dbg;
|
debug bool dbg;
|
||||||
|
|
||||||
@ -257,7 +260,7 @@ const Command NO_CMD = {
|
|||||||
type: CT.None,
|
type: CT.None,
|
||||||
};
|
};
|
||||||
|
|
||||||
Command[21] CMD_LIST = [
|
Command[22] CMD_LIST = [
|
||||||
{
|
{
|
||||||
name: "Open",
|
name: "Open",
|
||||||
cmd: "open",
|
cmd: "open",
|
||||||
@ -268,14 +271,21 @@ Command[21] CMD_LIST = [
|
|||||||
{
|
{
|
||||||
name: "Save",
|
name: "Save",
|
||||||
cmd: "save",
|
cmd: "save",
|
||||||
desc: "Save the current file in the focused editor view.",
|
desc: "Save the current file.",
|
||||||
type: CT.Callback,
|
type: CT.Callback,
|
||||||
fn: &SaveFileWindow,
|
fn: &CmdSaveFile,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "Save As",
|
||||||
|
cmd: "save as",
|
||||||
|
desc: "Save the current file as a specified name.",
|
||||||
|
type: CT.Callback,
|
||||||
|
fn: &CmdSaveFileWindow,
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
name: "New File",
|
name: "New File",
|
||||||
cmd: "new file",
|
cmd: "new file",
|
||||||
desc: "Create a new file with a specified name and location.",
|
desc: "Open an empty buffer",
|
||||||
type: CT.Callback,
|
type: CT.Callback,
|
||||||
fn: &NotImplementedCallback,
|
fn: &NotImplementedCallback,
|
||||||
},
|
},
|
||||||
@ -595,53 +605,54 @@ InitCtx(PlatformWindow* window)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void
|
bool
|
||||||
SaveFile(Editor* ed, string file_name)
|
SaveBufferToFile(Editor* editor)
|
||||||
{
|
{
|
||||||
import core.stdc.stdio;
|
bool saved;
|
||||||
|
|
||||||
file_name = file_name.length == 0 ? Str(ed.file_name) : file_name;
|
assert(editor.buffer);
|
||||||
|
assert(editor.file_name.length);
|
||||||
|
|
||||||
if(file_name.length > 0)
|
auto f = FOpen(editor.file_name.ptr, "wb");
|
||||||
|
if(f != null)
|
||||||
{
|
{
|
||||||
string file_path = AbsolutePath(file_name);
|
u64 tab_count;
|
||||||
auto f = fopen(cast(char*)file_path.ptr, "wb");
|
for(u64 i = 0; i < editor.length; i += 1)
|
||||||
if(f != null)
|
|
||||||
{
|
{
|
||||||
u64 tab_count;
|
if(editor.data[i] == '\t')
|
||||||
for(u64 i = 0; i < ed.length; i += 1)
|
|
||||||
{
|
{
|
||||||
if(ed.data[i] == '\t')
|
tab_count += 1;
|
||||||
{
|
|
||||||
tab_count += 1;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
u64 tab_width = GetCtx().tab_width;
|
|
||||||
u64 buf_size = ed.length + ((tab_width-1) * tab_count);
|
|
||||||
u8[] temp_buf = ScratchAlloc!(u8)(buf_size);
|
|
||||||
|
|
||||||
u64 buf_pos;
|
|
||||||
for(u64 i = 0; i < ed.length; i += 1)
|
|
||||||
{
|
|
||||||
if(ed.data[i] == '\t')
|
|
||||||
{
|
|
||||||
for(u64 j = 0; j < tab_width; j += 1)
|
|
||||||
{
|
|
||||||
temp_buf[buf_pos++] = ' ';
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
temp_buf[buf_pos++] = ed.data[i];
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fwrite(temp_buf.ptr, 1, buf_size, f);
|
|
||||||
fflush(f);
|
|
||||||
fclose(f);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
u64 tab_width = GetCtx().tab_width;
|
||||||
|
u64 buffer_size = editor.length + ((tab_width-1) * tab_count);
|
||||||
|
u8[] temp_buf = ScratchAlloc!(u8)(buffer_size);
|
||||||
|
|
||||||
|
u64 buf_pos;
|
||||||
|
for(u64 i = 0; i < editor.length; i += 1)
|
||||||
|
{
|
||||||
|
if(editor.data[i] == '\t')
|
||||||
|
{
|
||||||
|
for(u64 j = 0; j < tab_width; j += 1)
|
||||||
|
{
|
||||||
|
temp_buf[buf_pos++] = ' ';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
temp_buf[buf_pos++] = editor.data[i];
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
FWrite(temp_buf.ptr, 1, buffer_size, f);
|
||||||
|
FFlush(f);
|
||||||
|
FClose(f);
|
||||||
|
|
||||||
|
saved = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
return saved;
|
||||||
}
|
}
|
||||||
|
|
||||||
string
|
string
|
||||||
|
|||||||
102
src/editor/ui.d
102
src/editor/ui.d
@ -335,6 +335,14 @@ struct Rect
|
|||||||
};
|
};
|
||||||
};
|
};
|
||||||
|
|
||||||
|
this(Vec2 p0, Vec2 p1)
|
||||||
|
{
|
||||||
|
this.v[0].x = p0.x;
|
||||||
|
this.v[0].y = p0.y;
|
||||||
|
this.v[1].x = p1.x;
|
||||||
|
this.v[1].y = p1.y;
|
||||||
|
}
|
||||||
|
|
||||||
ref Vec2 opIndex(usize index)
|
ref Vec2 opIndex(usize index)
|
||||||
{
|
{
|
||||||
return this.v[index];
|
return this.v[index];
|
||||||
@ -344,8 +352,28 @@ struct Rect
|
|||||||
{
|
{
|
||||||
return this.v[index] = value;
|
return this.v[index] = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rect opBinary(string op)(Rect rhs)
|
||||||
|
if(op == "*" || op == "+" || op == "-" || op == "+" || op == "/")
|
||||||
|
{
|
||||||
|
Rect result;
|
||||||
|
static foreach(i; 0 .. this.v.length)
|
||||||
|
{
|
||||||
|
mixin("result.v[", i, "].x = this.v[", i, "].x"~op~"rhs.v[", i, "].x;");
|
||||||
|
mixin("result.v[", i, "].y = this.v[", i, "].y"~op~"rhs.v[", i, "].y;");
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Rect RectX0(f32 value) => Rect(Vec2(value, 0.0), Vec2(0.0, 0.0));
|
||||||
|
Rect RectY0(f32 value) => Rect(Vec2(0.0, value), Vec2(0.0, 0.0));
|
||||||
|
Rect RectX1(f32 value) => Rect(Vec2(0.0, 0.0), Vec2(value, 0.0));
|
||||||
|
Rect RectY1(f32 value) => Rect(Vec2(0.0, 0.0), Vec2(0.0, value));
|
||||||
|
Rect RectXY0(f32 x, f32 y) => Rect(Vec2(x, y), Vec2(0.0, 0.0));
|
||||||
|
Rect RectXY1(f32 x, f32 y) => Rect(Vec2(0.0, 0.0), Vec2(x, y));
|
||||||
|
|
||||||
alias UIHash = u64;
|
alias UIHash = u64;
|
||||||
|
|
||||||
alias UIPair = KVPair!(UIHash, UIItem*);
|
alias UIPair = KVPair!(UIHash, UIItem*);
|
||||||
@ -1029,24 +1057,40 @@ SearchInputWindow(T)(string hash_text, SearchWindowCtx!(T)* window_ctx, bool rea
|
|||||||
}
|
}
|
||||||
|
|
||||||
bool
|
bool
|
||||||
SaveFileWindow(ref Ctx ctx)
|
CmdSaveFile(ref Ctx ctx)
|
||||||
|
{
|
||||||
|
bool result = true;
|
||||||
|
Editor* editor = ctx.focused_panel.ed;
|
||||||
|
if(editor.file_name.length)
|
||||||
|
{
|
||||||
|
SaveBufferToFile(editor);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
result = CmdSaveFileWindow(ctx);
|
||||||
|
}
|
||||||
|
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool
|
||||||
|
CmdSaveFileWindow(ref Ctx ctx)
|
||||||
{
|
{
|
||||||
bool exit;
|
bool exit;
|
||||||
Editor* ed = ctx.focused_panel.ed;
|
Editor* editor = ctx.focused_panel.ed;
|
||||||
|
|
||||||
static bool init = false;
|
static bool init = false;
|
||||||
if(!init)
|
if(!init)
|
||||||
{
|
{
|
||||||
ctx.cmd.exec_cmd_input.data[0 .. ed.file_name.length] = Arr!(u8)(ed.file_name[0 .. $]);
|
ctx.cmd.exec_cmd_input.data[0 .. editor.file_name.length] = Arr!(u8)(editor.file_name[0 .. $]);
|
||||||
ctx.cmd.exec_cmd_input.length = ed.file_name.length;
|
ctx.cmd.exec_cmd_input.length = editor.file_name.length;
|
||||||
}
|
}
|
||||||
|
|
||||||
const PAD = 4.0f;
|
const PAD = 4.0f;
|
||||||
|
|
||||||
Vec2 extent = GetExtent();
|
Vec2 extent = GetExtent();
|
||||||
|
|
||||||
// TODO: fix: This breaks when setting GetFontSet input to not 12, probably incorrect draw call boundaries (again)
|
FontSet* fs = GetFontSet(14);
|
||||||
FontSet* fs = GetFontSet(12);
|
|
||||||
|
|
||||||
f32 x = extent.x * 0.1;
|
f32 x = extent.x * 0.1;
|
||||||
f32 w = extent.x * 0.8;
|
f32 w = extent.x * 0.8;
|
||||||
@ -1072,8 +1116,7 @@ SaveFileWindow(ref Ctx ctx)
|
|||||||
|
|
||||||
DrawRect(ctx, inner_rect, &CMD_STYLE);
|
DrawRect(ctx, inner_rect, &CMD_STYLE);
|
||||||
|
|
||||||
Rect text_rect = inner_rect;
|
Rect text_rect = inner_rect + RectX0(PAD);
|
||||||
text_rect.p0.x += PAD;
|
|
||||||
DrawText(ctx, Str(ctx.cmd.exec_cmd_input), WHITE, fs, text_rect, TA.Left, -1);
|
DrawText(ctx, Str(ctx.cmd.exec_cmd_input), WHITE, fs, text_rect, TA.Left, -1);
|
||||||
|
|
||||||
DrawBorder(ctx, inner_rect, &CMD_STYLE);
|
DrawBorder(ctx, inner_rect, &CMD_STYLE);
|
||||||
@ -1085,15 +1128,44 @@ SaveFileWindow(ref Ctx ctx)
|
|||||||
{
|
{
|
||||||
switch(ev.key) with(Input)
|
switch(ev.key) with(Input)
|
||||||
{
|
{
|
||||||
case Enter:
|
case Enter:
|
||||||
{
|
{
|
||||||
SaveFile(ed, Str(ctx.cmd.exec_cmd_input));
|
if(!ctx.cmd.exec_cmd_input.length) break;
|
||||||
|
|
||||||
|
// TODO: continue here, create new flat buffer then put in new save function
|
||||||
|
|
||||||
|
string file_name = AbsolutePath(Str(ctx.cmd.exec_cmd_input));
|
||||||
|
if(file_name != editor.file_name)
|
||||||
|
{
|
||||||
|
bool found;
|
||||||
|
foreach(i; 0 .. ctx.text_buffer_count)
|
||||||
|
{
|
||||||
|
if(file_name == ctx.text_buffers[i].file_name)
|
||||||
|
{
|
||||||
|
ctx.text_buffers[i].Overwrite(editor.buffer);
|
||||||
|
editor.buffer = &ctx.text_buffers[i];
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(!found)
|
||||||
|
{
|
||||||
|
editor.buffer = CreateFlatBuffer(ctx, editor.buffer.data, file_name);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(SaveBufferToFile(editor))
|
||||||
|
{
|
||||||
|
editor.flags &= ~(BFRF.Modified & BFRF.NoFile);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// TODO: show error..
|
||||||
|
}
|
||||||
} goto case;
|
} goto case;
|
||||||
case Escape:
|
case Escape: exit = taken = true; break;
|
||||||
{
|
default: taken = HandleTextInput(&ctx.cmd.exec_cmd_input, ev); break;
|
||||||
exit = taken = true;
|
|
||||||
} break;
|
|
||||||
default: taken = HandleTextInput(&ctx.cmd.exec_cmd_input, ev); break;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user