Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -281,23 +281,23 @@ private void computeExpectedExecutionCosts() {
}

/**
* An {@link IDocumentListener} that makes sure that {@link #fVisibleRegionDuringProjection} is
* updated when the document changes and ensures that the collapsed region after the visible
* region is recreated appropriately.
* An {@link IDocumentListener} that makes sure that {@link #fConfiguredVisibleRegion} is updated when the
* document changes and ensures that the collapsed region after the visible region is recreated
* appropriately.
*/
private final class UpdateDocumentListener implements IDocumentListener {
@Override
public void documentChanged(DocumentEvent event) {
if (fVisibleRegionDuringProjection == null) {
if (fConfiguredVisibleRegion == null) {
return;
}
int oldLength= event.getLength();
int newLength= event.getText().length();
int oldVisibleRegionEnd= fVisibleRegionDuringProjection.getOffset() + fVisibleRegionDuringProjection.getLength();
if (event.getOffset() < fVisibleRegionDuringProjection.getOffset()) {
fVisibleRegionDuringProjection= new Region(fVisibleRegionDuringProjection.getOffset() + newLength - oldLength, fVisibleRegionDuringProjection.getLength());
int oldVisibleRegionEnd= fConfiguredVisibleRegion.getOffset() + fConfiguredVisibleRegion.getLength();
if (event.getOffset() < fConfiguredVisibleRegion.getOffset()) {
fConfiguredVisibleRegion= new Region(fConfiguredVisibleRegion.getOffset() + newLength - oldLength, fConfiguredVisibleRegion.getLength());
} else if (event.getOffset() + oldLength <= oldVisibleRegionEnd) {
fVisibleRegionDuringProjection= new Region(fVisibleRegionDuringProjection.getOffset(), fVisibleRegionDuringProjection.getLength() + newLength - oldLength);
fConfiguredVisibleRegion= new Region(fConfiguredVisibleRegion.getOffset(), fConfiguredVisibleRegion.getLength() + newLength - oldLength);
}
}

Expand All @@ -324,13 +324,11 @@ public void documentAboutToBeChanged(DocumentEvent event) {
private List<AnnotationModelEvent> fPendingRequests= new ArrayList<>();
/** The replace-visible-document execution trigger */
private IDocument fReplaceVisibleDocumentExecutionTrigger;
/** <code>true</code> if projection was on the last time we switched to segmented mode. */
private boolean fWasProjectionEnabled;
/**
* The region set by {@link #setVisibleRegion(int, int)} during projection or <code>null</code>
* if not in a projection
* The region set by {@link #setVisibleRegion(int, int)} or <code>null</code>
* if no visible region has been set
*/
private IRegion fVisibleRegionDuringProjection;
private IRegion fConfiguredVisibleRegion;
/** The queue of projection commands used to assess the costs of projection changes. */
private ProjectionCommandQueue fCommandQueue;
/**
Expand All @@ -340,7 +338,7 @@ public void documentAboutToBeChanged(DocumentEvent event) {
*/
private int fDeletedLines;

private UpdateDocumentListener fUpdateDocumentListener;
private final UpdateDocumentListener fUpdateDocumentListener;

/**
* Creates a new projection source viewer.
Expand Down Expand Up @@ -400,12 +398,15 @@ public void setDocument(IDocument document, IAnnotationModel annotationModel, in
}

if (fProjectionAnnotationModel != null) {
removeDocumentUpdateListener();
wasProjectionEnabled= removeProjectionAnnotationModel(getVisualAnnotationModel()) != null;
fProjectionAnnotationModel= null;
}

removeDocumentUpdateListener();
super.setDocument(document, annotationModel, modelRangeOffset, modelRangeLength);
if (document != null) {
document.addDocumentListener(fUpdateDocumentListener);
}

if (wasProjectionEnabled && document != null) {
enableProjection();
Expand Down Expand Up @@ -560,9 +561,9 @@ public final void disableProjection() {
fProjectionAnnotationModel.removeAllAnnotations();
fFindReplaceDocumentAdapter= null;
fireProjectionDisabled();
if (fVisibleRegionDuringProjection != null) {
super.setVisibleRegion(fVisibleRegionDuringProjection.getOffset(), fVisibleRegionDuringProjection.getLength());
fVisibleRegionDuringProjection= null;
if (fConfiguredVisibleRegion != null) {
super.setVisibleRegion(fConfiguredVisibleRegion.getOffset(), fConfiguredVisibleRegion.getLength());
fConfiguredVisibleRegion= null;
}
removeDocumentUpdateListener();
}
Expand All @@ -580,8 +581,9 @@ public final void enableProjection() {
if (document == null) {
return;
}
IRegion visibleRegion= getVisibleRegion();
IRegion visibleRegion= fConfiguredVisibleRegion;
if (visibleRegion != null && (visibleRegion.getOffset() != 0 || visibleRegion.getLength() != 0) && visibleRegion.getLength() < document.getLength()) {
fConfiguredVisibleRegion= null;
setVisibleRegion(visibleRegion.getOffset(), visibleRegion.getLength());
}
document.addDocumentListener(fUpdateDocumentListener);
Expand All @@ -593,9 +595,9 @@ private void expandAll() {
IDocument doc= getDocument();
int length= doc == null ? 0 : doc.getLength();
if (isProjectionMode()) {
if (fVisibleRegionDuringProjection != null) {
offset= fVisibleRegionDuringProjection.getOffset();
length= fVisibleRegionDuringProjection.getLength();
if (fConfiguredVisibleRegion != null) {
offset= fConfiguredVisibleRegion.getOffset();
length= fConfiguredVisibleRegion.getLength();
}
fProjectionAnnotationModel.expandAll(offset, length);
}
Expand Down Expand Up @@ -757,6 +759,7 @@ private int toLineStart(IDocument document, int offset, boolean testLastLine) th
public void setVisibleRegion(int start, int length) {
if (!isProjectionMode()) {
super.setVisibleRegion(start, length);
fConfiguredVisibleRegion= new Region(start, length);
return;
}
IDocument document= getDocument();
Expand All @@ -769,17 +772,17 @@ public void setVisibleRegion(int start, int length) {
int end= computeEndOfVisibleRegion(start, length, document);
expandOutsideCurrentVisibleRegion(document);
collapseOutsideOfNewVisibleRegion(start, end, document);
fVisibleRegionDuringProjection= new Region(start, end - start - 1);
fConfiguredVisibleRegion= new Region(start, end - start - 1);
} catch (BadLocationException e) {
ILog log= ILog.of(getClass());
log.log(new Status(IStatus.WARNING, getClass(), IStatus.OK, null, e));
}
}

private void expandOutsideCurrentVisibleRegion(IDocument document) throws BadLocationException {
if (fVisibleRegionDuringProjection != null) {
expand(0, fVisibleRegionDuringProjection.getOffset(), false, true);
int oldEnd= fVisibleRegionDuringProjection.getOffset() + fVisibleRegionDuringProjection.getLength();
if (fConfiguredVisibleRegion != null) {
expand(0, fConfiguredVisibleRegion.getOffset(), false, true);
int oldEnd= fConfiguredVisibleRegion.getOffset() + fConfiguredVisibleRegion.getLength();
int length= document.getLength() - oldEnd;
if (length > 0) {
expand(oldEnd, length, false, true);
Expand Down Expand Up @@ -841,16 +844,23 @@ protected void setVisibleDocument(IDocument document) {

@Override
public void resetVisibleRegion() {
super.resetVisibleRegion();
if (fWasProjectionEnabled) {
enableProjection();
if (isProjectionMode()) {
try {
expandOutsideCurrentVisibleRegion(getDocument());
} catch (BadLocationException e) {
ILog log= ILog.of(getClass());
log.log(new Status(IStatus.WARNING, getClass(), IStatus.OK, null, e));
}
} else {
super.resetVisibleRegion();
}
fConfiguredVisibleRegion= null;
}

@Override
public IRegion getVisibleRegion() {
if (fVisibleRegionDuringProjection != null) {
return fVisibleRegionDuringProjection;
if (isProjectionMode() && fConfiguredVisibleRegion != null) {
return fConfiguredVisibleRegion;
}
IRegion visibleRegion= getModelCoverage();
if (visibleRegion == null) {
Expand All @@ -862,8 +872,8 @@ public IRegion getVisibleRegion() {

@Override
public boolean overlapsWithVisibleRegion(int offset, int length) {
if (fVisibleRegionDuringProjection != null) {
return TextUtilities.overlaps(fVisibleRegionDuringProjection, new Region(offset, length));
if (isProjectionMode() && fConfiguredVisibleRegion != null) {
return TextUtilities.overlaps(fConfiguredVisibleRegion, new Region(offset, length));
}
IRegion coverage= getModelCoverage();
if (coverage == null) {
Expand Down Expand Up @@ -999,9 +1009,14 @@ private void expand(int offset, int length, boolean fireRedraw, boolean performO
}
}

private boolean overlapsWithNonVisibleRegions(int offset, int length) {
return fVisibleRegionDuringProjection != null
&& (offset < fVisibleRegionDuringProjection.getOffset() || offset + length > fVisibleRegionDuringProjection.getOffset() + fVisibleRegionDuringProjection.getLength());
private boolean overlapsWithNonVisibleRegions(int offset, int length) throws BadLocationException {
if (fConfiguredVisibleRegion == null) {
return false;
}
// ignore overlaps within the same line
int visibleRegionStartLineOffset= getDocument().getLineInformationOfOffset(fConfiguredVisibleRegion.getOffset()).getOffset();
int regionToCheckEndLineOffset= getDocument().getLineInformationOfOffset(offset + length).getOffset();
return offset < visibleRegionStartLineOffset || regionToCheckEndLineOffset > fConfiguredVisibleRegion.getOffset() + fConfiguredVisibleRegion.getLength();
}

/**
Expand Down Expand Up @@ -1486,7 +1501,6 @@ private boolean willAutoExpand(Position position, int offset, int length) {

@Override
protected void handleDispose() {
fWasProjectionEnabled= false;
removeDocumentUpdateListener();
super.handleDispose();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -417,6 +417,9 @@ private void internalRemoveMasterDocumentRange(int offsetInMaster, int lengthInM
if (fragment.getOffset() == offsetInMaster) {
fragment.setOffset(offsetInMaster + lengthInMaster);
fragment.setLength(fragment.getLength() - lengthInMaster);
if (fragment.getLength() == 0 && offsetInMaster != 0 && offsetInMaster + lengthInMaster == getMasterDocument().getLength()) {
fragment.setOffset(offsetInMaster);
}
} else {
// split fragment into three fragments, let position updater remove it

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -27,6 +27,7 @@
import org.junit.Assert;
import org.junit.Before;
import org.junit.Test;
import org.junit.jupiter.api.Assertions;

import org.eclipse.jface.text.BadLocationException;
import org.eclipse.jface.text.DefaultLineTracker;
Expand Down Expand Up @@ -2652,4 +2653,39 @@ public void test29_38() {
assertTrue(false);
}
}

@Test
public void testFullDocumentRangeRemovedAtOnce() throws BadLocationException {
fSlaveDocument.addMasterDocumentRange(0, fMasterDocument.getLength());
fSlaveDocument.removeMasterDocumentRange(0, fMasterDocument.getLength());
Assertions.assertEquals("", fSlaveDocument.get());
Position[] fragments = fSlaveDocument.getFragments2();
Assertions.assertEquals(1, fragments.length);
Assertions.assertEquals(new Position(fMasterDocument.getLength(), 0), fragments[0]);
}

@Test
public void testFullDocumentRangeRemovedInTwoParts() throws BadLocationException {
fSlaveDocument.addMasterDocumentRange(0, fMasterDocument.getLength());
fSlaveDocument.removeMasterDocumentRange(0, 10);
Assertions.assertEquals(fMasterDocument.getLength() - 10, fSlaveDocument.getLength());
fSlaveDocument.removeMasterDocumentRange(10, fMasterDocument.getLength() - 10);
Assertions.assertEquals("", fSlaveDocument.get());
Position[] fragments = fSlaveDocument.getFragments2();
Assertions.assertEquals(1, fragments.length);
Assertions.assertEquals(new Position(10, 0), fragments[0]);
}

@Test
public void testRemovePartsOfDocument() throws BadLocationException {
fSlaveDocument.addMasterDocumentRange(0, fMasterDocument.getLength());
fSlaveDocument.removeMasterDocumentRange(0, 10);
Assertions.assertEquals(fMasterDocument.getLength() - 10, fSlaveDocument.getLength());
fSlaveDocument.removeMasterDocumentRange(10, fMasterDocument.getLength() - 20);
Assertions.assertEquals(fMasterDocument.get(fMasterDocument.getLength() - 10, 10),
fSlaveDocument.get());
Position[] fragments = fSlaveDocument.getFragments2();
Assertions.assertEquals(1, fragments.length);
Assertions.assertEquals(new Position(fMasterDocument.getLength() - 10, 10), fragments[0]);
}
}
Loading