2 * Copyright 2000-2009 JetBrains s.r.o.
4 * Licensed under the Apache License, Version 2.0 (the "License");
5 * you may not use this file except in compliance with the License.
6 * You may obtain a copy of the License at
8 * http://www.apache.org/licenses/LICENSE-2.0
10 * Unless required by applicable law or agreed to in writing, software
11 * distributed under the License is distributed on an "AS IS" BASIS,
12 * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
13 * See the License for the specific language governing permissions and
14 * limitations under the License.
17 package com
.intellij
.codeInsight
.editorActions
;
19 import com
.intellij
.codeInsight
.highlighting
.BraceMatcher
;
20 import com
.intellij
.codeInsight
.highlighting
.BraceMatchingUtil
;
21 import com
.intellij
.openapi
.editor
.Editor
;
22 import com
.intellij
.openapi
.editor
.ex
.EditorEx
;
23 import com
.intellij
.openapi
.editor
.highlighter
.HighlighterIterator
;
24 import com
.intellij
.openapi
.fileTypes
.FileType
;
25 import com
.intellij
.openapi
.util
.Pair
;
26 import com
.intellij
.openapi
.util
.TextRange
;
27 import com
.intellij
.openapi
.vfs
.VirtualFile
;
28 import com
.intellij
.psi
.PsiElement
;
29 import com
.intellij
.psi
.tree
.IElementType
;
31 import java
.util
.ArrayList
;
32 import java
.util
.LinkedList
;
33 import java
.util
.List
;
36 * @author Gregory.Shrago
38 public abstract class BraceMatcherBasedSelectioner
extends ExtendWordSelectionHandlerBase
{
40 public List
<TextRange
> select(final PsiElement e
, final CharSequence editorText
, final int cursorOffset
, final Editor editor
) {
41 final VirtualFile file
= e
.getContainingFile().getVirtualFile();
42 final FileType fileType
= file
== null?
null : file
.getFileType();
43 if (fileType
== null) return super.select(e
, editorText
, cursorOffset
, editor
);
44 final TextRange totalRange
= e
.getTextRange();
45 final HighlighterIterator iterator
= ((EditorEx
)editor
).getHighlighter().createIterator(totalRange
.getStartOffset());
46 final BraceMatcher braceMatcher
= BraceMatchingUtil
.getBraceMatcher(fileType
, iterator
);
48 final ArrayList
<TextRange
> result
= new ArrayList
<TextRange
>();
49 final LinkedList
<Pair
<Integer
, IElementType
>> stack
= new LinkedList
<Pair
<Integer
, IElementType
>>();
50 while (!iterator
.atEnd() && iterator
.getStart() < totalRange
.getEndOffset()) {
51 final Pair
<Integer
, IElementType
> last
;
52 if (braceMatcher
.isLBraceToken(iterator
, editorText
, fileType
)) {
53 stack
.addLast(Pair
.create(iterator
.getStart(), iterator
.getTokenType()));
55 else if (braceMatcher
.isRBraceToken(iterator
, editorText
, fileType
)
56 && !stack
.isEmpty() && braceMatcher
.isPairBraces((last
= stack
.getLast()).second
, iterator
.getTokenType())) {
58 final int start
= last
.first
;
59 result
.addAll(expandToWholeLine(editorText
, new TextRange(start
, iterator
.getEnd())));
60 int bodyStart
= start
+ 1;
61 int bodyEnd
= iterator
.getEnd() - 1;
62 while (Character
.isWhitespace(editorText
.charAt(bodyStart
))) bodyStart
++;
63 while (Character
.isWhitespace(editorText
.charAt(bodyEnd
- 1))) bodyEnd
--;
64 result
.addAll(expandToWholeLine(editorText
, new TextRange(bodyStart
, bodyEnd
)));
68 result
.add(e
.getTextRange());