diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/CodeFoldingManager.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/CodeFoldingManager.java index f9929ee72154..76832aa1bab5 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/CodeFoldingManager.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/CodeFoldingManager.java @@ -1,8 +1,7 @@ -/* - * Copyright 2000-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. - */ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. package com.intellij.codeInsight.folding; +import com.intellij.openapi.components.ServiceManager; import com.intellij.openapi.editor.Document; import com.intellij.openapi.editor.Editor; import com.intellij.openapi.editor.FoldRegion; @@ -14,7 +13,7 @@ import org.jetbrains.annotations.Nullable; public abstract class CodeFoldingManager { public static CodeFoldingManager getInstance(Project project) { - return project.getComponent(CodeFoldingManager.class); + return ServiceManager.getService(project, CodeFoldingManager.class); } public abstract void updateFoldRegions(@NotNull Editor editor); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java index 2030906ef128..9506b28b77ef 100644 --- a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/CodeFoldingManagerImpl.java @@ -3,40 +3,29 @@ package com.intellij.codeInsight.folding.impl; import com.intellij.codeInsight.daemon.DaemonCodeAnalyzer; import com.intellij.codeInsight.folding.CodeFoldingManager; -import com.intellij.codeInsight.hint.EditorFragmentComponent; -import com.intellij.codeInsight.hint.HintManager; import com.intellij.openapi.Disposable; import com.intellij.openapi.application.ApplicationManager; -import com.intellij.openapi.components.ProjectComponent; -import com.intellij.openapi.editor.*; -import com.intellij.openapi.editor.event.EditorMouseEvent; -import com.intellij.openapi.editor.event.EditorMouseEventArea; -import com.intellij.openapi.editor.event.EditorMouseMotionListener; -import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.editor.Document; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.editor.FoldRegion; import com.intellij.openapi.editor.ex.FoldingModelEx; import com.intellij.openapi.fileEditor.impl.text.CodeFoldingState; -import com.intellij.openapi.project.DumbAwareRunnable; import com.intellij.openapi.project.DumbService; import com.intellij.openapi.project.Project; -import com.intellij.openapi.startup.StartupManager; import com.intellij.openapi.util.Key; -import com.intellij.openapi.util.TextRange; -import com.intellij.openapi.util.UnfairTextRange; import com.intellij.openapi.util.UserDataHolderEx; import com.intellij.psi.PsiDocumentManager; import com.intellij.psi.PsiFile; -import com.intellij.ui.LightweightHint; import com.intellij.util.containers.WeakList; import org.jdom.Element; import org.jetbrains.annotations.NotNull; import org.jetbrains.annotations.Nullable; -import java.awt.*; -import java.awt.event.MouseEvent; import java.util.Collection; import java.util.List; -public class CodeFoldingManagerImpl extends CodeFoldingManager implements ProjectComponent, Disposable { +public class CodeFoldingManagerImpl extends CodeFoldingManager implements Disposable { private final Project myProject; private final Collection myDocumentsWithFoldingInfo = new WeakList<>(); @@ -44,7 +33,7 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec private final Key myFoldingInfoInDocumentKey = Key.create("FOLDING_INFO_IN_DOCUMENT_KEY"); private static final Key FOLDING_STATE_KEY = Key.create("FOLDING_STATE_KEY"); - CodeFoldingManagerImpl(Project project) { + public CodeFoldingManagerImpl(Project project) { myProject = project; } @@ -57,90 +46,6 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec } } - @Override - public void projectOpened() { - final EditorMouseMotionListener myMouseMotionListener = new EditorMouseMotionListener() { - LightweightHint myCurrentHint; - FoldRegion myCurrentFold; - - @Override - public void mouseMoved(@NotNull EditorMouseEvent e) { - if (myProject.isDisposed()) return; - LightweightHint hint = null; - try { - HintManager hintManager = HintManager.getInstance(); - if (hintManager != null && hintManager.hasShownHintsThatWillHideByOtherHint(false)) { - return; - } - - if (e.getArea() != EditorMouseEventArea.FOLDING_OUTLINE_AREA) return; - - Editor editor = e.getEditor(); - if (PsiDocumentManager.getInstance(myProject).isUncommited(editor.getDocument())) return; - - MouseEvent mouseEvent = e.getMouseEvent(); - FoldRegion fold = ((EditorEx)editor).getGutterComponentEx().findFoldingAnchorAt(mouseEvent.getX(), mouseEvent.getY()); - - if (fold == null || !fold.isValid()) return; - if (fold == myCurrentFold && myCurrentHint != null) { - hint = myCurrentHint; - return; - } - - TextRange psiElementRange = EditorFoldingInfo.get(editor).getPsiElementRange(fold); - if (psiElementRange == null) return; - - int textOffset = psiElementRange.getStartOffset(); - // There is a possible case that target PSI element's offset is less than fold region offset (e.g. complete method is - // returned as PSI element for fold region that corresponds to java method code block). We don't want to show any hint - // if start of the current fold region is displayed. - Point foldStartXY = editor.visualPositionToXY(editor.offsetToVisualPosition(Math.max(textOffset, fold.getStartOffset()))); - Rectangle visibleArea = editor.getScrollingModel().getVisibleArea(); - if (visibleArea.y > foldStartXY.y) { - if (myCurrentHint != null) { - myCurrentHint.hide(); - myCurrentHint = null; - } - - - // We want to show a hint with the top fold region content that is above the current viewport position. - // However, there is a possible case that complete region has a big height and only a little bottom part - // is shown at the moment. We can't just show hint with the whole top content because it would hide actual - // editor content, hence, we show max(2; available visual lines number) instead. - // P.S. '2' is used here in assumption that many java methods have javadocs which first line is just '/**'. - // So, it's not too useful to show only it even when available vertical space is not big enough. - int availableVisualLines = EditorFragmentComponent.getAvailableVisualLinesAboveEditor(editor); - int startVisualLine = editor.offsetToVisualPosition(textOffset).line; - int desiredEndVisualLine = Math.max(0, editor.xyToVisualPosition(new Point(0, visibleArea.y)).line - 1); - int endVisualLine = startVisualLine + availableVisualLines; - if (endVisualLine > desiredEndVisualLine) { - endVisualLine = desiredEndVisualLine; - } - - // Show only the non-displayed top part of the target fold region - int endOffset = editor.logicalPositionToOffset(editor.visualToLogicalPosition(new VisualPosition(endVisualLine, 0))); - TextRange textRange = new UnfairTextRange(textOffset, endOffset); - hint = EditorFragmentComponent.showEditorFragmentHint(editor, textRange, true, true); - myCurrentFold = fold; - myCurrentHint = hint; - } - } - finally { - if (hint == null) { - if (myCurrentHint != null) { - myCurrentHint.hide(); - myCurrentHint = null; - } - myCurrentFold = null; - } - } - } - }; - - StartupManager.getInstance(myProject).registerPostStartupActivity( - (DumbAwareRunnable)() -> EditorFactory.getInstance().getEventMulticaster().addEditorMouseMotionListener(myMouseMotionListener, myProject)); - } - @Override public void releaseFoldings(@NotNull Editor editor) { ApplicationManager.getApplication().assertIsDispatchThread(); diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingHintMouseMotionListener.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingHintMouseMotionListener.java new file mode 100644 index 000000000000..0930a57a9970 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingHintMouseMotionListener.java @@ -0,0 +1,104 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.codeInsight.folding.impl; + +import com.intellij.codeInsight.hint.EditorFragmentComponent; +import com.intellij.codeInsight.hint.HintManager; +import com.intellij.openapi.editor.Editor; +import com.intellij.openapi.editor.FoldRegion; +import com.intellij.openapi.editor.VisualPosition; +import com.intellij.openapi.editor.event.EditorMouseEvent; +import com.intellij.openapi.editor.event.EditorMouseEventArea; +import com.intellij.openapi.editor.event.EditorMouseMotionListener; +import com.intellij.openapi.editor.ex.EditorEx; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.util.TextRange; +import com.intellij.openapi.util.UnfairTextRange; +import com.intellij.psi.PsiDocumentManager; +import com.intellij.ui.LightweightHint; +import org.jetbrains.annotations.NotNull; + +import java.awt.*; +import java.awt.event.MouseEvent; + +class FoldingHintMouseMotionListener implements EditorMouseMotionListener { + private final Project myProject; + LightweightHint myCurrentHint; + FoldRegion myCurrentFold; + + FoldingHintMouseMotionListener(Project project) { + myProject = project; + } + + @Override + public void mouseMoved(@NotNull EditorMouseEvent e) { + if (myProject.isDisposed()) return; + LightweightHint hint = null; + try { + HintManager hintManager = HintManager.getInstance(); + if (hintManager != null && hintManager.hasShownHintsThatWillHideByOtherHint(false)) { + return; + } + + if (e.getArea() != EditorMouseEventArea.FOLDING_OUTLINE_AREA) return; + + Editor editor = e.getEditor(); + if (PsiDocumentManager.getInstance(myProject).isUncommited(editor.getDocument())) return; + + MouseEvent mouseEvent = e.getMouseEvent(); + FoldRegion fold = ((EditorEx)editor).getGutterComponentEx().findFoldingAnchorAt(mouseEvent.getX(), mouseEvent.getY()); + + if (fold == null || !fold.isValid()) return; + if (fold == myCurrentFold && myCurrentHint != null) { + hint = myCurrentHint; + return; + } + + TextRange psiElementRange = EditorFoldingInfo.get(editor).getPsiElementRange(fold); + if (psiElementRange == null) return; + + int textOffset = psiElementRange.getStartOffset(); + // There is a possible case that target PSI element's offset is less than fold region offset (e.g. complete method is + // returned as PSI element for fold region that corresponds to java method code block). We don't want to show any hint + // if start of the current fold region is displayed. + Point foldStartXY = editor.visualPositionToXY(editor.offsetToVisualPosition(Math.max(textOffset, fold.getStartOffset()))); + Rectangle visibleArea = editor.getScrollingModel().getVisibleArea(); + if (visibleArea.y > foldStartXY.y) { + if (myCurrentHint != null) { + myCurrentHint.hide(); + myCurrentHint = null; + } + + + // We want to show a hint with the top fold region content that is above the current viewport position. + // However, there is a possible case that complete region has a big height and only a little bottom part + // is shown at the moment. We can't just show hint with the whole top content because it would hide actual + // editor content, hence, we show max(2; available visual lines number) instead. + // P.S. '2' is used here in assumption that many java methods have javadocs which first line is just '/**'. + // So, it's not too useful to show only it even when available vertical space is not big enough. + int availableVisualLines = EditorFragmentComponent.getAvailableVisualLinesAboveEditor(editor); + int startVisualLine = editor.offsetToVisualPosition(textOffset).line; + int desiredEndVisualLine = Math.max(0, editor.xyToVisualPosition(new Point(0, visibleArea.y)).line - 1); + int endVisualLine = startVisualLine + availableVisualLines; + if (endVisualLine > desiredEndVisualLine) { + endVisualLine = desiredEndVisualLine; + } + + // Show only the non-displayed top part of the target fold region + int endOffset = editor.logicalPositionToOffset(editor.visualToLogicalPosition(new VisualPosition(endVisualLine, 0))); + TextRange textRange = new UnfairTextRange(textOffset, endOffset); + hint = EditorFragmentComponent.showEditorFragmentHint(editor, textRange, true, true); + myCurrentFold = fold; + myCurrentHint = hint; + } + } + finally { + if (hint == null) { + if (myCurrentHint != null) { + myCurrentHint.hide(); + myCurrentHint = null; + } + myCurrentFold = null; + } + } + } +} diff --git a/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingHintPostStartupActivity.java b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingHintPostStartupActivity.java new file mode 100644 index 000000000000..9fcd41d78d79 --- /dev/null +++ b/platform/lang-impl/src/com/intellij/codeInsight/folding/impl/FoldingHintPostStartupActivity.java @@ -0,0 +1,16 @@ +// Copyright 2000-2019 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license that can be found in the LICENSE file. +package com.intellij.codeInsight.folding.impl; + +import com.intellij.openapi.editor.EditorFactory; +import com.intellij.openapi.project.Project; +import com.intellij.openapi.startup.StartupActivity; +import org.jetbrains.annotations.NotNull; + +public class FoldingHintPostStartupActivity implements StartupActivity.DumbAware { + @Override + public void runActivity(@NotNull Project project) { + EditorFactory.getInstance().getEventMulticaster().addEditorMouseMotionListener( + new FoldingHintMouseMotionListener(project), project); + + } +} diff --git a/platform/platform-resources/src/META-INF/LangExtensions.xml b/platform/platform-resources/src/META-INF/LangExtensions.xml index 4b665409dafb..03b3a235cff9 100644 --- a/platform/platform-resources/src/META-INF/LangExtensions.xml +++ b/platform/platform-resources/src/META-INF/LangExtensions.xml @@ -122,6 +122,9 @@ + + diff --git a/platform/platform-resources/src/componentSets/Lang.xml b/platform/platform-resources/src/componentSets/Lang.xml index ac5224089ecf..4d3e85ef62ea 100644 --- a/platform/platform-resources/src/componentSets/Lang.xml +++ b/platform/platform-resources/src/componentSets/Lang.xml @@ -29,11 +29,6 @@ com.intellij.execution.impl.ProjectRunConfigurationInitializer - - com.intellij.codeInsight.folding.CodeFoldingManager - com.intellij.codeInsight.folding.impl.CodeFoldingManagerImpl - - com.intellij.openapi.fileEditor.FileEditorManager com.intellij.openapi.fileEditor.impl.PsiAwareFileEditorManagerImpl