Skip to content

Commit 715befb

Browse files
Christopher-Hermannpraveen-skp
authored andcommitted
Refactoring sticky lines provider and handler
Refactors the sticky lines provider and extract the method to an interface. This is a preparation step for providing a extension point for sticky lines provider.
1 parent 0bb6a25 commit 715befb

File tree

6 files changed

+142
-89
lines changed

6 files changed

+142
-89
lines changed
Lines changed: 17 additions & 32 deletions
Original file line numberDiff line numberDiff line change
@@ -24,32 +24,26 @@
2424

2525
/**
2626
* This class provides sticky lines for the given source code in the source viewer. The
27-
* implementation is completely based on indentation and therefore should work by default for
28-
* several languages.
27+
* implementation is completely based on indentation and therefore works by default for several
28+
* languages.
2929
*/
30-
public class StickyLinesProvider {
30+
public class DefaultStickyLinesProvider implements IStickyLinesProvider {
3131

32-
private final static int IGNORE_INDENTATION= -1;
32+
private final static int IGNORE_LINE_INDENTATION= -1;
3333

3434
private final static String TAB= "\t"; //$NON-NLS-1$
3535

36-
private int tabWidth= 4;
37-
38-
/**
39-
* Calculate the sticky lines for the given source code in the source viewer for the given
40-
* vertical offset.
41-
*
42-
* @param verticalOffset The vertical offset line index of the first visible line
43-
* @param sourceViewer The source viewer containing the source code
44-
* @return A list of sticky lines
45-
*/
46-
public List<StickyLine> get(int verticalOffset, ISourceViewer sourceViewer) {
47-
LinkedList<StickyLine> stickyLines= new LinkedList<>();
36+
private StickyLinesProperties fProperties;
4837

49-
if (verticalOffset == 0) {
50-
return stickyLines;
38+
@Override
39+
public List<StickyLine> getStickyLines(ISourceViewer sourceViewer, StickyLinesProperties properties) {
40+
if (sourceViewer.getTopIndex() == 0) {
41+
return Collections.emptyList();
5142
}
5243

44+
this.fProperties= properties;
45+
LinkedList<StickyLine> stickyLines= new LinkedList<>();
46+
5347
try {
5448
StyledText textWidget= sourceViewer.getTextWidget();
5549
int startLine= textWidget.getTopIndex();
@@ -71,7 +65,7 @@ private void calculateStickyLinesForLineNumber(LinkedList<StickyLine> stickyLine
7165
String line= textWidget.getLine(i);
7266
int indentation= getIndentation(line);
7367

74-
if (indentation == IGNORE_INDENTATION) {
68+
if (indentation == IGNORE_LINE_INDENTATION) {
7569
continue;
7670
}
7771

@@ -91,7 +85,7 @@ private void calculateStickyLinesUnderStickyLineControl(LinkedList<StickyLine> s
9185

9286
String line= textWidget.getLine(i);
9387
int indentation= getIndentation(line);
94-
if (indentation == IGNORE_INDENTATION) {
88+
if (indentation == IGNORE_LINE_INDENTATION) {
9589
continue;
9690
}
9791

@@ -123,7 +117,7 @@ private int mapLineNumberToSourceViewerLine(int lineNumber, ISourceViewer source
123117

124118
private int getStartIndentation(int startFromLine, StyledText styledText) {
125119
int indentation= getIndentation(styledText.getLine(startFromLine));
126-
if (indentation != IGNORE_INDENTATION) {
120+
if (indentation != IGNORE_LINE_INDENTATION) {
127121
return indentation;
128122
} else {
129123
int nextContentLine= getIndentation(getNextContentLine(startFromLine, styledText));
@@ -154,21 +148,12 @@ private String getPreviousContentLine(int startFromLine, StyledText styledText)
154148

155149
private int getIndentation(String line) {
156150
if (line == null || line.isBlank()) {
157-
return IGNORE_INDENTATION;
151+
return IGNORE_LINE_INDENTATION;
158152
}
159-
String tabAsSpaces= String.join("", Collections.nCopies(tabWidth, " ")); //$NON-NLS-1$ //$NON-NLS-2$
153+
String tabAsSpaces= String.join("", Collections.nCopies(fProperties.tabWith(), " ")); //$NON-NLS-1$ //$NON-NLS-2$
160154

161155
line= line.replace(TAB, tabAsSpaces);
162156
return line.length() - line.stripLeading().length();
163157
}
164158

165-
/**
166-
* Sets the with in spaces of a tab in the editor.
167-
*
168-
* @param tabWidth The amount of spaces a tab is using.
169-
*/
170-
public void setTabWidth(int tabWidth) {
171-
this.tabWidth= tabWidth;
172-
}
173-
174159
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2024 SAP SE.
3+
*
4+
* This program and the accompanying materials
5+
* are made available under the terms of the Eclipse Public License 2.0
6+
* which accompanies this distribution, and is available at
7+
* https://www.eclipse.org/legal/epl-2.0/
8+
*
9+
* SPDX-License-Identifier: EPL-2.0
10+
*
11+
* Contributors:
12+
* SAP SE - initial API and implementation
13+
*******************************************************************************/
14+
package org.eclipse.ui.internal.texteditor.stickyscroll;
15+
16+
import java.util.List;
17+
18+
import org.eclipse.swt.custom.StyledText;
19+
20+
import org.eclipse.jface.text.source.ISourceViewer;
21+
22+
/**
23+
* A sticky lines provider calculates the sticky lines for a given source viewer. The sticky lines
24+
* will be displayed in the top area of the editor.
25+
*
26+
* TODO move to public package and add since 3.19
27+
*/
28+
public interface IStickyLinesProvider {
29+
30+
/**
31+
* Calculate the sticky lines for the source code of the given sourceViewer. Specific
32+
* properties, such as the <code>tabWidht</code> can be retrieved from the
33+
* <code>properties</code>.
34+
*
35+
* @param sourceViewer The source viewer containing the source code and information about the
36+
* first visible line
37+
* @return The list of sticky lines to show
38+
*
39+
* @see ISourceViewer#getTopIndex()
40+
* @see ISourceViewer#getTextWidget()
41+
* @see StyledText#getTopIndex()
42+
*/
43+
public List<StickyLine> getStickyLines(ISourceViewer sourceViewer, StickyLinesProperties properties);
44+
45+
/**
46+
* Properties required to calculate the sticky lines.
47+
*
48+
* @param tabWith The with of a tab
49+
*/
50+
record StickyLinesProperties(int tabWith) {
51+
}
52+
53+
}

bundles/org.eclipse.ui.editors/src/org/eclipse/ui/internal/texteditor/stickyscroll/StickyScrollingHandler.java

Lines changed: 32 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -21,6 +21,7 @@
2121
import static org.eclipse.ui.texteditor.AbstractDecoratedTextEditorPreferenceConstants.EDITOR_TAB_WIDTH;
2222

2323
import java.time.Duration;
24+
import java.util.Collections;
2425
import java.util.List;
2526

2627
import org.eclipse.swt.graphics.Color;
@@ -37,9 +38,10 @@
3738
import org.eclipse.jface.text.source.IVerticalRuler;
3839

3940
import org.eclipse.ui.internal.editors.text.EditorsPlugin;
41+
import org.eclipse.ui.internal.texteditor.stickyscroll.IStickyLinesProvider.StickyLinesProperties;
4042

4143
/**
42-
* A sticky scrolling handler that retrieves stick lines from the {@link StickyLinesProvider} and
44+
* A sticky scrolling handler that retrieves stick lines from a {@link IStickyLinesProvider} and
4345
* shows them in a {@link StickyScrollingControl} on top of the given source viewer.
4446
*/
4547
public class StickyScrollingHandler implements IViewportListener {
@@ -50,94 +52,95 @@ public class StickyScrollingHandler implements IViewportListener {
5052

5153
private StickyScrollingControl stickyScrollingControl;
5254

53-
private int tabWidth;
54-
5555
private IPropertyChangeListener propertyChangeListener;
5656

5757
private IPreferenceStore preferenceStore;
5858

59-
private StickyLinesProvider stickyLinesProvider;
59+
private IStickyLinesProvider stickyLinesProvider;
60+
61+
private StickyLinesProperties stickyLinesProperties;
6062

6163
private Throttler throttler;
6264

6365
private int verticalOffset;
6466

6567
/**
66-
* Creates a StickyScrollingHandlerIndentation that will be linked to the given source viewer.
67-
* The sticky scrolling will be computed by the default {@link StickyLinesProvider}.
68+
* Creates a StickyScrollingHandler that will be linked to the given source viewer. The sticky
69+
* lines will be provided by the {@link DefaultStickyLinesProvider}.
6870
*
69-
* @param sourceViewer The source viewer to link the handler
71+
* @param sourceViewer The source viewer to link the handler with
7072
* @param verticalRuler The vertical ruler of the source viewer
7173
* @param preferenceStore The preference store
7274
*/
7375
public StickyScrollingHandler(ISourceViewer sourceViewer, IVerticalRuler verticalRuler, IPreferenceStore preferenceStore) {
74-
this(sourceViewer, verticalRuler, preferenceStore, new StickyLinesProvider());
76+
this(sourceViewer, verticalRuler, preferenceStore, new DefaultStickyLinesProvider());
7577
}
7678

7779
/**
78-
* Creates a StickyScrollingHandlerIndentation that will be linked to the given source viewer.
80+
* Creates a StickyScrollingHandler that will be linked to the given source viewer. The sticky
81+
* lines will be provided by the given <code>stickyLinesProvider</code>.
7982
*
80-
* @param sourceViewer The source viewer to link the handler
83+
* @param sourceViewer The source viewer to link the handler with
8184
* @param verticalRuler The vertical ruler of the source viewer
8285
* @param preferenceStore The preference store
83-
* @param stickyLinesProvider The sticky scrolling computer
86+
* @param stickyLinesProvider The sticky scrolling provider
8487
*/
8588
public StickyScrollingHandler(ISourceViewer sourceViewer, IVerticalRuler verticalRuler, IPreferenceStore preferenceStore,
86-
StickyLinesProvider stickyLinesProvider) {
89+
IStickyLinesProvider stickyLinesProvider) {
8790
this.sourceViewer= sourceViewer;
8891

8992
throttler= new Throttler(sourceViewer.getTextWidget().getDisplay(), Duration.ofMillis(THROTTLER_DELAY), this::calculateAndShowStickyLines);
9093
this.stickyLinesProvider= stickyLinesProvider;
9194

92-
StickyScrollingControlSettings settings= loadAndListenForProperties(preferenceStore);
95+
listenForPropertiesChanges(preferenceStore);
96+
stickyLinesProperties= loadStickyLinesProperties(preferenceStore);
97+
StickyScrollingControlSettings settings= loadControlSettings(preferenceStore);
98+
9399
stickyScrollingControl= new StickyScrollingControl(sourceViewer, verticalRuler, settings, this);
94100

95101
sourceViewer.addViewportListener(this);
96102
}
97103

98-
private StickyScrollingControlSettings loadAndListenForProperties(IPreferenceStore store) {
104+
private void listenForPropertiesChanges(IPreferenceStore store) {
99105
preferenceStore= store;
100106
propertyChangeListener= e -> {
101107
if (e.getProperty().equals(EDITOR_TAB_WIDTH) || e.getProperty().equals(EDITOR_STICKY_SCROLLING_MAXIMUM_COUNT)
102108
|| e.getProperty().equals(EDITOR_CURRENT_LINE_COLOR) || e.getProperty().equals(EDITOR_LINE_NUMBER_RULER)
103109
|| e.getProperty().equals(STICKY_LINES_SEPARATOR_COLOR)) {
104110
if (stickyScrollingControl != null && !sourceViewer.getTextWidget().isDisposed()) {
105-
StickyScrollingControlSettings settings= loadSettings(preferenceStore);
111+
StickyScrollingControlSettings settings= loadControlSettings(preferenceStore);
106112
stickyScrollingControl.applySettings(settings);
107-
stickyLinesProvider.setTabWidth(tabWidth);
113+
stickyLinesProperties= loadStickyLinesProperties(preferenceStore);
108114
}
109115
}
110116
};
111117
store.addPropertyChangeListener(propertyChangeListener);
112-
return loadSettings(store);
113118
}
114119

115-
private StickyScrollingControlSettings loadSettings(IPreferenceStore store) {
116-
tabWidth= store.getInt(EDITOR_TAB_WIDTH);
117-
120+
private StickyScrollingControlSettings loadControlSettings(IPreferenceStore store) {
118121
int stickyScrollingMaxCount= store.getInt(EDITOR_STICKY_SCROLLING_MAXIMUM_COUNT);
119122

120123
Color lineNumberColor= new Color(PreferenceConverter.getColor(store, EDITOR_LINE_NUMBER_RULER_COLOR));
121124
sourceViewer.getTextWidget().addDisposeListener(e -> lineNumberColor.dispose());
122-
123125
Color stickyLineHoverColor= new Color(PreferenceConverter.getColor(store, EDITOR_CURRENT_LINE_COLOR));
124126
sourceViewer.getTextWidget().addDisposeListener(e -> stickyLineHoverColor.dispose());
125-
126127
Color stickyLineBackgroundColor= sourceViewer.getTextWidget().getBackground();
127-
128128
boolean showLineNumbers= store.getBoolean(EDITOR_LINE_NUMBER_RULER);
129-
130129
Color stickyLineSeparatorColor= null;
131130
if (EditorsPlugin.getDefault() != null) {
132131
RGB rgb= PreferenceConverter.getColor(store, STICKY_LINES_SEPARATOR_COLOR);
133132
ISharedTextColors sharedTextColors= EditorsPlugin.getDefault().getSharedTextColors();
134133
stickyLineSeparatorColor= sharedTextColors.getColor(rgb);
135134
}
136-
137135
return new StickyScrollingControlSettings(stickyScrollingMaxCount,
138136
lineNumberColor, stickyLineHoverColor, stickyLineBackgroundColor, stickyLineSeparatorColor, showLineNumbers);
139137
}
140138

139+
private StickyLinesProperties loadStickyLinesProperties(IPreferenceStore store) {
140+
int tabWidth= store.getInt(EDITOR_TAB_WIDTH);
141+
return new StickyLinesProperties(tabWidth);
142+
}
143+
141144
@Override
142145
public void viewportChanged(int newVerticalOffset) {
143146
if (this.verticalOffset == newVerticalOffset) {
@@ -148,7 +151,10 @@ public void viewportChanged(int newVerticalOffset) {
148151
}
149152

150153
private void calculateAndShowStickyLines() {
151-
List<StickyLine> stickyLines= stickyLinesProvider.get(verticalOffset, sourceViewer);
154+
List<StickyLine> stickyLines= stickyLinesProvider.getStickyLines(sourceViewer, stickyLinesProperties);
155+
if (stickyLines == null) {
156+
stickyLines= Collections.emptyList();
157+
}
152158
stickyScrollingControl.setStickyLines(stickyLines);
153159
}
154160

tests/org.eclipse.ui.editors.tests/src/org/eclipse/ui/editors/tests/EditorsTestSuite.java

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -21,7 +21,7 @@
2121

2222
import org.eclipse.jface.text.tests.codemining.CodeMiningTest;
2323

24-
import org.eclipse.ui.internal.texteditor.stickyscroll.StickyLinesProviderTest;
24+
import org.eclipse.ui.internal.texteditor.stickyscroll.DefaultStickyLinesProviderTest;
2525
import org.eclipse.ui.internal.texteditor.stickyscroll.StickyScrollingControlTest;
2626
import org.eclipse.ui.internal.texteditor.stickyscroll.StickyScrollingHandlerTest;
2727

@@ -49,7 +49,7 @@
4949

5050
StickyScrollingControlTest.class,
5151
StickyScrollingHandlerTest.class,
52-
StickyLinesProviderTest.class,
52+
DefaultStickyLinesProviderTest.class,
5353

5454
CodeMiningTest.class,
5555
})

0 commit comments

Comments
 (0)