diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProvider.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProvider.java index f0f1370257f..c4281899d1e 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProvider.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProvider.java @@ -19,9 +19,6 @@ import org.eclipse.swt.custom.StyledText; -import org.eclipse.jface.text.ITextViewerExtension5; -import org.eclipse.jface.text.source.ISourceViewer; - /** * This class provides sticky lines for the given source code in the source viewer. The * implementation is completely based on indentation and therefore works by default for several @@ -36,83 +33,31 @@ public class DefaultStickyLinesProvider implements IStickyLinesProvider { private StickyLinesProperties fProperties; @Override - public List getStickyLines(ISourceViewer sourceViewer, StickyLinesProperties properties) { - if (sourceViewer.getTopIndex() == 0) { - return Collections.emptyList(); - } - + public List getStickyLines(StyledText textWidget, int lineNumber, StickyLinesProperties properties) { this.fProperties= properties; LinkedList stickyLines= new LinkedList<>(); try { - StyledText textWidget= sourceViewer.getTextWidget(); - int startLine= textWidget.getTopIndex(); + int startIndetation= getStartIndentation(lineNumber, textWidget); - calculateStickyLinesForLineNumber(stickyLines, sourceViewer, startLine); - calculateStickyLinesUnderStickyLineControl(stickyLines, sourceViewer, startLine); - } catch (IllegalArgumentException e) { - stickyLines.clear(); - } + for (int i= lineNumber, previousIndetation= startIndetation; i >= 0; i--) { + String line= textWidget.getLine(i); + int indentation= getIndentation(line); - return stickyLines; - } + if (indentation == IGNORE_LINE_INDENTATION) { + continue; + } - private void calculateStickyLinesForLineNumber(LinkedList stickyLines, ISourceViewer sourceViewer, int lineNumber) { - StyledText textWidget= sourceViewer.getTextWidget(); - int startIndetation= getStartIndentation(lineNumber, textWidget); - - for (int i= lineNumber, previousIndetation= startIndetation; i >= 0; i--) { - String line= textWidget.getLine(i); - int indentation= getIndentation(line); - - if (indentation == IGNORE_LINE_INDENTATION) { - continue; - } - - if (indentation < previousIndetation) { - previousIndetation= indentation; - stickyLines.addFirst(new StickyLine(line, mapLineNumberToSourceViewerLine(i, sourceViewer))); - } - } - } - - private void calculateStickyLinesUnderStickyLineControl(LinkedList stickyLines, ISourceViewer sourceViewer, int startLine) { - int firstBelowControl= startLine + stickyLines.size(); - StyledText textWidget= sourceViewer.getTextWidget(); - int lineCount= textWidget.getLineCount(); - - for (int i= startLine; i < firstBelowControl && i < lineCount; i++) { - - String line= textWidget.getLine(i); - int indentation= getIndentation(line); - if (indentation == IGNORE_LINE_INDENTATION) { - continue; - } - - while (!stickyLines.isEmpty() && indentation <= getLastStickyLineIndentation(stickyLines) && i < firstBelowControl) { - stickyLines.removeLast(); - firstBelowControl--; - } - - String nextContentLine= getNextContentLine(i, textWidget); - if (getIndentation(nextContentLine) > indentation && i < firstBelowControl) { - stickyLines.addLast(new StickyLine(line, mapLineNumberToSourceViewerLine(i, sourceViewer))); - firstBelowControl++; - continue; + if (indentation < previousIndetation) { + previousIndetation= indentation; + stickyLines.addFirst(new StickyLine(line, i)); + } } + } catch (IllegalArgumentException e) { + stickyLines.clear(); } - } - private int getLastStickyLineIndentation(LinkedList stickyLines) { - String text= stickyLines.getLast().text(); - return getIndentation(text); - } - - private int mapLineNumberToSourceViewerLine(int lineNumber, ISourceViewer sourceViewer) { - if (sourceViewer instanceof ITextViewerExtension5 extension) { - return extension.widgetLine2ModelLine(lineNumber); - } - return lineNumber; + return stickyLines; } private int getStartIndentation(int startFromLine, StyledText styledText) { diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/IStickyLinesProvider.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/IStickyLinesProvider.java index 677ae114cd3..6b0b92dbd44 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/IStickyLinesProvider.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/IStickyLinesProvider.java @@ -28,26 +28,28 @@ public interface IStickyLinesProvider { /** - * Calculate the sticky lines for the source code of the given sourceViewer. Specific - * properties, such as the tabWidht can be retrieved from the - * properties. + * Calculate the sticky lines for the source code of the given textWidget. Specific properties, + * such as the tabWidht can be retrieved from the properties. To get + * access to additional information, the source viewer can be used. * - * @param sourceViewer The source viewer containing the source code and information about the - * first visible line + * @param textWidget The text widget containing the source code + * @param lineNumber The line number to calculate the sticky lines for + * @param properties Properties for additional information * @return The list of sticky lines to show * * @see ISourceViewer#getTopIndex() * @see ISourceViewer#getTextWidget() * @see StyledText#getTopIndex() */ - public List getStickyLines(ISourceViewer sourceViewer, StickyLinesProperties properties); + public List getStickyLines(StyledText textWidget, int lineNumber, StickyLinesProperties properties); /** - * Properties required to calculate the sticky lines. + * Additional properties and access in order to calculate the sticky lines. * * @param tabWith The with of a tab + * @param sourceViewer The sourceViewer to access additional information */ - record StickyLinesProperties(int tabWith) { + record StickyLinesProperties(int tabWith, ISourceViewer sourceViewer) { } } diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControl.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControl.java index 414abd5c19c..51179e8c130 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControl.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControl.java @@ -208,7 +208,8 @@ private void updateStickyScrollingControls() { for (int i= 0; i < getNumberStickyLines(); i++) { StickyLine stickyLine= stickyLines.get(i); stickyLineTextJoiner.add(stickyLine.text()); - stickyLineNumberJoiner.add(fillLineNumberWithLeadingSpaces(stickyLine.lineNumber() + 1)); + int lineNumber= getSourceViewerLineNumber(stickyLine.lineNumber()); + stickyLineNumberJoiner.add(fillLineNumberWithLeadingSpaces(lineNumber + 1)); } String newStickyLineText= stickyLineTextJoiner.toString(); @@ -223,6 +224,13 @@ private void updateStickyScrollingControls() { } } + private int getSourceViewerLineNumber(int i) { + if (sourceViewer instanceof ITextViewerExtension5 extension) { + return extension.widgetLine2ModelLine(i); + } + return i; + } + private String fillLineNumberWithLeadingSpaces(int lineNumber) { int lineCount= sourceViewer.getDocument().getNumberOfLines(); int lineNumberLength= String.valueOf(lineCount).length(); @@ -257,9 +265,6 @@ private void styleStickyLines() { private List getStickyLineStyleRanges(StickyLine stickyLine, int stickyLineTextOffset) { int lineNumber= stickyLine.lineNumber(); - if (sourceViewer instanceof ITextViewerExtension5 extension) { - lineNumber= extension.modelLine2WidgetLine(lineNumber); - } try { StyledText textWidget= sourceViewer.getTextWidget(); int offsetAtLine= textWidget.getOffsetAtLine(lineNumber); diff --git a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandler.java b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandler.java index 432ee38f381..df2ea6bee66 100644 --- a/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandler.java +++ b/bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandler.java @@ -22,8 +22,10 @@ import java.time.Duration; import java.util.Collections; +import java.util.LinkedList; import java.util.List; +import org.eclipse.swt.custom.StyledText; import org.eclipse.swt.graphics.Color; import org.eclipse.swt.graphics.RGB; @@ -138,7 +140,7 @@ private StickyScrollingControlSettings loadControlSettings(IPreferenceStore stor private StickyLinesProperties loadStickyLinesProperties(IPreferenceStore store) { int tabWidth= store.getInt(EDITOR_TAB_WIDTH); - return new StickyLinesProperties(tabWidth); + return new StickyLinesProperties(tabWidth, sourceViewer); } @Override @@ -151,13 +153,52 @@ public void viewportChanged(int newVerticalOffset) { } private void calculateAndShowStickyLines() { - List stickyLines= stickyLinesProvider.getStickyLines(sourceViewer, stickyLinesProperties); + List stickyLines= Collections.emptyList(); + + StyledText textWidget= sourceViewer.getTextWidget(); + int startLine= textWidget.getTopIndex(); + + if (startLine > 0) { + stickyLines= stickyLinesProvider.getStickyLines(textWidget, startLine, stickyLinesProperties); + } + if (stickyLines == null) { stickyLines= Collections.emptyList(); } + + stickyLines= adaptStickyLinesToVisibleArea(stickyLines, startLine); + stickyScrollingControl.setStickyLines(stickyLines); } + private List adaptStickyLinesToVisibleArea(List stickyLines, int startLine) { + if (stickyLines.isEmpty()) { + return stickyLines; + } + + LinkedList adaptedStickyLines= new LinkedList<>(stickyLines); + + int firstVisibleLine= startLine + adaptedStickyLines.size(); + StyledText textWidget= sourceViewer.getTextWidget(); + int maximumLines= textWidget.getLineCount(); + + for (int i= startLine + 1; i <= firstVisibleLine && i < maximumLines; i++) { + List stickyLinesInLineI= stickyLinesProvider.getStickyLines(textWidget, i, stickyLinesProperties); + + if (stickyLinesInLineI.size() > adaptedStickyLines.size()) { + adaptedStickyLines= new LinkedList<>(stickyLinesInLineI); + firstVisibleLine= startLine + adaptedStickyLines.size(); + } + + while (stickyLinesInLineI.size() < adaptedStickyLines.size() && i < firstVisibleLine) { + adaptedStickyLines.removeLast(); + firstVisibleLine--; + } + } + + return adaptedStickyLines; + } + /** * Uninstalls the sticky scrolling handler from the source viewer. This completely disposes the * {@link StickyScrollingControl} and removes all corresponding listeners. diff --git a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProviderTest.java b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProviderTest.java index 5e9fd440589..afd782d5f91 100644 --- a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProviderTest.java +++ b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/DefaultStickyLinesProviderTest.java @@ -25,13 +25,9 @@ import org.eclipse.swt.SWT; import org.eclipse.swt.custom.StyledText; -import org.eclipse.swt.widgets.Composite; import org.eclipse.swt.widgets.Display; import org.eclipse.swt.widgets.Shell; -import org.eclipse.jface.text.IRegion; -import org.eclipse.jface.text.ITextViewerExtension5; -import org.eclipse.jface.text.source.IVerticalRuler; import org.eclipse.jface.text.source.SourceViewer; import org.eclipse.ui.internal.texteditor.stickyscroll.IStickyLinesProvider.StickyLinesProperties; @@ -50,12 +46,12 @@ public void setup() { sourceViewer = new SourceViewer(shell, null, SWT.None); stickyLinesProvider = new DefaultStickyLinesProvider(); textWidget = sourceViewer.getTextWidget(); - stickyLinesProperties = new StickyLinesProperties(4); + stickyLinesProperties = new StickyLinesProperties(4, sourceViewer); } @Test public void testEmptySourceCode() { - List stickyLines = stickyLinesProvider.getStickyLines(sourceViewer, stickyLinesProperties); + List stickyLines = stickyLinesProvider.getStickyLines(textWidget, 0, stickyLinesProperties); assertThat(stickyLines, is(empty())); } @@ -67,7 +63,7 @@ public void testSingleStickyLine() { line 2<"""; setText(text); - List stickyLines = stickyLinesProvider.getStickyLines(sourceViewer, stickyLinesProperties); + List stickyLines = stickyLinesProvider.getStickyLines(textWidget, 1, stickyLinesProperties); assertThat(stickyLines, contains(new StickyLine("line 1", 0))); } @@ -81,9 +77,9 @@ public void testLineUnderStickyLine() { line 4"""; setText(text); - List stickyLines = stickyLinesProvider.getStickyLines(sourceViewer, stickyLinesProperties); + List stickyLines = stickyLinesProvider.getStickyLines(textWidget, 1, stickyLinesProperties); - assertThat(stickyLines, contains(new StickyLine("line 1", 0), new StickyLine(" line 2<", 1))); + assertThat(stickyLines, contains(new StickyLine("line 1", 0))); } @Test @@ -95,7 +91,7 @@ public void testNewStickyRoot() { line 4<"""; setText(text); - List stickyLines = stickyLinesProvider.getStickyLines(sourceViewer, stickyLinesProperties); + List stickyLines = stickyLinesProvider.getStickyLines(textWidget, 3, stickyLinesProperties); assertThat(stickyLines, contains(new StickyLine("line 3", 2))); } @@ -110,24 +106,23 @@ public void testIgnoreEmptyLines() { line 3<"""; setText(text); - List stickyLines = stickyLinesProvider.getStickyLines(sourceViewer, stickyLinesProperties); + List stickyLines = stickyLinesProvider.getStickyLines(textWidget, 4, stickyLinesProperties); assertThat(stickyLines, contains(new StickyLine("line 1", 0), new StickyLine(" line 2", 2))); } @Test public void testLinesWithTabs() { - stickyLinesProperties = new StickyLinesProperties(2); + stickyLinesProperties = new StickyLinesProperties(2, sourceViewer); String text = """ line 1 \tline 2 \t\tline 3<"""; setText(text); - List stickyLines = stickyLinesProvider.getStickyLines(sourceViewer, stickyLinesProperties); + List stickyLines = stickyLinesProvider.getStickyLines(textWidget, 2, stickyLinesProperties); assertThat(stickyLines, contains(new StickyLine("line 1", 0), new StickyLine("\tline 2", 1))); - } @Test @@ -141,10 +136,9 @@ public void testStartAtEmptyLineWithNext() { textWidget.setText(text); textWidget.setTopIndex(3); - List stickyLines = stickyLinesProvider.getStickyLines(sourceViewer, stickyLinesProperties); + List stickyLines = stickyLinesProvider.getStickyLines(textWidget, 3, stickyLinesProperties); assertThat(stickyLines, contains(new StickyLine("line 1", 0), new StickyLine(" line 2", 2))); - } @Test @@ -152,42 +146,14 @@ public void testStartAtEmptyLineWithPrevious() { String text = """ line 1 line 2 - line 3< - line 4"""; - setText(text); - - List stickyLines = stickyLinesProvider.getStickyLines(sourceViewer, stickyLinesProperties); - - assertThat(stickyLines, contains(new StickyLine("line 1", 0))); - } - - @Test - public void testRemoveStickyLines() { - String text = """ - line 1 - line 2 - line 3 - line 4<"""; - setText(text); - - List stickyLines = stickyLinesProvider.getStickyLines(sourceViewer, stickyLinesProperties); - - assertThat(stickyLines, contains(new StickyLine("line 3", 2))); - } - - @Test - public void testSourceViewerWithDifferentModelAndWindgetLines() { - sourceViewer = new SourceViewerLineMapping(shell, null, SWT.None); - textWidget = sourceViewer.getTextWidget(); + line 3 - String text = """ - line 1 - line 2<"""; + line 4"""; setText(text); - List stickyLines = stickyLinesProvider.getStickyLines(sourceViewer, stickyLinesProperties); + List stickyLines = stickyLinesProvider.getStickyLines(textWidget, 3, stickyLinesProperties); - assertThat(stickyLines, contains(new StickyLine("line 1", 42))); + assertThat(stickyLines, contains(new StickyLine("line 1", 0), new StickyLine(" line 2", 1))); } /** @@ -196,37 +162,6 @@ public void testSourceViewerWithDifferentModelAndWindgetLines() { */ private void setText(String text) { textWidget.setText(text); - - String[] lines = text.split("\n"); - for (int i = 0; i < lines.length; i++) { - if (lines[i].contains(String.valueOf("<"))) { - textWidget.setTopIndex(i); - return; - } - } - } - - private class SourceViewerLineMapping extends SourceViewer implements ITextViewerExtension5 { - - public SourceViewerLineMapping(Composite parent, IVerticalRuler ruler, int styles) { - super(parent, ruler, styles); - } - - @Override - public IRegion[] getCoveredModelRanges(IRegion modelRange) { - return null; - } - - @Override - public boolean exposeModelRange(IRegion modelRange) { - return false; - } - - @Override - public int widgetLine2ModelLine(int widgetLine) { - return 42; - } - } } diff --git a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControlTest.java b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControlTest.java index 031e3cfa623..2d0999e6b4d 100644 --- a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControlTest.java +++ b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingControlTest.java @@ -43,6 +43,8 @@ import org.eclipse.swt.widgets.Shell; import org.eclipse.jface.text.Document; +import org.eclipse.jface.text.IRegion; +import org.eclipse.jface.text.ITextViewerExtension5; import org.eclipse.jface.text.source.IVerticalRuler; import org.eclipse.jface.text.source.SourceViewer; @@ -56,6 +58,7 @@ public class StickyScrollingControlTest { private Color separatorColor; private StickyScrollingControl stickyScrollingControl; private IVerticalRuler ruler; + private StickyScrollingControlSettings settings; @Before public void setup() { @@ -71,8 +74,8 @@ public void setup() { hoverColor = new Color(1, 1, 1); backgroundColor = new Color(2, 2, 2); separatorColor = new Color(3, 3, 3); - StickyScrollingControlSettings settings = new StickyScrollingControlSettings(2, lineNumberColor, hoverColor, - backgroundColor, separatorColor, true); + settings = new StickyScrollingControlSettings(2, lineNumberColor, hoverColor, backgroundColor, separatorColor, + true); stickyScrollingControl = new StickyScrollingControl(sourceViewer, ruler, settings, null); } @@ -98,6 +101,30 @@ public void testShowStickyLineTexts() { assertEquals(expStickyLineText, stickyLineText.getText()); } + @Test + public void testShowStickyLineTextsWithSourceViewerMapping() { + shell.dispose(); + shell = new Shell(Display.getDefault()); + shell.setSize(200, 200); + shell.setLayout(new FillLayout()); + + sourceViewer = new SourceViewerLineMapping(shell, ruler, SWT.V_SCROLL | SWT.H_SCROLL); + sourceViewer.setDocument(new Document()); + sourceViewer.getTextWidget().setBounds(0, 0, 200, 200); + + stickyScrollingControl = new StickyScrollingControl(sourceViewer, ruler, settings, null); + + List stickyLines = List.of(new StickyLine("line 10", 9), new StickyLine("line 20", 19)); + stickyScrollingControl.setStickyLines(stickyLines); + + StyledText stickyLineNumber = getStickyLineNumber(); + String expLineNumber = "52" + System.lineSeparator() + "62"; + assertEquals(expLineNumber, stickyLineNumber.getText()); + StyledText stickyLineText = getStickyLineText(); + String expStickyLineText = "line 10" + System.lineSeparator() + "line 20"; + assertEquals(expStickyLineText, stickyLineText.getText()); + } + @Test public void testCorrectColorsApplied() { List stickyLines = List.of(new StickyLine("line 10", 9), new StickyLine("line 20", 19)); @@ -119,8 +146,8 @@ public void testLimitStickyLinesCount() { List stickyLines = List.of(new StickyLine("line 10", 9), new StickyLine("line 20", 19)); stickyScrollingControl.setStickyLines(stickyLines); - StickyScrollingControlSettings settings = new StickyScrollingControlSettings(1, lineNumberColor, hoverColor, - backgroundColor, separatorColor, true); + settings = new StickyScrollingControlSettings(1, lineNumberColor, hoverColor, backgroundColor, separatorColor, + true); stickyScrollingControl.applySettings(settings); StyledText stickyLineNumber = getStickyLineNumber(); @@ -147,8 +174,8 @@ public void testCopyStyleRanges() { @Test public void testWithoutVerticalRuler() { sourceViewer = new SourceViewer(shell, null, SWT.None); - StickyScrollingControlSettings settings = new StickyScrollingControlSettings(5, lineNumberColor, hoverColor, - backgroundColor, separatorColor, true); + settings = new StickyScrollingControlSettings(5, lineNumberColor, hoverColor, backgroundColor, separatorColor, + true); stickyScrollingControl = new StickyScrollingControl(sourceViewer, settings); StyledText stickyLineNumber = getStickyLineNumber(); @@ -164,8 +191,8 @@ public void testWithoutLineNumber() { StyledText stickyLineNumber = getStickyLineNumber(); assertThat(stickyLineNumber.getLeftMargin(), greaterThan(0)); - StickyScrollingControlSettings settings = new StickyScrollingControlSettings(5, lineNumberColor, hoverColor, - backgroundColor, separatorColor, false); + settings = new StickyScrollingControlSettings(5, lineNumberColor, hoverColor, backgroundColor, separatorColor, + false); stickyScrollingControl.applySettings(settings); stickyLineNumber = getStickyLineNumber(); @@ -419,4 +446,27 @@ private void drainDisplayEventQueue() { } } + private class SourceViewerLineMapping extends SourceViewer implements ITextViewerExtension5 { + + public SourceViewerLineMapping(Composite parent, IVerticalRuler ruler, int styles) { + super(parent, ruler, styles); + } + + @Override + public IRegion[] getCoveredModelRanges(IRegion modelRange) { + return null; + } + + @Override + public boolean exposeModelRange(IRegion modelRange) { + return false; + } + + @Override + public int widgetLine2ModelLine(int widgetLine) { + return widgetLine + 42; + } + + } + } diff --git a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandlerTest.java b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandlerTest.java index 3fc500fae2d..a72bc6a0f7b 100644 --- a/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandlerTest.java +++ b/tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandlerTest.java @@ -23,6 +23,11 @@ import static org.mockito.Mockito.atLeastOnce; import static org.mockito.Mockito.atMost; import static org.mockito.Mockito.mock; +import static org.mockito.ArgumentMatchers.any; +import static org.mockito.ArgumentMatchers.anyInt; +import static org.mockito.Mockito.mock; +import static org.mockito.Mockito.never; +import static org.mockito.Mockito.times; import static org.mockito.Mockito.verify; import static org.mockito.Mockito.when; @@ -62,6 +67,7 @@ public class StickyScrollingHandlerTest { private IStickyLinesProvider linesProvider; private StickyScrollingHandler stickyScrollingHandler; private StickyLinesProperties stickyLinesProperties; + private StyledText textWidget; @Before public void setup() { @@ -69,7 +75,10 @@ public void setup() { ruler = new CompositeRuler(); sourceViewer = new SourceViewer(shell, ruler, SWT.None); sourceViewer.setDocument(new Document()); - sourceViewer.getTextWidget().setBounds(0, 0, 200, 200); + sourceViewer.getTextWidget().setBounds(0, 0, 200, 150); + textWidget = sourceViewer.getTextWidget(); + textWidget.setText("first 1 \nline 2 \nline 3 \nline 4 \nline 5 \nline 6 \nline 7 \nline 8 \nline 9 \nline 10"); + textWidget.setTopIndex(1); lineNumberColor = new Color(0, 0, 0); hoverColor = new Color(1, 1, 1); @@ -78,7 +87,7 @@ public void setup() { linesProvider = mock(IStickyLinesProvider.class); stickyScrollingHandler = new StickyScrollingHandler(sourceViewer, ruler, store, linesProvider); - stickyLinesProperties = new StickyLinesProperties(4); + stickyLinesProperties = new StickyLinesProperties(4, sourceViewer); } @After @@ -88,7 +97,7 @@ public void teardown() { @Test public void testShowStickyLines() { - when(linesProvider.getStickyLines(sourceViewer, stickyLinesProperties)) + when(linesProvider.getStickyLines(textWidget, 1, stickyLinesProperties)) .thenReturn(List.of(new StickyLine("line 10", 9))); stickyScrollingHandler.viewportChanged(100); @@ -101,6 +110,19 @@ public void testShowStickyLines() { assertEquals(expStickyLineText, stickyLineText.getText()); } + @Test + public void testDontCalculateStickyLinesForFirstLine() { + textWidget.setTopIndex(0); + + stickyScrollingHandler.viewportChanged(100); + + StyledText stickyLineNumber = getStickyLineNumber(); + assertEquals("", stickyLineNumber.getText()); + StyledText stickyLineText = getStickyLineText(); + assertEquals("", stickyLineText.getText()); + verify(linesProvider, never()).getStickyLines(any(), anyInt(), any()); + } + @Test public void testUnistallStickyLines() { Canvas stickyControlCanvas = getStickyControlCanvas(this.shell); @@ -112,7 +134,7 @@ public void testUnistallStickyLines() { @Test public void testPreferencesLoaded() { - when(linesProvider.getStickyLines(sourceViewer, stickyLinesProperties)) + when(linesProvider.getStickyLines(textWidget, 1, stickyLinesProperties)) .thenReturn(List.of(new StickyLine("line 10", 9))); stickyScrollingHandler.viewportChanged(100); @@ -123,7 +145,9 @@ public void testPreferencesLoaded() { @Test public void testPreferencesUpdated() { - when(linesProvider.getStickyLines(sourceViewer, stickyLinesProperties)) + when(linesProvider.getStickyLines(textWidget, 1, stickyLinesProperties)) + .thenReturn(List.of(new StickyLine("line 10", 9), new StickyLine("line 20", 19))); + when(linesProvider.getStickyLines(textWidget, 2, stickyLinesProperties)) .thenReturn(List.of(new StickyLine("line 10", 9), new StickyLine("line 20", 19))); stickyScrollingHandler.viewportChanged(100); @@ -141,13 +165,13 @@ public void testPreferencesUpdated() { @Test public void testThrottledExecution() throws InterruptedException { - when(linesProvider.getStickyLines(sourceViewer, stickyLinesProperties)) + when(linesProvider.getStickyLines(textWidget, 1, stickyLinesProperties)) .thenReturn(List.of(new StickyLine("line 10", 9))); - when(linesProvider.getStickyLines(sourceViewer, stickyLinesProperties)) + when(linesProvider.getStickyLines(textWidget, 1, stickyLinesProperties)) .thenReturn(List.of(new StickyLine("line 10", 9))); - when(linesProvider.getStickyLines(sourceViewer, stickyLinesProperties)) + when(linesProvider.getStickyLines(textWidget, 1, stickyLinesProperties)) .thenReturn(List.of(new StickyLine("line 10", 9))); - when(linesProvider.getStickyLines(sourceViewer, stickyLinesProperties)) + when(linesProvider.getStickyLines(textWidget, 1, stickyLinesProperties)) .thenReturn(List.of(new StickyLine("line 10", 9))); stickyScrollingHandler.viewportChanged(100); @@ -166,6 +190,34 @@ public void testThrottledExecution() throws InterruptedException { verify(linesProvider, atLeastOnce()).getStickyLines(sourceViewer, stickyLinesProperties); } + @Test + public void testRemoveStickyLines() { + when(linesProvider.getStickyLines(textWidget, 1, stickyLinesProperties)) + .thenReturn(List.of(new StickyLine("line 1", 0), new StickyLine("line 2", 1))); + when(linesProvider.getStickyLines(textWidget, 2, stickyLinesProperties)) + .thenReturn(List.of(new StickyLine("line 3", 2))); + + stickyScrollingHandler.viewportChanged(100); + + StyledText stickyLineText = getStickyLineText(); + String expStickyLineText = "line 1"; + assertEquals(expStickyLineText, stickyLineText.getText()); + } + + @Test + public void testLineUnderStickyLine() { + when(linesProvider.getStickyLines(textWidget, 1, stickyLinesProperties)) + .thenReturn(List.of(new StickyLine("line 1", 0))); + when(linesProvider.getStickyLines(textWidget, 2, stickyLinesProperties)) + .thenReturn(List.of(new StickyLine("line 1", 0), new StickyLine("line 2", 1))); + + stickyScrollingHandler.viewportChanged(100); + + StyledText stickyLineText = getStickyLineText(); + String expStickyLineText = "line 1" + System.lineSeparator() + "line 2"; + assertEquals(expStickyLineText, stickyLineText.getText()); + } + private void waitInUi(int ms) throws InterruptedException { while (shell.getDisplay().readAndDispatch()) { }