private static Collection<String> suggestKeywords(PsiElement position) { TextRange posRange = position.getTextRange(); BnfFile posFile = (BnfFile) position.getContainingFile(); BnfRule statement = PsiTreeUtil.getTopmostParentOfType(position, BnfRule.class); final TextRange range; if (statement != null) { range = new TextRange(statement.getTextRange().getStartOffset(), posRange.getStartOffset()); } else { int offset = posRange.getStartOffset(); for (PsiElement cur = GrammarUtil.getDummyAwarePrevSibling(position); cur != null; cur = GrammarUtil.getDummyAwarePrevSibling(cur)) { if (cur instanceof BnfAttrs) offset = cur.getTextRange().getEndOffset(); else if (cur instanceof BnfRule) offset = cur.getTextRange().getStartOffset(); else continue; break; } range = new TextRange(offset, posRange.getStartOffset()); } final String text = range.isEmpty() ? CompletionInitializationContext.DUMMY_IDENTIFIER : range.substring(posFile.getText()); PsiFile file = PsiFileFactory.getInstance(posFile.getProject()) .createFileFromText("a.bnf", BnfLanguage.INSTANCE, text, true, false); int completionOffset = posRange.getStartOffset() - range.getStartOffset(); GeneratedParserUtilBase.CompletionState state = new GeneratedParserUtilBase.CompletionState(completionOffset) { @Override public String convertItem(Object o) { // we do not have other keywords return o instanceof String ? (String) o : null; } }; file.putUserData(GeneratedParserUtilBase.COMPLETION_STATE_KEY, state); TreeUtil.ensureParsed(file.getNode()); return state.items; }
@NotNull @Override public FoldingDescriptor[] buildFoldRegions( @NotNull PsiElement root, @NotNull Document document, boolean quick) { if (!(root instanceof BnfFile)) return FoldingDescriptor.EMPTY; BnfFile file = (BnfFile) root; final ArrayList<FoldingDescriptor> result = new ArrayList<FoldingDescriptor>(); for (BnfAttrs attrs : file.getAttributes()) { TextRange textRange = attrs.getTextRange(); if (textRange.getLength() <= 2) continue; result.add(new FoldingDescriptor(attrs, textRange)); } for (BnfRule rule : file.getRules()) { // result.add(new FoldingDescriptor(rule, rule.getTextRange())); BnfAttrs attrs = rule.getAttrs(); if (attrs != null) { result.add(new FoldingDescriptor(attrs, attrs.getTextRange())); } } if (!quick) { PsiTreeUtil.processElements( file, new PsiElementProcessor() { @Override public boolean execute(@NotNull PsiElement element) { if (element.getNode().getElementType() == BnfParserDefinition.BNF_BLOCK_COMMENT) { result.add(new FoldingDescriptor(element, element.getTextRange())); } return true; } }); } return result.toArray(new FoldingDescriptor[result.size()]); }