2017-03-10 4 views
1

외부 프로그램을 사용하여 Visual Studio 내에서 코드의 서식을 지정하는 확장 프로그램 작업 중입니다.캐럿을 유지하면서 문서의 텍스트 바꾸기

을 사용하여 파일의 내용을 바꿀 경우 ITextEdit.Replace (...) 탈자구는 문서 끝에 잘못 표시됩니다.

난 할 노력하고있어 이전에 컨텐츠를 교체하기 전에 textbuffer에 있던 위치로 캐럿 위치를 설정 한 후 파일의 내용을 교체하고, 전에 textbuffer에서 현재 캐럿 위치의 스냅 샷을 저장입니다 .

그러나 ITextEdit.Apply() 예외 던져 _textView.Caret.MoveTo (포인트)를 일으키는 새로운 스냅 샷을 생성한다 :

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) 

I는 새로운 스냅 지점을 만드는 시도를 대신과 같이, _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"기능을 그대로 유지하면서 이동 캐럿을 편집의 일부로 간주하고 싶습니다.

언제나처럼, 어떤 도움을 주셔서 감사합니다!

답변

0

콜 우 있지만 - 내 질문에 대한 MSFT의 대답은 내 문제를 해결 도움이, 그것은 didn를

제공된 코드를 사용하면 캐럿을 움직이게되지만, 문서의 전체 내용을 바꿀 때까지 캐럿이 f 인 경우에도 스크롤 위치가 맨 위로 다시 설정됩니다. 문서를 추가로 다운로드하십시오.

또한이 여전히 발생 "다중 실행 취소"대신 ​​하나의 : 캐럿이 CTRL + Z를 공격하도록 사용자에게 필요한 두 개의 "실행 취소"이었다 문서의 내용을 교체하고 이동하여 예 두 번만 대신을 사용하면 교체를 취소 할 수 있습니다.

내가 다음에 코드를 변경이 문제를 해결하려면 다음

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

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

    public void Format() 
    { 
     var input = _textView.TextSnapshot.GetText(); 
     var output = _formatter.format(input); 

     using (var undo = _undoManager.TextBufferUndoHistory.CreateTransaction("Format")) 
     using (var edit = _undoManager.TextBuffer.CreateEdit(EditOptions.DefaultMinimalChange, 0, null)) 
     { 
      edit.Replace(0, _textView.TextSnapshot.Length, output); 
      edit.Apply(); 

      undo.Complete(); 
     } 
    } 
} 

이 내가 원하는 정확히 방식으로 작동하지 않기 때문에 캐럿 (후행 공백에 위치) 때때로 받는 사람 아래로 점프 현재 줄의 끝 대신에 다음 줄의 시작.

그러나 충분히 가깝습니다.

1

포인트의 위치를 ​​검색 한 다음 새 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

+0

도움 주셔서 감사합니다. @coleWuMsft - 아래에서 허용되는 답변을 참조하십시오. –