Java 类com.intellij.openapi.editor.ex.FoldingModelEx 实例源码

项目:intellij-ce-playground    文件:FoldingModelSupport.java   
public void expandAll(final boolean expanded) {
  if (myDuringSynchronize) return;
  myDuringSynchronize = true;
  try {
    for (int i = 0; i < myCount; i++) {
      final int index = i;
      final FoldingModelEx model = myEditors[index].getFoldingModel();
      model.runBatchFoldingOperation(new Runnable() {
        @Override
        public void run() {
          for (FoldedBlock folding : getFoldedBlocks()) {
            FoldRegion region = folding.getRegion(index);
            if (region != null) region.setExpanded(expanded);
          }
        }
      });
    }
  }
  finally {
    myDuringSynchronize = false;
  }
}
项目:intellij-ce-playground    文件:UpdateFoldRegionsOperation.java   
@Override
public void run() {
  EditorFoldingInfo info = EditorFoldingInfo.get(myEditor);
  FoldingModelEx foldingModel = (FoldingModelEx)myEditor.getFoldingModel();
  Map<TextRange,Boolean> rangeToExpandStatusMap = newTroveMap();

  // FoldingUpdate caches instances of our object, so they must be immutable.
  FoldingUpdate.FoldingMap elementsToFold = new FoldingUpdate.FoldingMap(myElementsToFoldMap); 

  removeInvalidRegions(info, foldingModel, elementsToFold, rangeToExpandStatusMap);

  Map<FoldRegion, Boolean> shouldExpand = newTroveMap();
  Map<FoldingGroup, Boolean> groupExpand = newTroveMap();
  List<FoldRegion> newRegions = addNewRegions(info, foldingModel, elementsToFold, rangeToExpandStatusMap, shouldExpand, groupExpand);

  applyExpandStatus(newRegions, shouldExpand, groupExpand);
}
项目:intellij-ce-playground    文件:CollapseSelectionHandler.java   
public static boolean isEnabled(@NotNull Editor editor) {
  if (editor.getSelectionModel().hasSelection()) {
    int start = editor.getSelectionModel().getSelectionStart();
    int end = editor.getSelectionModel().getSelectionEnd();
    if (start + 1 >= end) {
      return false;
    }
    if (start < end && editor.getDocument().getCharsSequence().charAt(end - 1) == '\n') end--;
    FoldRegion region = FoldingUtil.findFoldRegion(editor, start, end);
    if (region == null) {
      return !((FoldingModelEx) editor.getFoldingModel()).intersectsRegion(start, end); 
    } else {
      return EditorFoldingInfo.get(editor).getPsiElement(region) == null;
    }
  } else {
    return FoldingUtil.getFoldRegionsAtOffset(editor, editor.getCaretModel().getOffset()).length > 0;
  }
}
项目:consulo    文件:FoldingModelSupport.java   
public void expandAll(final boolean expanded) {
  if (myDuringSynchronize) return;
  myDuringSynchronize = true;
  try {
    for (int i = 0; i < myCount; i++) {
      final int index = i;
      final FoldingModelEx model = myEditors[index].getFoldingModel();
      model.runBatchFoldingOperation(new Runnable() {
        @Override
        public void run() {
          for (FoldedBlock folding : getFoldedBlocks()) {
            FoldRegion region = folding.getRegion(index);
            if (region != null) region.setExpanded(expanded);
          }
        }
      });
    }
  }
  finally {
    myDuringSynchronize = false;
  }
}
项目:consulo    文件:UpdateFoldRegionsOperation.java   
@Override
public void run() {
  EditorFoldingInfo info = EditorFoldingInfo.get(myEditor);
  FoldingModelEx foldingModel = (FoldingModelEx)myEditor.getFoldingModel();
  Map<TextRange,Boolean> rangeToExpandStatusMap = new THashMap<>();

  removeInvalidRegions(info, foldingModel, rangeToExpandStatusMap);

  Map<FoldRegion, Boolean> shouldExpand = new THashMap<>();
  Map<FoldingGroup, Boolean> groupExpand = new THashMap<>();
  List<FoldRegion> newRegions = addNewRegions(info, foldingModel, rangeToExpandStatusMap, shouldExpand, groupExpand);

  applyExpandStatus(newRegions, shouldExpand, groupExpand);

  foldingModel.clearDocumentRangesModificationStatus();
}
项目:intellij-ce-playground    文件:JavaFoldingGotoTest.java   
public void testIDEA127145() {
  PsiFile file = myFixture.addFileToProject("Program.java",
                                            "import java.io.InputStream;\n" +
                                            "import java.util.HashMap;\n" +
                                            "import java.util.Map;\n" +
                                            "\n" +
                                            "class Program {\n" +
                                            "  private static InputStream getFile(String name, Map<String, Object> args) {\n" +
                                            "    return Program.class.getResourceAsStream(name);\n" +
                                            "  }\n" +
                                            "\n" +
                                            "  public static void main(String[] args) {\n" +
                                            "    // Ctrl + B or Ctrl + Left Mouse Button work correctly for following string:\n" +
                                            "    final String name = \"file.sql\";\n" +
                                            "    // But it jumps only to folder in following case:\n" +
                                            "    final InputStream inputStream = getFile(\"dir/fil<caret>e.sql\", new HashMap<String, Object>());\n" +
                                            "  }\n" +
                                            "}");

  PsiFile fileSql = myFixture.addFileToProject("dir/file.sql", "select 1;");
  myFixture.configureFromExistingVirtualFile(file.getVirtualFile());

  Editor editor = myFixture.getEditor();
  CodeFoldingManager.getInstance(getProject()).buildInitialFoldings(editor);
  FoldingModelEx foldingModel = (FoldingModelEx)editor.getFoldingModel();
  foldingModel.rebuild();
  myFixture.doHighlighting();

  PsiElement element = GotoDeclarationAction.findTargetElement(getProject(), editor, editor.getCaretModel().getOffset());
  assertTrue("Should navigate to: file.sql instead of " + element, element != null && element.equals(fileSql));
}
项目:intellij-ce-playground    文件:FoldingModelSupport.java   
private void destroyFoldings(final int index) {
  final FoldingModelEx model = myEditors[index].getFoldingModel();
  model.runBatchFoldingOperation(new Runnable() {
    @Override
    public void run() {
      for (FoldedBlock folding : getFoldedBlocks()) {
        FoldRegion region = folding.getRegion(index);
        if (region != null) model.removeFoldRegion(region);
      }
    }
  });
}
项目:intellij-ce-playground    文件:CaretImpl.java   
@Override
public int getLeadSelectionOffset() {
  validateContext(false);
  int caretOffset = getOffset();
  if (hasSelection()) {
    RangeMarker marker = mySelectionMarker;
    if (marker != null) {
      int startOffset = marker.getStartOffset();
      int endOffset = marker.getEndOffset();
      if (caretOffset != startOffset && caretOffset != endOffset) {
        // Try to check if current selection is tweaked by fold region.
        FoldingModelEx foldingModel = myEditor.getFoldingModel();
        FoldRegion foldRegion = foldingModel.getCollapsedRegionAtOffset(caretOffset);
        if (foldRegion != null) {
          if (foldRegion.getStartOffset() == startOffset) {
            return endOffset;
          }
          else if (foldRegion.getEndOffset() == endOffset) {
            return startOffset;
          }
        }
      }

      if (caretOffset == endOffset) {
        return startOffset;
      }
      else {
        return endOffset;
      }
    }
  }
  return caretOffset;
}
项目:intellij-ce-playground    文件:FoldingTest.java   
@Override
public void setUp() throws Exception {
  super.setUp();
  init("I don't know what you mean by `glory,'\" Alice said" +
    "Humpty Dumpty smiled contemptuously. \"Of course you don't -- till I tell you. I meant `there's a nice knock-down argument for you!'" +
    "But glory doesn't mean `a nice knock-down argument,'\" Alice objected." +
    "When I use a word,\" Humpty Dumpty said, in a rather scornful tone, \"it means just what I choose it to mean -- neither more nor less." +
    "The question is,\" said Alice, \"whether you can make words mean so many different things." +
    "The question is,\" said Humpty Dumpty, \"which is to be master -- that's all.",
       TestFileType.TEXT);
  myModel = (FoldingModelEx)myEditor.getFoldingModel();
}
项目:intellij-ce-playground    文件:CodeFoldingManagerImpl.java   
@Override
public void buildInitialFoldings(@NotNull final Editor editor) {
  final Project project = editor.getProject();
  if (project == null || !project.equals(myProject) || editor.isDisposed()) return;
  if (!((FoldingModelEx)editor.getFoldingModel()).isFoldingEnabled()) return;
  if (!FoldingUpdate.supportsDumbModeFolding(editor)) return;

  Document document = editor.getDocument();
  PsiDocumentManager.getInstance(myProject).commitDocument(document);
  CodeFoldingState foldingState = buildInitialFoldings(document);
  if (foldingState != null) {
    foldingState.setToEditor(editor);
  }
}
项目:intellij-ce-playground    文件:CodeFoldingManagerImpl.java   
@Nullable
@Override
public CodeFoldingState buildInitialFoldings(@NotNull final Document document) {
  if (myProject.isDisposed()) {
    return null;
  }
  ApplicationManager.getApplication().assertReadAccessAllowed();
  PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(myProject);
  if (psiDocumentManager.isUncommited(document)) {
    // skip building foldings for uncommitted document, CodeFoldingPass invoked by daemon will do it later
    return null;
  }
  //Do not save/restore folding for code fragments
  final PsiFile file = psiDocumentManager.getPsiFile(document);
  if (file == null || !file.isValid() || !file.getViewProvider().isPhysical() && !ApplicationManager.getApplication().isUnitTestMode()) {
    return null;
  }


  final FoldingUpdate.FoldingMap foldingMap = FoldingUpdate.getFoldingsFor(file, document, true);

  return new CodeFoldingState() {
    @Override
    public void setToEditor(@NotNull final Editor editor) {
      ApplicationManagerEx.getApplicationEx().assertIsDispatchThread();
      if (myProject.isDisposed() || editor.isDisposed()) return;
      final FoldingModelEx foldingModel = (FoldingModelEx)editor.getFoldingModel();
      if (!foldingModel.isFoldingEnabled()) return;
      if (isFoldingsInitializedInEditor(editor)) return;
      if (DumbService.isDumb(myProject) && !FoldingUpdate.supportsDumbModeFolding(editor)) return;

      foldingModel.runBatchFoldingOperationDoNotCollapseCaret(new UpdateFoldRegionsOperation(myProject, editor, file, foldingMap, YES, false));
      initFolding(editor);
    }
  };
}
项目:tools-idea    文件:SelectionModelImpl.java   
@Override
public int getLeadSelectionOffset() {
  validateContext(false);
  int caretOffset = myEditor.getCaretModel().getOffset();
  if (hasSelection()) {
    MyRangeMarker marker = mySelectionMarker;
    if (marker != null) {
      int startOffset = marker.getStartOffset();
      int endOffset = marker.getEndOffset();
      if (caretOffset != startOffset && caretOffset != endOffset) {
        // Try to check if current selection is tweaked by fold region.
        FoldingModelEx foldingModel = myEditor.getFoldingModel();
        FoldRegion foldRegion = foldingModel.getCollapsedRegionAtOffset(caretOffset);
        if (foldRegion != null) {
          if (foldRegion.getStartOffset() == startOffset) {
            return endOffset;
          }
          else if (foldRegion.getEndOffset() == endOffset) {
            return startOffset;
          }
        }
      }

      if (caretOffset == endOffset) {
        return startOffset;
      }
      else {
        return endOffset;
      }
    }
  }
  return caretOffset;
}
项目:tools-idea    文件:UpdateFoldRegionsOperation.java   
@Override
public void run() {
  EditorFoldingInfo info = EditorFoldingInfo.get(myEditor);
  FoldingModelEx foldingModel = (FoldingModelEx)myEditor.getFoldingModel();
  Map<TextRange,Boolean> rangeToExpandStatusMap = newTroveMap();

  removeInvalidRegions(info, foldingModel, rangeToExpandStatusMap);

  Map<FoldRegion, Boolean> shouldExpand = newTroveMap();
  Map<FoldingGroup, Boolean> groupExpand = newTroveMap();
  List<FoldRegion> newRegions = addNewRegions(info, foldingModel, rangeToExpandStatusMap, shouldExpand, groupExpand);

  applyExpandStatus(newRegions, shouldExpand, groupExpand);
}
项目:tools-idea    文件:EditorFoldingInfo.java   
public static void resetInfo(@NotNull Editor editor) {
  EditorFoldingInfo info = editor.getUserData(KEY);
  if (info != null) {
    info.dispose();
  }
  FoldingModel foldingModel = editor.getFoldingModel();
  if (foldingModel instanceof FoldingModelEx) {
    ((FoldingModelEx)foldingModel).rebuild();
  }
  editor.putUserData(KEY, null);
}
项目:consulo    文件:FoldingModelSupport.java   
private void destroyFoldings(final int index) {
  final FoldingModelEx model = myEditors[index].getFoldingModel();
  model.runBatchFoldingOperation(new Runnable() {
    @Override
    public void run() {
      for (FoldedBlock folding : getFoldedBlocks()) {
        FoldRegion region = folding.getRegion(index);
        if (region != null) model.removeFoldRegion(region);
      }
    }
  });
}
项目:consulo    文件:FoldingTest.java   
@Override
public void setUp() throws Exception {
  super.setUp();
  init("I don't know what you mean by `glory,'\" Alice said" +
       "Humpty Dumpty smiled contemptuously. \"Of course you don't -- till I tell you. I meant `there's a nice knock-down argument for you!'" +
       "But glory doesn't mean `a nice knock-down argument,'\" Alice objected." +
       "When I use a word,\" Humpty Dumpty said, in a rather scornful tone, \"it means just what I choose it to mean -- neither more nor less." +
       "The question is,\" said Alice, \"whether you can make words mean so many different things." +
       "The question is,\" said Humpty Dumpty, \"which is to be master -- that's all.",
       TestFileType.TEXT);
  myModel = (FoldingModelEx)myEditor.getFoldingModel();
}
项目:consulo    文件:VisualLineFragmentsIterator.java   
private void init(EditorView view, int startOffset, int startLogicalLine, int currentOrPrevWrapIndex, int nextFoldingIndex,
                  @Nullable Runnable quickEvaluationListener) {
  myQuickEvaluationListener = quickEvaluationListener;
  myView = view;
  EditorImpl editor = view.getEditor();
  myDocument = editor.getDocument();
  FoldingModelEx foldingModel = editor.getFoldingModel();
  FoldRegion[] regions = foldingModel.fetchTopLevel();
  myRegions = regions == null ? FoldRegion.EMPTY_ARRAY : regions;
  SoftWrapModelImpl softWrapModel = editor.getSoftWrapModel();
  List<? extends SoftWrap> softWraps = softWrapModel.getRegisteredSoftWraps();
  SoftWrap currentOrPrevWrap = currentOrPrevWrapIndex < 0 || currentOrPrevWrapIndex >= softWraps.size() ? null :
                               softWraps.get(currentOrPrevWrapIndex);
  SoftWrap followingWrap = (currentOrPrevWrapIndex + 1) < 0 || (currentOrPrevWrapIndex + 1) >= softWraps.size() ? null :
                           softWraps.get(currentOrPrevWrapIndex + 1);

  myVisualLineStartOffset = mySegmentStartOffset = startOffset;

  myCurrentFoldRegionIndex = nextFoldingIndex;
  myCurrentEndLogicalLine = startLogicalLine;
  myCurrentX = myView.getInsets().left;
  if (mySegmentStartOffset == 0) {
    myCurrentX += myView.getPrefixTextWidthInPixels();
  }
  else if (currentOrPrevWrap != null && mySegmentStartOffset == currentOrPrevWrap.getStart()) {
    myCurrentX += currentOrPrevWrap.getIndentInPixels();
    myCurrentVisualColumn = currentOrPrevWrap.getIndentInColumns();
  }
  myNextWrapOffset = followingWrap == null ? Integer.MAX_VALUE : followingWrap.getStart();
  setInlaysAndFragmentIterator();
}
项目:consulo    文件:CaretImpl.java   
@Override
public int getLeadSelectionOffset() {
  validateContext(false);
  int caretOffset = getOffset();
  if (hasSelection()) {
    RangeMarker marker = mySelectionMarker;
    if (marker != null && marker.isValid()) {
      int startOffset = marker.getStartOffset();
      int endOffset = marker.getEndOffset();
      if (caretOffset != startOffset && caretOffset != endOffset) {
        // Try to check if current selection is tweaked by fold region.
        FoldingModelEx foldingModel = myEditor.getFoldingModel();
        FoldRegion foldRegion = foldingModel.getCollapsedRegionAtOffset(caretOffset);
        if (foldRegion != null) {
          if (foldRegion.getStartOffset() == startOffset) {
            return endOffset;
          }
          else if (foldRegion.getEndOffset() == endOffset) {
            return startOffset;
          }
        }
      }

      if (caretOffset == endOffset) {
        return startOffset;
      }
      else {
        return endOffset;
      }
    }
  }
  return caretOffset;
}
项目:consulo    文件:CodeFoldingManagerImpl.java   
@Override
public void buildInitialFoldings(@Nonnull final Editor editor) {
  final Project project = editor.getProject();
  if (project == null || !project.equals(myProject) || editor.isDisposed()) return;
  if (!((FoldingModelEx)editor.getFoldingModel()).isFoldingEnabled()) return;
  if (!FoldingUpdate.supportsDumbModeFolding(editor)) return;

  Document document = editor.getDocument();
  PsiDocumentManager.getInstance(myProject).commitDocument(document);
  CodeFoldingState foldingState = buildInitialFoldings(document);
  if (foldingState != null) {
    foldingState.setToEditor(editor);
  }
}
项目:consulo    文件:CodeFoldingManagerImpl.java   
@Nullable
@Override
public CodeFoldingState buildInitialFoldings(@Nonnull final Document document) {
  if (myProject.isDisposed()) {
    return null;
  }
  ApplicationManager.getApplication().assertReadAccessAllowed();
  PsiDocumentManager psiDocumentManager = PsiDocumentManager.getInstance(myProject);
  if (psiDocumentManager.isUncommited(document)) {
    // skip building foldings for uncommitted document, CodeFoldingPass invoked by daemon will do it later
    return null;
  }
  //Do not save/restore folding for code fragments
  final PsiFile file = psiDocumentManager.getPsiFile(document);
  if (file == null || !file.isValid() || !file.getViewProvider().isPhysical() && !ApplicationManager.getApplication().isUnitTestMode()) {
    return null;
  }


  final List<FoldingUpdate.RegionInfo> regionInfos = FoldingUpdate.getFoldingsFor(file, document, true);

  return editor -> {
    ApplicationManagerEx.getApplicationEx().assertIsDispatchThread();
    if (myProject.isDisposed() || editor.isDisposed()) return;
    final FoldingModelEx foldingModel = (FoldingModelEx)editor.getFoldingModel();
    if (!foldingModel.isFoldingEnabled()) return;
    if (isFoldingsInitializedInEditor(editor)) return;
    if (DumbService.isDumb(myProject) && !FoldingUpdate.supportsDumbModeFolding(editor)) return;

    foldingModel.runBatchFoldingOperationDoNotCollapseCaret(new UpdateFoldRegionsOperation(myProject, editor, file, regionInfos,
                                                                                           UpdateFoldRegionsOperation.ApplyDefaultStateMode.YES,
                                                                                           false, false));
    initFolding(editor);
  };
}
项目:intellij-ce-playground    文件:CollapseBlockHandler.java   
@Override
public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file) {
  editor.getFoldingModel().runBatchFoldingOperation(new Runnable() {
    @Override
    public void run() {
      final EditorFoldingInfo info = EditorFoldingInfo.get(editor);
      FoldingModelEx model = (FoldingModelEx) editor.getFoldingModel();
      PsiElement element = file.findElementAt(editor.getCaretModel().getOffset() - 1);
      if (!(element instanceof PsiJavaToken) || ((PsiJavaToken) element).getTokenType() != JavaTokenType.RBRACE) {
        element = file.findElementAt(editor.getCaretModel().getOffset());
      }
      if (element == null) return;
      PsiCodeBlock block = PsiTreeUtil.getParentOfType(element, PsiCodeBlock.class);
      FoldRegion previous = null;
      FoldRegion myPrevious = null;
      while (block != null) {
        int start = block.getTextRange().getStartOffset();
        int end = block.getTextRange().getEndOffset();
        FoldRegion existing = FoldingUtil.findFoldRegion(editor, start, end);
        if (existing != null) {
          if (existing.isExpanded()) {
            existing.setExpanded(false);
            editor.getCaretModel().moveToOffset(existing.getEndOffset());
            return;
          }
          previous = existing;
          if (info.getPsiElement(existing) == null) myPrevious = existing;
          block = PsiTreeUtil.getParentOfType(block, PsiCodeBlock.class);
          continue;
        }
        if (!model.intersectsRegion(start, end)) {
          FoldRegion region = model.addFoldRegion(start, end, ourPlaceHolderText);
          LOG.assertTrue(region != null);
          region.setExpanded(false);
          if (myPrevious != null && info.getPsiElement(region) == null) {
            info.removeRegion(myPrevious);
            model.removeFoldRegion(myPrevious);
          }
          int offset = block.getTextRange().getEndOffset() < editor.getCaretModel().getOffset() ?
              start : end;
          editor.getCaretModel().moveToOffset(offset);
          return;
        } else break;
      }
      if (previous != null) {
        previous.setExpanded(false);
        if (myPrevious != null) {
          info.removeRegion(myPrevious);
          model.removeFoldRegion(myPrevious);
        }
        editor.getCaretModel().moveToOffset(previous.getEndOffset());
      }
    }
  });
}
项目:intellij-ce-playground    文件:DocumentFragmentTooltipRenderer.java   
@Override
public LightweightHint show(@NotNull final Editor editor, @NotNull Point p, boolean alignToRight, @NotNull TooltipGroup group, @NotNull HintHint intInfo) {
  LightweightHint hint;

  final JComponent editorComponent = editor.getComponent();

  TextRange range = myDocumentFragment.getTextRange();
  int startOffset = range.getStartOffset();
  int endOffset = range.getEndOffset();
  Document doc = myDocumentFragment.getDocument();
  int endLine = doc.getLineNumber(endOffset);
  int startLine = doc.getLineNumber(startOffset);

  JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane();

  // There is a possible case that collapsed folding region is soft wrapped, hence, we need to anchor
  // not logical but visual line start.
  VisualPosition visual = editor.offsetToVisualPosition(startOffset);
  p = editor.visualPositionToXY(visual);
  p = SwingUtilities.convertPoint(
    ((EditorEx)editor).getGutterComponentEx(),
    p,
    layeredPane
  );

  p.x -= 3;
  p.y += editor.getLineHeight();

  Point screenPoint = new Point(p);
  SwingUtilities.convertPointToScreen(screenPoint, layeredPane);
  int maxLineCount = (ScreenUtil.getScreenRectangle(screenPoint).height - screenPoint.y) / editor.getLineHeight();

  if (endLine - startLine > maxLineCount) {
    endOffset = doc.getLineEndOffset(Math.max(0, Math.min(startLine + maxLineCount, doc.getLineCount() - 1)));
  }
  if (endOffset < startOffset) return null;

  FoldingModelEx foldingModel = (FoldingModelEx)editor.getFoldingModel();
  foldingModel.setFoldingEnabled(false);
  TextRange textRange = new TextRange(startOffset, endOffset);
  hint = EditorFragmentComponent.showEditorFragmentHintAt(editor, textRange, p.y, false, false, true, true, true);
  foldingModel.setFoldingEnabled(true);
  return hint;
}
项目:intellij-ce-playground    文件:VisualLineFragmentsIterator.java   
private VisualLineFragmentsIterator(EditorView view, int offset, boolean beforeSoftWrap, @Nullable Runnable quickEvaluationListener) {
  myQuickEvaluationListener = quickEvaluationListener;
  myView = view;
  EditorImpl editor = view.getEditor();
  myDocument = editor.getDocument();
  FoldingModelEx foldingModel = editor.getFoldingModel();
  FoldRegion[] regions = foldingModel.fetchTopLevel();
  myRegions = regions == null ? FoldRegion.EMPTY_ARRAY : regions;
  int visualLineStartOffset = EditorUtil.getNotFoldedLineStartOffset(editor, offset);

  SoftWrapModelImpl softWrapModel = editor.getSoftWrapModel();
  List<? extends SoftWrap> softWraps = softWrapModel.getRegisteredSoftWraps();
  int currentOrPrevWrapIndex = softWrapModel.getSoftWrapIndex(offset);
  if (currentOrPrevWrapIndex < 0) {
    currentOrPrevWrapIndex = - currentOrPrevWrapIndex - 2;
  }
  else if (beforeSoftWrap) {
    currentOrPrevWrapIndex--;
  }
  SoftWrap currentOrPrevWrap = currentOrPrevWrapIndex < 0 || currentOrPrevWrapIndex >= softWraps.size() ? null :
                               softWraps.get(currentOrPrevWrapIndex);
  SoftWrap followingWrap = (currentOrPrevWrapIndex + 1) >= softWraps.size() ? null : softWraps.get(currentOrPrevWrapIndex + 1);

  if (currentOrPrevWrap != null && currentOrPrevWrap.getStart() > visualLineStartOffset) {
    visualLineStartOffset = currentOrPrevWrap.getStart();
  }

  myVisualLineStartOffset = mySegmentStartOffset = visualLineStartOffset;

  myCurrentFoldRegionIndex = foldingModel.getLastCollapsedRegionBefore(mySegmentStartOffset) + 1;
  myCurrentEndLogicalLine = myDocument.getLineNumber(mySegmentStartOffset);
  if (mySegmentStartOffset == 0) {
    myCurrentX = myView.getPrefixTextWidthInPixels();
  }
  else if (currentOrPrevWrap != null && mySegmentStartOffset == currentOrPrevWrap.getStart()) {
    myCurrentX = currentOrPrevWrap.getIndentInPixels();
    myCurrentVisualColumn = currentOrPrevWrap.getIndentInColumns();
  }
  myNextWrapOffset = followingWrap == null ? Integer.MAX_VALUE : followingWrap.getStart();
  setFragmentIterator();
}
项目:intellij-ce-playground    文件:CachingSoftWrapDataMapper.java   
private <T> T calculate(@NotNull MappingStrategy<T> strategy) throws IllegalStateException {
  T eagerMatch = strategy.eagerMatch();
  if (eagerMatch != null) {
    return eagerMatch;
  }

  EditorPosition position = strategy.buildInitialPosition();

  // Folding model doesn't return information about fold regions if their 'enabled' state is set to 'false'. Unfortunately,
  // such situation occurs not only on manual folding disabling but on internal processing as well. E.g. 'enabled' is set
  // to 'false' during fold preview representation. So, we set it to 'true' in order to retrieve fold regions and restore
  // to previous state after that.
  FoldingModelEx foldingModel = myEditor.getFoldingModel();
  boolean foldingState = foldingModel.isFoldingEnabled();
  foldingModel.setFoldingEnabled(true);
  CompositeDataProvider provider;
  try {
    provider = new CompositeDataProvider(
      new SoftWrapsDataProvider(myStorage), new FoldingDataProvider(myEditor.getFoldingModel().fetchTopLevel()),
      getTabulationDataProvider(position.visualLine)
    );
  }
  finally {
    foldingModel.setFoldingEnabled(foldingState);
  }
  provider.advance(position.offset);

  while (provider.hasData()) {
    Pair<SoftWrapDataProviderKeys, ?> data = provider.getData();
    T result = null;
    int sortingKey = provider.getSortingKey();

    // There is a possible case that, say, fold region is soft wrapped. We don't want to perform unnecessary then.
    if (position.offset <= sortingKey) {
      result = strategy.advance(position, sortingKey);
      if (result != null) {
        return result;
      }
    }

    switch (data.first) {
      case SOFT_WRAP: result = strategy.processSoftWrap(position, (SoftWrap)data.second); break;
      case COLLAPSED_FOLDING: result = strategy.processFoldRegion(position, (FoldRegion)data.second); break;
      case TABULATION: result = strategy.processTabulation(position, (TabData)data.second); break;
    }
    if (result != null) {
      return result;
    }
    provider.next();
  }
  return strategy.build(position);
}
项目:intellij-ce-playground    文件:UpdateFoldRegionsOperation.java   
private List<FoldRegion> addNewRegions(@NotNull EditorFoldingInfo info,
                                       @NotNull FoldingModelEx foldingModel,
                                       FoldingUpdate.FoldingMap elementsToFold, @NotNull Map<TextRange, Boolean> rangeToExpandStatusMap,
                                       @NotNull Map<FoldRegion, Boolean> shouldExpand,
                                       @NotNull Map<FoldingGroup, Boolean> groupExpand) {
  List<FoldRegion> newRegions = newArrayList();
  SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject);
  for (PsiElement element : elementsToFold.keySet()) {
    ProgressManager.checkCanceled();
    final Collection<FoldingDescriptor> descriptors = elementsToFold.get(element);
    for (FoldingDescriptor descriptor : descriptors) {
      FoldingGroup group = descriptor.getGroup();
      TextRange range = descriptor.getRange();
      String placeholder = descriptor.getPlaceholderText();
      if (range.getEndOffset() > myEditor.getDocument().getTextLength()) {
        LOG.error(String.format("Invalid folding descriptor detected (%s). It ends beyond the document range (%d)",
                                descriptor, myEditor.getDocument().getTextLength()));
        continue;
      }
      FoldRegion region = foldingModel.createFoldRegion(range.getStartOffset(), range.getEndOffset(),
                                                        placeholder == null ? "..." : placeholder,
                                                        group,
                                                        descriptor.isNonExpandable());
      if (region == null) continue;

      PsiElement psi = descriptor.getElement().getPsi();

      if (psi == null || !psi.isValid() || !foldingModel.addFoldRegion(region) || !myFile.isValid()) {
        region.dispose();
        continue;
      }

      info.addRegion(region, smartPointerManager.createSmartPsiElementPointer(psi));
      newRegions.add(region);

      boolean expandStatus = !descriptor.isNonExpandable() && shouldExpandNewRegion(element, range, rangeToExpandStatusMap);
      if (group == null) {
        shouldExpand.put(region, expandStatus);
      }
      else {
        final Boolean alreadyExpanded = groupExpand.get(group);
        groupExpand.put(group, alreadyExpanded == null ? expandStatus : alreadyExpanded.booleanValue() || expandStatus);
      }
    }
  }

  return newRegions;
}
项目:intellij-ce-playground    文件:FoldingModelWindow.java   
FoldingModelWindow(@NotNull FoldingModelEx delegate, @NotNull DocumentWindow documentWindow, @NotNull EditorWindow editorWindow) {
  myDelegate = delegate;
  myDocumentWindow = documentWindow;
  myEditorWindow = editorWindow;
}
项目:tools-idea    文件:CollapseBlockHandler.java   
@Override
public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file) {
  editor.getFoldingModel().runBatchFoldingOperation(new Runnable() {
    @Override
    public void run() {
      final EditorFoldingInfo info = EditorFoldingInfo.get(editor);
      FoldingModelEx model = (FoldingModelEx) editor.getFoldingModel();
      PsiElement element = file.findElementAt(editor.getCaretModel().getOffset() - 1);
      if (!(element instanceof PsiJavaToken) || ((PsiJavaToken) element).getTokenType() != JavaTokenType.RBRACE) {
        element = file.findElementAt(editor.getCaretModel().getOffset());
      }
      if (element == null) return;
      PsiCodeBlock block = PsiTreeUtil.getParentOfType(element, PsiCodeBlock.class);
      FoldRegion previous = null;
      FoldRegion myPrevious = null;
      while (block != null) {
        int start = block.getTextRange().getStartOffset();
        int end = block.getTextRange().getEndOffset();
        FoldRegion existing = FoldingUtil.findFoldRegion(editor, start, end);
        if (existing != null) {
          previous = existing;
          if (info.getPsiElement(existing) == null) myPrevious = existing;
          block = PsiTreeUtil.getParentOfType(block, PsiCodeBlock.class);
          continue;
        }
        if (!model.intersectsRegion(start, end)) {
          FoldRegion region = model.addFoldRegion(start, end, ourPlaceHolderText);
          LOG.assertTrue(region != null);
          region.setExpanded(false);
          if (myPrevious != null && info.getPsiElement(region) == null) {
            info.removeRegion(myPrevious);
            model.removeFoldRegion(myPrevious);
          }
          int offset = block.getTextRange().getEndOffset() < editor.getCaretModel().getOffset() ?
              start : end;
          editor.getCaretModel().moveToOffset(offset);
          return;
        } else break;
      }
      if (previous != null) {
        previous.setExpanded(false);
        if (myPrevious != null) {
          info.removeRegion(myPrevious);
          model.removeFoldRegion(myPrevious);
        }
        editor.getCaretModel().moveToOffset(previous.getEndOffset());
      }
    }
  });
}
项目:tools-idea    文件:DocumentFragmentTooltipRenderer.java   
@Override
public LightweightHint show(@NotNull final Editor editor, @NotNull Point p, boolean alignToRight, @NotNull TooltipGroup group, @NotNull HintHint intInfo) {
  LightweightHint hint;

  final JComponent editorComponent = editor.getComponent();

  TextRange range = myDocumentFragment.getTextRange();
  int startOffset = range.getStartOffset();
  int endOffset = range.getEndOffset();
  Document doc = myDocumentFragment.getDocument();
  int endLine = doc.getLineNumber(endOffset);
  int startLine = doc.getLineNumber(startOffset);

  JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane();

  // There is a possible case that collapsed folding region is soft wrapped, hence, we need to anchor
  // not logical but visual line start.
  VisualPosition visual = editor.offsetToVisualPosition(startOffset);
  p = editor.visualPositionToXY(visual);
  p = SwingUtilities.convertPoint(
    ((EditorEx)editor).getGutterComponentEx(),
    p,
    layeredPane
  );

  p.x -= 3;
  p.y += editor.getLineHeight();

  Point screenPoint = new Point(p);
  SwingUtilities.convertPointToScreen(screenPoint, layeredPane);
  int maxLineCount = (ScreenUtil.getScreenRectangle(screenPoint).height - screenPoint.y) / editor.getLineHeight();

  if (endLine - startLine > maxLineCount) {
    endOffset = doc.getLineEndOffset(Math.max(0, Math.min(startLine + maxLineCount, doc.getLineCount() - 1)));
  }

  FoldingModelEx foldingModel = (FoldingModelEx)editor.getFoldingModel();
  foldingModel.setFoldingEnabled(false);
  TextRange textRange = new TextRange(startOffset, endOffset);
  hint = EditorFragmentComponent.showEditorFragmentHintAt(editor, textRange, p.x, p.y, false, false, true);
  foldingModel.setFoldingEnabled(true);
  return hint;
}
项目:tools-idea    文件:CachingSoftWrapDataMapper.java   
private <T> T calculate(@NotNull MappingStrategy<T> strategy) throws IllegalStateException {
  T eagerMatch = strategy.eagerMatch();
  if (eagerMatch != null) {
    return eagerMatch;
  }

  EditorPosition position = strategy.buildInitialPosition();

  // Folding model doesn't return information about fold regions if their 'enabled' state is set to 'false'. Unfortunately,
  // such situation occurs not only on manual folding disabling but on internal processing as well. E.g. 'enabled' is set
  // to 'false' during fold preview representation. So, we set it to 'true' in order to retrieve fold regions and restore
  // to previous state after that.
  FoldingModelEx foldingModel = myEditor.getFoldingModel();
  boolean foldingState = foldingModel.isFoldingEnabled();
  foldingModel.setFoldingEnabled(true);
  CompositeDataProvider provider;
  try {
    provider = new CompositeDataProvider(
      new SoftWrapsDataProvider(myStorage), new FoldingDataProvider(myEditor.getFoldingModel().fetchTopLevel()),
      getTabulationDataProvider(position.visualLine)
    );
  }
  finally {
    foldingModel.setFoldingEnabled(foldingState);
  }
  provider.advance(position.offset);

  while (provider.hasData()) {
    Pair<SoftWrapDataProviderKeys, ?> data = provider.getData();
    T result = null;
    int sortingKey = provider.getSortingKey();

    // There is a possible case that, say, fold region is soft wrapped. We don't want to perform unnecessary then.
    if (position.offset <= sortingKey) {
      result = strategy.advance(position, sortingKey);
      if (result != null) {
        return result;
      }
    }

    switch (data.first) {
      case SOFT_WRAP: result = strategy.processSoftWrap(position, (SoftWrap)data.second); break;
      case COLLAPSED_FOLDING: result = strategy.processFoldRegion(position, (FoldRegion)data.second); break;
      case TABULATION: result = strategy.processTabulation(position, (TabData)data.second); break;
    }
    if (result != null) {
      return result;
    }
    provider.next();
  }
  return strategy.build(position);
}
项目:tools-idea    文件:FoldingTest.java   
public void testDuplicateRegions() {
  StringBuilder text = new StringBuilder();
  for (int i = 0; i < 450; i++) {
    text.append('a');
  }
  Editor editor = EditorFactory.getInstance().createEditor(new DocumentImpl(text));
  try {
    final Ref<Boolean> expandedStatus = new Ref<Boolean>();
    final int startOffset = 6;
    final int endOffset = 16;
    final FoldingModelEx model = (FoldingModelEx)editor.getFoldingModel();
    model.runBatchFoldingOperation(new Runnable() {
      @Override
      public void run() {
        model.addFoldRegion(2, 20, "..");
        model.addFoldRegion(4, 18, "..");
        FoldRegion oldRegion = model.addFoldRegion(startOffset, endOffset, "..");
        assertNotNull(oldRegion);
        expandedStatus.set(!oldRegion.isExpanded());
      }
    });
    assertEquals(3, model.getAllFoldRegions().length);

    final Ref<FoldRegion> newRegion = new Ref<FoldRegion>();
    model.runBatchFoldingOperation(new Runnable() {
      @Override
      public void run() {
        newRegion.set(model.createFoldRegion(startOffset, endOffset, "..", null, false));
        assertNotNull(newRegion.get());
        newRegion.get().setExpanded(expandedStatus.get());
        boolean additionFlag = model.addFoldRegion(newRegion.get());
        assertTrue(additionFlag);
      }
    });
    FoldRegion fetched = model.fetchOutermost(startOffset);
    assertSame(newRegion.get(), fetched);
    assertEquals(3, model.getAllFoldRegions().length);
  }
  finally {
    EditorFactory.getInstance().releaseEditor(editor);
  }
}
项目:tools-idea    文件:UpdateFoldRegionsOperation.java   
private List<FoldRegion> addNewRegions(@NotNull EditorFoldingInfo info,
                                       @NotNull FoldingModelEx foldingModel,
                                       @NotNull Map<TextRange, Boolean> rangeToExpandStatusMap,
                                       @NotNull Map<FoldRegion, Boolean> shouldExpand,
                                       @NotNull Map<FoldingGroup, Boolean> groupExpand) {
  List<FoldRegion> newRegions = newArrayList();
  SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject);
  for (PsiElement element : myElementsToFoldMap.keySet()) {
    ProgressManager.checkCanceled();
    final Collection<FoldingDescriptor> descriptors = myElementsToFoldMap.get(element);
    for (FoldingDescriptor descriptor : descriptors) {
      FoldingGroup group = descriptor.getGroup();
      TextRange range = descriptor.getRange();
      String placeholder = descriptor.getPlaceholderText();
      if (range.getEndOffset() > myEditor.getDocument().getTextLength()) {
        LOG.error(String.format("Invalid folding descriptor detected (%s). It ends beyond the document range (%d)",
                                descriptor, myEditor.getDocument().getTextLength()));
        continue;
      }
      FoldRegion region = foldingModel.createFoldRegion(range.getStartOffset(), range.getEndOffset(),
                                                        placeholder == null ? "..." : placeholder,
                                                        group,
                                                        descriptor.isNonExpandable());
      if (region == null) continue;

      PsiElement psi = descriptor.getElement().getPsi();

      if (psi == null || !psi.isValid() || !foldingModel.addFoldRegion(region)) {
        region.dispose();
        continue;
      }

      info.addRegion(region, smartPointerManager.createSmartPsiElementPointer(psi, myFile));
      newRegions.add(region);

      boolean expandStatus = !descriptor.isNonExpandable() && shouldExpandNewRegion(element, range, rangeToExpandStatusMap);
      if (group == null) {
        shouldExpand.put(region, expandStatus);
      }
      else {
        final Boolean alreadyExpanded = groupExpand.get(group);
        groupExpand.put(group, alreadyExpanded == null ? expandStatus : alreadyExpanded.booleanValue() || expandStatus);
      }
    }
  }

  return newRegions;
}
项目:tools-idea    文件:CodeFoldingManagerImpl.java   
@Override
public void buildInitialFoldings(@NotNull final Editor editor) {
  ApplicationManagerEx.getApplicationEx().assertIsDispatchThread(editor.getComponent());
  final Project project = editor.getProject();
  if (project == null || !project.equals(myProject)) return;

  final Document document = editor.getDocument();
  //Do not save/restore folding for code fragments
  final PsiFile file = PsiDocumentManager.getInstance(myProject).getPsiFile(document);
  if (file == null || !file.getViewProvider().isPhysical() && !ApplicationManager.getApplication().isUnitTestMode()) return;

  final FoldingModelEx foldingModel = (FoldingModelEx)editor.getFoldingModel();
  if (!foldingModel.isFoldingEnabled()) return;
  if (project.isDisposed() || editor.isDisposed() || !file.isValid()) return;

  PsiDocumentManager.getInstance(myProject).commitDocument(document);

  Runnable operation = new Runnable() {
    @Override
    public void run() {
      Runnable runnable = updateFoldRegions(editor, true, true);
      if (runnable != null) {
        runnable.run();
      }
      if (myProject.isDisposed() || editor.isDisposed()) return;
      foldingModel.runBatchFoldingOperation(new Runnable() {
        @Override
        public void run() {
          DocumentFoldingInfo documentFoldingInfo = getDocumentFoldingInfo(document);
          Editor[] editors = EditorFactory.getInstance().getEditors(document, myProject);
          for (Editor otherEditor : editors) {
            if (otherEditor == editor) continue;
            documentFoldingInfo.loadFromEditor(otherEditor);
            break;
          }
          documentFoldingInfo.setToEditor(editor);

          documentFoldingInfo.clear();
        }
      });
    }
  };
  UIUtil.invokeLaterIfNeeded(operation);
}
项目:tools-idea    文件:FoldingModelWindow.java   
public FoldingModelWindow(@NotNull FoldingModelEx delegate, @NotNull DocumentWindow documentWindow, @NotNull EditorWindow editorWindow) {
  myDelegate = delegate;
  myDocumentWindow = documentWindow;
  myEditorWindow = editorWindow;
}
项目:consulo    文件:DocumentFragmentTooltipRenderer.java   
@Override
public LightweightHint show(@Nonnull final Editor editor, @Nonnull Point p, boolean alignToRight, @Nonnull TooltipGroup group, @Nonnull HintHint intInfo) {
  LightweightHint hint;

  final JComponent editorComponent = editor.getComponent();

  TextRange range = myDocumentFragment.getTextRange();
  int startOffset = range.getStartOffset();
  int endOffset = range.getEndOffset();
  Document doc = myDocumentFragment.getDocument();
  int endLine = doc.getLineNumber(endOffset);
  int startLine = doc.getLineNumber(startOffset);

  JLayeredPane layeredPane = editorComponent.getRootPane().getLayeredPane();

  // There is a possible case that collapsed folding region is soft wrapped, hence, we need to anchor
  // not logical but visual line start.
  VisualPosition visual = editor.offsetToVisualPosition(startOffset);
  p = editor.visualPositionToXY(visual);
  p = SwingUtilities.convertPoint(
          ((EditorEx)editor).getGutterComponentEx(),
          p,
          layeredPane
  );

  p.x -= 3;
  p.y += editor.getLineHeight();

  Point screenPoint = new Point(p);
  SwingUtilities.convertPointToScreen(screenPoint, layeredPane);
  int maxLineCount = (ScreenUtil.getScreenRectangle(screenPoint).height - screenPoint.y) / editor.getLineHeight();

  if (endLine - startLine > maxLineCount) {
    endOffset = doc.getLineEndOffset(Math.max(0, Math.min(startLine + maxLineCount, doc.getLineCount() - 1)));
  }
  if (endOffset < startOffset) return null;

  FoldingModelEx foldingModel = (FoldingModelEx)editor.getFoldingModel();
  foldingModel.setFoldingEnabled(false);
  TextRange textRange = new TextRange(startOffset, endOffset);
  hint = EditorFragmentComponent.showEditorFragmentHintAt(editor, textRange, p.y, false, false, true, true, true);
  foldingModel.setFoldingEnabled(true);
  return hint;
}
项目:consulo    文件:UpdateFoldRegionsOperation.java   
private List<FoldRegion> addNewRegions(@Nonnull EditorFoldingInfo info,
                                       @Nonnull FoldingModelEx foldingModel,
                                       @Nonnull Map<TextRange, Boolean> rangeToExpandStatusMap,
                                       @Nonnull Map<FoldRegion, Boolean> shouldExpand,
                                       @Nonnull Map<FoldingGroup, Boolean> groupExpand) {
  List<FoldRegion> newRegions = new ArrayList<>();
  SmartPointerManager smartPointerManager = SmartPointerManager.getInstance(myProject);
  for (FoldingUpdate.RegionInfo regionInfo : myRegionInfos) {
    ProgressManager.checkCanceled();
    FoldingDescriptor descriptor = regionInfo.descriptor;
    FoldingGroup group = descriptor.getGroup();
    TextRange range = descriptor.getRange();
    String placeholder = null;
    try {
      placeholder = descriptor.getPlaceholderText();
    }
    catch (IndexNotReadyException ignore) {
    }
    if (range.getEndOffset() > myEditor.getDocument().getTextLength()) {
      LOG.error(String.format("Invalid folding descriptor detected (%s). It ends beyond the document range (%d)",
                              descriptor, myEditor.getDocument().getTextLength()));
      continue;
    }
    FoldRegion region = foldingModel.createFoldRegion(range.getStartOffset(), range.getEndOffset(),
                                                      placeholder == null ? "..." : placeholder,
                                                      group,
                                                      descriptor.isNonExpandable());
    if (region == null) continue;

    if (descriptor.isNonExpandable()) region.putUserData(FoldingModelImpl.SELECT_REGION_ON_CARET_NEARBY, Boolean.TRUE);

    PsiElement psi = descriptor.getElement().getPsi();

    if (psi == null || !psi.isValid() || !myFile.isValid()) {
      region.dispose();
      continue;
    }

    if (descriptor.canBeRemovedWhenCollapsed()) region.putUserData(CAN_BE_REMOVED_WHEN_COLLAPSED, Boolean.TRUE);
    region.putUserData(COLLAPSED_BY_DEFAULT, regionInfo.collapsedByDefault);
    region.putUserData(SIGNATURE, regionInfo.signature);

    info.addRegion(region, smartPointerManager.createSmartPsiElementPointer(psi));
    newRegions.add(region);

    boolean expandStatus = !descriptor.isNonExpandable() && shouldExpandNewRegion(range, rangeToExpandStatusMap,
                                                                                  regionInfo.collapsedByDefault);
    if (group == null) {
      shouldExpand.put(region, expandStatus);
    }
    else {
      final Boolean alreadyExpanded = groupExpand.get(group);
      groupExpand.put(group, alreadyExpanded == null ? expandStatus : alreadyExpanded.booleanValue() || expandStatus);
    }
  }

  return newRegions;
}
项目:consulo    文件:UpdateFoldRegionsOperation.java   
private boolean regionCanBeRemovedWhenCollapsed(FoldRegion region) {
  return Boolean.TRUE.equals(region.getUserData(CAN_BE_REMOVED_WHEN_COLLAPSED)) ||
         ((FoldingModelEx)myEditor.getFoldingModel()).hasDocumentRegionChangedFor(region) ||
         !region.isValid() ||
         isRegionInCaretLine(region);
}
项目:consulo    文件:FoldingModelWindow.java   
FoldingModelWindow(@Nonnull FoldingModelEx delegate, @Nonnull DocumentWindow documentWindow, @Nonnull EditorWindow editorWindow) {
  myDelegate = delegate;
  myDocumentWindow = documentWindow;
  myEditorWindow = editorWindow;
}
项目:consulo-java    文件:CollapseBlockHandler.java   
@Override
public void invoke(@NotNull final Project project, @NotNull final Editor editor, @NotNull final PsiFile file) {
  editor.getFoldingModel().runBatchFoldingOperation(new Runnable() {
    @Override
    public void run() {
      final EditorFoldingInfo info = EditorFoldingInfo.get(editor);
      FoldingModelEx model = (FoldingModelEx) editor.getFoldingModel();
      PsiElement element = file.findElementAt(editor.getCaretModel().getOffset() - 1);
      if (!(element instanceof PsiJavaToken) || ((PsiJavaToken) element).getTokenType() != JavaTokenType.RBRACE) {
        element = file.findElementAt(editor.getCaretModel().getOffset());
      }
      if (element == null) return;
      PsiCodeBlock block = PsiTreeUtil.getParentOfType(element, PsiCodeBlock.class);
      FoldRegion previous = null;
      FoldRegion myPrevious = null;
      while (block != null) {
        int start = block.getTextRange().getStartOffset();
        int end = block.getTextRange().getEndOffset();
        FoldRegion existing = FoldingUtil.findFoldRegion(editor, start, end);
        if (existing != null) {
          previous = existing;
          if (info.getPsiElement(existing) == null) myPrevious = existing;
          block = PsiTreeUtil.getParentOfType(block, PsiCodeBlock.class);
          continue;
        }
        if (!model.intersectsRegion(start, end)) {
          FoldRegion region = model.addFoldRegion(start, end, ourPlaceHolderText);
          LOG.assertTrue(region != null);
          region.setExpanded(false);
          if (myPrevious != null && info.getPsiElement(region) == null) {
            info.removeRegion(myPrevious);
            model.removeFoldRegion(myPrevious);
          }
          int offset = block.getTextRange().getEndOffset() < editor.getCaretModel().getOffset() ?
              start : end;
          editor.getCaretModel().moveToOffset(offset);
          return;
        } else break;
      }
      if (previous != null) {
        previous.setExpanded(false);
        if (myPrevious != null) {
          info.removeRegion(myPrevious);
          model.removeFoldRegion(myPrevious);
        }
        editor.getCaretModel().moveToOffset(previous.getEndOffset());
      }
    }
  });
}