Skip to content

Commit

Permalink
Added a brace matcher
Browse files Browse the repository at this point in the history
  • Loading branch information
yzhang committed May 11, 2013
1 parent da09173 commit f843ec5
Show file tree
Hide file tree
Showing 4 changed files with 130 additions and 2 deletions.
1 change: 1 addition & 0 deletions META-INF/plugin.xml
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@
<lang.fileViewProviderFactory language="Dust" implementationClass="com.linkedin.intellij.dust.DustFileViewProviderFactory" />
<colorSettingsPage implementation="com.linkedin.intellij.dust.DustColorSettingsPage"/>
<annotator language="Dust" implementationClass="com.linkedin.intellij.dust.DustAnnotator"/>
<braceMatcher filetype="Dust" implementationClass="com.linkedin.intellij.dust.DustBraceMatcher"/>
<lang.commenter language="Dust" implementationClass="com.linkedin.intellij.dust.DustCommenter"/>
</extensions>
</idea-plugin>
4 changes: 2 additions & 2 deletions src/com/linkedin/intellij/dust/Dust.bnf
Original file line number Diff line number Diff line change
Expand Up @@ -32,9 +32,9 @@ open_tag ::= (SECTION|EXISTANCE|NOT_EXISTANCE|HELPER|PARTIAL|INLINE_PARTIAL|BLOC

else_tag ::= ELSE tag_name tag_content RD

close_tag ::= CLOSE tag_name tag_content RD
close_tag ::= CLOSE tag_name index_deref? tag_content RD

self_close_tag ::= (SECTION|EXISTANCE|NOT_EXISTANCE|HELPER|PARTIAL|INLINE_PARTIAL|BLOCK|CLOSE|ELSE|LD) tag_name context* tag_content SLASH_RD
self_close_tag ::= (HELPER|PARTIAL|INLINE_PARTIAL|CLOSE|ELSE|LD) tag_name context* tag_content SLASH_RD

tag_name ::= (path|STRING|STRING_SINGLE|IDENTIFIER|PERIOD)

Expand Down
125 changes: 125 additions & 0 deletions src/com/linkedin/intellij/dust/DustBraceMatcher.java
Original file line number Diff line number Diff line change
@@ -0,0 +1,125 @@
package com.linkedin.intellij.dust;

import com.intellij.codeInsight.highlighting.BraceMatcher;
import com.intellij.openapi.editor.highlighter.HighlighterIterator;
import com.intellij.openapi.fileTypes.FileType;
import com.intellij.psi.PsiFile;
import com.intellij.psi.tree.IElementType;
import com.linkedin.intellij.dust.psi.DustTypes;
import org.jetbrains.annotations.NotNull;
import org.jetbrains.annotations.Nullable;

import java.util.HashSet;
import java.util.Set;

/**
* Created with IntelliJ IDEA.
* User: yzhang
* Date: 5/10/13
* Time: 5:17 PM
*/
public class DustBraceMatcher implements BraceMatcher {

private static final Set<IElementType> LEFT_BRACES = new HashSet<IElementType>();
private static final Set<IElementType> RIGHT_BRACES = new HashSet<IElementType>();

static {
LEFT_BRACES.add(DustTypes.LD);
LEFT_BRACES.add(DustTypes.BLOCK);
LEFT_BRACES.add(DustTypes.SECTION);
LEFT_BRACES.add(DustTypes.PARTIAL);
LEFT_BRACES.add(DustTypes.HELPER);
LEFT_BRACES.add(DustTypes.EXISTANCE);
LEFT_BRACES.add(DustTypes.NOT_EXISTANCE);
LEFT_BRACES.add(DustTypes.INLINE_PARTIAL);
LEFT_BRACES.add(DustTypes.ELSE);

RIGHT_BRACES.add(DustTypes.SLASH_RD);
RIGHT_BRACES.add(DustTypes.RD);
}

@Override
public boolean isPairBraces(IElementType tokenType1, IElementType tokenType2) {
return LEFT_BRACES.contains(tokenType1) && RIGHT_BRACES.contains(tokenType2)
|| RIGHT_BRACES.contains(tokenType1) && LEFT_BRACES.contains(tokenType2);
}

@Override
public boolean isLBraceToken(HighlighterIterator iterator, CharSequence fileText, FileType fileType) {
return LEFT_BRACES.contains(iterator.getTokenType());
}

@Override
public boolean isRBraceToken(HighlighterIterator iterator, CharSequence fileText, FileType fileType) {
if (!RIGHT_BRACES.contains(iterator.getTokenType())) {
// definitely not a right brace
return false;
} else if (iterator.getTokenType() == DustTypes.SLASH_RD) {
return true;
}

boolean isRBraceToken = false;
int iteratorRetreatCount = 0;
while (true) {
iterator.retreat();
iteratorRetreatCount++;

if (iterator.atEnd()) {
break;
}

if (iterator.getTokenType() == DustTypes.SECTION
|| iterator.getTokenType() == DustTypes.EXISTANCE
|| iterator.getTokenType() == DustTypes.NOT_EXISTANCE
|| iterator.getTokenType() == DustTypes.INLINE_PARTIAL
|| iterator.getTokenType() == DustTypes.BLOCK) {
// If first open type token we encountered is a block opener, the this is not a close brace because
// the paired close brace for these block openers is at the end of the corresponding block close tags
break;
}

if (iterator.getTokenType() == DustTypes.LD
|| iterator.getTokenType() == DustTypes.PARTIAL
|| iterator.getTokenType() == DustTypes.HELPER
|| iterator.getTokenType() == DustTypes.CLOSE) {
// If the first open token we encountered was a simple opener (i.e. didn't start a block)
// or the closing brace of a closing tag, then this is definitely a right brace.
isRBraceToken = true;
}
}

// reset the given iterator before returning
while (iteratorRetreatCount-- > 0) {
iterator.advance();
}

return isRBraceToken;
}

@Override
public int getBraceTokenGroupId(IElementType tokenType) {
return 1;
}

@Override
public boolean isStructuralBrace(HighlighterIterator iterator, CharSequence text, FileType fileType) {
return false;
}

@Nullable
@Override
public IElementType getOppositeBraceTokenType(@NotNull IElementType type) {
return null;
}

@Override
public boolean isPairedBracesAllowedBeforeType(@NotNull IElementType lbraceType, @Nullable IElementType contextType) {
return true;
}

@Override
public int getCodeConstructStart(PsiFile file, int openingBraceOffset) {
return openingBraceOffset;
}
}

2 changes: 2 additions & 0 deletions src/com/linkedin/intellij/dust/DustSyntaxHighlighter.java
Original file line number Diff line number Diff line change
Expand Up @@ -72,6 +72,8 @@ public TextAttributesKey[] getTokenHighlights(IElementType tokenType) {
private static boolean isPartOfTag(IElementType tokenType) {
return tokenType.equals(DustTypes.LD)
|| tokenType.equals(DustTypes.RD)
|| tokenType.equals(DustTypes.LB)
|| tokenType.equals(DustTypes.RB)
|| tokenType.equals(DustTypes.SLASH_RD)
|| tokenType.equals(DustTypes.SECTION)
|| tokenType.equals(DustTypes.EXISTANCE)
Expand Down

0 comments on commit f843ec5

Please sign in to comment.