add translation key referencing inside editor
This commit is contained in:
parent
45cae6e7ae
commit
562266f9c0
@ -5,6 +5,7 @@
|
|||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
### Added
|
### Added
|
||||||
- Support for YAML locale files. Thanks to @sunarya-thito
|
- Support for YAML locale files. Thanks to @sunarya-thito
|
||||||
|
- Translation key referencing inside editor
|
||||||
- Optional path-prefix for translations
|
- Optional path-prefix for translations
|
||||||
|
|
||||||
### Changed
|
### Changed
|
||||||
|
85
src/main/java/de/marhali/easyi18n/editor/KeyReference.java
Normal file
85
src/main/java/de/marhali/easyi18n/editor/KeyReference.java
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package de.marhali.easyi18n.editor;
|
||||||
|
|
||||||
|
import com.intellij.openapi.util.TextRange;
|
||||||
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.psi.impl.FakePsiElement;
|
||||||
|
|
||||||
|
import de.marhali.easyi18n.dialog.AddDialog;
|
||||||
|
import de.marhali.easyi18n.dialog.EditDialog;
|
||||||
|
import de.marhali.easyi18n.model.KeyedTranslation;
|
||||||
|
import de.marhali.easyi18n.model.LocalizedNode;
|
||||||
|
import de.marhali.easyi18n.service.DataStore;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.annotations.Nullable;
|
||||||
|
|
||||||
|
public class KeyReference extends PsiReferenceBase<PsiElement> {
|
||||||
|
|
||||||
|
@Nullable private final String myKey;
|
||||||
|
|
||||||
|
public KeyReference(@NotNull final PsiElement element) {
|
||||||
|
this(element, (String)null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyReference(@NotNull final PsiElement element, @Nullable final String myKey) {
|
||||||
|
super(element, true);
|
||||||
|
this.myKey = myKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyReference(@NotNull final PsiElement element, @NotNull TextRange textRange) {
|
||||||
|
this(element, textRange, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public KeyReference(@NotNull PsiElement element, TextRange textRange, @Nullable String myKey) {
|
||||||
|
super(element, textRange, true);
|
||||||
|
this.myKey = myKey;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable PsiElement resolve() {
|
||||||
|
return new TranslationKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
public String getKey() {
|
||||||
|
return myKey != null ? myKey : getValue();
|
||||||
|
}
|
||||||
|
|
||||||
|
class TranslationKey extends FakePsiElement implements SyntheticElement {
|
||||||
|
@Override
|
||||||
|
public PsiElement getParent() {
|
||||||
|
return myElement;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void navigate(boolean requestFocus) {
|
||||||
|
LocalizedNode node = DataStore.getInstance(getProject()).getTranslations().getNode(getKey());
|
||||||
|
|
||||||
|
if(node != null) {
|
||||||
|
new EditDialog(getProject(), new KeyedTranslation(getKey(), node.getValue())).showAndHandle();
|
||||||
|
} else {
|
||||||
|
new AddDialog(getProject(), getKey()).showAndHandle();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getPresentableText() {
|
||||||
|
return getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public String getName() {
|
||||||
|
return getKey();
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public @Nullable TextRange getTextRange() {
|
||||||
|
final TextRange rangeInElement = getRangeInElement();
|
||||||
|
final TextRange elementRange = myElement.getTextRange();
|
||||||
|
return elementRange != null ? rangeInElement.shiftRight(elementRange.getStartOffset()) : rangeInElement;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static boolean isReferencable(String value) {
|
||||||
|
return value.matches("^[^\\s:/]+$");
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,51 @@
|
|||||||
|
package de.marhali.easyi18n.editor.generic;
|
||||||
|
|
||||||
|
import com.intellij.patterns.PlatformPatterns;
|
||||||
|
import com.intellij.psi.*;
|
||||||
|
import com.intellij.util.ProcessingContext;
|
||||||
|
|
||||||
|
import de.marhali.easyi18n.editor.KeyReference;
|
||||||
|
import de.marhali.easyi18n.service.DataStore;
|
||||||
|
import de.marhali.easyi18n.service.SettingsService;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Generic translation key reference contributor.
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public class GenericKeyReferenceContributor extends PsiReferenceContributor {
|
||||||
|
@Override
|
||||||
|
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
|
||||||
|
registrar.registerReferenceProvider(PlatformPatterns.psiElement(PsiLiteralValue.class), getProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
private PsiReferenceProvider getProvider() {
|
||||||
|
return new PsiReferenceProvider() {
|
||||||
|
@Override
|
||||||
|
public PsiReference @NotNull [] getReferencesByElement(
|
||||||
|
@NotNull PsiElement element, @NotNull ProcessingContext context) {
|
||||||
|
|
||||||
|
PsiLiteralValue literalValue = (PsiLiteralValue) element;
|
||||||
|
String value = literalValue.getValue() instanceof String ? (String) literalValue.getValue() : null;
|
||||||
|
|
||||||
|
if(value == null) {
|
||||||
|
return PsiReference.EMPTY_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not reference keys if service is disabled
|
||||||
|
if(!SettingsService.getInstance(element.getProject()).getState().isCodeAssistance()) {
|
||||||
|
return PsiReference.EMPTY_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(DataStore.getInstance(element.getProject()).getTranslations().getNode(value) == null) {
|
||||||
|
if(!KeyReference.isReferencable(value)) { // Creation policy
|
||||||
|
return PsiReference.EMPTY_ARRAY;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PsiReference[] { new KeyReference(element, value) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,56 @@
|
|||||||
|
package de.marhali.easyi18n.editor.kotlin;
|
||||||
|
|
||||||
|
import com.intellij.patterns.PlatformPatterns;
|
||||||
|
import com.intellij.psi.*;
|
||||||
|
|
||||||
|
import com.intellij.util.ProcessingContext;
|
||||||
|
|
||||||
|
import de.marhali.easyi18n.editor.KeyReference;
|
||||||
|
import de.marhali.easyi18n.service.DataStore;
|
||||||
|
import de.marhali.easyi18n.service.SettingsService;
|
||||||
|
|
||||||
|
import org.jetbrains.annotations.NotNull;
|
||||||
|
import org.jetbrains.kotlin.psi.KtLiteralStringTemplateEntry;
|
||||||
|
import org.jetbrains.kotlin.psi.KtStringTemplateExpression;
|
||||||
|
|
||||||
|
/**
|
||||||
|
* Kotlin translation key reference contributor.
|
||||||
|
* @author marhali
|
||||||
|
*/
|
||||||
|
public class KotlinKeyReferenceContributor extends PsiReferenceContributor {
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void registerReferenceProviders(@NotNull PsiReferenceRegistrar registrar) {
|
||||||
|
registrar.registerReferenceProvider(PlatformPatterns.psiElement().inside(KtStringTemplateExpression.class), getProvider());
|
||||||
|
}
|
||||||
|
|
||||||
|
private PsiReferenceProvider getProvider() {
|
||||||
|
return new PsiReferenceProvider() {
|
||||||
|
@Override
|
||||||
|
public PsiReference @NotNull [] getReferencesByElement(@NotNull PsiElement element, @NotNull ProcessingContext context) {
|
||||||
|
String value = null;
|
||||||
|
|
||||||
|
for (PsiElement child : element.getChildren()) {
|
||||||
|
if(child instanceof KtLiteralStringTemplateEntry) {
|
||||||
|
value = child.getText();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if(value == null) {
|
||||||
|
return PsiReference.EMPTY_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Do not reference keys if service is disabled
|
||||||
|
if(!SettingsService.getInstance(element.getProject()).getState().isCodeAssistance()) {
|
||||||
|
return PsiReference.EMPTY_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
if(DataStore.getInstance(element.getProject()).getTranslations().getNode(value) == null) {
|
||||||
|
return PsiReference.EMPTY_ARRAY;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new PsiReference[] { new KeyReference(element, value) };
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
@ -4,5 +4,8 @@
|
|||||||
|
|
||||||
<completion.contributor language="kotlin"
|
<completion.contributor language="kotlin"
|
||||||
implementationClass="de.marhali.easyi18n.editor.kotlin.KotlinKeyCompletionContributor" />
|
implementationClass="de.marhali.easyi18n.editor.kotlin.KotlinKeyCompletionContributor" />
|
||||||
|
|
||||||
|
<psi.referenceContributor language="kotlin"
|
||||||
|
implementation="de.marhali.easyi18n.editor.kotlin.KotlinKeyReferenceContributor" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -17,5 +17,7 @@
|
|||||||
implementationClass="de.marhali.easyi18n.editor.generic.GenericKeyCompletionContributor" />
|
implementationClass="de.marhali.easyi18n.editor.generic.GenericKeyCompletionContributor" />
|
||||||
|
|
||||||
<annotator language="" implementationClass="de.marhali.easyi18n.editor.generic.GenericKeyAnnotator" />
|
<annotator language="" implementationClass="de.marhali.easyi18n.editor.generic.GenericKeyAnnotator" />
|
||||||
|
|
||||||
|
<psi.referenceContributor implementation="de.marhali.easyi18n.editor.generic.GenericKeyReferenceContributor" />
|
||||||
</extensions>
|
</extensions>
|
||||||
</idea-plugin>
|
</idea-plugin>
|
@ -16,4 +16,4 @@ settings.path.text=Locales directory
|
|||||||
settings.path.file-pattern=Translation file pattern
|
settings.path.file-pattern=Translation file pattern
|
||||||
settings.path.prefix=Path prefix
|
settings.path.prefix=Path prefix
|
||||||
settings.preview=Preview locale
|
settings.preview=Preview locale
|
||||||
settings.editor.assistance=I18n key completion and annotation inside editor
|
settings.editor.assistance=I18n key completion, annotation and reference inside editor
|
Loading…
x
Reference in New Issue
Block a user