c# - 在保留插入符号的同时替换文档中的文本

标签 c# mef document visual-studio-extensions

我正在开发一个扩展,它使用外部程序在 Visual Studio 中格式化代码。

如果我使用 ITextEdit.Replace(...) 替换文件的内容,插入符号将放在文档的末尾,这是错误的。

我想做的是在替换文件内容之前在文本缓冲区中保存当前插入符位置的快照,然后将插入符位置设置为它之前在替换内容之前的文本缓冲区。

但是,ITextEdit.Apply() 正在生成一个新快照,导致 _textView.Caret.MoveTo(point) 抛出异常:

System.ArgumentException: The supplied SnapshotPoint is on an incorrect snapshot.
Parameter name: bufferPosition
at Microsoft.VisualStudio.Text.Editor.Implementation.CaretElement.InternalMoveTo(VirtualSnapshotPoint bufferPosition, PositionAffinity caretAffinity, Boolean captureHorizontalPosition, Boolean captureVerticalPosition, Boolean raiseEvent)
at Microsoft.VisualStudio.Text.Editor.Implementation.CaretElement.MoveTo(SnapshotPoint bufferPosition)

我也试过创建一个新的快照点而不是使用 _textView.Caret.Position.BufferPosition,像这样:

var point = new SnapshotPoint(_textView.TextSnapshot, 0);

抛出相同的“提供的 SnapshotPoint 位于不正确的快照上。”异常。

public class MyCommand
{
    private readonly IWpfTextView _textView;
    private readonly MyFormatter _formatter;
    private readonly ITextDocument _document;

    public MyCommand(IWpfTextView textView, MyFormatter formatter, ITextDocument document)
    {
        _textView = textView;
        _formatter = formatter;
        _document = document;
    }

    public void Format()
    {
        var input = _document.TextBuffer.CurrentSnapshot.GetText();
        var output = _formatter.format(input);

        // get caret snapshot point
        var point = _textView.Caret.Position.BufferPosition;

        using (var edit = _document.TextBuffer.CreateEdit())
        {
            edit.Replace(0, _document.TextBuffer.CurrentSnapshot.Length, output);
            edit.Apply();
        }

        // set caret position
        _textView.Caret.MoveTo(point);
    }
}

我不想实现一些自定义插入符“历史记录”,我想按预期的方式进行。 此外,我希望将移动插入符号视为编辑的一部分,从而保持“ctrl+z”功能完整。

一如既往,非常感谢任何帮助!

最佳答案

您可以检索该点的位置,然后创建一个新的 SnapshotPoint 并移动到它。

像这样:

var point = _textView.Caret.Position.BufferPosition;
int position = point.Position;

        using (var edit = _document.TextBuffer.CreateEdit())
        {
            edit.Replace(0, _document.TextBuffer.CurrentSnapshot.Length, output);
            edit.Apply();
        }

        // set caret position
        _textView.Caret.MoveTo(new SnapshotPoint(_textView.TextSnapshot, position));

此外,您可以创建和使用这样的扩展: https://github.com/jaredpar/EditorUtils/blob/master/Src/EditorUtils/Extensions.cs

关于c# - 在保留插入符号的同时替换文档中的文本,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/42712164/

相关文章:

c# - 无法将类型 'string' 隐式转换为 'System.Data.SqlClient.Sqlconnection'

c# - MVC 页面未显示,404 未找到

mvvm - 如何使用 MVVM、PRISM 和 MEF 在没有用户请求的情况下处理来自 View 模型的 UI 交互

c# - 集中 MEF 组合

c# - 如何将MEF导入导出信息持久化到磁盘

python - 有没有Powerpoint上Python win32com操作的文档?

java - 使 DocumentBuilder.parse 忽略 DTD 引用

c# - ASP.NET Web Api 2 通过 Id 获取

c# - sqlite 抛出一个 "String not recognized as a valid datetime"

java - 选择索引与 getText 索引不同