Editing infobar applies changes to buffer
This commit is contained in:
@@ -700,7 +700,6 @@ struct CircularArray {
|
|||||||
T *data;
|
T *data;
|
||||||
int16_t cap;
|
int16_t cap;
|
||||||
int16_t write;
|
int16_t write;
|
||||||
int16_t buffer_is_full;
|
|
||||||
};
|
};
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
@@ -718,25 +717,23 @@ void Add(CircularArray<T> *arr, T item) {
|
|||||||
arr->cap = 128;
|
arr->cap = 128;
|
||||||
arr->data = AllocArray(arr->allocator, T, arr->cap);
|
arr->data = AllocArray(arr->allocator, T, arr->cap);
|
||||||
}
|
}
|
||||||
int idx = arr->write;
|
int16_t i = arr->write;
|
||||||
arr->write = (arr->write + 1) % arr->cap;
|
arr->write = (arr->write + 1) % arr->cap;
|
||||||
if (arr->write == 0) arr->buffer_is_full = 1;
|
arr->data[i] = item;
|
||||||
arr->data[idx] = item;
|
}
|
||||||
|
|
||||||
|
static int GetCircularIndex(int cap, int idx) {
|
||||||
|
int result = idx % cap;
|
||||||
|
if (result < 0) result = cap + result;
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
template <class T>
|
template <class T>
|
||||||
T Get(CircularArray<T> *arr, int idx, T default_value) {
|
T Get(CircularArray<T> *arr, int idx, T default_value) {
|
||||||
if (idx >= arr->cap) return default_value;
|
int idx = circ->write - 1 - i;
|
||||||
int i = arr->write - 1 - idx;
|
idx = GetCircularIndex(circ->size, idx);
|
||||||
if (i < 0 && arr->buffer_is_full) {
|
int result = circ->data[idx];
|
||||||
i = arr->cap + i;
|
return result;
|
||||||
}
|
|
||||||
|
|
||||||
if (i >= 0 && i < arr->cap) {
|
|
||||||
return arr->data[i];
|
|
||||||
} else {
|
|
||||||
return default_value;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
struct UTF32Result {
|
struct UTF32Result {
|
||||||
|
|||||||
@@ -150,3 +150,42 @@ String16 CutPostfix(String16 *string, int64_t len) {
|
|||||||
*string = Chop(*string, len);
|
*string = Chop(*string, len);
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
String16 Trim(String16 string) {
|
||||||
|
if (string.len == 0)
|
||||||
|
return string;
|
||||||
|
|
||||||
|
int64_t whitespace_begin = 0;
|
||||||
|
for (; whitespace_begin < string.len; whitespace_begin++) {
|
||||||
|
if (!IsWhitespace(string.data[whitespace_begin])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int64_t whitespace_end = string.len;
|
||||||
|
for (; whitespace_end != whitespace_begin; whitespace_end--) {
|
||||||
|
if (!IsWhitespace(string.data[whitespace_end - 1])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (whitespace_begin == whitespace_end) {
|
||||||
|
string.len = 0;
|
||||||
|
} else {
|
||||||
|
string = GetSlice(string, whitespace_begin, whitespace_end);
|
||||||
|
}
|
||||||
|
|
||||||
|
return string;
|
||||||
|
}
|
||||||
|
|
||||||
|
String16 TrimEnd(String16 string) {
|
||||||
|
int64_t whitespace_end = string.len;
|
||||||
|
for (; whitespace_end != 0; whitespace_end--) {
|
||||||
|
if (!IsWhitespace(string.data[whitespace_end - 1])) {
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
String16 result = GetPrefix(string, whitespace_end);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|||||||
@@ -170,6 +170,7 @@ void ReplaceText(Buffer *buffer, Range range, String16 string) {
|
|||||||
Assert(range.min >= 0 && range.min <= buffer->len);
|
Assert(range.min >= 0 && range.min <= buffer->len);
|
||||||
buffer->dirty = true;
|
buffer->dirty = true;
|
||||||
buffer->change_id += 1;
|
buffer->change_id += 1;
|
||||||
|
buffer->change_frame_id = FrameID;
|
||||||
|
|
||||||
Int size_to_remove = range.max - range.min;
|
Int size_to_remove = range.max - range.min;
|
||||||
Int size_to_add = string.len;
|
Int size_to_add = string.len;
|
||||||
|
|||||||
@@ -227,6 +227,23 @@ Array<Range> FindAllInBuffer(Allocator allocator, Buffer *buffer, String16 needl
|
|||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ToggleFullscreen() {
|
||||||
|
if (IsInFullscreen) {
|
||||||
|
SDL_SetWindowSize(SDLWindow, FullScreenSizeX, FullScreenSizeY);
|
||||||
|
SDL_SetWindowPosition(SDLWindow, FullScreenPositionX, FullScreenPositionY);
|
||||||
|
} else {
|
||||||
|
SDL_GetWindowSize(SDLWindow, &FullScreenSizeX, &FullScreenSizeY);
|
||||||
|
SDL_GetWindowPosition(SDLWindow, &FullScreenPositionX, &FullScreenPositionY);
|
||||||
|
|
||||||
|
SDL_DisplayID display = SDL_GetDisplayForWindow(SDLWindow);
|
||||||
|
const SDL_DisplayMode *dm = SDL_GetCurrentDisplayMode(display);
|
||||||
|
SDL_SetWindowSize(SDLWindow, dm->w, dm->h);
|
||||||
|
SDL_SetWindowPosition(SDLWindow, 0, 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
IsInFullscreen = !IsInFullscreen;
|
||||||
|
}
|
||||||
|
|
||||||
bool GlobalCommand(Event event) {
|
bool GlobalCommand(Event event) {
|
||||||
ProfileFunction();
|
ProfileFunction();
|
||||||
bool run_window_command = true;
|
bool run_window_command = true;
|
||||||
@@ -314,6 +331,10 @@ bool GlobalCommand(Event event) {
|
|||||||
run_window_command = false;
|
run_window_command = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (Press(SDLK_F11)) {
|
||||||
|
ToggleFullscreen();
|
||||||
|
}
|
||||||
|
|
||||||
if (Ctrl(SDLK_P)) {
|
if (Ctrl(SDLK_P)) {
|
||||||
Window *command_window = GetWindow(CommandWindowID);
|
Window *command_window = GetWindow(CommandWindowID);
|
||||||
if (command_window->visible) {
|
if (command_window->visible) {
|
||||||
@@ -367,7 +388,6 @@ void ReportErrorf(const char *fmt, ...) {
|
|||||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error!", string.data, NULL);
|
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error!", string.data, NULL);
|
||||||
|
|
||||||
Buffer *buffer = GetBuffer("*console*");
|
Buffer *buffer = GetBuffer("*console*");
|
||||||
if (!buffer) return;
|
|
||||||
String16 string16 = ToString16(scratch, string);
|
String16 string16 = ToString16(scratch, string);
|
||||||
ReplaceText(buffer, {}, string16);
|
ReplaceText(buffer, {}, string16);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -266,12 +266,74 @@ void ReplaceDebugData() {
|
|||||||
Append(buffer, ToString16(scratch, window_list));
|
Append(buffer, ToString16(scratch, window_list));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void ApplyInfobarChanges(Window *window, View *view, Buffer *buffer) {
|
||||||
|
String16 buffer_string = GetString(*buffer);
|
||||||
|
Range replace_range = {0, buffer->len};
|
||||||
|
if (Seek(buffer_string, L" |", &replace_range.max)) {
|
||||||
|
}
|
||||||
|
buffer_string = GetString(*buffer, replace_range);
|
||||||
|
buffer_string = Trim(buffer_string);
|
||||||
|
|
||||||
|
String16 col = {};
|
||||||
|
for (int64_t i = buffer_string.len - 1; i >= 0; i -= 1) {
|
||||||
|
if (IsDigit(buffer_string.data[i])) {
|
||||||
|
col.data = buffer_string.data + i;
|
||||||
|
col.len += 1;
|
||||||
|
} else if (buffer_string.data[i] == L':') {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer_string = Chop(buffer_string, col.len + 1);
|
||||||
|
|
||||||
|
String16 line = {};
|
||||||
|
for (int64_t i = buffer_string.len - 1; i >= 0; i -= 1) {
|
||||||
|
if (IsDigit(buffer_string.data[i])) {
|
||||||
|
line.data = buffer_string.data + i;
|
||||||
|
line.len += 1;
|
||||||
|
} else if (buffer_string.data[i] == L':') {
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
buffer_string = Chop(buffer_string, line.len + 1);
|
||||||
|
|
||||||
|
Window *last_window = GetWindow(GetLastActiveWindow());
|
||||||
|
View *last_view = GetActiveView(last_window);
|
||||||
|
Buffer *last_buffer = GetBuffer(last_view->active_buffer);
|
||||||
|
|
||||||
|
// @todo: maybe intern the filenames?
|
||||||
|
// @leak
|
||||||
|
String filepath = ToString(Perm, buffer_string);
|
||||||
|
if (!BufferNameExists(filepath)) {
|
||||||
|
last_buffer->name = filepath;
|
||||||
|
}
|
||||||
|
|
||||||
|
Scratch scratch;
|
||||||
|
String line_string = ToString(scratch, line);
|
||||||
|
String col_string = ToString(scratch, col);
|
||||||
|
Int linei = strtoll(line_string.data, NULL, 10) - 1;
|
||||||
|
Int coli = strtoll(col_string.data, NULL, 10) - 1;
|
||||||
|
Int buffer_pos = XYToPos(*last_buffer, {coli, linei});
|
||||||
|
|
||||||
|
Caret &caret = last_view->carets[0];
|
||||||
|
if (GetFront(caret) != buffer_pos) {
|
||||||
|
caret = MakeCaret(buffer_pos);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void ReplaceInfobarData() {
|
void ReplaceInfobarData() {
|
||||||
Window *window = GetWindow(InfoBarWindowID);
|
Window *window = GetWindow(InfoBarWindowID);
|
||||||
if (IsActive(window)) return;
|
|
||||||
|
|
||||||
View *view = GetView(window->active_view);
|
View *view = GetView(window->active_view);
|
||||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||||
|
if (IsActive(window)) {
|
||||||
|
if (buffer->change_frame_id == FrameID) {
|
||||||
|
ApplyInfobarChanges(window, view, buffer);
|
||||||
|
}
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
Window *last_window = GetWindow(GetLastActiveWindow());
|
Window *last_window = GetWindow(GetLastActiveWindow());
|
||||||
View *last_view = GetActiveView(last_window);
|
View *last_view = GetActiveView(last_window);
|
||||||
@@ -284,7 +346,7 @@ void ReplaceInfobarData() {
|
|||||||
String16 buffer_string = GetString(*buffer);
|
String16 buffer_string = GetString(*buffer);
|
||||||
Range replace_range = {0, buffer->len};
|
Range replace_range = {0, buffer->len};
|
||||||
if (!Seek(buffer_string, L" |", &replace_range.max)) {
|
if (!Seek(buffer_string, L" |", &replace_range.max)) {
|
||||||
// ReplaceText(buffer, GetEndAsRange(*buffer), L" |");
|
ReplaceText(buffer, GetEndAsRange(*buffer), L" |");
|
||||||
}
|
}
|
||||||
|
|
||||||
// String s = Format(scratch, " %lld:%lld", (long long)xy.line + 1ll, (long long)xy.col + 1ll);
|
// String s = Format(scratch, " %lld:%lld", (long long)xy.line + 1ll, (long long)xy.col + 1ll);
|
||||||
|
|||||||
@@ -39,6 +39,11 @@ inline Buffer *GetBuffer(String name) {
|
|||||||
return &Buffers[0];
|
return &Buffers[0];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
inline Buffer *BufferNameExists(String name) {
|
||||||
|
For(Buffers) if (it.name == name) return ⁢
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
inline View *GetView(ViewID id) {
|
inline View *GetView(ViewID id) {
|
||||||
For(Views) if (it.id.id == id.id) return ⁢
|
For(Views) if (it.id.id == id.id) return ⁢
|
||||||
return &Views[0];
|
return &Views[0];
|
||||||
|
|||||||
@@ -13,6 +13,11 @@
|
|||||||
#include "external/stb_truetype.h"
|
#include "external/stb_truetype.h"
|
||||||
#include "external/stb_truetype.c"
|
#include "external/stb_truetype.c"
|
||||||
|
|
||||||
|
SDL_Window *SDLWindow;
|
||||||
|
bool IsInFullscreen;
|
||||||
|
int FullScreenSizeX, FullScreenSizeY;
|
||||||
|
int FullScreenPositionX, FullScreenPositionY;
|
||||||
|
|
||||||
#include "platform/font.cpp"
|
#include "platform/font.cpp"
|
||||||
#include "platform/render_opengl.cpp"
|
#include "platform/render_opengl.cpp"
|
||||||
|
|
||||||
@@ -142,22 +147,22 @@ int main()
|
|||||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||||
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
SDL_GL_SetAttribute(SDL_GL_STENCIL_SIZE, 8);
|
||||||
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||||
SDL_Window *sdl_window = SDL_CreateWindow("Text editor", 1280, 720, window_flags);
|
SDLWindow = SDL_CreateWindow("Text editor", 1280, 720, window_flags);
|
||||||
if (sdl_window == NULL) {
|
if (SDLWindow == NULL) {
|
||||||
ReportErrorf("Couldn't create window! %s", SDL_GetError());
|
ReportErrorf("Couldn't create window! %s", SDL_GetError());
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_GLContext gl_context = SDL_GL_CreateContext(sdl_window);
|
SDL_GLContext gl_context = SDL_GL_CreateContext(SDLWindow);
|
||||||
SDL_GL_MakeCurrent(sdl_window, gl_context);
|
SDL_GL_MakeCurrent(SDLWindow, gl_context);
|
||||||
SDL_GL_SetSwapInterval(1); // Enable vsync
|
SDL_GL_SetSwapInterval(1); // Enable vsync
|
||||||
SDL_ShowWindow(sdl_window);
|
SDL_ShowWindow(SDLWindow);
|
||||||
|
|
||||||
// Set icon
|
// Set icon
|
||||||
{
|
{
|
||||||
uint32_t data = 0xddddddff;
|
uint32_t data = 0xddddddff;
|
||||||
SDL_Surface *surface = SDL_CreateSurfaceFrom(1, 1, SDL_PIXELFORMAT_RGBA8888, &data, sizeof(uint32_t));
|
SDL_Surface *surface = SDL_CreateSurfaceFrom(1, 1, SDL_PIXELFORMAT_RGBA8888, &data, sizeof(uint32_t));
|
||||||
SDL_SetWindowIcon(sdl_window, surface);
|
SDL_SetWindowIcon(SDLWindow, surface);
|
||||||
SDL_DestroySurface(surface);
|
SDL_DestroySurface(surface);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -166,10 +171,10 @@ int main()
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_StartTextInput(sdl_window);
|
SDL_StartTextInput(SDLWindow);
|
||||||
SDL_GL_SetSwapInterval(1); // vsync
|
SDL_GL_SetSwapInterval(1); // vsync
|
||||||
{
|
{
|
||||||
float scale = SDL_GetWindowDisplayScale(sdl_window);
|
float scale = SDL_GetWindowDisplayScale(SDLWindow);
|
||||||
if (scale != 1.0f) DPIScale = scale;
|
if (scale != 1.0f) DPIScale = scale;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -232,7 +237,7 @@ int main()
|
|||||||
WaitForEvents = true;
|
WaitForEvents = true;
|
||||||
|
|
||||||
int window_x, window_y;
|
int window_x, window_y;
|
||||||
SDL_GetWindowSize(sdl_window, &window_x, &window_y);
|
SDL_GetWindowSize(SDLWindow, &window_x, &window_y);
|
||||||
WindowSize = {(float)window_x, (float)window_y};
|
WindowSize = {(float)window_x, (float)window_y};
|
||||||
BeginFrameRender();
|
BeginFrameRender();
|
||||||
LayoutWindows();
|
LayoutWindows();
|
||||||
@@ -271,7 +276,7 @@ int main()
|
|||||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||||
const char *dirty = buffer->dirty ? "!" : "";
|
const char *dirty = buffer->dirty ? "!" : "";
|
||||||
Format(scratch, "%.*s%s", buffer->name, dirty);
|
Format(scratch, "%.*s%s", buffer->name, dirty);
|
||||||
SDL_SetWindowTitle(sdl_window, buffer->name.data);
|
SDL_SetWindowTitle(SDLWindow, buffer->name.data);
|
||||||
}
|
}
|
||||||
ReplaceInfobarData();
|
ReplaceInfobarData();
|
||||||
ReplaceDebugData();
|
ReplaceDebugData();
|
||||||
@@ -310,10 +315,10 @@ int main()
|
|||||||
DrawWindow(window);
|
DrawWindow(window);
|
||||||
}
|
}
|
||||||
EndFrameRender(ColorBackground);
|
EndFrameRender(ColorBackground);
|
||||||
SDL_GL_SwapWindow(sdl_window);
|
SDL_GL_SwapWindow(SDLWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
SDL_DestroyWindow(sdl_window);
|
SDL_DestroyWindow(SDLWindow);
|
||||||
SDL_Quit();
|
SDL_Quit();
|
||||||
|
|
||||||
EndProfiler();
|
EndProfiler();
|
||||||
|
|||||||
@@ -24,6 +24,7 @@ struct Buffer {
|
|||||||
BufferID id;
|
BufferID id;
|
||||||
String name;
|
String name;
|
||||||
Int change_id;
|
Int change_id;
|
||||||
|
Int change_frame_id;
|
||||||
|
|
||||||
union {
|
union {
|
||||||
U16 *data;
|
U16 *data;
|
||||||
|
|||||||
@@ -1,6 +1,5 @@
|
|||||||
- Windows
|
- Windows
|
||||||
- Mark windows as absolute or non-automatic layout and then just loop through windows
|
- Mark windows as absolute or non-automatic layout and then just loop through windows
|
||||||
- Remove view children, replace with view history
|
|
||||||
- layouting, resize windows
|
- layouting, resize windows
|
||||||
- column based, choose number of columns and then evenly split - we can adjust sizes using mouse
|
- column based, choose number of columns and then evenly split - we can adjust sizes using mouse
|
||||||
- maybe we can use first line number to use the window?
|
- maybe we can use first line number to use the window?
|
||||||
@@ -9,12 +8,10 @@
|
|||||||
- is this even practical if we have tab based design?
|
- is this even practical if we have tab based design?
|
||||||
- this would allow to create new windows just like that to inform user and so on
|
- this would allow to create new windows just like that to inform user and so on
|
||||||
- window borders as flag
|
- window borders as flag
|
||||||
- You should be able to edit buffer name, column and line in info bar which would apply to the last open view. Make sure name is unique
|
|
||||||
- Implement console buffer mimicking vscode with ctrl+~ etc.
|
- Implement console buffer mimicking vscode with ctrl+~ etc.
|
||||||
- Reverse order of append in console buffer - it should be appending from top to bottom and scrolling
|
- Reverse order of append in console buffer - it should be appending from top to bottom and scrolling
|
||||||
- Modify error popups to not focus, introduce a interaction timer which after some time will make window invisible
|
- Modify error popups to not focus, introduce a interaction timer which after some time will make window invisible
|
||||||
- Implement shell interaction in a console buffer
|
- Implement shell interaction in a console buffer
|
||||||
- Fullscreen
|
|
||||||
|
|
||||||
- files
|
- files
|
||||||
- load directory
|
- load directory
|
||||||
@@ -29,7 +26,6 @@
|
|||||||
|
|
||||||
- execution
|
- execution
|
||||||
- experiment with using multiple cursors to select command and it's input
|
- experiment with using multiple cursors to select command and it's input
|
||||||
-
|
|
||||||
|
|
||||||
- mouse
|
- mouse
|
||||||
- open selected string or auto enclosed word when right clicking or middle (this needs to be also handled on keyboard level)
|
- open selected string or auto enclosed word when right clicking or middle (this needs to be also handled on keyboard level)
|
||||||
|
|||||||
Reference in New Issue
Block a user