I am currently experimenting with Roslyn and Code Actions, more specific Code Refactorings.
It feels kind of easy, but I have a difficulty I cannot solve.
Code actions are executed once against a dummy workspace as a "preview" option, so that you can see the actual changes before you click the action and execute it against the real workspace.
Now I am dealing with some things Roslyn can't really do (yet), so I am doing some changes via EnvDTE
. I know, it's bad, but I couldn't find another way.
So the issue here is:
When I hover over my code action, the code gets executed as preview, and it should NOT do the EnvDTE
changes. Those should only be done when the real execute happens.
I have created a gist with a small example of my code. It doesn't really makes sense, but should show what I want to achieve. Do some modifications via roslyn, then do something via EnvDTE
, like changing Cursor position. But of course only on the real execution.
The relevant part for those who can't click the gist:
public sealed override async Task ComputeRefactoringsAsync(CodeRefactoringContext context)
{
var root = await context.Document.GetSyntaxRootAsync(context.CancellationToken).ConfigureAwait(continueOnCapturedContext: false);
var node = root.FindNode(context.Span);
var dec = node as MethodDeclarationSyntax;
if (dec == null)
return;
context.RegisterRefactoring(CodeAction.Create("MyAction", c => DoMyAction(context.Document, dec, c)));
}
private static async Task<Solution> DoMyAction(Document document, MethodDeclarationSyntax method, CancellationToken cancellationToken)
{
var syntaxTree = await document.GetSyntaxTreeAsync(cancellationToken);
var root = await syntaxTree.GetRootAsync(cancellationToken);
// some - for the question irrelevant - roslyn changes, like:
document = document.WithSyntaxRoot(root.ReplaceNode(method, method.WithIdentifier(SyntaxFactory.ParseToken(method.Identifier.Text + "Suffix"))));
// now the DTE magic
var preview = false; // <--- TODO: How to check if I am in preview here?
if (!preview)
{
var requestedItem = DTE.Solution.FindProjectItem(document.FilePath);
var window = requestedItem.Open(Constants.vsViewKindCode);
window.Activate();
var position = method.Identifier.GetLocation().GetLineSpan().EndLinePosition;
var textSelection = (TextSelection) window.Document.Selection;
textSelection.MoveTo(position.Line, position.Character);
}
return document.Project.Solution;
}
See Question&Answers more detail:
os 与恶龙缠斗过久,自身亦成为恶龙;凝视深渊过久,深渊将回以凝视…