update copyrights
[fedora-idea.git] / platform / lang-impl / src / com / intellij / codeInsight / editorActions / enter / EnterAfterUnmatchedBraceHandler.java
blob1aaeabefc6f6407cd002680612a4218379946d76
1 /*
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);
62 try {
63 CodeStyleManager.getInstance(project).adjustLineIndent(file, offset + 1);
65 catch (IncorrectOperationException e) {
66 LOG.error(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)
84 ) {
85 return false;
88 Language language = iterator.getTokenType().getLanguage();
90 iterator = highlighter.createIterator(0);
91 int balance = 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)) {
97 balance++;
98 } else if (braceMatcher.isRBraceToken(iterator, chars, fileType)) {
99 balance--;
103 iterator.advance();
105 return balance > 0;