Add custom syntax highlighter and optimize
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
#ifndef EDITOR_COMPLETIONS_H
|
||||
#define EDITOR_COMPLETIONS_H
|
||||
|
||||
#include "editor/decl.h"
|
||||
#include "pch.h"
|
||||
#include "ui/completionbox.h"
|
||||
#include "ui/hover.h"
|
||||
|
||||
@@ -9,22 +9,6 @@ struct TextEdit {
|
||||
std::string text;
|
||||
};
|
||||
|
||||
struct Fold {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
|
||||
bool contains(uint32_t line) const { return line >= start && line <= end; }
|
||||
bool operator<(const Fold &other) const { return start < other.start; }
|
||||
};
|
||||
|
||||
struct Span {
|
||||
uint32_t start;
|
||||
uint32_t end;
|
||||
Highlight *hl;
|
||||
|
||||
bool operator<(const Span &other) const { return start < other.start; }
|
||||
};
|
||||
|
||||
struct VWarn {
|
||||
uint32_t line;
|
||||
std::string text;
|
||||
|
||||
@@ -3,10 +3,9 @@
|
||||
|
||||
#include "editor/completions.h"
|
||||
#include "editor/indents.h"
|
||||
#include "editor/spans.h"
|
||||
#include "io/knot.h"
|
||||
#include "io/sysio.h"
|
||||
#include "ts/decl.h"
|
||||
#include "syntax/parser.h"
|
||||
#include "ui/completionbox.h"
|
||||
#include "ui/diagnostics.h"
|
||||
#include "ui/hover.h"
|
||||
@@ -35,12 +34,6 @@ struct Editor {
|
||||
Coord size;
|
||||
Coord scroll;
|
||||
Language lang;
|
||||
TSSetMain ts;
|
||||
Queue<TSInputEdit> edit_queue;
|
||||
std::vector<Fold> folds;
|
||||
Spans spans;
|
||||
Spans word_spans;
|
||||
Spans hex_color_spans;
|
||||
uint32_t hooks[94];
|
||||
bool jumper_set;
|
||||
std::shared_mutex v_mtx;
|
||||
@@ -56,19 +49,17 @@ struct Editor {
|
||||
std::atomic<int> lsp_version = 1;
|
||||
CompletionSession completion;
|
||||
IndentationEngine indents;
|
||||
Parser *parser;
|
||||
};
|
||||
|
||||
Editor *new_editor(const char *filename_arg, Coord position, Coord size);
|
||||
void save_file(Editor *editor);
|
||||
void free_editor(Editor *editor);
|
||||
void render_editor(Editor *editor);
|
||||
void fold(Editor *editor, uint32_t start_line, uint32_t end_line);
|
||||
void cursor_up(Editor *editor, uint32_t number);
|
||||
void cursor_down(Editor *editor, uint32_t number);
|
||||
Coord move_left(Editor *editor, Coord cursor, uint32_t number);
|
||||
Coord move_right(Editor *editor, Coord cursor, uint32_t number);
|
||||
Coord move_left_pure(Editor *editor, Coord cursor, uint32_t number);
|
||||
Coord move_right_pure(Editor *editor, Coord cursor, uint32_t number);
|
||||
void cursor_left(Editor *editor, uint32_t number);
|
||||
void cursor_right(Editor *editor, uint32_t number);
|
||||
void scroll_up(Editor *editor, int32_t number);
|
||||
@@ -90,9 +81,6 @@ void word_boundaries(Editor *editor, Coord coord, uint32_t *prev_col,
|
||||
uint32_t *next_clusters);
|
||||
void word_boundaries_exclusive(Editor *editor, Coord coord, uint32_t *prev_col,
|
||||
uint32_t *next_col);
|
||||
std::vector<Fold>::iterator find_fold_iter(Editor *editor, uint32_t line);
|
||||
bool add_fold(Editor *editor, uint32_t start, uint32_t end);
|
||||
bool remove_fold(Editor *editor, uint32_t line);
|
||||
void editor_lsp_handle(Editor *editor, json msg);
|
||||
void apply_lsp_edits(Editor *editor, std::vector<TextEdit> edits, bool move);
|
||||
void completion_resolve_doc(Editor *editor);
|
||||
|
||||
@@ -1,150 +0,0 @@
|
||||
#ifndef EDITOR_FOLDS_H
|
||||
#define EDITOR_FOLDS_H
|
||||
|
||||
#include "editor/editor.h"
|
||||
|
||||
inline std::vector<Fold>::iterator find_fold_iter(Editor *editor,
|
||||
uint32_t line) {
|
||||
auto &folds = editor->folds;
|
||||
auto it = std::lower_bound(
|
||||
folds.begin(), folds.end(), line,
|
||||
[](const Fold &fold, uint32_t value) { return fold.start < value; });
|
||||
if (it != folds.end() && it->start == line)
|
||||
return it;
|
||||
if (it != folds.begin()) {
|
||||
--it;
|
||||
if (it->contains(line))
|
||||
return it;
|
||||
}
|
||||
return folds.end();
|
||||
}
|
||||
|
||||
inline bool add_fold(Editor *editor, uint32_t start, uint32_t end) {
|
||||
if (!editor || !editor->root)
|
||||
return false;
|
||||
if (start > end)
|
||||
std::swap(start, end);
|
||||
if (start >= editor->root->line_count)
|
||||
return false;
|
||||
end = std::min(end, editor->root->line_count - 1);
|
||||
if (start == end)
|
||||
return false;
|
||||
Fold new_fold{start, end};
|
||||
auto &folds = editor->folds;
|
||||
auto it = std::lower_bound(
|
||||
folds.begin(), folds.end(), new_fold.start,
|
||||
[](const Fold &fold, uint32_t value) { return fold.start < value; });
|
||||
if (it != folds.begin()) {
|
||||
auto prev = std::prev(it);
|
||||
if (prev->end + 1 >= new_fold.start) {
|
||||
new_fold.start = std::min(new_fold.start, prev->start);
|
||||
new_fold.end = std::max(new_fold.end, prev->end);
|
||||
it = folds.erase(prev);
|
||||
}
|
||||
}
|
||||
while (it != folds.end() && it->start <= new_fold.end + 1) {
|
||||
new_fold.end = std::max(new_fold.end, it->end);
|
||||
it = folds.erase(it);
|
||||
}
|
||||
folds.insert(it, new_fold);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline bool remove_fold(Editor *editor, uint32_t line) {
|
||||
auto it = find_fold_iter(editor, line);
|
||||
if (it == editor->folds.end())
|
||||
return false;
|
||||
editor->folds.erase(it);
|
||||
return true;
|
||||
}
|
||||
|
||||
inline void apply_line_insertion(Editor *editor, uint32_t line, uint32_t rows) {
|
||||
for (auto it = editor->folds.begin(); it != editor->folds.end();) {
|
||||
if (line <= it->start) {
|
||||
it->start += rows;
|
||||
it->end += rows;
|
||||
++it;
|
||||
} else if (line <= it->end) {
|
||||
it = editor->folds.erase(it);
|
||||
} else {
|
||||
++it;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
inline void apply_line_deletion(Editor *editor, uint32_t removal_start,
|
||||
uint32_t removal_end) {
|
||||
if (removal_start > removal_end)
|
||||
return;
|
||||
uint32_t rows_removed = removal_end - removal_start + 1;
|
||||
std::vector<Fold> updated;
|
||||
updated.reserve(editor->folds.size());
|
||||
for (auto fold : editor->folds) {
|
||||
if (removal_end < fold.start) {
|
||||
fold.start -= rows_removed;
|
||||
fold.end -= rows_removed;
|
||||
updated.push_back(fold);
|
||||
continue;
|
||||
}
|
||||
if (removal_start > fold.end) {
|
||||
updated.push_back(fold);
|
||||
continue;
|
||||
}
|
||||
}
|
||||
editor->folds.swap(updated);
|
||||
}
|
||||
|
||||
inline const Fold *fold_for_line(const std::vector<Fold> &folds,
|
||||
uint32_t line) {
|
||||
auto it = std::lower_bound(
|
||||
folds.begin(), folds.end(), line,
|
||||
[](const Fold &fold, uint32_t value) { return fold.start < value; });
|
||||
if (it != folds.end() && it->start == line)
|
||||
return &(*it);
|
||||
if (it != folds.begin()) {
|
||||
--it;
|
||||
if (it->contains(line))
|
||||
return &(*it);
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
inline Fold *fold_for_line(std::vector<Fold> &folds, uint32_t line) {
|
||||
const auto *fold =
|
||||
fold_for_line(static_cast<const std::vector<Fold> &>(folds), line);
|
||||
return const_cast<Fold *>(fold);
|
||||
}
|
||||
|
||||
inline bool line_is_fold_start(const std::vector<Fold> &folds, uint32_t line) {
|
||||
const Fold *fold = fold_for_line(folds, line);
|
||||
return fold && fold->start == line;
|
||||
}
|
||||
|
||||
inline bool line_is_folded(const std::vector<Fold> &folds, uint32_t line) {
|
||||
return fold_for_line(folds, line) != nullptr;
|
||||
}
|
||||
|
||||
inline uint32_t next_unfolded_row(const Editor *editor, uint32_t row) {
|
||||
uint32_t limit = editor && editor->root ? editor->root->line_count : 0;
|
||||
while (row < limit) {
|
||||
const Fold *fold = fold_for_line(editor->folds, row);
|
||||
if (!fold)
|
||||
return row;
|
||||
row = fold->end + 1;
|
||||
}
|
||||
return limit;
|
||||
}
|
||||
|
||||
inline uint32_t prev_unfolded_row(const Editor *editor, uint32_t row) {
|
||||
while (row > 0) {
|
||||
const Fold *fold = fold_for_line(editor->folds, row);
|
||||
if (!fold)
|
||||
return row;
|
||||
if (fold->start == 0)
|
||||
return 0;
|
||||
row = fold->start - 1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
@@ -1,85 +0,0 @@
|
||||
#ifndef EDITOR_SPANS_H
|
||||
#define EDITOR_SPANS_H
|
||||
|
||||
#include "editor/decl.h"
|
||||
#include "utils/utils.h"
|
||||
|
||||
struct Spans {
|
||||
std::vector<Span> spans;
|
||||
Queue<std::pair<uint32_t, int64_t>> edits;
|
||||
std::atomic<bool> mid_parse = false;
|
||||
std::shared_mutex mtx;
|
||||
};
|
||||
|
||||
struct SpanCursor {
|
||||
Spans &spans;
|
||||
size_t index = 0;
|
||||
std::vector<Span *> active;
|
||||
std::shared_lock<std::shared_mutex> lock;
|
||||
|
||||
SpanCursor(Spans &s) : spans(s) {}
|
||||
Highlight *get_highlight(uint32_t byte_offset) {
|
||||
for (int i = (int)active.size() - 1; i >= 0; i--)
|
||||
if (active[i]->end <= byte_offset)
|
||||
active.erase(active.begin() + i);
|
||||
while (index < spans.spans.size() &&
|
||||
spans.spans[index].start <= byte_offset) {
|
||||
if (spans.spans[index].end > byte_offset)
|
||||
active.push_back(const_cast<Span *>(&spans.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) {
|
||||
lock = std::shared_lock(spans.mtx);
|
||||
active.clear();
|
||||
size_t left = 0, right = spans.spans.size();
|
||||
while (left < right) {
|
||||
size_t mid = (left + right) / 2;
|
||||
if (spans.spans[mid].start <= byte_offset)
|
||||
left = mid + 1;
|
||||
else
|
||||
right = mid;
|
||||
}
|
||||
index = left;
|
||||
while (left > 0) {
|
||||
left--;
|
||||
if (spans.spans[left].end > byte_offset)
|
||||
active.push_back(const_cast<Span *>(&spans.spans[left]));
|
||||
else if (byte_offset - spans.spans[left].end > 1000)
|
||||
break;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
inline void apply_edit(std::vector<Span> &spans, uint32_t x, int64_t y) {
|
||||
Span key{.start = x, .end = 0, .hl = nullptr};
|
||||
auto it = std::lower_bound(
|
||||
spans.begin(), spans.end(), key,
|
||||
[](const Span &a, const Span &b) { return a.start < b.start; });
|
||||
size_t idx = std::distance(spans.begin(), it);
|
||||
while (idx > 0 && spans.at(idx - 1).end >= x)
|
||||
--idx;
|
||||
for (size_t i = idx; i < spans.size();) {
|
||||
Span &s = spans.at(i);
|
||||
if (s.start < x && s.end >= x) {
|
||||
s.end += y;
|
||||
} else if (s.start > x) {
|
||||
s.start += y;
|
||||
s.end += y;
|
||||
}
|
||||
if (s.end <= s.start)
|
||||
spans.erase(spans.begin() + i);
|
||||
else
|
||||
++i;
|
||||
}
|
||||
}
|
||||
|
||||
#endif
|
||||
Reference in New Issue
Block a user