| 83 | } |
| 84 | |
| 85 | BrowseManager::JumpLocation BrowseManager::determineJumpLoc(KTextEditor::Cursor textCursor, const QUrl& viewUrl) const |
| 86 | { |
| 87 | // Step 1: Look for a special language object(Macro, included header, etc.) |
| 88 | const auto languages = ICore::self()->languageController()->languagesForUrl(viewUrl); |
| 89 | for (const auto& language : languages) { |
| 90 | auto jumpTo = language->specialLanguageObjectJumpCursor(viewUrl, textCursor); |
| 91 | if (jumpTo.first.isValid() && jumpTo.second.isValid()) { |
| 92 | return { |
| 93 | jumpTo.first, jumpTo.second |
| 94 | }; |
| 95 | } |
| 96 | } |
| 97 | |
| 98 | // Step 2: Look for a declaration/use |
| 99 | DUChainReadLocker lock; |
| 100 | // Jump to definition by default, unless a definition itself was selected, |
| 101 | // in which case jump to declaration. |
| 102 | // Also, when the definition is in a file for which we don't know the project, |
| 103 | // that usually means it's a generated file and we rather want to open the declaration |
| 104 | // after all. Unless the viewUrl and textCursor points at the declaration already. |
| 105 | if (auto selectedDeclaration = DUChainUtils::itemUnderCursor(viewUrl, textCursor).declaration) { |
| 106 | auto jumpDestination = selectedDeclaration; |
| 107 | if (selectedDeclaration->isDefinition()) { |
| 108 | // A definition was clicked directly - jump to declaration instead. |
| 109 | if (auto declaration = DUChainUtils::declarationForDefinition(selectedDeclaration)) { |
| 110 | jumpDestination = declaration; |
| 111 | } |
| 112 | } else if (selectedDeclaration == DUChainUtils::declarationForDefinition(selectedDeclaration)) { |
| 113 | // Clicked the declaration - jump to definition |
| 114 | // unless that isn't in a project |
| 115 | if (auto definition = FunctionDefinition::definition(selectedDeclaration)) { |
| 116 | const auto preferDefinition = [&]() -> bool { |
| 117 | // when we are jumping from declaration, we definitely want to go to the definition |
| 118 | if (viewUrl == selectedDeclaration->url().toUrl() |
| 119 | && selectedDeclaration->rangeInCurrentRevision().contains(textCursor)) |
| 120 | { |
| 121 | return true; |
| 122 | } |
| 123 | // otherwise only jump to the definition when we know the project |
| 124 | // for the file in which the definition lives |
| 125 | // this won't be the case for generated files which are usually not interesting |
| 126 | // like e.g. Qt moc files - there, we want to jump to the header first |
| 127 | return ICore::self()->projectController()->findProjectForUrl(definition->url().toUrl()); |
| 128 | }(); |
| 129 | if (preferDefinition) { |
| 130 | jumpDestination = definition; |
| 131 | } |
| 132 | } |
| 133 | } |
| 134 | return { |
| 135 | jumpDestination->url().toUrl(), jumpDestination->rangeInCurrentRevision().start() |
| 136 | }; |
| 137 | } |
| 138 | |
| 139 | return {}; |
| 140 | } |
| 141 | |
| 142 | bool BrowseManager::eventFilter(QObject* watched, QEvent* event) |
nothing calls this directly
no test coverage detected