public void InsertAtCaret (string text)
{
if (String.IsNullOrEmpty (text))
return;
using (var undo = OpenUndoGroup ()) {
DeleteSelectedText (IsSomethingSelected ? MainSelection.SelectionMode != SelectionMode.Block : true);
// Needs to be called after delete text, delete text handles virtual caret postitions itself,
// but afterwards the virtual position may need to be restored.
EnsureCaretIsNotVirtual ();
if (IsSomethingSelected && MainSelection.SelectionMode == SelectionMode.Block) {
var visualInsertLocation = LogicalToVisualLocation (MainSelection.Anchor);
var selection = MainSelection;
Caret.PreserveSelection = true;
for (int lineNumber = selection.MinLine; lineNumber <= selection.MaxLine; lineNumber++) {
var lineSegment = GetLine (lineNumber);
int insertOffset = lineSegment.GetLogicalColumn (this, visualInsertLocation.Column) - 1;
string textToInsert;
if (lineSegment.Length < insertOffset) {
int visualLastColumn = lineSegment.GetVisualColumn (this, lineSegment.Length + 1);
int charsToInsert = visualInsertLocation.Column - visualLastColumn;
int spaceCount = charsToInsert % Options.TabSize;
textToInsert = new string ('\t', (charsToInsert - spaceCount) / Options.TabSize) + new string (' ', spaceCount) + text;
insertOffset = lineSegment.Length;
} else {
textToInsert = text;
}
Insert (lineSegment.Offset + insertOffset, textToInsert);
}
var visualColumn = GetLine (Caret.Location.Line).GetVisualColumn (this, Caret.Column);
MainSelection = new Selection (
new DocumentLocation (selection.Anchor.Line, GetLine (selection.Anchor.Line).GetLogicalColumn (this, visualColumn)),
new DocumentLocation (selection.Lead.Line, GetLine (selection.Lead.Line).GetLogicalColumn (this, visualColumn)),
SelectionMode.Block
);
Caret.PreserveSelection = false;
Document.CommitMultipleLineUpdate (selection.MinLine, selection.MaxLine);
} else {
EnsureCaretIsNotVirtual ();
Insert (Caret.Offset, text);
}
}
}