From 0307801336c0599b069a5cda8ac0cb3a3d0c2eee Mon Sep 17 00:00:00 2001 From: eidheim Date: Fri, 9 Oct 2015 16:32:17 +0200 Subject: [PATCH] Ongoing work: Find Documentation. --- src/config.cc | 9 ++++++ src/files.h | 13 ++++++++ src/menu.cc | 2 ++ src/source.cc | 83 +++++++++++++++++++++++++++++++++++++++++++++++++++ src/source.h | 9 ++++++ src/window.cc | 37 ++++++++++++++++++++++- 6 files changed, 152 insertions(+), 1 deletion(-) diff --git a/src/config.cc b/src/config.cc index 13cc842..e16f22f 100644 --- a/src/config.cc +++ b/src/config.cc @@ -134,6 +134,15 @@ void MainConfig::GenerateSource() { for (auto &i : source_json.get_child("clang_types")) source_cfg->clang_types[i.first] = i.second.get_value(); + + auto pt_doc_search=cfg.get_child("documentation_searches"); + for(auto &pt_doc_search_lang: pt_doc_search) { + source_cfg->documentation_searches[pt_doc_search_lang.first].separator=pt_doc_search_lang.second.get("separator"); + auto &queries=source_cfg->documentation_searches.find(pt_doc_search_lang.first)->second.queries; + for(auto &i: pt_doc_search_lang.second.get_child("queries")) { + queries[i.first]=i.second.get_value(); + } + } } void MainConfig::GenerateDirectoryFilter() { diff --git a/src/files.h b/src/files.h index 49d4021..9fcb4d7 100644 --- a/src/files.h +++ b/src/files.h @@ -73,6 +73,7 @@ const std::string configjson = " \"source_goto_declaration\": \"d\",\n" " \"source_goto_method\": \"m\",\n" " \"source_rename\": \"r\",\n" +" \"source_find_documentation\": \"d\",\n" " \"source_goto_next_diagnostic\": \"e\",\n" " \"source_apply_fix_its\": \"space\",\n" " \"compile_and_run\": \"Return\",\n" @@ -92,6 +93,18 @@ const std::string configjson = #endif " \"make_command\": \"make\"\n" " },\n" +" \"documentation_searches\": {\n" +" \"clang\": {\n" +" \"separator\": \"::\",\n" +" \"queries\": {\n" +" \"@empty\": \"https://www.google.com/search?btnI&q=site:http://www.cplusplus.com/reference/+\",\n" +" \"std\": \"https://www.google.com/search?btnI&q=site:http://www.cplusplus.com/reference/+\",\n" +" \"boost\": \"https://www.google.com/search?btnI&q=site:http://www.boost.org/doc/libs/1_59_0/+\",\n" +" \"Gtk\": \"https://www.google.com/search?btnI&q=site:https://developer.gnome.org/gtkmm/stable/+\",\n" +" \"@any\": \"https://www.google.com/search?btnI&q=\"\n" +" }\n" +" }\n" +" },\n" " \"directoryfilter\": {\n" " \"ignore\": [\n" " ],\n" diff --git a/src/menu.cc b/src/menu.cc index f6590a5..8c19df2 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -54,6 +54,8 @@ Menu::Menu() { " \n" " \n" " \n" + " \n" + " \n" " \n" " \n" " \n" diff --git a/src/source.cc b/src/source.cc index 34fe021..d914241 100644 --- a/src/source.cc +++ b/src/source.cc @@ -2345,6 +2345,89 @@ Source::ClangViewAutocomplete(file_path, project_path, language) { } }; + get_token_data=[this]() { + const auto find_non_word_char=[](const std::string &str, size_t start_pos) { + for(size_t c=start_pos;c='a' && str[c]<='z') || + (str[c]>='A' && str[c]<='Z') || + (str[c]>='0' && str[c]<='9') || + str[c]=='_')) + return c; + } + return std::string::npos; + }; + + std::vector data; + if(source_readable) { + auto iter=get_buffer()->get_insert()->get_iter(); + auto line=(unsigned)iter.get_line(); + auto index=(unsigned)iter.get_line_index(); + for(auto &token: *clang_tokens) { + auto cursor=token.get_cursor(); + if(token.get_kind()==clang::Token_Identifier && cursor.has_type()) { + if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1) { + auto referenced=cursor.get_referenced(); + if(referenced) { + auto usr=referenced.get_usr(); + data.emplace_back("clang"); + + //namespace - not working + size_t pos1=usr.find("@N@"); + size_t pos2; + std::string first_namespace; + while(pos1!=std::string::npos) { + pos1+=3; + pos2=find_non_word_char(usr, pos1); + if(pos1!=std::string::npos && pos2!=std::string::npos) { + auto ns=usr.substr(pos1, pos2-pos1); + if(first_namespace.size()==0) + first_namespace=ns; + else if(ns==first_namespace || ns=="std") + break; + data.emplace_back(ns); + pos1=usr.find("@N@", pos2); + } + else + pos1=std::string::npos; + } + + //type + pos1=usr.find("@T@"); + if(pos1==std::string::npos) + pos1=usr.find("@S@"); + if(pos1!=std::string::npos) { + pos1+=3; + pos2=find_non_word_char(usr, pos1); + } + if(pos1!=std::string::npos) { + if(pos2!=std::string::npos) + data.emplace_back(usr.substr(pos1, pos2-pos1)); + else + data.emplace_back(usr.substr(pos1)); + } + + //function + pos1=usr.find("@F@"); + if(pos1!=std::string::npos) { + pos1+=3; + pos2=find_non_word_char(usr, pos1); + } + if(pos1!=std::string::npos) { + if(pos2!=std::string::npos) + data.emplace_back(usr.substr(pos1, pos2-pos1)); + else + data.emplace_back(usr.substr(pos1)); + } + + break; + } + } + } + } + } + return data; + }; + goto_next_diagnostic=[this]() { if(source_readable) { auto insert_offset=get_buffer()->get_insert()->get_iter().get_offset(); diff --git a/src/source.h b/src/source.h index cbaaf45..ad9837a 100644 --- a/src/source.h +++ b/src/source.h @@ -23,6 +23,12 @@ namespace Source { class Config { public: + class DocumentationSearch { + public: + std::string separator; + std::unordered_map queries; + }; + std::string style; std::string font; std::string spellcheck_language; @@ -37,6 +43,8 @@ namespace Source { bool highlight_current_line; bool show_line_numbers; std::unordered_map clang_types; + + std::unordered_map documentation_searches; }; class Token { @@ -104,6 +112,7 @@ namespace Source { std::function()> get_declaration_location; std::function goto_method; std::function get_token; + std::function()> get_token_data; std::function rename_similar_tokens; std::function goto_next_diagnostic; std::function apply_fix_its; diff --git a/src/window.cc b/src/window.cc index 6663fa7..e83986c 100644 --- a/src/window.cc +++ b/src/window.cc @@ -117,7 +117,10 @@ Window::Window() : box(Gtk::ORIENTATION_VERTICAL), notebook(directories), compil menu_item->set_sensitive((bool)notebook.get_current_view()->goto_next_diagnostic); if(auto menu_item=dynamic_cast(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceApplyFixIts"))) - menu_item->set_sensitive((bool)notebook.get_current_view()->apply_fix_its); + menu_item->set_sensitive((bool)notebook.get_current_view()->apply_fix_its); + + if(auto menu_item=dynamic_cast(menu.ui_manager->get_widget("/MenuBar/SourceMenu/SourceFindDocumentation"))) + menu_item->set_sensitive((bool)notebook.get_current_view()->get_token_data); directories.select(notebook.get_current_view()->file_path); @@ -296,6 +299,38 @@ void Window::create_menu() { menu.action_group->add(Gtk::Action::create("SourceRename", "Rename"), Gtk::AccelKey(menu.key_map["source_rename"]), [this]() { rename_token_entry(); }); + menu.action_group->add(Gtk::Action::create("SourceFindDocumentation", "Find Documentation"), Gtk::AccelKey(menu.key_map["source_find_documentation"]), [this]() { + if(notebook.get_current_page()!=-1) { + if(notebook.get_current_view()->get_token_data) { + auto data=notebook.get_current_view()->get_token_data(); + if(data.size()>0) { + auto documentation_search=Singleton::Config::source()->documentation_searches.find(data[0]); + if(documentation_search!=Singleton::Config::source()->documentation_searches.end()) { + std::string token_query; + for(size_t c=1;c0) { + if(token_query.size()>0) + token_query+=documentation_search->second.separator; + token_query+=data[c]; + } + } + if(token_query.size()>0) { + std::unordered_map::iterator query; + if(data[1].size()>0) + query=documentation_search->second.queries.find(data[1]); + else + query=documentation_search->second.queries.find("@empty"); + if(query==documentation_search->second.queries.end()) + query=documentation_search->second.queries.find("@any"); + + if(query!=documentation_search->second.queries.end()) + Singleton::terminal()->execute("open \""+query->second+token_query+"\""); + } + } + } + } + } + }); menu.action_group->add(Gtk::Action::create("SourceGotoNextDiagnostic", "Go to next Diagnostic"), Gtk::AccelKey(menu.key_map["source_goto_next_diagnostic"]), [this]() { if(notebook.get_current_page()!=-1) { if(notebook.get_current_view()->goto_next_diagnostic) {