Extensión de documentos de Visual Studio
Un documento es la representación en memoria de un archivo que se abre en Visual Studio. Se hace referencia a él por moniker, que es un absoluto Uri
mediante el file://
esquema . Un documento se representa mediante la DocumentSnapshot
clase , que tiene las siguientes propiedades:
Moniker
IsDirty
IsReadOnly
IsInitialized
El DocumentsExtensibility
objeto proporciona varios métodos que se usan para obtener y trabajar con DocumentSnapshot
instancias de objeto.
Trabajar con documentos
Esta guía está diseñada para cubrir los principales escenarios de usuario al trabajar con documentos:
- Abrir un documento
- Obtención de una instantánea de documento de texto
- Reacción a eventos relacionados con documentos
Abrir un documento
Dada la ruta de acceso a un archivo en disco, es fácil abrir el archivo en Visual Studio:
DocumentsExtensibility documents = this.Extensibility.Documents();
Uri uri = new Uri(@"C:\path\to\Class1.cs", UriKind.Absolute);
DocumentSnapshot document = await documents.OpenDocumentAsync(uri, cancellationToken);
// optionally do something with the document
Obtención de una instantánea de documento de texto
A DocumentSnapshot
es una representación abstracta de un documento. Si desea leer o escribir el texto en , DocumentSnapshot
puede hacerlo mediante la ITextDocumentSnapshot
interfaz , que se puede obtener con el método de AsTextDocumentAsync
extensión para DocumentSnapshot
.
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
DocumentsExtensibility documents = this.Extensibility.Documents();
Uri moniker = await context.GetSelectedPathAsync(cancellationToken);
DocumentSnapshot document = await documents.GetDocumentAsync(moniker, cancellationToken);
ITextDocumentSnapshot snapshot = await document.AsTextDocumentAsync(this.Extensibility, cancellationToken);
// insert the current date/time
EditorExtensibility editor = this.Extensibility.Editor();
using ITextViewSnapshot textView = await context.GetActiveTextViewAsync(cancellationToken);
await editor.EditAsync(
batch => snapshot.AsEditable(batch).Replace(textView.Selection.Extent, DateTime.Now.ToString()),
cancellationToken);
}
Reacción a eventos relacionados con documentos
Hay escenarios en los que los componentes pueden querer reaccionar a eventos relacionados con documentos (es decir, cuando se abren, cierran o guardan). Esto se puede lograr mediante la implementación de la IDocumentEventsListener
interfaz y el uso DocumentsExtensibility.SubscribeAsync
de para configurar la suscripción de eventos.
internal sealed class SubscribeCommand : Command, IToggleCommand
{
private IDisposable? subscription;
bool? IToggleCommand.IsChecked => this.subscription is not null;
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
if (this.subscription is null)
{
// subscribe for events
this.subscription = await Subscription.CreateInstanceAsync(this.Extensibility, cancellationToken);
}
else
{
// remove the event subscription
this.subscription.Dispose();
this.subscription = null;
}
this.OnPropertyChanged(new PropertyChangedEventArgs(nameof(IToggleCommand.IsChecked)));
}
private class Subscription : IDisposable, IDocumentEventsListener
{
private readonly OutputWindowExtensibility output;
private IDisposable? rawSubscription;
private Subscription(VisualStudioExtensibility extensibility)
{
this.output = extensibility.Views().Output;
}
public static async Task<Subscription> CreateInstanceAsync(
VisualStudioExtensibility extensibility,
CancellationToken cancellationToken)
{
var subscription = new Subscription(extensibility);
DocumentsExtensibility documents = extensibility.Documents();
subscription.rawSubscription = await documents.SubscribeAsync(subscription, filterRegex: null, cancellationToken);
return subscription;
}
public void Dispose()
{
this.rawSubscription?.Dispose();
this.rawSubscription = null;
}
Task IDocumentEventsListener.ClosedAsync(DocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.ClosedAsync ({e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
Task IDocumentEventsListener.HiddenAsync(DocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.HiddenAsync ({e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
Task IDocumentEventsListener.OpenedAsync(DocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.OpenedAsync ({e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
Task IDocumentEventsListener.RenamedAsync(RenamedDocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.RenamedAsync ({e.OldMoniker} -> {e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
Task IDocumentEventsListener.SavedAsync(DocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.SavedAsync ({e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
Task IDocumentEventsListener.SavingAsync(DocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.SavingAsync ({e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
Task IDocumentEventsListener.ShownAsync(DocumentEventArgs e, CancellationToken token)
{
string text = $"IDocumentEventsListener.ShownAsync ({e.Moniker})";
return this.OutputEventTextAsync(text, token);
}
private async Task OutputEventTextAsync(string text, CancellationToken token)
{
using OutputWindow outputWindow = await this.output.GetChannelAsync(
identifier: "Document Sample Command Output",
displayNameResourceId: nameof(Strings.DocumentsSampleOutputWindowPaneName),
token);
await outputWindow.Writer.WriteLineAsync($"Event received: {text}");
}
}
}
Pasos siguientes
- Siga el inicio rápido sobre la creación del proyecto en la sección Introducción.