Browse Source

Improvement of primary-right click: now goes to declaration if no implementation was found (related to #317)

merge-requests/365/head
eidheim 9 years ago
parent
commit
30e0eace01
  1. 7
      src/source.cc
  2. 2
      src/source.h
  3. 150
      src/source_clang.cc
  4. 18
      src/window.cc

7
src/source.cc

@ -2246,15 +2246,10 @@ bool Source::View::on_button_press_event(GdkEventButton *event) {
if(iter)
get_buffer()->place_cursor(iter);
if(is_implementation_location) {
if(is_implementation_location())
Menu::get().actions["source_goto_declaration"]->activate();
else
Menu::get().actions["source_goto_implementation"]->activate();
Menu::get().actions["source_goto_declaration_or_implementation"]->activate();
return true;
}
}
}
// Open right click menu
if((event->type == GDK_BUTTON_PRESS) && (event->button == 3)){

2
src/source.h

@ -68,8 +68,8 @@ namespace Source {
std::function<void()> non_interactive_completion;
std::function<void()> format_style;
std::function<Offset()> get_declaration_location;
std::function<bool()> is_implementation_location;
std::function<std::vector<Offset>(const std::vector<Source::View*> &views)> get_implementation_locations;
std::function<std::vector<Offset>(const std::vector<Source::View*> &views)> get_declaration_or_implementation_locations;
std::function<std::vector<std::pair<Offset, std::string> >(const std::vector<Source::View*> &views)> get_usages;
std::function<std::string()> get_method;
std::function<std::vector<std::pair<Offset, std::string> >()> get_methods;

150
src/source_clang.cc

@ -1012,7 +1012,14 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
}
});
auto get_header_location=[this]() {
auto declaration_location=[this]() {
auto identifier=get_identifier();
if(identifier) {
auto source_location=identifier.cursor.get_canonical().get_source_location();
auto offset=source_location.get_offset();
return Offset(offset.line-1, offset.index-1, source_location.get_path());
}
else {
// If cursor is at an include line, return offset to included file
const static std::regex include_regex("^[ \t]*#[ \t]*include[ \t]*[<\"]([^<>\"]+)[>\"].*$");
std::smatch sm;
@ -1062,50 +1069,23 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
if(!client_data.found_include.empty())
return Offset(0, 0, client_data.found_include);
}
}
return Offset();
};
get_declaration_location=[this, get_header_location](){
get_declaration_location=[this, declaration_location](){
if(!parsed) {
Info::get().print("Buffer is parsing");
return Offset();
}
auto identifier=get_identifier();
if(identifier) {
auto source_location=identifier.cursor.get_canonical().get_source_location();
auto offset=source_location.get_offset();
return Offset(offset.line-1, offset.index-1, source_location.get_path());
}
else {
auto location=get_header_location();
if(location)
return location;
}
auto offset=declaration_location();
if(!offset)
Info::get().print("No declaration found");
return Offset();
return offset;
};
is_implementation_location=[this]() {
if(!parsed)
return false;
auto iter=get_buffer()->get_insert()->get_iter();
auto line=static_cast<unsigned>(iter.get_line());
auto index=static_cast<unsigned>(iter.get_line_index());
for(auto &token: *clang_tokens) {
if(token.is_identifier()) {
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index <=token.offsets.second.index-1)
return clang_isCursorDefinition(token.get_cursor().cx_cursor)>0;
}
}
return false;
};
get_implementation_locations=[this, get_header_location](const std::vector<Source::View*> &views){
std::vector<Offset> locations;
if(!parsed) {
Info::get().print("Buffer is parsing");
return locations;
}
auto implementation_locations=[this](const std::vector<Source::View*> &views) {
std::vector<Offset> offsets;
auto identifier=get_identifier();
if(identifier) {
wait_parsing(views);
@ -1122,32 +1102,32 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
if(referenced && identifier.kind==referenced.get_kind() &&
identifier.spelling==token.get_spelling() && identifier.usr==referenced.get_usr()) {
if(clang_isCursorDefinition(referenced.cx_cursor)) {
Offset location;
location.file_path=cursor.get_source_location().get_path();
Offset offset;
offset.file_path=cursor.get_source_location().get_path();
auto clang_offset=cursor.get_source_location().get_offset();
location.line=clang_offset.line-1;
location.index=clang_offset.index-1;
locations.emplace_back(location);
offset.line=clang_offset.line-1;
offset.index=clang_offset.index-1;
offsets.emplace_back(offset);
}
}
}
}
}
}
if(!locations.empty())
return locations;
if(!offsets.empty())
return offsets;
//If no implementation was found, try using clang_getCursorDefinition
auto definition=identifier.cursor.get_definition();
if(definition) {
auto definition_location=definition.get_source_location();
Offset location;
location.file_path=definition_location.get_path();
auto offset=definition_location.get_offset();
location.line=offset.line-1;
location.index=offset.index-1;
locations.emplace_back(location);
return locations;
Offset offset;
offset.file_path=definition_location.get_path();
auto definition_offset=definition_location.get_offset();
offset.line=definition_offset.line-1;
offset.index=definition_offset.index-1;
offsets.emplace_back(offset);
return offsets;
}
//If no implementation was found, try using Ctags
@ -1161,24 +1141,72 @@ Source::ClangViewRefactor::ClangViewRefactor(const boost::filesystem::path &file
auto ctags_locations=Ctags::get_locations(this->file_path, name, identifier.cursor.get_type_description());
if(!ctags_locations.empty()) {
for(auto &ctags_location: ctags_locations) {
Offset location;
location.file_path=ctags_location.file_path;
location.line=ctags_location.line;
location.index=ctags_location.index;
locations.emplace_back(location);
Offset offset;
offset.file_path=ctags_location.file_path;
offset.line=ctags_location.line;
offset.index=ctags_location.index;
offsets.emplace_back(offset);
}
return offsets;
}
}
return offsets;
};
get_implementation_locations=[this, implementation_locations](const std::vector<Source::View*> &views){
if(!parsed) {
Info::get().print("Buffer is parsing");
return std::vector<Offset>();
}
auto offsets=implementation_locations(views);
if(offsets.empty())
Info::get().print("No implementation found");
return offsets;
};
get_declaration_or_implementation_locations=[this, declaration_location, implementation_locations](const std::vector<Source::View*> &views) {
if(!parsed) {
Info::get().print("Buffer is parsing");
return std::vector<Offset>();
}
std::vector<Offset> offsets;
bool is_implementation=false;
auto iter=get_buffer()->get_insert()->get_iter();
auto line=static_cast<unsigned>(iter.get_line());
auto index=static_cast<unsigned>(iter.get_line_index());
for(auto &token: *clang_tokens) {
if(token.is_identifier()) {
if(line==token.offsets.first.line-1 && index>=token.offsets.first.index-1 && index<=token.offsets.second.index-1) {
if(clang_isCursorDefinition(token.get_cursor().cx_cursor)>0)
is_implementation=true;
break;
}
}
return locations;
}
// If cursor is at implementation, return declaration_location
if(is_implementation) {
auto offset=declaration_location();
if(offset)
offsets.emplace_back(offset);
}
else {
auto location=get_header_location();
if(location) {
locations.emplace_back(location);
return locations;
auto implementation_offsets=implementation_locations(views);
if(!implementation_offsets.empty()) {
offsets=std::move(implementation_offsets);
}
else {
auto offset=declaration_location();
if(offset)
offsets.emplace_back(offset);
}
Info::get().print("No implementation found");
return locations;
}
if(offsets.empty())
Info::get().print("No declaration or implementation found");
return offsets;
};
get_usages=[this](const std::vector<Source::View*> &views) {

18
src/window.cc

@ -741,10 +741,7 @@ void Window::set_menu_actions() {
}
}
});
menu.add_action("source_goto_implementation", [this]() {
if(auto view=Notebook::get().get_current_view()) {
if(view->get_implementation_locations) {
auto locations=view->get_implementation_locations(Notebook::get().get_views());
auto goto_selected_location=[](Source::View *view, const std::vector<Source::Offset> &locations) {
if(!locations.empty()) {
auto dialog_iter=view->get_iter_for_dialog();
SelectionDialog::create(view, view->get_buffer()->create_mark(dialog_iter), true, true);
@ -779,7 +776,7 @@ void Window::set_menu_actions() {
view->scroll_to_cursor_delayed(view, true, false);
return;
}
SelectionDialog::get()->on_select=[this, rows](const std::string &selected, bool hide_window) {
SelectionDialog::get()->on_select=[rows](const std::string &selected, bool hide_window) {
auto location=rows->at(selected);
if(!boost::filesystem::is_regular_file(location.file_path))
return;
@ -792,7 +789,17 @@ void Window::set_menu_actions() {
view->hide_tooltips();
SelectionDialog::get()->show();
}
};
menu.add_action("source_goto_implementation", [this, goto_selected_location]() {
if(auto view=Notebook::get().get_current_view()) {
if(view->get_implementation_locations)
goto_selected_location(view, view->get_implementation_locations(Notebook::get().get_views()));
}
});
menu.add_action("source_goto_declaration_or_implementation", [this, goto_selected_location]() {
if(auto view=Notebook::get().get_current_view()) {
if(view->get_declaration_or_implementation_locations)
goto_selected_location(view, view->get_declaration_or_implementation_locations(Notebook::get().get_views()));
}
});
@ -1202,6 +1209,7 @@ void Window::activate_menu_items() {
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_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);

Loading…
Cancel
Save