Skip to content

Commit af1eb78

Browse files
committed
Fixed GotoRelatedSymbol feature. This probably needs to include usages/definitions in other package files
1 parent d8cbd8d commit af1eb78

2 files changed

Lines changed: 88 additions & 101 deletions

File tree

src/de/halirutan/mathematica/codeinsight/navigation/MathematicaGotoRelatedProvider.java

Lines changed: 0 additions & 101 deletions
This file was deleted.
Lines changed: 88 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,88 @@
1+
/*
2+
* Copyright (c) 2017 Patrick Scheibe
3+
* Permission is hereby granted, free of charge, to any person obtaining a copy
4+
* of this software and associated documentation files (the "Software"), to deal
5+
* in the Software without restriction, including without limitation the rights
6+
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
7+
* copies of the Software, and to permit persons to whom the Software is
8+
* furnished to do so, subject to the following conditions:
9+
*
10+
* The above copyright notice and this permission notice shall be included in
11+
* all copies or substantial portions of the Software.
12+
*
13+
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
14+
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
15+
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
16+
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
17+
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
18+
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
19+
* THE SOFTWARE.
20+
*/
21+
22+
package de.halirutan.mathematica.codeinsight.navigation
23+
24+
import com.intellij.navigation.GotoRelatedItem
25+
import com.intellij.navigation.GotoRelatedProvider
26+
import com.intellij.openapi.util.TextRange
27+
import com.intellij.psi.PsiDocumentManager
28+
import com.intellij.psi.PsiElement
29+
import com.intellij.psi.impl.source.tree.LeafPsiElement
30+
import com.intellij.psi.search.GlobalSearchScope
31+
import com.intellij.psi.search.searches.ReferencesSearch
32+
import com.intellij.util.containers.SortedList
33+
import de.halirutan.mathematica.lang.parsing.MathematicaElementTypes
34+
import de.halirutan.mathematica.lang.psi.api.Symbol
35+
import java.util.*
36+
37+
/**
38+
* Provides functionality to navigate through different usages of the symbol under the caret.
39+
* It will take the correct scope which means that it won't stupidly highlight symbols with the same name.
40+
* Rather, it will find out if the symbol is globally defined, in a Module, or in any other scoping construct.
41+
* Then, the list of suggestions contains only correct places which really refer to usages of the current symbol.
42+
* @author patrick (28.12.16).
43+
*/
44+
class MathematicaGotoRelatedProvider : GotoRelatedProvider() {
45+
46+
override fun getItems(psiElement: PsiElement): List<GotoRelatedItem> {
47+
// I want the entries in the suggestion window to be sorted by line number!
48+
val symbol = when {
49+
psiElement is Symbol -> psiElement
50+
psiElement is LeafPsiElement && psiElement.elementType == MathematicaElementTypes.IDENTIFIER -> psiElement.parent
51+
else -> psiElement
52+
}
53+
val declarations = SortedList(Comparator.comparingInt<GotoSymbolItem>({ it.lineNumber }))
54+
if (symbol is Symbol) {
55+
val project = symbol.getProject()
56+
val documentManager = PsiDocumentManager.getInstance(project)
57+
val containingFile = symbol.getContainingFile()
58+
val fileName = containingFile.name
59+
val document = documentManager.getDocument(containingFile) ?: return declarations
60+
val usages = ReferencesSearch.search(symbol, GlobalSearchScope.fileScope(containingFile)).findAll()
61+
for (usage in usages) {
62+
val usageElement = usage.element
63+
if (usageElement is Symbol && usageElement.isValid) {
64+
// What follows is that want to collect code around the found element.
65+
// I will collect neighbouring PsiElements but not more than 20 characters to the right and
66+
// to the left of the current usageElement.
67+
val elementTextOffset = usageElement.getTextOffset()
68+
val lineNumber = document.getLineNumber(elementTextOffset)
69+
val lineStartOffset = document.getLineStartOffset(lineNumber)
70+
val lineEndOffset = document.getLineEndOffset(lineNumber)
71+
assert(lineStartOffset <= lineEndOffset)
72+
73+
var textToShow = document.getText(TextRange.create(lineStartOffset, lineEndOffset)).trim { it <= ' ' }
74+
textToShow = if (textToShow.length > 80) textToShow.substring(0, 80) else textToShow
75+
76+
val item = GotoSymbolItem(
77+
usageElement,
78+
textToShow,
79+
"(line ${lineNumber + 1} in $fileName)",
80+
lineNumber)
81+
declarations.add(item)
82+
}
83+
}
84+
}
85+
return declarations
86+
}
87+
88+
}

0 commit comments

Comments
 (0)