Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Sample update for VS 17.9 Preview 1 #278

Merged
merged 42 commits into from
Nov 14, 2023
Merged
Show file tree
Hide file tree
Changes from 30 commits
Commits
Show all changes
42 commits
Select commit Hold shift + click to select a range
a1fd129
Initial attempt at converting out-of-proc extension samples
Aug 8, 2023
470269d
Update
Aug 9, 2023
81354bd
Fix
Aug 9, 2023
526eaf8
Cleanup
Aug 11, 2023
977195b
Update
Aug 16, 2023
a9251db
Update
Aug 18, 2023
95d63e8
Update package references
Aug 23, 2023
7c73c79
No need to disable extension deployment anymore
Aug 25, 2023
3d95668
Updating dependencies
Aug 28, 2023
8f345b6
Updating package references
Sep 11, 2023
72b43c9
Update package versions
Sep 11, 2023
cc434ab
Updating samples
Oct 12, 2023
3d54d1a
Merge from main and other fixes
Oct 12, 2023
de4b6a9
Updates
Oct 12, 2023
13fa508
Update Markdown Linter extension
BertanAygun Oct 16, 2023
d0db66a
Addressing PR comments
Oct 16, 2023
cf29161
Merge branch 'dev/maprospe/vsix_creation' of https://github.com/micro…
Oct 16, 2023
6b49829
Updating package version
Oct 16, 2023
181bc64
Fix breaking changes
RyanToth3 Oct 17, 2023
7804cb9
Update readmes
RyanToth3 Oct 17, 2023
3648e47
Update readmes to contain more information
RyanToth3 Oct 17, 2023
79a2a26
Update packages
Oct 20, 2023
d680652
Updating samples
Oct 23, 2023
14e1a57
Standardize the warning suppressions for all projects
Oct 23, 2023
e4546ea
Minor cleanups
Oct 23, 2023
bec6c7f
Updating comment remover readme
Oct 23, 2023
6d24805
Add disclaimer to Output Window readme
Oct 24, 2023
61fd833
Add readmes for the tool window and dialog samples (#275)
Newrad0603 Oct 25, 2023
41233ad
Add README for UserPromptSample project
Oct 25, 2023
0ebc8ad
Update samples landing page.
maiak Oct 26, 2023
c04d370
Update markdown linter readme
BertanAygun Oct 26, 2023
7e4aed2
Update package versions
Oct 26, 2023
993c1b7
Update InsertGuid.csproj
matteo-prosperi Oct 27, 2023
15700f9
Build in GitHub using .NET 8 (#279)
matteo-prosperi Oct 27, 2023
cb4fedd
Merge pull request #277 from microsoft/dev/maiak/samplesLandingPage
maiak Oct 27, 2023
f5b5c36
Merge pull request #276 from microsoft/dev/chawill/user-prompt-readme
maiak Oct 27, 2023
c3b9e14
Adds LSP sample using Rust analyzer (#281)
javierdlg Nov 1, 2023
7c196a1
Update packages
Nov 1, 2023
29241bf
Fix warning
Nov 1, 2023
05aa7d6
Upodating packages
Nov 1, 2023
7db3a00
Set extension type for the in-proc sample
Nov 2, 2023
66c514b
Update packages
Nov 3, 2023
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions New_Extensibility_Model/Samples/.editorconfig
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
root = true

[*]
indent_style = tab
indent_style = spaces

# (Please don't specify an indent_size here; that has too many unintended consequences.)

Expand Down Expand Up @@ -125,7 +125,7 @@ csharp_indent_labels = flush_left
# Prefer "var" everywhere
csharp_style_var_for_built_in_types = true:suggestion
csharp_style_var_when_type_is_apparent = true:suggestion
csharp_style_var_elsewhere = false:warning
csharp_style_var_elsewhere = false:suggestion

# Prefer method-like constructs to have a block body
csharp_style_expression_bodied_methods = false:none
Expand Down
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
{
"CommandParentingSample.SampleCommand.DisplayName": "My Command",
"CommandParentingSample.ToolBar.DisplayName": "Command Parenting Sample Toolbar"
"CommandParentingSample.SampleCommand.DisplayName": "My Command",
"CommandParentingSample.ToolBar.DisplayName": "Command Parenting Sample Toolbar"
}
Original file line number Diff line number Diff line change
@@ -1,26 +1,18 @@
<Project Sdk="Microsoft.NET.Sdk">

<PropertyGroup>
<TargetFrameworks>net6.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>11</LangVersion>
<CopyLocalLockFileAssemblies>true</CopyLocalLockFileAssemblies>
<NoWarn>SA1633;SA1600;CA1303;CA1016;CA1031;CA1812;$(NoWarn)</NoWarn>
<PropertyGroup>
<TargetFrameworks>net8.0-windows8.0</TargetFrameworks>
<ImplicitUsings>enable</ImplicitUsings>
<Nullable>enable</Nullable>
<LangVersion>11</LangVersion>
<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.8.2055-preview-3" />
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Build" Version="17.8.2055-preview-3" />
</ItemGroup>

<ItemGroup>
<Content Include=".vsextension\**\string-resources.json">
<CopyToOutputDirectory>PreserveNewest</CopyToOutputDirectory>
</Content>
</ItemGroup>
<!-- 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.41-preview-1" />
<PackageReference Include="Microsoft.VisualStudio.Extensibility.Build" Version="17.9.41-preview-1" />
</ItemGroup>
</Project>
Original file line number Diff line number Diff line change
Expand Up @@ -12,19 +12,20 @@ namespace CommandParentingSample;
[VisualStudioContribution]
public class CommandParentingSampleExtension : Extension
{
/// <inheritdoc/>
public override ExtensionConfiguration ExtensionConfiguration => new()
{
Metadata = new(
id: "CommandParentingSample.c30b7870-76bc-4ef6-93e8-15b9a54c9e2b",
version: this.ExtensionAssemblyVersion,
publisherName: "Microsoft",
displayName: "Command Parenting Sample Extension"),
};
/// <inheritdoc/>
public override ExtensionConfiguration ExtensionConfiguration => new()
{
Metadata = new(
id: "CommandParentingSample.c30b7870-76bc-4ef6-93e8-15b9a54c9e2b",
version: this.ExtensionAssemblyVersion,
publisherName: "Microsoft",
displayName: "Command Parenting Sample Extension",
description: "Sample extension demonstrating command parenting"),
};

/// <inheritdoc/>
protected override void InitializeServices(IServiceCollection serviceCollection)
{
base.InitializeServices(serviceCollection);
}
/// <inheritdoc/>
protected override void InitializeServices(IServiceCollection serviceCollection)
{
base.InitializeServices(serviceCollection);
}
}
Original file line number Diff line number Diff line change
@@ -1,16 +1,19 @@
namespace CommandParentingSample;
// Copyright (c) Microsoft. All rights reserved.
// Licensed under the MIT license. See LICENSE file in the project root for full license information.

namespace CommandParentingSample;

using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.Commands;

internal static class ExtensionCommandConfiguration
{
[VisualStudioContribution]
public static ToolbarConfiguration ToolBar => new("%CommandParentingSample.ToolBar.DisplayName%")
{
Children = new[]
{
ToolbarChild.Command<SampleCommand>(),
},
};
[VisualStudioContribution]
public static ToolbarConfiguration ToolBar => new("%CommandParentingSample.ToolBar.DisplayName%")
{
Children = new[]
{
ToolbarChild.Command<SampleCommand>(),
},
};
}
69 changes: 66 additions & 3 deletions New_Extensibility_Model/Samples/CommandParentingSample/README.md
Original file line number Diff line number Diff line change
@@ -1,10 +1,73 @@
---
title: Command Parenting Sample reference
date: 2022-10-14
date: 2023-10-17
---

## Command Parenting Sample

This extension is meant to act as a sample for how to author a command that can be parented to different aspects of the IDE. The command in this extension is parented to a new Toolbar created by the extension, the context menu when a project item is selected in the Solution Explorer, the context menu when a project is selected in the Solution Explorer, and the solution is selected in the Solution Explorer.
This extension is meant to act as a sample for how to author a command that can be parented to different aspects of the IDE. The command in this extension is parented to a new Toolbar created by the extension, the context menu when a project item is selected in the Solution Explorer, the context menu when a project is selected in the Solution Explorer, and the solution is selected in the Solution Explorer.

See also, [Add commands](https://learn.microsoft.com/visualstudio/extensibility/visualstudio.extensibility/command/command).
## Walkthrough: Command Parenting Sample

This extension is meant to act as a sample for how to author a command that can be parented to different aspects of the IDE. The command in this extension is parented to a new Toolbar created by the extension, the context menu when a project item is selected in the `Solution Explorer`, the context menu when a project is selected in the `Solution Explorer`, and the context menu when a solution is selected in the `Solution Explorer`.

### Command definition

The extension contains a code file that defines a command and its properties starting with the `VisualStudioContribution` class attribute which makes the command available to Visual Studio:

```csharp
[VisualStudioContribution]
internal class SampleCommand : Command
{
```

The `VisualStudioContribution` attribute registers the command using the class full type name `CommandParentingSample.SampleCommand` as its unique identifier.

The `CommandConfiguration` property defines information about the command that are available to Visual Studio even before the extension is loaded:

```csharp
public override CommandConfiguration CommandConfiguration => new("%CommandParentingSample.SampleCommand.DisplayName%")
{
Placements = new[]
{
// File in project context menu
CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id: 521, priority: 0),

// Project context menu
CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id: 518, priority: 0),

// Solution context menu
CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id: 537, priority: 0),
},
};
```

The command is placed in the in 3 different places in the IDE using the `CommandPlacement.VsctParent` method. The command will always be enabled and visible.

### Toolbar Definition

Different from commands, toolbars are configured as static properties and the `VisualStudioContribution` attribute is placed on the property itself instead of the owning class. The attribute registers the toolbar using the owning class full type name plus the property name, `CommandParentingSample.ExtensionCommandConfiguration.ToolBar`, as its unique identifier.

The `ToolbarConfiguration` property defines information about the toolbar that are available to Visual Studio even before the extension is loaded:

```csharp
[VisualStudioContribution]
public static ToolbarConfiguration ToolBar => new("%CommandParentingSample.ToolBar.DisplayName%")
{
Children = new[]
{
ToolbarChild.Command<SampleCommand>(),
},
};
```

By default, all toolbars registered this way are parented to the `Standard Toolbar Tray` in Visual Studio. The toolbar can be made visible by clicking the command under `View` -> `Toolbars` -> `Command Parenting Sample Toolbar`.

The `SampleCommand` from earlier is parented onto this toolbar using `ToolbarChild.Command<SampleCommand>()` in the toolbar's `Children`.

### Additional Readings

More information can be found at:

- [Add Visual Studio commands](https://learn.microsoft.com/visualstudio/extensibility/visualstudio.extensibility/command/command)
- [Menus and Toolbars overview](https://learn.microsoft.com/en-us/visualstudio/extensibility/visualstudio.extensibility/command/menus-and-toolbars?view=vs-2022)
Original file line number Diff line number Diff line change
Expand Up @@ -11,30 +11,25 @@ namespace CommandParentingSample;
[VisualStudioContribution]
internal class SampleCommand : Command
{
public SampleCommand(VisualStudioExtensibility extensibility)
: base(extensibility)
{
}
/// <inheritdoc />
public override CommandConfiguration CommandConfiguration => new("%CommandParentingSample.SampleCommand.DisplayName%")
{
Placements = new[]
{
// File in project context menu
CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id: 521, priority: 0),

/// <inheritdoc />
public override CommandConfiguration CommandConfiguration => new("%CommandParentingSample.SampleCommand.DisplayName%")
{
Placements = new[]
{
// File in project context menu
CommandPlacement.FromVsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), 521),
// Project context menu
CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id: 518, priority: 0),

// Project context menu
CommandPlacement.FromVsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), 518),
// Solution context menu
CommandPlacement.VsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), id: 537, priority: 0),
},
};

// Solution context menu
CommandPlacement.FromVsctParent(new Guid("{d309f791-903f-11d0-9efc-00a0c911004f}"), 537),
},
};

/// <inheritdoc />
public override Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
/// <inheritdoc />
public override Task ExecuteCommandAsync(IClientContext context, CancellationToken cancellationToken)
{
return Task.CompletedTask;
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"CommentRemover.CommentRemoverMenu.DisplayName": "Comments",
"CommentRemover.RemoveAllComments.DisplayName": "Remove All",
"CommentRemover.RemoveAllExceptTaskComments.DisplayName": "Remove All Except Tasks",
"CommentRemover.RemoveAllExceptXmlDocComments.DisplayName": "Remove All Except Xml Docs",
"CommentRemover.RemoveRegions.DisplayName": "Remove Regions",
"CommentRemover.RemoveTasks.DisplayName": "Remove Tasks",
"CommentRemover.RemoveXmlDocComments.DisplayName": "Remove Xml Docs"
}
130 changes: 130 additions & 0 deletions New_Extensibility_Model/Samples/CommentRemover/BaseCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,130 @@
namespace CommentRemover;

using EnvDTE;
using EnvDTE80;
using Microsoft;
using Microsoft.VisualStudio;
using Microsoft.VisualStudio.Editor;
using Microsoft.VisualStudio.Extensibility;
using Microsoft.VisualStudio.Extensibility.VSSdkCompatibility;
using Microsoft.VisualStudio.Shell;
using Microsoft.VisualStudio.Text;
using Microsoft.VisualStudio.Text.Editor;
using Microsoft.VisualStudio.Text.Tagging;
using Microsoft.VisualStudio.TextManager.Interop;
using Microsoft.VisualStudio.Threading;
using System.Diagnostics;
using System.Text.RegularExpressions;

internal abstract class CommentRemoverCommand : Microsoft.VisualStudio.Extensibility.Commands.Command
{
protected static readonly ActivationConstraint CommandEnabledWhen = ActivationConstraint.ClientContext(ClientContextKey.Shell.ActiveSelectionFileName, @"\.(cs|vb|fs)$");

private static readonly string[] TaskCaptions = { "TODO", "HACK", "UNDONE", "UNRESOLVEDMERGECONFLICT" };

public CommentRemoverCommand(
TraceSource traceSource,
AsyncServiceProviderInjection<DTE, DTE2> dte,
MefInjection<IBufferTagAggregatorFactoryService> bufferTagAggregatorFactoryService,
MefInjection<IVsEditorAdaptersFactoryService> editorAdaptersFactoryService,
AsyncServiceProviderInjection<SVsTextManager, IVsTextManager> textManager)
{
this.TraceSource = traceSource;
this.Dte = dte;
this.BufferTagAggregatorFactoryService = bufferTagAggregatorFactoryService;
this.EditorAdaptersFactoryService = editorAdaptersFactoryService;
this.TextManager = textManager;
}

protected AsyncServiceProviderInjection<DTE, DTE2> Dte { get; private set; }

protected MefInjection<IBufferTagAggregatorFactoryService> BufferTagAggregatorFactoryService { get; private set; }

protected MefInjection<IVsEditorAdaptersFactoryService> EditorAdaptersFactoryService { get; private set; }

protected AsyncServiceProviderInjection<SVsTextManager, IVsTextManager> TextManager { get; private set; }

protected TraceSource TraceSource { get; private set; }

protected static bool IsLineEmpty(ITextSnapshotLine line)
{
var text = line.GetText().Trim();

return string.IsNullOrWhiteSpace(text)
|| text == "<!--"
|| text == "-->"
|| text == "<%%>"
|| text == "<%"
|| text == "%>"
|| Regex.IsMatch(text, @"<!--(\s+)?-->");
}

protected static bool IsXmlDocComment(ITextSnapshotLine line)
{
var text = line.GetText().Trim();
Microsoft.VisualStudio.Utilities.IContentType contentType = line.Snapshot.TextBuffer.ContentType;

if (contentType.IsOfType("CSharp") && text.StartsWith("///", StringComparison.Ordinal))
{
return true;
}

if (contentType.IsOfType("FSharp") && text.StartsWith("///", StringComparison.Ordinal))
{
return true;
}

if (contentType.IsOfType("Basic") && text.StartsWith("'''", StringComparison.Ordinal))
{
return true;
}

return false;
}

protected static bool ContainsTaskComment(ITextSnapshotLine line)
{
string text = line.GetText().ToUpperInvariant();

foreach (var task in TaskCaptions)
{
if (text.Contains(task + ":"))
{
return true;
}
}

return false;
}

protected async Task<IEnumerable<IMappingSpan>> GetClassificationSpansAsync(IWpfTextView view, string classificationName)
{
if (view is null)
{
return Enumerable.Empty<IMappingSpan>();
}

IBufferTagAggregatorFactoryService bufferTagAggregatorFactoryService = await this.BufferTagAggregatorFactoryService.GetServiceAsync();
ITagAggregator<IClassificationTag> classifier = bufferTagAggregatorFactoryService.CreateTagAggregator<IClassificationTag>(view.TextBuffer);
var snapshot = new SnapshotSpan(view.TextBuffer.CurrentSnapshot, 0, view.TextBuffer.CurrentSnapshot.Length);

return from s in classifier.GetTags(snapshot).Reverse()
where s.Tag.ClassificationType.Classification.IndexOf(classificationName, StringComparison.OrdinalIgnoreCase) > -1
select s.Span;
}

protected async Task<IWpfTextView> GetCurrentTextViewAsync()
{
IVsEditorAdaptersFactoryService editorAdapter = await this.EditorAdaptersFactoryService.GetServiceAsync();
var view = editorAdapter.GetWpfTextView(await this.GetCurrentNativeTextViewAsync());
Assumes.Present(view);
return view;
}

protected async Task<IVsTextView> GetCurrentNativeTextViewAsync()
{
var textManager = await this.TextManager.GetServiceAsync();
ErrorHandler.ThrowOnFailure(textManager.GetActiveView(1, null, out IVsTextView activeView));
return activeView;
}
}
Loading
Loading