Skip to content

Commit f454fc8

Browse files
authored
Merge pull request #90 from 0xcaff/martin/path-references
add support for path references
2 parents 90c4249 + 6968fc1 commit f454fc8

File tree

4 files changed

+80
-1
lines changed

4 files changed

+80
-1
lines changed
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,63 @@
1+
package org.nixos.idea.imports
2+
3+
import com.intellij.codeInsight.lookup.LookupElement
4+
import com.intellij.openapi.util.TextRange
5+
import com.intellij.openapi.util.io.FileUtil
6+
import com.intellij.openapi.vfs.LocalFileSystem
7+
import com.intellij.openapi.vfs.VirtualFile
8+
import com.intellij.openapi.vfs.VirtualFileSystem
9+
import com.intellij.patterns.PlatformPatterns
10+
import com.intellij.psi.PsiElement
11+
import com.intellij.psi.PsiManager
12+
import com.intellij.psi.PsiReference
13+
import com.intellij.psi.PsiReferenceBase
14+
import com.intellij.psi.PsiReferenceContributor
15+
import com.intellij.psi.PsiReferenceProvider
16+
import com.intellij.psi.PsiReferenceRegistrar
17+
import com.intellij.util.ProcessingContext
18+
import org.nixos.idea.psi.impl.NixExprStdPathMixin
19+
20+
class NixFilePathReferenceContributor: PsiReferenceContributor() {
21+
override fun registerReferenceProviders(registrar: PsiReferenceRegistrar) {
22+
registrar.registerReferenceProvider(
23+
PlatformPatterns.psiElement(NixExprStdPathMixin::class.java),
24+
object : PsiReferenceProvider() {
25+
override fun getReferencesByElement(
26+
element: PsiElement,
27+
context: ProcessingContext
28+
): Array<PsiReference> {
29+
val it = element as? NixExprStdPathMixin ?: return emptyArray()
30+
return arrayOf(NixImportReferenceImpl(it))
31+
}
32+
}
33+
)
34+
}
35+
}
36+
37+
private class NixImportReferenceImpl(key: NixExprStdPathMixin) : PsiReferenceBase<NixExprStdPathMixin>(key) {
38+
override fun resolve(): PsiElement? {
39+
val path = element.containingFile.parent?.virtualFile?.path ?: return null
40+
val fs = LocalFileSystem.getInstance()
41+
val file = resolvePath(fs, path, element.text) ?: return null
42+
43+
val project = element.project
44+
val psiFile = PsiManager.getInstance(project).findFile(file)
45+
46+
return psiFile
47+
}
48+
49+
override fun getVariants(): Array<out LookupElement> = LookupElement.EMPTY_ARRAY
50+
51+
override fun calculateDefaultRangeInElement(): TextRange = TextRange.from(0, element.textLength)
52+
}
53+
54+
private fun resolvePath(fs: VirtualFileSystem, cwd: String, target: String): VirtualFile? {
55+
val resolved = FileUtil.join(cwd, target)
56+
val resolvedFile = fs.findFileByPath(resolved) ?: return null
57+
58+
if (resolvedFile.isDirectory) {
59+
return resolvedFile.findChild("default.nix")
60+
}
61+
62+
return resolvedFile
63+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
package org.nixos.idea.psi.impl
2+
3+
import com.intellij.lang.ASTNode
4+
import com.intellij.psi.PsiReference
5+
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry
6+
7+
open class NixExprStdPathMixin(node: ASTNode): NixExprPathImpl(node) {
8+
override fun getReferences(): Array<PsiReference> =
9+
ReferenceProvidersRegistry.getReferencesFromProviders(this)
10+
}

src/main/lang/Nix.bnf

+3-1
Original file line numberDiff line numberDiff line change
@@ -193,7 +193,9 @@ expr_uri ::= URI
193193
;{ extends("expr_lookup_path|expr_std_path")=expr_path }
194194
expr_path ::= expr_lookup_path | expr_std_path
195195
expr_lookup_path ::= SPATH
196-
expr_std_path ::= PATH_SEGMENT (PATH_SEGMENT | antiquotation)* PATH_END
196+
expr_std_path ::= PATH_SEGMENT (PATH_SEGMENT | antiquotation)* PATH_END {
197+
mixin="org.nixos.idea.psi.impl.NixExprStdPathMixin"
198+
}
197199
expr_parens ::= LPAREN expr recover_parens RPAREN { pin=1 }
198200
expr_attrs ::= [ REC | LET ] LCURLY recover_set (bind recover_set)* RCURLY { pin=2 }
199201
expr_list ::= LBRAC recover_list (expr_select recover_list)* RBRAC { pin=1 methods=[ items="expr" ] }

src/main/resources/META-INF/plugin.xml

+4
Original file line numberDiff line numberDiff line change
@@ -50,6 +50,10 @@
5050
<searcher forClass="com.intellij.find.usages.api.UsageSearchParameters"
5151
implementationClass="org.nixos.idea.lang.references.NixUsageSearcher"/>
5252

53+
<psi.referenceContributor
54+
language="Nix"
55+
implementation="org.nixos.idea.imports.NixFilePathReferenceContributor" />
56+
5357
<projectConfigurable
5458
parentId="build"
5559
displayName="NixIDEA Settings"

0 commit comments

Comments
 (0)