From f01fbec05c3e6d1d6cc3d0e4fd06bad72c66c9c0 Mon Sep 17 00:00:00 2001 From: Dennis Ushakov Date: Fri, 25 Sep 2015 14:15:40 +0300 Subject: [PATCH] use brace highlighter for navigation #WEB-18200 fixed #WEB-18201 fixed #IDEA-111328 fixed #IDEA-12068 fixed --- .../editorActions/MatchBraceAction.java | 74 ++++++++++--------- 1 file changed, 41 insertions(+), 33 deletions(-) diff --git a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/MatchBraceAction.java b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/MatchBraceAction.java index 0f19120e39f0..4b8be89d0cec 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/editorActions/MatchBraceAction.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/editorActions/MatchBraceAction.java @@ -15,24 +15,25 @@ */ package com.intellij.codeInsight.editorActions; +import com.intellij.codeInsight.highlighting.BraceMatchingUtil; import com.intellij.openapi.actionSystem.CommonDataKeys; import com.intellij.openapi.actionSystem.DataContext; -import com.intellij.openapi.editor.CaretModel; +import com.intellij.openapi.editor.Caret; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.actionSystem.EditorAction; import com.intellij.openapi.editor.actionSystem.EditorActionHandler; -import com.intellij.openapi.project.Project; -import gnu.trove.TIntHashSet; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.highlighter.EditorHighlighter; +import com.intellij.openapi.editor.highlighter.HighlighterIterator; +import com.intellij.openapi.fileTypes.FileType; +import com.intellij.psi.PsiFile; +import com.intellij.psi.util.PsiUtilBase; /** * @author Denis Zhdanov * @since 10/24/12 11:10 AM */ public class MatchBraceAction extends EditorAction { - - private static final TIntHashSet OPEN_BRACES = new TIntHashSet(new int[] { '(', '[', '{', '<' }); - private static final TIntHashSet CLOSE_BRACES = new TIntHashSet(new int[] { ')', ']', '}', '>' }); - public MatchBraceAction() { super(new MyHandler()); } @@ -42,37 +43,44 @@ public class MatchBraceAction extends EditorAction { super(true); } - @Override public void execute(Editor editor, DataContext dataContext) { - Project project = CommonDataKeys.PROJECT.getData(dataContext); - if (project == null) { - return; + final PsiFile file = CommonDataKeys.PSI_FILE.getData(dataContext); + if (file == null) return; + + final Caret caret = editor.getCaretModel().getCurrentCaret(); + final EditorHighlighter highlighter = ((EditorEx)editor).getHighlighter(); + final CharSequence text = editor.getDocument().getCharsSequence(); + int offset = caret.getOffset(); + final FileType fileType = PsiUtilBase.getPsiFileAtOffset(file, offset).getFileType(); + + HighlighterIterator iterator = highlighter.createIterator(offset); + + if (iterator.atEnd() || BraceMatchingUtil.isRBraceToken(iterator, text, fileType)) { + offset--; + } + else if (!BraceMatchingUtil.isLBraceToken(iterator, text, fileType)) { + offset--; + + if (offset >= 0) { + final HighlighterIterator i = highlighter.createIterator(offset); + if (!BraceMatchingUtil.isRBraceToken(i, text, PsiUtilBase.getPsiFileAtOffset(file, i.getStart()).getFileType())) offset++; + } } - CaretModel caretModel = editor.getCaretModel(); - int offset = caretModel.getOffset(); - CharSequence text = editor.getDocument().getCharsSequence(); - char c = text.charAt(offset); - if (!OPEN_BRACES.contains(c) && !CLOSE_BRACES.contains(c)) { - boolean canContinue = false; - for (offset--; offset >= 0; offset--) { - c = text.charAt(offset); - if (OPEN_BRACES.contains(c) || CLOSE_BRACES.contains(c)) { - canContinue = true; - caretModel.moveToOffset(offset); - break; - } - } - if (!canContinue) { - return; - } + iterator = highlighter.createIterator(offset); + while (!BraceMatchingUtil.isLBraceToken(iterator, text, fileType) && + !BraceMatchingUtil.isRBraceToken(iterator, text, fileType)) { + iterator.retreat(); + offset = iterator.getStart(); } - - if (OPEN_BRACES.contains(c)) { - CodeBlockUtil.moveCaretToCodeBlockEnd(project, editor, false); + + if (BraceMatchingUtil.matchBrace(text, fileType, iterator, true)) { + caret.moveToOffset(iterator.getEnd()); + return; } - else if (CLOSE_BRACES.contains(c)) { - CodeBlockUtil.moveCaretToCodeBlockStart(project, editor, false); + iterator = highlighter.createIterator(offset); + if (BraceMatchingUtil.matchBrace(text, fileType, iterator, false)) { + caret.moveToOffset(iterator.getStart()); } } }