diff --git a/HighlightBracketPair-1.1.2.zip b/HighlightBracketPair-1.1.2.zip new file mode 100644 index 0000000..785fa86 Binary files /dev/null and b/HighlightBracketPair-1.1.2.zip differ diff --git a/src/main/java/io/github/qeesung/component/HighlightEditorComponent.java b/src/main/java/io/github/qeesung/component/HighlightEditorComponent.java index 0842087..95456b8 100644 --- a/src/main/java/io/github/qeesung/component/HighlightEditorComponent.java +++ b/src/main/java/io/github/qeesung/component/HighlightEditorComponent.java @@ -21,6 +21,7 @@ public class HighlightEditorComponent implements CaretListener { private final Editor editor; private List highlighterList = new ArrayList<>(); + private List gutterHighlighterList = new ArrayList<>(); private ExtraHighlightTrigger extraHighlightTrigger; public void dispose() { @@ -98,6 +99,9 @@ public void highlightEditorCurrentPair(Editor editor) { // clear the high lighter highlighter.eraseHighlight(highlighterList); + // clear braces in gutter + highlighter.eraseHighlight(gutterHighlighterList); + // find the brace positions BracePair bracePair = highlighter.findClosetBracePair(offset); @@ -105,6 +109,14 @@ public void highlightEditorCurrentPair(Editor editor) { Pair highlighterEntry = highlighter.highlightPair(bracePair); + // show braces in gutter + List showBracesInGutter = + highlighter.showBracesInGutter(bracePair); + + if (showBracesInGutter!= null) { + gutterHighlighterList.addAll(showBracesInGutter); + } + // record the high lighter if (highlighterEntry != null) { highlighterList.add(highlighterEntry.getLeft()); diff --git a/src/main/java/io/github/qeesung/highlighter/BraceHighlighter.java b/src/main/java/io/github/qeesung/highlighter/BraceHighlighter.java index 6c5ef99..a1722b8 100644 --- a/src/main/java/io/github/qeesung/highlighter/BraceHighlighter.java +++ b/src/main/java/io/github/qeesung/highlighter/BraceHighlighter.java @@ -7,10 +7,7 @@ import com.intellij.openapi.editor.ex.MarkupModelEx; import com.intellij.openapi.editor.highlighter.EditorHighlighter; import com.intellij.openapi.editor.highlighter.HighlighterIterator; -import com.intellij.openapi.editor.markup.HighlighterLayer; -import com.intellij.openapi.editor.markup.HighlighterTargetArea; -import com.intellij.openapi.editor.markup.RangeHighlighter; -import com.intellij.openapi.editor.markup.TextAttributes; +import com.intellij.openapi.editor.markup.*; import com.intellij.openapi.fileTypes.FileType; import com.intellij.openapi.project.Project; import com.intellij.psi.PsiDocumentManager; @@ -21,7 +18,11 @@ import io.github.qeesung.brace.BracePair; import io.github.qeesung.setting.HighlightBracketPairSettingsPage; import io.github.qeesung.util.Pair; +import org.jetbrains.annotations.NotNull; +import javax.swing.*; +import java.awt.*; +import java.util.ArrayList; import java.util.LinkedList; import java.util.List; @@ -57,7 +58,6 @@ public BraceHighlighter(Editor editor) { } /** - * * @return */ public List> getSupportedBraceToken() { @@ -82,8 +82,6 @@ public BracePair findClosetBracePairInBraceTokens(int offset) { rightType(braceTokenPair.getRight()). leftIterator(leftTraverseIterator). rightIterator(rightTraverseIterator).build(); - - } } return EMPTY_BRACE_PAIR; @@ -125,6 +123,89 @@ public BracePair findClosetBracePair(int offset) { } } + public List showBracesInGutter(BracePair bracePair) { + final Brace leftBrace = bracePair.getLeftBrace(); + final Brace rightBrace = bracePair.getRightBrace(); + final int leftBraceOffset = leftBrace.getOffset(); + final int rightBraceOffset = rightBrace.getOffset(); + final String leftBraceText = leftBrace.getText(); + final String rightBraceText = rightBrace.getText(); + + if (leftBraceOffset == NON_OFFSET || + rightBraceOffset == NON_OFFSET) + return null; + + // try to get the text attr by element type + TextAttributesKey textAttributesKey = + HighlightBracketPairSettingsPage.getTextAttributesKeyByToken(leftBrace.getElementType()); + // if not found, get the text attr by brace text + if (textAttributesKey == null) { + textAttributesKey = HighlightBracketPairSettingsPage.getTextAttributesKeyByText(leftBraceText); + } + final TextAttributes textAttributes = editor.getColorsScheme().getAttributes(textAttributesKey); + + int openBraceLine = document.getLineNumber(leftBraceOffset); + RangeHighlighter openBraceHighlighter = renderBraceInGutter(openBraceLine, leftBraceText, textAttributes); + + int closeBraceLine = document.getLineNumber(rightBraceOffset); + RangeHighlighter closeBraceHighlighter = renderBraceInGutter(closeBraceLine, rightBraceText, textAttributes); + + List highlighters = new ArrayList(); + highlighters.add(openBraceHighlighter); + highlighters.add(closeBraceHighlighter); + + return highlighters; + } + + public RangeHighlighter renderBraceInGutter(int braceLine, String braceText, TextAttributes textAttributes) { + RangeHighlighter braceHighlighter = editor.getMarkupModel() + .addLineHighlighter(braceLine, HighlighterLayer.SELECTION, null); + + GutterIconRenderer braceGutterIconRenderer = new GutterIconRenderer() { + + @NotNull + @Override + public Icon getIcon() { + return new Icon() { + @Override + public void paintIcon(Component c, Graphics g, int x, int y) { + if (braceText.toString().toCharArray().length < 1) { + return; + } + + g.setColor(textAttributes.getForegroundColor()); + g.drawChars(braceText.toString().toCharArray(), 0, braceText.length(), 0, 0); + } + + @Override + public int getIconWidth() { + return 1; + } + + @Override + public int getIconHeight() { + return 1; + } + }; + } + + @Override + public boolean equals(Object obj) { + return false; + } + + @Override + public int hashCode() { + return 1; + } + }; + + braceHighlighter.setGutterIconRenderer(braceGutterIconRenderer); + braceHighlighter.setGreedyToRight(true); + + return braceHighlighter; + } + public Pair highlightPair(BracePair bracePair) { final Brace leftBrace = bracePair.getLeftBrace(); final Brace rightBrace = bracePair.getRightBrace();