如何在自定义CodeFixProvider应用代码修复后移动光标至summary标签内?
实现CodeFix后将光标定位到空summary标签内部
我之前开发自定义CodeFixProvider时也遇到过一模一样的需求,用DocumentNavigationOperation实现修复后的光标定位其实非常直观,下面给你一步步拆解具体的实现方法:
核心思路
CodeFix的本质是生成一系列IOperation执行代码更改和后续操作,我们需要先完成XML注释的添加,再追加一个导航操作,让IDE自动把光标移动到<summary></summary>的空内容区域。
具体实现步骤
1. 确认依赖
首先确保你的项目已经引用了Microsoft.CodeAnalysis.Features NuGet包,DocumentNavigationOperation类就包含在这个包里。
2. 在RegisterCodeFixesAsync中添加导航逻辑
在你的CodeFixProvider的RegisterCodeFixesAsync方法里,完成代码更改后,需要:
- 定位到新增的
<summary>标签的内容位置 - 创建导航操作并和代码更改操作合并
这里给你一段完整的示例代码:
public override async Task RegisterCodeFixesAsync(CodeFixContext context) { var cancellationToken = context.CancellationToken; var root = await context.Document.GetSyntaxRootAsync(cancellationToken).ConfigureAwait(false); var diagnostic = context.Diagnostics.First(); var targetNode = root.FindNode(diagnostic.Location.SourceSpan); // 第一步:生成带有空summary的XML注释(替换成你已有的注释生成逻辑即可) var xmlComment = SyntaxFactory.DocumentationCommentTrivia( SyntaxKind.SingleLineDocumentationCommentTrivia, SyntaxFactory.List<XmlNodeSyntax>(new[] { SyntaxFactory.XmlElement( SyntaxFactory.XmlElementStartTag(SyntaxFactory.XmlName(SyntaxFactory.Identifier("summary"))), SyntaxFactory.XmlElementEndTag(SyntaxFactory.XmlName(SyntaxFactory.Identifier("summary"))) ) }) ); var newRoot = root.InsertNodesBefore(targetNode, new[] { xmlComment }); // 第二步:找到新增的summary标签,确定光标位置 var summaryElement = newRoot.DescendantNodes() .OfType<XmlElementSyntax>() .FirstOrDefault(e => e.StartTag.Name.Identifier.Text == "summary"); if (summaryElement == null) { // 处理找不到summary标签的异常情况 return; } // 光标定位到summary结束标签的起始位置,也就是<summary></summary>的中间空白处 var cursorPosition = summaryElement.EndTag.GetLocation().SourceSpan.Start; // 第三步:创建导航操作和代码更改操作,并合并执行顺序 var codeChangeOp = DocumentOperation.EditDocument(context.Document.Id, newRoot, cancellationToken); var navigationOp = DocumentNavigationOperation.Create(context.Document.Id, cursorPosition); // 组合操作:先完成代码更改,再执行光标移动 var combinedOp = codeChangeOp.Compose(navigationOp); // 注册最终的修复操作 context.RegisterCodeFix( CodeAction.Create( title: "添加XML文档注释", createOperation: _ => Task.FromResult(combinedOp), equivalenceKey: nameof(YourCodeFixProviderName)), diagnostic); }
关键细节说明
- 光标位置的确定:我们取
summaryElement.EndTag的起始位置(也就是</summary>中<的位置),这样光标会自动落在<summary>和</summary>之间的空白区域,完全符合需求。 - 操作合并:用
Compose方法把代码更改和导航操作组合,确保代码修改完成后再执行光标移动,避免因代码变更导致的位置偏移。 - 优化建议:如果你的XML注释是通过
SyntaxFactory直接构建的,可以在构建时直接记录summary标签的位置,不用事后遍历查找,能提升一点执行效率。
内容的提问来源于stack exchange,提问作者fss
相关产品推荐
相关产品推荐

