#include "editor/editor.h" void apply_lsp_edits(Editor *editor, std::vector edits) { std::sort( edits.begin(), edits.end(), [](const TextEdit &a, const TextEdit &b) { return a.start > b.start; }); for (const auto &edit : edits) edit_replace(editor, edit.start, edit.end, edit.text.c_str(), edit.text.size()); editor->cursor = edits[0].start; editor->cursor = move_right_pure(editor, editor->cursor, count_clusters(edits[0].text.c_str(), edits[0].text.size(), 0, edits[0].text.size())); } void editor_lsp_handle(Editor *editor, json msg) { if (msg.contains("method") && msg["method"] == "textDocument/publishDiagnostics") { std::unique_lock lock(editor->v_mtx); editor->warnings.clear(); json diagnostics = msg["params"]["diagnostics"]; for (size_t i = 0; i < diagnostics.size(); i++) { json d = diagnostics[i]; VWarn w; // HACK: convert back to utf-8 but as this is only visually affecting it // is not worth getting the line string from the rope. w.line = d["range"]["start"]["line"]; w.start = d["range"]["start"]["character"]; uint32_t end = d["range"]["end"]["character"]; if (d["range"]["end"]["line"] == w.line) w.end = end; std::string text = trim(d["message"].get()); w.text_full = text; auto pos = text.find('\n'); w.text = (pos == std::string::npos) ? text : text.substr(0, pos); if (d.contains("source")) w.source = d["source"].get(); if (d.contains("code")) { w.code = "["; if (d["code"].is_string()) w.code += d["code"].get() + "] "; else if (d["code"].is_number()) w.code += std::to_string(d["code"].get()) + "] "; else w.code.clear(); if (d.contains("codeDescription") && d["codeDescription"].contains("href")) w.code += d["codeDescription"]["href"].get(); } if (d.contains("relatedInformation")) { json related = d["relatedInformation"]; for (size_t j = 0; j < related.size(); j++) { json rel = related[j]; std::string message = rel["message"].get(); auto pos = message.find('\n'); message = (pos == std::string::npos) ? message : message.substr(0, pos); std::string uri = filename_from_path( percent_decode(rel["location"]["uri"].get())); std::string row = std::to_string( rel["location"]["range"]["start"]["line"].get()); w.see_also.push_back(uri + ":" + row + ": " + message); } } w.type = 1; if (d.contains("severity")) w.type = d["severity"].get(); editor->warnings.push_back(w); } std::sort(editor->warnings.begin(), editor->warnings.end()); editor->warnings_dirty = true; } }