Lua and better cursor movement

This commit is contained in:
Krzosa Karol
2024-07-23 16:49:13 +02:00
parent 45c6495121
commit 0ebfedbf4d
10 changed files with 164 additions and 24 deletions

View File

@@ -48,6 +48,32 @@ Library PrepareRaylib() {
return l;
}
Library PrepareLua() {
Library l = {};
l.include_paths.add("../src/external/lua/src");
MA_Scratch scratch;
for (OS_FileIter it = OS_IterateFiles(scratch, "../src/external/lua/src"); OS_IsValid(it); OS_Advance(&it)) {
if (it.filename == "luac.c") continue;
if (it.filename == "lua.c") continue;
if (S8_EndsWith(it.filename, ".c", true)) {
l.sources.add(it.absolute_path);
S8_String file = S8_ChopLastPeriod(it.filename);
l.objects.add(Fmt("%.*s.obj", S8_Expand(file)));
}
}
if (!OS_FileExists(l.objects[0])) {
Array<S8_String> cmd = {};
cmd.add("cl.exe -c");
AddCommonFlags(&cmd);
For(l.include_paths) cmd.add(S8_Format(Perm, "-I %.*s ", S8_Expand(it)));
cmd += l.sources;
Run(cmd);
}
return l;
}
Library PrepareGlad() {
Library l = {};
l.sources.add("../src/external/glad/glad.c");
@@ -69,6 +95,7 @@ int CompileTextEditor() {
Array<Library> libs = {};
libs.add(PrepareRaylib());
libs.add(PrepareLua());
Array<S8_String> cmd = {};
cmd.add("cl.exe");

View File

@@ -3,17 +3,17 @@ https://code.visualstudio.com/blogs/2018/03/23/text-buffer-reimplementation
*/
#define BUFFER_DEBUG 0
void InitBuffer(Allocator allocator, Buffer *buffer) {
void InitBuffer(Allocator allocator, Buffer *buffer, Int size = 4096) {
buffer->id = AllocBufferID();
buffer->cap = 4096;
buffer->cap = size;
buffer->data = AllocArray(allocator, U16, buffer->cap);
buffer->line_starts.allocator = allocator;
Add(&buffer->line_starts, (Int)0);
}
Buffer *CreateBuffer(Allocator allocator) {
Buffer *CreateBuffer(Allocator allocator, Int size = 4096) {
Buffer *result = Alloc(&Buffers);
InitBuffer(allocator, result);
InitBuffer(allocator, result, size);
return result;
}
@@ -188,6 +188,49 @@ void ReplaceText(Buffer *buffer, Range range, String16 string) {
#endif
}
Buffer *OpenFile(String path) {
Scratch scratch;
String string = ReadFile(scratch, path);
Allocator sys_allocator = GetSystemAllocator();
Buffer *buffer = CreateBuffer(sys_allocator, string.len * 4);
for (Int i = 0; i < string.len;) {
if (string.data[i] == '\r') {
i += 1;
continue;
}
if (string.data[i] == '\t') {
// @WARNING: DONT INCREASE THE SIZE CARELESSLY, WE NEED TO ADJUST BUFFER SIZE
for (Int i = 0; i < 4; i += 1) buffer->data[buffer->len++] = L' ';
i += 1;
continue;
}
uint32_t u32 = '?';
UTF32Result decode = UTF8ToUTF32(string.data + i, (int64_t)(string.len - i));
if (!decode.error) {
i += decode.advance;
u32 = decode.out_str;
} else {
i += 1;
}
UTF16Result encode = UTF32ToUTF16(decode.out_str);
if (!encode.error) {
for (int64_t encode_i = 0; encode_i < encode.len; encode_i += 1) {
buffer->data[buffer->len++] = encode.out_str[encode_i];
Assert(buffer->len < buffer->cap);
}
} else {
buffer->data[buffer->len++] = L'?';
}
}
UpdateLines(buffer, {}, String16{(wchar_t *)buffer->data, buffer->len});
return buffer;
}
void TestBuffer() {
Scratch scratch;
{

View File

@@ -63,18 +63,27 @@ bool IsDoubleClick() {
Int MoveOnWhitespaceBoundaryForward(Buffer &buffer, Int pos) {
pos = Clamp(pos, (Int)0, buffer.len);
bool standing_on_whitespace = IsWhitespace(buffer.str[pos]);
bool standing_on_symbol = IsSymbol(buffer.str[pos]);
bool standing_on_word = !standing_on_whitespace && !standing_on_symbol;
bool seek_whitespace = standing_on_whitespace == false;
bool seek_word = standing_on_whitespace;
bool seek_word = standing_on_whitespace || standing_on_symbol;
bool seek_symbol = standing_on_whitespace || standing_on_word;
Int result = buffer.len;
Int prev_pos = pos;
for (Int i = pos; i < buffer.len; i += 1) {
bool whitespace = IsWhitespace(buffer.str[i]);
if (seek_word && !whitespace) {
bool is_whitespace = IsWhitespace(buffer.str[i]);
bool is_symbol = IsSymbol(buffer.str[i]);
bool is_word = !is_whitespace && !is_symbol;
if (seek_word && is_word) {
result = i;
break;
}
if (seek_whitespace && whitespace) {
if (seek_whitespace && is_whitespace) {
result = i;
break;
}
if (seek_symbol && is_symbol) {
result = i;
break;
}
@@ -86,18 +95,27 @@ Int MoveOnWhitespaceBoundaryForward(Buffer &buffer, Int pos) {
Int MoveOnWhitespaceBoundaryBackward(Buffer &buffer, Int pos) {
pos = Clamp(pos - 1, (Int)0, buffer.len);
bool standing_on_whitespace = IsWhitespace(buffer.str[pos]);
bool standing_on_symbol = IsSymbol(buffer.str[pos]);
bool standing_on_word = !standing_on_whitespace && !standing_on_symbol;
bool seek_whitespace = standing_on_whitespace == false;
bool seek_word = standing_on_whitespace;
bool seek_word = standing_on_whitespace || standing_on_symbol;
bool seek_symbol = standing_on_whitespace || standing_on_word;
Int result = 0;
Int prev_pos = pos;
for (Int i = pos; i >= 0; i -= 1) {
bool whitespace = IsWhitespace(buffer.str[i]);
if (seek_word && !whitespace) {
bool is_whitespace = IsWhitespace(buffer.str[i]);
bool is_symbol = IsSymbol(buffer.str[i]);
bool is_word = !is_whitespace && !is_symbol;
if (seek_word && is_word) {
result = prev_pos;
break;
}
if (seek_whitespace && whitespace) {
if (seek_whitespace && is_whitespace) {
result = prev_pos;
break;
}
if (seek_symbol && is_symbol) {
result = prev_pos;
break;
}

View File

@@ -271,7 +271,12 @@ void HandleActiveWindowBindings(Window *window) {
Command_MoveCursorsToSide(window, DIR_RIGHT);
}
if (window->banish_new_lines == false && Press(KEY_ENTER)) {
if (CtrlPress(KEY_ENTER)) {
Int line = PosToLine(*buffer, GetFront(view.carets[0]));
Range range = GetLineRange(*buffer, line);
String16 string = GetString(*buffer, range);
EvalString(string);
} else if (window->banish_new_lines == false && Press(KEY_ENTER)) {
Command_Replace(&view, L"\n");
}

View File

@@ -0,0 +1,32 @@
lua_State *LuaState = NULL;
int LuaOpenFile(lua_State *L) {
const char *text = luaL_checkstring(L, 1);
String string = text;
Buffer *buffer = OpenFile(string);
View *view = CreateView(buffer->id);
Window *window = GetWindow({1});
AddView(window, view->id);
window->active_view = view->id;
SetActiveWindow(window->id);
return 0; // number of results
}
void InitLua() {
LuaState = luaL_newstate();
luaL_openlibs(LuaState);
lua_pushcfunction(LuaState, LuaOpenFile);
lua_setglobal(LuaState, "open");
}
void EvalString(String16 string16) {
if (!LuaState) InitLua();
Scratch scratch;
String string = ToString(scratch, string16);
if (luaL_dostring(LuaState, string.data) != LUA_OK) {
const char *text = lua_tostring(LuaState, -1);
printf("lua error: %s", text);
}
// @todo: send error or data to some buffer
}

View File

@@ -13,6 +13,11 @@ bool IsWhitespace(wchar_t w) {
return result;
}
bool IsSymbol(wchar_t w) {
bool result = (w >= '!' && w <= '/') || (w >= ':' && w <= '@') || (w >= '[' && w <= '`') || (w >= '{' && w <= '~');
return result;
}
bool IsAlphabetic(wchar_t a) {
bool result = (a >= 'a' && a <= 'z') || (a >= 'A' && a <= 'Z');
return result;

View File

@@ -1,5 +1,6 @@
#define BASIC_IMPL
#include "../basic/basic.h"
#include "../basic/filesystem.h"
#include "../profiler/profiler.cpp"
#include "new_basic.cpp"
#include "string16.cpp"
@@ -24,17 +25,25 @@
#include "window.cpp"
#include "window_draw.cpp"
#include "lua.hpp"
#include "lua_api.cpp"
/*
- Open file (utf8->utf16), process determine line endings, tabs to spaces?, Save file (utf16->utf8)
- line endings
- resize windows
- command window
- maybe use lua and have there be lua commands that you choose with cursor
- open "asd/asd/asd/asd"
- file dock on left side
- We can actually combine this with command window and lua, it's just going to be a buffer of
- open "asd/asd/asd/asd"
- Ctrl + F
- Better enclosure and word hopping
- line endings
- word completion
- Colored strings
- file dock on left side
- move off raylib
- Adjust text position a little bit down?
@@ -79,7 +88,7 @@ int main(void) {
View *view = CreateView(buffer->id);
Window *window = CreateWindow();
window->visible = false;
AddView(window->id, view->id);
AddView(window, view->id);
}
{
@@ -87,7 +96,7 @@ int main(void) {
Buffer *b = CreateBuffer(sys_allocator);
View *v = CreateView(b->id);
LoadTextA(b);
AddView(w->id, v->id);
AddView(w, v->id);
}
ActiveWindow.id = 1;
@@ -96,14 +105,13 @@ int main(void) {
Buffer *b = CreateBuffer(sys_allocator);
View *v = CreateView(b->id);
LoadUnicode(b);
AddView(w->id, v->id);
AddView(w, v->id);
}
{
Window *w = CreateWindow();
Buffer *b = CreateBuffer(sys_allocator);
Buffer *b = OpenFile("C:/Work/text_editor/src/text_editor/text_editor.cpp");
View *v = CreateView(b->id);
LoadLine(b);
AddView(w->id, v->id);
AddView(w, v->id);
}
{
Window *w = CreateWindow();
@@ -114,7 +122,7 @@ int main(void) {
Buffer *b = CreateBuffer(sys_allocator);
View *v = CreateView(b->id);
LoadLine(b);
AddView(w->id, v->id);
AddView(w, v->id);
CommandWindowID = w->id;
}

View File

@@ -134,3 +134,5 @@ inline View *GetActiveView(Window *window) {
if (window->active_view.id == 0) return GetView(window->views[0]);
else return GetView(window->active_view);
}
void EvalString(String16 string16);

View File

@@ -8,8 +8,7 @@ Window *CreateWindow() {
return w;
}
void AddView(WindowID window, ViewID view) {
Window *w = GetWindow(window);
void AddView(Window *w, ViewID view) {
if (w->active_view.id == 0) w->active_view = view;
For(w->views) if (it.id == view.id) return;
Add(&w->views, view);

View File

@@ -52,6 +52,7 @@ void DrawVisibleText(Window &window) {
Vec2I pos = {visible.min.x * (Int)FontCharSpacing, line_index * (Int)FontLineSpacing};
pos -= view.scroll;
pos += window.document_rect.min;
// pos.y += (Int)(0.3 * (double)FontSize); // @todo: descent
float text_offset_x = 0;
for (Int col_index = visible.min.x; col_index < visible.max.x && col_index >= 0 && col_index < line_string.len; col_index += 1) {