summaryrefslogtreecommitdiff
path: root/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
diff options
context:
space:
mode:
Diffstat (limited to 'platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java')
-rw-r--r--platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java263
1 files changed, 3 insertions, 260 deletions
diff --git a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
index 3780e3a79e0c..942a33aaace8 100644
--- a/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
+++ b/platform/platform-api/src/com/intellij/openapi/editor/LazyRangeMarkerFactory.java
@@ -15,276 +15,19 @@
*/
package com.intellij.openapi.editor;
-import com.intellij.codeStyle.CodeStyleFacade;
-import com.intellij.openapi.application.ApplicationManager;
import com.intellij.openapi.components.ServiceManager;
-import com.intellij.openapi.editor.event.DocumentAdapter;
-import com.intellij.openapi.editor.event.DocumentEvent;
-import com.intellij.openapi.fileEditor.FileDocumentManager;
import com.intellij.openapi.project.Project;
-import com.intellij.openapi.util.Computable;
-import com.intellij.openapi.util.Key;
-import com.intellij.openapi.util.UserDataHolderBase;
import com.intellij.openapi.vfs.VirtualFile;
-import com.intellij.util.SmartList;
-import com.intellij.util.containers.WeakList;
import org.jetbrains.annotations.NotNull;
-import org.jetbrains.annotations.Nullable;
-
-import java.util.List;
-
-public class LazyRangeMarkerFactory {
- private final Project myProject;
- private static final Key<WeakList<LazyMarker>> LAZY_MARKERS_KEY = Key.create("LAZY_MARKERS_KEY");
+public abstract class LazyRangeMarkerFactory {
public static LazyRangeMarkerFactory getInstance(Project project) {
return ServiceManager.getService(project, LazyRangeMarkerFactory.class);
}
- public LazyRangeMarkerFactory(@NotNull Project project, @NotNull final FileDocumentManager fileDocumentManager) {
- myProject = project;
-
- EditorFactory.getInstance().getEventMulticaster().addDocumentListener(new DocumentAdapter() {
- @Override
- public void beforeDocumentChange(DocumentEvent e) {
- transformRangeMarkers(e);
- }
-
- @Override
- public void documentChanged(DocumentEvent e) {
- transformRangeMarkers(e);
- }
-
- private void transformRangeMarkers(@NotNull DocumentEvent e) {
- Document document = e.getDocument();
- VirtualFile file = fileDocumentManager.getFile(document);
- if (file == null) {
- return;
- }
-
- WeakList<LazyMarker> lazyMarkers = file.getUserData(LAZY_MARKERS_KEY);
- if (lazyMarkers == null) {
- return;
- }
-
- List<LazyMarker> markers = lazyMarkers.toStrongList();
- List<LazyMarker> markersToRemove = null;
- for (LazyMarker marker : markers) {
- if (file.equals(marker.getFile()) && marker.documentChanged(document) != null) {
- if (markersToRemove == null) {
- markersToRemove = new SmartList<LazyMarker>();
- }
- markersToRemove.add(marker);
- }
- }
- if (markersToRemove != null) {
- lazyMarkers.removeAll(markersToRemove);
- }
- }
- }, project);
- }
-
- private static void addToLazyMarkersList(@NotNull LazyMarker marker, @NotNull VirtualFile file) {
- WeakList<LazyMarker> markers = file.getUserData(LAZY_MARKERS_KEY);
-
- if (markers == null) {
- markers = file.putUserDataIfAbsent(LAZY_MARKERS_KEY, new WeakList<LazyMarker>());
- }
- markers.add(marker);
- }
-
@NotNull
- public RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int offset) {
- return ApplicationManager.getApplication().runReadAction(new Computable<RangeMarker>() {
- @Override
- public RangeMarker compute() {
- // even for already loaded document do not create range marker yet - wait until it really needed when e.g. user clicked to jump to OpenFileDescriptor
- final LazyMarker marker = new OffsetLazyMarker(file, offset);
- addToLazyMarkersList(marker, file);
- return marker;
- }
- });
- }
+ public abstract RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int offset);
@NotNull
- public RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int line, final int column, final boolean persistent) {
- return ApplicationManager.getApplication().runReadAction(new Computable<RangeMarker>() {
- @Override
- public RangeMarker compute() {
- final Document document = FileDocumentManager.getInstance().getCachedDocument(file);
- if (document != null) {
- final int offset = calculateOffset(myProject, file, document, line, column);
- return document.createRangeMarker(offset, offset, persistent);
- }
-
- final LazyMarker marker = new LineColumnLazyMarker(file, line, column);
- addToLazyMarkersList(marker, file);
- return marker;
- }
- });
- }
-
- private abstract static class LazyMarker extends UserDataHolderBase implements RangeMarker {
- private RangeMarker myDelegate;
- private final VirtualFile myFile;
- protected final int myInitialOffset;
-
- private LazyMarker(@NotNull VirtualFile file, int offset) {
- myFile = file;
- myInitialOffset = offset;
- }
-
- @NotNull
- public VirtualFile getFile() {
- return myFile;
- }
-
- @Nullable
- protected final RangeMarker getOrCreateDelegate() {
- if (myDelegate == null) {
- Document document = FileDocumentManager.getInstance().getDocument(myFile);
- if (document == null) {
- return null;
- }
- myDelegate = createDelegate(myFile, document);
- }
- return myDelegate;
- }
-
- @Nullable
- protected final RangeMarker documentChanged(@NotNull Document document) {
- if (myDelegate == null) {
- myDelegate = createDelegate(myFile, document);
- }
- return myDelegate;
- }
-
- @Nullable
- protected abstract RangeMarker createDelegate(@NotNull VirtualFile file, @NotNull Document document);
-
- @Override
- @NotNull
- public Document getDocument() {
- RangeMarker delegate = getOrCreateDelegate();
- if (delegate == null) {
- //noinspection ConstantConditions
- return FileDocumentManager.getInstance().getDocument(myFile);
- }
- return delegate.getDocument();
- }
-
- @Override
- public int getStartOffset() {
- return myDelegate == null ? myInitialOffset : myDelegate.getStartOffset();
- }
-
-
- @Override
- public int getEndOffset() {
- return myDelegate == null ? myInitialOffset : myDelegate.getEndOffset();
- }
-
- @Override
- public boolean isValid() {
- RangeMarker delegate = getOrCreateDelegate();
- return delegate != null && delegate.isValid();
- }
-
- @Override
- public void setGreedyToLeft(boolean greedy) {
- getOrCreateDelegate().setGreedyToLeft(greedy);
- }
-
- @Override
- public void setGreedyToRight(boolean greedy) {
- getOrCreateDelegate().setGreedyToRight(greedy);
- }
-
- @Override
- public boolean isGreedyToRight() {
- return getOrCreateDelegate().isGreedyToRight();
- }
-
- @Override
- public boolean isGreedyToLeft() {
- return getOrCreateDelegate().isGreedyToLeft();
- }
-
- @Override
- public void dispose() {
- RangeMarker delegate = getOrCreateDelegate();
- if (delegate != null) {
- delegate.dispose();
- }
- }
- }
-
- private static class OffsetLazyMarker extends LazyMarker {
- private OffsetLazyMarker(@NotNull VirtualFile file, int offset) {
- super(file, offset);
- }
-
- @Override
- @NotNull
- public RangeMarker createDelegate(@NotNull VirtualFile file, @NotNull final Document document) {
- final int offset = Math.min(myInitialOffset, document.getTextLength());
- return document.createRangeMarker(offset, offset);
- }
- }
-
- private class LineColumnLazyMarker extends LazyMarker {
- private final int myLine;
- private final int myColumn;
-
- private LineColumnLazyMarker(@NotNull VirtualFile file, int line, int column) {
- super(file, -1);
- myLine = line;
- myColumn = column;
- }
-
- @Override
- @Nullable
- public RangeMarker createDelegate(@NotNull VirtualFile file, @NotNull Document document) {
- if (document.getTextLength() == 0 && !(myLine == 0 && myColumn == 0)) {
- return null;
- }
-
- int offset = calculateOffset(myProject, file, document, myLine, myColumn);
- return document.createRangeMarker(offset, offset);
- }
-
- @Override
- public int getStartOffset() {
- getOrCreateDelegate();
- return super.getStartOffset();
- }
-
- @Override
- public int getEndOffset() {
- getOrCreateDelegate();
- return super.getEndOffset();
- }
- }
-
- private static int calculateOffset(@NotNull Project project, @NotNull VirtualFile file, @NotNull Document document, final int line, final int column) {
- int offset;
- if (line < document.getLineCount()) {
- final int lineStart = document.getLineStartOffset(line);
- final int lineEnd = document.getLineEndOffset(line);
- final CharSequence docText = document.getCharsSequence();
- final int tabSize = CodeStyleFacade.getInstance(project).getTabSize(file.getFileType());
-
- offset = lineStart;
- int col = 0;
- while (offset < lineEnd && col < column) {
- col += docText.charAt(offset) == '\t' ? tabSize : 1;
- offset++;
- }
- }
- else {
- offset = document.getTextLength();
- }
- return offset;
- }
-
+ public abstract RangeMarker createRangeMarker(@NotNull final VirtualFile file, final int line, final int column, final boolean persistent);
}