Changing caret position
LeeMSilver opened this issue · comments
According to the comments in the EditAsync() definition:
'Initiates an edit request in the host Visual Studio process, enabling the extension
to atomically request one or more Microsoft.VisualStudio.Extensibility.Editor.ITextDocumentSnapshot
edits, caret position changes, or other state changes.'
Is it documented how to make caret position changes?
The selection (caret) is part of https://learn.microsoft.com/en-us/dotnet/api/microsoft.visualstudio.extensibility.editor.itextviewsnapshot?view=vs-extensibility so apply edits to its editable version (ITextViewSnapshot.AsEditable())
'... so apply edits to its editable version (ITextViewSnapshot.AsEditable())'
Are you saying that the Delete
/Insert
/Replace
methods affect the selection (caret)? (the comments in ITextDocumentEditor
do not indicate this.
Even if so, I sometimes need to set the caret independent of the above methods - to a position not affected by the above methods.
@LeeMSilver, editing text document implicitly affects caret position, for example inserting some text at the caret will move the caret to the end of the inserted text:
await this.Extensibility.Editor().EditAsync(
batch =>
{
textView.Document.AsEditable(batch).Replace(textView.Selection.Extent, newGuidString);
},
cancellationToken);
You can use ITextViewSnapshot.AsEditable().SetSelections() to set the caret explicitly to a different position, e.g. this code would insert some text, but keep the caret at the original position:|
await this.Extensibility.Editor().EditAsync(
batch =>
{
var caret = textView.Selection.Extent.Start;
textView.Document.AsEditable(batch).Replace(textView.Selection.Extent, newGuidString);
textView.AsEditable(batch).SetSelections([new Selection(activePosition: caret, anchorPosition: caret, insertionPosition: caret)]);
},
cancellationToken);
Thanks - that's exactly what I am looking for.
Is it documented anywhere that AsEditable
is also an extension-method for ITextViewSnapshot
besides being an extension-method for ITextViewSnapshot.Document
?
If I had known this I would not have needed to ask the question.
@LeeMSilver fair point about documentation. I'm tracking this issue internally.
@LeeMSilver, editing text document implicitly affects caret position, for example inserting some text at the caret will move the caret to the end of the inserted text:
await this.Extensibility.Editor().EditAsync( batch => { textView.Document.AsEditable(batch).Replace(textView.Selection.Extent, newGuidString); }, cancellationToken);You can use ITextViewSnapshot.AsEditable().SetSelections() to set the caret explicitly to a different position, e.g. this code would insert some text, but keep the caret at the original position:|
await this.Extensibility.Editor().EditAsync( batch => { var caret = textView.Selection.Extent.Start; textView.Document.AsEditable(batch).Replace(textView.Selection.Extent, newGuidString); textView.AsEditable(batch).SetSelections([new Selection(activePosition: caret, anchorPosition: caret, insertionPosition: caret)]); }, cancellationToken);
I just tried this code but it did not work. The caret is not preserved.
Even though sometimes it seems to work, in reality, if the user presses up/down, the keyboard real anchor is at the end of the file and not at the caret position specified/displayed.
I can even see two caret markers:
A blue caret (the caret position I specified in SetSelections)
A red caret (the one the keyboard/VS is really responding to).
@olegtk is there something I'm missing or could it be a bug in the API?