Cleanup and add visible whitespaces.
This commit is contained in:
@@ -6,6 +6,9 @@ A TUI IDE.
|
||||
|
||||
# TODO
|
||||
|
||||
- [ ] Fix indentation logic
|
||||
- [ ] For `"insertTextFormat": 2` in `clangd` and similar use only the last word in the signature when replacing
|
||||
- [ ] Keep a list of words in the current buffer. (for auto completion) (maybe?)
|
||||
- [ ] Add ecma to js and make tsx
|
||||
- [ ] Add support for LSP & autocomplete / snippets.
|
||||
- First research
|
||||
@@ -27,7 +30,6 @@ A TUI IDE.
|
||||
3. One for Warnings/errors and inlay hints etc. (stuff that adds virtual text to the editor)
|
||||
4. One for fromatting and stuff like that. (stuff that edits the buffer text)
|
||||
- [ ] Add codeium/copilot support for auto-completion (uses the VAI virtual text) as a test phase.
|
||||
- [ ] Redo cpp/c/h scm file . also pretty much all of them do manually
|
||||
- [ ] Add a whitespace highlighter (nerd font). for spaces and tabs at start/end of line. not as virtual but instead at render time.
|
||||
- [ ] Once renderer is proven to work well (i.e. redo this commit) merge `experimental` branch into `main`. commit `43f443e` on `experimental`.
|
||||
- [ ] Add snippets from wherever i get them. (like luasnip or vsnip)
|
||||
@@ -50,6 +52,8 @@ A TUI IDE.
|
||||
- [ ] Add the highlight of block edges when cursor is on a bracket (or in). (prolly from lsp)
|
||||
- [ ] Add this thing where selection double click on a bracket selects whole block.
|
||||
- (only on the first time) and sets mode to `WORD`.
|
||||
- [ ] Redo cpp/c/h scm file . also pretty much all of them do manually
|
||||
- [ ] Try making `lua-typed` and man pages `tree-sitter` grammar.
|
||||
- [ ] Redo folding system and its relation to move_line_* functions. (Currently its a mess)
|
||||
- [ ] Make whole thing event driven and not clock driven.
|
||||
|
||||
|
||||
@@ -123,6 +123,12 @@
|
||||
;; !cpp
|
||||
(code_fence_content) @injection.cpp)
|
||||
|
||||
(fenced_code_block
|
||||
(info_string
|
||||
(language) @injection.language (#match? @injection.language "^objective-cpp$"))
|
||||
;; !cpp
|
||||
(code_fence_content) @injection.cpp)
|
||||
|
||||
(fenced_code_block
|
||||
(info_string
|
||||
(language) @injection.language (#match? @injection.language "^h$"))
|
||||
|
||||
@@ -33,6 +33,8 @@ struct Editor {
|
||||
Queue<TSInputEdit> edit_queue;
|
||||
std::vector<Fold> folds;
|
||||
Spans spans;
|
||||
// TODO: Split into 2 groups to have their own mutex's . one for word hl and
|
||||
// one for hex colors
|
||||
Spans def_spans;
|
||||
uint32_t hooks[94];
|
||||
bool jumper_set;
|
||||
|
||||
@@ -33,6 +33,8 @@ struct LSPInstance {
|
||||
std::atomic<bool> exited = false;
|
||||
bool incremental_sync = false;
|
||||
bool allow_hover = false;
|
||||
bool allow_completion = false;
|
||||
std::string trigger_chars;
|
||||
uint32_t last_id = 0;
|
||||
Queue<json> inbox;
|
||||
Queue<json> outbox;
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
#include "./pch.h"
|
||||
#include "./utils.h"
|
||||
#include <cstdint>
|
||||
|
||||
#define KEY_CHAR 0
|
||||
#define KEY_SPECIAL 1
|
||||
|
||||
@@ -12,9 +12,7 @@ end
|
||||
# Emoji-heavy strings
|
||||
emojis = "👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏👋🌏"
|
||||
|
||||
# Mixed-width CJK blocks
|
||||
#
|
||||
# https://chatgpt.com/c/695232e9-febc-8331-88c0-b47020948e5b
|
||||
# Mixed-width CJK block
|
||||
cjk_samples = [
|
||||
"漢字テスト",
|
||||
"測試中文字串",
|
||||
|
||||
@@ -1,3 +1,4 @@
|
||||
#include <cstdint>
|
||||
extern "C" {
|
||||
#include "../libs/libgrapheme/grapheme.h"
|
||||
}
|
||||
@@ -206,6 +207,14 @@ void render_editor(Editor *editor) {
|
||||
break;
|
||||
if (line_len > 0 && line[line_len - 1] == '\n')
|
||||
line_len--;
|
||||
uint32_t content_end = line_len;
|
||||
while (content_end > 0 &&
|
||||
(line[content_end - 1] == ' ' || line[content_end - 1] == '\t'))
|
||||
content_end--;
|
||||
uint32_t content_start = 0;
|
||||
while (content_start < line_len &&
|
||||
(line[content_start] == ' ' || line[content_start] == '\t'))
|
||||
content_start++;
|
||||
std::vector<VWarn> line_warnings;
|
||||
while (warn_it != editor->warnings.end() && warn_it->line == line_index) {
|
||||
line_warnings.push_back(*warn_it);
|
||||
@@ -258,9 +267,9 @@ void render_editor(Editor *editor) {
|
||||
uint8_t fl = hl ? hl->flags : 0;
|
||||
if (def_hl) {
|
||||
if (def_hl->fg != 0)
|
||||
fg |= def_hl->fg;
|
||||
fg = def_hl->fg;
|
||||
if (def_hl->bg != 0)
|
||||
bg |= def_hl->bg;
|
||||
bg = def_hl->bg;
|
||||
fl |= def_hl->flags;
|
||||
}
|
||||
if (editor->selection_active && absolute_byte_pos >= sel_start &&
|
||||
@@ -297,8 +306,19 @@ void render_editor(Editor *editor) {
|
||||
int width = display_width(cluster.c_str(), cluster_len);
|
||||
if (col + width > render_width)
|
||||
break;
|
||||
update(editor->position.row + rendered_rows, render_x + col,
|
||||
cluster.c_str(), fg, bg | color, fl, u_color);
|
||||
if (current_byte_offset + local_render_offset >= content_start &&
|
||||
current_byte_offset + local_render_offset < content_end) {
|
||||
update(editor->position.row + rendered_rows, render_x + col,
|
||||
cluster.c_str(), fg, bg | color, fl, u_color);
|
||||
} else {
|
||||
if (cluster[0] == ' ') {
|
||||
update(editor->position.row + rendered_rows, render_x + col, "·",
|
||||
0x282828, bg | color, fl, u_color);
|
||||
} else {
|
||||
update(editor->position.row + rendered_rows, render_x + col, "-> ",
|
||||
0x282828, bg | color, (fl & ~CF_BOLD) | CF_ITALIC, u_color);
|
||||
}
|
||||
}
|
||||
local_render_offset += cluster_len;
|
||||
line_left -= cluster_len;
|
||||
col += width;
|
||||
|
||||
@@ -264,7 +264,6 @@ void handle_editor_event(Editor *editor, KeyEvent event) {
|
||||
pending->editor = editor;
|
||||
pending->method = "textDocument/hover";
|
||||
pending->callback = [](Editor *editor, std::string, json hover) {
|
||||
log("%s\n", hover.dump().c_str());
|
||||
if (hover.contains("result") && !hover["result"].is_null()) {
|
||||
auto &contents = hover["result"]["contents"];
|
||||
std::string hover_text = "";
|
||||
@@ -367,6 +366,45 @@ void handle_editor_event(Editor *editor, KeyEvent event) {
|
||||
case CTRL('s'):
|
||||
save_file(editor);
|
||||
break;
|
||||
case CTRL(' '):
|
||||
if (editor->lsp) {
|
||||
json msg = {
|
||||
{"jsonrpc", "2.0"},
|
||||
{"method", "textDocument/completion"},
|
||||
{
|
||||
"params",
|
||||
{
|
||||
{
|
||||
"textDocument",
|
||||
{
|
||||
{"uri", editor->uri},
|
||||
},
|
||||
},
|
||||
{
|
||||
"position",
|
||||
{
|
||||
{"line", editor->cursor.row},
|
||||
{"character", editor->cursor.col},
|
||||
},
|
||||
},
|
||||
{
|
||||
"context",
|
||||
{
|
||||
{"triggerKind", 1},
|
||||
},
|
||||
},
|
||||
},
|
||||
},
|
||||
};
|
||||
LSPPending *pending = new LSPPending();
|
||||
pending->editor = editor;
|
||||
pending->method = "textDocument/completion";
|
||||
pending->callback = [](Editor *editor, std::string, json completion) {
|
||||
log("%s\n", completion.dump().c_str());
|
||||
};
|
||||
lsp_send(editor->lsp, msg, pending);
|
||||
}
|
||||
break;
|
||||
case 'p':
|
||||
uint32_t len;
|
||||
char *text = get_from_clipboard(&len);
|
||||
@@ -652,7 +690,7 @@ void hover_diagnostic(Editor *editor) {
|
||||
editor->diagnostics_active = true;
|
||||
}
|
||||
|
||||
static Highlight HL_UNDERLINE = {0, 0, 1 << 2, 100};
|
||||
static Highlight HL_UNDERLINE = {0, 0, CF_UNDERLINE, UINT8_MAX - 1};
|
||||
|
||||
void editor_worker(Editor *editor) {
|
||||
if (!editor || !editor->root)
|
||||
@@ -665,17 +703,18 @@ void editor_worker(Editor *editor) {
|
||||
ts_collect_spans(editor);
|
||||
uint32_t prev_col, next_col;
|
||||
word_boundaries_exclusive(editor, editor->cursor, &prev_col, &next_col);
|
||||
std::unique_lock lock(editor->def_spans.mtx);
|
||||
editor->def_spans.spans.clear();
|
||||
if (next_col - prev_col > 0 && next_col - prev_col < 256 - 4) {
|
||||
std::shared_lock lock(editor->knot_mtx);
|
||||
std::shared_lock lockk(editor->knot_mtx);
|
||||
uint32_t offset = line_to_byte(editor->root, editor->cursor.row, nullptr);
|
||||
char *word = read(editor->root, offset + prev_col, next_col - prev_col);
|
||||
lockk.unlock();
|
||||
if (word) {
|
||||
char buf[256];
|
||||
snprintf(buf, sizeof(buf), "\\b%s\\b", word);
|
||||
std::vector<std::pair<size_t, size_t>> results =
|
||||
search_rope(editor->root, buf);
|
||||
std::unique_lock lock(editor->def_spans.mtx);
|
||||
editor->def_spans.spans.clear();
|
||||
for (const auto &match : results) {
|
||||
Span s;
|
||||
s.start = match.first;
|
||||
@@ -683,15 +722,35 @@ void editor_worker(Editor *editor) {
|
||||
s.hl = &HL_UNDERLINE;
|
||||
editor->def_spans.spans.push_back(s);
|
||||
}
|
||||
std::sort(editor->def_spans.spans.begin(), editor->def_spans.spans.end());
|
||||
lock.unlock();
|
||||
free(word);
|
||||
}
|
||||
} else {
|
||||
std::unique_lock lock(editor->def_spans.mtx);
|
||||
editor->def_spans.spans.clear();
|
||||
lock.unlock();
|
||||
}
|
||||
uint8_t top = 0;
|
||||
static Highlight *hl_s = (Highlight *)calloc(200, sizeof(Highlight));
|
||||
if (!hl_s)
|
||||
exit(ENOMEM);
|
||||
std::vector<std::pair<size_t, size_t>> results =
|
||||
search_rope(editor->root, "(0x|#)[0-9a-fA-F]{6}");
|
||||
std::shared_lock lockk(editor->knot_mtx);
|
||||
for (int i = 0; i < results.size() && top < 200; i++) {
|
||||
Span s;
|
||||
s.start = results[i].first;
|
||||
s.end = results[i].first + results[i].second;
|
||||
char *buf = read(editor->root, s.start, s.end - s.start);
|
||||
int x = buf[0] == '#' ? 1 : 2;
|
||||
uint32_t bg = HEX(buf + x);
|
||||
free(buf);
|
||||
uint8_t r = bg >> 16, g = (bg >> 8) & 0xFF, b = bg & 0xFF;
|
||||
double luminance = 0.299 * r + 0.587 * g + 0.114 * b;
|
||||
uint32_t fg = (luminance > 128) ? 0x010101 : 0xFEFEFE;
|
||||
hl_s[top] = {fg, bg, CF_BOLD, UINT8_MAX};
|
||||
s.hl = &hl_s[top];
|
||||
editor->def_spans.spans.push_back(s);
|
||||
top++;
|
||||
}
|
||||
std::sort(editor->def_spans.spans.begin(), editor->def_spans.spans.end());
|
||||
lock.unlock();
|
||||
lockk.unlock();
|
||||
hover_diagnostic(editor);
|
||||
}
|
||||
|
||||
|
||||
22
src/lsp.cc
22
src/lsp.cc
@@ -84,11 +84,12 @@ std::shared_ptr<LSPInstance> get_or_init_lsp(uint8_t lsp_id) {
|
||||
lsp->incremental_sync = (change_type == 2);
|
||||
}
|
||||
}
|
||||
if (caps.contains("hoverProvider")) {
|
||||
if (caps.contains("hoverProvider"))
|
||||
lsp->allow_hover = caps["hoverProvider"].get<bool>();
|
||||
} else {
|
||||
else
|
||||
lsp->allow_hover = false;
|
||||
}
|
||||
if (caps.contains("completionProvider"))
|
||||
lsp->allow_completion = true;
|
||||
}
|
||||
lsp->initialized = true;
|
||||
json initialized = {{"jsonrpc", "2.0"},
|
||||
@@ -110,7 +111,20 @@ std::shared_ptr<LSPInstance> get_or_init_lsp(uint8_t lsp_id) {
|
||||
{"capabilities",
|
||||
{{"textDocument",
|
||||
{{"publishDiagnostics", {{"relatedInformation", true}}},
|
||||
{"hover", {{"contentFormat", {"markdown", "plaintext"}}}}}}}}}}};
|
||||
{"hover", {{"contentFormat", {"markdown", "plaintext"}}}},
|
||||
{"completion",
|
||||
{{"completionItem",
|
||||
{{"snippetSupport", true},
|
||||
{"documentationFormat", {"markdown", "plaintext"}},
|
||||
{"resolveSupport",
|
||||
{{"properties", {"documentation", "detail"}}}},
|
||||
{"insertReplaceSupport", true},
|
||||
{"labelDetailsSupport", true},
|
||||
{"insertTextModeSupport", {{"valueSet", json::array({1})}}}}},
|
||||
{"completionItemKind",
|
||||
{{"valueSet", {1, 2, 3, 4, 5, 6, 7, 8, 9, 10}}}},
|
||||
{"contextSupport", true},
|
||||
{"insertTextMode", 1}}}}}}}}}};
|
||||
lsp_send(lsp, init_message, pending);
|
||||
active_lsps[lsp_id] = lsp;
|
||||
return lsp;
|
||||
|
||||
@@ -62,6 +62,7 @@ void update(uint32_t row, uint32_t col, std::string utf8, uint32_t fg,
|
||||
screen[idx].fg = fg;
|
||||
screen[idx].bg = bg;
|
||||
screen[idx].flags = flags;
|
||||
screen[idx].ul_color = 0;
|
||||
}
|
||||
|
||||
void update(uint32_t row, uint32_t col, const char *utf8, uint32_t fg,
|
||||
@@ -77,6 +78,7 @@ void update(uint32_t row, uint32_t col, const char *utf8, uint32_t fg,
|
||||
screen[idx].fg = fg;
|
||||
screen[idx].bg = bg;
|
||||
screen[idx].flags = flags;
|
||||
screen[idx].ul_color = 0;
|
||||
}
|
||||
|
||||
void update(uint32_t row, uint32_t col, std::string utf8, uint32_t fg,
|
||||
|
||||
Reference in New Issue
Block a user