Visual Studio のドキュメントを拡張する
ドキュメントは、Visual Studio で開かれたファイルのメモリ内表現です。 これはモニカーによって参照されます。これはスキームを使用したfile://
絶対Uri
です。 ドキュメントは、次のプロパティを DocumentSnapshot
持つクラスによって表されます。
Moniker
IsDirty
IsReadOnly
IsInitialized
オブジェクトには DocumentsExtensibility
、オブジェクト インスタンスの取得と操作 DocumentSnapshot
に使用されるさまざまなメソッドが用意されています。
文書の操作
このガイドは、ドキュメントを操作する際の上位のユーザー シナリオについて説明するように設計されています。
ドキュメントを開く
ディスク上のファイルへのパスを指定すると、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
テキスト ドキュメント スナップショットを取得する
A DocumentSnapshot
は、ドキュメントの抽象表現です。 テキストを読み書きDocumentSnapshot
する場合は、インターフェイスをITextDocumentSnapshot
使用して行うことができます。これは拡張メソッドDocumentSnapshot
でAsTextDocumentAsync
取得できます。
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);
}
ドキュメントに関連するイベントに対応する
コンポーネントがドキュメントに関連するイベント (つまり、開く、閉じる、または保存されたとき) に対応したい場合があります。 これを実現するには、インターフェイスを IDocumentEventsListener
実装し、イベント サブスクリプションを設定するために使用 DocumentsExtensibility.SubscribeAsync
します。
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}");
}
}
}
次のステップ
- 「はじめに」 セクションの「プロジェクト の作成」クイック スタートに従います。