mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
CodeFoldingManager converted to service
GitOrigin-RevId: 511fec1be0ccd3f6ccb9a5030ee994f96b9178ac
This commit is contained in:
committed by
intellij-monorepo-bot
parent
c661506070
commit
69c67340be
@@ -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);
|
||||
|
||||
+6
-101
@@ -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<Document> myDocumentsWithFoldingInfo = new WeakList<>();
|
||||
@@ -44,7 +33,7 @@ public class CodeFoldingManagerImpl extends CodeFoldingManager implements Projec
|
||||
private final Key<DocumentFoldingInfo> myFoldingInfoInDocumentKey = Key.create("FOLDING_INFO_IN_DOCUMENT_KEY");
|
||||
private static final Key<Boolean> 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();
|
||||
|
||||
+104
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
+16
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
@@ -122,6 +122,9 @@
|
||||
|
||||
<applicationService serviceInterface="com.intellij.codeInsight.folding.CodeFoldingSettings"
|
||||
serviceImplementation="com.intellij.codeInsight.folding.CodeFoldingSettingsImpl"/>
|
||||
<postStartupActivity implementation="com.intellij.codeInsight.folding.impl.FoldingHintPostStartupActivity"/>
|
||||
<projectService serviceInterface="com.intellij.codeInsight.folding.CodeFoldingManager"
|
||||
serviceImplementation="com.intellij.codeInsight.folding.impl.CodeFoldingManagerImpl"/>
|
||||
|
||||
<applicationService serviceInterface="com.intellij.psi.statistics.StatisticsManager"
|
||||
serviceImplementation="com.intellij.psi.statistics.impl.StatisticsManagerImpl"/>
|
||||
|
||||
@@ -29,11 +29,6 @@
|
||||
<implementation-class>com.intellij.execution.impl.ProjectRunConfigurationInitializer</implementation-class>
|
||||
</component>
|
||||
|
||||
<component>
|
||||
<interface-class>com.intellij.codeInsight.folding.CodeFoldingManager</interface-class>
|
||||
<implementation-class>com.intellij.codeInsight.folding.impl.CodeFoldingManagerImpl</implementation-class>
|
||||
</component>
|
||||
|
||||
<component>
|
||||
<interface-class>com.intellij.openapi.fileEditor.FileEditorManager</interface-class>
|
||||
<implementation-class>com.intellij.openapi.fileEditor.impl.PsiAwareFileEditorManagerImpl</implementation-class>
|
||||
|
||||
Reference in New Issue
Block a user