dotnet / dotnet/roslyn

Sync Namespaces at folder level

Open
#79,185 1 comment 0 reactions 0 assignees View on GitHub
Area-IDE help wanted
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

Open the contributing 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

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.