Broken, remove lua
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
- What precise workflow do I need for me to be viable to use this?
|
||||
- From a user (novice) point of view, how does it look like?
|
||||
|
||||
- Move things to window_ .cpp files (command, build, search, debug, status .. )
|
||||
- Remove LUA and replace with keybindings, config, commands
|
||||
- "DO YOU REALLY WANT TO QUIT?" popup
|
||||
- open all in the folder and ctrl + p like in VSCode (without special buffers)
|
||||
|
||||
@@ -117,24 +117,6 @@ void EndJump(BSet set) {
|
||||
UpdateScroll(set.window, true);
|
||||
}
|
||||
|
||||
Int ScreenSpaceToBufferPos(Window *window, View *view, Buffer *buffer, Vec2I mouse) {
|
||||
Vec2I mworld = mouse - window->document_rect.min + view->scroll;
|
||||
double px = (double)mworld.x / (double)window->font->char_spacing;
|
||||
double py = (double)mworld.y / (double)window->font->line_spacing;
|
||||
XY xy = {(Int)round(px), (Int)floor(py)};
|
||||
Int result = XYToPosWithoutNL(buffer, xy);
|
||||
return result;
|
||||
}
|
||||
|
||||
Int ScreenSpaceToBufferPosErrorOutOfBounds(Window *window, View *view, Buffer *buffer, Vec2I mouse) {
|
||||
Vec2I mworld = mouse - window->document_rect.min + view->scroll;
|
||||
double px = (double)mworld.x / (double)window->font->char_spacing;
|
||||
double py = (double)mworld.y / (double)window->font->line_spacing;
|
||||
XY xy = {(Int)round(px), (Int)floor(py)};
|
||||
Int result = XYToPosErrorOutOfBounds(buffer, xy);
|
||||
return result;
|
||||
}
|
||||
|
||||
void MouseLoadWord(Event event, String meta = "") {
|
||||
Vec2I mouse = MouseVec2I();
|
||||
BSet active = GetBSet(ActiveWindowID);
|
||||
@@ -387,8 +369,6 @@ void ApplyClangFormat(Buffer *buffer) {
|
||||
}
|
||||
|
||||
void SaveBuffer(Buffer *buffer) {
|
||||
CallOnSave(buffer->id);
|
||||
|
||||
Scratch scratch;
|
||||
String string = AllocCharString(scratch, buffer);
|
||||
bool success = WriteFile(buffer->name, string);
|
||||
@@ -507,6 +487,8 @@ void NewDir(Window *window, String name = "") {
|
||||
Open(name);
|
||||
}
|
||||
|
||||
String CodeEndings[] = { ".c", ".cpp", ".h", ".hpp", ".py", ".lua", ".cxx", ".hxx", };
|
||||
|
||||
void ListFilesRecursive(Buffer *buffer, String dir) {
|
||||
Scratch scratch(buffer->line_starts.allocator);
|
||||
for (FileIter it = IterateFiles(scratch, dir); IsValid(it); Advance(&it)) {
|
||||
@@ -516,11 +498,14 @@ void ListFilesRecursive(Buffer *buffer, String dir) {
|
||||
if (it.is_directory) {
|
||||
ListFilesRecursive(buffer, it.absolute_path);
|
||||
} else {
|
||||
bool good = CallIsCode(it.absolute_path);
|
||||
if (!good) {
|
||||
continue;
|
||||
bool match = false;
|
||||
ForItem (ending, CodeEndings) {
|
||||
if (EndsWith(it.absolute_path, ending)) {
|
||||
match = true;
|
||||
break;
|
||||
}
|
||||
RawAppendf(buffer, "%-80S || %S\n", it.filename, it.absolute_path);
|
||||
}
|
||||
if (match) RawAppendf(buffer, "%-80S || %S\n", it.filename, it.absolute_path);
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -541,49 +526,72 @@ BSet Exec(String cmd, String working_dir, bool set_active = true) {
|
||||
return main;
|
||||
}
|
||||
|
||||
enum OpenKind {
|
||||
OpenKind_Invalid,
|
||||
OpenKind_Skip,
|
||||
OpenKind_Exec,
|
||||
OpenKind_Goto,
|
||||
OpenKind_Command,
|
||||
};
|
||||
|
||||
struct ResolvedOpen {
|
||||
OpenKind kind;
|
||||
String path;
|
||||
Int line, col;
|
||||
};
|
||||
|
||||
ResolvedOpen ResolveOpen(String path, String meta) {
|
||||
ResolvedOpen result = {};
|
||||
|
||||
if (StartsWith(path, ":")) {
|
||||
result = OpenKind_Command;
|
||||
result.path = Skip(path, 1);
|
||||
} else if (StartsWith(path, "!")) {
|
||||
result = OpenKind_Exec;
|
||||
result.path = Skip(path, 1);
|
||||
} else if () {
|
||||
}
|
||||
}
|
||||
|
||||
BSet Open(Window *window, String path, String meta, bool set_active = true) {
|
||||
Scratch scratch;
|
||||
BSet set = GetBSet(window);
|
||||
path = Trim(path);
|
||||
OnOpenResult ores = CallOnOpen(scratch, path, meta);
|
||||
if (ores.kind == "text") {
|
||||
ResolvedOpen o = ResolveOpen(path, meta);
|
||||
if (o.kind == OpenKind_Goto) {
|
||||
if (set_active) {
|
||||
ActiveWindowID = set.window->id;
|
||||
}
|
||||
if (IsDir(ores.file_path)) {
|
||||
JumpGarbageBuffer(&set, GetUniqueBufferName(ores.file_path, "temp", ".dirlisting"));
|
||||
if (IsDir(o.path)) {
|
||||
JumpGarbageBuffer(&set, GetUniqueBufferName(o.path, "temp", ".dirlisting"));
|
||||
Appendf(set.view, "..\n");
|
||||
for (FileIter it = IterateFiles(scratch, ores.file_path); IsValid(it); Advance(&it)) {
|
||||
for (FileIter it = IterateFiles(scratch, o.path); IsValid(it); Advance(&it)) {
|
||||
Appendf(set.view, "%S\n", it.filename);
|
||||
}
|
||||
} else {
|
||||
CheckpointBeforeGoto(set.window);
|
||||
View *view = WindowOpenBufferView(set.window, ores.file_path);
|
||||
View *view = WindowOpenBufferView(set.window, o.path);
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
if (ores.line != -1) {
|
||||
if (ores.col == -1) ores.col = 1;
|
||||
Int pos = XYToPos(buffer, {ores.col - 1, ores.line - 1});
|
||||
if (o.line != -1) {
|
||||
if (o.col == -1) o.col = 1;
|
||||
Int pos = XYToPos(buffer, {o.col - 1, o.line - 1});
|
||||
view->carets[0] = MakeCaret(pos);
|
||||
}
|
||||
}
|
||||
UpdateScroll(set.window, true);
|
||||
} else if (ores.kind == "exec") {
|
||||
} else if (o.kind == OpenKind_Exec) {
|
||||
if (set_active) {
|
||||
ActiveWindowID = set.window->id;
|
||||
}
|
||||
JumpGarbageBuffer(&set);
|
||||
Exec(set.view->id, true, ores.cmd, ores.working_dir);
|
||||
} else if (ores.kind == "exec_console") {
|
||||
// this shouldn't change the focus/window/view
|
||||
Exec(NullViewID, true, ores.cmd, ores.working_dir);
|
||||
} else if (ores.kind == "skip") {
|
||||
Exec(set.view->id, true, o.path, WorkDir);
|
||||
} else if (o.kind == OpenKind_Skip) {
|
||||
return {};
|
||||
} else {
|
||||
ReportWarningf("Failed to match any of OnOpen results!");
|
||||
}
|
||||
|
||||
set = GetBSet(window);
|
||||
return set;
|
||||
return GetBSet(window);
|
||||
}
|
||||
|
||||
BSet Open(String path, String meta) {
|
||||
@@ -598,19 +606,6 @@ BSet Open(String16 path, String meta) {
|
||||
return Open(string, meta);
|
||||
}
|
||||
|
||||
void Eval(String string) {
|
||||
if (luaL_dostring(LuaState, string.data) != LUA_OK) {
|
||||
const char *error_message = lua_tostring(LuaState, -1);
|
||||
ReportWarningf("Execution error! %s", error_message);
|
||||
lua_pop(LuaState, 1);
|
||||
}
|
||||
}
|
||||
|
||||
void Eval(String16 string) {
|
||||
Scratch scratch;
|
||||
Eval(ToString(scratch, string));
|
||||
}
|
||||
|
||||
void SetProjectFile(Buffer *buffer) {
|
||||
WorkDir = ChopLastSlash(buffer->name);
|
||||
LuaProjectBuffer = buffer;
|
||||
@@ -664,13 +659,8 @@ void Command_SetProjectFile() {
|
||||
} RegisterCommand(Command_SetProjectFile, "");
|
||||
|
||||
void Command_SetWorkDir() {
|
||||
String dir = lua_tostring(LuaState, -1);
|
||||
if (dir.len == 0) {
|
||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||
WorkDir = ChopLastSlash(main.buffer->name);
|
||||
} else {
|
||||
WorkDir = dir;
|
||||
}
|
||||
} RegisterCommand(Command_SetWorkDir, "");
|
||||
|
||||
void Command_SetProject() {
|
||||
|
||||
@@ -49,7 +49,6 @@ View *TraceView;
|
||||
String WorkDir;
|
||||
RandomSeed UniqueBufferNameSeed = {};
|
||||
Array<Event> EventPlayback;
|
||||
lua_State *LuaState = NULL;
|
||||
BlockArena Perm;
|
||||
|
||||
// clipboard
|
||||
@@ -78,7 +77,6 @@ String Intern(InternTable *table, String string) {
|
||||
InternTable GlobalInternTable;
|
||||
|
||||
Array<CommandData> CommandFunctions;
|
||||
Array<LuaFunctionData> LuaFunctions;
|
||||
Array<FunctionData> TestFunctions;
|
||||
Array<Variable> Variables;
|
||||
|
||||
|
||||
@@ -1,298 +0,0 @@
|
||||
static void HookLuaForceExit(lua_State *L, lua_Debug *debug) {
|
||||
SDL_PumpEvents();
|
||||
int numkeys = 0;
|
||||
const bool *keys = SDL_GetKeyboardState(&numkeys);
|
||||
if (keys[SDL_SCANCODE_F9])
|
||||
luaL_error(L, "lua execution got interrupted");
|
||||
}
|
||||
|
||||
API double GetStyleFloat(String name, double default_float) {
|
||||
double result = default_float;
|
||||
lua_getglobal(LuaState, "Style");
|
||||
defer { lua_pop(LuaState, 1); };
|
||||
if (lua_istable(LuaState, -1)) {
|
||||
lua_pushlstring(LuaState, name.data, name.len);
|
||||
lua_gettable(LuaState, -2);
|
||||
defer { lua_pop(LuaState, 1); };
|
||||
if (lua_isnumber(LuaState, -1) || lua_isboolean(LuaState, -1) || lua_isinteger(LuaState, -1)) {
|
||||
lua_Number num = lua_tonumber(LuaState, -1);
|
||||
result = (double)num;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
API Int GetStyleInt(String name, Int default_int) {
|
||||
Int result = default_int;
|
||||
lua_getglobal(LuaState, "Style");
|
||||
defer { lua_pop(LuaState, 1); };
|
||||
if (lua_istable(LuaState, -1)) {
|
||||
lua_pushlstring(LuaState, name.data, name.len);
|
||||
lua_gettable(LuaState, -2);
|
||||
defer { lua_pop(LuaState, 1); };
|
||||
if (lua_isnumber(LuaState, -1) || lua_isboolean(LuaState, -1) || lua_isinteger(LuaState, -1)) {
|
||||
lua_Integer num = lua_tointeger(LuaState, -1);
|
||||
result = (Int)num;
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
API String GetStyleString(String name, String default_string) {
|
||||
String result = default_string;
|
||||
lua_getglobal(LuaState, "Style");
|
||||
defer { lua_pop(LuaState, 1); };
|
||||
if (lua_istable(LuaState, -1)) {
|
||||
lua_pushlstring(LuaState, name.data, name.len);
|
||||
lua_gettable(LuaState, -2);
|
||||
defer { lua_pop(LuaState, 1); };
|
||||
if (lua_isstring(LuaState, -1)) {
|
||||
const char *string = lua_tostring(LuaState, -1);
|
||||
result = Intern(&GlobalInternTable, string);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
API Color GetColor(String name, Color default_color) {
|
||||
Color result = default_color;
|
||||
lua_getglobal(LuaState, "Color");
|
||||
defer { lua_pop(LuaState, 1); };
|
||||
if (lua_istable(LuaState, -1)) {
|
||||
lua_pushlstring(LuaState, name.data, name.len);
|
||||
lua_gettable(LuaState, -2);
|
||||
defer { lua_pop(LuaState, 1); };
|
||||
if (lua_isnumber(LuaState, -1)) {
|
||||
lua_Integer num = lua_tointeger(LuaState, -1);
|
||||
result.r = (uint8_t)((0xFF000000 & num) >> 24);
|
||||
result.g = (uint8_t)((0x00FF0000 & num) >> 16);
|
||||
result.b = (uint8_t)((0x0000FF00 & num) >> 8);
|
||||
result.a = (uint8_t)((0x000000FF & num) >> 0);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
API String GetFieldString(lua_State *L, String name) {
|
||||
String result = {};
|
||||
if (lua_istable(L, -1)) {
|
||||
lua_pushlstring(L, name.data, name.len);
|
||||
lua_gettable(L, -2);
|
||||
defer { lua_pop(L, 1); };
|
||||
if (lua_isstring(L, -1)) {
|
||||
result = lua_tostring(L, -1);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
extern String BaseLuaConfig;
|
||||
|
||||
API void LoadLuaBuffer(Buffer *lua_buffer) {
|
||||
if (!lua_buffer) return;
|
||||
ReportConsolef("reloading config: %S", lua_buffer->name);
|
||||
|
||||
Scratch scratch;
|
||||
String string = AllocCharString(scratch, lua_buffer);
|
||||
if (luaL_dostring(LuaState, string.data) == LUA_OK) {
|
||||
if (lua_isstring(LuaState, -1)) {
|
||||
const char *text = lua_tostring(LuaState, -1);
|
||||
ReportConsolef(text);
|
||||
lua_pop(LuaState, 1);
|
||||
}
|
||||
} else {
|
||||
const char *error_message = lua_tostring(LuaState, -1);
|
||||
ReportWarningf("Failed to load user config! %s", error_message);
|
||||
lua_pop(LuaState, 1);
|
||||
}
|
||||
lua_buffer->user_change_id = lua_buffer->change_id;
|
||||
}
|
||||
|
||||
API void ReloadLuaConfigs(bool reload) {
|
||||
if (LuaConfigBuffer && !LuaConfigBuffer->dirty && LuaConfigBuffer->change_id != LuaConfigBuffer->user_change_id) {
|
||||
reload = true;
|
||||
}
|
||||
if (LuaProjectBuffer && !LuaProjectBuffer->dirty && LuaProjectBuffer->change_id != LuaProjectBuffer->user_change_id) {
|
||||
reload = true;
|
||||
}
|
||||
if (reload == false) {
|
||||
return;
|
||||
}
|
||||
|
||||
LoadLuaBuffer(LuaConfigBuffer);
|
||||
LoadLuaBuffer(LuaProjectBuffer);
|
||||
|
||||
For (Variables) {
|
||||
if (it.type == VariableType_Color) it.color[0] = GetColor(Skip(it.name, 5), it.color[0]);
|
||||
else if (it.type == VariableType_Int) it.i[0] = GetStyleInt(Skip(it.name, 5), it.i[0]);
|
||||
else if (it.type == VariableType_String) it.string[0] = GetStyleString(Skip(it.name, 5), it.string[0]);
|
||||
else if (it.type == VariableType_Float) it.f[0] = GetStyleFloat(Skip(it.name, 5), it.f[0]);
|
||||
else Assert(!"Invalid codepath");
|
||||
}
|
||||
ReloadFont(StyleFont, (U32)StyleFontSize);
|
||||
For(Windows) {
|
||||
it->draw_scrollbar = StyleDrawScrollbar;
|
||||
it->draw_line_numbers = StyleDrawLineNumbers;
|
||||
}
|
||||
}
|
||||
|
||||
API bool CallLuaFunc(char *func_name, int arg_count, int ret_count) {
|
||||
if (lua_pcall(LuaState, arg_count, ret_count, 0) != 0) {
|
||||
const char *error_message = lua_tostring(LuaState, -1);
|
||||
ReportWarningf("Failed to call a lua function: %s! %s", func_name, error_message);
|
||||
lua_pop(LuaState, 1);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
void CallLuaOnInit() {
|
||||
lua_getglobal(LuaState, "OnInit");
|
||||
CallLuaFunc("OnInit", 0, 0);
|
||||
}
|
||||
|
||||
API void InitLuaConfig() {
|
||||
LuaState = luaL_newstate();
|
||||
luaL_openlibs(LuaState);
|
||||
lua_sethook(LuaState, HookLuaForceExit, LUA_MASKCOUNT, 100000000);
|
||||
|
||||
For(LuaFunctions) {
|
||||
lua_pushcfunction(LuaState, it.function);
|
||||
lua_setglobal(LuaState, it.name.data);
|
||||
}
|
||||
|
||||
#if OS_WINDOWS
|
||||
lua_pushinteger(LuaState, 0);
|
||||
#else
|
||||
lua_pushinteger(LuaState, 1);
|
||||
#endif
|
||||
lua_setglobal(LuaState, "OS_VALUE");
|
||||
|
||||
// Init base config, test that it works and initialize the lua stuff
|
||||
if (!luaL_dostring(LuaState, BaseLuaConfig.data) == LUA_OK) {
|
||||
const char *error_message = lua_tostring(LuaState, -1);
|
||||
ReportErrorf("Failed to load base lua config! %s", error_message);
|
||||
lua_pop(LuaState, 1);
|
||||
Assert(!"Invalid codepath");
|
||||
}
|
||||
|
||||
// Init user config
|
||||
Buffer *lua_buffer = NULL;
|
||||
|
||||
Scratch scratch;
|
||||
String lua_config_exe = Format(scratch, "%S/init.lua", GetExeDir(scratch));
|
||||
if (FileExists(lua_config_exe)) {
|
||||
lua_buffer = BufferOpenFile(lua_config_exe);
|
||||
}
|
||||
|
||||
if (lua_buffer == NULL) {
|
||||
String lua_config_remote = Format(scratch, "%S/init.lua", ConfigDir);
|
||||
// #if DEBUG_BUILD
|
||||
// // WARNING! Delete config to make sure we are running this code more frequently
|
||||
// SDL_RemovePath(lua_config_remote.data);
|
||||
// ReportConsolef("deleting config for debug purposes!");
|
||||
// #endif
|
||||
lua_buffer = BufferOpenFile(lua_config_remote);
|
||||
if (lua_buffer->len == 0) {
|
||||
String16 string16 = ToString16(scratch, BaseLuaConfig);
|
||||
RawReplaceText(lua_buffer, {}, string16);
|
||||
ReportConsolef("no config at: %S - creating config buffer", lua_config_remote);
|
||||
}
|
||||
}
|
||||
LuaConfigBuffer = lua_buffer;
|
||||
ReloadLuaConfigs(true);
|
||||
CallLuaOnInit();
|
||||
}
|
||||
|
||||
struct OnOpenResult {
|
||||
String kind;
|
||||
String file_path;
|
||||
Int line, col;
|
||||
String working_dir;
|
||||
String cmd;
|
||||
};
|
||||
|
||||
OnOpenResult CallOnOpen(Allocator allocator, String path, String meta) {
|
||||
lua_getglobal(LuaState, "OnOpen");
|
||||
lua_pushlstring(LuaState, path.data, path.len);
|
||||
lua_pushlstring(LuaState, meta.data, meta.len);
|
||||
if (!CallLuaFunc("OnOpen", 2, 1)) {
|
||||
return {};
|
||||
}
|
||||
|
||||
String file_path = GetFieldString(LuaState, "file_path");
|
||||
String line_string = GetFieldString(LuaState, "line");
|
||||
String col_string = GetFieldString(LuaState, "col");
|
||||
String cmd = GetFieldString(LuaState, "cmd");
|
||||
String working_dir = GetFieldString(LuaState, "working_dir");
|
||||
String kind = GetFieldString(LuaState, "kind");
|
||||
|
||||
OnOpenResult result = {};
|
||||
result.cmd = cmd;
|
||||
result.working_dir = working_dir;
|
||||
result.file_path = file_path;
|
||||
if (!IsAbsolute(result.file_path)) {
|
||||
String dir = GetMainDir();
|
||||
result.file_path = Format(allocator, "%S/%S", dir, result.file_path);
|
||||
}
|
||||
if (col_string.len) {
|
||||
result.col = strtoll(col_string.data, NULL, 10);
|
||||
} else {
|
||||
result.col = -1;
|
||||
}
|
||||
if (line_string.len) {
|
||||
result.line = strtoll(line_string.data, NULL, 10);
|
||||
} else {
|
||||
result.line = -1;
|
||||
}
|
||||
result.kind = kind;
|
||||
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
bool CallIsCode(String path, String meta = "") {
|
||||
lua_getglobal(LuaState, "IsCode");
|
||||
lua_pushlstring(LuaState, path.data, path.len);
|
||||
lua_pushlstring(LuaState, meta.data, meta.len);
|
||||
if (!CallLuaFunc("IsCode", 2, 1)) {
|
||||
return false;
|
||||
}
|
||||
|
||||
bool result = lua_toboolean(LuaState, -1);
|
||||
lua_pop(LuaState, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
void CallOnSave(BufferID buffer_id) {
|
||||
lua_getglobal(LuaState, "OnSave");
|
||||
lua_pushinteger(LuaState, buffer_id.id);
|
||||
CallLuaFunc("OnSave", 1, 0);
|
||||
}
|
||||
|
||||
void PushEvent(lua_State *L, Event *event) {
|
||||
lua_createtable(L, 0, EVENT_FIELD_COUNT);
|
||||
#define lua_pushInt lua_pushinteger
|
||||
#define lua_pushString lua_pushstring
|
||||
#define lua_pushFloat lua_pushnumber
|
||||
#define X(TYPE, KIND, NAME) \
|
||||
lua_push##KIND(L, event->NAME); \
|
||||
lua_setfield(L, -2, #NAME);
|
||||
EVENT_FIELDS
|
||||
#undef X
|
||||
}
|
||||
|
||||
bool CallOnCommand(Event *event) {
|
||||
lua_getglobal(LuaState, "OnCommand");
|
||||
PushEvent(LuaState, event);
|
||||
CallLuaFunc("OnCommand", 1, 1);
|
||||
bool result = lua_toboolean(LuaState, -1);
|
||||
lua_pop(LuaState, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
void CallLuaOnUpdate(Event *event) {
|
||||
lua_getglobal(LuaState, "OnUpdate");
|
||||
PushEvent(LuaState, event);
|
||||
CallLuaFunc("OnUpdate", 1, 0);
|
||||
}
|
||||
@@ -1,9 +0,0 @@
|
||||
API double GetStyleFloat(String name, double default_float);
|
||||
API Int GetStyleInt(String name, Int default_int);
|
||||
API String GetStyleString(String name, String default_string);
|
||||
API Color GetColor(String name, Color default_color);
|
||||
API String GetFieldString(lua_State *L, String name);
|
||||
API void LoadLuaBuffer(Buffer *lua_buffer);
|
||||
API void ReloadLuaConfigs(bool reload = false);
|
||||
API bool CallLuaFunc(char *func_name, int arg_count, int ret_count);
|
||||
API void InitLuaConfig();
|
||||
@@ -1,297 +0,0 @@
|
||||
int Lua_print(lua_State *L) {
|
||||
Scratch scratch;
|
||||
int nargs = lua_gettop(L);
|
||||
View *null_view = GetView(NullViewID);
|
||||
for (int i = 1; i <= nargs; i += 1) {
|
||||
String string = lua_tostring(L, i);
|
||||
Appendf(null_view, "%S ", string);
|
||||
}
|
||||
Appendf(null_view, "\n");
|
||||
lua_pop(L, nargs);
|
||||
return 0;
|
||||
} RegisterLua(Lua_print);
|
||||
|
||||
int Lua_Print(lua_State *L) {
|
||||
Scratch scratch;
|
||||
int nargs = lua_gettop(L);
|
||||
for (int i = 1; i <= nargs; i += 1) {
|
||||
String string = lua_tostring(L, i);
|
||||
Appendf(TraceView, "%S ", string);
|
||||
}
|
||||
Appendf(TraceView, "\n");
|
||||
lua_pop(L, nargs);
|
||||
return 0;
|
||||
} RegisterLua(Lua_Print);
|
||||
|
||||
int Lua_GetLoadWord(lua_State *L) {
|
||||
BSet active = GetBSet(ActiveWindowID);
|
||||
Range range = active.view->carets[0].range;
|
||||
if (GetSize(range) == 0) {
|
||||
range = EncloseLoadWord(active.buffer, range.min);
|
||||
}
|
||||
|
||||
Scratch scratch;
|
||||
String string = AllocCharString(scratch, active.buffer, range);
|
||||
lua_pushlstring(L, string.data, string.len);
|
||||
return 1;
|
||||
} RegisterLua(Lua_GetLoadWord);
|
||||
|
||||
int Lua_BufferExists(lua_State *L) {
|
||||
String string = lua_tostring(L, 1);
|
||||
lua_pop(L, 1);
|
||||
Buffer *buffer = GetBuffer(string);
|
||||
lua_pushboolean(L, buffer != NULL);
|
||||
return 1;
|
||||
} RegisterLua(Lua_BufferExists);
|
||||
|
||||
int Lua_GetSelection(lua_State *L) {
|
||||
Scratch scratch;
|
||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||
String16 string16 = GetString(main.buffer, main.view->carets[0].range);
|
||||
String string = ToString(scratch, string16);
|
||||
lua_pushlstring(L, string.data, string.len);
|
||||
return 1;
|
||||
} RegisterLua(Lua_GetSelection);
|
||||
|
||||
int Lua_GetEntireBuffer(lua_State *L) {
|
||||
Scratch scratch;
|
||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||
String16 string16 = GetString(main.buffer);
|
||||
String string = ToString(scratch, string16);
|
||||
lua_pushlstring(L, string.data, string.len);
|
||||
return 1;
|
||||
} RegisterLua(Lua_GetEntireBuffer);
|
||||
|
||||
int Lua_GetClipboard(lua_State *L) {
|
||||
Scratch scratch;
|
||||
String string = ToString(scratch, SavedClipboardString);
|
||||
lua_pushlstring(L, string.data, string.len);
|
||||
return 1;
|
||||
} RegisterLua(Lua_GetClipboard);
|
||||
|
||||
int Lua_GetFilename(lua_State *L) {
|
||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||
lua_pushlstring(L, main.buffer->name.data, main.buffer->name.len);
|
||||
return 1;
|
||||
} RegisterLua(Lua_GetFilename);
|
||||
|
||||
int Lua_GetLine(lua_State *L) {
|
||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||
Caret caret = main.view->carets[0];
|
||||
Int front = GetFront(caret);
|
||||
Int line = PosToLine(main.buffer, front);
|
||||
lua_pushinteger(L, line + 1);
|
||||
return 1;
|
||||
} RegisterLua(Lua_GetLine);
|
||||
|
||||
int Lua_FileExists(lua_State *L) {
|
||||
String path = luaL_checkstring(L, 1);
|
||||
lua_pop(L, 1);
|
||||
bool exists = FileExists(path);
|
||||
lua_pushboolean(L, exists);
|
||||
return 1;
|
||||
} RegisterLua(Lua_FileExists);
|
||||
|
||||
int Lua_GetWorkDir(lua_State *L) {
|
||||
lua_pushlstring(L, WorkDir.data, WorkDir.len);
|
||||
return 1;
|
||||
} RegisterLua(Lua_GetWorkDir);
|
||||
|
||||
int Lua_GetExeDir(lua_State *L) {
|
||||
Scratch scratch;
|
||||
String exe_dir = GetExeDir(scratch);
|
||||
lua_pushlstring(L, exe_dir.data, exe_dir.len);
|
||||
return 1;
|
||||
} RegisterLua(Lua_GetExeDir);
|
||||
|
||||
int Lua_GetMainDir(lua_State *L) {
|
||||
String name = GetMainDir();
|
||||
lua_pushlstring(L, name.data, name.len);
|
||||
return 1;
|
||||
} RegisterLua(Lua_GetMainDir);
|
||||
|
||||
int Lua_ListCommands(lua_State *L) {
|
||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||
BeginJump(&main);
|
||||
int i = 0;
|
||||
For (LuaFunctions) {
|
||||
Appendf(main.view, "%20S() ", it.name);
|
||||
if (((i + 1) % 6) == 0) {
|
||||
Appendf(main.view, "\n");
|
||||
}
|
||||
i += 1;
|
||||
}
|
||||
EndJump(main);
|
||||
ActiveWindowID = main.window->id;
|
||||
return 0;
|
||||
} RegisterLua(Lua_ListCommands);
|
||||
|
||||
int Lua_GetBufferList(lua_State *L) {
|
||||
lua_createtable(L, 0, (int)Buffers.len);
|
||||
|
||||
int i = 1;
|
||||
For(Buffers) {
|
||||
lua_pushinteger(L, i++);
|
||||
lua_pushlstring(L, it->name.data, it->name.len);
|
||||
lua_settable(L, -3); /* 3rd element from the stack top */
|
||||
}
|
||||
/* We still have table left on top of the Lua stack. */
|
||||
return 1;
|
||||
} RegisterLua(Lua_GetBufferList);
|
||||
|
||||
int Lua_Eval(lua_State *L) {
|
||||
String string = lua_tostring(L, 1);
|
||||
lua_pop(L, 1);
|
||||
Eval(string);
|
||||
return 0;
|
||||
} RegisterLua(Lua_Eval);
|
||||
|
||||
int Lua_ApplyClangFormat(lua_State *L) {
|
||||
lua_Integer buffer_id = luaL_checkinteger(L, 1);
|
||||
lua_pop(L, 1);
|
||||
Buffer *buffer = GetBuffer({buffer_id});
|
||||
ApplyClangFormat(buffer);
|
||||
return 0;
|
||||
} RegisterLua(Lua_ApplyClangFormat);
|
||||
|
||||
int Lua_GetBufferNameByID(lua_State *L) {
|
||||
lua_Integer buffer_id = luaL_checkinteger(L, 1);
|
||||
lua_pop(L, 1);
|
||||
Buffer *buffer = GetBuffer({buffer_id});
|
||||
lua_pushlstring(L, buffer->name.data, buffer->name.len);
|
||||
return 1;
|
||||
} RegisterLua(Lua_GetBufferNameByID);
|
||||
|
||||
|
||||
int Lua_ConvertLineEndingsToLF(lua_State *L) {
|
||||
lua_Integer buffer_id = luaL_checkinteger(L, 1);
|
||||
int trim_lines_with_caret = lua_toboolean(L, 2);
|
||||
lua_pop(L, 2);
|
||||
Buffer *buffer = GetBuffer({buffer_id});
|
||||
ConvertLineEndingsToLF(buffer, trim_lines_with_caret);
|
||||
return 0;
|
||||
} RegisterLua(Lua_ConvertLineEndingsToLF);
|
||||
|
||||
int Lua_New(lua_State *L) {
|
||||
String name = lua_tostring(L, 1);
|
||||
lua_pop(L, 1);
|
||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||
New(main.window, name);
|
||||
return 0;
|
||||
} RegisterLua(Lua_New);
|
||||
|
||||
int Lua_NewDir(lua_State *L) {
|
||||
String name = lua_tostring(L, 1);
|
||||
lua_pop(L, 1);
|
||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||
NewDir(main.window, name);
|
||||
return 0;
|
||||
} RegisterLua(Lua_NewDir);
|
||||
|
||||
int Lua_C(lua_State *L) {
|
||||
String string = lua_tostring(L, 1);
|
||||
lua_pop(L, 1);
|
||||
Exec(string, GetMainDir());
|
||||
return 0;
|
||||
} RegisterLua(Lua_C);
|
||||
|
||||
int Lua_Open(lua_State *L) {
|
||||
Scratch scratch;
|
||||
String path = luaL_checkstring(L, 1);
|
||||
lua_pop(L, 1);
|
||||
Open(path);
|
||||
return 0;
|
||||
} RegisterLua(Lua_Open);
|
||||
|
||||
int Lua_Cmd(lua_State *L) {
|
||||
if (!lua_istable(L, -1)) luaL_error(L, "expected a table as argument");
|
||||
defer { lua_pop(L, 1); };
|
||||
|
||||
lua_getfield(L, -1, "working_dir");
|
||||
String working_dir = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
if (working_dir == "") {
|
||||
working_dir = GetMainDir();
|
||||
}
|
||||
|
||||
lua_getfield(L, -1, "cmd");
|
||||
if (!lua_isstring(L, -1)) luaL_error(L, "expected a string for cmd param");
|
||||
String cmd = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
lua_getfield(L, -1, "kind");
|
||||
String kind = lua_tostring(L, -1);
|
||||
lua_pop(L, 1);
|
||||
|
||||
BSet main = GetBSet(LastActiveLayoutWindowID);
|
||||
if (kind == "console") {
|
||||
BSet set = GetConsoleSet();
|
||||
main.window->active_goto_list = set.view->id;
|
||||
main.window->goto_list_pos = set.buffer->len;
|
||||
SelectRange(set.view, MakeRange(set.buffer->len));
|
||||
BeginJump(&set);
|
||||
Exec(set.view->id, true, cmd, working_dir);
|
||||
EndJump(set);
|
||||
} else {
|
||||
JumpGarbageBuffer(&main);
|
||||
main.window->active_goto_list = main.view->id;
|
||||
main.window->goto_list_pos = 0;
|
||||
Exec(main.view->id, true, cmd, working_dir);
|
||||
ActiveWindowID = main.window->id;
|
||||
}
|
||||
|
||||
return 0;
|
||||
} RegisterLua(Lua_Cmd);
|
||||
|
||||
Int GetFieldAInt(lua_State *L, const char *name) {
|
||||
lua_getfield(L, -1, name);
|
||||
lua_Integer num = lua_tointeger(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return (Int)num;
|
||||
}
|
||||
|
||||
double GetFieldAFloat(lua_State *L, const char *name) {
|
||||
lua_getfield(L, -1, name);
|
||||
double num = lua_tonumber(L, -1);
|
||||
lua_pop(L, 1);
|
||||
return num;
|
||||
}
|
||||
|
||||
const char *GetFieldAString(lua_State *L, const char *name) {
|
||||
lua_getfield(L, -1, name);
|
||||
const char *result = lua_tostring(L, -1);
|
||||
|
||||
lua_pop(L, 1);
|
||||
return result;
|
||||
}
|
||||
|
||||
// :Event
|
||||
int Lua_Play(lua_State *L) {
|
||||
if (!lua_istable(L, -1)) luaL_error(L, "expected a table of events");
|
||||
defer { lua_pop(L, 1); };
|
||||
|
||||
int size = (int)lua_rawlen(L, -1);
|
||||
for (int i = 0; i < size; i += 1) {
|
||||
lua_geti(L, -1, i + 1);
|
||||
if (!lua_istable(L, -1)) luaL_error(L, "expected a table of events");
|
||||
defer { lua_pop(L, 1); };
|
||||
|
||||
Event event = {};
|
||||
#define X(TYPE, KIND, NAME) event.NAME = (TYPE)GetFieldA##KIND(L, #NAME);
|
||||
EVENT_FIELDS
|
||||
#undef X
|
||||
Add(&EventPlayback, event);
|
||||
}
|
||||
|
||||
return 0;
|
||||
} RegisterLua(Lua_Play);
|
||||
|
||||
|
||||
int Lua_TrimTrailingWhitespace(lua_State *L) {
|
||||
lua_Integer buffer_id = luaL_checkinteger(L, 1);
|
||||
int trim_lines_with_caret = lua_toboolean(L, 2);
|
||||
lua_pop(L, 2);
|
||||
Buffer *buffer = GetBuffer({buffer_id});
|
||||
TrimTrailingWhitespace(buffer, trim_lines_with_caret);
|
||||
return 0;
|
||||
} RegisterLua(Lua_TrimTrailingWhitespace);
|
||||
@@ -12,8 +12,6 @@
|
||||
#endif
|
||||
#define MINICORO_IMPL
|
||||
#include "external/minicoro.h"
|
||||
#define LUA_USE_LONGJMP
|
||||
#include "external/luaunity.c"
|
||||
|
||||
#include "render/generated_font.cpp"
|
||||
#include "render/font.cpp"
|
||||
@@ -23,10 +21,8 @@
|
||||
#include "view.h"
|
||||
#include "window.h"
|
||||
#include "text_editor.h"
|
||||
#include "lua.h"
|
||||
|
||||
#include "globals.cpp"
|
||||
#include "lua.cpp"
|
||||
#include "buffer.cpp"
|
||||
#include "view.cpp"
|
||||
#include "window.cpp"
|
||||
@@ -39,13 +35,9 @@
|
||||
#include "event.cpp"
|
||||
#include "parser.cpp"
|
||||
|
||||
|
||||
#include "commands.cpp"
|
||||
#include "lua_api.cpp"
|
||||
#include "commands_clipboard.cpp"
|
||||
|
||||
#include "generated_config.cpp"
|
||||
|
||||
#include "draw.cpp"
|
||||
#include "coroutines.cpp"
|
||||
#include "test/tests.cpp"
|
||||
@@ -511,8 +503,6 @@ void Update(Event event) {
|
||||
CommandWindowUpdate();
|
||||
UpdateProcesses();
|
||||
CoUpdate(&event);
|
||||
ReloadLuaConfigs();
|
||||
CallLuaOnUpdate(&event);
|
||||
GarbageCollect();
|
||||
|
||||
For(IterateInReverse(&order)) {
|
||||
@@ -744,7 +734,6 @@ int main(int argc, char **argv)
|
||||
}
|
||||
|
||||
ReportConsolef("WorkDir = %S", WorkDir);
|
||||
InitLuaConfig();
|
||||
if (Testing) InitTests();
|
||||
#if OS_WINDOWS
|
||||
CoAdd(Windows_SetupVCVarsall);
|
||||
|
||||
@@ -130,9 +130,7 @@ Buffer *BufferOpenFile(String path);
|
||||
|
||||
typedef void Function();
|
||||
typedef void PFunction(void *param);
|
||||
typedef int LuaFunction(lua_State *state);
|
||||
struct FunctionData { String name; Function *function; };
|
||||
struct LuaFunctionData { String name; LuaFunction *function; };
|
||||
struct CommandData { String name; String binding; Function *function; struct Trigger *trigger; };
|
||||
struct PFunctionData { String name; PFunction *function; };
|
||||
|
||||
@@ -148,9 +146,6 @@ struct Register_Function {
|
||||
};
|
||||
#define RegisterFunction(functions, name) Register_Function RF__##name(functions, #name, name)
|
||||
|
||||
struct Register_Lua { Register_Lua(Array<LuaFunctionData> *funcs, LuaFunction *function, String name) { if (StartsWith(name, "Lua_")) name = Skip(name, 4); Add(funcs, {name, function}); } };
|
||||
#define RegisterLua(NAME) Register_Lua RL_##NAME(&LuaFunctions, NAME, #NAME)
|
||||
|
||||
struct Register_Command { Register_Command(Array<CommandData> *fucs, Function *function, String name, String binding) { if (StartsWith(name, "Command_")) name = Skip(name, 8); Add(fucs, {name, binding, function}); } };
|
||||
#define RegisterCommand(name, binding) Register_Command RC__##name(&CommandFunctions, name, #name, binding)
|
||||
|
||||
|
||||
@@ -204,3 +204,81 @@ Window *SwitchWindow(int direction) {
|
||||
Window *result = GetOverlappingWindow(p, window);
|
||||
return result;
|
||||
}
|
||||
|
||||
Int ScreenSpaceToBufferPos(Window *window, View *view, Buffer *buffer, Vec2I mouse) {
|
||||
Vec2I mworld = mouse - window->document_rect.min + view->scroll;
|
||||
double px = (double)mworld.x / (double)window->font->char_spacing;
|
||||
double py = (double)mworld.y / (double)window->font->line_spacing;
|
||||
XY xy = {(Int)round(px), (Int)floor(py)};
|
||||
Int result = XYToPosWithoutNL(buffer, xy);
|
||||
return result;
|
||||
}
|
||||
|
||||
Int ScreenSpaceToBufferPosErrorOutOfBounds(Window *window, View *view, Buffer *buffer, Vec2I mouse) {
|
||||
Vec2I mworld = mouse - window->document_rect.min + view->scroll;
|
||||
double px = (double)mworld.x / (double)window->font->char_spacing;
|
||||
double py = (double)mworld.y / (double)window->font->line_spacing;
|
||||
XY xy = {(Int)round(px), (Int)floor(py)};
|
||||
Int result = XYToPosErrorOutOfBounds(buffer, xy);
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
void CheckpointBeforeGoto(Window *window, View *view) {
|
||||
if (window->jump_history == false) return;
|
||||
Add(&window->goto_history, {view->id, view->carets[0], GetTimeSeconds()});
|
||||
window->goto_redo.len = 0;
|
||||
}
|
||||
|
||||
void CheckpointBeforeGoto(Window *window) {
|
||||
CheckpointBeforeGoto(window, GetView(window->active_view));
|
||||
}
|
||||
|
||||
GotoCrumb GetCrumb(Array<GotoCrumb> *cr) {
|
||||
for (; cr->len;) {
|
||||
GotoCrumb c = Pop(cr);
|
||||
View *view = FindView(c.view_id);
|
||||
if (view) return c;
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
void GotoBackward(Window *window) {
|
||||
if (window->jump_history == false) return;
|
||||
if (window->goto_history.len <= 0) return;
|
||||
BSet set = GetBSet(window);
|
||||
Add(&window->goto_redo, {set.view->id, set.view->carets[0], GetTimeSeconds()});
|
||||
|
||||
GotoCrumb c = GetCrumb(&window->goto_history);
|
||||
window->active_view = c.view_id;
|
||||
View *view = GetView(c.view_id);
|
||||
view->carets[0] = c.caret;
|
||||
UpdateScroll(window, true);
|
||||
|
||||
if (window->goto_history.len) {
|
||||
GotoCrumb *next = GetLast(window->goto_history);
|
||||
if (c.time - next->time <= StyleUndoMergeTimeout) {
|
||||
GotoBackward(window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void GotoForward(Window *window) {
|
||||
if (window->goto_redo.len <= 0) return;
|
||||
if (window->jump_history == false) return;
|
||||
BSet set = GetBSet(window);
|
||||
Add(&window->goto_history, {set.view->id, set.view->carets[0], GetTimeSeconds()});
|
||||
|
||||
GotoCrumb c = GetCrumb(&window->goto_redo);
|
||||
window->active_view = c.view_id;
|
||||
View *view = GetView(c.view_id);
|
||||
view->carets[0] = c.caret;
|
||||
UpdateScroll(window, true);
|
||||
|
||||
if (window->goto_redo.len) {
|
||||
GotoCrumb *next = GetLast(window->goto_redo);
|
||||
if (c.time - next->time <= StyleUndoMergeTimeout) {
|
||||
GotoForward(window);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -67,20 +67,6 @@ void Command_ShowCommands() {
|
||||
SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer));
|
||||
} RegisterCommand(Command_ShowCommands, "ctrl-shift-p");
|
||||
|
||||
void Command_ShowLuaFunctions() {
|
||||
BSet command_bar = GetBSet(CommandBarWindowID);
|
||||
command_bar.window->visible = true;
|
||||
command_bar.window->eval_command = false;
|
||||
ActiveWindowID = command_bar.window->id;
|
||||
ResetBuffer(command_bar.buffer);
|
||||
For(LuaFunctions) {
|
||||
Appendf(command_bar.view, "%S()\n ", it.name);
|
||||
}
|
||||
command_bar.view->update_scroll = true;
|
||||
SelectRange(command_bar.view, GetBufferEndAsRange(command_bar.buffer));
|
||||
} RegisterCommand(Command_ShowLuaFunctions, "");
|
||||
|
||||
|
||||
void Command_ShowBufferList() {
|
||||
BSet command_bar = GetBSet(CommandBarWindowID);
|
||||
command_bar.window->visible = true;
|
||||
|
||||
Reference in New Issue
Block a user