Skip to content

Commit 202cf94

Browse files
author
kef
committed
Added navigation/completion/rename support for Nix paths and path-like strings.
1 parent 41cd249 commit 202cf94

File tree

7 files changed

+129
-0
lines changed

7 files changed

+129
-0
lines changed

CHANGELOG.md

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,13 @@
22

33
## [Unreleased]
44
### Added
5+
- Navigation (Ctrl-B/Cmd-B) for Nix paths and path-like strings.
6+
- Directories containing a `default.nix` file offer that file as an optional destination.
7+
- Find usages for files and directories in project view referenced by Nix paths.
8+
- Completion of files and subdirectories for Nix paths.
59

10+
## [0.4.0.4]
11+
### Added
612
- Support for IDEA 2022.2 EAP
713

814
### Removed
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.nixos.idea.psi.impl;
2+
3+
import com.intellij.lang.ASTNode;
4+
import com.intellij.psi.PsiReference;
5+
import org.jetbrains.annotations.NotNull;
6+
import org.nixos.idea.reference.ReferenceUtil;
7+
8+
public class NixLiteralReferencingElementImpl extends NixExprSimpleImpl {
9+
public NixLiteralReferencingElementImpl(@NotNull ASTNode node) {
10+
super(node);
11+
}
12+
13+
@Override
14+
public PsiReference @NotNull [] getReferences() {
15+
return ReferenceUtil.getReferences(this);
16+
}
17+
18+
@Override
19+
public PsiReference getReference() {
20+
return ReferenceUtil.getReference(this);
21+
}
22+
}
Lines changed: 22 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
package org.nixos.idea.psi.impl;
2+
3+
import com.intellij.lang.ASTNode;
4+
import com.intellij.psi.PsiReference;
5+
import org.jetbrains.annotations.NotNull;
6+
import org.nixos.idea.reference.ReferenceUtil;
7+
8+
public class NixStringReferencingElementImpl extends NixStringPartImpl {
9+
public NixStringReferencingElementImpl(@NotNull ASTNode node) {
10+
super(node);
11+
}
12+
13+
@Override
14+
public PsiReference @NotNull [] getReferences() {
15+
return ReferenceUtil.getReferences(this);
16+
}
17+
18+
@Override
19+
public PsiReference getReference() {
20+
return ReferenceUtil.getReference(this);
21+
}
22+
}
Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
package org.nixos.idea.reference;
2+
3+
import com.intellij.psi.*;
4+
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
5+
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
6+
import com.intellij.util.ProcessingContext;
7+
import org.jetbrains.annotations.NotNull;
8+
import org.nixos.idea.psi.NixLiteral;
9+
import org.nixos.idea.psi.NixStringText;
10+
11+
import java.util.Arrays;
12+
13+
import static com.intellij.patterns.PlatformPatterns.psiElement;
14+
import static com.intellij.patterns.StandardPatterns.or;
15+
import static com.intellij.patterns.StandardPatterns.string;
16+
17+
public class NixReferenceContributor extends PsiReferenceContributor {
18+
19+
// Same as the pattern in Nix.flex.
20+
private static final String NIX_PATH_REGEX = "[a-zA-Z0-9._+-]*(\\/[a-zA-Z0-9._+-]+)+\\/?";
21+
22+
@Override
23+
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferenceRegistrar) {
24+
psiReferenceRegistrar.registerReferenceProvider(
25+
or(
26+
psiElement(NixLiteral.class),
27+
psiElement(NixStringText.class)
28+
.withText(string().matches(NIX_PATH_REGEX))
29+
),
30+
new NixReferenceProvider()
31+
);
32+
}
33+
34+
private static class NixReferenceProvider extends PsiReferenceProvider {
35+
36+
@Override
37+
public boolean acceptsTarget(@NotNull PsiElement target) {
38+
return target instanceof PsiFileSystemItem;
39+
}
40+
41+
@Override
42+
public PsiReference @NotNull [] getReferencesByElement(@NotNull PsiElement psiElement,
43+
@NotNull ProcessingContext processingContext) {
44+
FileReferenceSet fileReferenceSet = new FileReferenceSet(psiElement);
45+
FileReference[] references = fileReferenceSet.getAllReferences();
46+
FileReference lastReference = fileReferenceSet.getLastReference();
47+
FileReference defaultNixReference = fileReferenceSet.createFileReference(lastReference.getRangeInElement(), lastReference.getIndex() + 1, "default.nix");
48+
PsiReference[] allReferences = Arrays.copyOf(references, references.length + 1);
49+
allReferences[allReferences.length - 1] = defaultNixReference;
50+
return allReferences;
51+
}
52+
}
53+
}
Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,18 @@
1+
package org.nixos.idea.reference;
2+
3+
import com.intellij.psi.PsiElement;
4+
import com.intellij.psi.PsiReference;
5+
import com.intellij.psi.PsiReferenceService;
6+
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
7+
import com.intellij.util.ArrayUtil;
8+
import org.jetbrains.annotations.NotNull;
9+
10+
public class ReferenceUtil {
11+
public static PsiReference @NotNull [] getReferences(@NotNull PsiElement element) {
12+
return ReferenceProvidersRegistry.getReferencesFromProviders(element, PsiReferenceService.Hints.NO_HINTS);
13+
}
14+
15+
public static PsiReference getReference(@NotNull PsiElement element) {
16+
return ArrayUtil.getFirstElement(getReferences(element));
17+
}
18+
}

src/main/lang/Nix.bnf

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ expr_simple ::=
169169
| legacy_let
170170
identifier ::= ID
171171
literal ::= INT | FLOAT | PATH | HPATH | SPATH | URI
172+
{
173+
mixin="org.nixos.idea.psi.impl.NixLiteralReferencingElementImpl"
174+
}
172175
parens ::= LPAREN expr recover_parens RPAREN { pin=1 }
173176
set ::= [ REC ] LCURLY recover_set (bind recover_set)* RCURLY { pin=2 }
174177
list ::= LBRAC recover_list (expr_select recover_list)* RBRAC { pin=1 }
@@ -186,6 +189,9 @@ ind_string ::= IND_STRING_OPEN string_part* IND_STRING_CLOSE { pin=1 }
186189
;{ extends("string_text|antiquotation")=string_part }
187190
string_part ::= string_text | antiquotation { recoverWhile=string_part_recover }
188191
string_text ::= STR | IND_STR
192+
{
193+
mixin="org.nixos.idea.psi.impl.NixStringReferencingElementImpl"
194+
}
189195
antiquotation ::= DOLLAR LCURLY expr recover_antiquotation RCURLY { pin=1 }
190196
private recover_antiquotation ::= { recoverWhile=curly_recover }
191197
private string_part_recover ::= !(STR | IND_STR | DOLLAR | STRING_CLOSE | IND_STRING_CLOSE)

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

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -37,6 +37,8 @@
3737
id="org.nixos.idea.settings.NixIDEASettings"
3838
instance="org.nixos.idea.settings.NixIDEASettings" />
3939

40+
<psi.referenceContributor language="Nix" implementation="org.nixos.idea.reference.NixReferenceContributor"/>
41+
4042
</extensions>
4143

4244
</idea-plugin>

0 commit comments

Comments
 (0)