Skip to content

Commit d86886c

Browse files
Merge pull request #27 from matteo-prosperi/dev/maprospe/classification
Add docs for classification taggers and minor cleanup of editor docs.
2 parents 854806c + b484fe5 commit d86886c

File tree

6 files changed

+105
-12
lines changed

6 files changed

+105
-12
lines changed

docs/extensibility/visualstudio.extensibility/editor/editor-concepts.md

Lines changed: 17 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ ms.subservice: extensibility-integration
1414

1515
This article describes the extensibility object model that represents the Visual Studio editor and the text document that is opened for editing. For an introduction to working with the editor extension functionality, see [Use Visual Studio editor extensibility](editor.md).
1616

17-
The Visual Studio Editor extensibility object model is composed of a few integral parts. This article covers [ITextViewSnapshot](/dotnet/api/microsoft.visualstudio.extensibility.editor.itextviewsnapshot), [ITextDocumentSnapshot](/dotnet/api/microsoft.visualstudio.extensibility.editor.itextdocumentsnapshot), and other abstract representations of the whole document, as well as `Position` and `Span`, which represent location and spans of text, respectively.
17+
The Visual Studio Editor extensibility object model is composed of a few integral parts. This article covers [ITextViewSnapshot](/dotnet/api/microsoft.visualstudio.extensibility.editor.itextviewsnapshot), [ITextDocumentSnapshot](/dotnet/api/microsoft.visualstudio.extensibility.editor.itextdocumentsnapshot), and other abstract representations of the whole document, as well as [TextPosition](/dotnet/api/microsoft.visualstudio.extensibility.editor.textposition) and [TextRange](/dotnet/api/microsoft.visualstudio.extensibility.editor.textrange), which represent locations and spans of text, respectively.
1818

1919
## ITextViewSnapshot
2020

@@ -36,25 +36,33 @@ If you're familiar with legacy Visual Studio extensions, [ITextDocumentSnapshot]
3636

3737
Best Practices:
3838

39-
- You can use Position and Span to represent substrings in the document without expending resources copying or allocating strings. Most APIs operate in terms of these primitives.
39+
- You can use Position and Range to represent substrings in the document without expending resources copying or allocating strings. Most APIs operate in terms of these primitives.
4040
- You can use the indexer syntax, `textDocument[0]`, to read character by character in the document without copying it to a string.
41-
- If you must create a string such as for use as a dictionary key, use the overload that takes a `Span`, to avoid creating a large throwaway string from the entire line or document.
41+
- If you must create a string such as for use as a dictionary key, use the overload that takes a `Range`, to avoid creating a large throwaway string from the entire line or document.
4242
- Avoid assuming lines or documents will be short. Many languages minify into huge lines or consume very large files
43-
- - [ITextDocumentSnapshot](/dotnet/api/microsoft.visualstudio.extensibility.editor.itextdocumentsnapshot) references large data structures that may consume memory if an old enough version is stored. Best practice is to periodically update positions and spans that you're storing long term to the latest document version via their `TranslateTo()` method so the old `ITextDocumentSnapshot` version can be garbage collected.
43+
- - [ITextDocumentSnapshot](/dotnet/api/microsoft.visualstudio.extensibility.editor.itextdocumentsnapshot) references large data structures that may consume memory if an old enough version is stored. Best practice is to periodically update positions and ranges that you're storing long term to the latest document version via their `TranslateTo()` method so the old `ITextDocumentSnapshot` version can be garbage collected.
4444

4545
## Position
4646

47-
Represents a position within the text document. As opposed to `int` positions, the Position type is aware of the [ITextDocumentSnapshot](/dotnet/api/microsoft.visualstudio.extensibility.editor.itextdocumentsnapshot) it came from and supports `GetChar()` to directly get the character at that point.
47+
[TextPosition](/dotnet/api/microsoft.visualstudio.extensibility.editor.textposition) represents a position within the text document. As opposed to `int` positions, the `TextPosition` type is aware of the [ITextDocumentSnapshot](/dotnet/api/microsoft.visualstudio.extensibility.editor.itextdocumentsnapshot) it came from and supports `GetChar()` to directly get the character at that point.
4848

49-
If you're familiar with legacy Visual Studio extensions, Position is almost the same as [SnapshotPoint](/dotnet/api/microsoft.visualstudio.text.snapshotpoint) and supports most of the same methods.
49+
If you're familiar with legacy Visual Studio extensions, `TextPosition` is almost the same as [SnapshotPoint](/dotnet/api/microsoft.visualstudio.text.snapshotpoint) and supports most of the same methods.
5050

51-
## Span
51+
## Range
5252

53-
Represents a contiguous substring of characters within an [ITextDocumentSnapshot](/dotnet/api/microsoft.visualstudio.extensibility.editor.itextdocumentsnapshot). As opposed to a string created with `string.Substring()` or `ITextDocumentSnapshot.CopyToString()`, creating a Span doesn't require any allocations or additional memory. You can later call `Span.GetText()` to realize it into a string in a deferred fashion.
53+
[TextRange](/dotnet/api/microsoft.visualstudio.extensibility.editor.textrange) represents a contiguous substring of characters within an [ITextDocumentSnapshot](/dotnet/api/microsoft.visualstudio.extensibility.editor.itextdocumentsnapshot). As opposed to a string created with `string.Substring()` or `ITextDocumentSnapshot.CopyToString()`, creating a `TextRange` doesn't require any allocations or additional memory. You can later call [CopyToString()](/dotnet/api/microsoft.visualstudio.extensibility.editor.textextensions.copytostring) to realize it into a string in a deferred fashion.
5454

55-
If you're familiar with legacy Visual Studio extensions, `Position` is almost the same as
55+
If you're familiar with legacy Visual Studio extensions, `TextRange` is almost the same as
5656
[SnapshotSpan](/dotnet/api/microsoft.visualstudio.text.snapshotSpan) and supports most of the same methods.
5757

58+
## Tracking modes
59+
60+
`TextPosition` and `TextRange` are associated with a specific `ITextDocumentSnapshot`: the state of the document at a specific time. Such positions and ranges can be translated to a different snapshot using the `TranslateTo` methods. Such translation takes in account any text added or removed before, after (or, in the case of ranges, in the middle) the position or range. When any of such edits happen exactly at the position or exactly at the edge of the range, [TextPositionTrackingMode](/dotnet/api/microsoft.visualstudio.extensibility.editor.textpositiontrackingmode) and [TextRangeTrackingMode](/dotnet/api/microsoft.visualstudio.extensibility.editor.textrangetrackingmode) are used to specify how the translation should behave.
61+
62+
## Tag
63+
64+
[Taggers](./walkthroughs/taggers.md) are used to associate data (a [tag](/dotnet/api/microsoft.visualstudio.extensibility.editor.itag)) with spans of text, such data is consumed by other Visual Studio features (E.g., [CodeLens](./walkthroughs/codelens.md), [classification](./walkthroughs/classification.md), etc.).
65+
5866
## Related content
5967

6068
Review sample code for a simple editor-based extension:

docs/extensibility/visualstudio.extensibility/editor/editor.md

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,7 +44,7 @@ Extensions can contribute new CodeLenses to the Visual Studio editor. A CodeLens
4444
For detailed walkthrough of how to provide your own CodeLens with your extension, refer to [Extending Visual Studio editor with a new CodeLens](./walkthroughs/codelens.md)
4545

4646
### Taggers
47-
Extensions can contribute new taggers to the Visual Studio editor. Taggers are used to associate data with spans of text, such data is consumed by other Visual Studio features (E.g., CodeLens).
47+
Extensions can contribute new taggers to the Visual Studio editor. Taggers are used to associate data with ranges of text, such data is consumed by other Visual Studio features (E.g., [CodeLens](./walkthroughs/codelens.md), [classification](./walkthroughs/classification.md), etc.).
4848

4949
For detailed walkthrough of how to provide your own taggers with your extension, refer to [Extending Visual Studio editor with a new tagger](./walkthroughs/taggers.md)
5050

Lines changed: 81 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,81 @@
1+
---
2+
title: Customizing classification in the editor
3+
description: A walkthrough of how to provide your own classification in the Visual Studio editor using extensions
4+
ms.date: 4/23/2025
5+
ms.topic: conceptual
6+
ms.author: maprospe
7+
monikerRange: ">=vs-2022"
8+
author: tinaschrepfer
9+
manager: mijacobs
10+
ms.subservice: extensibility-integration
11+
---
12+
13+
# Extending Visual Studio editor with a new classification tagger
14+
15+
A Visual Studio extension can classify a document's syntax allowing for
16+
the text to be colorized accordingly. This is achieved by contributing
17+
a tagger that returns `ClassificationTag` values.
18+
19+
A detailed description of how to provide a tagger can be found in the
20+
[Extending Visual Studio editor with a new tagger](./taggers.md) article.
21+
22+
Following the article linked above, we implement a tagger provider and a
23+
tagger:
24+
25+
```cs
26+
[VisualStudioContribution]
27+
internal class MyClassificationTaggerProvider :
28+
ExtensionPart,
29+
ITextViewTaggerProvider<ClassificationTag>,
30+
ITextViewChangedListener
31+
{
32+
...
33+
```
34+
35+
```cs
36+
internal class MyClassificationTagger :
37+
TextViewTagger<ClassificationTag>
38+
{
39+
...
40+
```
41+
42+
Since we want the document colorization to appear as instantly as possible,
43+
the tagger will need to be as fast as possible. The article linked above
44+
stresses the importance of:
45+
- only generating tags for the requested document portion (or a small
46+
superset of it), not the whole document;
47+
- avoiding parsing the whole document in order to generate tags.
48+
49+
Once the tagger structure is ready and the syntax parsing for the specific
50+
file format is implemented, the tagger can provide text classification, by
51+
simply creating `ClassificationTag` values using the available
52+
`ClassificationType` know values, and calling `UpdateTagsAsync`.
53+
54+
```cs
55+
List<TaggedTrackingTextRange<ClassificationTag>> tags = new();
56+
List<TextRange> ranges = new();
57+
58+
...
59+
60+
ranges.Add(new(document, lineStart, lineLength));
61+
tags.Add(
62+
new TaggedTrackingTextRange<ClassificationTag>(
63+
new TrackingTextRange(
64+
document,
65+
tagStartPosition,
66+
tagLength,
67+
TextRangeTrackingMode.ExtendNone),
68+
new ClassificationTag(ClassificationType.KnownValues.Operator)));
69+
70+
...
71+
72+
await this.UpdateTagsAsync(ranges, tags, CancellationToken.None);
73+
```
74+
75+
At this time, VisualStudio.Extensibility doesn't support defining text colors
76+
for new classification types yet, so we must use existing classification types
77+
(`ClassificationType.KnownValues`).
78+
79+
[VisualStudio.Extensibility in-proc extension](../../get-started/in-proc-extensions.md), can use [ClassificationTypeDefinition](/dotnet/api/microsoft.visualstudio.text.classification.classificationtypedefinition)
80+
to define new classification types. Their name can be referenced using
81+
`ClassificationType.Custom`.

docs/extensibility/visualstudio.extensibility/editor/walkthroughs/taggers.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -11,12 +11,13 @@ ms.subservice: extensibility-integration
1111
---
1212

1313
# Extending Visual Studio editor with a new tagger
14-
Extensions can contribute new taggers to Visual Studio. Taggers are used to associate data with spans of text. The data provided by taggers are consumed by other Visual Studio features (for example, [CodeLens](./codelens.md)).
14+
Extensions can contribute new taggers to Visual Studio. Taggers are used to associate data with ranges of text. The data provided by taggers are consumed by other Visual Studio features (for example, [CodeLens](./codelens.md)).
1515

1616
VisualStudio.Extensibility only supports tag types that are provided by the [Microsoft.VisualStudio.Extensibility](https://www.nuget.org/packages/Microsoft.VisualStudio.Extensibility) package and implement the `Microsoft.VisualStudio.Extensibility.Editor.ITag` interface:
1717

1818
- `CodeLensTag` can be used together with an [ICodeLensProvider](./codelens.md) to add Code Lenses to documents
1919
- `TextMarkerTag` can be used to highlight portions of documents. VisualStudio.Extensibility doesn't support defining new Text Marker styles yet, so only styles that are built into Visual Studio or provided by a VSSDK extension can be used for now (a [VisualStudio.Extensibility in-proc extension](../../get-started/in-proc-extensions.md) can create Text Marker styles with an `[Export(typeof(EditorFormatDefinition))]`).
20+
- `ClassificationTag` can be used to classify a document's syntax allowing for the text to be colorized accordingly.
2021

2122
To generate tags, the extension must contribute an extension part that implements `ITextViewTaggerProvider<>` for the type (or types) of tags provided. The extension part also needs to implement `ITextViewChangedListener` to react to document changes:
2223

docs/extensibility/visualstudio.extensibility/toc.yml

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,9 @@ items:
4646
- name: Extending Visual Studio editor with a new CodeLens
4747
href: ./editor/walkthroughs/codelens.md
4848
- name: Extending Visual Studio editor with a new tagger
49-
href: ./editor/walkthroughs/taggers.md
49+
href: ./editor/walkthroughs/taggers.md
50+
- name: Extending Visual Studio editor with new classification tagger
51+
href: ./editor/walkthroughs/classification.md
5052
- name: Editor concepts
5153
href: ./editor/editor-concepts.md
5254
- name: Editor RPC

docs/extensibility/visualstudio.extensibility/visualstudio-extensibility.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -107,6 +107,7 @@ You can find a Visual Studio solution that contains all samples at [Samples.sln]
107107
| [RegexMatchDebugVisualizer](https://github.com/microsoft/VSExtensibility/tree/main/New_Extensibility_Model/Samples/RegexMatchDebugVisualizer) | Shows how to use [Remote UI](./inside-the-sdk/remote-ui.md) to create a [Debugger Visualizer](./debugger-visualizer/debugger-visualizers.md) to visualize regular expression matches that will launch in a modal dialog window. |
108108
| [MemoryStreamDebugVisualizer](https://github.com/microsoft/VSExtensibility/tree/main/New_Extensibility_Model/Samples/MemoryStreamDebugVisualizer) | Shows how to create a [Debugger Visualizer](./debugger-visualizer/debugger-visualizers.md) to visualize MemoryStream objects that launches in a non-modal tool window. |
109109
| [RustLanguageServiceProvider](https://github.com/microsoft/VSExtensibility/tree/main/New_Extensibility_Model/Samples/RustLanguageServerProvider) | Shows how to create a Rust language server provider extension that adds Intellisense and tooltips when a rust file is opened. |
110+
| [CompositeExtension](https://github.com/microsoft/VSExtensibility/tree/main/New_Extensibility_Model/Samples/CompositeExtension) | Shows how to create an extension with in-proc and out-of-proc components that communicate using brokered services. . |
110111

111112
## Experimental APIs and Breaking Changes
112113
Starting with our 17.9 release, we're ready to label most of our APIs as stable. That is, we don't plan to make any breaking changes to these APIs. Any breaking changes, such as those prompted by user feedback on usability, will be formally communicated in advance on our [breaking changes](https://github.com/microsoft/VSExtensibility/blob/main/docs/breaking_changes.md) page with ample notice.

0 commit comments

Comments
 (0)