Skip to content

Commit 18539e5

Browse files
Add SourceViewer#computeStyleRanges() to highlight external documents
Introduces computeStyleRanges(IDocument, IRegion) on SourceViewer, which applies the viewer's own presentation reconciler and partitioner to an external document, returning the resulting SWT StyleRanges for the given region without affecting the viewer's current document.
1 parent ed75400 commit 18539e5

File tree

2 files changed

+82
-1
lines changed

2 files changed

+82
-1
lines changed

bundles/org.eclipse.jface.text/META-INF/MANIFEST.MF

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ Manifest-Version: 1.0
22
Bundle-ManifestVersion: 2
33
Bundle-Name: %pluginName
44
Bundle-SymbolicName: org.eclipse.jface.text
5-
Bundle-Version: 3.30.100.qualifier
5+
Bundle-Version: 3.31.0.qualifier
66
Bundle-Vendor: %providerName
77
Bundle-Localization: plugin
88
Export-Package:

bundles/org.eclipse.jface.text/src/org/eclipse/jface/text/source/SourceViewer.java

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@
2424
import java.util.Stack;
2525

2626
import org.eclipse.swt.SWT;
27+
import org.eclipse.swt.custom.StyleRange;
2728
import org.eclipse.swt.custom.StyledText;
2829
import org.eclipse.swt.graphics.Point;
2930
import org.eclipse.swt.graphics.Rectangle;
@@ -46,7 +47,9 @@
4647
import org.eclipse.jface.text.IAutoEditStrategy;
4748
import org.eclipse.jface.text.IBlockTextSelection;
4849
import org.eclipse.jface.text.IDocument;
50+
import org.eclipse.jface.text.IDocumentExtension3;
4951
import org.eclipse.jface.text.IDocumentExtension4;
52+
import org.eclipse.jface.text.IDocumentPartitioner;
5053
import org.eclipse.jface.text.IPositionUpdater;
5154
import org.eclipse.jface.text.IRegion;
5255
import org.eclipse.jface.text.IRewriteTarget;
@@ -56,8 +59,11 @@
5659
import org.eclipse.jface.text.ITextSelection;
5760
import org.eclipse.jface.text.ITextViewerExtension2;
5861
import org.eclipse.jface.text.ITextViewerLifecycle;
62+
import org.eclipse.jface.text.ITypedRegion;
5963
import org.eclipse.jface.text.Position;
6064
import org.eclipse.jface.text.Region;
65+
import org.eclipse.jface.text.TextPresentation;
66+
import org.eclipse.jface.text.TextUtilities;
6167
import org.eclipse.jface.text.TextViewer;
6268
import org.eclipse.jface.text.codemining.ICodeMiningProvider;
6369
import org.eclipse.jface.text.contentassist.IContentAssistant;
@@ -71,6 +77,8 @@
7177
import org.eclipse.jface.text.hyperlink.IHyperlinkDetector;
7278
import org.eclipse.jface.text.information.IInformationPresenter;
7379
import org.eclipse.jface.text.presentation.IPresentationReconciler;
80+
import org.eclipse.jface.text.presentation.IPresentationReconcilerExtension;
81+
import org.eclipse.jface.text.presentation.IPresentationRepairer;
7482
import org.eclipse.jface.text.projection.ChildDocument;
7583
import org.eclipse.jface.text.quickassist.IQuickAssistAssistant;
7684
import org.eclipse.jface.text.quickassist.IQuickAssistInvocationContext;
@@ -1393,4 +1401,77 @@ private void uninstallTextViewer() {
13931401
lifecycles.clear();
13941402
}
13951403

1404+
/**
1405+
* Computes syntax-highlighting style ranges for a region of an external document using this
1406+
* viewer's configured presentation reconciler and partitioner.
1407+
* <p>
1408+
* This is useful when you want to syntax-color content that is <em>not</em> the document
1409+
* currently displayed in the viewer — for example, to preview or render a snippet with the same
1410+
* language rules that are active in this viewer.
1411+
* </p>
1412+
* <p>
1413+
* The viewer's partitioner is temporarily connected to the given document so that its
1414+
* presentation repairers can compute the correct highlighting. The viewer's own document is not
1415+
* affected.
1416+
* </p>
1417+
*
1418+
* @param document the external document whose content should be highlighted; must not be
1419+
* {@code null} and must use the same language/content type as this viewer
1420+
* @param damage the region within {@code document} for which style ranges are computed; must
1421+
* not be {@code null}
1422+
* @return the list of {@link org.eclipse.swt.custom.StyleRange}s covering the given region, as
1423+
* produced by this viewer's presentation reconciler; never {@code null}, may be empty
1424+
* if no repairer is registered for the content type
1425+
* @throws BadLocationException if {@code damage} is outside the bounds of {@code document}
1426+
* @since 3.31
1427+
*/
1428+
public List<StyleRange> computeStyleRanges(IDocument document, IRegion damage) throws BadLocationException {
1429+
String partition= IDocumentExtension3.DEFAULT_PARTITIONING;
1430+
IPresentationReconciler reconciler= fPresentationReconciler;
1431+
if (reconciler instanceof IPresentationReconcilerExtension ext) {
1432+
String extPartition= ext.getDocumentPartitioning();
1433+
if (extPartition != null && !extPartition.isEmpty()) {
1434+
partition= extPartition;
1435+
}
1436+
}
1437+
IDocument originalDocument= getDocument();
1438+
IDocumentPartitioner partitioner= originalDocument.getDocumentPartitioner();
1439+
document.setDocumentPartitioner(partitioner);
1440+
IDocumentPartitioner originalDocumentPartitioner= null;
1441+
if (document instanceof IDocumentExtension3 ext
1442+
&& originalDocument instanceof IDocumentExtension3 originalExt) {
1443+
originalDocumentPartitioner= originalExt.getDocumentPartitioner(partition);
1444+
if (originalDocumentPartitioner != null) {
1445+
// set temporarily another document in partitioner so that presentation can be
1446+
// created for given source
1447+
originalDocumentPartitioner.disconnect();
1448+
try {
1449+
originalDocumentPartitioner.connect(document);
1450+
} finally {
1451+
ext.setDocumentPartitioner(partition, originalDocumentPartitioner);
1452+
}
1453+
}
1454+
}
1455+
TextPresentation presentation= new TextPresentation(damage, 1000);
1456+
ITypedRegion[] partitioning= TextUtilities.computePartitioning(document, partition, damage.getOffset(),
1457+
damage.getLength(), false);
1458+
for (ITypedRegion r : partitioning) {
1459+
IPresentationRepairer repairer= reconciler.getRepairer(r.getType());
1460+
if (repairer != null) {
1461+
repairer.setDocument(document);
1462+
repairer.createPresentation(presentation, r);
1463+
repairer.setDocument(originalDocument);
1464+
}
1465+
}
1466+
if (originalDocumentPartitioner != null) {
1467+
originalDocumentPartitioner.connect(originalDocument);
1468+
}
1469+
List<StyleRange> result= new ArrayList<>();
1470+
var it= presentation.getAllStyleRangeIterator();
1471+
while (it.hasNext()) {
1472+
StyleRange next= it.next();
1473+
result.add(next);
1474+
}
1475+
return result;
1476+
}
13961477
}

0 commit comments

Comments
 (0)