Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Enhance unused reference feature to support undo/redo #6795

Closed
JoeRobich opened this issue Dec 16, 2020 · 20 comments
Closed

Enhance unused reference feature to support undo/redo #6795

JoeRobich opened this issue Dec 16, 2020 · 20 comments
Assignees
Labels
Feature-Language-Service Populating the Roslyn workspace with references, source files, analyzers, etc Triage-Approved Reviewed and prioritized
Milestone

Comments

@JoeRobich
Copy link
Member

JoeRobich commented Dec 16, 2020

We would like the API implemented in #6692 enhanced with the ability to re-add a reference that has been removed.

One possibility is a new UpdateAction.Add
In particular the call to IProjectSystemReferenceCleanupService.GetProjectReferenceAsync would need to be enhanced so that we capture enough information about each reference that it could be recreated from the ProjectSystemReferenceInfo model. This information may need to include the position in the project file where the reference would be inserted. Next the IProjectSystemReferenceCleanupService.TryUpdateReferenceAsync would need to be updated to support an ProjectSystemUpdateAction.Add scenario where, given this enhacned ReferenceInfo model, a reference is added to the project file.

Another possibility is that we share the same undo context
The IProjectSystemReferenceCleanupService.TryUpdateReferenceAsync could return a OleUndoUnit or we could pass in a UndoTransaction of sorts.

Tracked in DevOps 1348735

@drewnoakes drewnoakes added the Triage-Approved Reviewed and prioritized label Dec 18, 2020
@drewnoakes drewnoakes added this to the 16.9 milestone Dec 18, 2020
@jjmew jjmew modified the milestones: 16.9, 16.10, Backlog Feb 9, 2021
@ocallesp
Copy link
Contributor

@JoeRobich
In this scenario, the Undo/Redo action will come from Roslyn ?

  • If a user does ctrl+z, Roslyn will detect it and then Roslyn will call ProjectSystem to execute the undo/redo in the IProjectSystemReferenceCleanupService ?

The undo/redo should keep the history of all actions or only the last action ?

@JoeRobich
Copy link
Member Author

Roslyn would be responsible for adding the undo/redo action. We need to work out the best way to support undo/redo.

  • Should Roslyn capture the project file text prior to updating references so that it could be restored in an undo operation?
  • Should the project system return child undo operations for each call to UpdateRefrences which Roslyn could batch together into a transaction?
  • or some other method of supporting undo/redo in this scenario?

@ocallesp
Copy link
Contributor

I think the interface should add undo/redo methods and call dotnet ProjectSystem to do IProjectSystemReferenceCleanupService.Undo() or IProjectSystemReferenceCleanupService.Redo()

@JoeRobich
Copy link
Member Author

@ocallesp Can you describe how this would work end-to-end? Would you be storing state in the CleanupService or would we be passing some state when calling Undo/Redo?

@ocallesp
Copy link
Contributor

ProjectSystem can store the state in the CleanupService

@mikadumont
Copy link

mikadumont commented Mar 23, 2021

UX Proposal:

Typing Ctrl+Z/Ctrl+Y and selecting undo/redo:
image

Will either undo/redo remove unused references. And the Remove Unused References commit should appear in the undo/redo history stack:
image

@vatsalyaagrawal
Copy link

vatsalyaagrawal commented Mar 23, 2021

@jjmew, @ocallesp please see the UX proposal above.

@jjmew
Copy link
Contributor

jjmew commented Mar 23, 2021

@vatsalyaagrawal Thanks for sharing. I assume your team is hooking up to the undo/redo stack and you will call us when needed. Is that correct? cc: @ocallesp

@mikadumont
Copy link

UX update: I met with UX and they mentioned that we dont need a dialog - just having Remove Unused References show up in the undo/redo history stack is good enough.

@JoeRobich
Copy link
Member Author

I assume your team is hooking up to the undo/redo stack and you will call us when needed. Is that correct?

@jjmew Yes, Roslyn will manage the undo/redo stack and we can call into the cleanup service as @ocallesp proposes.

@jjmew
Copy link
Contributor

jjmew commented Mar 24, 2021

@mikadumont what is the expectation on this scenario?

  1. User removes un-used references A,B,C
  2. They modify a file
  3. They copy some text into a file
  4. User removes un-used references X,Y,Z
  5. User does "Ctrl Z"

What is the result?
What happens after another "Ctrl Z"

@JoeRobich
Copy link
Member Author

@jjmew Ctrl-Z should only undo the last operation. In this case it should restore the X, Y, Z references.

@jjmew
Copy link
Contributor

jjmew commented Mar 24, 2021

@jodavis what about the 4th "Ctrl Z" . Should it re-add references A,B,C?

@JoeRobich
Copy link
Member Author

@jjmew That is correct. I feel like we will need to keep some state information with each undo action that is pushed on the stack, so that we can properly track which changes need to be undone.

@jjmew
Copy link
Contributor

jjmew commented Mar 24, 2021

@jodavis the expectation then is that the productivity team will request the project system to undo the last action on the "Remove Unused References" stack. We will add the references that we previously removed. Is there any error handling that you expect? for example if we were not able to re-add the references.

@JoeRobich
Copy link
Member Author

@jjmew It would be coarse-grained but we could have the proposed Undo() and Redo() methods return bool indicating success. We would then inform the user on our end.

@ocallesp
Copy link
Contributor

The itemSpecification returned by GetProjectReferencesAsync() are different from the TryUpdateReferenceAsync()
i.e "..\ClassLibrary1\ClassLibrary1.csproj" and "ClassLibrary1"

Roslyn needs to fix the itemSpecification to use the one from GetProjectReferencesAsync()
and add the missing methods Undo(), and Redo() to IProjectSystemReferenceCleanupService

This PR already implements the undo/redo #7065

@JoeRobich
Copy link
Member Author

JoeRobich commented Apr 6, 2021

I met with Osvaldo and to discuss the implementation and we have agreed on adding the following interface changes.

interface IProjectSystemUpdateReferenceOperation
{
    Task<bool> ApplyAsync();
    Task<bool> RevertAsync();
}
 
interface IProjectSystemReferenceCleanupService2
{
    Task<IProjectSystemUpdateReferenceOperation> GetUpdateReferenceOperationAsync(
        string projectPath,
        ProjectSystemReferenceUpdate referenceUpdate,
        CancellationToken canellationToken);
}

Roslyn will request update actions for each of the changes from the Project System. We will then apply the actions and push an Undo action onto the UndoManager which will contain all the actions for the Remove Reference invocation.

@jjmew jjmew modified the milestones: Backlog, 17.0 Jun 28, 2021
@MiYanni MiYanni added the Feature-Language-Service Populating the Roslyn workspace with references, source files, analyzers, etc label Aug 24, 2021
@MiYanni MiYanni modified the milestones: 17.0, 17.1 Aug 24, 2021
@drewnoakes drewnoakes modified the milestones: 17.1, 17.3 Apr 7, 2022
@ocallesp
Copy link
Contributor

ocallesp commented Nov 8, 2022

Implementations of IProjectSystemUpdateReferenceOperation

@drewnoakes
Copy link
Member

@ocallesp do you recall which version this was fixed in?

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
Feature-Language-Service Populating the Roslyn workspace with references, source files, analyzers, etc Triage-Approved Reviewed and prioritized
Projects
None yet
Development

No branches or pull requests

7 participants