Switch to c++
This commit is contained in:
111
include/editor.h
Normal file
111
include/editor.h
Normal file
@@ -0,0 +1,111 @@
|
||||
#pragma once
|
||||
#include "../libs/tree-sitter/lib/include/tree_sitter/api.h"
|
||||
#include "./rope.h"
|
||||
#include "./ui.h"
|
||||
#include "./utils.h"
|
||||
#include <cstdint>
|
||||
#include <map>
|
||||
#include <shared_mutex>
|
||||
|
||||
struct Highlight {
|
||||
uint32_t fg;
|
||||
uint32_t bg;
|
||||
uint32_t flags;
|
||||
uint8_t priority;
|
||||
};
|
||||
|
||||
struct Span {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
Highlight *hl;
|
||||
|
||||
bool operator<(const Span &other) const { return start < other.start; }
|
||||
};
|
||||
|
||||
struct SpanCursor {
|
||||
const std::vector<Span> &spans;
|
||||
size_t index = 0;
|
||||
std::vector<Span *> active;
|
||||
|
||||
SpanCursor(const std::vector<Span> &s) : spans(s) {}
|
||||
Highlight *get_highlight(uint32_t byte_offset) {
|
||||
for (int i = active.size() - 1; i >= 0; i--)
|
||||
if (active[i]->end <= byte_offset)
|
||||
active.erase(active.begin() + i);
|
||||
while (index < spans.size() && spans[index].start <= byte_offset) {
|
||||
if (spans[index].end > byte_offset)
|
||||
active.push_back(const_cast<Span *>(&spans[index]));
|
||||
index++;
|
||||
}
|
||||
Highlight *best = nullptr;
|
||||
int max_prio = -1;
|
||||
for (auto *s : active) {
|
||||
if (s->hl->priority > max_prio) {
|
||||
max_prio = s->hl->priority;
|
||||
best = s->hl;
|
||||
}
|
||||
}
|
||||
return best;
|
||||
}
|
||||
void sync(uint32_t byte_offset) {
|
||||
active.clear();
|
||||
size_t left = 0, right = spans.size();
|
||||
while (left < right) {
|
||||
size_t mid = (left + right) / 2;
|
||||
if (spans[mid].start <= byte_offset)
|
||||
left = mid + 1;
|
||||
else
|
||||
right = mid;
|
||||
}
|
||||
index = left;
|
||||
while (left > 0) {
|
||||
left--;
|
||||
if (spans[left].end > byte_offset)
|
||||
active.push_back(const_cast<Span *>(&spans[left]));
|
||||
else if (byte_offset - spans[left].end > 1000)
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
struct Editor {
|
||||
const char *filename; // Filename of the editor
|
||||
Knot *root; // A rope
|
||||
std::shared_mutex knot_mtx; // A mutex
|
||||
std::shared_mutex span_mtx; // A mutex
|
||||
Coord cursor; // position of the cursor
|
||||
uint32_t cursor_preffered; // preffered visual column
|
||||
Coord selection; // position of the selection
|
||||
bool selection_active; // true if there is a selection
|
||||
Coord position; // Position of the editor
|
||||
Coord size; // Size of the editor
|
||||
Coord scroll; // Position of the scroll
|
||||
TSTree *tree; // Tree-sitter tree
|
||||
TSParser *parser; // Tree-sitter parser
|
||||
TSQuery *query; // Tree-sitter query
|
||||
const TSLanguage *language; // Tree-sitter language
|
||||
Queue<TSInputEdit> edit_queue; // Tree-sitter edit queue
|
||||
std::vector<Highlight> query_map; // Tree-sitter query map
|
||||
int *folded; // folded lines indexed by line number - cached form of
|
||||
// folded_node
|
||||
std::vector<Span> spans;
|
||||
std::map<uint32_t, bool> folded_node; // maps content hash to fold state
|
||||
// - built by tree-sitter
|
||||
};
|
||||
|
||||
typedef struct TSLoad {
|
||||
Editor *editor;
|
||||
char *prev = nullptr;
|
||||
} TSLoad;
|
||||
|
||||
Editor *new_editor(const char *filename, Coord position, Coord size);
|
||||
void free_editor(Editor *editor);
|
||||
void render_editor(Editor *editor);
|
||||
void fold(Editor *editor, uint32_t start_line, uint32_t end_line);
|
||||
void scroll_up(Editor *editor, uint32_t lines);
|
||||
void scroll_down(Editor *editor, uint32_t lines);
|
||||
void cursor_up(Editor *editor, uint32_t number);
|
||||
void cursor_down(Editor *editor, uint32_t number);
|
||||
void cursor_left(Editor *editor, uint32_t number);
|
||||
void cursor_right(Editor *editor, uint32_t number);
|
||||
void ensure_scroll(Editor *editor);
|
||||
Reference in New Issue
Block a user