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
.enter
;
19 import com
.intellij
.codeInsight
.CodeInsightSettings
;
20 import com
.intellij
.codeInsight
.highlighting
.BraceMatcher
;
21 import com
.intellij
.codeInsight
.highlighting
.BraceMatchingUtil
;
22 import com
.intellij
.lang
.Language
;
23 import com
.intellij
.openapi
.actionSystem
.DataContext
;
24 import com
.intellij
.openapi
.diagnostic
.Logger
;
25 import com
.intellij
.openapi
.editor
.Document
;
26 import com
.intellij
.openapi
.editor
.Editor
;
27 import com
.intellij
.openapi
.editor
.actionSystem
.EditorActionHandler
;
28 import com
.intellij
.openapi
.editor
.ex
.EditorEx
;
29 import com
.intellij
.openapi
.editor
.highlighter
.EditorHighlighter
;
30 import com
.intellij
.openapi
.editor
.highlighter
.HighlighterIterator
;
31 import com
.intellij
.openapi
.fileTypes
.FileType
;
32 import com
.intellij
.openapi
.project
.Project
;
33 import com
.intellij
.openapi
.util
.Ref
;
34 import com
.intellij
.psi
.PsiDocumentManager
;
35 import com
.intellij
.psi
.PsiFile
;
36 import com
.intellij
.psi
.codeStyle
.CodeStyleManager
;
37 import com
.intellij
.psi
.tree
.IElementType
;
38 import com
.intellij
.util
.IncorrectOperationException
;
39 import com
.intellij
.util
.text
.CharArrayUtil
;
41 public class EnterAfterUnmatchedBraceHandler
implements EnterHandlerDelegate
{
42 private static final Logger LOG
= Logger
.getInstance("#com.intellij.codeInsight.editorActions.enter.EnterAfterUnmatchedBraceHandler");
44 public Result
preprocessEnter(final PsiFile file
, final Editor editor
, final Ref
<Integer
> caretOffsetRef
, final Ref
<Integer
> caretAdvance
,
45 final DataContext dataContext
, final EditorActionHandler originalHandler
) {
46 Document document
= editor
.getDocument();
47 CharSequence text
= document
.getText();
48 Project project
= file
.getProject();
49 int caretOffset
= caretOffsetRef
.get().intValue();
50 if (CodeInsightSettings
.getInstance().INSERT_BRACE_ON_ENTER
&& isAfterUnmatchedLBrace(editor
, caretOffset
, file
.getFileType())) {
51 int offset
= CharArrayUtil
.shiftForward(text
, caretOffset
, " \t");
52 if (offset
< document
.getTextLength()) {
53 char c
= text
.charAt(offset
);
54 if (c
!= ')' && c
!= ']' && c
!= ';' && c
!= ',' && c
!= '%' && c
!= '<') {
55 offset
= CharArrayUtil
.shiftForwardUntil(text
, caretOffset
, "\n");
58 offset
= Math
.min(offset
, document
.getTextLength());
60 document
.insertString(offset
, "\n}");
61 PsiDocumentManager
.getInstance(project
).commitDocument(document
);
63 CodeStyleManager
.getInstance(project
).adjustLineIndent(file
, offset
+ 1);
65 catch (IncorrectOperationException e
) {
68 return Result
.DefaultForceIndent
;
70 return Result
.Continue
;
73 public static boolean isAfterUnmatchedLBrace(Editor editor
, int offset
, FileType fileType
) {
74 if (offset
== 0) return false;
75 CharSequence chars
= editor
.getDocument().getCharsSequence();
76 if (chars
.charAt(offset
- 1) != '{') return false;
78 EditorHighlighter highlighter
= ((EditorEx
)editor
).getHighlighter();
79 HighlighterIterator iterator
= highlighter
.createIterator(offset
- 1);
80 BraceMatcher braceMatcher
= BraceMatchingUtil
.getBraceMatcher(fileType
, iterator
);
82 if (!braceMatcher
.isLBraceToken(iterator
, chars
, fileType
) ||
83 !braceMatcher
.isStructuralBrace(iterator
, chars
, fileType
)
88 Language language
= iterator
.getTokenType().getLanguage();
90 iterator
= highlighter
.createIterator(0);
92 while (!iterator
.atEnd()) {
93 IElementType tokenType
= iterator
.getTokenType();
94 if (tokenType
.getLanguage().equals(language
)) {
95 if (braceMatcher
.isStructuralBrace(iterator
, chars
, fileType
)) {
96 if (braceMatcher
.isLBraceToken(iterator
, chars
, fileType
)) {
98 } else if (braceMatcher
.isRBraceToken(iterator
, chars
, fileType
)) {