Skip to content

Commit 34e558f

Browse files
committed
Added support for spellchecker and to-do view (#15)
1 parent 5aeec87 commit 34e558f

File tree

4 files changed

+132
-6
lines changed

4 files changed

+132
-6
lines changed

resources/META-INF/plugin.xml

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -63,6 +63,11 @@
6363
<projectService serviceInterface="com.intellij.lang.jsgraphql.endpoint.ide.project.JSGraphQLEndpointNamedTypeRegistry" serviceImplementation="com.intellij.lang.jsgraphql.endpoint.ide.project.JSGraphQLEndpointNamedTypeRegistry" />
6464

6565

66+
<!-- Spellchecking and to-do view-->
67+
<spellchecker.support language="GraphQL Endpoint" implementationClass="com.intellij.lang.jsgraphql.endpoint.JSGraphQLEndpointSpellcheckingStrategy" />
68+
<todoIndexer filetype="GraphQL Endpoint" implementationClass="com.intellij.lang.jsgraphql.endpoint.JSGraphQLEndpointTodoIndexer"/>
69+
70+
6671
<!-- Project tree -->
6772
<treeStructureProvider implementation="com.intellij.lang.jsgraphql.schema.ide.project.JSGraphQLSchemaTreeStructureProvider" />
6873

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
/**
2+
* Copyright (c) 2015-present, Jim Kynde Meyer
3+
* All rights reserved.
4+
* <p>
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
package com.intellij.lang.jsgraphql.endpoint;
9+
10+
import com.intellij.codeInspection.SuppressionUtil;
11+
import com.intellij.psi.PsiComment;
12+
import com.intellij.psi.PsiElement;
13+
import com.intellij.psi.PsiNameIdentifierOwner;
14+
import com.intellij.psi.PsiWhiteSpace;
15+
import com.intellij.spellchecker.inspections.IdentifierSplitter;
16+
import com.intellij.spellchecker.tokenizer.PsiIdentifierOwnerTokenizer;
17+
import com.intellij.spellchecker.tokenizer.SpellcheckingStrategy;
18+
import com.intellij.spellchecker.tokenizer.Tokenizer;
19+
import com.intellij.spellchecker.tokenizer.TokenizerBase;
20+
import org.jetbrains.annotations.NotNull;
21+
22+
public class JSGraphQLEndpointSpellcheckingStrategy extends SpellcheckingStrategy {
23+
24+
private static final TokenizerBase<PsiElement> IDENTIFIER_TOKENIZER = new TokenizerBase<>(IdentifierSplitter.getInstance());
25+
26+
@NotNull
27+
@Override
28+
public Tokenizer getTokenizer(PsiElement element) {
29+
if (element instanceof PsiWhiteSpace) {
30+
return EMPTY_TOKENIZER;
31+
}
32+
if (element instanceof PsiNameIdentifierOwner) {
33+
return new PsiIdentifierOwnerTokenizer();
34+
}
35+
if (element.getParent() instanceof PsiNameIdentifierOwner) {
36+
return EMPTY_TOKENIZER;
37+
}
38+
if (element.getNode().getElementType() == JSGraphQLEndpointTokenTypes.IDENTIFIER) {
39+
return IDENTIFIER_TOKENIZER;
40+
}
41+
if (element instanceof PsiComment) {
42+
if (SuppressionUtil.isSuppressionComment(element)) {
43+
return EMPTY_TOKENIZER;
44+
}
45+
return myCommentTokenizer;
46+
}
47+
return EMPTY_TOKENIZER;
48+
}
49+
}
Lines changed: 42 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,42 @@
1+
/**
2+
* Copyright (c) 2015-present, Jim Kynde Meyer
3+
* All rights reserved.
4+
* <p>
5+
* This source code is licensed under the MIT license found in the
6+
* LICENSE file in the root directory of this source tree.
7+
*/
8+
package com.intellij.lang.jsgraphql.endpoint;
9+
10+
import com.intellij.lang.jsgraphql.endpoint.lexer.JSGraphQLEndpointLexer;
11+
import com.intellij.lexer.FlexAdapter;
12+
import com.intellij.lexer.Lexer;
13+
import com.intellij.psi.impl.cache.impl.BaseFilterLexer;
14+
import com.intellij.psi.impl.cache.impl.OccurrenceConsumer;
15+
import com.intellij.psi.impl.cache.impl.todo.LexerBasedTodoIndexer;
16+
import com.intellij.psi.search.UsageSearchContext;
17+
import com.intellij.psi.tree.IElementType;
18+
19+
public class JSGraphQLEndpointTodoIndexer extends LexerBasedTodoIndexer {
20+
21+
@Override
22+
public Lexer createLexer(OccurrenceConsumer consumer) {
23+
return new JSGraphQLEndpointTodoLexer(consumer);
24+
}
25+
26+
private static class JSGraphQLEndpointTodoLexer extends BaseFilterLexer {
27+
28+
JSGraphQLEndpointTodoLexer(OccurrenceConsumer occurrenceConsumer) {
29+
super(new FlexAdapter(new JSGraphQLEndpointLexer()), occurrenceConsumer);
30+
}
31+
32+
@Override
33+
public void advance() {
34+
final IElementType tokenType = this.myDelegate.getTokenType();
35+
if (tokenType == JSGraphQLEndpointTokenTypes.LINE_COMMENT) {
36+
this.scanWordsInToken(UsageSearchContext.IN_COMMENTS, false, false);
37+
this.advanceTodoItemCountsInToken();
38+
}
39+
this.myDelegate.advance();
40+
}
41+
}
42+
}

src/main/com/intellij/lang/jsgraphql/endpoint/doc/ide/annotator/JSGraphQLEndpointDocHighlightAnnotator.java

Lines changed: 36 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -7,11 +7,6 @@
77
*/
88
package com.intellij.lang.jsgraphql.endpoint.doc.ide.annotator;
99

10-
import java.util.HashMap;
11-
import java.util.Map;
12-
13-
import org.jetbrains.annotations.NotNull;
14-
1510
import com.intellij.lang.annotation.Annotation;
1611
import com.intellij.lang.annotation.AnnotationHolder;
1712
import com.intellij.lang.annotation.Annotator;
@@ -22,11 +17,17 @@
2217
import com.intellij.lang.jsgraphql.endpoint.psi.JSGraphQLEndpointInputValueDefinition;
2318
import com.intellij.lang.jsgraphql.endpoint.psi.JSGraphQLEndpointInputValueDefinitions;
2419
import com.intellij.openapi.editor.DefaultLanguageHighlighterColors;
20+
import com.intellij.openapi.editor.colors.CodeInsightColors;
2521
import com.intellij.openapi.editor.colors.TextAttributesKey;
22+
import com.intellij.openapi.util.Key;
2623
import com.intellij.psi.PsiComment;
2724
import com.intellij.psi.PsiElement;
2825
import com.intellij.psi.tree.IElementType;
2926
import com.intellij.psi.util.PsiTreeUtil;
27+
import org.jetbrains.annotations.NotNull;
28+
29+
import java.util.HashMap;
30+
import java.util.Map;
3031

3132
/**
3233
* Highlights GraphQL Endpoint documentation comments
@@ -41,13 +42,35 @@ public class JSGraphQLEndpointDocHighlightAnnotator implements Annotator {
4142
ATTRIBUTES.put(JSGraphQLEndpointDocTokenTypes.DOCVALUE, DefaultLanguageHighlighterColors.DOC_COMMENT_TAG_VALUE);
4243
}
4344

45+
private static final Key<PsiElement> TODO_ELEMENT = Key.create("JSGraphQLEndpointDocHighlightAnnotator.Todo");
4446

4547
@SuppressWarnings("unchecked")
4648
@Override
4749
public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder holder) {
50+
51+
final IElementType elementType = element.getNode().getElementType();
52+
53+
// highlight TO-DO items
54+
if(elementType == JSGraphQLEndpointDocTokenTypes.DOCTEXT) {
55+
final String elementText = element.getText().toLowerCase();
56+
if(isTodoToken(elementText)) {
57+
setTextAttributes(element, holder, CodeInsightColors.TODO_DEFAULT_ATTRIBUTES);
58+
holder.getCurrentAnnotationSession().putUserData(TODO_ELEMENT, element);
59+
return;
60+
} else {
61+
PsiElement prevSibling = element.getPrevSibling();
62+
while (prevSibling != null) {
63+
if(prevSibling == holder.getCurrentAnnotationSession().getUserData(TODO_ELEMENT)) {
64+
setTextAttributes(element, holder, CodeInsightColors.TODO_DEFAULT_ATTRIBUTES);
65+
return;
66+
}
67+
prevSibling = prevSibling.getPrevSibling();
68+
}
69+
}
70+
}
71+
4872
final PsiComment comment = PsiTreeUtil.getContextOfType(element, PsiComment.class);
4973
if (comment != null && JSGraphQLEndpointDocPsiUtil.isDocumentationComment(comment)) {
50-
final IElementType elementType = element.getNode().getElementType();
5174
final TextAttributesKey textAttributesKey = ATTRIBUTES.get(elementType);
5275
if (textAttributesKey != null) {
5376
setTextAttributes(element, holder, textAttributesKey);
@@ -85,6 +108,13 @@ public void annotate(@NotNull PsiElement element, @NotNull AnnotationHolder hold
85108
}
86109
}
87110

111+
private boolean isTodoToken(String elementText) {
112+
if(elementText.startsWith("todo")) {
113+
return elementText.length() == 4 || !Character.isAlphabetic(elementText.charAt(4));
114+
}
115+
return false;
116+
}
117+
88118
private void setTextAttributes(PsiElement element, AnnotationHolder holder, TextAttributesKey key) {
89119
final Annotation annotation = holder.createInfoAnnotation(element, null);
90120
annotation.setTextAttributes(key);

0 commit comments

Comments
 (0)