-
-
Notifications
You must be signed in to change notification settings - Fork 31
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Add navigation/find usages/completion support for Nix paths #45
base: master
Are you sure you want to change the base?
Changes from all commits
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
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; | ||
} | ||
} | ||
} |
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)); | ||
} | ||
} |
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -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 } | ||
|
@@ -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" | ||
} | ||
Comment on lines
191
to
+194
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Can you provide some rationale why you are putting the mixin at There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. Hi I am in good hands I just need some money I am going back in tomorrow and I'm trying my luck and I'm not even trying |
||
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) | ||
|
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
I currently don't quite understand how this is working. How does this code associate which files match against which strings or paths? The sting might also contain escape sequences, shouldn't we have to parse them somewhere?