Skip to content

Commit

Permalink
use completion contributor instead of completion data: rnc
Browse files Browse the repository at this point in the history
  • Loading branch information
denofevil committed Jul 27, 2016
1 parent 510b9f9 commit 1da42e6
Show file tree
Hide file tree
Showing 3 changed files with 109 additions and 137 deletions.
2 changes: 1 addition & 1 deletion xml/relaxng/src/META-INF/relaxng-plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@
<hectorComponentProvider implementation="org.intellij.plugins.relaxNG.config.NoNamespaceConfigImpl$HectorProvider" />

<fileTypeFactory implementation="org.intellij.plugins.relaxNG.compact.RncFileType$Factory" />
<completionData fileType="RNG Compact" className="org.intellij.plugins.relaxNG.compact.RncCompletionData" />
<completion.contributor language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.RncCompletionContributor" />
<standardResourceProvider implementation="org.intellij.plugins.relaxNG.ApplicationLoader$ResourceProvider" />

<annotator language="RELAX-NG" implementationClass="org.intellij.plugins.relaxNG.compact.ReferenceAnnotator" />
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
/*
* Copyright 2000-2016 JetBrains s.r.o.
*
* Licensed under the Apache License, Version 2.0 (the "License");
* you may not use this file except in compliance with the License.
* You may obtain a copy of the License at
*
* http://www.apache.org/licenses/LICENSE-2.0
*
* Unless required by applicable law or agreed to in writing, software
* distributed under the License is distributed on an "AS IS" BASIS,
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
* See the License for the specific language governing permissions and
* limitations under the License.
*/
package org.intellij.plugins.relaxNG.compact;

import com.intellij.codeInsight.TailType;
import com.intellij.codeInsight.completion.*;
import com.intellij.codeInsight.lookup.LookupElementBuilder;
import com.intellij.codeInsight.lookup.TailTypeDecorator;
import com.intellij.patterns.ElementPattern;
import com.intellij.patterns.PsiElementPattern;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiWhiteSpace;
import com.intellij.psi.util.PsiTreeUtil;
import com.intellij.util.ArrayUtil;
import com.intellij.util.ProcessingContext;
import org.intellij.plugins.relaxNG.compact.psi.RncDecl;
import org.intellij.plugins.relaxNG.compact.psi.RncDefine;
import org.intellij.plugins.relaxNG.compact.psi.RncGrammar;
import org.intellij.plugins.relaxNG.compact.psi.util.EscapeUtil;
import org.jetbrains.annotations.NotNull;

import static com.intellij.patterns.PlatformPatterns.psiElement;
import static com.intellij.patterns.StandardPatterns.and;
import static com.intellij.patterns.StandardPatterns.not;

/**
* @author Dennis.Ushakov
*/
public class RncCompletionContributor extends CompletionContributor {
private static final ElementPattern TOP_LEVEL =
not(psiElement().inside(psiElement(RncGrammar.class)
.inside(true, psiElement(RncGrammar.class))));

private static final PsiElementPattern DECL_PATTERN =
psiElement().inside(psiElement(RncDecl.class));

private static final PsiElementPattern DEFAULT_PATTERN =
DECL_PATTERN.afterLeaf(psiElement().withText("default"));

private static final ElementPattern DEFINE_PATTERN =
and(psiElement().withParent(RncDefine.class), psiElement().afterLeafSkipping(psiElement(PsiWhiteSpace.class), psiElement().withText("=")));

private static final String[] DECL_KEYWORDS = new String[]{ "default", "namespace", "datatypes" };
private static final String[] GRAMMAR_CONTENT_KEYWORDS = new String[]{ "include", "div", "start" };
private static final String[] PATTERN_KEYWORDS = new String[]{ "attribute", "element", "grammar",
"notAllowed", "text", "empty", "external", "parent", "list", "mixed" };


public RncCompletionContributor() {
CompletionProvider<CompletionParameters> provider = new CompletionProvider<CompletionParameters>() {
@Override
protected void addCompletions(@NotNull CompletionParameters parameters,
ProcessingContext context,
@NotNull CompletionResultSet result) {
String[] keywords = getKeywords(parameters.getPosition());
for (String keyword : keywords) {
result.addElement(TailTypeDecorator.withTail(LookupElementBuilder.create(keyword).bold(), TailType.SPACE));
}
}
};
extend(null, psiElement().afterLeaf(psiElement(RncTokenTypes.KEYWORD_DEFAULT)), provider);
extend(null, psiElement().andNot(psiElement().inside(psiElement(RncTokenTypes.LITERAL))).
andNot(psiElement().afterLeaf(psiElement().withElementType(RncTokenTypes.KEYWORDS))), provider);
}


private static String[] getKeywords(PsiElement context) {
final PsiElement next = PsiTreeUtil.skipSiblingsForward(context, PsiWhiteSpace.class);
if (next != null && EscapeUtil.unescapeText(next).equals("=")) {
return new String[]{ "start" };
}

if (DEFAULT_PATTERN.accepts(context)) {
return new String[]{ "namespace" };
} else if (DECL_PATTERN.accepts(context)) {
return ArrayUtil.EMPTY_STRING_ARRAY;
} else if (context.getParent() instanceof RncDefine && context.getParent().getFirstChild() == context) {
if (DEFINE_PATTERN.accepts(context)) {
return ArrayUtil.EMPTY_STRING_ARRAY;
}
if (TOP_LEVEL.accepts(context)) {
if (!afterPattern(context)) {
return ArrayUtil.mergeArrays(DECL_KEYWORDS, ArrayUtil.mergeArrays(GRAMMAR_CONTENT_KEYWORDS, PATTERN_KEYWORDS));
}
}
return GRAMMAR_CONTENT_KEYWORDS;
}
return PATTERN_KEYWORDS;
}

private static boolean afterPattern(PsiElement context) {
// TODO: recognize all patterns
return PsiTreeUtil.getPrevSiblingOfType(context.getParent(), RncDefine.class) != null;
}
}

This file was deleted.

0 comments on commit 1da42e6

Please sign in to comment.