brace matching for plain text files, also when used as the template data in freemarker

This commit is contained in:
peter
2010-08-26 20:25:08 +01:00
parent 47fb82e8ce
commit 548e09edf5
12 changed files with 116 additions and 27 deletions
@@ -49,6 +49,8 @@ public interface CustomHighlighterTokenType {
IElementType L_BRACE = new CustomElementType("L_BRACE");
IElementType R_BRACE = new CustomElementType("R_BRACE");
IElementType L_ANGLE = new CustomElementType("L_BROCKET");
IElementType R_ANGLE = new CustomElementType("R_BROCKET");
IElementType L_BRACKET = new CustomElementType("L_BRACKET");
IElementType R_BRACKET = new CustomElementType("R_BRACKET");
IElementType L_PARENTH = new CustomElementType("L_PARENTH");
@@ -43,7 +43,6 @@ import com.intellij.openapi.extensions.Extensions;
import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.PsiDocumentManager;
import com.intellij.psi.PsiElement;
import com.intellij.psi.PsiFile;
@@ -182,8 +181,7 @@ public class TypedHandler implements TypedActionHandler {
EditorModificationUtil.deleteSelectedText(editor);
}
final VirtualFile virtualFile = file.getVirtualFile();
FileType fileType = virtualFile == null ? file.getFileType() : virtualFile.getFileType();
FileType fileType = file.getFileType();
for(TypedHandlerDelegate delegate: delegates) {
final TypedHandlerDelegate.Result result = delegate.beforeCharTyped(charTyped, project, editor, file, fileType);
@@ -428,8 +426,7 @@ public class TypedHandler implements TypedActionHandler {
text = "}";
}
else {
LOG.error("Unknown char "+lparenChar);
return;
throw new AssertionError("Unknown char "+lparenChar);
}
editor.getDocument().insertString(offset, text);
}
@@ -98,8 +98,7 @@ public class BraceHighlightingHandler {
if (isReallyDisposed(editor, project)) return;
final PsiFile injected = ApplicationManager.getApplication().runReadAction(new Computable<PsiFile>() {
public PsiFile compute() {
Document document = editor.getDocument();
PsiFile psiFile = PsiDocumentManager.getInstance(project).getPsiFile(document);
PsiFile psiFile = PsiUtilBase.getPsiFileInEditor(editor, project);
return null != psiFile ? getInjectedFileIfAny(editor, project, offset, psiFile, alarm) : null;
}
});
@@ -320,13 +320,14 @@ public class BraceMatchingUtil {
@NotNull
public static BraceMatcher getBraceMatcher(FileType fileType, Language lang) {
final BraceMatcher byFileType = getBraceMatcherByFileType(fileType);
if (byFileType != null) return byFileType;
PairedBraceMatcher matcher = LanguageBraceMatching.INSTANCE.forLanguage(lang);
if (matcher != null) {
return new PairedBraceMatcherAdapter(matcher, lang);
}
final BraceMatcher byFileType = getBraceMatcherByFileType(fileType);
if (byFileType != null) return byFileType;
if (fileType instanceof LanguageFileType) {
final Language language = ((LanguageFileType)fileType).getLanguage();
if (lang != language) {
@@ -23,10 +23,12 @@ import com.intellij.psi.CustomHighlighterTokenType;
import com.intellij.psi.tree.IElementType;
import com.intellij.util.ArrayUtil;
import java.util.List;
/**
* @author dsl
*/
public abstract class AbstractCustomLexer extends LexerBase {
public class AbstractCustomLexer extends LexerBase {
protected CharSequence myBuffer = ArrayUtil.EMPTY_CHAR_SEQUENCE;
protected int myStartOffset = 0;
protected int myEndOffset = 0;
@@ -34,8 +36,8 @@ public abstract class AbstractCustomLexer extends LexerBase {
private TokenInfo myCurrentToken;
private int myPosition;
public AbstractCustomLexer(TokenParser[] tokenParsers) {
myTokenParsers = tokenParsers;
public AbstractCustomLexer(List<TokenParser> tokenParsers) {
myTokenParsers = tokenParsers.toArray(new TokenParser[tokenParsers.size()]);
int smartUpdateShift = 0;
for (TokenParser tokenParser : myTokenParsers) {
@@ -20,6 +20,7 @@ import com.intellij.ide.highlighter.custom.tokens.*;
import com.intellij.psi.CustomHighlighterTokenType;
import java.util.ArrayList;
import java.util.List;
import java.util.Set;
/**
@@ -34,8 +35,7 @@ public final class CustomFileTypeLexer extends AbstractCustomLexer {
this(table, false);
}
private static TokenParser[] buildTokenParsers(SyntaxTable table, boolean forHighlighting) {
final WhitespaceParser whitespaceParser = new WhitespaceParser();
private static List<TokenParser> buildTokenParsers(SyntaxTable table, boolean forHighlighting) {
final LineCommentParser lineCommentParser = LineCommentParser.create(table.getLineComment());
final MultilineCommentParser multilineCommentParser =
MultilineCommentParser.create(table.getStartComment(), table.getEndComment());
@@ -55,7 +55,7 @@ public final class CustomFileTypeLexer extends AbstractCustomLexer {
);
ArrayList<TokenParser> tokenParsers = new ArrayList<TokenParser>();
tokenParsers.add(whitespaceParser);
tokenParsers.add(new WhitespaceParser());
tokenParsers.add(quotedStringParser);
tokenParsers.add(quotedStringParser2);
if (lineCommentParser != null) {
@@ -73,21 +73,18 @@ public final class CustomFileTypeLexer extends AbstractCustomLexer {
tokenParsers.add(identifierParser);
if (table.isHasBraces()) {
tokenParsers.add(new BraceTokenParser("{", CustomHighlighterTokenType.L_BRACE));
tokenParsers.add(new BraceTokenParser("}", CustomHighlighterTokenType.R_BRACE));
tokenParsers.addAll(BraceTokenParser.BRACES);
}
if (table.isHasParens()) {
tokenParsers.add(new BraceTokenParser("(", CustomHighlighterTokenType.L_PARENTH));
tokenParsers.add(new BraceTokenParser(")", CustomHighlighterTokenType.R_PARENTH));
tokenParsers.addAll(BraceTokenParser.PARENS);
}
if (table.isHasBrackets()) {
tokenParsers.add(new BraceTokenParser("[", CustomHighlighterTokenType.L_BRACKET));
tokenParsers.add(new BraceTokenParser("]", CustomHighlighterTokenType.R_BRACKET));
tokenParsers.addAll(BraceTokenParser.BRACKETS);
}
return tokenParsers.toArray(new TokenParser[tokenParsers.size()]);
return tokenParsers;
}
@@ -28,7 +28,7 @@ import org.jetbrains.annotations.Nullable;
/**
* @author Maxim.Mossienko
*/
class CustomFileTypeBraceMatcher implements BraceMatcher {
public class CustomFileTypeBraceMatcher implements BraceMatcher {
public int getBraceTokenGroupId(IElementType tokenType) {
return 777;
}
@@ -37,6 +37,7 @@ class CustomFileTypeBraceMatcher implements BraceMatcher {
final IElementType tokenType = iterator.getTokenType();
return tokenType == CustomHighlighterTokenType.L_BRACKET ||
tokenType == CustomHighlighterTokenType.L_ANGLE ||
tokenType == CustomHighlighterTokenType.L_PARENTH ||
tokenType == CustomHighlighterTokenType.L_BRACE;
}
@@ -47,6 +48,7 @@ class CustomFileTypeBraceMatcher implements BraceMatcher {
private static boolean isRBraceToken(IElementType tokenType) {
return tokenType == CustomHighlighterTokenType.R_BRACKET ||
tokenType == CustomHighlighterTokenType.R_ANGLE ||
tokenType == CustomHighlighterTokenType.R_PARENTH ||
tokenType == CustomHighlighterTokenType.R_BRACE;
}
@@ -56,6 +58,8 @@ class CustomFileTypeBraceMatcher implements BraceMatcher {
(tokenType == CustomHighlighterTokenType.R_BRACE && tokenType2 == CustomHighlighterTokenType.L_BRACE) ||
(tokenType == CustomHighlighterTokenType.L_BRACKET && tokenType2 == CustomHighlighterTokenType.R_BRACKET) ||
(tokenType == CustomHighlighterTokenType.R_BRACKET && tokenType2 == CustomHighlighterTokenType.L_BRACKET) ||
(tokenType == CustomHighlighterTokenType.L_ANGLE && tokenType2 == CustomHighlighterTokenType.R_ANGLE) ||
(tokenType == CustomHighlighterTokenType.R_ANGLE && tokenType2 == CustomHighlighterTokenType.L_ANGLE) ||
(tokenType == CustomHighlighterTokenType.L_PARENTH && tokenType2 == CustomHighlighterTokenType.R_PARENTH) ||
(tokenType == CustomHighlighterTokenType.R_PARENTH && tokenType2 == CustomHighlighterTokenType.L_PARENTH);
}
@@ -75,6 +79,8 @@ class CustomFileTypeBraceMatcher implements BraceMatcher {
if (type == CustomHighlighterTokenType.L_BRACKET) return CustomHighlighterTokenType.R_BRACKET;
if (type == CustomHighlighterTokenType.R_BRACKET) return CustomHighlighterTokenType.L_BRACKET;
if (type == CustomHighlighterTokenType.L_ANGLE) return CustomHighlighterTokenType.R_ANGLE;
if (type == CustomHighlighterTokenType.R_ANGLE) return CustomHighlighterTokenType.L_ANGLE;
if (type == CustomHighlighterTokenType.L_PARENTH) return CustomHighlighterTokenType.R_PARENTH;
if (type == CustomHighlighterTokenType.R_PARENTH) return CustomHighlighterTokenType.L_PARENTH;
@@ -16,12 +16,25 @@
package com.intellij.ide.highlighter.custom.tokens;
import com.intellij.psi.CustomHighlighterTokenType;
import com.intellij.psi.tree.IElementType;
import java.util.Arrays;
import java.util.List;
/**
* @author Maxim.Mossienko
*/
public class BraceTokenParser extends PrefixedTokenParser {
public static final List<BraceTokenParser> BRACES = Arrays.asList(new BraceTokenParser("{", CustomHighlighterTokenType.L_BRACE),
new BraceTokenParser("}", CustomHighlighterTokenType.R_BRACE));
public static final List<BraceTokenParser> PARENS = Arrays.asList(new BraceTokenParser("(", CustomHighlighterTokenType.L_PARENTH),
new BraceTokenParser(")", CustomHighlighterTokenType.R_PARENTH));
public static final List<BraceTokenParser> BRACKETS = Arrays.asList(new BraceTokenParser("[", CustomHighlighterTokenType.L_BRACKET),
new BraceTokenParser("]", CustomHighlighterTokenType.R_BRACKET));
public static final List<BraceTokenParser> ANGLE_BRACKETS = Arrays.asList(new BraceTokenParser("<", CustomHighlighterTokenType.L_ANGLE),
new BraceTokenParser(">", CustomHighlighterTokenType.R_ANGLE));
public BraceTokenParser(String prefix, IElementType tokenType) {
super(prefix, tokenType);
}
@@ -0,0 +1,69 @@
/*
* Copyright 2000-2009 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.
*/
/*
* @author max
*/
package com.intellij.openapi.fileTypes;
import com.intellij.ide.highlighter.custom.AbstractCustomLexer;
import com.intellij.ide.highlighter.custom.CustomHighlighterColors;
import com.intellij.ide.highlighter.custom.tokens.*;
import com.intellij.lexer.Lexer;
import com.intellij.openapi.editor.colors.TextAttributesKey;
import com.intellij.openapi.project.Project;
import com.intellij.openapi.vfs.VirtualFile;
import com.intellij.psi.CustomHighlighterTokenType;
import com.intellij.psi.tree.IElementType;
import org.jetbrains.annotations.NotNull;
import java.util.ArrayList;
/**
* @author peter
*/
public class PlainTextSyntaxHighlighterFactory extends SyntaxHighlighterFactory {
@NotNull
public SyntaxHighlighter getSyntaxHighlighter(final Project project, final VirtualFile virtualFile) {
return new SyntaxHighlighterBase() {
@NotNull
@Override
public Lexer getHighlightingLexer() {
ArrayList<TokenParser> tokenParsers = new ArrayList<TokenParser>();
tokenParsers.add(new WhitespaceParser());
tokenParsers.add(new NumberParser("", false));
tokenParsers.add(new PunctuationParser());
tokenParsers.add(new IdentifierParser());
tokenParsers.addAll(BraceTokenParser.BRACES);
tokenParsers.addAll(BraceTokenParser.PARENS);
tokenParsers.addAll(BraceTokenParser.BRACKETS);
tokenParsers.addAll(BraceTokenParser.ANGLE_BRACKETS);
return new AbstractCustomLexer(tokenParsers);
}
@NotNull
@Override
public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
if (tokenType == CustomHighlighterTokenType.NUMBER) {
return new TextAttributesKey[]{CustomHighlighterColors.CUSTOM_NUMBER_ATTRIBUTES};
}
return EMPTY;
}
};
}
}
@@ -17,6 +17,8 @@
package com.intellij.psi.impl.source;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.openapi.fileTypes.PlainTextLanguage;
import com.intellij.openapi.fileTypes.StdFileTypes;
import com.intellij.psi.*;
import com.intellij.psi.impl.source.resolve.reference.ReferenceProvidersRegistry;
import org.jetbrains.annotations.NotNull;
@@ -26,7 +28,7 @@ public class PsiPlainTextFileImpl extends PsiFileImpl implements PsiPlainTextFil
public PsiPlainTextFileImpl(FileViewProvider viewProvider) {
super(PlainTextTokenTypes.PLAIN_TEXT_FILE, PlainTextTokenTypes.PLAIN_TEXT_FILE, viewProvider);
myFileType = viewProvider.getVirtualFile().getFileType();
myFileType = viewProvider.getBaseLanguage() != PlainTextLanguage.INSTANCE ? StdFileTypes.PLAIN_TEXT : viewProvider.getVirtualFile().getFileType();
}
public void accept(@NotNull PsiElementVisitor visitor){
@@ -22,7 +22,7 @@ import com.intellij.psi.tree.TokenSet;
import java.util.Map;
public abstract class SyntaxHighlighterBase implements SyntaxHighlighter {
private static final TextAttributesKey[] EMPTY = new TextAttributesKey[0];
protected static final TextAttributesKey[] EMPTY = new TextAttributesKey[0];
public static TextAttributesKey[] pack(TextAttributesKey key) {
if (key == null) return EMPTY;
@@ -282,7 +282,8 @@
<!--<projectConfigurable implementation="com.intellij.application.options.ProjectCodeStyleConfigurable" order="before vcs"/>-->
<lang.parserDefinition language="TEXT" implementationClass="com.intellij.openapi.fileTypes.PlainTextParserDefinition"/>
<lang.syntaxHighlighterFactory language="TEXT" implementationClass="com.intellij.openapi.fileTypes.PlainSyntaxHighlighterFactory"/>
<lang.syntaxHighlighterFactory key="TEXT" implementationClass="com.intellij.openapi.fileTypes.PlainTextSyntaxHighlighterFactory"/>
<braceMatcher filetype="PLAIN_TEXT" implementationClass="com.intellij.ide.highlighter.custom.impl.CustomFileTypeBraceMatcher"/>
<lang.ast.factory language="TEXT" implementationClass="com.intellij.psi.impl.source.tree.PlainTextASTFactory"/>
<getDataRule key="psi.File" implementationClass="com.intellij.ide.impl.dataRules.PsiFileRule"/>