Repository metrics
- Stars
- (20,414 stars)
- PR merge metrics
- (Avg merge 6d 17h) (256 merged PRs in 30d)
Description
#74777 #61479 comment
Currently the context menu can only be used for solution or single project.
TBD
Is sync just for the selected folder / folders or should there be multiple options Directory Directory and descendants Directory and ascendants
Solution - for single directory
- Add to commands.vsct
<CommandPlacement guid="guidRoslynGrpId" id="cmdidSyncNamespaces" priority="0xF200"> <Parent guid="guidSHLMainMenu" id="IDG_VS_CTXT_FOLDER_ADD" /> </CommandPlacement>
-
Change the VisualStudioCommandHandlerHelpers to look for C# code files Look for single in OnSyncNamespacesForSelectedProjectStatus Look for multiple in OnSyncNamespacesForSelectedProject More on this later
-
SyncNamespacesCommandHandler changes In adition to the new folder functionality it addresses shared folders that do not work and allows working in a .Net Framework non sdk style project. The CollectFolderCSharpFiles enumeration allows for DirectoryAndDescendants ....
private void OnSyncNamespacesForSelectedProjectStatus(object sender, EventArgs e)
{
var command = (OleMenuCommand)sender;
var visible = false;
if (VisualStudioCommandHandlerHelpers.TryGetSelectedProjectHierarchyWithSelectionDetails(_serviceProvider, CollectFolderCSharpFiles.Directory, out var projectHierarchy, out var projectOrFolderWithCSharpFiles))
{
var isShared = projectHierarchy.TryGetProjectFilePath()?.EndsWith(".shproj") == true;
if (!isShared)
{
visible = projectOrFolderWithCSharpFiles && projectHierarchy.IsCapabilityMatch("CSharp");
}
}
The code files are then passed to the service as a new argument.
private void OnSyncNamespacesForSelectedProject(object sender, EventArgs args)
{
if (VisualStudioCommandHandlerHelpers.TryGetSelectedProjectHierarchyWithCSharpFilePaths(_serviceProvider, CollectFolderCSharpFiles.Directory, out var projectHierarchy, out var cSharpFilePaths))
{
var projects = GetProjectsForHierarchy(projectHierarchy);
SyncNamespaces(projects, cSharpFilePaths);
}
internal interface ISyncNamespacesService : ILanguageService
{
Task<Solution> SyncNamespacesAsync(
ImmutableArray<Project> projects, ImmutableArray<string>? codeFilePaths, IProgress<CodeAnalysisProgress> progressTracker, CancellationToken cancellationToken);
}
The AbstractSyncNamespacesService will use GetAnalysisResultAsync for the SyntaxTree of each code file if code files are passed (using FileUtilities.TryNormalizeAbsolutePath ) otherwise will continue to use GetAnalyzerDiagnosticsAsync.
How I have implemented 2.
Created a VisualStudioFolderWalker helper that uses IVsHierarchy and __VSHPROPID.VSHPROPID_FirstChild, __VSHPROPID.VSHPROPID_NextSibling __VSHPROPID.VSHPROPID_TypeGuid
to walk and has predicates for descending directories and completion.
The VisualStudioCommandHandlerHelpers determines when to descend based on the CollectFolderCSharpFiles enumeration parameter and collects the C# code files from the walker predicate ( returning early when presence of a code file is all that is required). If multi select then IVsMultiItemSelect.GetSelectedItems is used for walking each folder.