can now open files through command palette
This commit is contained in:
parent
54619b52d3
commit
6905c73710
2
src/dlib
2
src/dlib
@ -1 +1 @@
|
||||
Subproject commit cadb2b5f853a22aa870dc1d986e73330c9136bb5
|
||||
Subproject commit 6e1952eab0ee2eed5c105311df56e603857798c2
|
||||
@ -48,21 +48,12 @@ CreateFlatBuffer(u8[] data)
|
||||
u8[] buf = MAllocArray!(u8)(capacity);
|
||||
buf[0 .. data.length] = data[0 .. data.length];
|
||||
|
||||
u64 lf_count = 0;
|
||||
for(u64 i = 0; i < cast(u64)data.length; i += 1)
|
||||
{
|
||||
if(data.ptr[i] == '\n')
|
||||
{
|
||||
lf_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
FlatBuffer fb = {
|
||||
arena: CreateArena(MB(1)),
|
||||
ls_arena: CreateArena(KB(512)),
|
||||
data: buf,
|
||||
length: cast(u64)data.length,
|
||||
lf_count: lf_count,
|
||||
lf_count: CountLF(data),
|
||||
};
|
||||
|
||||
fb.tk = CreateTokenizer(&fb);
|
||||
@ -72,6 +63,38 @@ CreateFlatBuffer(u8[] data)
|
||||
return fb;
|
||||
}
|
||||
|
||||
void
|
||||
Change(FlatBuffer* fb, u8[] data)
|
||||
{
|
||||
MFreeArray(fb.data);
|
||||
|
||||
u64 cap = data.length > 0 ? RoundUp(cast(u64)(data.length) * 2, KB(4)) : KB(4);
|
||||
|
||||
fb.data = MAllocArray!(u8)(cap);
|
||||
fb.data[0 .. data.length] = data[0 .. $];
|
||||
fb.length = data.length;
|
||||
fb.lf_count = CountLF(data);
|
||||
|
||||
Change(fb);
|
||||
|
||||
Fix(fb);
|
||||
}
|
||||
|
||||
u64
|
||||
CountLF(u8[] data)
|
||||
{
|
||||
u64 lf_count = 0;
|
||||
for(u64 i = 0; i < data.length; i += 1)
|
||||
{
|
||||
if(data.ptr[i] == '\n')
|
||||
{
|
||||
lf_count += 1;
|
||||
}
|
||||
}
|
||||
|
||||
return lf_count;
|
||||
}
|
||||
|
||||
void
|
||||
Fix(FlatBuffer* buffer)
|
||||
{
|
||||
@ -89,12 +112,12 @@ Fix(FlatBuffer* buffer)
|
||||
line_starts[ls_idx] = i+1;
|
||||
ls_idx += 1;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
dirty = false;
|
||||
|
||||
Tokenize(buffer);
|
||||
// TODO: fix
|
||||
//Tokenize(buffer);
|
||||
}
|
||||
}
|
||||
|
||||
@ -537,16 +560,23 @@ struct Tokenizer
|
||||
}
|
||||
|
||||
Tokenizer
|
||||
CreateTokenizer(FlatBuffer* buffer)
|
||||
CreateTokenizer(FlatBuffer* fb)
|
||||
{
|
||||
Tokenizer tokenizer = {
|
||||
arena: CreateArena(MB(8)),
|
||||
buffer: MAllocArray!(TS)(buffer.data.length),
|
||||
buffer: MAllocArray!(TS)(fb.data.length),
|
||||
};
|
||||
|
||||
return tokenizer;
|
||||
}
|
||||
|
||||
void
|
||||
Change(FlatBuffer* fb)
|
||||
{
|
||||
MFreeArray(fb.tk.buffer);
|
||||
fb.tk.buffer = MAllocArray!(TS)(fb.data.length);
|
||||
}
|
||||
|
||||
u8
|
||||
PeekNextChar(FlatBuffer* fb)
|
||||
{
|
||||
|
||||
@ -31,17 +31,20 @@ struct EditorCtx
|
||||
u32 icount;
|
||||
Timer timer;
|
||||
CmdPalette cmd;
|
||||
u8[][] file_names;
|
||||
}
|
||||
|
||||
struct CmdPalette
|
||||
{
|
||||
Arena arena;
|
||||
u8[] buffer;
|
||||
u32 icount;
|
||||
Command[] commands;
|
||||
u8[][] opt_strs;
|
||||
i64 selected;
|
||||
Command current;
|
||||
Arena arena;
|
||||
Arena cmd_arena;
|
||||
u8[] buffer;
|
||||
u32 icount;
|
||||
Command[] commands;
|
||||
u8[][] opt_strs;
|
||||
i64 selected;
|
||||
Command current;
|
||||
Parameter[] params;
|
||||
}
|
||||
|
||||
struct Editor
|
||||
@ -67,6 +70,12 @@ struct Command
|
||||
CmdType type;
|
||||
}
|
||||
|
||||
struct Parameter
|
||||
{
|
||||
u8[] value;
|
||||
bool visible;
|
||||
}
|
||||
|
||||
enum CmdType
|
||||
{
|
||||
None,
|
||||
@ -144,7 +153,8 @@ InitEditorCtx(PlatformWindow* window)
|
||||
EditorCtx ctx = {
|
||||
arena: CreateArena(MB(2)),
|
||||
cmd: {
|
||||
arena: CreateArena(KB(512)),
|
||||
arena: CreateArena(MB(1)),
|
||||
cmd_arena: CreateArena(MB(1)),
|
||||
buffer: MAllocArray!(u8)(1024),
|
||||
},
|
||||
};
|
||||
@ -154,6 +164,37 @@ InitEditorCtx(PlatformWindow* window)
|
||||
ctx.timer = CreateTimer();
|
||||
SetFocusedPanel(ctx.base_panel);
|
||||
|
||||
if(getcwd() != "/")
|
||||
{
|
||||
// TODO: replace this with something nogc/nothrow
|
||||
try
|
||||
{
|
||||
u64 count = 0;
|
||||
foreach(DirEntry e; dirEntries(".", SpanMode.breadth))
|
||||
{
|
||||
if(indexOf(e.name, ".git") != -1 || e.isDir) continue;
|
||||
|
||||
u64 start = indexOf(e.name, "./") == 0 ? 2 : 0;
|
||||
count += 1;
|
||||
}
|
||||
|
||||
ctx.file_names = AllocArray!(u8[])(&ctx.arena, count);
|
||||
|
||||
count = 0;
|
||||
foreach(DirEntry e; dirEntries(".", SpanMode.breadth))
|
||||
{
|
||||
if(indexOf(e.name, ".git") != -1 || e.isDir) continue;
|
||||
|
||||
u64 start = indexOf(e.name, "./") == 0 ? 2 : 0;
|
||||
ctx.file_names[count++] = AllocCopy!(u8)(&ctx.arena, CastStr!(u8)(e.name[start .. $]));
|
||||
}
|
||||
}
|
||||
catch(Exception e)
|
||||
{
|
||||
Logf("failed to open directory for filenames");
|
||||
}
|
||||
}
|
||||
|
||||
return ctx;
|
||||
}
|
||||
|
||||
@ -179,9 +220,35 @@ EditModeActive()
|
||||
}
|
||||
|
||||
void
|
||||
ScanFiles(EditorCtx* ctx)
|
||||
OpenFile(Editor* ed, u8[] file_name)
|
||||
{
|
||||
import core.stdc.stdio;
|
||||
|
||||
auto f = fopen(cast(char*)file_name.ptr, "rb");
|
||||
if(f != null)
|
||||
{
|
||||
Logf("opened");
|
||||
scope(exit) fclose(f);
|
||||
|
||||
fseek(f, 0, SEEK_END);
|
||||
i64 len = ftell(f);
|
||||
fseek(f, 0, SEEK_SET);
|
||||
|
||||
if(len > 0)
|
||||
{
|
||||
Logf("b");
|
||||
u8[] buf = ScratchAlloc!(u8)(len);
|
||||
Logf("a");
|
||||
fread(buf.ptr, u8.sizeof, len, f);
|
||||
Change(&ed.buf, buf);
|
||||
|
||||
Logf("read");
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
Logf("[Error] Unable to open file %s", cast(char[])file_name);
|
||||
}
|
||||
}
|
||||
|
||||
// Load all files then move things into editor after being created when selected
|
||||
@ -290,6 +357,18 @@ InsertInputToBuf(EditorCtx* ctx)
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
ResetCtx(EditorCtx* ctx)
|
||||
{
|
||||
InsertInputToBuf(ctx);
|
||||
|
||||
ctx.state = ES.NormalMode;
|
||||
ctx.cmd.icount = 0;
|
||||
ctx.cmd.commands = [];
|
||||
ctx.cmd.current = cast(Command)NO_CMD;
|
||||
ctx.cmd.selected = 0;
|
||||
}
|
||||
|
||||
void
|
||||
HandleInputs(EditorCtx* ctx, Inputs* inputs)
|
||||
{
|
||||
@ -304,10 +383,7 @@ HandleInputs(EditorCtx* ctx, Inputs* inputs)
|
||||
{
|
||||
if(key == Input.Escape)
|
||||
{
|
||||
ctx.state = ES.NormalMode;
|
||||
ctx.cmd.icount = 0;
|
||||
ctx.cmd.commands = [];
|
||||
InsertInputToBuf(ctx);
|
||||
ResetCtx(ctx);
|
||||
taken = true;
|
||||
}
|
||||
else if(ctx.state == ES.InputMode)
|
||||
@ -472,6 +548,52 @@ TextLineCharCases()
|
||||
return result;
|
||||
}
|
||||
|
||||
pragma(inline) u8
|
||||
Lower(u8 ch)
|
||||
{
|
||||
if(ch >= 65 && ch <= 90)
|
||||
{
|
||||
ch += 32;
|
||||
}
|
||||
|
||||
return ch;
|
||||
}
|
||||
|
||||
bool
|
||||
StrContains(bool begins_with)(const u8[] str, u8[] match)
|
||||
{
|
||||
return StrContains!(begins_with)(cast(u8[])str, match);
|
||||
}
|
||||
|
||||
bool
|
||||
StrContains(bool begins_with)(u8[] str, u8[] match)
|
||||
{
|
||||
u64 count;
|
||||
for(u64 i = 0; i < str.length; i += 1)
|
||||
{
|
||||
static if(begins_with) if(i >= match.length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
|
||||
if(Lower(str[i]) == Lower(match[count]))
|
||||
{
|
||||
count += 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
count = 0;
|
||||
}
|
||||
|
||||
static if(!begins_with) if(count == match.length)
|
||||
{
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return count == match.length;
|
||||
}
|
||||
|
||||
void
|
||||
GetCommands(CmdPalette* cmd)
|
||||
{
|
||||
@ -492,6 +614,7 @@ GetCommands(CmdPalette* cmd)
|
||||
|
||||
Reset(&cmd.arena);
|
||||
cmd.commands = AllocArray!(Command)(&cmd.arena, cmd_list.length);
|
||||
cmd.params = [];
|
||||
|
||||
u8[] str = cmd.buffer[0 .. cmd.icount];
|
||||
|
||||
@ -500,16 +623,7 @@ GetCommands(CmdPalette* cmd)
|
||||
{
|
||||
for(u64 i = 0; i < cmd_list.length; i += 1)
|
||||
{
|
||||
u64 match = 0;
|
||||
for(u64 j = 0; j < str.length && j < cmd_list[i].name.length; j += 1)
|
||||
{
|
||||
if(str[j] == cmd_list[i].name[j] || (str[j]-32) == cmd_list[i].name[j])
|
||||
{
|
||||
match += 1;
|
||||
}
|
||||
}
|
||||
|
||||
if(match == str.length)
|
||||
if(StrContains!(true)(cmd_list[i].name, str))
|
||||
{
|
||||
cmd.commands[count] = cast(Command)cmd_list[i];
|
||||
count += 1;
|
||||
@ -543,7 +657,28 @@ HandleCmdMode(EditorCtx* ctx, InputEvent ev)
|
||||
u64 prev_count = cmd.icount;
|
||||
switch(ev.key) with(Input)
|
||||
{
|
||||
mixin(TextLineCharCases());
|
||||
case Enter:
|
||||
{
|
||||
if(cmd.current.type == CT.None)
|
||||
{
|
||||
goto case Tab;
|
||||
}
|
||||
|
||||
switch(cmd.current.type)
|
||||
{
|
||||
case CT.OpenFile:
|
||||
{
|
||||
UIPanel* p = GetFocusedPanel();
|
||||
if(!Nil(p) && cmd.selected >= 0 && cmd.selected < cmd.opt_strs.length)
|
||||
{
|
||||
OpenFile(p.ed, cmd.opt_strs[cmd.selected]);
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
|
||||
ResetCtx(ctx);
|
||||
} goto CmdInputEnd;
|
||||
case Backspace:
|
||||
{
|
||||
if(cmd.icount > 0)
|
||||
@ -580,11 +715,12 @@ HandleCmdMode(EditorCtx* ctx, InputEvent ev)
|
||||
} break;
|
||||
case Down:
|
||||
{
|
||||
if(cmd.selected < cmd.commands.length)
|
||||
if(cmd.selected < cmd.opt_strs.length)
|
||||
{
|
||||
cmd.selected += 1;
|
||||
}
|
||||
} break;
|
||||
mixin(TextLineCharCases());
|
||||
default: break;
|
||||
}
|
||||
|
||||
@ -594,13 +730,69 @@ HandleCmdMode(EditorCtx* ctx, InputEvent ev)
|
||||
cmd.buffer[cmd.icount++] = result;
|
||||
}
|
||||
|
||||
if(cmd.commands.length == 0 || prev_count != cmd.icount)
|
||||
if(cmd.current.type == CT.None && (cmd.commands.length == 0 || prev_count != cmd.icount))
|
||||
{
|
||||
GetCommands(cmd);
|
||||
cmd.selected = 0;
|
||||
|
||||
Logf("%s", cmd.current.type);
|
||||
}
|
||||
else if(prev_count != cmd.icount)
|
||||
{
|
||||
u64 start = cmd.current.name.length;
|
||||
bool has_param;
|
||||
for(u64 i = start; i < cmd.icount; i += 1)
|
||||
{
|
||||
if(cmd.buffer[i] != ' ')
|
||||
{
|
||||
start = i;
|
||||
has_param = true;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
u8[] param = cmd.buffer[start .. cmd.icount];
|
||||
|
||||
switch(cmd.current.type) with(CT)
|
||||
{
|
||||
case OpenFile:
|
||||
{
|
||||
if(cmd.params.length == 0 || !has_param)
|
||||
{
|
||||
cmd.params = AllocArray!(Parameter)(&cmd.cmd_arena, ctx.file_names.length);
|
||||
cmd.opt_strs = AllocArray!(u8[])(&cmd.cmd_arena, ctx.file_names.length);
|
||||
|
||||
for(u64 i = 0; i < cmd.params.length; i += 1)
|
||||
{
|
||||
cmd.params[i].value = ctx.file_names[i];
|
||||
cmd.params[i].visible = true;
|
||||
cmd.opt_strs[i] = cmd.params[i].value;
|
||||
}
|
||||
}
|
||||
|
||||
if(has_param)
|
||||
{
|
||||
cmd.opt_strs = AllocArray!(u8[])(&cmd.cmd_arena, ctx.file_names.length);
|
||||
|
||||
u64 matches;
|
||||
for(u64 i = 0; i < cmd.params.length; i += 1)
|
||||
{
|
||||
bool contains = StrContains!(false)(cmd.params[i].value, param);
|
||||
if(contains)
|
||||
{
|
||||
cmd.opt_strs[matches] = cmd.params[i].value;
|
||||
matches += 1;
|
||||
}
|
||||
|
||||
cmd.params[i].visible = contains;
|
||||
}
|
||||
|
||||
cmd.opt_strs = cmd.opt_strs[0 .. matches];
|
||||
}
|
||||
} break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
|
||||
CmdInputEnd:
|
||||
|
||||
return taken;
|
||||
}
|
||||
|
||||
@ -11,47 +11,23 @@ import core.stdc.math : fabsf;
|
||||
import std.conv;
|
||||
import core.stdc.stdio : sprintf;
|
||||
|
||||
const Vec4[4] DEFAULT_COL = [
|
||||
Vec4(0.13, 0.13, 0.13, 1.0),
|
||||
Vec4(0.13, 0.13, 0.13, 1.0),
|
||||
Vec4(0.13, 0.13, 0.13, 1.0),
|
||||
Vec4(0.13, 0.13, 0.13, 1.0),
|
||||
];
|
||||
const Vec4[4] DEFAULT_COL = Vec4(0.13, 0.13, 0.13, 1.0);
|
||||
|
||||
const Vec4[4] CMD_PALETTE_COL = [
|
||||
Vec4(0.21, 0.21, 0.21, 1.0),
|
||||
Vec4(0.21, 0.21, 0.21, 1.0),
|
||||
Vec4(0.21, 0.21, 0.21, 1.0),
|
||||
Vec4(0.21, 0.21, 0.21, 1.0),
|
||||
];
|
||||
const Vec4[4] CMD_PALETTE_COL = Vec4(0.21, 0.21, 0.21, 1.0);
|
||||
|
||||
const Vec4[4] DEFAULT_BORDER_COL = [
|
||||
Vec4(0.254, 0.254, 0.266, 1.0),
|
||||
Vec4(0.254, 0.254, 0.266, 1.0),
|
||||
Vec4(0.254, 0.254, 0.266, 1.0),
|
||||
Vec4(0.254, 0.254, 0.266, 1.0),
|
||||
];
|
||||
const Vec4[4] DEFAULT_BORDER_COL = Vec4(0.254, 0.254, 0.266, 1.0);
|
||||
|
||||
const Vec4[4] HL_BORDER_COL = [
|
||||
Vec4(0.035, 0.549, 0.824, 1.0),
|
||||
Vec4(0.035, 0.549, 0.824, 1.0),
|
||||
Vec4(0.035, 0.549, 0.824, 1.0),
|
||||
Vec4(0.035, 0.549, 0.824, 1.0),
|
||||
];
|
||||
const Vec4[4] HL_BORDER_COL = Vec4(0.035, 0.549, 0.824, 1.0);
|
||||
|
||||
const Vec4[4] LC_COLOR = [
|
||||
Vec4(0.12, 0.12, 0.12, 1.0),
|
||||
Vec4(0.12, 0.12, 0.12, 1.0),
|
||||
Vec4(0.12, 0.12, 0.12, 1.0),
|
||||
Vec4(0.12, 0.12, 0.12, 1.0),
|
||||
];
|
||||
const Vec4[4] LC_COLOR = Vec4(0.12, 0.12, 0.12, 1.0);
|
||||
|
||||
const Vec4[4] LC_HL_COLOR = [
|
||||
Vec4(0.012, 0.176, 0.29, 1.0),
|
||||
Vec4(0.012, 0.176, 0.29, 1.0),
|
||||
Vec4(0.012, 0.176, 0.29, 1.0),
|
||||
Vec4(0.012, 0.176, 0.29, 1.0),
|
||||
];
|
||||
const Vec4[4] LC_HL_COLOR = Vec4(0.012, 0.176, 0.29, 1.0);
|
||||
|
||||
const Vec4[4] CMD_PALETTE_INPUT_HL = Vec4(0.24, 0.45, 0.81, 1.0);
|
||||
|
||||
const Vec4[4] CMD_INPUT_BORDER_COL = Vec4(0.003, 0.48, 0.68, 1.0);
|
||||
|
||||
const Vec4[4] CMD_INPUT_BORDER_HL = Vec4(0.05, 0.56, 0.76, 1.0);
|
||||
|
||||
const Vec4[4] CMD_PALETTE_INPUT_COL = [
|
||||
Vec4(0.14, 0.14, 0.14, 1.0),
|
||||
@ -60,29 +36,6 @@ const Vec4[4] CMD_PALETTE_INPUT_COL = [
|
||||
Vec4(0.17, 0.17, 0.17, 1.0),
|
||||
];
|
||||
|
||||
const Vec4[4] CMD_PALETTE_INPUT_HL = [
|
||||
Vec4(0.24, 0.45, 0.81, 1.0),
|
||||
Vec4(0.24, 0.45, 0.81, 1.0),
|
||||
Vec4(0.24, 0.45, 0.81, 1.0),
|
||||
Vec4(0.24, 0.45, 0.81, 1.0),
|
||||
];
|
||||
|
||||
const Vec4[4] CMD_INPUT_BORDER_COL = [
|
||||
Vec4(0.003, 0.48, 0.68, 1.0),
|
||||
Vec4(0.003, 0.48, 0.68, 1.0),
|
||||
Vec4(0.003, 0.48, 0.68, 1.0),
|
||||
Vec4(0.003, 0.48, 0.68, 1.0),
|
||||
];
|
||||
|
||||
const Vec4[4] CMD_INPUT_BORDER_HL = [
|
||||
Vec4(0.05, 0.56, 0.76, 1.0),
|
||||
Vec4(0.05, 0.56, 0.76, 1.0),
|
||||
Vec4(0.05, 0.56, 0.76, 1.0),
|
||||
Vec4(0.05, 0.56, 0.76, 1.0),
|
||||
];
|
||||
|
||||
// 9, 141, 211
|
||||
|
||||
const UIPanel g_ui_nil_panel;
|
||||
UIPanel* g_UI_NIL_PANEL;
|
||||
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user