Add a galley extension sample (#288)
* Add a galley extension sample --------- Co-authored-by: Matteo Prosperi <maprospe@microsoft.com>
This commit is contained in:
Родитель
3c73510eed
Коммит
f24073093f
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"FeatureGallery.MainToolWindowCommand.DisplayName": "VisualStudio.Extensibility Feature Gallery",
|
||||
"FeatureGallery.LanguageServer.TodoLanguageServerProvider.DisplayName": "TODO language server"
|
||||
}
|
|
@ -0,0 +1,60 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery;
|
||||
#else
|
||||
namespace FeatureGallery;
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.Extensibility;
|
||||
using System.IO;
|
||||
using Microsoft.VisualStudio.RpcContracts.Documents;
|
||||
using Microsoft.VisualStudio.Extensibility.Shell;
|
||||
|
||||
[DataContract]
|
||||
internal class DocumentEditingTest : TestData
|
||||
{
|
||||
public DocumentEditingTest(VisualStudioExtensibility extensibility)
|
||||
: base(extensibility)
|
||||
{
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public override string ButtonText => "Edit a document";
|
||||
|
||||
[DataMember]
|
||||
public override string Description => "This command opens a new file and writes a random GUID in it. A prompt will ask to close the file.";
|
||||
|
||||
protected override async Task RunAsync(IClientContext clientContext, CancellationToken cancellationToken)
|
||||
{
|
||||
var filePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + ".md");
|
||||
File.Create(filePath).Close();
|
||||
bool keepFile = false;
|
||||
try
|
||||
{
|
||||
var textDocumentSnapshot = await this.Extensibility.Documents().OpenTextDocumentAsync(new(filePath), cancellationToken);
|
||||
|
||||
await this.Extensibility.Editor().EditAsync(
|
||||
batch => textDocumentSnapshot.AsEditable(batch).Insert(0, Guid.NewGuid().ToString()),
|
||||
cancellationToken);
|
||||
|
||||
if (!await this.Extensibility.Shell().ShowPromptAsync("Press OK to close and delete the file.", PromptOptions.OKCancel, cancellationToken))
|
||||
{
|
||||
keepFile = true;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!keepFile)
|
||||
{
|
||||
await this.Extensibility.Documents().CloseDocumentAsync(new(filePath), SaveDocumentOption.NoSave, cancellationToken);
|
||||
File.Delete(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,78 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery;
|
||||
#else
|
||||
namespace FeatureGallery;
|
||||
#endif
|
||||
|
||||
using System.IO;
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.Extensibility;
|
||||
using Microsoft.VisualStudio.Extensibility.Editor;
|
||||
using Microsoft.VisualStudio.Extensibility.Shell;
|
||||
using Microsoft.VisualStudio.RpcContracts.Documents;
|
||||
|
||||
[DataContract]
|
||||
internal class EditorMarginTest : TestData
|
||||
{
|
||||
#if INPROC
|
||||
public const string FileExtension = "mywords";
|
||||
#else
|
||||
public const string FileExtension = "words";
|
||||
#endif
|
||||
|
||||
public EditorMarginTest(VisualStudioExtensibility extensibility)
|
||||
: base(extensibility)
|
||||
{
|
||||
}
|
||||
|
||||
[VisualStudioContribution]
|
||||
public static DocumentTypeConfiguration WordsDocumentType => new(FileExtension)
|
||||
{
|
||||
FileExtensions = new[] { "." + FileExtension },
|
||||
BaseDocumentType = DocumentType.KnownValues.Text,
|
||||
};
|
||||
|
||||
[DataMember]
|
||||
public override string ButtonText => "Editor margin";
|
||||
|
||||
[DataMember]
|
||||
public override string Description => $"This command opens a text document with a custom editor margin counting the words in the document. A prompt will ask to close the file.";
|
||||
|
||||
protected override async Task RunAsync(IClientContext clientContext, CancellationToken cancellationToken)
|
||||
{
|
||||
var filePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + "." + FileExtension);
|
||||
bool keepFile = false;
|
||||
|
||||
using var file = new StreamWriter(File.Create(filePath));
|
||||
try
|
||||
{
|
||||
await file.WriteAsync("""
|
||||
Lorem ipsum dolor sit amet, consectetur adipiscing elit, sed do eiusmod tempor incididunt ut labore et dolore magna aliqua.
|
||||
Ut enim ad minim veniam, quis knostrud exercitation ullamco laboris nisi ut aliquip ex ea commodo consequat. Duis aute
|
||||
irure dolor in reprehenderit in voluptate velit esse cillum dolore eu fugiat nulla pariatur. Excepteur sint occaecat
|
||||
cupidatat non proident, sunt in culpa qui officia deserunt mollit anim id est laborum.
|
||||
""");
|
||||
file.Close();
|
||||
|
||||
var textDocumentSnapshot = await this.Extensibility.Documents().OpenTextDocumentAsync(new(filePath), cancellationToken);
|
||||
|
||||
if (!await this.Extensibility.Shell().ShowPromptAsync("Press OK to close and delete the file.", PromptOptions.OKCancel, cancellationToken))
|
||||
{
|
||||
keepFile = true;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!keepFile)
|
||||
{
|
||||
await this.Extensibility.Documents().CloseDocumentAsync(new(filePath), SaveDocumentOption.NoSave, cancellationToken);
|
||||
File.Delete(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery.EditorMargin;
|
||||
#else
|
||||
namespace FeatureGallery.EditorMargin;
|
||||
#endif
|
||||
|
||||
using Microsoft.VisualStudio.Extensibility.UI;
|
||||
|
||||
/// <summary>
|
||||
/// A sample remote user control to use as the margin content.
|
||||
/// </summary>
|
||||
internal class WordCountControl : RemoteUserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="WordCountControl" /> class.
|
||||
/// </summary>
|
||||
/// <param name="dataContext">
|
||||
/// Data context of the remote control which can be referenced from xaml through data binding.
|
||||
/// </param>
|
||||
public WordCountControl(object? dataContext)
|
||||
: base(dataContext)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,10 @@
|
|||
<DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vs="http://schemas.microsoft.com/visualstudio/extensibility/2022/xaml">
|
||||
<DockPanel Background="LightSkyBlue" TextBlock.FontSize="11" Height="16">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<TextBlock Padding="2, 0, 2, 0">Words: </TextBlock>
|
||||
<TextBlock x:Name="WordCountText" Text="{Binding WordCount}"/>
|
||||
</StackPanel>
|
||||
</DockPanel>
|
||||
</DataTemplate>
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery.EditorMargin;
|
||||
#else
|
||||
namespace FeatureGallery.EditorMargin;
|
||||
#endif
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
using Microsoft.VisualStudio.Extensibility.UI;
|
||||
|
||||
[DataContract]
|
||||
public class WordCountData : NotifyPropertyChangedObject
|
||||
{
|
||||
private int wordCount;
|
||||
|
||||
[DataMember]
|
||||
public int WordCount
|
||||
{
|
||||
get => this.wordCount;
|
||||
set => this.SetProperty(ref this.wordCount, value);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,91 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery.EditorMargin;
|
||||
#else
|
||||
namespace FeatureGallery.EditorMargin;
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.Extensibility;
|
||||
using Microsoft.VisualStudio.Extensibility.Editor;
|
||||
using Microsoft.VisualStudio.RpcContracts.RemoteUI;
|
||||
|
||||
/// <summary>
|
||||
/// A sample text view margin provider, which adds a margin to the Visual Studio editor status bar, to the left
|
||||
/// of the built-in line number margin, indicating number of words in the current text document.
|
||||
/// </summary>
|
||||
[VisualStudioContribution]
|
||||
internal class WordCountMarginProvider : ExtensionPart, ITextViewMarginProvider, ITextViewOpenClosedListener, ITextViewChangedListener
|
||||
{
|
||||
private readonly Dictionary<Uri, WordCountData> dataModels = new();
|
||||
|
||||
/// <summary>
|
||||
/// Configures this extension part to be applied to any text view.
|
||||
/// </summary>
|
||||
public TextViewExtensionConfiguration TextViewExtensionConfiguration => new()
|
||||
{
|
||||
AppliesTo = new[]
|
||||
{
|
||||
DocumentFilter.FromDocumentType(EditorMarginTest.WordsDocumentType),
|
||||
},
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Configures the margin to be placed to the left of built-in Visual Studio line number margin.
|
||||
/// </summary>
|
||||
public TextViewMarginProviderConfiguration TextViewMarginProviderConfiguration =>
|
||||
new(marginContainer: ContainerMarginPlacement.KnownValues.BottomRightCorner)
|
||||
{
|
||||
Before = new[] { MarginPlacement.KnownValues.RowMargin },
|
||||
};
|
||||
|
||||
/// <summary>
|
||||
/// Creates a remotable visual element representing the content of the margin.
|
||||
/// </summary>
|
||||
public Task<IRemoteUserControl> CreateVisualElementAsync(ITextViewSnapshot textView, CancellationToken cancellationToken)
|
||||
{
|
||||
var dataModel = new WordCountData();
|
||||
dataModel.WordCount = CountWords(textView.Document);
|
||||
this.dataModels[textView.Uri] = dataModel;
|
||||
return Task.FromResult<IRemoteUserControl>(new WordCountControl(dataModel));
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task TextViewChangedAsync(TextViewChangedArgs args, CancellationToken cancellationToken)
|
||||
{
|
||||
this.dataModels[args.AfterTextView.Uri].WordCount = CountWords(args.AfterTextView.Document);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task TextViewClosedAsync(ITextViewSnapshot textView, CancellationToken cancellationToken)
|
||||
{
|
||||
this.dataModels.Remove(textView.Uri);
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public Task TextViewOpenedAsync(ITextViewSnapshot textView, CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
private static int CountWords(ITextDocumentSnapshot documentSnapshot)
|
||||
{
|
||||
int wordCount = 0;
|
||||
for (int i = 1; i < documentSnapshot.Length; i++)
|
||||
{
|
||||
if (char.IsWhiteSpace(documentSnapshot[i - 1]) && char.IsLetterOrDigit(documentSnapshot[i]))
|
||||
{
|
||||
wordCount++;
|
||||
}
|
||||
}
|
||||
|
||||
return wordCount;
|
||||
}
|
||||
}
|
|
@ -0,0 +1,26 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net8.0-windows8.0</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>11</LangVersion>
|
||||
<NeutralLanguage>en-US</NeutralLanguage>
|
||||
<NoWarn>$(NoWarn);CS1591;CA1812;CA1303;SA1600</NoWarn>
|
||||
|
||||
<!-- The VisualStudio.Extensibility preview packages are available from the azure-public/vside/msft_consumption feed -->
|
||||
<RestoreAdditionalProjectSources>https://pkgs.dev.azure.com/azure-public/vside/_packaging/msft_consumption/nuget/v3/index.json;$(RestoreAdditionalProjectSources)</RestoreAdditionalProjectSources>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Sdk" Version="17.9.52-preview-1" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Build" Version="17.9.52-preview-1" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.LanguageServer.Protocol" Version="17.2.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="EditorMargin\WordCountControl.xaml" />
|
||||
<EmbeddedResource Include="MainToolWindowControl.xaml" />
|
||||
<EmbeddedResource Include="ModalDialog\ModalDialogControl.xaml" />
|
||||
<Page Remove="MainToolWindowControl.xaml" />
|
||||
<Page Remove="EditorMargin\WordCountControl.xaml" />
|
||||
<Page Remove="ModalDialog\ModalDialogControl.xaml" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,39 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery;
|
||||
#else
|
||||
namespace FeatureGallery;
|
||||
#endif
|
||||
|
||||
using Microsoft.Extensions.DependencyInjection;
|
||||
using Microsoft.VisualStudio.Extensibility;
|
||||
|
||||
/// <summary>
|
||||
/// Extension entry point for the ToolWindowSample.
|
||||
/// </summary>
|
||||
[VisualStudioContribution]
|
||||
public class FeatureGalleryExtension : Extension
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override ExtensionConfiguration ExtensionConfiguration => new()
|
||||
{
|
||||
#if INPROC
|
||||
RequiresInProcessHosting = true,
|
||||
#else
|
||||
Metadata = new(
|
||||
id: "FeatureGalleryExtension.f83f7a5e-61aa-4bb6-8f25-1cd2764e0123",
|
||||
version: this.ExtensionAssemblyVersion,
|
||||
publisherName: "Microsoft",
|
||||
displayName: "VisualStudio.Extensibility Feature Gallery",
|
||||
description: "An extension demonstrating multiple Visual Studio extension points."),
|
||||
#endif
|
||||
};
|
||||
|
||||
/// <inheritdoc/>
|
||||
protected override void InitializeServices(IServiceCollection serviceCollection)
|
||||
{
|
||||
base.InitializeServices(serviceCollection);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,112 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery.LanguageServer;
|
||||
#else
|
||||
namespace FeatureGallery.LanguageServer;
|
||||
#endif
|
||||
|
||||
using System;
|
||||
using System.Threading.Tasks;
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Text.RegularExpressions;
|
||||
using Microsoft.VisualStudio.LanguageServer.Protocol;
|
||||
using Newtonsoft.Json.Linq;
|
||||
using StreamJsonRpc;
|
||||
using System.Threading;
|
||||
using System.Linq;
|
||||
using Microsoft.ServiceHub.Resources;
|
||||
|
||||
internal class LanguageServer
|
||||
{
|
||||
private static readonly Regex TodoRegex = new(@"TODO:\s*(.+)$", RegexOptions.Compiled);
|
||||
private readonly JsonRpc rpc;
|
||||
|
||||
public LanguageServer(JsonRpc rpc)
|
||||
{
|
||||
this.rpc = rpc;
|
||||
}
|
||||
|
||||
[JsonRpcMethod(Methods.InitializeName)]
|
||||
public InitializeResult Initialize(JToken arg)
|
||||
{
|
||||
return new()
|
||||
{
|
||||
Capabilities = new()
|
||||
{
|
||||
TextDocumentSync = new()
|
||||
{
|
||||
OpenClose = true,
|
||||
Change = TextDocumentSyncKind.Full,
|
||||
},
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
[JsonRpcMethod(Methods.TextDocumentDidOpenName, UseSingleObjectParameterDeserialization = true)]
|
||||
public async Task OnTextDocumentOpenedAsync(DidOpenTextDocumentParams messageParams, CancellationToken cancellationToken)
|
||||
{
|
||||
await this.VerifyDocumentAsync(messageParams.TextDocument.Uri, messageParams.TextDocument.Text);
|
||||
}
|
||||
|
||||
[JsonRpcMethod(Methods.TextDocumentDidChangeName, UseSingleObjectParameterDeserialization = true)]
|
||||
public async Task OnTextDocumentChangedAsync(DidChangeTextDocumentParams messageParams, CancellationToken cancellationToken)
|
||||
{
|
||||
await this.VerifyDocumentAsync(messageParams.TextDocument.Uri, messageParams.ContentChanges.Single().Text);
|
||||
}
|
||||
|
||||
[JsonRpcMethod(Methods.TextDocumentDidCloseName, UseSingleObjectParameterDeserialization = true)]
|
||||
public async Task OnTextDocumentClosedAsync(DidCloseTextDocumentParams messageParams, CancellationToken cancellationToken)
|
||||
{
|
||||
PublishDiagnosticParams notificationParams = new() { Uri = messageParams.TextDocument.Uri, Diagnostics = Array.Empty<Diagnostic>() };
|
||||
await this.rpc.NotifyWithParameterObjectAsync(Methods.TextDocumentPublishDiagnosticsName, notificationParams);
|
||||
}
|
||||
|
||||
private async Task VerifyDocumentAsync(Uri uri, string text)
|
||||
{
|
||||
List<Diagnostic> diagnostics = new();
|
||||
|
||||
using StringReader reader = new(text);
|
||||
string line;
|
||||
for (int lineCounter = 0;
|
||||
(line = await reader.ReadLineAsync()) != null;
|
||||
lineCounter++)
|
||||
{
|
||||
var match = TodoRegex.Match(line);
|
||||
if (match.Success)
|
||||
{
|
||||
var group = match.Groups[1];
|
||||
|
||||
diagnostics.Add(new()
|
||||
{
|
||||
Severity = DiagnosticSeverity.Error,
|
||||
Code = "TODO",
|
||||
#if INPROC
|
||||
Source = "In-proc TODO Language Server",
|
||||
#else
|
||||
Source = "TODO Language Server",
|
||||
#endif
|
||||
Message = group.Value,
|
||||
Range = new()
|
||||
{
|
||||
Start = new()
|
||||
{
|
||||
Line = lineCounter,
|
||||
Character = group.Index,
|
||||
},
|
||||
End = new()
|
||||
{
|
||||
Line = lineCounter,
|
||||
Character = group.Index + group.Length,
|
||||
},
|
||||
},
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
PublishDiagnosticParams notificationParams = new() { Uri = uri, Diagnostics = diagnostics.ToArray() };
|
||||
await this.rpc.NotifyWithParameterObjectAsync(Methods.TextDocumentPublishDiagnosticsName, notificationParams);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,80 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery;
|
||||
#else
|
||||
namespace FeatureGallery;
|
||||
#endif
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.Extensibility;
|
||||
using System.IO;
|
||||
using Microsoft.VisualStudio.RpcContracts.Documents;
|
||||
using Microsoft.VisualStudio.Extensibility.Shell;
|
||||
using Microsoft.VisualStudio.Extensibility.Editor;
|
||||
using Microsoft.VisualStudio.Extensibility.LanguageServer;
|
||||
|
||||
[DataContract]
|
||||
internal class LanguageServerTest : TestData
|
||||
{
|
||||
#if INPROC
|
||||
public const string FileExtension = "todo";
|
||||
#else
|
||||
public const string FileExtension = "todos";
|
||||
#endif
|
||||
|
||||
public LanguageServerTest(VisualStudioExtensibility extensibility)
|
||||
: base(extensibility)
|
||||
{
|
||||
}
|
||||
|
||||
[VisualStudioContribution]
|
||||
#pragma warning disable VSEXTAPI0001 // This API is marked as Preview.
|
||||
public static DocumentTypeConfiguration TodosDocumentType => new(FileExtension)
|
||||
{
|
||||
FileExtensions = new[] { "." + FileExtension },
|
||||
BaseDocumentType = LanguageServerProvider.LanguageServerBaseDocumentType,
|
||||
};
|
||||
#pragma warning restore VSEXTAPI0001 // This API is marked as Preview.
|
||||
|
||||
[DataMember]
|
||||
public override string ButtonText => "Language Server";
|
||||
|
||||
[DataMember]
|
||||
public override string Description => $"This command opens a new file, warning diagnostics will be generated for each line containing `TODO:`. A prompt will ask to close the file.";
|
||||
|
||||
protected override async Task RunAsync(IClientContext clientContext, CancellationToken cancellationToken)
|
||||
{
|
||||
var filePath = Path.Combine(Path.GetTempPath(), Path.GetRandomFileName() + "." + FileExtension);
|
||||
bool keepFile = false;
|
||||
|
||||
using var file = new StreamWriter(File.Create(filePath));
|
||||
try
|
||||
{
|
||||
await file.WriteAsync("""
|
||||
TODO: My first todo.
|
||||
Some other text.
|
||||
TODO: My second reminder.
|
||||
""");
|
||||
file.Close();
|
||||
|
||||
var textDocumentSnapshot = await this.Extensibility.Documents().OpenTextDocumentAsync(new(filePath), cancellationToken);
|
||||
|
||||
if (!await this.Extensibility.Shell().ShowPromptAsync("Press OK to close and delete the file.", PromptOptions.OKCancel, cancellationToken))
|
||||
{
|
||||
keepFile = true;
|
||||
}
|
||||
}
|
||||
finally
|
||||
{
|
||||
if (!keepFile)
|
||||
{
|
||||
await this.Extensibility.Documents().CloseDocumentAsync(new(filePath), SaveDocumentOption.NoSave, cancellationToken);
|
||||
File.Delete(filePath);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
|
@ -0,0 +1,51 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery.LanguageServer;
|
||||
#else
|
||||
namespace FeatureGallery.LanguageServer;
|
||||
|
||||
using System;
|
||||
#endif
|
||||
|
||||
using System.IO.Pipelines;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.Extensibility;
|
||||
using Microsoft.VisualStudio.Extensibility.LanguageServer;
|
||||
using Nerdbank.Streams;
|
||||
using StreamJsonRpc;
|
||||
|
||||
/// <inheritdoc/>
|
||||
[VisualStudioContribution]
|
||||
#pragma warning disable VSEXTAPI0001 // This API is marked as Preview.
|
||||
internal class TodoLanguageServerProvider : LanguageServerProvider
|
||||
{
|
||||
/// <inheritdoc/>
|
||||
public override LanguageServerProviderConfiguration LanguageServerProviderConfiguration => new(
|
||||
#if INPROC
|
||||
"%InProcFeatureGallery.LanguageServer.TodoLanguageServerProvider.DisplayName%",
|
||||
#else
|
||||
"%FeatureGallery.LanguageServer.TodoLanguageServerProvider.DisplayName%",
|
||||
#endif
|
||||
new[]
|
||||
{
|
||||
DocumentFilter.FromDocumentType(LanguageServerTest.TodosDocumentType),
|
||||
});
|
||||
|
||||
/// <inheritdoc/>
|
||||
public override Task<IDuplexPipe?> CreateServerConnectionAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
var streams = FullDuplexStream.CreatePair();
|
||||
|
||||
JsonRpc rpc = new(streams.Item2);
|
||||
rpc.AddLocalRpcTarget(new LanguageServer(rpc));
|
||||
rpc.StartListening();
|
||||
|
||||
return Task.FromResult<IDuplexPipe?>(new DuplexPipe(
|
||||
PipeReader.Create(streams.Item1),
|
||||
PipeWriter.Create(streams.Item1)));
|
||||
}
|
||||
}
|
||||
#pragma warning restore VSEXTAPI0001 // This API is marked as Preview.
|
|
@ -0,0 +1,56 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery;
|
||||
#else
|
||||
namespace FeatureGallery;
|
||||
#endif
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.Extensibility;
|
||||
using Microsoft.VisualStudio.Extensibility.ToolWindows;
|
||||
using Microsoft.VisualStudio.RpcContracts.RemoteUI;
|
||||
|
||||
/// <summary>
|
||||
/// A sample tool window.
|
||||
/// </summary>
|
||||
[VisualStudioContribution]
|
||||
public class MainToolWindow : ToolWindow
|
||||
{
|
||||
private readonly IReadOnlyList<TestData> tests;
|
||||
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MainToolWindow" /> class.
|
||||
/// </summary>
|
||||
public MainToolWindow()
|
||||
{
|
||||
#if INPROC
|
||||
this.Title = "In-proc VisualStudio.Extensibility Feature Gallery";
|
||||
#else
|
||||
this.Title = "VisualStudio.Extensibility Feature Gallery";
|
||||
#endif
|
||||
this.tests = new TestData[]
|
||||
{
|
||||
new DocumentEditingTest(this.Extensibility),
|
||||
new ModalDialogTest(this.Extensibility),
|
||||
new EditorMarginTest(this.Extensibility),
|
||||
new LanguageServerTest(this.Extensibility),
|
||||
};
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override ToolWindowConfiguration ToolWindowConfiguration => new()
|
||||
{
|
||||
Placement = ToolWindowPlacement.Floating,
|
||||
AllowAutoCreation = true,
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public override Task<IRemoteUserControl> GetContentAsync(CancellationToken cancellationToken)
|
||||
{
|
||||
return Task.FromResult<IRemoteUserControl>(new MainToolWindowControl(this.tests));
|
||||
}
|
||||
}
|
|
@ -0,0 +1,46 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery;
|
||||
#else
|
||||
namespace FeatureGallery;
|
||||
#endif
|
||||
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.Extensibility;
|
||||
using Microsoft.VisualStudio.Extensibility.Commands;
|
||||
|
||||
/// <summary>
|
||||
/// A sample command for showing a tool window.
|
||||
/// </summary>
|
||||
[VisualStudioContribution]
|
||||
public class MainToolWindowCommand : Command
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MainToolWindowCommand" /> class.
|
||||
/// </summary>
|
||||
public MainToolWindowCommand()
|
||||
{
|
||||
}
|
||||
|
||||
/// <inheritdoc />
|
||||
public override CommandConfiguration CommandConfiguration => new(
|
||||
#if INPROC
|
||||
"%InProcFeatureGallery.MainToolWindowCommand.DisplayName%"
|
||||
#else
|
||||
"%FeatureGallery.MainToolWindowCommand.DisplayName%"
|
||||
#endif
|
||||
)
|
||||
{
|
||||
Placements = new[] { CommandPlacement.KnownPlacements.ExtensionsMenu },
|
||||
Icon = new(ImageMoniker.KnownValues.Extension, IconSettings.IconAndText),
|
||||
};
|
||||
|
||||
/// <inheritdoc />
|
||||
public override async Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
|
||||
{
|
||||
await this.Extensibility.Shell().ShowToolWindowAsync<MainToolWindow>(activate: true, cancellationToken);
|
||||
}
|
||||
}
|
|
@ -0,0 +1,27 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery;
|
||||
#else
|
||||
namespace FeatureGallery;
|
||||
#endif
|
||||
|
||||
using Microsoft.VisualStudio.Extensibility.UI;
|
||||
|
||||
/// <summary>
|
||||
/// A sample remote user control to use as tool window UI content.
|
||||
/// </summary>
|
||||
internal class MainToolWindowControl : RemoteUserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="MainToolWindowControl" /> class.
|
||||
/// </summary>
|
||||
/// <param name="dataContext">
|
||||
/// Data context of the remote control which can be referenced from xaml through data binding.
|
||||
/// </param>
|
||||
public MainToolWindowControl(object? dataContext)
|
||||
: base(dataContext)
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,33 @@
|
|||
<DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vs="http://schemas.microsoft.com/visualstudio/extensibility/2022/xaml"
|
||||
xmlns:styles="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.15.0"
|
||||
xmlns:colors="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0">
|
||||
<Grid x:Name="RootGrid">
|
||||
<Grid.Resources>
|
||||
<Style TargetType="ListView" BasedOn="{StaticResource {x:Static styles:VsResourceKeys.ThemedDialogListViewStyleKey}}" />
|
||||
<Style TargetType="Button" BasedOn="{StaticResource {x:Static styles:VsResourceKeys.ButtonStyleKey}}" />
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static styles:VsBrushes.WindowTextKey}}" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
<ListView ItemsSource="{Binding .}" HorizontalContentAlignment="Stretch" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="Auto" />
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<Button Content="{Binding ButtonText}" Command="{Binding Command}" IsEnabled="{Binding Command.RunningCommandsCount.IsZero}" />
|
||||
<TextBlock Text="{Binding Description}" TextWrapping="Wrap" Grid.Row="1" Grid.ColumnSpan="2" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
</Grid>
|
||||
</DataTemplate>
|
|
@ -0,0 +1,24 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery.ModalDialog;
|
||||
#else
|
||||
namespace FeatureGallery.ModalDialog;
|
||||
#endif
|
||||
|
||||
using Microsoft.VisualStudio.Extensibility.UI;
|
||||
|
||||
/// <summary>
|
||||
/// A sample remote user control to use as tool window UI content.
|
||||
/// </summary>
|
||||
internal class ModalDialogControl : RemoteUserControl
|
||||
{
|
||||
/// <summary>
|
||||
/// Initializes a new instance of the <see cref="ModalDialogControl" /> class.
|
||||
/// </summary>
|
||||
public ModalDialogControl()
|
||||
: base(new ModalDialogData())
|
||||
{
|
||||
}
|
||||
}
|
|
@ -0,0 +1,45 @@
|
|||
<DataTemplate xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:vs="http://schemas.microsoft.com/visualstudio/extensibility/2022/xaml"
|
||||
xmlns:styles="clr-namespace:Microsoft.VisualStudio.Shell;assembly=Microsoft.VisualStudio.Shell.15.0"
|
||||
xmlns:colors="clr-namespace:Microsoft.VisualStudio.PlatformUI;assembly=Microsoft.VisualStudio.Shell.15.0">
|
||||
<Grid x:Name="RootGrid">
|
||||
<Grid.Resources>
|
||||
<Style TargetType="ListView" BasedOn="{StaticResource {x:Static styles:VsResourceKeys.ThemedDialogListViewStyleKey}}" />
|
||||
<Style TargetType="Button" BasedOn="{StaticResource {x:Static styles:VsResourceKeys.ButtonStyleKey}}" />
|
||||
<Style TargetType="TextBlock">
|
||||
<Setter Property="Foreground" Value="{DynamicResource {x:Static styles:VsBrushes.WindowTextKey}}" />
|
||||
</Style>
|
||||
</Grid.Resources>
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="*"/>
|
||||
<RowDefinition Height="Auto" />
|
||||
</Grid.RowDefinitions>
|
||||
<ListView ItemsSource="{Binding Colors}" HorizontalContentAlignment="Stretch" MinWidth="200" MinHeight="400">
|
||||
<ListView.ItemTemplate>
|
||||
<DataTemplate>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="*" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
<ColumnDefinition Width="Auto" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<TextBlock Text="{Binding ColorText}" />
|
||||
<Rectangle Fill="{Binding Color}" Width="50px" Grid.Column="1" />
|
||||
<Button Content="Remove" Grid.Column="2" IsEnabled="{Binding Path=(vs:ExtensibilityUICommands.RunningCommandsCount).IsZero, RelativeSource={RelativeSource Self}}">
|
||||
<vs:ExtensibilityUICommands.EventHandlers>
|
||||
<vs:EventHandlerCollection>
|
||||
<vs:EventHandler Event="Click"
|
||||
Command="{Binding DataContext.RemoveColorCommand, ElementName=RootGrid}"
|
||||
CommandParameter="{Binding}"
|
||||
CounterTarget="{Binding RelativeSource={RelativeSource Self}}" />
|
||||
</vs:EventHandlerCollection>
|
||||
</vs:ExtensibilityUICommands.EventHandlers>
|
||||
</Button>
|
||||
</Grid>
|
||||
</DataTemplate>
|
||||
</ListView.ItemTemplate>
|
||||
</ListView>
|
||||
<Button Content="Add color" Command="{Binding AddColorCommand}" IsEnabled="{Binding AddColorCommand.RunningCommandsCount.IsZero}" Grid.Row="1" />
|
||||
</Grid>
|
||||
</DataTemplate>
|
|
@ -0,0 +1,66 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery.ModalDialog;
|
||||
#else
|
||||
namespace FeatureGallery.ModalDialog;
|
||||
#endif
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading.Tasks;
|
||||
using System;
|
||||
using Microsoft.VisualStudio.Extensibility.UI;
|
||||
|
||||
[DataContract]
|
||||
internal class ModalDialogData
|
||||
{
|
||||
private Random random = new();
|
||||
|
||||
public ModalDialogData()
|
||||
{
|
||||
this.AddColorCommand = new AsyncCommand((parameter, cancellationToken) =>
|
||||
{
|
||||
var color = new byte[3];
|
||||
this.random.NextBytes(color);
|
||||
this.Colors.Add(new MyColor(color[0], color[1], color[2]));
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
|
||||
this.RemoveColorCommand = new AsyncCommand((parameter, cancellationToken) =>
|
||||
{
|
||||
this.Colors.Remove((MyColor)parameter!);
|
||||
return Task.CompletedTask;
|
||||
});
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public ObservableList<MyColor> Colors { get; } = new();
|
||||
|
||||
[DataMember]
|
||||
public AsyncCommand AddColorCommand { get; }
|
||||
|
||||
[DataMember]
|
||||
public AsyncCommand RemoveColorCommand { get; }
|
||||
|
||||
[DataContract]
|
||||
public class MyColor
|
||||
{
|
||||
public MyColor(byte r, byte g, byte b)
|
||||
{
|
||||
this.ColorText = $"#{r:X2}{g:X2}{b:X2}";
|
||||
this.Color = new($"""
|
||||
<LinearGradientBrush xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" StartPoint="0,0" EndPoint="1,1">
|
||||
<GradientStop Color="Black" Offset="0.0" />
|
||||
<GradientStop Color="{this.ColorText}" Offset="0.7" />
|
||||
</LinearGradientBrush>
|
||||
""");
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public string ColorText { get; }
|
||||
|
||||
[DataMember]
|
||||
public XamlFragment Color { get; }
|
||||
}
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery;
|
||||
#else
|
||||
namespace FeatureGallery;
|
||||
#endif
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.VisualStudio.Extensibility;
|
||||
|
||||
[DataContract]
|
||||
internal class ModalDialogTest : TestData
|
||||
{
|
||||
public ModalDialogTest(VisualStudioExtensibility extensibility)
|
||||
: base(extensibility)
|
||||
{
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public override string ButtonText => "Modal dialog";
|
||||
|
||||
[DataMember]
|
||||
public override string Description => "This command opens a modal dialog where random colors can be added or removed from a list.";
|
||||
|
||||
protected override async Task RunAsync(IClientContext clientContext, CancellationToken cancellationToken)
|
||||
{
|
||||
#pragma warning disable CA2000 // Dispose objects before losing scope. ModalDialogControl is passed to Visual Studio which will take care of disposing it
|
||||
await this.Extensibility.Shell().ShowDialogAsync(new ModalDialog.ModalDialogControl(), cancellationToken);
|
||||
#pragma warning restore CA2000 // Dispose objects before losing scope
|
||||
}
|
||||
}
|
|
@ -0,0 +1,38 @@
|
|||
// Copyright (c) Microsoft. All rights reserved.
|
||||
// Licensed under the MIT license. See LICENSE file in the project root for full license information.
|
||||
|
||||
#if INPROC
|
||||
namespace InProcFeatureGallery;
|
||||
#else
|
||||
namespace FeatureGallery;
|
||||
#endif
|
||||
|
||||
using System.Runtime.Serialization;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft;
|
||||
using Microsoft.VisualStudio.Extensibility;
|
||||
using Microsoft.VisualStudio.Extensibility.UI;
|
||||
|
||||
[DataContract]
|
||||
internal abstract class TestData
|
||||
{
|
||||
public TestData(VisualStudioExtensibility extensibility)
|
||||
{
|
||||
this.Extensibility = extensibility;
|
||||
this.Command = new AsyncCommand((_, cc, ct) => this.RunAsync(cc, ct));
|
||||
}
|
||||
|
||||
[DataMember]
|
||||
public abstract string ButtonText { get; }
|
||||
|
||||
[DataMember]
|
||||
public abstract string Description { get; }
|
||||
|
||||
[DataMember]
|
||||
public IAsyncCommand Command { get; }
|
||||
|
||||
protected VisualStudioExtensibility Extensibility { get; }
|
||||
|
||||
protected abstract Task RunAsync(IClientContext clientContext, CancellationToken cancellationToken);
|
||||
}
|
|
@ -0,0 +1,4 @@
|
|||
{
|
||||
"InProcFeatureGallery.MainToolWindowCommand.DisplayName": "In-proc VisualStudio.Extensibility Feature Gallery",
|
||||
"InProcFeatureGallery.LanguageServer.TodoLanguageServerProvider.DisplayName": "In-proc TODO language server"
|
||||
}
|
|
@ -0,0 +1,35 @@
|
|||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup>
|
||||
<TargetFramework>net472</TargetFramework>
|
||||
<Nullable>enable</Nullable>
|
||||
<LangVersion>11</LangVersion>
|
||||
<NeutralLanguage>en-US</NeutralLanguage>
|
||||
<NoWarn>$(NoWarn);CS1591;CA1812;CA1303;SA1600</NoWarn>
|
||||
|
||||
<!-- The VisualStudio.Extensibility preview packages are available from the azure-public/vside/msft_consumption feed -->
|
||||
<RestoreAdditionalProjectSources>https://pkgs.dev.azure.com/azure-public/vside/_packaging/msft_consumption/nuget/v3/index.json;$(RestoreAdditionalProjectSources)</RestoreAdditionalProjectSources>
|
||||
|
||||
<VssdkCompatibleExtension>true</VssdkCompatibleExtension>
|
||||
<DefineConstants>$(DefineConstants);INPROC</DefineConstants>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Sdk" Version="17.9.52-preview-1" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Build" Version="17.9.52-preview-1" />
|
||||
<PackageReference Include="Microsoft.VisualStudio.LanguageServer.Protocol" Version="17.2.8" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<EmbeddedResource Include="..\FeatureGallery\MainToolWindowControl.xaml" />
|
||||
<EmbeddedResource Include="..\FeatureGallery\EditorMargin\WordCountControl.xaml" Link="EditorMargin\WordCountControl.xaml" />
|
||||
<EmbeddedResource Include="..\FeatureGallery\ModalDialog\ModalDialogControl.xaml" Link="ModalDialog\ModalDialogControl.xaml" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Compile Include="..\FeatureGallery\**\*.cs" />
|
||||
</ItemGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<Content Include=".vsextension\string-resources.json" />
|
||||
</ItemGroup>
|
||||
</Project>
|
|
@ -0,0 +1,22 @@
|
|||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<PackageManifest Version="2.0.0" xmlns="http://schemas.microsoft.com/developer/vsx-schema/2011" xmlns:d="http://schemas.microsoft.com/developer/vsx-schema-design/2011">
|
||||
<Metadata>
|
||||
<Identity Id="InProcFeatureGalleryExtension.8856bea4-d1fd-4b49-9f3a-c99ea5f66e57" Version="1.0" Language="en-US" Publisher="Microsoft" />
|
||||
<DisplayName>In-proc VisualStudio.Extensibility Feature Gallery</DisplayName>
|
||||
<Description xml:space="preserve">An extension demonstrating multiple Visual Studio extension points.</Description>
|
||||
</Metadata>
|
||||
<Installation ExtensionType="VSSDK+VisualStudio.Extensibility">
|
||||
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[17.9,18.0)">
|
||||
<ProductArchitecture>amd64</ProductArchitecture>
|
||||
</InstallationTarget>
|
||||
<InstallationTarget Id="Microsoft.VisualStudio.Community" Version="[17.9,18.0)">
|
||||
<ProductArchitecture>arm64</ProductArchitecture>
|
||||
</InstallationTarget>
|
||||
</Installation>
|
||||
<Prerequisites>
|
||||
<Prerequisite Id="Microsoft.VisualStudio.Component.CoreEditor" Version="[17.0,)" DisplayName="Visual Studio core editor" />
|
||||
</Prerequisites>
|
||||
<Assets>
|
||||
<Asset Type="Microsoft.VisualStudio.VsPackage" d:Source="Project" d:ProjectName="%CurrentProject%" Path="|%CurrentProject%;PkgdefProjectOutputGroup|" />
|
||||
</Assets>
|
||||
</PackageManifest>
|
|
@ -47,6 +47,10 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "CommentRemover", "CommentRe
|
|||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "RustLanguageServerProvider", "RustLanguageServerProvider\RustLanguageServerProvider.csproj", "{99684185-2C81-45B3-A69F-0852AD0E4F9E}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "FeatureGallery", "FeatureGallery\FeatureGallery.csproj", "{7411CD7E-B825-4E7A-91A9-99A65EEE4073}"
|
||||
EndProject
|
||||
Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "InProcFeatureGallery", "InProcFeatureGallery\InProcFeatureGallery.csproj", "{713DB53E-4099-42FF-B6D9-ACA84F6136D9}"
|
||||
EndProject
|
||||
Global
|
||||
GlobalSection(SolutionConfigurationPlatforms) = preSolution
|
||||
Debug|Any CPU = Debug|Any CPU
|
||||
|
@ -199,6 +203,26 @@ Global
|
|||
{99684185-2C81-45B3-A69F-0852AD0E4F9E}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{99684185-2C81-45B3-A69F-0852AD0E4F9E}.Release|x86.Build.0 = Release|Any CPU
|
||||
{99684185-2C81-45B3-A69F-0852AD0E4F9E}.Release|x86.Deploy.0 = Release|Any CPU
|
||||
{7411CD7E-B825-4E7A-91A9-99A65EEE4073}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{7411CD7E-B825-4E7A-91A9-99A65EEE4073}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{7411CD7E-B825-4E7A-91A9-99A65EEE4073}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
|
||||
{7411CD7E-B825-4E7A-91A9-99A65EEE4073}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{7411CD7E-B825-4E7A-91A9-99A65EEE4073}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{7411CD7E-B825-4E7A-91A9-99A65EEE4073}.Debug|x86.Deploy.0 = Debug|Any CPU
|
||||
{7411CD7E-B825-4E7A-91A9-99A65EEE4073}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{7411CD7E-B825-4E7A-91A9-99A65EEE4073}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{7411CD7E-B825-4E7A-91A9-99A65EEE4073}.Release|Any CPU.Deploy.0 = Release|Any CPU
|
||||
{7411CD7E-B825-4E7A-91A9-99A65EEE4073}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{7411CD7E-B825-4E7A-91A9-99A65EEE4073}.Release|x86.Build.0 = Release|Any CPU
|
||||
{7411CD7E-B825-4E7A-91A9-99A65EEE4073}.Release|x86.Deploy.0 = Release|Any CPU
|
||||
{713DB53E-4099-42FF-B6D9-ACA84F6136D9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
|
||||
{713DB53E-4099-42FF-B6D9-ACA84F6136D9}.Debug|Any CPU.Build.0 = Debug|Any CPU
|
||||
{713DB53E-4099-42FF-B6D9-ACA84F6136D9}.Debug|x86.ActiveCfg = Debug|Any CPU
|
||||
{713DB53E-4099-42FF-B6D9-ACA84F6136D9}.Debug|x86.Build.0 = Debug|Any CPU
|
||||
{713DB53E-4099-42FF-B6D9-ACA84F6136D9}.Release|Any CPU.ActiveCfg = Release|Any CPU
|
||||
{713DB53E-4099-42FF-B6D9-ACA84F6136D9}.Release|Any CPU.Build.0 = Release|Any CPU
|
||||
{713DB53E-4099-42FF-B6D9-ACA84F6136D9}.Release|x86.ActiveCfg = Release|Any CPU
|
||||
{713DB53E-4099-42FF-B6D9-ACA84F6136D9}.Release|x86.Build.0 = Release|Any CPU
|
||||
EndGlobalSection
|
||||
GlobalSection(SolutionProperties) = preSolution
|
||||
HideSolutionNode = FALSE
|
||||
|
|
Загрузка…
Ссылка в новой задаче