#pragma once #include "autocomplete.h" #include "process.hpp" #include "source.h" #include #include #include #include #include #include namespace Source { class LanguageProtocolView; } namespace LanguageProtocol { class Offset { public: Offset(const boost::property_tree::ptree &pt) : line(pt.get("line")), character(pt.get("character")) {} int line; int character; }; class Range { public: Range(const boost::property_tree::ptree &pt) : start(pt.get_child("start")), end(pt.get_child("end")) {} Range() = default; Offset start, end; }; class Location { public: Location(const boost::property_tree::ptree &pt, std::string uri_ = {}) : range(pt.get_child("range")) { if(uri_.empty()) { uri = pt.get("uri"); uri.erase(0, 7); } else uri = std::move(uri_); } std::string uri; Range range; }; class Diagnostic { public: class RelatedInformation { public: RelatedInformation(const boost::property_tree::ptree &pt) : message(pt.get("message")), location(pt.get_child("location")) {} std::string message; Location location; }; Diagnostic(const boost::property_tree::ptree &pt) : message(pt.get("message")), range(pt.get_child("range")), severity(pt.get("severity", 0)) { auto related_information_it = pt.get_child("relatedInformation", boost::property_tree::ptree()); for(auto it = related_information_it.begin(); it != related_information_it.end(); ++it) related_informations.emplace_back(it->second); } std::string message; Range range; int severity; std::vector related_informations; }; class TextEdit { public: TextEdit(const boost::property_tree::ptree &pt, std::string new_text_ = {}) : range(pt.get_child("range")), new_text(new_text_.empty() ? pt.get("newText") : std::move(new_text_)) {} Range range; std::string new_text; }; class Capabilities { public: enum class TextDocumentSync { NONE = 0, FULL, INCREMENTAL }; TextDocumentSync text_document_sync; bool hover; bool completion; bool definition; bool references; bool document_highlight; bool workspace_symbol; bool document_symbol; bool document_formatting; bool document_range_formatting; bool rename; }; class Client { Client(std::string root_uri, std::string language_id); std::string root_uri; std::string language_id; Capabilities capabilities; std::set views; std::mutex views_mutex; std::mutex initialize_mutex; std::unique_ptr process; std::mutex read_write_mutex; std::stringstream server_message_stream; size_t server_message_size = static_cast(-1); size_t server_message_content_pos; bool header_read = false; size_t message_id = 1; std::map>> handlers; std::vector timeout_threads; std::mutex timeout_threads_mutex; public: static std::shared_ptr get(const boost::filesystem::path &file_path, const std::string &language_id); ~Client(); bool initialized = false; Capabilities initialize(Source::LanguageProtocolView *view); void close(Source::LanguageProtocolView *view); void parse_server_message(); void write_request(Source::LanguageProtocolView *view, const std::string &method, const std::string ¶ms, std::function &&function = nullptr); void write_notification(const std::string &method, const std::string ¶ms); void handle_server_request(const std::string &method, const boost::property_tree::ptree ¶ms); }; } // namespace LanguageProtocol namespace Source { class LanguageProtocolView : public View { public: LanguageProtocolView(const boost::filesystem::path &file_path, const Glib::RefPtr &language, std::string language_id_); void initialize(bool setup); void close(); ~LanguageProtocolView() override; void rename(const boost::filesystem::path &path) override; bool save() override; void update_diagnostics(std::vector &&diagnostics); Gtk::TextIter get_iter_at_line_pos(int line, int pos) override; protected: void show_type_tooltips(const Gdk::Rectangle &rectangle) override; void apply_similar_symbol_tag() override; void apply_clickable_tag(const Gtk::TextIter &iter) override; private: std::string language_id; LanguageProtocol::Capabilities capabilities; std::shared_ptr client; size_t document_version = 1; std::thread initialize_thread; Dispatcher dispatcher; void setup_navigation_and_refactoring(); void escape_text(std::string &text); void tag_similar_symbols(); Offset get_declaration(const Gtk::TextIter &iter); Autocomplete autocomplete; void setup_autocomplete(); std::vector autocomplete_comment; std::vector autocomplete_insert; std::list, Glib::RefPtr>> argument_marks; boost::filesystem::path flow_coverage_executable; std::vector, Glib::RefPtr>> flow_coverage_marks; size_t num_warnings = 0, num_errors = 0, num_fix_its = 0, num_flow_coverage_warnings = 0; void add_flow_coverage_tooltips(bool called_in_thread); }; } // namespace Source