Lsp completion logic

This commit is contained in:
2026-01-04 03:27:17 +00:00
parent ac04754318
commit a905e333fc
24 changed files with 624 additions and 136 deletions

View File

@@ -0,0 +1,44 @@
#ifndef EDITOR_COMPLETIONS_H
#define EDITOR_COMPLETIONS_H
#include "editor/decl.h"
#include "pch.h"
#include "ui/completionbox.h"
#include "utils/utils.h"
struct CompletionItem {
std::string label; // Shown in the autocomplete box
uint8_t kind; // Function, variable, class, etc.
std::optional<std::string> detail; // Shown greyed in autocomplete box
std::optional<std::string> documentation; // Hover box (can be lazy-loaded)
bool is_markup = false;
bool deprecated = false; // Shown with strikethrough, may push down in list
std::string sort; // Used for sorting
std::string filter; // Used for filtering (default: label)
bool snippet = false;
std::vector<TextEdit> edits;
json original;
std::vector<char> end_chars; // Ends completion session if typed
};
struct CompletionSession {
std::shared_mutex mtx;
bool active = false;
Coord hook; // set to start of word
std::optional<std::string> prefix; // text between hook and cursor
uint8_t select = 0; // index of selected item (defualts to preselcted one
// when data requested)
std::vector<CompletionItem> items;
std::vector<uint8_t> visible;
bool complete = true; // If false, client may request more items on filter
// (but doesnt try filtering on its own)
std::optional<char> trigger_char; // Character that triggered completion sent
// to lsp for isIncomplete resolving
uint8_t trigger = 0; // Type of trigger (1: manual, 2: trigger char, 3: auto)
CompletionBox box;
CompletionSession() : box(this) {}
};
#endif

View File

@@ -3,6 +3,14 @@
#include "utils/utils.h"
struct TextEdit {
// NOTE: start.col is in utf16 index and not clusters or utf8
Coord start;
// NOTE: end.col is in utf16 index and not clusters or utf8
Coord end;
std::string text;
};
struct Fold {
uint32_t start;
uint32_t end;

View File

@@ -1,10 +1,12 @@
#ifndef EDITOR_H
#define EDITOR_H
#include "editor/completions.h"
#include "editor/spans.h"
#include "io/knot.h"
#include "io/sysio.h"
#include "ts/decl.h"
#include "ui/completionbox.h"
#include "ui/diagnostics.h"
#include "ui/hover.h"
#include "utils/utils.h"
@@ -49,6 +51,7 @@ struct Editor {
bool diagnostics_active;
DiagnosticBox diagnostics;
int lsp_version = 1;
CompletionSession completion;
};
Editor *new_editor(const char *filename_arg, Coord position, Coord size);
@@ -73,6 +76,8 @@ void ensure_scroll(Editor *editor);
void handle_editor_event(Editor *editor, KeyEvent event);
void edit_erase(Editor *editor, Coord pos, int64_t len);
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);
Coord editor_hit_test(Editor *editor, uint32_t x, uint32_t y);
char *get_selection(Editor *editor, uint32_t *out_len, Coord *out_start);
void editor_worker(Editor *editor);
@@ -90,6 +95,13 @@ uint32_t leading_indent(const char *line, uint32_t len);
uint32_t get_indent(Editor *editor, Coord cursor);
bool closing_after_cursor(const char *line, uint32_t len, uint32_t col);
void editor_lsp_handle(Editor *editor, json msg);
void apply_lsp_edits(Editor *editor, std::vector<TextEdit> edits);
void completion_resolve_doc(Editor *editor);
void complete_accept(Editor *editor);
void complete_next(Editor *editor);
void complete_prev(Editor *editor);
void complete_select(Editor *editor, uint8_t index);
void handle_completion(Editor *editor, KeyEvent event);
inline void apply_hook_insertion(Editor *editor, uint32_t line, uint32_t rows) {
for (auto &hook : editor->hooks)