Skip to content

Commit

Permalink
Added navigation/find usages/completion support for Nix paths and pat…
Browse files Browse the repository at this point in the history
…h-like strings.
  • Loading branch information
kef committed Jun 1, 2022
1 parent 452fe69 commit 9712a74
Show file tree
Hide file tree
Showing 7 changed files with 127 additions and 0 deletions.
4 changes: 4 additions & 0 deletions CHANGELOG.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,6 +2,10 @@

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

### Changed

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.nixos.idea.psi.impl;

import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiReference;
import org.jetbrains.annotations.NotNull;
import org.nixos.idea.reference.ReferenceUtil;

public class NixLiteralReferencingElementImpl extends NixExprSimpleImpl {
public NixLiteralReferencingElementImpl(@NotNull ASTNode node) {
super(node);
}

@Override
public PsiReference @NotNull [] getReferences() {
return ReferenceUtil.getReferences(this);
}

@Override
public PsiReference getReference() {
return ReferenceUtil.getReference(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
package org.nixos.idea.psi.impl;

import com.intellij.lang.ASTNode;
import com.intellij.psi.PsiReference;
import org.jetbrains.annotations.NotNull;
import org.nixos.idea.reference.ReferenceUtil;

public class NixStringReferencingElementImpl extends NixStringPartImpl {
public NixStringReferencingElementImpl(@NotNull ASTNode node) {
super(node);
}

@Override
public PsiReference @NotNull [] getReferences() {
return ReferenceUtil.getReferences(this);
}

@Override
public PsiReference getReference() {
return ReferenceUtil.getReference(this);
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
package org.nixos.idea.reference;

import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReference;
import com.intellij.psi.impl.source.resolve.reference.impl.providers.FileReferenceSet;
import com.intellij.util.ProcessingContext;
import org.jetbrains.annotations.NotNull;
import org.nixos.idea.psi.NixLiteral;
import org.nixos.idea.psi.NixStringText;

import java.util.Arrays;

import static com.intellij.patterns.PlatformPatterns.psiElement;
import static com.intellij.patterns.StandardPatterns.or;
import static com.intellij.patterns.StandardPatterns.string;

public class NixReferenceContributor extends PsiReferenceContributor {

// Same as the pattern in Nix.flex.
private static final String NIX_PATH_REGEX = "[a-zA-Z0-9._+-]*(\\/[a-zA-Z0-9._+-]+)+\\/?";

@Override
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar psiReferenceRegistrar) {
psiReferenceRegistrar.registerReferenceProvider(
or(
psiElement(NixLiteral.class),
psiElement(NixStringText.class)
.withText(string().matches(NIX_PATH_REGEX))
),
new NixReferenceProvider()
);
}

private static class NixReferenceProvider extends PsiReferenceProvider {

@Override
public boolean acceptsTarget(@NotNull PsiElement target) {
return target instanceof PsiFileSystemItem;
}

@Override
public PsiReference @NotNull [] getReferencesByElement(@NotNull PsiElement psiElement,
@NotNull ProcessingContext processingContext) {
FileReferenceSet fileReferenceSet = new FileReferenceSet(psiElement);
FileReference[] references = fileReferenceSet.getAllReferences();
FileReference lastReference = fileReferenceSet.getLastReference();
FileReference defaultNixReference = fileReferenceSet.createFileReference(lastReference.getRangeInElement(), lastReference.getIndex() + 1, "default.nix");
PsiReference[] allReferences = Arrays.copyOf(references, references.length + 1);
allReferences[allReferences.length - 1] = defaultNixReference;
return allReferences;
}
}
}
18 changes: 18 additions & 0 deletions src/main/java/org/nixos/idea/reference/ReferenceUtil.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,18 @@
package org.nixos.idea.reference;

import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiReference;
import com.intellij.psi.PsiReferenceService;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import com.intellij.util.ArrayUtil;
import org.jetbrains.annotations.NotNull;

public class ReferenceUtil {
public static PsiReference @NotNull [] getReferences(@NotNull PsiElement element) {
return ReferenceProvidersRegistry.getReferencesFromProviders(element, PsiReferenceService.Hints.NO_HINTS);
}

public static PsiReference getReference(@NotNull PsiElement element) {
return ArrayUtil.getFirstElement(getReferences(element));
}
}
6 changes: 6 additions & 0 deletions src/main/lang/Nix.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -169,6 +169,9 @@ expr_simple ::=
| legacy_let
identifier ::= ID
literal ::= INT | FLOAT | PATH | HPATH | SPATH | URI
{
mixin="org.nixos.idea.psi.impl.NixLiteralReferencingElementImpl"
}
parens ::= LPAREN expr recover_parens RPAREN { pin=1 }
set ::= [ REC ] LCURLY recover_set (bind recover_set)* RCURLY { pin=2 }
list ::= LBRAC recover_list (expr_select recover_list)* RBRAC { pin=1 }
Expand All @@ -186,6 +189,9 @@ ind_string ::= IND_STRING_OPEN string_part* IND_STRING_CLOSE { pin=1 }
;{ extends("string_text|antiquotation")=string_part }
string_part ::= string_text | antiquotation { recoverWhile=string_part_recover }
string_text ::= STR | IND_STR
{
mixin="org.nixos.idea.psi.impl.NixStringReferencingElementImpl"
}
antiquotation ::= DOLLAR LCURLY expr recover_antiquotation RCURLY { pin=1 }
private recover_antiquotation ::= { recoverWhile=curly_recover }
private string_part_recover ::= !(STR | IND_STR | DOLLAR | STRING_CLOSE | IND_STRING_CLOSE)
Expand Down
2 changes: 2 additions & 0 deletions src/main/resources/META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,8 @@
id="org.nixos.idea.settings.NixIDEASettings"
instance="org.nixos.idea.settings.NixIDEASettings" />

<psi.referenceContributor language="Nix" implementation="org.nixos.idea.reference.NixReferenceContributor"/>

</extensions>

</idea-plugin>

0 comments on commit 9712a74

Please sign in to comment.