Namespace Sync — Visual Studio extensionSets the
Built for Unity projects, but nothing about it is Unity-specific. InstallFrom the Visual Studio Marketplace, or build it yourself:
The VSIX lands in Press F5 to debug — VS opens an experimental instance ( How the namespace is worked outEach step runs in order; the first one that produces an answer wins.
Option 2 — the
|
| Setting | Default | Meaning |
|---|---|---|
| Sync on file create | true |
Runs when a .cs file is added to the project |
| Sync on rename / move | true |
Only when the file changes folder, not on a plain rename |
| Sync files created outside VS | true |
Watches the disk: git checkout/pull, Unity Editor, a copy from Explorer |
| Outside VS: only files without a namespace | true |
See below |
| Excluded paths | obj;bin;Library;Temp;Packages;PackageCache;node_modules |
|
| Prefer sibling files | true |
Step 1 above |
| Anchor file name | .nsroot |
|
Use Unity .asmdef |
true |
|
| Use asmdef name when rootNamespace is missing | false |
|
| Root folder names | Scripts |
|
| Namespace prefix | (empty) | Always prepended |
| Ignored folder segments | (empty) | For example Runtime;Scripts |
| Namespace style | Block |
Block / FileScoped / Auto (follows the sibling files) |
| Indent with tabs | false |
Unity: Unity only supports C# 9, which has no file-scoped namespaces. Leave this on Block.
Manual commands
- Right-click in the code window → Sync Namespace
- Right-click a file / folder / project in Solution Explorer → Sync Namespaces (recursive)
Both icons come from the built-in VS image catalog (KnownMonikers.Namespace and KnownMonikers.Sync),
so they follow the light/dark theme and the current DPI.
Output goes to View → Output → Namespace Sync.
Files that appear from outside Visual Studio
VS only raises events for things done inside VS (Add → New Item, drag and drop). Files written by
git checkout, git pull, the Unity Editor or Explorer never reach it. So the extension also watches the
solution directory itself.
- Events are batched for ~1.2 seconds and then processed in one pass — a checkout producing thousands of files still means one pass.
Library,Temp,obj,bin,.git,node_modules… and every folder in Excluded paths are not watched at all. This matters for Unity:Library/churns constantly, and watching it overflows the operating system's event buffer.- More than 2000 files at once and the whole batch is skipped with a log line — a safety limit, so a whole tree is never rewritten by accident.
Why it only touches files without a namespace by default
Another branch usually already carries namespaces that are correct for it. Rewriting all of them means a hundred modified files and a dirty working tree every time you switch branches. So by default the extension only sets a namespace on files that declare none — which is exactly the common case: a Unity script created without a namespace, committed, then pulled by someone else.
To force the folder-derived namespace onto every file that appears from outside, turn off Outside VS: only files without a namespace. Worth thinking about first — it rewrites files in bulk.
Actions inside VS (create / move a file) are not subject to this: they change the namespace even when the file already has one.
What happens to the file
- File already has a
namespace→ only the name changes; block vs file-scoped and everything else stays. - File has no
namespace→ inserted after the lastusing(or after the header comment), with the rest of the file wrapped in a block and indented one level. - File with more than one
namespace→ skipped, to be safe. - File declaring no type at all → skipped.
- The word
namespaceinside a comment or string literal is never mistaken for a declaration. - A file open in the editor is edited through its buffer (so undo works); otherwise it is written to disk, preserving the encoding/BOM and the line endings (CRLF or LF).
- Invalid folder names are cleaned up:
UI Widgets/3D-View→UI_Widgets._3D_View. *.designer.cs,*.g.csandAssemblyInfo.csare skipped.
Limits
- Visual Studio has to be running. Files that appear while VS is closed are seen by nobody, and reopening the solution does not scan retroactively — run Sync Namespaces on the project if you need it.
- Only the solution directory is watched. A project outside that tree is not covered.
- Top-level folders created after the solution opened are not watched until the next time it opens.
- For Unity, the cleanest option is still to edit the script template
(
Editor/Data/Resources/ScriptTemplates/81-C# Script-NewBehaviourScript.cs.txt) so new scripts are born with a namespace. This extension covers everything else.
Source layout
NamespaceSync/
Core/ pure logic, no VS SDK dependency (testable on its own)
IdentifierUtil.cs turns folder names into C# identifiers
CSharpSourceMask.cs marks real code vs comments/strings
NamespaceRewriter.cs reads / replaces / inserts the namespace
NamespaceResolver.cs works out the namespace from the path (the 5 steps above)
NamespaceSettings.cs settings interface
Integration/
DocumentTracker.cs IVsTrackProjectDocumentsEvents2 — files added/renamed inside VS
ExternalFileWatcher.cs FileSystemWatcher — files created outside VS (git, Unity, Explorer)
NamespaceSyncService.cs resolver + rewriter + writer
DocumentWriter.cs writes to the editor buffer or to disk
Logger.cs Output window pane
Commands/ manual commands
Options/ the Tools → Options page
Resources/ Icon.png 90x90 + PreviewImage.png 200x200 (shown in Manage Extensions)
NamespaceSyncPackage.cs AsyncPackage, autoloaded when a solution opens
License
MIT — see LICENSE.txt.