Compare commits

..

2 Commits

Author SHA1 Message Date
Krzosa Karol
de06ea05cc Hooks sketch 2026-01-08 10:15:02 +01:00
Krzosa Karol
5fecc74193 Remove header files, consolidate text_editor.h again because it was annoying 2026-01-07 22:47:05 +01:00
9 changed files with 301 additions and 407 deletions

View File

@@ -160,7 +160,7 @@ API bool AreOverlapping(Caret a, Caret b) {
return result;
}
API Range GetLineRange(Buffer *buffer, Int line, Int *end_of_buffer) {
API Range GetLineRange(Buffer *buffer, Int line, Int *end_of_buffer = NULL) {
Range result = {buffer->line_starts[line], buffer->len};
if (line + 1 < buffer->line_starts.len) {
result.max = buffer->line_starts[line + 1];
@@ -177,14 +177,14 @@ API Range GetLineRangeWithoutNL(Buffer *buffer, Int line) {
return line_range;
}
API String16 GetString(Buffer *buffer, Range range) {
API String16 GetString(Buffer *buffer, Range range = {0, INT64_MAX}) {
range.min = Clamp(range.min, (Int)0, buffer->len);
range.max = Clamp(range.max, (Int)0, buffer->len);
String16 result = {(char16_t *)buffer->data + range.min, GetSize(range)};
return result;
}
API String AllocCharString(Allocator allocator, Buffer *buffer, Range range) {
API String AllocCharString(Allocator allocator, Buffer *buffer, Range range = {0, INT64_MAX}) {
String16 string16 = GetString(buffer, range);
String result = ToString(allocator, string16);
return result;
@@ -211,7 +211,7 @@ API Int LastLine(Buffer *buffer) {
return result;
}
API String16 GetLineString(Buffer *buffer, Int line, Int *end_of_buffer) {
API String16 GetLineString(Buffer *buffer, Int line, Int *end_of_buffer = NULL) {
Range range = GetLineRange(buffer, line, end_of_buffer);
String16 string = GetString(buffer, range);
return string;
@@ -453,7 +453,7 @@ API Int GetFullLineStart(Buffer *buffer, Int pos) {
return range.min;
}
API Int GetFullLineEnd(Buffer *buffer, Int pos, Int *eof) {
API Int GetFullLineEnd(Buffer *buffer, Int pos, Int *eof = NULL) {
pos = Clamp(pos, (Int)0, buffer->len);
Int line = PosToLine(buffer, pos);
Range range = GetLineRange(buffer, line, eof);
@@ -674,6 +674,8 @@ void RawValidateLineStarts(Buffer *buffer) {
}
}
// These don't handle history, just raw operations on buffer memory
// TODO: MAYBE THEY SHOULD!
API void RawReplaceText(Buffer *buffer, Range range, String16 string) {
ProfileFunction();
Assert(range.max >= range.min);
@@ -986,6 +988,9 @@ API Array<Edit> BeginEdit(Allocator allocator, Buffer *buffer, Array<Caret> &car
return result;
}
// We can invoke SaveCaretHistoryBeforeBeginEdit(which is basically BeginEdit with
// different name before caret altering commands to save caret history
// and then call some editing command to edit which is not going to save carets
API void SaveCaretHistoryBeforeBeginEdit(Buffer *buffer, Array<Caret> &carets) {
BeginEdit({}, buffer, carets);
}
@@ -996,6 +1001,9 @@ API void AssertRanges(Array<Caret> carets) {
}
}
// Adjusts caret copies after edit to make them not move after for example
// a bar modification. Sometimes works, sometimes doesn't, depends, not an all solving tool.
// For example in case of ReopenBuffer, when we select and replace entire buffer, it didn't quite work.
API void AdjustCarets(Array<Edit> edits, Array<Caret> *carets) {
Scratch scratch;
Array<Caret> new_carets = TightCopy(scratch, *carets);
@@ -1375,7 +1383,7 @@ void Close(BufferID id) {
}
}
Buffer *CreateBuffer(Allocator allocator, String name, Int size) {
Buffer *CreateBuffer(Allocator allocator, String name, Int size = 4096) {
Buffer *result = AllocBuffer(allocator, name, size);
Add(&Buffers, result);
return result;
@@ -1468,6 +1476,15 @@ String16 ToUnixString16(Allocator allocator, String string_) {
return string;
}
// This function as name suggests tries to open a buffer,
// there is no name resolution here, path should already be resolved etc.
//
// 1. It tries to find an already open buffer
// 2. Returns a buffer if the file doesn't exist (even if a directory doesn't exist)
// - This is a worry for later time, also we want to handle weird names and so on
// 3. If file exists we read it, convert to utf16, tabs to spaces etc.
//
// We don't really care about opening buffers that don't have proper paths
Buffer *BufferOpenFile(String path) {
ProfileFunction();
Allocator sys_allocator = GetSystemAllocator();

View File

@@ -1,164 +0,0 @@
struct Buffer;
struct BufferID { Int id; Buffer *o; };
union Range { struct { Int min; Int max; }; Int e[2]; };
struct Caret { union { Range range; Int pos[2]; }; Int ifront;};
struct XY { Int col; Int line; };
struct Edit {
Range range;
String16 string;
};
struct HistoryEntry {
Array<Edit> edits;
Array<Caret> carets;
double time;
};
struct Buffer {
BufferID id;
String name;
Int begin_frame_change_id;
Int change_id;
Int user_change_id;
Int file_mod_time;
union {
U16 *data;
char16_t*str;
};
Int len;
Int cap;
Array<Int> line_starts;
Array<HistoryEntry> undo_stack;
Array<HistoryEntry> redo_stack;
int edit_phase;
struct {
unsigned no_history : 1;
unsigned no_line_starts : 1;
unsigned dirty : 1;
unsigned changed_on_disk : 1;
unsigned temp : 1;
unsigned dont_try_to_save_in_bulk_ops : 1;
unsigned close : 1;
unsigned special : 1;
unsigned is_dir : 1;
};
};
struct FuzzyPair {
int32_t index;
float rating;
};
enum {
KILL_SELECTION = 1,
};
constexpr Int LAST_LINE = INT64_MAX;
// @todo: buffer init, deinit
API Range MakeRange(Int a, Int b);
API Range MakeRange(Int a);
API Int GetSize(Range range);
API bool AreEqual(Range a, Range b);
API bool AreOverlapping(Range a, Range b);
API bool InBounds(Range range, Int pos);
API Range operator-(Range a, Int value);
API Range operator-=(Range &range, Int value);
API Range operator+(Range a, Int value);
API Range operator+=(Range &range, Int value);
API Range GetBufferEndAsRange(Buffer *buffer);
API Range GetBufferBeginAsRange(Buffer *buffer);
API Range GetRange(Buffer *buffer);
API Int Clamp(const Buffer *buffer, Int pos);
API Range Clamp(const Buffer *buffer, Range range);
API Int GetFront(Caret caret);
API Int GetBack(Caret caret);
API Caret MakeCaret(Int pos);
API Caret MakeCaret(Int front, Int back);
API Caret SetBack(Caret caret, Int back);
API Caret SetFront(Caret caret, Int front);
API Caret SetFrontWithAnchor(Caret caret, Caret anchor, Int p);
API bool AreEqual(Caret a, Caret b);
API bool AreOverlapping(Caret a, Caret b);
API Range GetLineRange(Buffer *buffer, Int line, Int *end_of_buffer = NULL);
API Range GetLineRangeWithoutNL(Buffer *buffer, Int line);
API String16 GetString(Buffer *buffer, Range range = {0, INT64_MAX});
API String AllocCharString(Allocator allocator, Buffer *buffer, Range range = {0, INT64_MAX});
API String16 GetLineString(Buffer *buffer, Int line, Int *end_of_buffer = NULL);
API String16 GetLineStringWithoutNL(Buffer *buffer, Int line);
API XY XYLine(Int line);
API Int LastLine(Buffer *buffer);
API Int PosToLine(Buffer *buffer, Int pos);
API XY PosToXY(Buffer *buffer, Int pos);
API Int XYToPos(Buffer *buffer, XY xy);
API Int XYToPosWithoutNL(Buffer *buffer, XY xy);
API Int XYToPosErrorOutOfBounds(Buffer *buffer, XY xy);
API char16_t GetChar(Buffer *buffer, Int pos);
API bool InBounds(const Buffer *buffer, Int pos);
API Int GetWordStart(Buffer *buffer, Int pos);
API Int GetWordEnd(Buffer *buffer, Int pos);
API bool IsLoadWord(char16_t w);
API Int GetLoadWordStart(Buffer *buffer, Int pos);
API Int GetLoadWordEnd(Buffer *buffer, Int pos);
API Range EncloseLoadWord(Buffer *buffer, Int pos);
API Int GetNextWordEnd(Buffer *buffer, Int pos);
API Int GetPrevWordStart(Buffer *buffer, Int pos);
API Int GetLineStart(Buffer *buffer, Int pos);
API Int GetLineEnd(Buffer *buffer, Int pos);
API Int GetFullLineStart(Buffer *buffer, Int pos);
API Int GetFullLineEnd(Buffer *buffer, Int pos, Int *eof = NULL);
API Int GetBufferEnd(Buffer *buffer);
API Int GetBufferStart(Buffer *buffer);
API Int GetNextEmptyLineStart(Buffer *buffer, Int pos);
API Int GetPrevEmptyLineStart(Buffer *buffer, Int pos);
API Range EncloseWord(Buffer *buffer, Int pos);
API Int SkipSpaces(Buffer *buffer, Int seek);
API Range EncloseLine(Buffer *buffer, Int pos);
API Range EncloseFullLine(Buffer *buffer, Int pos);
API Int OffsetByLine(Buffer *buffer, Int pos, Int line_offset);
API Int GetNextChar(Buffer *buffer, Int pos);
API Int GetPrevChar(Buffer *buffer, Int pos);
API Int GetLineIndent(Buffer *buffer, Int line);
API Int GetIndentAtPos(Buffer *buffer, Int pos);
API Range GetIndentRangeAtPos(Buffer *buffer, Int pos);
API Int FindRangeByPos(Array<Range> *ranges, Int pos);
// These don't handle history, just raw operations on buffer memory
API void RawReplaceText(Buffer *buffer, Range range, String16 string);
API void RawAppend(Buffer *buffer, String16 string);
API void RawAppend(Buffer *buffer, String string);
API void RawAppendf(Buffer *buffer, const char *fmt, ...);
// We can invoke SaveCaretHistoryBeforeBeginEdit(which is basically BeginEdit with
// different name before caret altering commands to save caret history
// and then call some editing command to edit which is not going to save carets
API void SaveCaretHistoryBeforeBeginEdit(Buffer *buffer, Array<Caret> &carets);
API Array<Edit> BeginEdit(Allocator allocator, Buffer *buffer, Array<Caret> &carets);
API void EndEdit(Buffer *buffer, Array<Edit> *edits, Array<Caret> *carets, bool kill_selection);
API void AddEdit(Array<Edit> *e, Range range, String16 string);
// Merge carets that overlap, this needs to be handled before any edits to
// make sure overlapping edits won't happen.
//
// mouse_selection_anchor is special case for mouse handling !
API void MergeCarets(Buffer *buffer, Array<Caret> *carets);
// Adjusts caret copies after edit to make them not move after for example
// a bar modification. Sometimes works, sometimes doesn't, depends, not an all solving tool.
// For example in case of ReopenBuffer, when we select and replace entire buffer, it didn't quite work.
API void AdjustCarets(Array<Edit> edits, Array<Caret> *carets);
API void AssertRanges(Array<Caret> carets);
API void RedoEdit(Buffer *buffer, Array<Caret> *carets);
API void UndoEdit(Buffer *buffer, Array<Caret> *carets);
API void ResetHistory(Buffer *buffer);
API void DeallocHistoryArray(Array<HistoryEntry> *entries);
API void DeallocHistoryEntries(Array<HistoryEntry> *entries);

View File

@@ -28,6 +28,12 @@ struct Trigger {
};
};
struct CachedTrigger {
Trigger *trigger;
String key;
};
Array<CachedTrigger> CachedTriggers;
void Advance(Lexer *lex) {
if (lex->at < lex->end) {
if (lex->at[0] == '\n') {
@@ -168,12 +174,6 @@ Trigger *ParseKey(Allocator allocator, String key, char *debug_name) {
return result;
}
struct CachedTrigger {
Trigger *trigger;
String key;
};
Array<CachedTrigger> CachedTriggers;
Trigger *ParseKeyCached(String key) {
key = Trim(key);
if (key.len == 0) {

View File

@@ -10,6 +10,16 @@ bool SearchCaseSensitive = false;
bool SearchWordBoundary = false;
bool BreakOnError = false;
Allocator SysAllocator = {SystemAllocatorProc};
String ConfigDir;
float DPIScale = 1.0f;
// @WARNING: be careful about using this, should only be used for debugging
// the problem with this is that we want events to be reproducible.
// We eat as many events as we can in a frame, we abstract the frame and so on.
// Dont use it
Int FrameID;
WindowID WindowIDs;
ViewID ViewIDs;
Int BufferIDs;

View File

@@ -1,7 +1,6 @@
#include "basic/basic.h"
#include "basic/basic.cpp"
#include "profiler.h"
#include "SDL3/SDL.h"
#include "external/glad/glad.c"
#include "external/glad/glad.h"
@@ -12,16 +11,10 @@
#endif
#define MINICORO_IMPL
#include "external/minicoro.h"
#include "render/generated_font.cpp"
#include "render/font.cpp"
#include "render/opengl.cpp"
#include "buffer.h"
#include "view.h"
#include "window.h"
#include "text_editor.h"
#include "globals.cpp"
#include "coroutines.cpp"
#include "buffer.cpp"
@@ -32,14 +25,11 @@
#include "window_status.cpp"
#include "window_search.cpp"
#include "window_build.cpp"
#include "process.cpp"
#include "event.cpp"
#include "config.cpp"
#include "commands.cpp"
#include "commands_clipboard.cpp"
#include "scratch.cpp"
#include "draw.cpp"
#include "test/tests.cpp"

View File

@@ -1,3 +1,203 @@
struct Buffer;
struct View;
struct Window;
struct BufferID { Int id; Buffer *o; };
struct ViewID { Int id; View *o; };
struct WindowID { Int id; Window *o; };
union Range { struct { Int min; Int max; }; Int e[2]; };
struct Caret { union { Range range; Int pos[2]; }; Int ifront;};
struct XY { Int col; Int line; };
typedef void Function();
struct FunctionData {
String name;
Function *function;
};
struct Edit {
Range range;
String16 string;
};
struct HistoryEntry {
Array<Edit> edits;
Array<Caret> carets;
double time;
};
struct Buffer {
BufferID id;
String name;
Int begin_frame_change_id;
Int change_id;
Int user_change_id;
Int file_mod_time;
union {
U16 *data;
char16_t*str;
};
Int len;
Int cap;
Array<Int> line_starts;
Array<HistoryEntry> undo_stack;
Array<HistoryEntry> redo_stack;
int edit_phase;
struct {
unsigned no_history : 1;
unsigned no_line_starts : 1;
unsigned dirty : 1;
unsigned changed_on_disk : 1;
unsigned temp : 1;
unsigned dont_try_to_save_in_bulk_ops : 1;
unsigned close : 1;
unsigned special : 1;
unsigned is_dir : 1;
};
};
enum HookKind {
HookKind_Invalid,
HookKind_AppInit,
HookKind_AppUpdate,
HookKind_AppExit,
HookKind_Binding,
HookKind_BeforeLayoutWindow,
HookKind_HandleLayoutWindow,
HookKind_AfterLayoutWindow,
HookKind_BeforeRenderWindow,
HookKind_HandleRenderWindow,
HookKind_AfterRenderWindow,
HookKind_BeforeBufferSave,
HookKind_HandleBufferSave,
HookKind_AfterBufferSave,
HookKind_BeforeBufferOpen,
HookKind_HandleBufferOpen,
HookKind_AfterBufferOpen,
HookKind_ViewUpdate,
};
// Global hooks, per (window, view, buffer) hooks
struct HookParam {
struct Hook *hook;
Buffer *buffer;
View *view;
Window *window;
};
typedef void HookFunction(HookParam *param);
struct Hook {
HookKind kind;
String name;
String doc;
HookFunction *function;
// HookKind_Binding
String binding;
struct Trigger *trigger;
};
struct CommandData {
String name;
String binding;
Function *function;
String doc;
struct Trigger *trigger;
};
enum ViewKind {
ViewKind_Normal,
ViewKind_FuzzySearch,
ViewKind_ActiveSearch,
};
struct View {
ViewID id;
BufferID active_buffer;
ViewKind kind;
Vec2I scroll;
Array<Caret> carets;
// window | view
Caret main_caret_on_begin_frame;
bool update_scroll;
String hook_cmd;
Array<CommandData> hooks;
uint64_t prev_search_line_hash;
struct {
unsigned close : 1;
unsigned special : 1;
};
};
struct GotoCrumb {
ViewID view_id;
Caret caret;
double time;
};
struct Window {
WindowID id;
ViewID active_view;
Rect2I total_rect;
Rect2I document_rect;
Rect2I scrollbar_rect;
Rect2I line_numbers_rect;
Rect2I resizer_rect;
Font *font;
double mouse_scroller_offset;
int z;
double weight;
Caret search_bar_anchor;
GotoCrumb begin_frame_crumb;
Array<GotoCrumb> goto_history;
Array<GotoCrumb> goto_redo;
ViewID active_goto_list;
Int goto_list_pos;
struct {
uint32_t draw_scrollbar : 1;
uint32_t draw_line_numbers : 1;
uint32_t secondary_window_style : 1;
uint32_t draw_line_highlight : 1;
uint32_t visible : 1;
uint32_t primary : 1;
uint32_t close : 1;
uint32_t sync_visibility_with_focus : 1;
uint32_t lose_focus_on_escape : 1;
uint32_t lose_visibility_on_escape : 1;
uint32_t jump_history : 1;
uint32_t skip_checkpoint : 1;
};
};
struct Scroller {
Rect2 rect;
double begin;
double end;
Int line_count;
};
struct BSet {
struct Window *window;
View *view;
Buffer *buffer;
};
#define EVENT_KINDS \
X(EVENT_NONE) \
X(EVENT_UPDATE) \
@@ -54,96 +254,10 @@ struct Event {
#undef X
};
struct BSet {
struct Window *window;
View *view;
Buffer *buffer;
struct FuzzyPair {
int32_t index;
float rating;
};
BSet GetBSet(struct Window *window);
BSet GetBSet(WindowID window_id);
// @WARNING: be careful about using this, should only be used for debugging
// the problem with this is that we want events to be reproducible.
// We eat as many events as we can in a frame, we abstract the frame and so on.
// Dont use it
Int FrameID;
Allocator SysAllocator = {SystemAllocatorProc};
String ConfigDir;
float DPIScale = 1.0f;
void AfterEdit(View *view, Array<Edit> edits);
Scroller ComputeScrollerRect(Window *window);
void UpdateScroll(Window *window, bool update_caret_scrolling);
String GetMainDir();
void SelectEntireBuffer(View *view);
void Replace(View *view, String16 string);
void SelectRange(View *view, Range range);
void Append(View *view, String16 string, bool scroll_to_end_if_cursor_on_last_line);
void Append(View *view, String string, bool scroll_to_end_if_cursor_on_last_line);
Array<Edit> ReplaceEx(Allocator scratch, View *view, String16 string);
void Eval(String string);
void Eval(String16 string);
void ReportDebugf(const char *fmt, ...);
void ReplaceWithoutMovingCarets(Buffer *buffer, Range range, String16 string);
void ClipboardCopy(View *view);
void ClipboardPaste(View *view);
void ReportConsolef(const char *fmt, ...);
void ReportErrorf(const char *fmt, ...);
void ReportWarningf(const char *fmt, ...);
void Appendf(View *view, const char *fmt, ...);
Buffer *CreateBuffer(Allocator allocator, String name, Int size = 4096);
View *CreateView(BufferID active_buffer);
void ReopenBuffer(Buffer *buffer);
bool ProcessIsActive(ViewID view);
void EvalCommand(String command);
void EvalCommand(String16 command);
inline bool operator==(BufferID a, BufferID b) { return a.id == b.id; }
inline bool operator==(ViewID a, ViewID b) { return a.id == b.id; }
inline bool operator!=(BufferID a, BufferID b) { return a.id != b.id; }
inline bool operator!=(ViewID a, ViewID b) { return a.id != b.id; }
// This function as name suggests tries to open a buffer,
// there is no name resolution here, path should already be resolved etc.
//
// 1. It tries to find an already open buffer
// 2. Returns a buffer if the file doesn't exist (even if a directory doesn't exist)
// - This is a worry for later time, also we want to handle weird names and so on
// 3. If file exists we read it, convert to utf16, tabs to spaces etc.
//
// We don't really care about opening buffers that don't have proper paths
Buffer *BufferOpenFile(String path);
typedef void PFunction(void *param);
struct PFunctionData { String name; PFunction *function; };
struct Register_Function {
Register_Function(Array<FunctionData> *functions, String name, Function *f) {
int64_t pos = 0;
if (Seek(name, "_", &pos, 0)) {
name = Skip(name, pos + 1);
}
Add(functions, {name, f});
}
};
#define RegisterFunction(functions, name) Register_Function RF__##name(functions, #name, name)
struct Register_Command { Register_Command(Array<CommandData> *fucs, Function *function, String name, String binding, String doc = "") { if (StartsWith(name, "CMD_")) name = Skip(name, sizeof("CMD_") - 1); Add(fucs, {name, binding, function, doc}); } };
#define RegisterCommand(name, ...) Register_Command RC__##name(&CommandFunctions, name, #name, __VA_ARGS__)
const int DIR_RIGHT = 0;
const int DIR_LEFT = 1;
const int DIR_DOWN = 2;
const int DIR_UP = 3;
const int DIR_COUNT = 4;
const bool CTRL_PRESSED = true;
const bool SHIFT_PRESS = true;
enum VariableType {
VariableType_Invalid,
@@ -174,8 +288,6 @@ struct Register_Variable {
type name = __VA_ARGS__; \
Register_Variable var_##name(&Variables, VariableType_##type, #name, &name)
void AddHook(Array<CommandData> *arr, String name, String binding, Function *function);
enum OpenKind {
OpenKind_Invalid,
OpenKind_Skip,
@@ -200,11 +312,65 @@ struct ResolvedOpen {
bool existing_buffer;
};
struct Register_Command { Register_Command(Array<CommandData> *fucs, Function *function, String name, String binding, String doc = "") { if (StartsWith(name, "CMD_")) name = Skip(name, sizeof("CMD_") - 1); Add(fucs, {name, binding, function, doc}); } };
#define RegisterCommand(name, ...) Register_Command RC__##name(&CommandFunctions, name, #name, __VA_ARGS__)
struct Register_Function {
Register_Function(Array<FunctionData> *functions, String name, Function *f) {
int64_t pos = 0;
if (Seek(name, "_", &pos, 0)) {
name = Skip(name, pos + 1);
}
Add(functions, {name, f});
}
};
#define RegisterFunction(functions, name) Register_Function RF__##name(functions, #name, name)
void AddHook(Array<CommandData> *arr, String name, String binding, Function *function);
constexpr int DIR_RIGHT = 0;
constexpr int DIR_LEFT = 1;
constexpr int DIR_DOWN = 2;
constexpr int DIR_UP = 3;
constexpr int DIR_COUNT = 4;
constexpr bool CTRL_PRESSED = true;
constexpr bool SHIFT_PRESS = true;
constexpr bool KILL_SELECTION = true;
constexpr Int LAST_LINE = INT64_MAX;
BSet GetBSet(struct Window *window);
BSet GetBSet(WindowID window_id);
void Append(View *view, String16 string, bool scroll_to_end_if_cursor_on_last_line);
void Append(View *view, String string, bool scroll_to_end_if_cursor_on_last_line);
void ReplaceWithoutMovingCarets(Buffer *buffer, Range range, String16 string);
void ReportDebugf(const char *fmt, ...);
void ReportConsolef(const char *fmt, ...);
void ReportErrorf(const char *fmt, ...);
void ReportWarningf(const char *fmt, ...);
void Appendf(View *view, const char *fmt, ...);
View *CreateView(BufferID active_buffer);
void EvalCommand(String command);
void EvalCommand(String16 command);
Rect2I GetVisibleCells(Window *window);
ResolvedOpen ResolveOpen(Allocator scratch, String path, ResolveOpenMeta meta);
BSet Open(String path, ResolveOpenMeta meta = ResolveOpenMeta_Normal);
BSet Open(String16 path, ResolveOpenMeta meta = ResolveOpenMeta_Normal);
void CenterView(WindowID window);
void TrimWhitespace(Buffer *buffer, bool trim_lines_with_caret = false);
void ApplyFormattingTool(Buffer *buffer, String tool);
void JumpTempBuffer(BSet *set, String buffer_name = "");
void CommandWindowLayout(Rect2I *rect, Int wx, Int wy);
void CommandWindowInit();
void SearchWindowLayout(Rect2I *rect, Int wx, Int wy);
void SearchWindowInit();
void StatusWindowInit();
void StatusWindowLayout(Rect2I *rect, Int wx, Int wy);
void DebugWindowInit();
void DebugWindowLayout(Rect2I *rect, Int wx, Int wy);
void BuildWindowInit();
void BuildWindowLayout(Rect2I *rect, Int wx, Int wy);
View *FindView(BufferID buffer_id, View *default_view = NULL);
bool operator==(BufferID a, BufferID b) { return a.id == b.id; }
bool operator==(ViewID a, ViewID b) { return a.id == b.id; }
bool operator!=(BufferID a, BufferID b) { return a.id != b.id; }
bool operator!=(ViewID a, ViewID b) { return a.id != b.id; }
bool operator==(WindowID a, WindowID b) { return a.id == b.id; }
bool operator!=(WindowID a, WindowID b) { return a.id != b.id; }

View File

@@ -20,7 +20,8 @@ void Dealloc(View *view) {
Dealloc(view->carets.allocator, view);
}
API View *FindView(ViewID view_id, View *default_view) {
// TODO: default_view should probably be Views[0] but could break stuff
API View *FindView(ViewID view_id, View *default_view = NULL) {
For(Views) {
if (it->id == view_id) {
return it;
@@ -38,7 +39,7 @@ API View *FindView(BufferID buffer_id, View *default_view) {
return default_view;
}
API View *FindView(String name, View *default_view) {
API View *FindView(String name, View *default_view = NULL) {
For(Views) {
Buffer *buffer = GetBuffer(it->active_buffer);
if (buffer->name == name) {

View File

@@ -1,58 +0,0 @@
struct View;
struct ViewID { Int id; View *o; };
typedef void Function();
struct FunctionData {
String name;
Function *function;
};
struct CommandData {
String name;
String binding;
Function *function;
String doc;
struct Trigger *trigger;
};
enum ViewKind {
ViewKind_Normal,
ViewKind_FuzzySearch,
ViewKind_ActiveSearch,
};
struct View {
ViewID id;
BufferID active_buffer;
ViewKind kind;
Vec2I scroll;
Array<Caret> carets;
// window | view
Caret main_caret_on_begin_frame;
bool update_scroll;
String hook_cmd;
Array<CommandData> hooks;
uint64_t prev_search_line_hash;
struct {
unsigned close : 1;
unsigned special : 1;
};
};
struct GotoCrumb {
ViewID view_id;
Caret caret;
double time;
};
API ViewID AllocViewID(View *view);
API View *CreateView(BufferID active_buffer);
API View *FindView(ViewID view_id, View *default_view = NULL);
API View *FindView(BufferID buffer_id, View *default_view = NULL);
API View *FindView(String name, View *default_view = NULL);
API View *GetView(ViewID id);
API View *OpenBufferView(String name);
API bool ViewIsCrumb(ViewID view_id);
API bool ViewIsReferenced(ViewID view);

View File

@@ -1,68 +0,0 @@
struct Window;
struct WindowID { Int id; Window *o; };
struct Window {
WindowID id;
ViewID active_view;
Rect2I total_rect;
Rect2I document_rect;
Rect2I scrollbar_rect;
Rect2I line_numbers_rect;
Rect2I resizer_rect;
Font *font;
double mouse_scroller_offset;
int z;
double weight;
Caret search_bar_anchor;
GotoCrumb begin_frame_crumb;
Array<GotoCrumb> goto_history;
Array<GotoCrumb> goto_redo;
ViewID active_goto_list;
Int goto_list_pos;
struct {
uint32_t draw_scrollbar : 1;
uint32_t draw_line_numbers : 1;
uint32_t secondary_window_style : 1;
uint32_t draw_line_highlight : 1;
uint32_t visible : 1;
uint32_t primary : 1;
uint32_t close : 1;
uint32_t sync_visibility_with_focus : 1;
uint32_t lose_focus_on_escape : 1;
uint32_t lose_visibility_on_escape : 1;
uint32_t jump_history : 1;
uint32_t skip_checkpoint : 1;
};
};
struct Scroller {
Rect2 rect;
double begin;
double end;
Int line_count;
};
inline bool operator==(WindowID a, WindowID b) { return a.id == b.id; }
inline bool operator!=(WindowID a, WindowID b) { return a.id != b.id; }
Rect2I GetVisibleCells(Window *window);
Window *CreateWind();
void CommandWindowLayout(Rect2I *rect, Int wx, Int wy);
void CommandWindowInit();
void SearchWindowLayout(Rect2I *rect, Int wx, Int wy);
void SearchWindowInit();
void StatusWindowInit();
void StatusWindowLayout(Rect2I *rect, Int wx, Int wy);
void DebugWindowInit();
void DebugWindowLayout(Rect2I *rect, Int wx, Int wy);
void BuildWindowInit();
void BuildWindowLayout(Rect2I *rect, Int wx, Int wy);