Adjust indent synchronously on relatively small files
[idea/community.git] / platform / lang-impl / src / com / intellij / psi / impl / source / codeStyle / lineIndent / FormatterBasedIndentAdjuster.java
1 /*
2  * Copyright 2000-2016 JetBrains s.r.o.
3  *
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
7  *
8  * http://www.apache.org/licenses/LICENSE-2.0
9  *
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.
15  */
16 package com.intellij.psi.impl.source.codeStyle.lineIndent;
17
18 import com.intellij.openapi.application.ApplicationManager;
19 import com.intellij.openapi.command.CommandProcessor;
20 import com.intellij.openapi.editor.Document;
21 import com.intellij.openapi.project.Project;
22 import com.intellij.psi.PsiDocumentManager;
23 import com.intellij.psi.codeStyle.CodeStyleManager;
24 import org.jetbrains.annotations.NotNull;
25
26 public class FormatterBasedIndentAdjuster  {
27   
28   private final static int MAX_SYNCHRONOUS_ADJUSTMENT_DOC_SIZE = 100000;
29
30   private FormatterBasedIndentAdjuster() {
31   }
32
33   public static void scheduleIndentAdjustment(@NotNull Project myProject,
34                                               @NotNull Document myDocument,
35                                               int myOffset) {
36     IndentAdjusterRunnable fixer = new IndentAdjusterRunnable(myProject, myDocument, myOffset);
37     PsiDocumentManager documentManager = PsiDocumentManager.getInstance(myProject);
38     if (isSynchronousAdjustment(myDocument)) {
39       documentManager.commitDocument(myDocument);
40       fixer.run();
41     }
42     else {
43       documentManager.performLaterWhenAllCommitted(fixer);
44     }
45   }
46   
47   private static boolean isSynchronousAdjustment(@NotNull Document document) {
48     return ApplicationManager.getApplication().isUnitTestMode() || document.getTextLength() <= MAX_SYNCHRONOUS_ADJUSTMENT_DOC_SIZE;
49   }
50   
51   public static class IndentAdjusterRunnable implements Runnable {
52     private Project myProject;
53     private int myLine;
54     private Document myDocument;
55
56     public IndentAdjusterRunnable(Project project, Document document, int offset) {
57       myProject = project;
58       myDocument = document;
59       myLine = myDocument.getLineNumber(offset);
60     }
61
62     public void run() {
63       int lineStart = myDocument.getLineStartOffset(myLine);
64       CommandProcessor.getInstance().runUndoTransparentAction(() ->
65         ApplicationManager.getApplication().runWriteAction(() -> {
66           CodeStyleManager.getInstance(myProject).adjustLineIndent(myDocument, lineStart);
67         }));
68     }
69   }
70   
71 }