diff --git a/src/text_editor/config.cpp b/src/text_editor/config.cpp index 833abc0..c3d8363 100644 --- a/src/text_editor/config.cpp +++ b/src/text_editor/config.cpp @@ -1,12 +1,3 @@ -struct Lexer { - Allocator allocator; - char *at; - char *start; - char *end; - char *name; - Int line, column; -}; - enum TriggerKind { TriggerKind_Error, TriggerKind_Key, @@ -34,40 +25,7 @@ struct CachedTrigger { }; Array CachedTriggers; -Lexer MakeLexer(Allocator allocator, String string, char *file, Int line, Int column) { - Lexer lexer = {allocator, string.data, string.data, string.data + string.len, file, line, column}; - return lexer; -} - -void Advance(Lexer *lex) { - if (lex->at < lex->end) { - if (lex->at[0] == '\n') { - lex->line += 1; - lex->column = 0; - } else { - lex->column += 1; - } - lex->at += 1; - } -} - -void Advance(Lexer *lex, int n) { - for (int i = 0; i < n; i += 1) Advance(lex); -} - -char At(Lexer *lex) { - if (lex->at < lex->end) { - return lex->at[0]; - } - return 0; -} - -String AsString(Lexer *lex) { - String result = {lex->at, lex->end - lex->at}; - return result; -} - -void EatWhitespace(Lexer *lex) { +void EatWhitespaceEx(Lexer *lex) { while (At(lex) != '\n' && IsWhitespace(At(lex))) { Advance(lex); } @@ -85,7 +43,7 @@ Trigger *TriggerBinary(Lexer *lex, Trigger *left, Trigger *right, int key) { Trigger *ParseKeyAtom(Lexer *lex) { Trigger *result = AllocType(lex->allocator, Trigger); result->kind = TriggerKind_Key; - EatWhitespace(lex); + EatWhitespaceEx(lex); for (;;) { String lex_string = AsString(lex); if (StartsWith(lex_string, "ctrl")) { @@ -123,12 +81,12 @@ Trigger *ParseKeyAtom(Lexer *lex) { if (!found) { result->kind = TriggerKind_Error; - ReportErrorf("%s:%d:%d: Failed to parse key trigger, unexpected identifier: '%d'", lex->name, lex->line, lex->column, result->key); + ReportErrorf("%s:%d:%d: Failed to parse key trigger, unexpected identifier: '%d'", lex->file, lex->line, lex->column, result->key); return result; } } else { result->kind = TriggerKind_Error; - ReportErrorf("%s:%d:%d: Failed to parse key trigger, unexpected character: '%c'", lex->name, lex->line, lex->column, At(lex)); + ReportErrorf("%s:%d:%d: Failed to parse key trigger, unexpected character: '%c'", lex->file, lex->line, lex->column, At(lex)); return result; } @@ -143,21 +101,21 @@ Trigger *ParseKeyAtom(Lexer *lex) { Trigger *ParseKeyChord(Lexer *lex) { Trigger *left = ParseKeyAtom(lex); - EatWhitespace(lex); + EatWhitespaceEx(lex); while (IsAlphanumeric(At(lex))) { left = TriggerBinary(lex, left, ParseKeyChord(lex), ' '); - EatWhitespace(lex); + EatWhitespaceEx(lex); } return left; } Trigger *ParseKeyOr(Lexer *lex) { Trigger *left = ParseKeyChord(lex); - EatWhitespace(lex); + EatWhitespaceEx(lex); while (At(lex) == '|') { Advance(lex); left = TriggerBinary(lex, left, ParseKeyOr(lex), '|'); - EatWhitespace(lex); + EatWhitespaceEx(lex); } return left; } diff --git a/src/text_editor/data_desc.cpp b/src/text_editor/data_desc.cpp index cac0883..c6fd6e8 100644 --- a/src/text_editor/data_desc.cpp +++ b/src/text_editor/data_desc.cpp @@ -1,22 +1,25 @@ -namespace DataDesc { -struct Lexer { - Allocator allocator; - char *at; - char *start; - char *end; +typedef U32 TokenKind; +enum { + TokenKind_EOF = 0, + TokenKind_Ident = (1<<0), + TokenKind_String = (1<<1), + TokenKind_Numeric = (1<<2), + TokenKind_Comment = (1<<3), + TokenKind_Error = (1<<4), - char *file; - int line, column; + TokenKind_OpenBrace = (1<<5), + TokenKind_CloseBrace = (1<<6), + TokenKind_Colon = (1<<7), + TokenKind_Comma = (1<<8), + TokenKind_Minus = (1<<9), + TokenKind_Tag = (1<<10), + TokenKind_Or = (1<<11), }; -enum TokenKind { - TokenKind_EOF, - TokenKind_String, - TokenKind_Colon, - TokenKind_Comma, - TokenKind_OpenBrace, - TokenKind_CloseBrace, - TokenKind_Error, +typedef U32 TokenGroup; +enum { + TokenGroup_String = (TokenKind_Numeric|TokenKind_String|TokenKind_Ident), + TokenGroup_Symbol = (TokenKind_OpenBrace|TokenKind_CloseBrace|TokenKind_Colon|TokenKind_Comma|TokenKind_Minus|TokenKind_Tag|TokenKind_Or), }; struct Token { @@ -25,14 +28,42 @@ struct Token { struct {char *data; Int len;}; String string; }; - int line, column; + Float f; + Int line, column; char *file; }; -Lexer MakeLexer(Allocator allocator, String string, char *file) { - Assert(string.data != NULL && string.data != 0); - Lexer result = {allocator, string.data, string.data, string.data + string.len}; - result.file = file; +struct Lexer { + Allocator allocator; + char *at; + char *start; + char *end; + char *file; + Int line, column; +}; + +Lexer MakeLexer(Allocator allocator, String string, char *file, Int line, Int column) { + Lexer lexer = {allocator, string.data, string.data, string.data + string.len, file, line, column}; + return lexer; +} + +void Advance(Lexer *lex) { + if (lex->at < lex->end) { + if (lex->at[0] == '\n') { + lex->line += 1; + lex->column = 0; + } + lex->column += 1; + lex->at += 1; + } +} + +void Advance(Lexer *lex, int n) { + for (int i = 0; i < n; i += 1) Advance(lex); +} + +String AsString(Lexer *lex) { + String result = {lex->at, lex->end - lex->at}; return result; } @@ -43,18 +74,6 @@ char At(Lexer *lex) { return 0; } -void Advance(Lexer *lex) { - if (lex->at >= lex->end) { - return; - } - if (lex->at[0] == '\n') { - lex->line += 1; - lex->column = 0; - } - lex->column += 1; - lex->at += 1; -} - void EatWhitespace(Lexer *lex) { while (IsWhitespace(At(lex))) { Advance(lex); @@ -82,8 +101,24 @@ void LexString(Lexer *lex, Token *t) { t->len = (Int)(lex->at - t->data) - 1; } -bool IsOkForIdent(char cc) { - bool result = IsAlphanumeric(cc) || cc == '_' || cc == '/' || cc == '-' || cc == '.' || cc == '@'; +void LexDigit(Lexer *lex, Token *t) { + t->kind = TokenKind_Numeric; + for (;;) { + char c = At(lex); + if (c == 0) { + break; + } + if (!IsDigit(c)) { + break; + } + Advance(lex); + } + t->len = (Int)(lex->at - t->data); + t->f = (Float)strtoll(t->data, NULL, 10); +} + +bool IsOkForIdent(Lexer *lex, char c) { + bool result = IsAlphanumeric(c) || c == '_' || c == '/'; return result; } @@ -99,7 +134,7 @@ Token Next(Lexer *lex) { Advance(lex); if (c == 0) { - t.kind = TokenKind_EOF; + return t; } else if (c == '{') { t.kind = TokenKind_OpenBrace; } else if (c == '}') { @@ -108,15 +143,17 @@ Token Next(Lexer *lex) { t.kind = TokenKind_Colon; } else if (c == ',') { t.kind = TokenKind_Comma; + } else if (IsDigit(c)) { + LexDigit(lex, &t); } else if (c == '"') { LexString(lex, &t); } else if (c == '`') { LexString(lex, &t); - } else if (IsOkForIdent(c)) { + } else if (IsOkForIdent(lex, c)) { t.kind = TokenKind_String; for (;;) { char cc = At(lex); - bool ok = IsOkForIdent(cc); + bool ok = IsOkForIdent(lex, cc); if (!ok) { break; } @@ -132,10 +169,10 @@ Token Next(Lexer *lex) { return t; } -void RunDataDescriptionTest() { +void TestDataDesc() { Scratch scratch; String s = "{/usr/bin/python3, `Hidden`, Input:Clipboard}"; - Lexer lexer = MakeLexer(scratch, s, "test"); + Lexer lexer = MakeLexer(scratch, s, "test", 0, 0); { Token tok = {}; tok = Next(&lexer); @@ -179,6 +216,4 @@ void RunDataDescriptionTest() { Assert(tok.kind == TokenKind_EOF); } - -} RegisterFunction(&TestFunctions, RunDataDescriptionTest); -} +} RegisterFunction(&TestFunctions, TestDataDesc); diff --git a/src/text_editor/globals.cpp b/src/text_editor/globals.cpp index 00d49ff..79b31eb 100644 --- a/src/text_editor/globals.cpp +++ b/src/text_editor/globals.cpp @@ -12,7 +12,6 @@ bool BreakOnError = false; Int ErrorCount; Allocator SysAllocator = {SystemAllocatorProc}; -String ConfigDir; float DPIScale = 1.0f; // @WARNING: be careful about using this, should only be used for debugging @@ -175,7 +174,8 @@ RegisterVariable(String, InternetBrowser, "firefox"); RegisterVariable(String, OpenCodePatterns, ".c .h .cpp .hpp .cc .cxx .rs .go .zig .py .lua .js .ts .jsx .tsx .java .kt .swift .cs .rb .php .html .css .scss .bat .sh .bash .zsh .sql .asm .s .cmake .make .json .yaml .toml .ini .txt .md .rst .Makefile .Dockerfile .gitignore .bashrc .zshrc"); RegisterVariable(String, OpenCodeExcludePatterns, ""); RegisterVariable(Int, TrimTrailingWhitespace, 1); - +RegisterVariable(String, HomeFolder, ""); +RegisterVariable(String, ConfigFolder, ""); // PROJECT_MANAGEMENT // Set at the beginning of the program to current directory diff --git a/src/text_editor/plugin_config.cpp b/src/text_editor/plugin_config.cpp index 7443538..6da19f1 100644 --- a/src/text_editor/plugin_config.cpp +++ b/src/text_editor/plugin_config.cpp @@ -153,4 +153,4 @@ void Set(String string) { ReportErrorf("Failed to :Set, no such variable found: %S", name); } -#endif \ No newline at end of file +#endif diff --git a/src/text_editor/text_editor.cpp b/src/text_editor/text_editor.cpp index 4312404..3ec46e8 100644 --- a/src/text_editor/text_editor.cpp +++ b/src/text_editor/text_editor.cpp @@ -861,7 +861,21 @@ int main(int argc, char **argv) #endif InitScratch(); InitOS(ReportErrorf); + ProjectFolder = GetWorkingDir(Perm); + HomeFolder = SDL_GetUserFolder(SDL_FOLDER_HOME); + { + String sdl_config_path = SDL_GetPrefPath("krzosa", "text_editor"); + if (sdl_config_path.len && sdl_config_path.data[sdl_config_path.len - 1] == '\\') { + sdl_config_path = Chop(sdl_config_path, 1); // chop '/' + } + if (sdl_config_path.len && sdl_config_path.data[sdl_config_path.len - 1] == '/') { + sdl_config_path = Chop(sdl_config_path, 1); // chop '/' + } + ConfigFolder = NormalizePath(Perm, sdl_config_path); + SDL_free(sdl_config_path.data); + } + #if OS_WINDOWS { wchar_t *p = GetEnvironmentStringsW(); @@ -889,18 +903,6 @@ int main(int argc, char **argv) // return 0; } - { - String sdl_config_path = SDL_GetPrefPath("krzosa", "text_editor"); - if (sdl_config_path.len && sdl_config_path.data[sdl_config_path.len - 1] == '\\') { - sdl_config_path = Chop(sdl_config_path, 1); // chop '/' - } - if (sdl_config_path.len && sdl_config_path.data[sdl_config_path.len - 1] == '/') { - sdl_config_path = Chop(sdl_config_path, 1); // chop '/' - } - ConfigDir = NormalizePath(Perm, sdl_config_path); - SDL_free(sdl_config_path.data); - } - if (!SDL_Init(SDL_INIT_VIDEO)) { ReportErrorf("Couldn't initialize SDL! %s", SDL_GetError()); return 1; @@ -1027,7 +1029,7 @@ int main(int argc, char **argv) #if PLUGIN_CONFIG { Scratch scratch; - GlobalConfigBufferID = LoadConfig(Format(scratch, "%S/config.te", ConfigDir)); + GlobalConfigBufferID = LoadConfig(Format(scratch, "%S/config.te", ConfigFolder)); } #endif for (int i = 1; i < argc; i += 1) { diff --git a/src/text_editor/ui.cpp b/src/text_editor/ui.cpp index 3fb98c7..87067bc 100644 --- a/src/text_editor/ui.cpp +++ b/src/text_editor/ui.cpp @@ -325,15 +325,17 @@ Otherwise it does filepath parsing: ./thing(10) -TODO: need to add '~', but where? - USECASE: Wouldn't it be cool to just select a part of codebase pipe that into a script - and get a result in a clipboard or capture the output and change the selection. -TODO: Data desc language + and get a result in a clipboard or capture the output and change the selection? + +PREV IDEA: !{bash,Out:Sel} SCRIPT !{bash,Out:Clip} SCRIPT Use variables for injecting selection: @Sel +TODO: I would pause the data desc language, seems a bit cumbersome... think of more concrete, constrained ideas +TODO: Unify lexers (Set and Trigger) + */ ResolvedOpen ResolveOpen(Allocator alo, Window *window, String path, ResolveOpenMeta meta) { ResolvedOpen result = {};