Roslyn: Renaming a class in the VS editor should also rename the containing file

Created on 22 Sep 2015  路  24Comments  路  Source: dotnet/roslyn

If I rename a file in the solution explorer it will, under certain mysterious conditions, offer to rename the class inside. Since developers generally live in the editor, it would be nice if the opposite was also true - renaming a class in the editor should rename the containing file. Also, instead of the annoying confirmation dialog used by the solution explorer, an extra checkbox could be added to the rename panel.

Area-IDE Feature Request Resolution-Fixed

Most helpful comment

Currently looking into an implementation for this. Look for design notes here as follow up

All 24 comments

Yes, we definitely want to do this soon.

I spent some time trying to fix this today...

filename

...but the lack of a RenameDocument API (#6261) makes it all but but unusable. Also related to #16253.

...but the lack of a RenameDocument API (#6261) makes it all but but unusable.

Can you clarify that more? The linked bug is about the problems when the doucment is a linked document. But certainly, we could at least make this work fine for non-linked documents, right?

@CyrusNajmabadi I don't know about linked documents, but did you look at #16253? It's similar since it also has to work around the lack of a rename API with a remove+add, and @Pilchie determined the root cause to be #6261. I never noticed the side effects in that code fix, but they hit me immediately when I hacked together a proof-of-concept for the inline rename feature.

Imagine you're typing away - you press F2 - type your new class name - Enter - the document flickers, your cursor jumps to the top of the file for some reason, all you exanded regions collapse, and now Ctrl+Z is broken! That's a horrible experience.

There's an existing API, Solution.WithDocumentName, that looked promising, but the VS workspace implementation doesn't seem to support it (it throws if document properties are changed).

That's a horrible experience.

Gotcha! Yup, i totally agree. That should be addressed.

There's an existing API, Solution.WithDocumentName, that looked promising, but the VS workspace implementation doesn't seem to support it (it throws if document properties are changed).

Want to fix that? :)

--

Note: it's probably best to just change RenameDocumentOperation: https://github.com/dotnet/roslyn/blob/master/src/Workspaces/Core/Portable/CodeActions/Operations/RenameDocumentOperation.cs

So instead of Remove/Add, it actually calls a supported APi for this which does the right thing in the VisualStudioWorkspace. If you try this and run into problems, @jasonmalinowski can probably walk you through the right calls in teh VSWorkspace to do the rename.

My gut is RenameDocumentOperation might have been added prior to @mattwar doing some of the rename stuff (which might have added that WithDocumentName). This might just be the case of the newer workspaces API being added but we didn't get rid of the old code yet. IIRC the change was "foundational" and we wanted to do more here.

But yes, right fix would be to fix VisualStudioWorkspace. TBH the "RenameDocumentOperation" is still wrong for source control systems that track file renames explicitly (think TFVC.)

I think I found the API that needs to be called - IVsRunningDocumentTable.RenameDocument - but I haven't managed to try it yet. The workspace layer is crashing because none of the event processing likes the DocumentInfoChanged change kind.

So... this seems like it could be quite a rabbit hole to fall down. Before I spend much time on this, do you think it's actually reasonable for a community submission fix this? Assume I know nothing about workspaces and the VS automation APIs...

If I follow the documentation correct (see above linked issue) the functionality is already available for non dotnet Core projects. So there must be some apis available to do this right?

I also see it has changed to priority 2. Does this mean that it has less priority? That's to bad because I would use this a lot!

I would love to have this available for my .NET Core applications!

Disabled resharper and was happy with what VS 2019 provided but then hit this issue. Fix coming anytime soon?

Currently looking into an implementation for this. Look for design notes here as follow up

Design Proposal

This is an attempt to enumerate them and express immediate plans as a proposal. Each should be able to be done in an isolated way but will as a whole make the rename experience better.

Inline Rename Dialog

Invoke when user does an inline rename (f2 or ctrl+r, ctrl+r). A dialog shows in the top right with some rename options and the editing stays inline while the user renames. Submission commits this action to the undo stack, such that undo will undo all changes as part of the rename. To support this scenario, we will add a checkbox to the dialog that will allow users to rename the file as part of the action.

Proposed UI

image of inline rename with new checkbox

  • Note, string is not final and open for suggestions

The checkbox will default to checked when enabled, and respect the last used setting for the user. For example, if a user unchecks the box and closes the rename dialog, the next time it is opened it will still be unchecked.

The checkbox will also only be enabled in the following scenarios, where file matching is considered without the extension:

  1. The name of the type already matches the file, regardless of the number of type definitions in the file
  2. The file name is {Partial Parent Name}.{Type Name}, and {Type Name} matches the current selected type
  3. The file name is {Type Name}`Arity, and {Type Name} matches the current selected type.
  4. The type definition is the only definition in the file

For UI hints to these, we have a few options:

  1. Hide the checkbox and string so it's not presented as an option
  2. Disable the checkbox and provide a small hint text to indicate that this action isn't allowed for the current rename

I'm in favor of option 2 to reduce user confusion about when UI is available. Dynamic UI can be great for increased complexity, but the single checkbox addition shouldn't be too noisy.

Post Change Renaming

All of these fixes should only apply in the same scenarios that the inline rename would allow a file rename as well. For these, I think we should follow convention of assuming, based on some setting, that renaming the file is also desirable. To help streamline the experience, we should add two operations to the undo stack. The first undo that a user performs will revert the file name, and the second undo will revert the symbol rename.

We should also respect this setting, such that if it is disabled we do not automate type/file name syncing. Likely the wording should be updated to better reflect the new behavior.

Projects and Solutions settings in Visual Studio with "Promp for symbol renaming when renaming files" highlighted

Name Style

If the naming style doesn't match what's defined in .editorconfig, we provide a code fix to rename the code. This gets difficult because this could be part of code cleanup, and therefor be many operations deep. If we can understand the context of when this code action is applied, we should use that information and provide the undo experience as described above. If this is part of a larger scope cleanup (document, project, solution) we will not automatically rename the file.

Post Rename Fix

I'm not sure of the correct terminology, but this happens when there's a dotted box around a symbol name.

Code fix for rename symbol after typing a new name

I believe in this case we can include the file rename as part of this action, with all of the assumptions noted in the Post Change Renaming section

File Rename

When a file is renamed in the solution explorer, there are times when we prompt the user to also rename the symbol. We should consolidate this to assume the rename is intended as noted above, but adjust the undo stack. The first undo the user performs should undo the symbol rename, and the second undo should undo the file rename.

Small nit:

The file name is {Partial Parent Name}.{Type Name}, and {Type Name} matches the current selected type

Also consider TypeName`Arity.ext :)

When a file is renamed in the solution explorer, there are times when we prompt the user to also rename the symbol. We should consolidate this to assume the rename is intended as noted above, but adjust the undo stack. The first undo should undo the symbol rename, and the second undo should undo the file rename.

I'd personally pull this out. It may be what i'm used to, but i really like getting the notification. I like it because a lot of the time i do not want to rename the class, and so having to go through the cost of the rename is unpleasant. Note: this is mitigated if the rename happens in a cancellable manner.

However, while obviously very related, i think it would be sensible to separate out these two. Thanks!

I want to keep the discussion tied together, at the very least, so we can be better with keeping the experience similar where possible. I tried to call out that the work flows can be done in separate passes at the beginning. Hopefully that helps facilitate a good discussion for overall experience while not inhibiting progress on the inline rename dialog.

Maybe with your preference, the prompt checkbox would be better to allow you to be prompted before the rename. If that setting is unchecked, we go through with the more streamlined experience that requires more hassle to separate the file and type name?

Maybe with your preference, the prompt checkbox would be better to allow you to be prompted before the rename. If that setting is unchecked, we go through with the more streamlined experience that requires more hassle to separate the file and type name?

Sure. If there's a checkbox, and it's only affected by me turning it off/on, then i think that would be fine. I'd even be fine with you changing the default to the more streamlined form. I can then reenable the option myself.

Thanks!

First Pass Implementation

From design meeting, we will hold off on any large behavior changes. The first pass will include the checkbox in the inline rename with the following changes:

  1. The checkbox will only show when renaming a type
  2. When disabled, the text beside the checkbox will also describe that the feature is not available
  3. Will be disabled for partial types
  4. Default state of the checkbox will use the Prompt for symbol renaming when renaming files setting.

Everything else will be as noted above in the Inline Rename Dialog. Changes included in Post Change Renaming will be considered at a later date.

Changes included in Post Change Renaming will be considered at a later date.

I'm really really looking forward to this part of the feature as shown in your screenshot "Rename file to One2.cs"

The initial implementation is done. It only exists for inline rename for now, but we have an eye on other implementations. For now, I'm going to close this issue. If we have more feedback on the current implementation it should be a new issue

Really been wanting for this feature for years!

Just saw this in Visual Studio 16.3 preview 1 - thank you, it works great!

image

I'm on 16.3.1 final and I cannot see this option (IN Either a .netcoreapp3.0 or Netstandard 2.0 project) ...

image

What gives ?

I think @graemechristie is correct - I only see this option in a full framework project (VS 2019 16.4.0 Preview 1) :-(

Tracking the rename file code fix not being offered with #37469 . This issue was used to track that inline rename also allowed file rename, and was added as a feature. Use #37469 to track the issue with the code fix

Was this page helpful?
0 / 5 - 0 ratings