VSIX 扩展:如何在文本替换时进行原子撤消

VSIX Extension: how to make atomic undo upon text replacement

我正在编写一个 Visual Studio 扩展模块 (VSIX),它允许用户 select 文本,并在菜单命令后,selected 文本被替换为新的文本:

var document = ProjectHelpers.DTE.ActiveDocument;
var selection = (TextSelection)document.Selection;
var text = selection.Text;
string newText = doSomethingWith(text);
selection.Text = newText; 

现在的问题是,当我想撤消操作时(例如通过Ctrl-Z),一次只删除一行新文本,最后恢复原始文本(需要使用Ctrl- Z 很多次)。

如何实现原子撤消,其中只有一个 Ctrl-Z 命令可以撤消整个过程?

以防万一,我正在为 VS2017 写作。

解决方案是创建一个撤消上下文,可以在其中收集所有更改,这应该作为单个事务出现:

try
{
   ProjectHelpers.DTE.UndoContext.Open("Description of operation");
   selection.Text = newText;
}
finally
{
   ProjectHelpers.DTE.UndoContext.Close();
}