Fix bugs with hl line data structures
This commit is contained in:
@@ -1,7 +1,6 @@
|
||||
#include "editor/editor.h"
|
||||
#include "lsp/lsp.h"
|
||||
#include "utils/utils.h"
|
||||
#include <cstdint>
|
||||
|
||||
void edit_erase(Editor *editor, Coord pos, int64_t len) {
|
||||
if (len == 0)
|
||||
@@ -52,7 +51,7 @@ void edit_erase(Editor *editor, Coord pos, int64_t len) {
|
||||
editor->root = erase(editor->root, start, byte_pos - start);
|
||||
lock_2.unlock();
|
||||
if (editor->parser)
|
||||
editor->parser->edit(editor->root, start_row, end_row, start_row);
|
||||
editor->parser->edit(start_row, end_row, 0);
|
||||
if (do_lsp) {
|
||||
if (editor->lsp->incremental_sync) {
|
||||
json message = {
|
||||
@@ -124,7 +123,7 @@ void edit_erase(Editor *editor, Coord pos, int64_t len) {
|
||||
editor->root = erase(editor->root, byte_pos, end - byte_pos);
|
||||
lock_2.unlock();
|
||||
if (editor->parser)
|
||||
editor->parser->edit(editor->root, start_row, end_row, start_row);
|
||||
editor->parser->edit(start_row, end_row, 0);
|
||||
if (do_lsp) {
|
||||
if (editor->lsp->incremental_sync) {
|
||||
json message = {
|
||||
@@ -175,7 +174,7 @@ void edit_insert(Editor *editor, Coord pos, char *data, uint32_t len) {
|
||||
apply_hook_insertion(editor, pos.row, rows);
|
||||
lock_2.unlock();
|
||||
if (editor->parser)
|
||||
editor->parser->edit(editor->root, pos.row, pos.row, pos.row + rows);
|
||||
editor->parser->edit(pos.row, pos.row, rows);
|
||||
if (editor->lsp) {
|
||||
if (editor->lsp->incremental_sync) {
|
||||
lock_1.lock();
|
||||
@@ -218,19 +217,64 @@ void edit_insert(Editor *editor, Coord pos, char *data, uint32_t len) {
|
||||
|
||||
void edit_replace(Editor *editor, Coord start, Coord end, const char *text,
|
||||
uint32_t len) {
|
||||
std::shared_lock lock(editor->knot_mtx);
|
||||
std::unique_lock lock(editor->knot_mtx);
|
||||
uint32_t start_byte =
|
||||
line_to_byte(editor->root, start.row, nullptr) + start.col;
|
||||
uint32_t end_byte = line_to_byte(editor->root, end.row, nullptr) + end.col;
|
||||
char *buf = read(editor->root, start_byte, end_byte - start_byte);
|
||||
if (!buf)
|
||||
return;
|
||||
lock.unlock();
|
||||
uint32_t erase_len =
|
||||
count_clusters(buf, end_byte - start_byte, 0, end_byte - start_byte);
|
||||
free(buf);
|
||||
if (erase_len != 0)
|
||||
edit_erase(editor, start, erase_len);
|
||||
LineIterator *it = begin_l_iter(editor->root, start.row);
|
||||
char *line = next_line(it, nullptr);
|
||||
int utf16_start = 0;
|
||||
if (line)
|
||||
utf16_start = utf8_byte_offset_to_utf16(line, start.col);
|
||||
free(it->buffer);
|
||||
free(it);
|
||||
it = begin_l_iter(editor->root, end.row);
|
||||
line = next_line(it, nullptr);
|
||||
int utf16_end = 0;
|
||||
if (line)
|
||||
utf16_end = utf8_byte_offset_to_utf16(line, end.col);
|
||||
free(it->buffer);
|
||||
free(it);
|
||||
if (start_byte != end_byte)
|
||||
editor->root = erase(editor->root, start_byte, end_byte - start_byte);
|
||||
if (len > 0)
|
||||
edit_insert(editor, start, const_cast<char *>(text), len);
|
||||
editor->root = insert(editor->root, start_byte, (char *)text, len);
|
||||
uint32_t rows = 0;
|
||||
for (uint32_t i = 0; i < len; i++)
|
||||
if (text[i] == '\n')
|
||||
rows++;
|
||||
if (editor->parser) {
|
||||
editor->parser->edit(start.row, end.row - 1, 0);
|
||||
editor->parser->edit(start.row, start.row, rows);
|
||||
}
|
||||
if (editor->lsp) {
|
||||
if (editor->lsp->incremental_sync) {
|
||||
json message = {
|
||||
{"jsonrpc", "2.0"},
|
||||
{"method", "textDocument/didChange"},
|
||||
{"params",
|
||||
{{"textDocument",
|
||||
{{"uri", editor->uri}, {"version", ++editor->lsp_version}}},
|
||||
{"contentChanges",
|
||||
json::array(
|
||||
{{{"range",
|
||||
{{"start",
|
||||
{{"line", start.row}, {"character", utf16_start}}},
|
||||
{"end", {{"line", end.row}, {"character", utf16_end}}}}},
|
||||
{"text", std::string(text, len)}}})}}}};
|
||||
lsp_send(editor->lsp, message, nullptr);
|
||||
} else {
|
||||
char *buf = read(editor->root, 0, editor->root->char_count);
|
||||
std::string full_text(buf);
|
||||
free(buf);
|
||||
json message = {
|
||||
{"jsonrpc", "2.0"},
|
||||
{"method", "textDocument/didChange"},
|
||||
{"params",
|
||||
{{"textDocument",
|
||||
{{"uri", editor->uri}, {"version", ++editor->lsp_version}}},
|
||||
{"contentChanges", json::array({{{"text", full_text}}})}}}};
|
||||
lsp_send(editor->lsp, message, nullptr);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -30,8 +30,11 @@ Editor *new_editor(const char *filename_arg, Coord position, Coord size) {
|
||||
free(str);
|
||||
editor->lang = language_for_file(filename.c_str());
|
||||
if (editor->lang.name != "unknown")
|
||||
editor->parser = new Parser(editor->root, &editor->knot_mtx,
|
||||
editor->lang.name, size.row + 5);
|
||||
editor->parser = new Parser(editor, editor->lang.name, size.row + 5);
|
||||
if (editor->lang.name == "css" || editor->lang.name == "html" ||
|
||||
editor->lang.name == "javascript" || editor->lang.name == "markdown" ||
|
||||
editor->lang.name == "typescript")
|
||||
editor->is_css_color = true;
|
||||
if (len <= (1024 * 28))
|
||||
request_add_to_lsp(editor->lang, editor);
|
||||
editor->indents.compute_indent(editor);
|
||||
@@ -52,12 +55,13 @@ void save_file(Editor *editor) {
|
||||
return;
|
||||
std::shared_lock lock(editor->knot_mtx);
|
||||
int version = editor->lsp_version;
|
||||
char *str = read(editor->root, 0, editor->root->char_count);
|
||||
uint32_t char_count = editor->root->char_count;
|
||||
char *str = read(editor->root, 0, char_count);
|
||||
if (!str)
|
||||
return;
|
||||
lock.unlock();
|
||||
std::ofstream out(editor->filename);
|
||||
out.write(str, editor->root->char_count);
|
||||
out.write(str, char_count);
|
||||
out.close();
|
||||
free(str);
|
||||
if (editor->lsp) {
|
||||
@@ -99,12 +103,14 @@ void save_file(Editor *editor) {
|
||||
apply_lsp_edits(editor, t_edits, false);
|
||||
ensure_scroll(editor);
|
||||
std::shared_lock lock(editor->knot_mtx);
|
||||
char *str = read(editor->root, 0, editor->root->char_count);
|
||||
uint32_t char_count = editor->root->char_count;
|
||||
char *str = read(editor->root, 0, char_count);
|
||||
if (!str)
|
||||
return;
|
||||
lock.unlock();
|
||||
std::ofstream out(editor->filename);
|
||||
out.write(str, editor->root->char_count);
|
||||
out.write(str, char_count);
|
||||
out.close();
|
||||
free(str);
|
||||
lsp_send(editor->lsp, save_msg, nullptr);
|
||||
}
|
||||
|
||||
@@ -1,10 +1,13 @@
|
||||
#include "editor/editor.h"
|
||||
#include "io/sysio.h"
|
||||
#include "main.h"
|
||||
#include "syntax/decl.h"
|
||||
#include "syntax/parser.h"
|
||||
#include <cstdint>
|
||||
|
||||
void render_editor(Editor *editor) {
|
||||
uint32_t sel_start = 0, sel_end = 0;
|
||||
std::shared_lock knot_lock(editor->knot_mtx);
|
||||
uint32_t numlen =
|
||||
EXTRA_META + static_cast<int>(std::log10(editor->root->line_count + 1));
|
||||
uint32_t render_width = editor->size.col - numlen;
|
||||
@@ -34,7 +37,6 @@ void render_editor(Editor *editor) {
|
||||
return (int)token.type;
|
||||
return 0;
|
||||
};
|
||||
std::shared_lock knot_lock(editor->knot_mtx);
|
||||
if (editor->selection_active) {
|
||||
Coord start, end;
|
||||
if (editor->cursor >= editor->selection) {
|
||||
@@ -88,6 +90,18 @@ void render_editor(Editor *editor) {
|
||||
LineIterator *it = begin_l_iter(editor->root, line_index);
|
||||
if (!it)
|
||||
return;
|
||||
uint32_t prev_col, next_col;
|
||||
std::string word;
|
||||
word_boundaries_exclusive(editor, editor->cursor, &prev_col, &next_col);
|
||||
if (next_col - prev_col > 0 && next_col - prev_col < 256 - 4) {
|
||||
uint32_t offset = line_to_byte(editor->root, editor->cursor.row, nullptr);
|
||||
char *word_ptr = read(editor->root, offset + prev_col, next_col - prev_col);
|
||||
if (word_ptr) {
|
||||
word = std::string(word_ptr, next_col - prev_col);
|
||||
free(word_ptr);
|
||||
}
|
||||
}
|
||||
editor->extra_hl.render(editor->root, line_index, word, editor->is_css_color);
|
||||
uint32_t rendered_rows = 0;
|
||||
uint32_t global_byte_offset = line_to_byte(editor->root, line_index, nullptr);
|
||||
while (rendered_rows < editor->size.row) {
|
||||
@@ -157,9 +171,19 @@ void render_editor(Editor *editor) {
|
||||
const Highlight *hl = nullptr;
|
||||
if (editor->parser)
|
||||
hl = &highlights[get_type(current_byte_offset + local_render_offset)];
|
||||
uint32_t fg = hl ? hl->fg : 0xFFFFFF;
|
||||
uint32_t bg = hl ? hl->bg : 0;
|
||||
uint8_t fl = hl ? hl->flags : 0;
|
||||
std::optional<std::pair<uint32_t, uint32_t>> extra =
|
||||
editor->extra_hl.get(
|
||||
{line_index, current_byte_offset + local_render_offset});
|
||||
uint32_t fg = extra && extra->second != UINT32_MAX
|
||||
? extra->first
|
||||
: (hl ? hl->fg : 0xFFFFFF);
|
||||
uint32_t bg = extra && extra->second != UINT32_MAX
|
||||
? extra->second
|
||||
: (hl ? hl->bg : 0x000000);
|
||||
uint8_t fl =
|
||||
(hl ? hl->flags : 0) |
|
||||
(extra ? (extra->second != UINT32_MAX ? CF_BOLD : CF_UNDERLINE)
|
||||
: 0);
|
||||
if (editor->selection_active && absolute_byte_pos >= sel_start &&
|
||||
absolute_byte_pos < sel_end)
|
||||
bg = 0x555555;
|
||||
|
||||
Reference in New Issue
Block a user