diff --git a/src/menu.h b/src/menu.h index 5afa7a2..9d56d6f 100644 --- a/src/menu.h +++ b/src/menu.h @@ -22,6 +22,7 @@ public: Glib::RefPtr window_menu; std::unique_ptr right_click_line_menu; std::unique_ptr right_click_selected_menu; + std::function toggle_menu_items = []{}; private: Glib::RefPtr builder; }; diff --git a/src/project.cc b/src/project.cc index a21202d..d27ecdc 100644 --- a/src/project.cc +++ b/src/project.cc @@ -713,7 +713,7 @@ void Project::LanguageProtocol::show_symbols() { } std::vector names; std::promise result_processed; - client->write_request("workspace/symbol", "\"query\":\""+text+"\"", [&result_processed, &names, offsets, project_path](const boost::property_tree::ptree &result, bool error) { + client->write_request(nullptr, "workspace/symbol", "\"query\":\""+text+"\"", [&result_processed, &names, offsets, project_path](const boost::property_tree::ptree &result, bool error) { if(!error) { for(auto it=result.begin();it!=result.end();++it) { auto name=it->second.get("name", ""); diff --git a/src/source_language_protocol.cc b/src/source_language_protocol.cc index 6f1d9a1..0a21b28 100644 --- a/src/source_language_protocol.cc +++ b/src/source_language_protocol.cc @@ -7,6 +7,7 @@ #ifdef JUCI_ENABLE_DEBUG #include "debug_lldb.h" #endif +#include "menu.h" #include #include #include @@ -41,13 +42,18 @@ std::shared_ptr LanguageProtocol::Client::get(const bo it=cache.emplace(cache_id, std::weak_ptr()).first; auto instance=it->second.lock(); if(!instance) - it->second=instance=std::shared_ptr(new Client(root_uri, language_id)); + it->second=instance=std::shared_ptr(new Client(root_uri, language_id), [](Client *client_ptr) { + std::thread delete_thread([client_ptr] { + delete client_ptr; + }); + delete_thread.detach(); + }); return instance; } LanguageProtocol::Client::~Client() { std::promise result_processed; - write_request("shutdown", "", [this, &result_processed](const boost::property_tree::ptree &result, bool error) { + write_request(nullptr, "shutdown", "", [this, &result_processed](const boost::property_tree::ptree &result, bool error) { if(!error) this->write_notification("exit", ""); result_processed.set_value(); @@ -76,11 +82,13 @@ LanguageProtocol::Capabilities LanguageProtocol::Client::initialize(Source::Lang views.emplace(view); } + std::lock_guard lock(initialize_mutex); + if(initialized) return capabilities; std::promise result_processed; - write_request("initialize", "\"processId\":"+std::to_string(process->get_id())+",\"rootUri\":\"file://"+root_uri+"\",\"capabilities\":{\"workspace\":{\"didChangeConfiguration\":{\"dynamicRegistration\":true},\"didChangeWatchedFiles\":{\"dynamicRegistration\":true},\"symbol\":{\"dynamicRegistration\":true},\"executeCommand\":{\"dynamicRegistration\":true}},\"textDocument\":{\"synchronization\":{\"dynamicRegistration\":true,\"willSave\":true,\"willSaveWaitUntil\":true,\"didSave\":true},\"completion\":{\"dynamicRegistration\":true,\"completionItem\":{\"snippetSupport\":true}},\"hover\":{\"dynamicRegistration\":true},\"signatureHelp\":{\"dynamicRegistration\":true},\"definition\":{\"dynamicRegistration\":true},\"references\":{\"dynamicRegistration\":true},\"documentHighlight\":{\"dynamicRegistration\":true},\"documentSymbol\":{\"dynamicRegistration\":true},\"codeAction\":{\"dynamicRegistration\":true},\"codeLens\":{\"dynamicRegistration\":true},\"formatting\":{\"dynamicRegistration\":true},\"rangeFormatting\":{\"dynamicRegistration\":true},\"onTypeFormatting\":{\"dynamicRegistration\":true},\"rename\":{\"dynamicRegistration\":true},\"documentLink\":{\"dynamicRegistration\":true}}},\"initializationOptions\":{\"omitInitBuild\":true},\"trace\":\"off\"", [this, &result_processed](const boost::property_tree::ptree &result, bool error) { + write_request(nullptr, "initialize", "\"processId\":"+std::to_string(process->get_id())+",\"rootUri\":\"file://"+root_uri+"\",\"capabilities\":{\"workspace\":{\"didChangeConfiguration\":{\"dynamicRegistration\":true},\"didChangeWatchedFiles\":{\"dynamicRegistration\":true},\"symbol\":{\"dynamicRegistration\":true},\"executeCommand\":{\"dynamicRegistration\":true}},\"textDocument\":{\"synchronization\":{\"dynamicRegistration\":true,\"willSave\":true,\"willSaveWaitUntil\":true,\"didSave\":true},\"completion\":{\"dynamicRegistration\":true,\"completionItem\":{\"snippetSupport\":true}},\"hover\":{\"dynamicRegistration\":true},\"signatureHelp\":{\"dynamicRegistration\":true},\"definition\":{\"dynamicRegistration\":true},\"references\":{\"dynamicRegistration\":true},\"documentHighlight\":{\"dynamicRegistration\":true},\"documentSymbol\":{\"dynamicRegistration\":true},\"codeAction\":{\"dynamicRegistration\":true},\"codeLens\":{\"dynamicRegistration\":true},\"formatting\":{\"dynamicRegistration\":true},\"rangeFormatting\":{\"dynamicRegistration\":true},\"onTypeFormatting\":{\"dynamicRegistration\":true},\"rename\":{\"dynamicRegistration\":true},\"documentLink\":{\"dynamicRegistration\":true}}},\"initializationOptions\":{\"omitInitBuild\":true},\"trace\":\"off\"", [this, &result_processed](const boost::property_tree::ptree &result, bool error) { if(!error) { auto capabilities_pt=result.find("capabilities"); if(capabilities_pt!=result.not_found()) { @@ -109,10 +117,19 @@ LanguageProtocol::Capabilities LanguageProtocol::Client::initialize(Source::Lang } void LanguageProtocol::Client::close(Source::LanguageProtocolView *view) { - std::unique_lock lock(views_mutex); - auto it=views.find(view); - if(it!=views.end()) - views.erase(it); + { + std::unique_lock lock(views_mutex); + auto it=views.find(view); + if(it!=views.end()) + views.erase(it); + } + std::unique_lock lock(read_write_mutex); + for(auto it=handlers.begin();it!=handlers.end();) { + if(it->second.first==view) + it=handlers.erase(it); + else + it++; + } } void LanguageProtocol::Client::parse_server_message() { @@ -169,7 +186,7 @@ void LanguageProtocol::Client::parse_server_message() { if(message_id) { auto id_it=handlers.find(message_id); if(id_it!=handlers.end()) { - auto function=std::move(id_it->second); + auto function=std::move(id_it->second.second); handlers.erase(id_it->first); lock.unlock(); function(result_it->second, false); @@ -183,7 +200,7 @@ void LanguageProtocol::Client::parse_server_message() { if(message_id) { auto id_it=handlers.find(message_id); if(id_it!=handlers.end()) { - auto function=std::move(id_it->second); + auto function=std::move(id_it->second.second); handlers.erase(id_it->first); lock.unlock(); function(result_it->second, true); @@ -218,10 +235,10 @@ void LanguageProtocol::Client::parse_server_message() { } } -void LanguageProtocol::Client::write_request(const std::string &method, const std::string ¶ms, std::function &&function) { +void LanguageProtocol::Client::write_request(Source::LanguageProtocolView *view, const std::string &method, const std::string ¶ms, std::function &&function) { std::unique_lock lock(read_write_mutex); if(function) { - handlers.emplace(message_id, std::move(function)); + handlers.emplace(message_id, std::make_pair(view, std::move(function))); auto message_id=this->message_id; std::unique_lock lock(timeout_threads_mutex); @@ -236,7 +253,7 @@ void LanguageProtocol::Client::write_request(const std::string &method, const st std::unique_lock lock(read_write_mutex); auto id_it=handlers.find(message_id); if(id_it!=handlers.end()) { - auto function=std::move(id_it->second); + auto function=std::move(id_it->second.second); handlers.erase(id_it->first); lock.unlock(); function(boost::property_tree::ptree(), false); @@ -252,7 +269,7 @@ void LanguageProtocol::Client::write_request(const std::string &method, const st Terminal::get().async_print("Error writing to language protocol server. Please close and reopen all project source files.\n", true); auto id_it=handlers.find(message_id-1); if(id_it!=handlers.end()) { - auto function=std::move(id_it->second); + auto function=std::move(id_it->second.second); handlers.erase(id_it->first); lock.unlock(); function(boost::property_tree::ptree(), false); @@ -310,10 +327,20 @@ Source::LanguageProtocolView::LanguageProtocolView(const boost::filesystem::path similar_symbol_tag=get_buffer()->create_tag(); similar_symbol_tag->property_weight()=Pango::WEIGHT_ULTRAHEAVY; - capabilities=client->initialize(this); - std::string text=get_buffer()->get_text(); - escape_text(text); - client->write_notification("textDocument/didOpen", "\"textDocument\":{\"uri\":\""+uri+"\",\"languageId\":\""+language_id+"\",\"version\":"+std::to_string(document_version++)+",\"text\":\""+text+"\"}"); + initialize_thread=std::thread([this] { + auto capabilities=client->initialize(this); + dispatcher.post([this, capabilities] { + this->capabilities=capabilities; + + std::string text=get_buffer()->get_text(); + escape_text(text); + client->write_notification("textDocument/didOpen", "\"textDocument\":{\"uri\":\""+uri+"\",\"languageId\":\""+language_id+"\",\"version\":"+std::to_string(document_version++)+",\"text\":\""+text+"\"}"); + + setup_autocomplete(); + setup_navigation_and_refactoring(); + Menu::get().toggle_menu_items(); + }); + }); get_buffer()->signal_changed().connect([this] { get_buffer()->remove_tag(similar_symbol_tag, get_buffer()->begin(), get_buffer()->end()); @@ -359,14 +386,14 @@ Source::LanguageProtocolView::LanguageProtocolView(const boost::filesystem::path } client->write_notification("textDocument/didChange", "\"textDocument\":{\"uri\":\""+uri+"\",\"version\":"+std::to_string(document_version++)+"},\"contentChanges\":["+content_changes+"]"); }, false); - - setup_navigation_and_refactoring(); - setup_autocomplete(); } Source::LanguageProtocolView::~LanguageProtocolView() { delayed_tag_similar_symbols_connection.disconnect(); + if(initialize_thread.joinable()) + initialize_thread.join(); + autocomplete.state=Autocomplete::State::IDLE; if(autocomplete.thread.joinable()) autocomplete.thread.join(); @@ -417,7 +444,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() { params="\"textDocument\":{\"uri\":\""+uri+"\"},\"options\":{"+options+"}"; } - client->write_request(method, params, [&replaces, &result_processed](const boost::property_tree::ptree &result, bool error) { + client->write_request(this, method, params, [&replaces, &result_processed](const boost::property_tree::ptree &result, bool error) { if(!error) { for(auto it=result.begin();it!=result.end();++it) { auto range_it=it->second.find("range"); @@ -483,7 +510,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() { std::vector> usages; std::vector end_offsets; std::promise result_processed; - client->write_request("textDocument/references", "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}, \"context\": {\"includeDeclaration\": true}", [&usages, &end_offsets, &result_processed](const boost::property_tree::ptree &result, bool error) { + client->write_request(this, "textDocument/references", "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}, \"context\": {\"includeDeclaration\": true}", [&usages, &end_offsets, &result_processed](const boost::property_tree::ptree &result, bool error) { if(!error) { try { for(auto it=result.begin();it!=result.end();++it) { @@ -628,7 +655,7 @@ void Source::LanguageProtocolView::setup_navigation_and_refactoring() { auto iter=get_buffer()->get_insert()->get_iter(); std::vector usages; std::promise result_processed; - client->write_request("textDocument/rename", "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}, \"newName\": \""+text+"\"", [this, &usages, &result_processed](const boost::property_tree::ptree &result, bool error) { + client->write_request(this, "textDocument/rename", "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}, \"newName\": \""+text+"\"", [this, &usages, &result_processed](const boost::property_tree::ptree &result, bool error) { if(!error) { boost::filesystem::path project_path; auto build=Project::Build::create(file_path); @@ -925,7 +952,11 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect return; auto offset=iter.get_offset(); - client->write_request("textDocument/hover", "\"textDocument\": {\"uri\":\"file://"+file_path.string()+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}", [this, offset](const boost::property_tree::ptree &result, bool error) { + + static int request_count=0; + request_count++; + auto current_request=request_count; + client->write_request(this, "textDocument/hover", "\"textDocument\": {\"uri\":\"file://"+file_path.string()+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}", [this, offset, current_request](const boost::property_tree::ptree &result, bool error) { if(!error) { // hover result structure vary significantly from the different language servers std::string content; @@ -949,7 +980,9 @@ void Source::LanguageProtocolView::show_type_tooltips(const Gdk::Rectangle &rect } } if(!content.empty()) { - dispatcher.post([this, offset, content=std::move(content)] { + dispatcher.post([this, offset, content=std::move(content), current_request] { + if(current_request!=request_count) + return; if(offset>=get_buffer()->get_char_count()) return; type_tooltips.clear(); @@ -1011,15 +1044,18 @@ void Source::LanguageProtocolView::tag_similar_symbols() { return; auto iter=get_buffer()->get_insert()->get_iter(); - std::vector> offsets; - std::promise result_processed; std::string method; if(capabilities.document_highlight) method="textDocument/documentHighlight"; else method="textDocument/references"; - client->write_request(method, "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}, \"context\": {\"includeDeclaration\": true}", [this, &result_processed, &offsets](const boost::property_tree::ptree &result, bool error) { + + static int request_count=0; + request_count++; + auto current_request=request_count; + client->write_request(this, method, "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}, \"context\": {\"includeDeclaration\": true}", [this, current_request](const boost::property_tree::ptree &result, bool error) { if(!error) { + std::vector> offsets; for(auto it=result.begin();it!=result.end();++it) { if(capabilities.document_highlight || it->second.get("uri", "")==uri) { auto range_it=it->second.find("range"); @@ -1036,23 +1072,24 @@ void Source::LanguageProtocolView::tag_similar_symbols() { } } } + dispatcher.post([this, offsets=std::move(offsets), current_request] { + if(current_request!=request_count) + return; + get_buffer()->remove_tag(similar_symbol_tag, get_buffer()->begin(), get_buffer()->end()); + for(auto &pair: offsets) { + auto start=get_iter_at_line_pos(pair.first.line, pair.first.index); + auto end=get_iter_at_line_pos(pair.second.line, pair.second.index); + get_buffer()->apply_tag(similar_symbol_tag, start, end); + } + }); } - result_processed.set_value(); }); - result_processed.get_future().get(); - - get_buffer()->remove_tag(similar_symbol_tag, get_buffer()->begin(), get_buffer()->end()); - for(auto &pair: offsets) { - auto start=get_iter_at_line_pos(pair.first.line, pair.first.index); - auto end=get_iter_at_line_pos(pair.second.line, pair.second.index); - get_buffer()->apply_tag(similar_symbol_tag, start, end); - } } Source::Offset Source::LanguageProtocolView::get_declaration(const Gtk::TextIter &iter) { auto offset=std::make_shared(); std::promise result_processed; - client->write_request("textDocument/definition", "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}", [offset, &result_processed](const boost::property_tree::ptree &result, bool error) { + client->write_request(this, "textDocument/definition", "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(iter.get_line())+", \"character\": "+std::to_string(iter.get_line_offset())+"}", [offset, &result_processed](const boost::property_tree::ptree &result, bool error) { if(!error) { for(auto it=result.begin();it!=result.end();++it) { auto uri=it->second.get("uri", ""); @@ -1110,7 +1147,7 @@ void Source::LanguageProtocolView::setup_autocomplete() { return false; std::string line=" "+get_line_before(); - const static std::regex dot_or_arrow("^.*[a-zA-Z0-9_\\)\\]\\>](\\.)([a-zA-Z0-9_]*)$"); + const static std::regex dot_or_arrow("^.*[a-zA-Z0-9_\\)\\]\\>\"'](\\.)([a-zA-Z0-9_]*)$"); const static std::regex colon_colon("^.*::([a-zA-Z0-9_]*)$"); const static std::regex part_of_symbol("^.*[^a-zA-Z0-9_]+([a-zA-Z0-9_]{3,})$"); std::smatch sm; @@ -1174,7 +1211,7 @@ void Source::LanguageProtocolView::setup_autocomplete() { autocomplete_comment.clear(); autocomplete_insert.clear(); std::promise result_processed; - client->write_request("textDocument/completion", "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(line_number-1)+", \"character\": "+std::to_string(column-1)+"}", [this, &result_processed](const boost::property_tree::ptree &result, bool error) { + client->write_request(this, "textDocument/completion", "\"textDocument\":{\"uri\":\""+uri+"\"}, \"position\": {\"line\": "+std::to_string(line_number-1)+", \"character\": "+std::to_string(column-1)+"}", [this, &result_processed](const boost::property_tree::ptree &result, bool error) { if(!error) { auto begin=result.begin(); // rust language server is bugged auto end=result.end(); diff --git a/src/source_language_protocol.h b/src/source_language_protocol.h index 3340cc6..f3389d2 100644 --- a/src/source_language_protocol.h +++ b/src/source_language_protocol.h @@ -48,6 +48,8 @@ namespace LanguageProtocol { std::unordered_set views; std::mutex views_mutex; + + std::mutex initialize_mutex; std::unique_ptr process; std::mutex read_write_mutex; @@ -59,7 +61,7 @@ namespace LanguageProtocol { size_t message_id = 1; - std::unordered_map> handlers; + std::unordered_map>> handlers; std::vector timeout_threads; std::mutex timeout_threads_mutex; @@ -73,7 +75,7 @@ namespace LanguageProtocol { void close(Source::LanguageProtocolView *view); void parse_server_message(); - void write_request(const std::string &method, const std::string ¶ms, std::function &&function = nullptr); + 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); }; @@ -102,6 +104,7 @@ namespace Source { size_t document_version = 1; + std::thread initialize_thread; Dispatcher dispatcher; void setup_navigation_and_refactoring(); diff --git a/src/window.cc b/src/window.cc index 21e6ea8..0848498 100644 --- a/src/window.cc +++ b/src/window.cc @@ -17,7 +17,7 @@ Window::Window() { set_menu_actions(); configure(); - activate_menu_items(); + Menu::get().toggle_menu_items(); Menu::get().right_click_line_menu->attach_to_widget(*this); Menu::get().right_click_selected_menu->attach_to_widget(*this); @@ -35,7 +35,7 @@ Window::Window() { view->search_highlight(last_search, case_sensitive_search, regex_search); } - activate_menu_items(); + Menu::get().toggle_menu_items(); Directories::get().select(view->file_path); @@ -51,7 +51,7 @@ Window::Window() { Project::debug_update_stop(); #endif }; - Notebook::get().on_close_page=[this](Source::View *view) { + Notebook::get().on_close_page=[](Source::View *view) { #ifdef JUCI_ENABLE_DEBUG if(Project::current && Project::debugging) { auto iter=view->get_buffer()->begin(); @@ -69,7 +69,7 @@ Window::Window() { else { Notebook::get().clear_status(); - activate_menu_items(); + Menu::get().toggle_menu_items(); } }; @@ -1166,39 +1166,39 @@ void Window::set_menu_actions() { menu.add_action("window_clear_terminal", [] { Terminal::get().clear(); }); -} - -void Window::activate_menu_items() { - auto &menu = Menu::get(); - auto view=Notebook::get().get_current_view(); - - menu.actions["file_reload_file"]->set_enabled(view); - menu.actions["source_spellcheck"]->set_enabled(view); - menu.actions["source_spellcheck_clear"]->set_enabled(view); - menu.actions["source_spellcheck_next_error"]->set_enabled(view); - menu.actions["source_git_next_diff"]->set_enabled(view); - menu.actions["source_git_show_diff"]->set_enabled(view); - menu.actions["source_indentation_set_buffer_tab"]->set_enabled(view); - menu.actions["source_goto_line"]->set_enabled(view); - menu.actions["source_center_cursor"]->set_enabled(view); - menu.actions["source_indentation_auto_indent_buffer"]->set_enabled(view && view->format_style); - menu.actions["source_comments_toggle"]->set_enabled(view && view->toggle_comments); - menu.actions["source_comments_add_documentation"]->set_enabled(view && view->get_documentation_template); - menu.actions["source_find_documentation"]->set_enabled(view && view->get_token_data); - menu.actions["source_goto_declaration"]->set_enabled(view && view->get_declaration_location); - menu.actions["source_goto_type_declaration"]->set_enabled(view && view->get_type_declaration_location); - menu.actions["source_goto_implementation"]->set_enabled(view && view->get_implementation_locations); - menu.actions["source_goto_declaration_or_implementation"]->set_enabled(view && view->get_declaration_or_implementation_locations); - menu.actions["source_goto_usage"]->set_enabled(view && view->get_usages); - menu.actions["source_goto_method"]->set_enabled(view && view->get_methods); - menu.actions["source_rename"]->set_enabled(view && view->rename_similar_tokens); - menu.actions["source_implement_method"]->set_enabled(view && view->get_method); - menu.actions["source_goto_next_diagnostic"]->set_enabled(view && view->goto_next_diagnostic); - menu.actions["source_apply_fix_its"]->set_enabled(view && view->get_fix_its); + menu.toggle_menu_items=[] { + auto &menu = Menu::get(); + auto view=Notebook::get().get_current_view(); + + menu.actions["file_reload_file"]->set_enabled(view); + menu.actions["source_spellcheck"]->set_enabled(view); + menu.actions["source_spellcheck_clear"]->set_enabled(view); + menu.actions["source_spellcheck_next_error"]->set_enabled(view); + menu.actions["source_git_next_diff"]->set_enabled(view); + menu.actions["source_git_show_diff"]->set_enabled(view); + menu.actions["source_indentation_set_buffer_tab"]->set_enabled(view); + menu.actions["source_goto_line"]->set_enabled(view); + menu.actions["source_center_cursor"]->set_enabled(view); + + menu.actions["source_indentation_auto_indent_buffer"]->set_enabled(view && view->format_style); + menu.actions["source_comments_toggle"]->set_enabled(view && view->toggle_comments); + menu.actions["source_comments_add_documentation"]->set_enabled(view && view->get_documentation_template); + menu.actions["source_find_documentation"]->set_enabled(view && view->get_token_data); + menu.actions["source_goto_declaration"]->set_enabled(view && view->get_declaration_location); + menu.actions["source_goto_type_declaration"]->set_enabled(view && view->get_type_declaration_location); + menu.actions["source_goto_implementation"]->set_enabled(view && view->get_implementation_locations); + menu.actions["source_goto_declaration_or_implementation"]->set_enabled(view && view->get_declaration_or_implementation_locations); + menu.actions["source_goto_usage"]->set_enabled(view && view->get_usages); + menu.actions["source_goto_method"]->set_enabled(view && view->get_methods); + menu.actions["source_rename"]->set_enabled(view && view->rename_similar_tokens); + menu.actions["source_implement_method"]->set_enabled(view && view->get_method); + menu.actions["source_goto_next_diagnostic"]->set_enabled(view && view->goto_next_diagnostic); + menu.actions["source_apply_fix_its"]->set_enabled(view && view->get_fix_its); #ifdef JUCI_ENABLE_DEBUG - Project::debug_activate_menu_items(); + Project::debug_activate_menu_items(); #endif + }; } void Window::add_widgets() { diff --git a/src/window.h b/src/window.h index 97be899..24ff4c2 100644 --- a/src/window.h +++ b/src/window.h @@ -25,7 +25,6 @@ private: void configure(); void set_menu_actions(); - void activate_menu_items(); void search_and_replace_entry(); void set_tab_entry(); void goto_line_entry();