Error reporting and popup, debug window

This commit is contained in:
Krzosa Karol
2024-07-28 10:12:18 +02:00
parent 07a41e0266
commit a486a09d9e
8 changed files with 388 additions and 44 deletions

View File

@@ -185,6 +185,131 @@ char *ToColor(const char *value) {
return f.str;
}
S8_String LuaScript = R"==(
-- @todo: should we rewrite linux paths to windows on windows and vice-versa?
WorkingDir = "C:/text_editor"
OperatingSystem = "Windows"
function GenericTextFileRule(_s)
function match_path(s)
-- ./something
-- add working directory
local working_dir_i, working_dir_j = string.find(s, "^%./.+")
if working_dir_j then
result = s:sub(3)
result = WorkingDir.."/"..result
return result
end
-- C:/something
local abs_i, abs_j = string.find(s, "^%a:/.+")
if abs_i then
return s
end
-- C:\something
local abs_i, abs_j = s:find("^%a:\\.+")
if abs_i then
s = s:gsub("\\", "/")
return s
end
-- /mnt/something
local abs_i, abs_j = s:find("^/.*")
if abs_i then
return s
end
-- other_random_filename
return s
end
function match_line_col(s)
local line = 0
local col = 0
-- filename:line:column
local lci, lcj = s:find(":%d+:%d+$")
if lci then
local line_and_col = s:sub(lci, lcj)
local i, j = line_and_col:find("%d+")
line = line_and_col:sub(i, j)
col = line_and_col:sub(j + 2, -1)
s = s:sub(1, lci - 1)
return line, col, s
else
local li, lj = s:find(":%d+$")
if li then
local line_string = s:sub(li, lj)
line = line_string:sub(2, -1)
s = s:sub(1, li - 1)
return line, col, s
end
end
-- filename(line,col):
local lci, lcj = s:find("%(%d+,%d+%):$")
if lci then
local line_and_col = s:sub(lci, lcj)
local i, j = line_and_col:find("%d+")
line = line_and_col:sub(i, j)
col = line_and_col:sub(j + 2, -3)
s = s:sub(1, lci - 1)
return line, col, s
else
local li, lj = s:find("(%d+):$")
if li then
local line_string = s:sub(li, lj)
line = line_string:sub(2, -3)
s = s:sub(1, li - 1)
return line, col, s
end
end
-- filename(line,col)
local lci, lcj = s:find("%(%d+,%d+%)$")
if lci then
local line_and_col = s:sub(lci, lcj)
local i, j = line_and_col:find("%d+")
line = line_and_col:sub(i, j)
col = line_and_col:sub(j + 2, -2)
s = s:sub(1, lci - 1)
return line, col, s
else
local li, lj = s:find("(%d+)$")
if li then
local line_string = s:sub(li, lj)
line = line_string:sub(2, -2)
s = s:sub(1, li - 1)
return line, col, s
end
end
return 0, 0, s
end
line, col, _s = match_line_col(_s)
file_path = match_path(_s)
return {kind = "open_textfile", file_path = file_path, line = line, col = col}
end
Rules = {}
Rules[#Rules + 1] = GenericTextFileRule
function ResolvePath(s)
for i = #Rules,1,-1 do
rule = Rules[i]
result = rule(s)
if result then
return result
end
end
return nil
end
)==";
void GenerateConfig() {
struct Color {
const char *name;
@@ -257,6 +382,7 @@ void GenerateConfig() {
For(gruvbox) sb.add(Fmt("local %s = %s", it.name, it.value));
sb.add("Color = {}");
For(colors) sb.add(Fmt("Color.%s = %s", it.name, it.value));
sb.add(LuaScript);
}
sb.add(")==\";");

View File

@@ -263,10 +263,8 @@ bool GlobalCommand(Event event) {
if (!window->visible) continue;
bool mouse_in_window = CheckCollisionPointRec(mouse, window->total_rect);
if (mouse_in_window) {
Window *active_window = GetWindow(ActiveWindow);
if (active_window->z <= window->z) {
SetActiveWindow(window->id);
}
SetActiveWindow(window->id);
break;
}
}
}
@@ -289,6 +287,11 @@ bool GlobalCommand(Event event) {
}
}
if (Ctrl(SDLK_0)) {
Window *window = GetWindow(DebugWindowID);
window->visible = !window->visible;
}
if (Press(SDLK_F5)) {
AppIsRunning = false;
run_window_command = false;
@@ -340,3 +343,32 @@ bool GlobalCommand(Event event) {
return run_window_command;
}
void ReportErrorf(const char *fmt, ...) {
Scratch scratch;
STRING_FORMAT(scratch, fmt, string);
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error!", string.data, NULL);
Buffer *buffer = GetBuffer("*console*");
if (!buffer) return;
String16 string16 = ToString16(scratch, string);
ReplaceText(buffer, {}, string16);
}
void ReportWarningf(const char *fmt, ...) {
Scratch scratch;
STRING_FORMAT(scratch, fmt, string);
String16 string16 = ToString16(scratch, string);
{
Buffer *buffer = GetBuffer("*console*");
ReplaceText(buffer, {}, string16);
ReplaceText(buffer, Rng(string16.len), L"\n");
}
{
Buffer *buffer = GetBuffer("*popup*");
ReplaceText(buffer, GetRange(*buffer), string16);
SetActiveWindow(PopupWindowID);
}
}

View File

@@ -96,6 +96,130 @@ Color.MainCaret = GruvboxDark0Hard
Color.SubCaret = GruvboxGray245
Color.Selection = GruvboxLight1
Color.WhitespaceDuringSelection = GruvboxLight2
-- @todo: should we rewrite linux paths to windows on windows and vice-versa?
WorkingDir = "C:/text_editor"
OperatingSystem = "Windows"
function GenericTextFileRule(_s)
function match_path(s)
-- ./something
-- add working directory
local working_dir_i, working_dir_j = string.find(s, "^%./.+")
if working_dir_j then
result = s:sub(3)
result = WorkingDir.."/"..result
return result
end
-- C:/something
local abs_i, abs_j = string.find(s, "^%a:/.+")
if abs_i then
return s
end
-- C:\something
local abs_i, abs_j = s:find("^%a:\\.+")
if abs_i then
s = s:gsub("\\", "/")
return s
end
-- /mnt/something
local abs_i, abs_j = s:find("^/.*")
if abs_i then
return s
end
-- other_random_filename
return s
end
function match_line_col(s)
local line = 0
local col = 0
-- filename:line:column
local lci, lcj = s:find(":%d+:%d+$")
if lci then
local line_and_col = s:sub(lci, lcj)
local i, j = line_and_col:find("%d+")
line = line_and_col:sub(i, j)
col = line_and_col:sub(j + 2, -1)
s = s:sub(1, lci - 1)
return line, col, s
else
local li, lj = s:find(":%d+$")
if li then
local line_string = s:sub(li, lj)
line = line_string:sub(2, -1)
s = s:sub(1, li - 1)
return line, col, s
end
end
-- filename(line,col):
local lci, lcj = s:find("%(%d+,%d+%):$")
if lci then
local line_and_col = s:sub(lci, lcj)
local i, j = line_and_col:find("%d+")
line = line_and_col:sub(i, j)
col = line_and_col:sub(j + 2, -3)
s = s:sub(1, lci - 1)
return line, col, s
else
local li, lj = s:find("(%d+):$")
if li then
local line_string = s:sub(li, lj)
line = line_string:sub(2, -3)
s = s:sub(1, li - 1)
return line, col, s
end
end
-- filename(line,col)
local lci, lcj = s:find("%(%d+,%d+%)$")
if lci then
local line_and_col = s:sub(lci, lcj)
local i, j = line_and_col:find("%d+")
line = line_and_col:sub(i, j)
col = line_and_col:sub(j + 2, -2)
s = s:sub(1, lci - 1)
return line, col, s
else
local li, lj = s:find("(%d+)$")
if li then
local line_string = s:sub(li, lj)
line = line_string:sub(2, -2)
s = s:sub(1, li - 1)
return line, col, s
end
end
return 0, 0, s
end
line, col, _s = match_line_col(_s)
file_path = match_path(_s)
return {kind = "open_textfile", file_path = file_path, line = line, col = col}
end
Rules = {}
Rules[#Rules + 1] = GenericTextFileRule
function ResolvePath(s)
for i = #Rules,1,-1 do
rule = Rules[i]
result = rule(s)
if result then
return result
end
end
return nil
end
)==";
void ReloadColors() {
ColorText = GetColor("Text", ColorText);

View File

@@ -86,7 +86,12 @@ String16 EvalString(Allocator allocator, String16 string16) {
String string = ToString(scratch, string16);
string = Format(scratch, "return %.*s", FmtString(string));
if (luaL_dostring(LuaState, string.data) != LUA_OK) {
const char *error_message = lua_tostring(LuaState, -1);
ReportWarningf("Failed to load base lua config! %s", error_message);
lua_pop(LuaState, 1);
return {};
}
const char *text = lua_tostring(LuaState, -1);
if (text) {
String s = text;

View File

@@ -6,12 +6,14 @@ Array<Buffer> Buffers = {};
Array<View> Views = {};
Array<Window> Windows = {};
WindowID NullWindowID = {0};
BufferID NullBufferID = {0};
ViewID NullViewID = {0};
WindowID CommandWindowID = {0};
WindowID InfoBarWindowID = {0};
WindowID SearchWindowID = {0};
WindowID NullWindowID;
BufferID NullBufferID;
ViewID NullViewID;
WindowID CommandWindowID;
WindowID InfoBarWindowID;
WindowID SearchWindowID;
WindowID PopupWindowID;
WindowID DebugWindowID;
Array<WindowID> WindowSwitchHistory; // @todo: probably better as a circular buffer
WindowID ActiveWindow;

View File

@@ -117,6 +117,9 @@ int main()
ExeDir = GetExeDir(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 (sdl_config_path.len && sdl_config_path.data[sdl_config_path.len - 1] == '/') {
sdl_config_path = Chop(sdl_config_path, 1); // chop '/'
}
@@ -125,7 +128,7 @@ int main()
}
if (SDL_Init(SDL_INIT_VIDEO) == -1) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't initialize SDL!", SDL_GetError(), NULL);
ReportErrorf("Couldn't initialize SDL! %s", SDL_GetError());
return 1;
}
@@ -141,7 +144,7 @@ int main()
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
SDL_Window *window = SDL_CreateWindow("Text editor", 1280, 720, window_flags);
if (window == NULL) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't create window!", SDL_GetError(), NULL);
ReportErrorf("Couldn't create window! %s", SDL_GetError());
return 1;
}
@@ -159,7 +162,7 @@ int main()
}
if (!gladLoadGLLoader((GLADloadproc)SDL_GL_GetProcAddress)) {
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Couldn't load opengl!", SDL_GetError(), NULL);
ReportErrorf("Couldn't load OpenGL! %s", SDL_GetError());
return 1;
}
@@ -180,7 +183,10 @@ int main()
{
// Init base config, test that it works and initialize the lua stuff
if (!luaL_dostring(LuaState, BaseLuaConfig.data) == LUA_OK) {
Assert(0);
const char *error_message = lua_tostring(LuaState, -1);
ReportErrorf("Failed to load base lua config! %s", error_message);
lua_pop(LuaState, 1);
return 1;
}
// Init user config
@@ -199,6 +205,9 @@ int main()
if (luaL_dostring(LuaState, string.data) == LUA_OK) {
ReloadColors();
} else {
const char *error_message = lua_tostring(LuaState, -1);
ReportWarningf("Failed to load user config! %s", error_message);
lua_pop(LuaState, 1);
}
} else {
ReplaceText(lua_buffer, {}, ToString16(scratch, BaseLuaConfig));
@@ -263,6 +272,9 @@ int main()
if (luaL_dostring(LuaState, string.data) == LUA_OK) {
ReloadColors();
} else {
const char *error_message = lua_tostring(LuaState, -1);
ReportWarningf("Failed to load user config! %s", error_message);
lua_pop(LuaState, 1);
}
lua_buffer_change_id = lua_buffer->change_id;
}

View File

@@ -103,4 +103,7 @@ void Command_EvalLua(View *view, String16 string);
void MergeCarets(View *view, Range *mouse_selection_anchor = NULL);
inline BufferID AllocBufferID();
void Command_SelectEntireBuffer(View *view);
void Command_Replace(View *view, String16 string);
void Command_Replace(View *view, String16 string);
void ReportErrorf(const char *fmt, ...);
void ReportWarningf(const char *fmt, ...);

View File

@@ -14,14 +14,15 @@ void InitWindows() {
Buffer *b = CreateBuffer(sys_allocator, "*load_text_a*");
View *v = CreateView(b->id);
LoadTextA(b);
LoadUnicode(b);
AddView(w, v->id);
}
{
Window *w = CreateWindow();
Buffer *b = CreateBuffer(sys_allocator, "*load_unicode*");
View *v = CreateView(b->id);
LoadUnicode(b);
Window *w = CreateWindow();
Buffer *b = CreateBuffer(sys_allocator, "*console*");
b->no_history = true;
View *v = CreateView(b->id);
AddView(w, v->id);
}
@@ -31,9 +32,11 @@ void InitWindows() {
window->draw_line_numbers = false;
window->draw_scrollbar = false;
window->dont_save_in_active_window_history = true;
window->visible = false;
buffer->no_history = true;
View *view = CreateView(buffer->id);
AddView(window, view->id);
DebugWindowID = window->id;
}
{
@@ -63,8 +66,7 @@ void InitWindows() {
View *v = CreateView(b->id);
AddView(w, v->id);
CommandWindowID = w->id;
Command_EvalLua(v, L"open \"./\"");
Command_EvalLua(v, L"list_buffers()");
}
{
@@ -80,6 +82,22 @@ void InitWindows() {
AddView(w, v->id);
SearchWindowID = w->id;
}
{
Window *w = CreateWindow();
w->draw_scrollbar = false;
w->draw_line_numbers = false;
w->visible = false;
w->dont_save_in_active_window_history = true;
w->invisible_when_inactive = true;
w->deactivate_on_escape = true;
Buffer *b = CreateBuffer(sys_allocator, "*popup*");
b->no_history = true;
View *v = CreateView(b->id);
AddView(w, v->id);
PopupWindowID = w->id;
}
SetActiveWindow({1});
}
@@ -89,50 +107,72 @@ void LayoutWindows() {
float line_numbers_size = GetStringSize(&MainFont, L"1234567891").x;
double sizex = (double)GetSize(screen_rect).x;
{
int i = 5;
Rect2I sr = screen_rect;
Rect2I rect = CutBottom(&sr, FontLineSpacing);
Windows[i].total_rect = rect;
Windows[i].document_rect = Windows[i].total_rect;
Windows[i].z = 1;
Window *window = GetWindow(SearchWindowID);
Rect2I sr = screen_rect;
Rect2I rect = CutBottom(&sr, FontLineSpacing);
window->total_rect = rect;
window->document_rect = window->total_rect;
window->z = 1;
}
{
int i = 0;
Windows[i].total_rect = CutLeft(&screen_rect, (Int)((double)sizex * 0.46));
Windows[i].total_rect = CutLeft(&screen_rect, (Int)((double)sizex * 0.5));
Windows[i].document_rect = Windows[i].total_rect;
if (Windows[i].draw_scrollbar) Windows[i].scrollbar_rect = CutRight(&Windows[i].document_rect, 10);
if (Windows[i].draw_line_numbers) Windows[i].line_numbers_rect = CutLeft(&Windows[i].document_rect, (Int)line_numbers_size);
}
{
int i = 1;
Windows[i].total_rect = CutLeft(&screen_rect, (Int)((double)sizex * 0.46));
Windows[i].document_rect = Windows[i].total_rect;
if (Windows[i].draw_scrollbar) Windows[i].scrollbar_rect = CutRight(&Windows[i].document_rect, 10);
if (Windows[i].draw_line_numbers) Windows[i].line_numbers_rect = CutLeft(&Windows[i].document_rect, (Int)line_numbers_size);
}
{
int i = 2;
Windows[i].total_rect = CutLeft(&screen_rect, (Int)((double)sizex));
Windows[i].document_rect = Windows[i].total_rect;
if (Windows[i].draw_scrollbar) Windows[i].scrollbar_rect = CutRight(&Windows[i].document_rect, 10);
if (Windows[i].draw_line_numbers) Windows[i].line_numbers_rect = CutLeft(&Windows[i].document_rect, (Int)line_numbers_size);
}
{
int i = 3;
Windows[i].total_rect = infobar_rect;
Windows[i].document_rect = Windows[i].total_rect;
Window *window = GetWindow(DebugWindowID);
Rect2 screen_rect = GetScreenRectF();
Vec2 size = GetSize(screen_rect);
Rect2 a = CutLeft(&screen_rect, 0.3f * size.x);
Rect2 b = CutBottom(&a, 0.4f * size.y);
Rect2 c = Shrink(b, 20);
window->z = 2;
window->total_rect = ToRect2I(c);
window->document_rect = window->total_rect;
}
{
Window *window = GetWindow(InfoBarWindowID);
window->total_rect = infobar_rect;
window->document_rect = window->total_rect;
}
{
int i = 4;
Rect2 screen_rect = GetScreenRectF();
Vec2 size = GetSize(screen_rect);
Window *window = GetWindow(CommandWindowID);
Rect2 screen_rect = GetScreenRectF();
Vec2 size = GetSize(screen_rect);
CutTop(&screen_rect, size.y * 0.05f);
CutLeft(&screen_rect, size.x * 0.2f);
CutRight(&screen_rect, size.x * 0.2f);
Rect2 r = CutTop(&screen_rect, FontLineSpacing * 30.f);
Windows[i].z = 1;
Windows[i].total_rect = ToRect2I(r);
Windows[i].document_rect = Windows[i].total_rect;
window->z = 1;
window->total_rect = ToRect2I(r);
window->document_rect = window->total_rect;
}
{
Window *window = GetWindow(PopupWindowID);
Rect2 screen_rect = GetScreenRectF();
Vec2 size = GetSize(screen_rect);
Rect2 a = CutRight(&screen_rect, 0.3f * size.x);
Rect2 b = CutBottom(&a, 0.15f * size.y);
Rect2 c = Shrink(b, 20);
window->z = 2;
window->total_rect = ToRect2I(c);
window->document_rect = window->total_rect;
}
}