Files
text_editor/src/text_editor/buffer.h

167 lines
6.3 KiB
C++

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;
int32_t 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 Int FindScopeEnd(Buffer *buffer, Int seek, Int max_seek, char16_t open, char16_t close);
API Range EncloseScope(Buffer *buffer, Int pos_min, Int pos_max, char16_t open, char16_t close);
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);