376 lines
9.1 KiB
C++
376 lines
9.1 KiB
C++
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;};
|
|
union XY {
|
|
struct {Int col; Int line;};
|
|
struct {Int x; Int y; };
|
|
};
|
|
|
|
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;
|
|
};
|
|
|
|
typedef void CMDFunction();
|
|
struct Command {
|
|
String name;
|
|
String docs;
|
|
CMDFunction *function;
|
|
String binding; // DONT USE, only for ParseKeyCached
|
|
struct Trigger *trigger;
|
|
};
|
|
|
|
enum UIAction {
|
|
UIAction_Null,
|
|
UIAction_Cancel,
|
|
UIAction_Yes,
|
|
UIAction_No,
|
|
};
|
|
|
|
struct ExecArgs {
|
|
String exe;
|
|
String cmd;
|
|
String cwd;
|
|
Array<String> env;
|
|
|
|
ViewID output_view; // poll_process
|
|
struct {
|
|
U32 poll_process : 1;
|
|
U32 open_stdin : 1;
|
|
U32 scroll_to_end : 1;
|
|
};
|
|
};
|
|
|
|
struct Process {
|
|
bool is_valid;
|
|
int exit_code;
|
|
char platform[6 * 8];
|
|
Int id;
|
|
|
|
ExecArgs args; // memory for exe and all that is invalid
|
|
};
|
|
|
|
enum OpenKind {
|
|
OpenKind_Invalid,
|
|
OpenKind_Skip,
|
|
OpenKind_Exec,
|
|
OpenKind_Goto,
|
|
OpenKind_Command,
|
|
#if PLUGIN_CONFIG
|
|
OpenKind_Set,
|
|
#endif
|
|
};
|
|
|
|
typedef uint32_t ResolveOpenMeta;
|
|
enum {
|
|
ResolveOpenMeta_Normal = 0,
|
|
ResolveOpenMeta_DontError = 2,
|
|
ResolveOpenMeta_DontExec = 4, // dont error +
|
|
};
|
|
|
|
struct ResolvedOpen {
|
|
OpenKind kind;
|
|
String path;
|
|
Int line, col;
|
|
|
|
struct {
|
|
U32 existing_buffer : 1;
|
|
U32 exec_in_background : 1;
|
|
U32 use_python_shell : 1;
|
|
};
|
|
};
|
|
|
|
struct Buffer {
|
|
BufferID id;
|
|
String name;
|
|
Int 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;
|
|
Array<Command> commands;
|
|
struct {
|
|
uint32_t no_history : 1;
|
|
uint32_t no_line_starts : 1;
|
|
uint32_t dirty : 1;
|
|
uint32_t changed_on_disk : 1;
|
|
uint32_t temp : 1;
|
|
uint32_t dont_try_to_save_in_bulk_ops : 1;
|
|
uint32_t close : 1;
|
|
uint32_t special : 1;
|
|
#if PLUGIN_DIRECTORY_NAVIGATION
|
|
uint32_t is_dir : 1;
|
|
#endif
|
|
};
|
|
};
|
|
|
|
struct View {
|
|
ViewID id;
|
|
BufferID active_buffer;
|
|
Vec2I scroll;
|
|
Array<Caret> carets;
|
|
|
|
// window | view
|
|
Caret main_caret_on_begin_frame;
|
|
bool update_scroll;
|
|
|
|
UIAction ui_action;
|
|
Array<Command> commands;
|
|
Function *update_hook;
|
|
uint64_t prev_search_line_hash;
|
|
struct {
|
|
uint32_t close : 1;
|
|
uint32_t 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; // maybe move to view @todo
|
|
|
|
GotoCrumb begin_frame_crumb;
|
|
Array<GotoCrumb> goto_history;
|
|
Array<GotoCrumb> goto_redo;
|
|
|
|
ViewID active_goto_list;
|
|
Int goto_list_pos;
|
|
|
|
String ui_query_file;
|
|
void (*after_resolve_open_hook)(Window *window, ResolvedOpen *resolved);
|
|
Array<Command> commands;
|
|
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) \
|
|
X(EVENT_QUIT) \
|
|
X(EVENT_MOUSE_LEFT) \
|
|
X(EVENT_MOUSE_RIGHT) \
|
|
X(EVENT_MOUSE_MIDDLE) \
|
|
X(EVENT_MOUSE_X1) \
|
|
X(EVENT_MOUSE_X2) \
|
|
X(EVENT_MOUSE_LEFT_UP) \
|
|
X(EVENT_MOUSE_RIGHT_UP) \
|
|
X(EVENT_MOUSE_MIDDLE_UP) \
|
|
X(EVENT_MOUSE_X1_UP) \
|
|
X(EVENT_MOUSE_X2_UP) \
|
|
X(EVENT_MOUSE_WHEEL) \
|
|
X(EVENT_KEY_PRESS) \
|
|
X(EVENT_TEXT_INPUT) \
|
|
X(EVENT_DROP_FILE)
|
|
|
|
enum EventKind {
|
|
#define X(TYPE) TYPE,
|
|
EVENT_KINDS
|
|
#undef X
|
|
EVENT_KIND_COUNT,
|
|
EVENT_KIND_INVALID = 111,
|
|
};
|
|
|
|
const char *EventKindStrings[] = {
|
|
#define X(TYPE) #TYPE,
|
|
EVENT_KINDS
|
|
#undef X
|
|
};
|
|
|
|
#define EVENT_FIELDS \
|
|
X(EventKind, Int, kind) \
|
|
X(SDL_Keycode, Int, key) \
|
|
X(int16_t, Int, xwindow) \
|
|
X(int16_t, Int, ywindow) \
|
|
X(int16_t, Int, xmouse) \
|
|
X(int16_t, Int, ymouse) \
|
|
X(uint8_t, Int, clicks) \
|
|
X(uint8_t, Int, shift) \
|
|
X(uint8_t, Int, ctrl) \
|
|
X(uint8_t, Int, alt) \
|
|
X(uint8_t, Int, super) \
|
|
X(float, Float, xwheel) \
|
|
X(float, Float, ywheel) \
|
|
X(char *, String, text)
|
|
#define EVENT_FIELD_COUNT 14
|
|
|
|
struct Event {
|
|
#define X(TYPE, KIND, NAME) TYPE NAME;
|
|
EVENT_FIELDS
|
|
#undef X
|
|
};
|
|
|
|
struct FuzzyPair {
|
|
int32_t index;
|
|
float rating;
|
|
};
|
|
|
|
enum VariableType {
|
|
VariableType_Invalid,
|
|
VariableType_Color,
|
|
VariableType_String,
|
|
VariableType_Int,
|
|
VariableType_Float,
|
|
};
|
|
|
|
struct Variable {
|
|
VariableType type;
|
|
String name;
|
|
union {
|
|
void *addr;
|
|
Color *color;
|
|
Int *i;
|
|
double *f;
|
|
String *string;
|
|
};
|
|
};
|
|
|
|
struct Register_Variable {
|
|
Register_Variable(Array<Variable> *variables, VariableType type, String name, void *addr) {
|
|
Add(variables, {type, name, {addr}});
|
|
}
|
|
};
|
|
#define RegisterVariable(type, name, ...) \
|
|
type name = __VA_ARGS__; \
|
|
Register_Variable var_##name(&Variables, VariableType_##type, #name, &name)
|
|
|
|
void AddCommand(Array<Command> *arr, String name, struct Trigger *trigger, CMDFunction *function);
|
|
struct Register_Command {
|
|
Register_Command(Array<Command> *funcs, CMDFunction *function, String name, String binding, String docs = "") {
|
|
int64_t pos = 0;
|
|
if (Seek(name, "_", &pos, 0)) {
|
|
name = Skip(name, pos + 1);
|
|
}
|
|
Command cmd = {};
|
|
cmd.name = name;
|
|
cmd.binding = binding;
|
|
cmd.function = function;
|
|
cmd.docs = docs;
|
|
Reserve(funcs, 512);
|
|
Add(funcs, cmd);
|
|
}
|
|
};
|
|
#define RegisterCommand(name, binding, docs) Register_Command RC__##name(&GlobalCommands, name, #name, binding, docs)
|
|
#define RegisterCoroutineCommand(name, binding, docs, ...) void CMD_##name() {\
|
|
RemoveCoroutine(#name);\
|
|
CCtx *data = AddCoroutine(name);\
|
|
__VA_ARGS__\
|
|
ResumeCoroutine(data);\
|
|
}\
|
|
Register_Command RC__##name(&GlobalCommands, CMD_##name, #name, binding, docs)
|
|
|
|
#define RegisterFunction(functions, name) Register_Function RF__##name(functions, #name, name)
|
|
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});
|
|
}
|
|
};
|
|
|
|
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 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 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, Window *window, 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 JumpTempBuffer(BSet *set, String buffer_name = "");
|
|
|
|
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; }
|