package org.elixir_lang.annonator;
import com.intellij.lang.annotation.AnnotationHolder;
import com.intellij.lang.annotation.Annotator;
import com.intellij.openapi.editor.colors.EditorColorsManager;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.editor.markup.TextAttributes;
import com.intellij.openapi.project.DumbAware;
import com.intellij.openapi.util.TextRange;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiRecursiveElementVisitor;
import com.intellij.psi.impl.source.tree.LeafPsiElement;
import org.elixir_lang.ElixirSyntaxHighlighter;
import org.elixir_lang.psi.ElixirKeywordKey;
import org.jetbrains.annotations.NotNull;
/**
* Annotates things that act like Atom as Atom
*/
public class Atom implements Annotator, DumbAware {
/*
* Public Instance Methods
*/
/**
* Annotates the specified PSI element.
* It is guaranteed to be executed in non-reentrant fashion.
* I.e there will be no call of this method for this instance before previous call get completed.
* Multiple instances of the annotator might exist simultaneously, though.
*
* @param element to annotate.
* @param holder the container which receives annotations created by the plugin.
*/
@Override
public void annotate(@NotNull final PsiElement element, @NotNull final AnnotationHolder holder) {
element.accept(
new PsiRecursiveElementVisitor() {
/*
* Public Instance Methods
*/
@Override
public void visitElement(PsiElement element) {
if (element instanceof ElixirKeywordKey) {
visitKeywordKey((ElixirKeywordKey) element);
}
}
/*
* Private Instance Methods
*/
private void visitKeywordKey(ElixirKeywordKey keywordKey) {
PsiElement child = keywordKey.getFirstChild();
// a normal, non-quoted keyword key
if (child instanceof LeafPsiElement) {
TextRange keywordKeyTextRange = keywordKey.getTextRange();
// highlight the `:` as part of the pseudo-atom
TextRange atomTextRange = new TextRange(
keywordKeyTextRange.getStartOffset(),
keywordKeyTextRange.getEndOffset() + 1
);
highlight(atomTextRange, holder, ElixirSyntaxHighlighter.ATOM);
}
}
}
);
}
/*
* Private Instance Methods
*/
/**
* Highlights `textRange` with the given `textAttributesKey`.
*
* @param textRange textRange in the document to highlight
* @param annotationHolder the container which receives annotations created by the plugin.
* @param textAttributesKey text attributes to apply to the `node`.
*/
private void highlight(@NotNull final TextRange textRange,
@NotNull AnnotationHolder annotationHolder,
@NotNull final TextAttributesKey textAttributesKey) {
annotationHolder.createInfoAnnotation(textRange, null)
.setEnforcedTextAttributes(TextAttributes.ERASE_MARKER);
annotationHolder.createInfoAnnotation(textRange, null)
.setEnforcedTextAttributes(
EditorColorsManager.getInstance().getGlobalScheme().getAttributes(textAttributesKey)
);
}
}