次の方法で共有


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使用して行うことができます。これは拡張メソッドDocumentSnapshotAsTextDocumentAsync取得できます。

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}");
        }
    }
}

次のステップ