Compare commits
5 Commits
830be12b24
...
main
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
3ab6639afb | ||
|
|
7a73a982d2 | ||
|
|
51f1fd1b4f | ||
|
|
930620a49e | ||
|
|
8cb1b49cd8 |
@@ -7,7 +7,7 @@
|
||||
- Window position: vscode opens in fullscreen and then remembers what position it was close in (could be a config option)
|
||||
- On Linux: Try to implement is_debugger_present()
|
||||
- Maybe IPC for te.exe when it's already open and file arguments are passed it should perhaps open a buffer in current window??
|
||||
- Add <<File>> <<ProjectDirectory>> template strings to Open (Then remove SEtWorkdirhere)
|
||||
- Add <<File>> <<ProjectFolder>> template strings to Open (Then remove SEtWorkdirhere)
|
||||
- :Set Filename to name current buffer ??? :O and others like that!!
|
||||
- Make a fuzzy command !> grep and fuzzy over it??? (doesn't seem very useful for grep)
|
||||
- Make the equivalent of SearchOpenBuffers but for cmds like !@git grep -n "@>"
|
||||
|
||||
@@ -73,10 +73,10 @@ static const char *glsl_fshader_es3 = R"==(#version 300 es
|
||||
}
|
||||
)==";
|
||||
|
||||
void ReportWarningf(const char *fmt, ...);
|
||||
void ReportErrorf(const char *fmt, ...);
|
||||
void GLDebugCallback(GLenum source, GLenum type, GLuint id, GLenum severity, GLsizei length, const GLchar *message, const void *user) {
|
||||
Unused(source); Unused(type); Unused(id); Unused(length); Unused(user);
|
||||
ReportWarningf("OpenGL message: %s", message);
|
||||
ReportErrorf("OpenGL message: %s", message);
|
||||
if (severity == GL_DEBUG_SEVERITY_HIGH || severity == GL_DEBUG_SEVERITY_MEDIUM) {
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "OpenGL error", message, NULL);
|
||||
}
|
||||
|
||||
@@ -1557,7 +1557,7 @@ void SaveBuffer(Buffer *buffer) {
|
||||
buffer->dirty = false;
|
||||
buffer->temp = false;
|
||||
} else {
|
||||
ReportWarningf("Failed to save file with name: %S", buffer->name);
|
||||
ReportErrorf("Failed to save file with name: %S", buffer->name);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -67,6 +67,12 @@ void Appendf(View *view, const char *fmt, ...) {
|
||||
Append(view, string, true);
|
||||
}
|
||||
|
||||
void ReportConsolef(const char *fmt, ...) {
|
||||
Scratch scratch;
|
||||
STRING_FORMAT(scratch, fmt, string);
|
||||
Appendf(LogView, "%S\n", string);
|
||||
}
|
||||
|
||||
void ReportErrorf(const char *fmt, ...) {
|
||||
ErrorCount += 1;
|
||||
Scratch scratch;
|
||||
@@ -77,28 +83,11 @@ void ReportErrorf(const char *fmt, ...) {
|
||||
|
||||
if (LogView) {
|
||||
Appendf(LogView, "%S\n", string);
|
||||
ShowUIMessagef("%S", string);
|
||||
} else {
|
||||
printf("%.*s\n", (int)string.len, string.data);
|
||||
}
|
||||
}
|
||||
|
||||
void ReportConsolef(const char *fmt, ...) {
|
||||
Scratch scratch;
|
||||
STRING_FORMAT(scratch, fmt, string);
|
||||
Appendf(LogView, "%S\n", string);
|
||||
}
|
||||
|
||||
void ReportWarningf(const char *fmt, ...) {
|
||||
ErrorCount += 1;
|
||||
Scratch scratch;
|
||||
STRING_FORMAT(scratch, fmt, string);
|
||||
if (BreakOnError) {
|
||||
BREAK();
|
||||
}
|
||||
Appendf(LogView, "%S\n", string);
|
||||
}
|
||||
|
||||
void CMD_CenterView() {
|
||||
CenterView(PrimaryWindowID);
|
||||
} RegisterCommand(CMD_CenterView, "", "");
|
||||
|
||||
@@ -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,35 +25,7 @@ struct CachedTrigger {
|
||||
};
|
||||
Array<CachedTrigger> CachedTriggers;
|
||||
|
||||
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);
|
||||
}
|
||||
@@ -80,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")) {
|
||||
@@ -118,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;
|
||||
}
|
||||
|
||||
@@ -138,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;
|
||||
}
|
||||
|
||||
@@ -61,7 +61,7 @@ void UpdateCoroutines(Event *event) {
|
||||
_CoroutineContext = ⁢
|
||||
mco_result ok = mco_resume(it.co);
|
||||
if (ok != MCO_SUCCESS) {
|
||||
ReportWarningf("failed to resume coroutine %d", ok);
|
||||
ReportErrorf("failed to resume coroutine %d", ok);
|
||||
DestroyCoroutine(&it);
|
||||
remove_item = true;
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -103,6 +103,7 @@ void DrawUnderline(Window *window, View *view, Buffer *buffer, Range range, Colo
|
||||
Vec2I max = {xy_max.col * window->font->char_spacing, (xy_max.line + 1) * window->font->line_spacing};
|
||||
Rect2I rect = {min, max};
|
||||
Rect2I scrolled_rect = rect - view->scroll + window->document_rect.min;
|
||||
if (scrolled_rect.min.x < window->document_rect.min.x) scrolled_rect.min.x = window->document_rect.min.x;
|
||||
DrawRectOutline(scrolled_rect, color);
|
||||
}
|
||||
|
||||
|
||||
@@ -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,10 +174,12 @@ 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
|
||||
RegisterVariable(String, ProjectDirectory, "");
|
||||
RegisterVariable(String, ProjectFolder, "");
|
||||
|
||||
// PLUGIN_BUILD_WINDOW
|
||||
RegisterVariable(String, Build1OnWindows, "build.bat slow");
|
||||
|
||||
@@ -5,7 +5,7 @@ BufferID BuildBufferID;
|
||||
void InitBuildWindow() {
|
||||
Window *window = CreateWind();
|
||||
BuildWindowID = window->id;
|
||||
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(ProjectDirectory, "build"));
|
||||
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(ProjectFolder, "build"));
|
||||
buffer->special = true;
|
||||
buffer->no_history = true;
|
||||
BuildBufferID = buffer->id;
|
||||
@@ -32,7 +32,7 @@ void LayoutBuildWindow(Rect2I *rect, int16_t wx, int16_t wy) {
|
||||
window->document_rect = window->total_rect = CutBottom(rect, barsize);
|
||||
}
|
||||
|
||||
BSet ExecBuild(String windows_cmd, String unix_cmd, String working_dir = ProjectDirectory) {
|
||||
BSet ExecBuild(String windows_cmd, String unix_cmd, String working_dir = ProjectFolder) {
|
||||
SaveAll();
|
||||
Scratch scratch;
|
||||
BSet build = GetBSet(BuildWindowID);
|
||||
|
||||
@@ -67,7 +67,7 @@ void LayoutCommandWindow(Rect2I *rect, int16_t wx, int16_t wy) {
|
||||
void InitCommandWindow() {
|
||||
Window *window = CreateWind();
|
||||
CommandWindowID = window->id;
|
||||
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(ProjectDirectory, "command_bar"));
|
||||
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(ProjectFolder, "command_bar"));
|
||||
buffer->special = true;
|
||||
buffer->no_history = true;
|
||||
View *view = CreateView(buffer->id);
|
||||
|
||||
@@ -56,17 +56,6 @@ void CMD_EvalCommandsLineByLine() {
|
||||
EvalCommandsLineByLine(set);
|
||||
} RegisterCommand(CMD_EvalCommandsLineByLine, "", "Goes line by line over a buffer and evaluates every line as a command, ignores empty or lines starting with '//'");
|
||||
|
||||
Variable *GetVariable(String name) {
|
||||
Variable *var = NULL;
|
||||
For (Variables) {
|
||||
if (name == it.name) {
|
||||
var = ⁢
|
||||
break;
|
||||
}
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
BufferID LoadConfig(String config_path) {
|
||||
ReportConsolef("Loading config %S...", config_path);
|
||||
Window *window = GetWindow(NullWindowID);
|
||||
@@ -128,8 +117,8 @@ void Set(String string) {
|
||||
}
|
||||
|
||||
#if PLUGIN_PROJECT_MANAGEMENT
|
||||
if (name == "ProjectDirectory") {
|
||||
SetProjectDirectory(*var->string);
|
||||
if (name == "ProjectFolder") {
|
||||
SetProjectFolder(*var->string);
|
||||
}
|
||||
#endif
|
||||
return;
|
||||
@@ -164,4 +153,4 @@ void Set(String string) {
|
||||
ReportErrorf("Failed to :Set, no such variable found: %S", name);
|
||||
}
|
||||
|
||||
#endif
|
||||
#endif
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#if PLUGIN_CONFIG
|
||||
void Set(String string);
|
||||
String InsertVariables(Allocator allocator, String string);
|
||||
#endif
|
||||
@@ -12,7 +12,7 @@ void InitDebugWindow() {
|
||||
window->primary = false;
|
||||
window->jump_history = false;
|
||||
|
||||
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(ProjectDirectory, "debug"));
|
||||
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(ProjectFolder, "debug"));
|
||||
DebugBufferID = buffer->id;
|
||||
buffer->no_history = true;
|
||||
buffer->special = true;
|
||||
|
||||
@@ -2,7 +2,7 @@ void Windows_SetupVCVarsall(mco_coro *co) {
|
||||
View *view = NULL;
|
||||
{
|
||||
Scratch scratch;
|
||||
String working_dir = ProjectDirectory;
|
||||
String working_dir = ProjectFolder;
|
||||
String buffer_name = GetUniqueBufferName(working_dir, "vcvarsall-");
|
||||
String cmd = Format(scratch, "\"%S\" && set", VCVarsPath);
|
||||
view = OpenBufferView(buffer_name);
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
void SetProjectDirectory(String dir) {
|
||||
ProjectDirectory = Intern(&GlobalInternTable, dir);
|
||||
void SetProjectFolder(String dir) {
|
||||
ProjectFolder = Intern(&GlobalInternTable, dir);
|
||||
Scratch scratch;
|
||||
For (Buffers) {
|
||||
if (it->special) {
|
||||
@@ -14,7 +14,7 @@ void CO_OpenCode(mco_coro *co) {
|
||||
Array<String> patterns = SplitWhitespace(ctx->arena, OpenCodePatterns);
|
||||
Array<String> exclude_patterns = SplitWhitespace(ctx->arena, OpenCodeExcludePatterns);
|
||||
Array<String> dirs = {ctx->arena};
|
||||
Add(&dirs, Copy(ctx->arena, ProjectDirectory));
|
||||
Add(&dirs, Copy(ctx->arena, ProjectFolder));
|
||||
for (int diri = 0; diri < dirs.len; diri += 1) {
|
||||
for (FileIter it = IterateFiles(ctx->arena, dirs[diri]); IsValid(it); Advance(&it)) {
|
||||
bool should_open = true;
|
||||
@@ -52,12 +52,12 @@ void CO_OpenCode(mco_coro *co) {
|
||||
} RegisterCoroutineCommand(
|
||||
CO_OpenCode,
|
||||
"",
|
||||
"Open all code files in current ProjectDirectory, the code files are determined through NonCodePatterns_EndsWith config variable list",
|
||||
"Open all code files in current ProjectFolder, the code files are determined through NonCodePatterns_EndsWith config variable list",
|
||||
data->dont_wait_until_resolved = true;
|
||||
);
|
||||
|
||||
void OpenProject(String directory) {
|
||||
SetProjectDirectory(directory);
|
||||
SetProjectFolder(directory);
|
||||
#if PLUGIN_CONFIG
|
||||
Scratch scratch;
|
||||
for (FileIter it = IterateFiles(scratch, directory); IsValid(it); Advance(&it)) {
|
||||
@@ -111,7 +111,7 @@ void CO_CreateProject(mco_coro *co) {
|
||||
String src_dir = Format(scratch, "%S/src", project_dir);
|
||||
MakeDir(project_dir);
|
||||
MakeDir(src_dir);
|
||||
SetProjectDirectory(project_dir);
|
||||
SetProjectFolder(project_dir);
|
||||
|
||||
Buffer *project = BufferOpenFile(Format(scratch, "%S/project.te", project_dir));
|
||||
RawAppendf(project, ":OpenCode\n:Set BinaryUnderDebug '%S/build/main.exe'\n", project_dir);
|
||||
|
||||
@@ -1 +1 @@
|
||||
void SetProjectDirectory(String name);
|
||||
void SetProjectFolder(String name);
|
||||
|
||||
@@ -2124,7 +2124,7 @@ bool RDBG_InitConnection(mco_coro *co, bool create_session = true) {
|
||||
|
||||
if (file.len == 0) {
|
||||
Scratch scratch;
|
||||
for (FileIter it = IterateFiles(scratch, ProjectDirectory); IsValid(it); Advance(&it)) {
|
||||
for (FileIter it = IterateFiles(scratch, ProjectFolder); IsValid(it); Advance(&it)) {
|
||||
if (EndsWith(it.filename, ".rdbg")) {
|
||||
file = Intern(&GlobalInternTable, it.absolute_path);
|
||||
break;
|
||||
@@ -2133,7 +2133,7 @@ bool RDBG_InitConnection(mco_coro *co, bool create_session = true) {
|
||||
}
|
||||
|
||||
if (file.len == 0) {
|
||||
ReportWarningf("Couldn't find neither .rdbg file, nor use the BinaryUnderDebug variable to locate the binary");
|
||||
ReportErrorf("Couldn't find neither .rdbg file, nor use the BinaryUnderDebug variable to locate the binary");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -2178,7 +2178,7 @@ bool RDBG_InitConnection(mco_coro *co, bool create_session = true) {
|
||||
rdbg_Id cfg_id;
|
||||
char *exe = file.data;
|
||||
char *args = NULL;
|
||||
char *work_dir = ProjectDirectory.data;
|
||||
char *work_dir = ProjectFolder.data;
|
||||
char *env = NULL;
|
||||
AddSessionConfig(&RDBG_Ctx, exe, args, work_dir, env, true, true, &res, &cfg_id);
|
||||
if (ContextHadError(&RDBG_Ctx)) {
|
||||
|
||||
@@ -63,7 +63,7 @@ void CMD_ToggleSearchWordBoundary() {
|
||||
void InitSearchWindow() {
|
||||
Window *window = CreateWind();
|
||||
SearchWindowID = window->id;
|
||||
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(ProjectDirectory, "search"));
|
||||
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(ProjectFolder, "search"));
|
||||
buffer->special = true;
|
||||
SearchBufferID = buffer->id;
|
||||
View *view = CreateView(buffer->id);
|
||||
|
||||
@@ -3,7 +3,7 @@ WindowID StatusWindowID;
|
||||
void InitStatusWindow() {
|
||||
Window *window = CreateWind();
|
||||
StatusWindowID = window->id;
|
||||
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(ProjectDirectory, "status_bar"));
|
||||
Buffer *buffer = CreateBuffer(SysAllocator, GetUniqueBufferName(ProjectFolder, "status_bar"));
|
||||
buffer->special = true;
|
||||
View *view = CreateView(buffer->id);
|
||||
view->special = true;
|
||||
|
||||
@@ -57,7 +57,7 @@ void CMD_FocusWindow4() {
|
||||
Window *third = GetOverlappingWindow(GetSideOfWindow(second, DIR_RIGHT));
|
||||
if (third) {
|
||||
Window *fourth = GetOverlappingWindow(GetSideOfWindow(third, DIR_RIGHT));
|
||||
if (fourth) NextActiveWindowID = third->id;
|
||||
if (fourth) NextActiveWindowID = fourth->id;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
// MAAAAAAAAAAAAN I DONT LIKE THIS CODE, BUT HOPE IT WORKS
|
||||
|
||||
// @todo: potentially bad that we are not checking against end! lexer->at[0] == 0 check is not enough
|
||||
struct Lexer2 {
|
||||
char16_t *at;
|
||||
};
|
||||
|
||||
@@ -854,25 +854,29 @@ extern char **environ;
|
||||
int main(int argc, char **argv)
|
||||
#endif
|
||||
{
|
||||
InitScratch();
|
||||
InitOS(ReportErrorf);
|
||||
#if OS_WINDOWS
|
||||
int argc = __argc;
|
||||
char **argv = __argv;
|
||||
AttachConsole(ATTACH_PARENT_PROCESS);
|
||||
#endif
|
||||
InitScratch();
|
||||
InitOS(ReportErrorf);
|
||||
|
||||
if (1) {
|
||||
RunArenaTest();
|
||||
For (TestFunctions) {
|
||||
it.function();
|
||||
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 '/'
|
||||
}
|
||||
|
||||
// ReportErrorf("Testing DONE\n");
|
||||
// return 0;
|
||||
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
|
||||
#if OS_WINDOWS
|
||||
{
|
||||
wchar_t *p = GetEnvironmentStringsW();
|
||||
for (;p && p[0];) {
|
||||
@@ -889,17 +893,14 @@ int main(int argc, char **argv)
|
||||
}
|
||||
#endif
|
||||
|
||||
ProjectDirectory = GetWorkingDir(Perm);
|
||||
{
|
||||
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 (1) {
|
||||
RunArenaTest();
|
||||
For (TestFunctions) {
|
||||
it.function();
|
||||
}
|
||||
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);
|
||||
|
||||
// ReportErrorf("Testing DONE\n");
|
||||
// return 0;
|
||||
}
|
||||
|
||||
if (!SDL_Init(SDL_INIT_VIDEO)) {
|
||||
@@ -979,13 +980,13 @@ int main(int argc, char **argv)
|
||||
{
|
||||
Allocator sys_allocator = GetSystemAllocator();
|
||||
Scratch scratch;
|
||||
Buffer *null_buffer = CreateBuffer(sys_allocator, Format(scratch, "%S/scratch", ProjectDirectory));
|
||||
Buffer *null_buffer = CreateBuffer(sys_allocator, Format(scratch, "%S/scratch", ProjectFolder));
|
||||
null_buffer->special = true;
|
||||
View *null_view = CreateView(null_buffer->id);
|
||||
null_view->special = true;
|
||||
Assert(null_buffer->id == NullBufferID && null_view->id == NullViewID);
|
||||
|
||||
Buffer *logs_buffer = CreateBuffer(sys_allocator, GetUniqueBufferName(ProjectDirectory, "logs", ""));
|
||||
Buffer *logs_buffer = CreateBuffer(sys_allocator, GetUniqueBufferName(ProjectFolder, "logs", ""));
|
||||
logs_buffer->special = true;
|
||||
View *logs_view = CreateView(logs_buffer->id);
|
||||
logs_view->special = true;
|
||||
@@ -993,13 +994,13 @@ int main(int argc, char **argv)
|
||||
LogView = logs_view;
|
||||
|
||||
#if PLUGIN_RECORD_GC
|
||||
GCInfoBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(ProjectDirectory, "gc"));
|
||||
GCInfoBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(ProjectFolder, "gc"));
|
||||
GCInfoBuffer->special = true;
|
||||
GCInfoBuffer->no_history = true;
|
||||
#endif
|
||||
|
||||
#if PLUGIN_RECORD_EVENTS
|
||||
EventBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(ProjectDirectory, "events"));
|
||||
EventBuffer = CreateBuffer(sys_allocator, GetUniqueBufferName(ProjectFolder, "events"));
|
||||
EventBuffer->no_history = true;
|
||||
EventBuffer->special = true;
|
||||
#endif
|
||||
@@ -1009,7 +1010,7 @@ int main(int argc, char **argv)
|
||||
ReloadFont(PathToFont, (U32)FontSize);
|
||||
CreateWind();
|
||||
ReopenBuffer(GetBuffer(NullBufferID));
|
||||
InitOS(ReportWarningf);
|
||||
InitOS(ReportErrorf);
|
||||
|
||||
For (GlobalCommands) {
|
||||
if (it.binding.len != 0) {
|
||||
@@ -1028,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) {
|
||||
|
||||
@@ -217,15 +217,92 @@ bool IsOpenBoundary(char c) {
|
||||
return result;
|
||||
}
|
||||
|
||||
Variable *GetVariable(String name) {
|
||||
Variable *var = NULL;
|
||||
For (Variables) {
|
||||
if (name == it.name) {
|
||||
var = ⁢
|
||||
break;
|
||||
}
|
||||
}
|
||||
return var;
|
||||
}
|
||||
|
||||
String InsertVariables(Allocator allocator, String string) {
|
||||
Scratch scratch(allocator);
|
||||
Array<String> parts = {scratch};
|
||||
String it = string;
|
||||
for (;;) {
|
||||
int64_t idx = 0;
|
||||
bool found = Seek(it, "@", &idx, SeekFlag_None);
|
||||
if (!found) {
|
||||
if (it.len > 0) {
|
||||
Add(&parts, it);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
String prev = GetPrefix(it, idx);
|
||||
if (prev.len > 0) {
|
||||
Add(&parts, prev);
|
||||
}
|
||||
|
||||
it = Skip(it, idx + 1);
|
||||
char c = At(it, 0);
|
||||
String name = {};
|
||||
if (c == '@') {
|
||||
Add(&parts, String{"@", 1});
|
||||
it = Skip(it, 1);
|
||||
continue;
|
||||
} else if (c == '(') {
|
||||
char *start = it.data + 1;
|
||||
while (At(it, 0) && At(it, 0) != ')') {
|
||||
it = Skip(it, 1);
|
||||
}
|
||||
Int len = it.data - start;
|
||||
name = {start, len};
|
||||
it = Skip(it, 1); // skip ')'
|
||||
} else {
|
||||
char *start = it.data;
|
||||
while (IsAlphanumeric(At(it, 0))) {
|
||||
it = Skip(it, 1);
|
||||
}
|
||||
Int len = it.data - start;
|
||||
name = {start, len};
|
||||
}
|
||||
Variable *variable = GetVariable(name);
|
||||
if (!variable) {
|
||||
ReportErrorf("Variable: %S, not found", name);
|
||||
return string;
|
||||
}
|
||||
if (variable->type != VariableType_String) {
|
||||
// @todo: this will not report - open will override
|
||||
ReportErrorf("Variable: %S, not of type String", variable->type);
|
||||
return string;
|
||||
}
|
||||
|
||||
Add(&parts, *variable->string);
|
||||
}
|
||||
|
||||
String result = Merge(allocator, parts, "");
|
||||
return result;
|
||||
}
|
||||
|
||||
void TestInsertVariable() {
|
||||
Scratch scratch;
|
||||
|
||||
String a = "Thing/@(ProjectFolder)/Another";
|
||||
String b = "Thing/@ProjectFolder/Another";
|
||||
Assert(InsertVariables(scratch, a) == InsertVariables(scratch, b));
|
||||
int c = 10;
|
||||
|
||||
} RegisterFunction(&TestFunctions, TestInsertVariable);
|
||||
|
||||
/*
|
||||
|
||||
Variables that control the default shell for '!' commands
|
||||
DefaultShellWindows - "cmd"
|
||||
DefaultShellUnix - "bash | sh"
|
||||
|
||||
Variables:
|
||||
@ProjectDirectory/build/te
|
||||
@(ProjectDirectory)/build/te
|
||||
@ProjectFolder/build/te
|
||||
@(ProjectFolder)/build/te
|
||||
|
||||
Start of string matchers:
|
||||
! Execute with default shell
|
||||
@@ -238,7 +315,7 @@ Start of string matchers:
|
||||
py: @todo, execute in python shell, this will use the python3 shell and pass the rest to it's stdin or maybe as a file
|
||||
|
||||
More comprehensive syntax for commands:
|
||||
!{/usr/bin/python,Hidden,Input:Clipboard,Output:Clipboard,WorkingDirectory:@ProjectDirectory,Env:{Thing:asd}}
|
||||
!{/usr/bin/python,Hidden,Input:Clipboard,Output:Clipboard,WorkingDirectory:@ProjectFolder,Env:{Thing:asd}}
|
||||
|
||||
Otherwise it does filepath parsing:
|
||||
C:/windows/path
|
||||
@@ -248,8 +325,16 @@ Otherwise it does filepath parsing:
|
||||
./thing(10)
|
||||
|
||||
|
||||
TODO: need to add '~', but where?
|
||||
TODO: on linux find shell on first command and set as default
|
||||
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?
|
||||
|
||||
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) {
|
||||
@@ -258,7 +343,7 @@ ResolvedOpen ResolveOpen(Allocator alo, Window *window, String path, ResolveOpen
|
||||
bool exec = !(ResolveOpenMeta_DontExec & meta);
|
||||
|
||||
#if PLUGIN_CONFIG
|
||||
// @todo: variable substitution {{ProjectDirectory}}/build/te.exe
|
||||
path = InsertVariables(alo, path);
|
||||
|
||||
if (exec && result.kind == OpenKind_Invalid && StartsWith(path, ":Set ")) {
|
||||
result.kind = OpenKind_Set;
|
||||
|
||||
Reference in New Issue
Block a user