diff --git a/README.md b/README.md index be83b23..75fe05c 100644 --- a/README.md +++ b/README.md @@ -20,7 +20,7 @@ towards libclang with speed and ease of use in mind. * Rename refactoring across files (C++) * Highlighting of similar types (C++) * Automated documentation search (C++) -* Go to methods and usages (C++) +* Go to declaration, implementation, methods and usages (C++) * Spell checking depending on file context * Run shell commands within JuCi++ * Regex search and replace diff --git a/docs/api.md b/docs/api.md index 60230c0..329e970 100644 --- a/docs/api.md +++ b/docs/api.md @@ -16,4 +16,4 @@ make doc ``` ## Where is the generated API documentation -Open jupicpp/build/src/html/index.html +Open jucipp/build/src/html/index.html diff --git a/src/files.h b/src/files.h index 858be1a..da3e171 100644 --- a/src/files.h +++ b/src/files.h @@ -2,7 +2,7 @@ #define JUCI_FILES_H_ #include -#define JUCI_VERSION "1.1.3" +#define JUCI_VERSION "1.1.3-1" const std::string configjson = "{\n" @@ -92,6 +92,7 @@ const std::string configjson = " \"source_center_cursor\": \"l\",\n" " \"source_find_documentation\": \"d\",\n" " \"source_goto_declaration\": \"d\",\n" +" \"source_goto_implementation\": \"i\",\n" " \"source_goto_usage\": \"u\",\n" " \"source_goto_method\": \"m\",\n" " \"source_rename\": \"r\",\n" diff --git a/src/menu.cc b/src/menu.cc index a8f75b3..f0665b9 100644 --- a/src/menu.cc +++ b/src/menu.cc @@ -213,6 +213,11 @@ Menu::Menu() { +accels["source_goto_declaration"]+ //For Ubuntu... " " " " + " _Go to Implementation" + " app.source_goto_implementation" + +accels["source_goto_implementation"]+ //For Ubuntu... + " " + " " " _Go to Usage" " app.source_goto_usage" +accels["source_goto_usage"]+ //For Ubuntu... diff --git a/src/source.h b/src/source.h index f9af6a3..33a3c2d 100644 --- a/src/source.h +++ b/src/source.h @@ -78,6 +78,7 @@ namespace Source { std::function auto_indent; std::function get_declaration_location; + std::function get_implementation_location; std::function >(const Token &token)> get_usages; std::function goto_method; std::function get_token; diff --git a/src/source_clang.cc b/src/source_clang.cc index 8e0a9e2..849a2f1 100644 --- a/src/source_clang.cc +++ b/src/source_clang.cc @@ -939,6 +939,30 @@ Source::ClangViewAutocomplete(file_path, language) { return location; }; + get_implementation_location=[this](const Token &token){ + Offset location; + if(parsed && this->language && this->language->get_id()!="chdr" && this->language->get_id()!="cpphdr") { + for(auto token_it=clang_tokens->rbegin();token_it!=clang_tokens->rend();++token_it) { + auto cursor=token_it->get_cursor(); + auto kind=cursor.get_kind(); + if((kind==clang::CursorKind::FunctionDecl || kind==clang::CursorKind::CXXMethod || + kind==clang::CursorKind::Constructor || kind==clang::CursorKind::Destructor) && + token_it->get_kind()==clang::Token_Identifier && cursor.has_type()) { + auto referenced=cursor.get_referenced(); + if(referenced && static_cast(token.type)==referenced.get_kind() && + token.spelling==token_it->get_spelling() && token.usr==referenced.get_usr()) { + location.file_path=cursor.get_source_location().get_path(); + auto clang_offset=cursor.get_source_location().get_offset(); + location.line=clang_offset.line; + location.index=clang_offset.index; + break; + } + } + } + } + return location; + }; + get_usages=[this](const Token &token) { std::vector > usages; diff --git a/src/window.cc b/src/window.cc index f793fce..1fb249e 100644 --- a/src/window.cc +++ b/src/window.cc @@ -426,7 +426,7 @@ void Window::set_menu_actions() { boost::system::error_code ec; declaration_file=boost::filesystem::canonical(location.file_path, ec); if(ec) - declaration_file=location.file_path; + return; notebook.open(declaration_file); auto line=static_cast(location.line)-1; auto index=static_cast(location.index)-1; @@ -446,6 +446,45 @@ void Window::set_menu_actions() { } } }); + menu.add_action("source_goto_implementation", [this]() { + if(notebook.get_current_page()!=-1) { + auto current_view=notebook.get_current_view(); + if(current_view->get_token) { + auto token=current_view->get_token(); + if(token) { + for(int page=0;pageget_implementation_location) { + auto location=view->get_implementation_location(token); + if(!location.file_path.empty()) { + boost::filesystem::path implementation_path; + boost::system::error_code ec; + implementation_path=boost::filesystem::canonical(location.file_path, ec); + if(ec) + return; + notebook.open(implementation_path); + auto line=static_cast(location.line)-1; + auto index=static_cast(location.index)-1; + auto view=notebook.get_current_view(); + line=std::min(line, view->get_buffer()->get_line_count()-1); + if(line>=0) { + auto iter=view->get_buffer()->get_iter_at_line(line); + while(!iter.ends_line()) + iter.forward_char(); + auto end_line_index=iter.get_line_index(); + index=std::min(index, end_line_index); + + view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(line, index)); + view->scroll_to_cursor_delayed(view, true, false); + } + return; + } + } + } + } + } + } + }); menu.add_action("source_goto_usage", [this]() { if(notebook.get_current_page()!=-1) { auto current_view=notebook.get_current_view(); @@ -488,7 +527,7 @@ void Window::set_menu_actions() { boost::system::error_code ec; declaration_file=boost::filesystem::canonical(offset.file_path, ec); if(ec) - declaration_file=offset.file_path; + return; notebook.open(declaration_file); auto view=notebook.get_current_view(); view->get_buffer()->place_cursor(view->get_buffer()->get_iter_at_line_index(offset.line, offset.index)); @@ -776,6 +815,7 @@ void Window::activate_menu_items(bool activate) { menu.actions["source_indentation_auto_indent_buffer"]->set_enabled(activate ? static_cast(notebook.get_current_view()->auto_indent) : false); menu.actions["source_find_documentation"]->set_enabled(activate ? static_cast(notebook.get_current_view()->get_token_data) : false); menu.actions["source_goto_declaration"]->set_enabled(activate ? static_cast(notebook.get_current_view()->get_declaration_location) : false); + menu.actions["source_goto_implementation"]->set_enabled(activate ? static_cast(notebook.get_current_view()->get_implementation_location) : false); menu.actions["source_goto_usage"]->set_enabled(activate ? static_cast(notebook.get_current_view()->get_usages) : false); menu.actions["source_goto_method"]->set_enabled(activate ? static_cast(notebook.get_current_view()->goto_method) : false); menu.actions["source_rename"]->set_enabled(activate ? static_cast(notebook.get_current_view()->rename_similar_tokens) : false);