mirror of
https://gitflic.ru/project/openide/openide.git
synced 2026-09-27 10:03:11 +07:00
reduce visibility to prevent subclassing of RangeMarkerImpl which can break tree invariants
This commit is contained in:
+3
-7
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2010 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -23,11 +23,7 @@ import org.jetbrains.annotations.NotNull;
|
||||
* @author Denis Zhdanov
|
||||
* @since 12/27/10 4:26 PM
|
||||
*/
|
||||
public class PersistentRangeMarkerUtil {
|
||||
|
||||
private PersistentRangeMarkerUtil() {
|
||||
}
|
||||
|
||||
class PersistentRangeMarkerUtil {
|
||||
/**
|
||||
* Answers if document region identified by the given range marker should be translated via diff algorithm on document change
|
||||
* identified by the given event.
|
||||
@@ -37,7 +33,7 @@ public class PersistentRangeMarkerUtil {
|
||||
* @return <code>true</code> if target document range referenced by the given range marker should be translated via
|
||||
* diff algorithm; <code>false</code> otherwise
|
||||
*/
|
||||
public static boolean shouldTranslateViaDiff(@NotNull DocumentEventImpl e, @NotNull RangeMarker rangeMarker) {
|
||||
static boolean shouldTranslateViaDiff(@NotNull DocumentEventImpl e, @NotNull RangeMarker rangeMarker) {
|
||||
if (e.isWholeTextReplaced()) {
|
||||
// Perform translation if the whole text is replaced.
|
||||
return true;
|
||||
|
||||
@@ -21,7 +21,6 @@ import com.intellij.openapi.editor.FoldRegion;
|
||||
import com.intellij.openapi.editor.FoldingGroup;
|
||||
import com.intellij.openapi.editor.ex.FoldingListener;
|
||||
import com.intellij.openapi.editor.ex.FoldingModelEx;
|
||||
import com.intellij.openapi.editor.impl.FoldRegionImpl;
|
||||
import com.intellij.openapi.editor.markup.TextAttributes;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
@@ -35,12 +34,12 @@ import java.util.List;
|
||||
/**
|
||||
* @author cdr
|
||||
*/
|
||||
public class FoldingModelWindow implements FoldingModelEx{
|
||||
class FoldingModelWindow implements FoldingModelEx{
|
||||
private final FoldingModelEx myDelegate;
|
||||
private final DocumentWindow myDocumentWindow;
|
||||
private final EditorWindow myEditorWindow;
|
||||
|
||||
public FoldingModelWindow(@NotNull FoldingModelEx delegate, @NotNull DocumentWindow documentWindow, @NotNull EditorWindow editorWindow) {
|
||||
FoldingModelWindow(@NotNull FoldingModelEx delegate, @NotNull DocumentWindow documentWindow, @NotNull EditorWindow editorWindow) {
|
||||
myDelegate = delegate;
|
||||
myDocumentWindow = documentWindow;
|
||||
myEditorWindow = editorWindow;
|
||||
@@ -82,12 +81,12 @@ public class FoldingModelWindow implements FoldingModelEx{
|
||||
|
||||
@Override
|
||||
public boolean addFoldRegion(@NotNull final FoldRegion region) {
|
||||
return myDelegate.addFoldRegion(((FoldingRegionWindow)region).getDelegate());
|
||||
return myDelegate.addFoldRegion((FoldRegion)((FoldingRegionWindow)region).getDelegate());
|
||||
}
|
||||
|
||||
@Override
|
||||
public void removeFoldRegion(@NotNull FoldRegion region) {
|
||||
myDelegate.removeFoldRegion(((FoldingRegionWindow)region).getDelegate());
|
||||
myDelegate.removeFoldRegion((FoldRegion)((FoldingRegionWindow)region).getDelegate());
|
||||
}
|
||||
|
||||
@Override
|
||||
@@ -172,7 +171,7 @@ public class FoldingModelWindow implements FoldingModelEx{
|
||||
FoldRegion hostRegion = myDelegate.createFoldRegion(hostRange.getStartOffset(), hostRange.getEndOffset(), placeholder, group, neverExpands);
|
||||
int startShift = Math.max(0, myDocumentWindow.hostToInjected(hostRange.getStartOffset()) - startOffset);
|
||||
int endShift = Math.max(0, endOffset - myDocumentWindow.hostToInjected(hostRange.getEndOffset()) - startShift);
|
||||
FoldingRegionWindow window = new FoldingRegionWindow(myDocumentWindow, myEditorWindow, (FoldRegionImpl)hostRegion, startShift, endShift);
|
||||
FoldingRegionWindow window = new FoldingRegionWindow(myDocumentWindow, myEditorWindow, hostRegion, startShift, endShift);
|
||||
hostRegion.putUserData(FOLD_REGION_WINDOW, window);
|
||||
return window;
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2012 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,24 +18,24 @@ package com.intellij.injected.editor;
|
||||
import com.intellij.openapi.editor.Editor;
|
||||
import com.intellij.openapi.editor.FoldRegion;
|
||||
import com.intellij.openapi.editor.FoldingGroup;
|
||||
import com.intellij.openapi.editor.impl.FoldRegionImpl;
|
||||
import com.intellij.openapi.editor.ex.RangeMarkerEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
/**
|
||||
* User: cdr
|
||||
*/
|
||||
public class FoldingRegionWindow extends RangeMarkerWindow implements FoldRegion {
|
||||
class FoldingRegionWindow extends RangeMarkerWindow implements FoldRegion {
|
||||
private final EditorWindow myEditorWindow;
|
||||
|
||||
private final FoldRegionImpl myHostRegion;
|
||||
private final FoldRegion myHostRegion;
|
||||
|
||||
public FoldingRegionWindow(@NotNull DocumentWindow documentWindow,
|
||||
@NotNull EditorWindow editorWindow,
|
||||
@NotNull FoldRegionImpl hostRegion,
|
||||
int startShift,
|
||||
int endShift)
|
||||
FoldingRegionWindow(@NotNull DocumentWindow documentWindow,
|
||||
@NotNull EditorWindow editorWindow,
|
||||
@NotNull FoldRegion hostRegion,
|
||||
int startShift,
|
||||
int endShift)
|
||||
{
|
||||
super(documentWindow, hostRegion, startShift, endShift);
|
||||
super(documentWindow, (RangeMarkerEx)hostRegion, startShift, endShift);
|
||||
myEditorWindow = editorWindow;
|
||||
myHostRegion = hostRegion;
|
||||
}
|
||||
@@ -72,7 +72,7 @@ public class FoldingRegionWindow extends RangeMarkerWindow implements FoldRegion
|
||||
}
|
||||
|
||||
@Override
|
||||
public FoldRegionImpl getDelegate() {
|
||||
return myHostRegion;
|
||||
public RangeMarkerEx getDelegate() {
|
||||
return (RangeMarkerEx)myHostRegion;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -29,12 +29,11 @@ import com.intellij.openapi.util.Key;
|
||||
import com.intellij.psi.PsiLanguageInjectionHost;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
public class RangeMarkerWindow implements RangeMarkerEx {
|
||||
|
||||
class RangeMarkerWindow implements RangeMarkerEx {
|
||||
private final DocumentWindow myDocumentWindow;
|
||||
private final RangeMarkerEx myHostMarker;
|
||||
private final int myStartShift;
|
||||
private final int myEndShift;
|
||||
private final RangeMarkerEx myHostMarker;
|
||||
private final int myStartShift;
|
||||
private final int myEndShift;
|
||||
|
||||
/**
|
||||
* Creates new <code>RangeMarkerWindow</code> object with the given data.
|
||||
@@ -51,7 +50,7 @@ public class RangeMarkerWindow implements RangeMarkerEx {
|
||||
* @param endShift similar to the 'startShift' argument but specifies difference between the target injected host end offset
|
||||
* and end offset of the given host range marker at the injected text
|
||||
*/
|
||||
public RangeMarkerWindow(@NotNull DocumentWindow documentWindow, RangeMarkerEx hostMarker, int startShift, int endShift) {
|
||||
RangeMarkerWindow(@NotNull DocumentWindow documentWindow, RangeMarkerEx hostMarker, int startShift, int endShift) {
|
||||
myDocumentWindow = documentWindow;
|
||||
myHostMarker = hostMarker;
|
||||
myStartShift = startShift;
|
||||
|
||||
+88
-18
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -17,30 +17,40 @@ package com.intellij.openapi.diff.impl.incrementalMerge;
|
||||
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.editor.Document;
|
||||
import com.intellij.openapi.editor.RangeMarker;
|
||||
import com.intellij.openapi.editor.event.DocumentAdapter;
|
||||
import com.intellij.openapi.editor.event.DocumentEvent;
|
||||
import com.intellij.openapi.editor.ex.DocumentEx;
|
||||
import com.intellij.openapi.editor.impl.RangeMarkerImpl;
|
||||
import com.intellij.openapi.util.Key;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
import java.util.ArrayList;
|
||||
|
||||
class DiffRangeMarker extends RangeMarkerImpl {
|
||||
class DiffRangeMarker implements RangeMarker {
|
||||
private static final Logger LOG = Logger.getInstance("#com.intellij.openapi.diff.impl.incrementalMerge.DiffRangeMarker");
|
||||
private final RangeMarker myRangeMarker;
|
||||
private RangeInvalidListener myListener;
|
||||
|
||||
DiffRangeMarker(@NotNull DocumentEx document, @NotNull TextRange range, RangeInvalidListener listener) {
|
||||
super(document, range.getStartOffset(), range.getEndOffset(),true);
|
||||
DiffRangeMarker(@NotNull Document document, @NotNull TextRange range, RangeInvalidListener listener) {
|
||||
myRangeMarker = document.createRangeMarker(range.getStartOffset(), range.getEndOffset());
|
||||
myListener = listener;
|
||||
if (myListener != null) InvalidRangeDispatcher.addClient(document);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void changedUpdateImpl(DocumentEvent e) {
|
||||
super.changedUpdateImpl(e);
|
||||
if (!isValid() && myListener != null) InvalidRangeDispatcher.notify(e.getDocument(), myListener);
|
||||
if (listener != null) {
|
||||
final InvalidRangeDispatcher notifier = InvalidRangeDispatcher.addClient(document);
|
||||
document.addDocumentListener(new DocumentAdapter() {
|
||||
@Override
|
||||
public void beforeDocumentChange(DocumentEvent e) {
|
||||
if (myListener != null) {
|
||||
notifier.notify(new RangeInvalidListener() {
|
||||
@Override
|
||||
public void onRangeInvalidated() {
|
||||
if (!isValid() && myListener != null) myListener.onRangeInvalidated();
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
public void removeListener(RangeInvalidListener listener) {
|
||||
@@ -49,7 +59,7 @@ class DiffRangeMarker extends RangeMarkerImpl {
|
||||
InvalidRangeDispatcher.removeClient(getDocument());
|
||||
}
|
||||
|
||||
public interface RangeInvalidListener {
|
||||
interface RangeInvalidListener {
|
||||
void onRangeInvalidated();
|
||||
}
|
||||
|
||||
@@ -58,6 +68,7 @@ class DiffRangeMarker extends RangeMarkerImpl {
|
||||
private final ArrayList<RangeInvalidListener> myDeferedNotifications = new ArrayList<RangeInvalidListener>();
|
||||
private int myClientCount = 0;
|
||||
|
||||
@Override
|
||||
public void documentChanged(DocumentEvent e) {
|
||||
if (myDeferedNotifications.isEmpty()) return;
|
||||
RangeInvalidListener[] notifications = myDeferedNotifications.toArray(new RangeInvalidListener[myDeferedNotifications.size()]);
|
||||
@@ -67,12 +78,11 @@ class DiffRangeMarker extends RangeMarkerImpl {
|
||||
}
|
||||
}
|
||||
|
||||
public static void notify(Document document, RangeInvalidListener listener) {
|
||||
InvalidRangeDispatcher notifier = document.getUserData(KEY);
|
||||
notifier.myDeferedNotifications.add(listener);
|
||||
public void notify(@NotNull RangeInvalidListener listener) {
|
||||
myDeferedNotifications.add(listener);
|
||||
}
|
||||
|
||||
public static void addClient(@NotNull Document document) {
|
||||
private static InvalidRangeDispatcher addClient(@NotNull Document document) {
|
||||
InvalidRangeDispatcher notifier = document.getUserData(KEY);
|
||||
if (notifier == null) {
|
||||
notifier = new InvalidRangeDispatcher();
|
||||
@@ -80,6 +90,7 @@ class DiffRangeMarker extends RangeMarkerImpl {
|
||||
document.addDocumentListener(notifier);
|
||||
}
|
||||
notifier.myClientCount++;
|
||||
return notifier;
|
||||
}
|
||||
|
||||
private static void removeClient(Document document) {
|
||||
@@ -96,4 +107,63 @@ class DiffRangeMarker extends RangeMarkerImpl {
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/// delegates
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public Document getDocument() {
|
||||
return myRangeMarker.getDocument();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getStartOffset() {
|
||||
return myRangeMarker.getStartOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public int getEndOffset() {
|
||||
return myRangeMarker.getEndOffset();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
return myRangeMarker.isValid();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGreedyToLeft(boolean greedy) {
|
||||
myRangeMarker.setGreedyToLeft(greedy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void setGreedyToRight(boolean greedy) {
|
||||
myRangeMarker.setGreedyToRight(greedy);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGreedyToRight() {
|
||||
return myRangeMarker.isGreedyToRight();
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isGreedyToLeft() {
|
||||
return myRangeMarker.isGreedyToLeft();
|
||||
}
|
||||
|
||||
@Override
|
||||
public void dispose() {
|
||||
myRangeMarker.dispose();
|
||||
}
|
||||
|
||||
@Override
|
||||
@Nullable
|
||||
public <T> T getUserData(@NotNull Key<T> key) {
|
||||
return myRangeMarker.getUserData(key);
|
||||
}
|
||||
|
||||
@Override
|
||||
public <T> void putUserData(@NotNull Key<T> key, @Nullable T value) {
|
||||
myRangeMarker.putUserData(key, value);
|
||||
}
|
||||
}
|
||||
|
||||
+12
-5
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2009 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -18,7 +18,6 @@ package com.intellij.openapi.diff.impl.incrementalMerge;
|
||||
import com.intellij.openapi.actionSystem.AnAction;
|
||||
import com.intellij.openapi.diagnostic.Logger;
|
||||
import com.intellij.openapi.diff.impl.highlighting.FragmentSide;
|
||||
import com.intellij.openapi.editor.ex.DocumentEx;
|
||||
import com.intellij.openapi.util.TextRange;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
|
||||
@@ -28,15 +27,16 @@ class SimpleChange extends Change implements DiffRangeMarker.RangeInvalidListene
|
||||
private final SimpleChangeSide[] mySides;
|
||||
private final ChangeList myChangeList;
|
||||
|
||||
public SimpleChange(@NotNull ChangeType type, @NotNull TextRange range1, @NotNull TextRange range2, @NotNull ChangeList changeList) {
|
||||
SimpleChange(@NotNull ChangeType type, @NotNull TextRange range1, @NotNull TextRange range2, @NotNull ChangeList changeList) {
|
||||
mySides = new SimpleChangeSide[]{ createSide(changeList, range1, FragmentSide.SIDE1),
|
||||
createSide(changeList, range2, FragmentSide.SIDE2)};
|
||||
myType = type;
|
||||
myChangeList = changeList;
|
||||
}
|
||||
|
||||
@NotNull
|
||||
private SimpleChangeSide createSide(@NotNull ChangeList changeList, @NotNull TextRange range1, @NotNull FragmentSide side) {
|
||||
return new SimpleChangeSide(side, new DiffRangeMarker((DocumentEx)changeList.getDocument(side), range1, this));
|
||||
return new SimpleChangeSide(side, new DiffRangeMarker(changeList.getDocument(side), range1, this));
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -55,19 +55,23 @@ class SimpleChange extends Change implements DiffRangeMarker.RangeInvalidListene
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void removeFromList() {
|
||||
myChangeList.remove(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
@NotNull
|
||||
public ChangeSide getChangeSide(@NotNull FragmentSide side) {
|
||||
return mySides[side.getIndex()];
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChangeType getType() {
|
||||
return myType;
|
||||
}
|
||||
|
||||
@Override
|
||||
public ChangeList getChangeList() {
|
||||
return myChangeList;
|
||||
}
|
||||
@@ -83,6 +87,7 @@ class SimpleChange extends Change implements DiffRangeMarker.RangeInvalidListene
|
||||
myChangeList.apply(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRemovedFromList() {
|
||||
for (int i = 0; i < mySides.length; i++) {
|
||||
SimpleChangeSide side = mySides[i];
|
||||
@@ -92,16 +97,18 @@ class SimpleChange extends Change implements DiffRangeMarker.RangeInvalidListene
|
||||
}
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isValid() {
|
||||
LOG.assertTrue((mySides[0] == null) == (mySides[1] == null));
|
||||
return mySides[0] != null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onRangeInvalidated() {
|
||||
myChangeList.remove(this);
|
||||
}
|
||||
|
||||
public static Change fromRanges(@NotNull TextRange baseRange, @NotNull TextRange versionRange, @NotNull ChangeList changeList) {
|
||||
static Change fromRanges(@NotNull TextRange baseRange, @NotNull TextRange versionRange, @NotNull ChangeList changeList) {
|
||||
ChangeType type = ChangeType.fromRanges(baseRange, versionRange);
|
||||
return new SimpleChange(type, baseRange, versionRange, changeList);
|
||||
}
|
||||
|
||||
@@ -95,7 +95,11 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
*/
|
||||
private int myDesiredX = -1;
|
||||
|
||||
private volatile MyRangeMarker mySelectionMarker;
|
||||
private volatile RangeMarker mySelectionMarker;
|
||||
private volatile VisualPosition myRangeMarkerStartPosition;
|
||||
private volatile VisualPosition myRangeMarkerEndPosition;
|
||||
private volatile boolean myRangeMarkerEndPositionIsLead;
|
||||
|
||||
private int startBefore;
|
||||
private int endBefore;
|
||||
boolean myUnknownDirection;
|
||||
@@ -140,7 +144,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
}
|
||||
|
||||
public void beforeDocumentChange() {
|
||||
MyRangeMarker marker = mySelectionMarker;
|
||||
RangeMarker marker = mySelectionMarker;
|
||||
if (marker != null && marker.isValid()) {
|
||||
startBefore = marker.getStartOffset();
|
||||
endBefore = marker.getEndOffset();
|
||||
@@ -148,7 +152,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
}
|
||||
|
||||
public void documentChanged() {
|
||||
MyRangeMarker marker = mySelectionMarker;
|
||||
RangeMarker marker = mySelectionMarker;
|
||||
if (marker != null) {
|
||||
int endAfter;
|
||||
int startAfter;
|
||||
@@ -164,7 +168,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
}
|
||||
else {
|
||||
startAfter = endAfter = getOffset();
|
||||
marker.release();
|
||||
marker.dispose();
|
||||
myStartVirtualOffset = 0;
|
||||
myEndVirtualOffset = 0;
|
||||
mySelectionMarker = null;
|
||||
@@ -189,6 +193,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
return;
|
||||
}
|
||||
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
final LogicalPosition logicalPosition = myEditor.offsetToLogicalPosition(offset);
|
||||
CaretEvent event = moveToLogicalPosition(logicalPosition, locateBeforeSoftWrap, null, false);
|
||||
@@ -203,12 +208,10 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
int inverseOffset = myEditor.logicalPositionToOffset(logicalPosition);
|
||||
LogMessageEx.error(
|
||||
LOG, "caret moved to wrong offset. Please submit a dedicated ticket and attach current editor's text to it.",
|
||||
String.format(
|
||||
"Requested: offset=%d, logical position='%s' but actual: offset=%d, logical position='%s' (%s). %s%n"
|
||||
+ "interested text [%d;%d): '%s'%n debug trace: %s%nLogical position -> offset ('%s'->'%d')",
|
||||
offset, logicalPosition, myOffset, myLogicalCaret, positionByOffsetAfterMove, myEditor.dumpState(),
|
||||
textStart, textEnd, text, debugBuffer, logicalPosition, inverseOffset
|
||||
)
|
||||
"Requested: offset=" + offset + ", logical position='" + logicalPosition + "' but actual: offset=" +
|
||||
myOffset + ", logical position='" + myLogicalCaret + "' (" + positionByOffsetAfterMove + "). " + myEditor.dumpState() +
|
||||
"\ninterested text [" + textStart + ";" + textEnd + "): '" + text + "'\n debug trace: " + debugBuffer +
|
||||
"\nLogical position -> offset ('" + logicalPosition + "'->'" + inverseOffset + "')"
|
||||
);
|
||||
}
|
||||
if (event != null) {
|
||||
@@ -251,6 +254,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
CopyPasteManager.getInstance().stopKillRings();
|
||||
}
|
||||
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SelectionModelImpl selectionModel = myEditor.getSelectionModel();
|
||||
final int leadSelectionOffset = getLeadSelectionOffset();
|
||||
@@ -431,6 +435,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
@Override
|
||||
public void moveToLogicalPosition(@NotNull final LogicalPosition pos) {
|
||||
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
moveToLogicalPosition(pos, false, null, true);
|
||||
}
|
||||
@@ -593,10 +598,9 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
}
|
||||
}
|
||||
else {
|
||||
LogMessageEx.error(LOG, "Invalid editor dimension mapping", String.format(
|
||||
"Expected to map visual position '%s' to offset %d but got the following: -> logical position '%s'; -> offset %d. "
|
||||
+ "State: %s", visualPosition, myOffset, logicalPosition, tmpOffset, myEditor.dumpState()
|
||||
));
|
||||
LogMessageEx.error(LOG, "Invalid editor dimension mapping", "Expected to map visual position '" +
|
||||
visualPosition + "' to offset " + myOffset + " but got the following: -> logical position '" +
|
||||
logicalPosition + "'; -> offset " + tmpOffset + ". State: " + myEditor.dumpState());
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -651,6 +655,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
@Override
|
||||
public void moveToVisualPosition(@NotNull final VisualPosition pos) {
|
||||
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
moveToVisualPosition(pos, true);
|
||||
}
|
||||
@@ -767,7 +772,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
@Override
|
||||
public void dispose() {
|
||||
if (mySelectionMarker != null) {
|
||||
mySelectionMarker.release();
|
||||
mySelectionMarker.dispose();
|
||||
mySelectionMarker = null;
|
||||
}
|
||||
releaseBulkCaretMarker();
|
||||
@@ -837,7 +842,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
/**
|
||||
* Recalculates caret visual position without changing its logical position (called when soft wraps are changing)
|
||||
*/
|
||||
public void updateVisualPosition() {
|
||||
void updateVisualPosition() {
|
||||
VerticalInfo oldInfo = myCaretInfo;
|
||||
LogicalPosition visUnawarePos = new LogicalPosition(myLogicalCaret.line, myLogicalCaret.column);
|
||||
setCurrentLogicalCaret(visUnawarePos);
|
||||
@@ -956,20 +961,20 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
return newOffset;
|
||||
}
|
||||
|
||||
CaretImpl cloneWithoutSelection() {
|
||||
private CaretImpl cloneWithoutSelection() {
|
||||
CaretImpl clone = new CaretImpl(myEditor);
|
||||
clone.myLogicalCaret = this.myLogicalCaret;
|
||||
clone.myCaretInfo = this.myCaretInfo;
|
||||
clone.myVisibleCaret = this.myVisibleCaret;
|
||||
clone.myOffset = this.myOffset;
|
||||
clone.myVirtualSpaceOffset = this.myVirtualSpaceOffset;
|
||||
clone.myVisualLineStart = this.myVisualLineStart;
|
||||
clone.myVisualLineEnd = this.myVisualLineEnd;
|
||||
clone.savedBeforeBulkCaretMarker = this.savedBeforeBulkCaretMarker;
|
||||
clone.mySkipChangeRequests = this.mySkipChangeRequests;
|
||||
clone.myLastColumnNumber = this.myLastColumnNumber;
|
||||
clone.myReportCaretMoves = this.myReportCaretMoves;
|
||||
clone.myDesiredX = this.myDesiredX;
|
||||
clone.myLogicalCaret = myLogicalCaret;
|
||||
clone.myCaretInfo = myCaretInfo;
|
||||
clone.myVisibleCaret = myVisibleCaret;
|
||||
clone.myOffset = myOffset;
|
||||
clone.myVirtualSpaceOffset = myVirtualSpaceOffset;
|
||||
clone.myVisualLineStart = myVisualLineStart;
|
||||
clone.myVisualLineEnd = myVisualLineEnd;
|
||||
clone.savedBeforeBulkCaretMarker = savedBeforeBulkCaretMarker;
|
||||
clone.mySkipChangeRequests = mySkipChangeRequests;
|
||||
clone.myLastColumnNumber = myLastColumnNumber;
|
||||
clone.myReportCaretMoves = myReportCaretMoves;
|
||||
clone.myDesiredX = myDesiredX;
|
||||
clone.myDesiredSelectionStartColumn = -1;
|
||||
clone.myDesiredSelectionEndColumn = -1;
|
||||
return clone;
|
||||
@@ -981,8 +986,12 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
assertIsDispatchThread();
|
||||
int lineShift = above ? -1 : 1;
|
||||
final CaretImpl clone = cloneWithoutSelection();
|
||||
final int newSelectionStartOffset, newSelectionEndOffset, newSelectionStartColumn, newSelectionEndColumn;
|
||||
final VisualPosition newSelectionStartPosition, newSelectionEndPosition;
|
||||
final int newSelectionStartOffset;
|
||||
final int newSelectionEndOffset;
|
||||
final int newSelectionStartColumn;
|
||||
final int newSelectionEndColumn;
|
||||
final VisualPosition newSelectionStartPosition;
|
||||
final VisualPosition newSelectionEndPosition;
|
||||
final boolean hasNewSelection;
|
||||
if (hasSelection() || myDesiredSelectionStartColumn >=0 || myDesiredSelectionEndColumn >= 0) {
|
||||
VisualPosition startPosition = getSelectionStartPosition();
|
||||
@@ -1060,7 +1069,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
* @return information on whether current selection's direction in known
|
||||
* @see #setUnknownDirection(boolean)
|
||||
*/
|
||||
public boolean isUnknownDirection() {
|
||||
boolean isUnknownDirection() {
|
||||
return myUnknownDirection;
|
||||
}
|
||||
|
||||
@@ -1076,9 +1085,8 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
* <b>Note:</b> when this method is called with <code>'true'</code>, subsequent calls are guaranteed to return <code>'true'</code>
|
||||
* until selection is changed. 'Unknown direction' flag is automatically reset then.
|
||||
*
|
||||
* @param unknownDirection
|
||||
*/
|
||||
public void setUnknownDirection(boolean unknownDirection) {
|
||||
void setUnknownDirection(boolean unknownDirection) {
|
||||
myUnknownDirection = unknownDirection;
|
||||
}
|
||||
|
||||
@@ -1086,7 +1094,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
public int getSelectionStart() {
|
||||
validateContext(false);
|
||||
if (hasSelection()) {
|
||||
MyRangeMarker marker = mySelectionMarker;
|
||||
RangeMarker marker = mySelectionMarker;
|
||||
if (marker != null) {
|
||||
return marker.getStartOffset();
|
||||
}
|
||||
@@ -1100,7 +1108,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
validateContext(false);
|
||||
VisualPosition position;
|
||||
if (hasSelection() && mySelectionMarker != null) {
|
||||
position = mySelectionMarker.getStartPosition();
|
||||
position = getRangeMarkerStartPosition();
|
||||
if (position == null) {
|
||||
position = myEditor.offsetToVisualPosition(mySelectionMarker.getStartOffset());
|
||||
}
|
||||
@@ -1118,7 +1126,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
public int getSelectionEnd() {
|
||||
validateContext(false);
|
||||
if (hasSelection()) {
|
||||
MyRangeMarker marker = mySelectionMarker;
|
||||
RangeMarker marker = mySelectionMarker;
|
||||
if (marker != null) {
|
||||
return marker.getEndOffset();
|
||||
}
|
||||
@@ -1132,7 +1140,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
validateContext(false);
|
||||
VisualPosition position;
|
||||
if (hasSelection() && mySelectionMarker != null) {
|
||||
position = mySelectionMarker.getEndPosition();
|
||||
position = getRangeMarkerEndPosition();
|
||||
if (position == null) {
|
||||
position = myEditor.offsetToVisualPosition(mySelectionMarker.getEndOffset());
|
||||
}
|
||||
@@ -1149,7 +1157,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
@Override
|
||||
public boolean hasSelection() {
|
||||
validateContext(false);
|
||||
MyRangeMarker marker = mySelectionMarker;
|
||||
RangeMarker marker = mySelectionMarker;
|
||||
return marker != null && marker.isValid() && (marker.getEndOffset() > marker.getStartOffset()
|
||||
|| isVirtualSelectionEnabled() && myEndVirtualOffset > myStartVirtualOffset);
|
||||
}
|
||||
@@ -1197,6 +1205,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
final boolean updateSystemSelection)
|
||||
{
|
||||
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
int startOffset = _startOffset;
|
||||
int endOffset = _endOffset;
|
||||
@@ -1255,24 +1264,24 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
oldSelectionStart = oldSelectionEnd = getOffset();
|
||||
}
|
||||
|
||||
MyRangeMarker marker = mySelectionMarker;
|
||||
RangeMarker marker = mySelectionMarker;
|
||||
if (marker != null) {
|
||||
marker.release();
|
||||
marker.dispose();
|
||||
}
|
||||
|
||||
marker = new MyRangeMarker((DocumentEx)doc, startOffset, endOffset);
|
||||
marker = doc.createRangeMarker(startOffset, endOffset);
|
||||
myStartVirtualOffset = 0;
|
||||
myEndVirtualOffset = 0;
|
||||
if (visualPositionAware) {
|
||||
if (endPosition.after(startPosition)) {
|
||||
marker.setStartPosition(startPosition);
|
||||
marker.setEndPosition(endPosition);
|
||||
marker.setEndPositionIsLead(false);
|
||||
setRangeMarkerStartPosition(startPosition);
|
||||
setRangeMarkerEndPosition(endPosition);
|
||||
setRangeMarkerEndPositionIsLead(false);
|
||||
}
|
||||
else {
|
||||
marker.setStartPosition(endPosition);
|
||||
marker.setEndPosition(startPosition);
|
||||
marker.setEndPositionIsLead(true);
|
||||
setRangeMarkerStartPosition(endPosition);
|
||||
setRangeMarkerEndPosition(startPosition);
|
||||
setRangeMarkerEndPositionIsLead(true);
|
||||
}
|
||||
|
||||
if (isVirtualSelectionEnabled() &&
|
||||
@@ -1314,15 +1323,16 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
return;
|
||||
}
|
||||
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
validateContext(true);
|
||||
myEditor.getSelectionModel().removeBlockSelection();
|
||||
int caretOffset = getOffset();
|
||||
MyRangeMarker marker = mySelectionMarker;
|
||||
RangeMarker marker = mySelectionMarker;
|
||||
if (marker != null) {
|
||||
int startOffset = marker.getStartOffset();
|
||||
int endOffset = marker.getEndOffset();
|
||||
marker.release();
|
||||
marker.dispose();
|
||||
mySelectionMarker = null;
|
||||
myStartVirtualOffset = 0;
|
||||
myEndVirtualOffset = 0;
|
||||
@@ -1337,7 +1347,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
validateContext(false);
|
||||
int caretOffset = getOffset();
|
||||
if (hasSelection()) {
|
||||
MyRangeMarker marker = mySelectionMarker;
|
||||
RangeMarker marker = mySelectionMarker;
|
||||
if (marker != null) {
|
||||
int startOffset = marker.getStartOffset();
|
||||
int endOffset = marker.getEndOffset();
|
||||
@@ -1369,7 +1379,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
@NotNull
|
||||
@Override
|
||||
public VisualPosition getLeadSelectionPosition() {
|
||||
MyRangeMarker marker = mySelectionMarker;
|
||||
RangeMarker marker = mySelectionMarker;
|
||||
VisualPosition caretPosition = getVisualPosition();
|
||||
if (isVirtualSelectionEnabled() && !hasSelection()) {
|
||||
return caretPosition;
|
||||
@@ -1378,8 +1388,8 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
return caretPosition;
|
||||
}
|
||||
|
||||
if (marker.isEndPositionIsLead()) {
|
||||
VisualPosition result = marker.getEndPosition();
|
||||
if (isRangeMarkerEndPositionIsLead()) {
|
||||
VisualPosition result = getRangeMarkerEndPosition();
|
||||
if (result == null) {
|
||||
return getSelectionEndPosition();
|
||||
}
|
||||
@@ -1391,7 +1401,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
}
|
||||
}
|
||||
else {
|
||||
VisualPosition result = marker.getStartPosition();
|
||||
VisualPosition result = getRangeMarkerStartPosition();
|
||||
if (result == null) {
|
||||
return getSelectionStartPosition();
|
||||
}
|
||||
@@ -1408,6 +1418,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
public void selectLineAtCaret() {
|
||||
validateContext(true);
|
||||
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
SelectionModelImpl.doSelectLineAtCaret(myEditor);
|
||||
}
|
||||
@@ -1418,6 +1429,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
public void selectWordAtCaret(final boolean honorCamelWordsSettings) {
|
||||
validateContext(true);
|
||||
myEditor.getCaretModel().doWithCaretMerging(new Runnable() {
|
||||
@Override
|
||||
public void run() {
|
||||
removeSelection();
|
||||
final EditorSettings settings = myEditor.getSettings();
|
||||
@@ -1481,7 +1493,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
|
||||
boolean hasVirtualSelection() {
|
||||
validateContext(false);
|
||||
MyRangeMarker marker = mySelectionMarker;
|
||||
RangeMarker marker = mySelectionMarker;
|
||||
return marker != null && marker.isValid() && isVirtualSelectionEnabled() && myEndVirtualOffset > myStartVirtualOffset;
|
||||
}
|
||||
|
||||
@@ -1503,7 +1515,7 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
/**
|
||||
* Encapsulates information about target vertical range info - its <code>'y'</code> coordinate and height in pixels.
|
||||
*/
|
||||
public static class VerticalInfo {
|
||||
private static class VerticalInfo {
|
||||
public final int y;
|
||||
public final int height;
|
||||
|
||||
@@ -1513,68 +1525,40 @@ public class CaretImpl extends UserDataHolderBase implements Caret {
|
||||
}
|
||||
}
|
||||
|
||||
private class MyRangeMarker extends RangeMarkerImpl {
|
||||
private VisualPosition myStartPosition;
|
||||
private VisualPosition myEndPosition;
|
||||
private boolean myEndPositionIsLead;
|
||||
private boolean myIsReleased;
|
||||
@Nullable
|
||||
private VisualPosition getRangeMarkerStartPosition() {
|
||||
invalidateRangeMarkerVisualPositions(mySelectionMarker);
|
||||
return myRangeMarkerStartPosition;
|
||||
}
|
||||
|
||||
MyRangeMarker(DocumentEx document, int start, int end) {
|
||||
super(document, start, end, true);
|
||||
myIsReleased = false;
|
||||
}
|
||||
private void setRangeMarkerStartPosition(@NotNull VisualPosition startPosition) {
|
||||
myRangeMarkerStartPosition = startPosition;
|
||||
}
|
||||
|
||||
public void release() {
|
||||
myIsReleased = true;
|
||||
dispose();
|
||||
}
|
||||
@Nullable
|
||||
private VisualPosition getRangeMarkerEndPosition() {
|
||||
invalidateRangeMarkerVisualPositions(mySelectionMarker);
|
||||
return myRangeMarkerEndPosition;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public VisualPosition getStartPosition() {
|
||||
invalidateVisualPositions();
|
||||
return myStartPosition;
|
||||
}
|
||||
void setRangeMarkerEndPosition(@NotNull VisualPosition endPosition) {
|
||||
myRangeMarkerEndPosition = endPosition;
|
||||
}
|
||||
|
||||
public void setStartPosition(@NotNull VisualPosition startPosition) {
|
||||
myStartPosition = startPosition;
|
||||
}
|
||||
private boolean isRangeMarkerEndPositionIsLead() {
|
||||
return myRangeMarkerEndPositionIsLead;
|
||||
}
|
||||
|
||||
@Nullable
|
||||
public VisualPosition getEndPosition() {
|
||||
invalidateVisualPositions();
|
||||
return myEndPosition;
|
||||
}
|
||||
void setRangeMarkerEndPositionIsLead(boolean endPositionIsLead) {
|
||||
myRangeMarkerEndPositionIsLead = endPositionIsLead;
|
||||
}
|
||||
|
||||
public void setEndPosition(@NotNull VisualPosition endPosition) {
|
||||
myEndPosition = endPosition;
|
||||
}
|
||||
|
||||
public boolean isEndPositionIsLead() {
|
||||
return myEndPositionIsLead;
|
||||
}
|
||||
|
||||
public void setEndPositionIsLead(boolean endPositionIsLead) {
|
||||
myEndPositionIsLead = endPositionIsLead;
|
||||
}
|
||||
|
||||
int startBefore;
|
||||
int endBefore;
|
||||
|
||||
@Override
|
||||
protected void changedUpdateImpl(DocumentEvent e) {
|
||||
if (myIsReleased) return;
|
||||
startBefore = getStartOffset();
|
||||
endBefore = getEndOffset();
|
||||
super.changedUpdateImpl(e);
|
||||
}
|
||||
|
||||
private void invalidateVisualPositions() {
|
||||
SoftWrapModelImpl model = myEditor.getSoftWrapModel();
|
||||
if (!myEditor.offsetToVisualPosition(getStartOffset()).equals(myStartPosition) && model.getSoftWrap(getStartOffset()) == null
|
||||
|| !myEditor.offsetToVisualPosition(getEndOffset()).equals(myEndPosition) && model.getSoftWrap(getEndOffset()) == null) {
|
||||
myStartPosition = null;
|
||||
myEndPosition = null;
|
||||
}
|
||||
private void invalidateRangeMarkerVisualPositions(RangeMarker marker) {
|
||||
SoftWrapModelImpl model = myEditor.getSoftWrapModel();
|
||||
if (!myEditor.offsetToVisualPosition(marker.getStartOffset()).equals(myRangeMarkerStartPosition) && model.getSoftWrap(marker.getStartOffset()) == null
|
||||
|| !myEditor.offsetToVisualPosition(marker.getEndOffset()).equals(myRangeMarkerEndPosition) && model.getSoftWrap(marker.getEndOffset()) == null) {
|
||||
myRangeMarkerStartPosition = null;
|
||||
myRangeMarkerEndPosition = null;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
/*
|
||||
* Copyright 2000-2011 JetBrains s.r.o.
|
||||
* Copyright 2000-2014 JetBrains s.r.o.
|
||||
*
|
||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||
* you may not use this file except in compliance with the License.
|
||||
@@ -31,7 +31,7 @@ import com.intellij.openapi.editor.ex.DocumentEx;
|
||||
import org.jetbrains.annotations.NotNull;
|
||||
import org.jetbrains.annotations.Nullable;
|
||||
|
||||
public class FoldRegionImpl extends RangeMarkerImpl implements FoldRegion {
|
||||
class FoldRegionImpl extends RangeMarkerImpl implements FoldRegion {
|
||||
private boolean myIsExpanded;
|
||||
private final Editor myEditor;
|
||||
private final String myPlaceholderText;
|
||||
@@ -94,7 +94,7 @@ public class FoldRegionImpl extends RangeMarkerImpl implements FoldRegion {
|
||||
return super.isValid() && intervalStart() < intervalEnd();
|
||||
}
|
||||
|
||||
public void setExpandedInternal(boolean toExpand) {
|
||||
void setExpandedInternal(boolean toExpand) {
|
||||
myIsExpanded = toExpand;
|
||||
}
|
||||
|
||||
@@ -120,6 +120,7 @@ public class FoldRegionImpl extends RangeMarkerImpl implements FoldRegion {
|
||||
return myShouldNeverExpand;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String toString() {
|
||||
return "FoldRegion " + (myIsExpanded ? "-" : "+") + "(" + getStartOffset() + ":" + getEndOffset() + ")"
|
||||
+ (isValid() ? "" : "(invalid)") + ", placeholder='" + myPlaceholderText + "'";
|
||||
|
||||
Reference in New Issue
Block a user