Sync Namespaces at folder level
- Dominant language
- C#
- Stars
- 20.7k
- Forks
- 4.3k
- PR merge metrics
- PR metrics pending
Description
#74777
#61479
[comment](https://github.com/dotnet/roslyn/issues/57847#issuecomment-1057529705)
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
1. Add to commands.vsct
`
`
2. Change the VisualStudioCommandHandlerHelpers to look for C# code files
Look for single in OnSyncNamespacesForSelectedProjectStatus
Look for multiple in OnSyncNamespacesForSelectedProject
More on this later
2. 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 SyncNamespacesAsync(
ImmutableArray projects, ImmutableArray? codeFilePaths, IProgress 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.
Contributor guide
Research direction
Start by reviewing the commands.vsct placement, VisualStudioCommandHandlerHelpers, SyncNamespacesCommandHandler, VisualStudioFolderWalker, and ISyncNamespacesService entry points described in the issue. Done means folder-level context-menu synchronization handles the selected folder or folders, supports the stated directory scope, and preserves shared-folder and non-SDK .NET Framework behavior.
Written by the indexing model from the issue text.
Assessment
- Tech stack
- csharp
- Domain
- tooling
- Issue type
- Feature
- Difficulty
- 5/5
- Estimated time
- Over a week
- Activity status
- Stale
- Clarity
- Needs clarification
- Newbie friendliness
- 25/100