Editing infobar applies changes to buffer
This commit is contained in:
@@ -700,7 +700,6 @@ struct CircularArray {
|
||||
T *data;
|
||||
int16_t cap;
|
||||
int16_t write;
|
||||
int16_t buffer_is_full;
|
||||
};
|
||||
|
||||
template <class T>
|
||||
@@ -718,25 +717,23 @@ void Add(CircularArray<T> *arr, T item) {
|
||||
arr->cap = 128;
|
||||
arr->data = AllocArray(arr->allocator, T, arr->cap);
|
||||
}
|
||||
int idx = arr->write;
|
||||
arr->write = (arr->write + 1) % arr->cap;
|
||||
if (arr->write == 0) arr->buffer_is_full = 1;
|
||||
arr->data[idx] = item;
|
||||
int16_t i = arr->write;
|
||||
arr->write = (arr->write + 1) % arr->cap;
|
||||
arr->data[i] = item;
|
||||
}
|
||||
|
||||
static int GetCircularIndex(int cap, int idx) {
|
||||
int result = idx % cap;
|
||||
if (result < 0) result = cap + result;
|
||||
return result;
|
||||
}
|
||||
|
||||
template <class T>
|
||||
T Get(CircularArray<T> *arr, int idx, T default_value) {
|
||||
if (idx >= arr->cap) return default_value;
|
||||
int i = arr->write - 1 - idx;
|
||||
if (i < 0 && arr->buffer_is_full) {
|
||||
i = arr->cap + i;
|
||||
}
|
||||
|
||||
if (i >= 0 && i < arr->cap) {
|
||||
return arr->data[i];
|
||||
} else {
|
||||
return default_value;
|
||||
}
|
||||
int idx = circ->write - 1 - i;
|
||||
idx = GetCircularIndex(circ->size, idx);
|
||||
int result = circ->data[idx];
|
||||
return result;
|
||||
}
|
||||
|
||||
struct UTF32Result {
|
||||
|
||||
@@ -150,3 +150,42 @@ String16 CutPostfix(String16 *string, int64_t len) {
|
||||
*string = Chop(*string, len);
|
||||
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);
|
||||
buffer->dirty = true;
|
||||
buffer->change_id += 1;
|
||||
buffer->change_frame_id = FrameID;
|
||||
|
||||
Int size_to_remove = range.max - range.min;
|
||||
Int size_to_add = string.len;
|
||||
|
||||
@@ -227,6 +227,23 @@ Array<Range> FindAllInBuffer(Allocator allocator, Buffer *buffer, String16 needl
|
||||
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) {
|
||||
ProfileFunction();
|
||||
bool run_window_command = true;
|
||||
@@ -314,6 +331,10 @@ bool GlobalCommand(Event event) {
|
||||
run_window_command = false;
|
||||
}
|
||||
|
||||
if (Press(SDLK_F11)) {
|
||||
ToggleFullscreen();
|
||||
}
|
||||
|
||||
if (Ctrl(SDLK_P)) {
|
||||
Window *command_window = GetWindow(CommandWindowID);
|
||||
if (command_window->visible) {
|
||||
@@ -366,8 +387,7 @@ void ReportErrorf(const char *fmt, ...) {
|
||||
STRING_FORMAT(scratch, fmt, string);
|
||||
SDL_ShowSimpleMessageBox(SDL_MESSAGEBOX_ERROR, "Error!", string.data, NULL);
|
||||
|
||||
Buffer *buffer = GetBuffer("*console*");
|
||||
if (!buffer) return;
|
||||
Buffer *buffer = GetBuffer("*console*");
|
||||
String16 string16 = ToString16(scratch, string);
|
||||
ReplaceText(buffer, {}, string16);
|
||||
}
|
||||
|
||||
@@ -266,12 +266,74 @@ void ReplaceDebugData() {
|
||||
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() {
|
||||
Window *window = GetWindow(InfoBarWindowID);
|
||||
if (IsActive(window)) return;
|
||||
|
||||
View *view = GetView(window->active_view);
|
||||
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());
|
||||
View *last_view = GetActiveView(last_window);
|
||||
@@ -284,7 +346,7 @@ void ReplaceInfobarData() {
|
||||
String16 buffer_string = GetString(*buffer);
|
||||
Range replace_range = {0, buffer->len};
|
||||
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);
|
||||
|
||||
@@ -39,6 +39,11 @@ inline Buffer *GetBuffer(String name) {
|
||||
return &Buffers[0];
|
||||
}
|
||||
|
||||
inline Buffer *BufferNameExists(String name) {
|
||||
For(Buffers) if (it.name == name) return ⁢
|
||||
return NULL;
|
||||
}
|
||||
|
||||
inline View *GetView(ViewID id) {
|
||||
For(Views) if (it.id.id == id.id) return ⁢
|
||||
return &Views[0];
|
||||
|
||||
@@ -13,6 +13,11 @@
|
||||
#include "external/stb_truetype.h"
|
||||
#include "external/stb_truetype.c"
|
||||
|
||||
SDL_Window *SDLWindow;
|
||||
bool IsInFullscreen;
|
||||
int FullScreenSizeX, FullScreenSizeY;
|
||||
int FullScreenPositionX, FullScreenPositionY;
|
||||
|
||||
#include "platform/font.cpp"
|
||||
#include "platform/render_opengl.cpp"
|
||||
|
||||
@@ -141,23 +146,23 @@ int main()
|
||||
SDL_GL_SetAttribute(SDL_GL_DOUBLEBUFFER, 1);
|
||||
SDL_GL_SetAttribute(SDL_GL_DEPTH_SIZE, 24);
|
||||
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;
|
||||
SDL_Window *sdl_window = SDL_CreateWindow("Text editor", 1280, 720, window_flags);
|
||||
if (sdl_window == NULL) {
|
||||
Uint32 window_flags = SDL_WINDOW_OPENGL | SDL_WINDOW_RESIZABLE | SDL_WINDOW_HIDDEN | SDL_WINDOW_HIGH_PIXEL_DENSITY;
|
||||
SDLWindow = SDL_CreateWindow("Text editor", 1280, 720, window_flags);
|
||||
if (SDLWindow == NULL) {
|
||||
ReportErrorf("Couldn't create window! %s", SDL_GetError());
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_GLContext gl_context = SDL_GL_CreateContext(sdl_window);
|
||||
SDL_GL_MakeCurrent(sdl_window, gl_context);
|
||||
SDL_GLContext gl_context = SDL_GL_CreateContext(SDLWindow);
|
||||
SDL_GL_MakeCurrent(SDLWindow, gl_context);
|
||||
SDL_GL_SetSwapInterval(1); // Enable vsync
|
||||
SDL_ShowWindow(sdl_window);
|
||||
SDL_ShowWindow(SDLWindow);
|
||||
|
||||
// Set icon
|
||||
{
|
||||
uint32_t data = 0xddddddff;
|
||||
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);
|
||||
}
|
||||
|
||||
@@ -166,10 +171,10 @@ int main()
|
||||
return 1;
|
||||
}
|
||||
|
||||
SDL_StartTextInput(sdl_window);
|
||||
SDL_StartTextInput(SDLWindow);
|
||||
SDL_GL_SetSwapInterval(1); // vsync
|
||||
{
|
||||
float scale = SDL_GetWindowDisplayScale(sdl_window);
|
||||
float scale = SDL_GetWindowDisplayScale(SDLWindow);
|
||||
if (scale != 1.0f) DPIScale = scale;
|
||||
}
|
||||
|
||||
@@ -232,7 +237,7 @@ int main()
|
||||
WaitForEvents = true;
|
||||
|
||||
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};
|
||||
BeginFrameRender();
|
||||
LayoutWindows();
|
||||
@@ -271,7 +276,7 @@ int main()
|
||||
Buffer *buffer = GetBuffer(view->active_buffer);
|
||||
const char *dirty = buffer->dirty ? "!" : "";
|
||||
Format(scratch, "%.*s%s", buffer->name, dirty);
|
||||
SDL_SetWindowTitle(sdl_window, buffer->name.data);
|
||||
SDL_SetWindowTitle(SDLWindow, buffer->name.data);
|
||||
}
|
||||
ReplaceInfobarData();
|
||||
ReplaceDebugData();
|
||||
@@ -310,10 +315,10 @@ int main()
|
||||
DrawWindow(window);
|
||||
}
|
||||
EndFrameRender(ColorBackground);
|
||||
SDL_GL_SwapWindow(sdl_window);
|
||||
SDL_GL_SwapWindow(SDLWindow);
|
||||
}
|
||||
|
||||
SDL_DestroyWindow(sdl_window);
|
||||
SDL_DestroyWindow(SDLWindow);
|
||||
SDL_Quit();
|
||||
|
||||
EndProfiler();
|
||||
|
||||
@@ -24,6 +24,7 @@ struct Buffer {
|
||||
BufferID id;
|
||||
String name;
|
||||
Int change_id;
|
||||
Int change_frame_id;
|
||||
|
||||
union {
|
||||
U16 *data;
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
- 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
|
||||
- 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?
|
||||
@@ -9,12 +8,10 @@
|
||||
- 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
|
||||
- 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.
|
||||
- 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
|
||||
- Implement shell interaction in a console buffer
|
||||
- Fullscreen
|
||||
|
||||
- files
|
||||
- load directory
|
||||
@@ -29,7 +26,6 @@
|
||||
|
||||
- execution
|
||||
- experiment with using multiple cursors to select command and it's input
|
||||
-
|
||||
|
||||
- mouse
|
||||
- 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