public static void Left (TextEditorData data) { using (var undo = data.OpenUndoGroup ()) { if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection) { data.Caret.Offset = System.Math.Min (data.SelectionAnchor, data.Caret.Offset); data.ClearSelection (); return; } if (data.Caret.Column > DocumentLocation.MinColumn) { DocumentLine line = data.Document.GetLine (data.Caret.Line); if (data.Caret.Column > line.Length + 1) { if (data.Caret.AllowCaretBehindLineEnd) { data.Caret.Column--; } else { data.Caret.Column = line.Length + 1; } } else { int offset = data.Caret.Offset - 1; foreach (var folding in data.Document.GetFoldingsFromOffset (offset).Where (f => f.IsFolded && f.Offset < offset)) { offset = System.Math.Min (offset, folding.Offset); } data.Caret.Offset = offset; } } else if (data.Caret.Line > DocumentLocation.MinLine) { DocumentLine prevLine = data.Document.GetLine (data.Caret.Line - 1); var nextLocation = new DocumentLocation (data.Caret.Line - 1, prevLine.Length + 1); if (data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual && nextLocation.Column == DocumentLocation.MinColumn) nextLocation = new DocumentLocation (data.Caret.Line - 1, data.GetVirtualIndentationColumn (nextLocation)); data.Caret.Location = nextLocation; } } }
public static int RemoveTabInLine (TextEditorData data, DocumentLine line) { if (line.LengthIncludingDelimiter == 0) return 0; using (var undoGroup = data.OpenUndoGroup ()) { char ch = data.Document.GetCharAt (line.Offset); if (ch == '\t') { data.Remove (line.Offset, 1); data.Document.CommitLineUpdate (line); return 1; } else if (ch == ' ') { int removeCount = 0; for (int i = 0; i < data.Options.IndentationSize;) { ch = data.Document.GetCharAt (line.Offset + i); if (ch == ' ') { removeCount++; i++; } else if (ch == '\t') { removeCount++; i += data.Options.TabSize; } else { break; } } data.Remove (line.Offset, removeCount); data.Document.CommitLineUpdate (line); return removeCount; } } return 0; }
static void NextWord (TextEditorData data, bool subword) { using (var undo = data.OpenUndoGroup ()) { int oldLine = data.Caret.Line; int caretOffset = data.Caret.Offset; int offset = subword ? data.FindNextSubwordOffset (caretOffset) : data.FindNextWordOffset (caretOffset); if (caretOffset != offset && data.CanEdit (oldLine) && data.CanEdit (data.Caret.Line)) { data.Remove (caretOffset, offset - caretOffset); } } }
public static void GotoMatchingBracket (TextEditorData data) { using (var undoGroup = data.OpenUndoGroup ()) { int matchingBracketOffset = data.Document.GetMatchingBracketOffset (data.Caret.Offset); if (matchingBracketOffset == -1 && data.Caret.Offset > 0) matchingBracketOffset = data.Document.GetMatchingBracketOffset (data.Caret.Offset - 1); if (matchingBracketOffset != -1) data.Caret.Offset = matchingBracketOffset; } }
public static void Select (TextEditorData data, Action<TextEditorData> caretMoveAction) { using (var undoGroup = data.OpenUndoGroup ()) { PositionChangedHandler handler = new PositionChangedHandler (data); data.Caret.PositionChanged += handler.DataCaretPositionChanged; StartSelection (data); caretMoveAction (data); data.Caret.PositionChanged -= handler.DataCaretPositionChanged; data.Caret.AutoScrollToCaret = true; data.Caret.PreserveSelection = false; } }
public void Insert (TextEditorData editor, string text) { int offset = editor.Document.LocationToOffset (Location); using (var undo = editor.OpenUndoGroup ()) { text = editor.FormatString (Location, text); LineSegment line = editor.Document.GetLineByOffset (offset); int insertionOffset = line.Offset + Location.Column - 1; offset = insertionOffset; InsertNewLine (editor, LineBefore, ref offset); offset += editor.Insert (offset, text); InsertNewLine (editor, LineAfter, ref offset); } }
public static void Left(TextEditorData editor) { if (!Platform.IsMac) { if (DocumentLocation.MinColumn < editor.Caret.Column) CaretMoveActions.Left(editor); } else { using (var undo = editor.OpenUndoGroup()) { if (editor.Caret.Column > DocumentLocation.MinColumn) editor.Caret.Column = editor.Caret.Column - 1; } } }
public static void Up(TextEditorData editor) { if (!Platform.IsMac) CaretMoveActions.Up(editor); else { using (var undo = editor.OpenUndoGroup()) { if (editor.Caret.Line > DocumentLocation.MinLine) { int visualLine = editor.LogicalToVisualLine(editor.Caret.Line); int line = editor.VisualToLogicalLine(visualLine - 1); editor.Caret.Line = line; } } } }
public static void Down(TextEditorData editor) { if (!Platform.IsMac) CaretMoveActions.Down(editor); else { using (var undo = editor.OpenUndoGroup()) { if (editor.Caret.Line < editor.Document.LineCount) { int nextLine = editor.LogicalToVisualLine(editor.Caret.Line); int line = editor.VisualToLogicalLine(nextLine + 1); editor.Caret.Line = line; } } } }
public static void RemoveIndentSelection (TextEditorData data) { if (!data.IsSomethingSelected) return; int startLineNr, endLineNr; GetSelectedLines (data, out startLineNr, out endLineNr); using (var undo = data.OpenUndoGroup (OperationType.Format)) { var anchor = data.MainSelection.Anchor; var lead = data.MainSelection.Lead; bool first = true; bool removedFromLast = false; int removeLast = 0; bool removedFromFirst = false; int removeFirst = 0; foreach (var line in data.SelectedLines) { int remove = RemoveTabInLine (data, line); removedFromLast |= remove > 0; removeLast = remove; if (first) { removedFromFirst = remove > 0; removeFirst = remove; first = false; } } var ac = System.Math.Max (DocumentLocation.MinColumn, anchor.Column - (anchor < lead ? removeFirst : removeLast)); var lc = System.Math.Max (DocumentLocation.MinColumn, lead.Column - (anchor < lead ? removeLast : removeFirst)); if (anchor < lead) { if (!removedFromFirst) ac = anchor.Column; if (!removedFromLast) lc = lead.Column; } else { if (!removedFromFirst) lc = lead.Column; if (!removedFromLast) ac = anchor.Column; } data.SetSelection (anchor.Line, ac, lead.Line, lc); } data.Document.RequestUpdate (new MultipleLineUpdate (startLineNr, endLineNr)); data.Document.CommitDocumentUpdate (); }
public static void CaretLineToStart(TextEditorData data) { if (!data.CanEdit(data.Caret.Line)) { return; } var line = data.Document.GetLine(data.Caret.Line); using (var undo = data.OpenUndoGroup()) { data.EnsureCaretIsNotVirtual(); int physColumn = data.Caret.Column - 1; var startLine = GetStartOfLineOffset(data, data.Caret.Location); data.Remove(startLine, (line.Offset + physColumn) - startLine); } data.Document.CommitLineUpdate(data.Caret.Line); }
public int Insert(TextEditorData editor, string text) { int offset = editor.Document.LocationToOffset(Location); using (var undo = editor.OpenUndoGroup()) { text = editor.FormatString(Location, text); DocumentLine line = editor.Document.GetLineByOffset(offset); int insertionOffset = line.Offset + Location.Column - 1; offset = insertionOffset; InsertNewLine(editor, LineBefore, ref offset); int result = offset - insertionOffset; offset += editor.Insert(offset, text); InsertNewLine(editor, LineAfter, ref offset); return(result); } }
static void NewLineSmartIndent(TextEditorData data) { using (var undo = data.OpenUndoGroup()) { data.EnsureCaretIsNotVirtual(); var oldCaretLine = data.Caret.Location.Line; string indentString = data.GetIndentationString(data.Caret.Location); data.InsertAtCaret(data.EolMarker); // Don't insert the indent string if the EOL insertion modified the caret location in an unexpected fashion // (This likely means someone has custom logic regarding insertion of the EOL) if (data.Caret.Location.Line == oldCaretLine + 1 && data.Caret.Location.Column == 1) { data.InsertAtCaret(indentString); } } }
public static void InsertNewLine (TextEditorData data) { if (!data.CanEditSelection) return; using (var undo = data.OpenUndoGroup ()) { if (data.IsSomethingSelected) data.DeleteSelectedText (); switch (data.Options.IndentStyle) { case IndentStyle.None: data.InsertAtCaret (data.EolMarker); break; case IndentStyle.Auto: data.EnsureCaretIsNotVirtual (); var sb = new StringBuilder (data.EolMarker); sb.Append (data.Document.GetLineIndent (data.Caret.Line)); data.InsertAtCaret (sb.ToString ()); break; case IndentStyle.Smart: if (!data.HasIndentationTracker) goto case IndentStyle.Auto; NewLineSmartIndent (data); break; case IndentStyle.Virtual: if (!data.HasIndentationTracker) goto case IndentStyle.Auto; var oldLine = data.Caret.Line; var curLine = data.GetLine (oldLine); var indentCol = data.GetVirtualIndentationColumn (data.Caret.Location); if (curLine.Length >= data.Caret.Column) { NewLineSmartIndent (data); data.FixVirtualIndentation (); data.FixVirtualIndentation (oldLine); break; } data.Insert (data.Caret.Offset, data.EolMarker); data.FixVirtualIndentation (oldLine); data.Caret.Column = indentCol; break; default: throw new ArgumentOutOfRangeException (); } } }
public static void IndentSelection (TextEditorData data) { if (!data.IsSomethingSelected) return; int startLineNr, endLineNr; GetSelectedLines (data, out startLineNr, out endLineNr); var anchor = data.MainSelection.Anchor; var lead = data.MainSelection.Lead; using (var undo = data.OpenUndoGroup ()) { foreach (DocumentLine line in data.SelectedLines) { data.Insert (line.Offset, data.Options.IndentationString); } } var leadCol = lead.Column > 1 || lead < anchor ? lead.Column + 1 : 1; var anchorCol = anchor.Column > 1 || anchor < lead ? anchor.Column + 1 : 1; data.SetSelection (anchor.Line, anchorCol, lead.Line, leadCol); data.Document.RequestUpdate (new MultipleLineUpdate (startLineNr, endLineNr)); data.Document.CommitDocumentUpdate (); }
public static void MoveBlockDown (TextEditorData data) { int lineStart = data.Caret.Line; int lineEnd = data.Caret.Line; bool setSelection = lineStart != lineEnd; DocumentLocation anchor = DocumentLocation.Empty, lead = DocumentLocation.Empty; if (data.IsSomethingSelected) { setSelection = true; lineStart = data.MainSelection.MinLine; lineEnd = data.MainSelection.MaxLine; anchor = data.MainSelection.Anchor; lead = data.MainSelection.Lead; } if (lineStart <= 0) return; using (var undo = data.OpenUndoGroup ()) { //Mono.TextEditor.LineSegment startLine = data.Document.GetLine (lineStart); //int relCaretOffset = data.Caret.Offset - startLine.Offset; Mono.TextEditor.DocumentLine nextLine = data.Document.GetLine (lineEnd + 1); if (nextLine == null) return; string text = data.Document.GetTextAt (nextLine.Offset, nextLine.Length); List<TextMarker> prevLineMarkers = new List<TextMarker> (nextLine.Markers); nextLine.ClearMarker (); var loc = data.Caret.Location; for (int i = lineEnd + 1; i >= lineStart; i--) { DocumentLine cur = data.Document.GetLine (i); DocumentLine prev = data.Document.GetLine (i - 1); data.Replace (cur.Offset, cur.Length, i != lineStart ? data.Document.GetTextAt (prev.Offset, prev.Length) : text); data.Document.GetLine (i).ClearMarker (); foreach (TextMarker marker in (i != lineStart ? data.Document.GetLine (i - 1).Markers : prevLineMarkers)) { data.Document.GetLine (i).AddMarker (marker); } } data.Caret.Location = new DocumentLocation (loc.Line + 1, loc.Column); if (setSelection) data.SetSelection (anchor.Line + 1, anchor.Column, lead.Line + 1, lead.Column); } }
public static int RemoveTabInLine(TextEditorData data, DocumentLine line) { if (line.LengthIncludingDelimiter == 0) { return(0); } using (var undoGroup = data.OpenUndoGroup()) { char ch = data.Document.GetCharAt(line.Offset); if (ch == '\t') { data.Remove(line.Offset, 1); data.Document.CommitLineUpdate(line); return(1); } else if (ch == ' ') { int removeCount = 0; for (int i = 0; i < data.Options.IndentationSize;) { ch = data.Document.GetCharAt(line.Offset + i); if (ch == ' ') { removeCount++; i++; } else if (ch == '\t') { removeCount++; i += data.Options.TabSize; } else { break; } } data.Remove(line.Offset, removeCount); data.Document.CommitLineUpdate(line); return(removeCount); } } return(0); }
static int PastePlainText(TextEditorData data, int offset, string text, bool preserveSelection = false, byte[] copyData = null) { int inserted = 0; var undo = data.OpenUndoGroup(); var version = data.Document.Version; if (!preserveSelection) { data.DeleteSelectedText(!data.IsSomethingSelected || data.MainSelection.SelectionMode != SelectionMode.Block); } data.EnsureCaretIsNotVirtual(); if (data.IsSomethingSelected && data.MainSelection.SelectionMode == SelectionMode.Block) { var selection = data.MainSelection; var visualInsertLocation = data.LogicalToVisualLocation(selection.Anchor); for (int lineNumber = selection.MinLine; lineNumber <= selection.MaxLine; lineNumber++) { var lineSegment = data.GetLine(lineNumber); int insertOffset = lineSegment.GetLogicalColumn(data, visualInsertLocation.Column) - 1; string textToInsert; if (lineSegment.Length < insertOffset) { int visualLastColumn = lineSegment.GetVisualColumn(data, lineSegment.Length + 1); int charsToInsert = visualInsertLocation.Column - visualLastColumn; int spaceCount = charsToInsert % data.Options.TabSize; textToInsert = new string ('\t', (charsToInsert - spaceCount) / data.Options.TabSize) + new string (' ', spaceCount) + text; insertOffset = lineSegment.Length; } else { textToInsert = text; } inserted = data.Insert(lineSegment.Offset + insertOffset, textToInsert); } } else { offset = version.MoveOffsetTo(data.Document.Version, offset); inserted = data.PasteText(offset, text, copyData, ref undo); } undo.Dispose(); return(inserted); }
public static void DuplicateLine(TextEditorData data) { using (var undoGroup = data.OpenUndoGroup()) { if (data.IsSomethingSelected) { var selectedText = data.SelectedText; data.ClearSelection(); data.InsertAtCaret(selectedText); } else { DocumentLine line = data.Document.GetLine(data.Caret.Line); if (line == null) { return; } data.Insert(line.Offset, data.GetTextAt(line.SegmentIncludingDelimiter)); } } }
public static void CaretLine(TextEditorData data) { if (data.Document.LineCount <= 1 || !data.CanEdit(data.Caret.Line)) { return; } using (var undo = data.OpenUndoGroup()) { if (data.IsSomethingSelected) { var startLine = data.GetLine(data.MainSelection.Start.Line); var endLine = data.GetLine(data.MainSelection.End.Line); data.Remove(startLine.Offset, endLine.EndOffsetIncludingDelimiter - startLine.Offset); return; } var start = GetStartOfLineOffset(data, data.Caret.Location); var end = GetEndOfLineOffset(data, data.Caret.Location); data.Remove(start, end - start); data.Caret.Column = DocumentLocation.MinColumn; } }
public static void RemoveIndentSelection (TextEditorData data) { if (!data.IsSomethingSelected) return; int startLineNr, endLineNr; GetSelectedLines (data, out startLineNr, out endLineNr); using (var undo = data.OpenUndoGroup ()) { var anchor = data.MainSelection.Anchor; var lead = data.MainSelection.Lead; bool first = true; bool removedFromLast = false; bool removedFromFirst = false; foreach (var line in data.SelectedLines) { int remove = RemoveTabInLine (data, line); removedFromLast |= remove > 0; if (first) { removedFromFirst = remove > 0; first = false; } } var ac = System.Math.Max (DocumentLocation.MinColumn, anchor.Column - 1); var lc = System.Math.Max (DocumentLocation.MinColumn, lead.Column - 1); if (anchor < lead) { if (!removedFromFirst) ac = anchor.Column; if (!removedFromLast) lc = lead.Column; } else { if (!removedFromFirst) lc = lead.Column; if (!removedFromLast) ac = anchor.Column; } data.SetSelection (anchor.Line, ac, lead.Line, lc); } data.Document.RequestUpdate (new MultipleLineUpdate (startLineNr, endLineNr)); data.Document.CommitDocumentUpdate (); }
public static void InsertTab(TextEditorData data) { if (!data.CanEditSelection) { return; } if (data.IsMultiLineSelection && data.MainSelection.SelectionMode != SelectionMode.Block) { IndentSelection(data); return; } using (var undo = data.OpenUndoGroup()) { string indentationString = "\t"; bool convertTabToSpaces = data.TabsToSpaces; if (!convertTabToSpaces && !data.Options.AllowTabsAfterNonTabs) { for (int i = 1; i < data.Caret.Column; i++) { if (data.Document.GetCharAt(data.Caret.Offset - i) != '\t') { convertTabToSpaces = true; break; } } } if (convertTabToSpaces) { DocumentLocation visualLocation = data.LogicalToVisualLocation(data.Caret.Location); int tabWidth = TextViewMargin.GetNextTabstop(data, visualLocation.Column) - visualLocation.Column; indentationString = new string(' ', tabWidth); } if (data.IsSomethingSelected) { data.DeleteSelectedText(data.MainSelection.SelectionMode != SelectionMode.Block); } data.InsertAtCaret(indentationString); } }
public static void RemoveTab(TextEditorData data) { if (data.IsSomethingSelected) { if (data.CanEditSelection) { RemoveIndentSelection(data); } return; } var line = data.Document.GetLine(data.Caret.Line); if (line != null) { using (var undo = data.OpenUndoGroup()) { data.EnsureCaretIsNotVirtual(); data.Document.ApplyTextChanges(new [] { RemoveTabInLine(data, line) }); data.FixVirtualIndentation(); } } }
public static void LineEnd(TextEditorData data) { using (var undo = data.OpenUndoGroup()) { if (!data.Caret.PreserveSelection) { data.ClearSelection(); } var line = data.Document.GetLine(data.Caret.Line); var newLocation = new DocumentLocation(data.Caret.Line, line.Length + 1); // handle folding IEnumerable <FoldSegment> foldings = data.Document.GetStartFoldings(line); FoldSegment segment = null; foreach (FoldSegment folding in foldings) { if (folding.IsFolded && folding.Contains(data.Document.LocationToOffset(newLocation))) { segment = folding; break; } } if (segment != null) { newLocation = data.Document.OffsetToLocation(segment.EndLine.Offset + segment.EndColumn - 1); } if (newLocation != data.Caret.Location) { data.Caret.Location = newLocation; } if (data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual) { int virtualIndentColumn = data.GetVirtualIndentationColumn(data.Caret.Location); if (virtualIndentColumn > data.Caret.Column) { data.Caret.Column = virtualIndentColumn; } } } }
public static Microsoft.CodeAnalysis.Text.TextChange RemoveTabInLine(TextEditorData data, DocumentLine line) { if (line.LengthIncludingDelimiter == 0) { return(default(Microsoft.CodeAnalysis.Text.TextChange)); } using (var undoGroup = data.OpenUndoGroup()) { char ch = data.Document.GetCharAt(line.Offset); if (ch == '\t') { return(new Microsoft.CodeAnalysis.Text.TextChange(new TextSpan(line.Offset, 1), "")); } else if (ch == ' ') { int removeCount = 0; for (int i = 0; i < data.Options.IndentationSize;) { ch = data.Document.GetCharAt(line.Offset + i); if (ch == ' ') { removeCount++; i++; } else if (ch == '\t') { removeCount++; i += data.Options.TabSize; } else { break; } } return(new Microsoft.CodeAnalysis.Text.TextChange(new TextSpan(line.Offset, removeCount), "")); } } return(default(Microsoft.CodeAnalysis.Text.TextChange)); }
public static void InsertNewLine(TextEditorData data) { if (!data.CanEditSelection) { return; } using (var undo = data.OpenUndoGroup()) { if (data.IsSomethingSelected) { data.DeleteSelectedText(); } data.EnsureCaretIsNotVirtual(); StringBuilder sb = new StringBuilder(data.EolMarker); if (data.Options.AutoIndent) { sb.Append(data.Document.GetLineIndent(data.Caret.Line)); } int offset = data.Caret.Offset; data.Insert(offset, sb.ToString()); data.Caret.Offset = offset + sb.Length; } }
public static void Down(TextEditorData data) { using (var undo = data.OpenUndoGroup()) { //on Mac, when deselecting and moving up/down a line, column is always the column of the selection's start if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection) { int col = data.MainSelection.Anchor > data.MainSelection.Lead ? data.MainSelection.Lead.Column : data.MainSelection.Anchor.Column; int line = data.MainSelection.MaxLine + 1; data.ClearSelection(); if (line <= data.Document.LineCount) { int offset = data.Document.LocationToOffset(line, col); data.Caret.SetToOffsetWithDesiredColumn(MoveCaretOutOfFolding(data, offset)); } else { data.Caret.Offset = data.Document.Length; } MoveOutOfUTF32Character(data); return; } if (data.Caret.Line < data.Document.LineCount) { int nextLine = data.LogicalToVisualLine(data.Caret.Line) + 1; int line = data.VisualToLogicalLine(nextLine); int offset = MoveCaretOutOfFolding(data, data.LocationToOffset(line, data.Caret.Column), true); data.Caret.SetToOffsetWithDesiredColumn(offset); } else { ToDocumentEnd(data); } MoveOutOfUTF32Character(data); } }
public static void InsertTab (TextEditorData data) { if (!data.CanEditSelection) return; if (data.IsMultiLineSelection && data.MainSelection.SelectionMode != SelectionMode.Block) { IndentSelection (data); return; } using (var undo = data.OpenUndoGroup ()) { string indentationString = "\t"; bool convertTabToSpaces = data.TabsToSpaces; if (!convertTabToSpaces && !data.Options.AllowTabsAfterNonTabs) { for (int i = 1; i < data.Caret.Column; i++) { if (data.Document.GetCharAt (data.Caret.Offset - i) != '\t') { convertTabToSpaces = true; break; } } } if (convertTabToSpaces) { DocumentLocation visualLocation = data.LogicalToVisualLocation (data.Caret.Location); int tabWidth = TextViewMargin.GetNextTabstop (data, visualLocation.Column) - visualLocation.Column; indentationString = new string (' ', tabWidth); } if (data.IsSomethingSelected) data.DeleteSelectedText (data.MainSelection.SelectionMode != SelectionMode.Block); data.InsertAtCaret (indentationString); } }
static void NewLineSmartIndent (TextEditorData data) { using (var undo = data.OpenUndoGroup ()) { data.EnsureCaretIsNotVirtual (); string indentString; if (data.HasIndentationTracker) { indentString = data.IndentationTracker.GetIndentationString (data.Caret.Location); } else { indentString = data.GetIndentationString (data.Caret.Location); } data.InsertAtCaret (data.EolMarker); data.InsertAtCaret (indentString); } }
public static void RemoveIndentSelection(TextEditorData data) { if (!data.IsSomethingSelected) { return; } int startLineNr, endLineNr; GetSelectedLines(data, out startLineNr, out endLineNr); using (var undo = data.OpenUndoGroup(OperationType.Format)) { var anchor = data.MainSelection.Anchor; var lead = data.MainSelection.Lead; bool first = true; bool removedFromLast = false; int removeLast = 0; bool removedFromFirst = false; int removeFirst = 0; var changes = new List <Microsoft.CodeAnalysis.Text.TextChange> (); DocumentLine last = null; foreach (var line in data.SelectedLines) { var remove = RemoveTabInLine(data, line); removedFromLast |= remove.Span.Length > 0; removeLast = remove.Span.Length; if (first) { removedFromFirst = remove.Span.Length > 0; removeFirst = remove.Span.Length; first = false; } if (remove.Span.Length > 0) { changes.Add(remove); } last = line; } data.Document.ApplyTextChanges(changes); if (last != null) { data.Document.CommitLineUpdate(last); } var ac = System.Math.Max(DocumentLocation.MinColumn, anchor.Column - (anchor < lead ? removeFirst : removeLast)); var lc = System.Math.Max(DocumentLocation.MinColumn, lead.Column - (anchor < lead ? removeLast : removeFirst)); if (anchor < lead) { if (!removedFromFirst) { ac = anchor.Column; } if (!removedFromLast) { lc = lead.Column; } } else { if (!removedFromFirst) { lc = lead.Column; } if (!removedFromLast) { ac = anchor.Column; } } data.SetSelection(anchor.Line, ac, lead.Line, lc); } data.Document.RequestUpdate(new MultipleLineUpdate(startLineNr, endLineNr)); data.Document.CommitDocumentUpdate(); }
public static void CaretLineToEnd (TextEditorData data) { if (!data.CanEdit (data.Caret.Line)) return; var line = data.Document.GetLine (data.Caret.Line); using (var undo = data.OpenUndoGroup ()) { data.EnsureCaretIsNotVirtual (); int physColumn = data.Caret.Column - 1; if (physColumn == line.Length) { // Nothing after the cursor, delete the end-of-line sequence data.Remove (line.Offset + physColumn, line.LengthIncludingDelimiter - physColumn); } else { // Delete from cursor position to the end of the line var end = GetEndOfLineOffset (data, data.Caret.Location, false); data.Remove (line.Offset + physColumn, end - (line.Offset + physColumn)); } } data.Document.CommitLineUpdate (data.Caret.Line); }
static int PasteFrom(Clipboard clipboard, TextEditorData data, bool preserveSelection, int insertionOffset, bool preserveState) { int result = -1; if (!data.CanEdit(data.Document.OffsetToLineNumber(insertionOffset))) { return(result); } if (clipboard.WaitIsTargetAvailable(CopyOperation.MD_ATOM)) { clipboard.RequestContents(CopyOperation.MD_ATOM, delegate(Clipboard clp, SelectionData selectionData) { if (selectionData.Length > 0) { byte[] selBytes = selectionData.Data; string text = System.Text.Encoding.UTF8.GetString(selBytes, 1, selBytes.Length - 1); bool pasteBlock = (selBytes [0] & 1) == 1; bool pasteLine = (selBytes [0] & 2) == 2; var clearSelection = data.IsSomethingSelected ? data.MainSelection.SelectionMode != SelectionMode.Block : true; using (var undo = data.OpenUndoGroup()) { if (pasteBlock) { data.Caret.PreserveSelection = true; if (preserveSelection && data.IsSomethingSelected) { data.DeleteSelectedText(clearSelection); } string[] lines = text.Split('\r'); int lineNr = data.Document.OffsetToLineNumber(insertionOffset); int col = insertionOffset - data.Document.GetLine(lineNr).Offset; int visCol = data.Document.GetLine(lineNr).GetVisualColumn(data, col); DocumentLine curLine; int lineCol = col; result = 0; for (int i = 0; i < lines.Length; i++) { while (data.Document.LineCount <= lineNr + i) { data.Insert(data.Document.TextLength, Environment.NewLine); result += Environment.NewLine.Length; } curLine = data.Document.GetLine(lineNr + i); if (lines [i].Length > 0) { lineCol = curLine.GetLogicalColumn(data, visCol); if (curLine.Length + 1 < lineCol) { result += lineCol - curLine.Length; data.Insert(curLine.Offset + curLine.Length, new string (' ', lineCol - curLine.Length)); } data.Insert(curLine.Offset + lineCol, lines [i]); result += lines [i].Length; } if (!preserveState) { data.Caret.Offset = curLine.Offset + lineCol + lines [i].Length; } } if (!preserveState) { data.ClearSelection(); } data.Caret.PreserveSelection = false; } else if (pasteLine) { data.Caret.PreserveSelection = true; if (preserveSelection && data.IsSomethingSelected) { data.DeleteSelectedText(clearSelection); } result = text.Length; DocumentLine curLine = data.Document.GetLine(data.Caret.Line); data.Insert(curLine.Offset, text + data.EolMarker); if (!preserveState) { data.ClearSelection(); } data.Caret.PreserveSelection = false; } else { PastePlainText(data, text); } } } }); // we got MD_ATOM text - no need to request text. (otherwise buffer may get copied twice). return(result); } if (result < 0 && clipboard.WaitIsTextAvailable()) { clipboard.RequestText(delegate(Clipboard clp, string text) { if (string.IsNullOrEmpty(text)) { return; } using (var undo = data.OpenUndoGroup()) { PastePlainText(data, text); } }); } return(result); }
public static void SetCompletionText (TextEditorData data, CodeCompletionContext ctx, string partialWord, string completeWord, int wordOffset) { if (data == null || data.Document == null) return; int triggerOffset = ctx.TriggerOffset; int length = String.IsNullOrEmpty (partialWord) ? 0 : partialWord.Length; // for named arguments invoke(arg:<Expr>); if (completeWord.EndsWith (":", StringComparison.Ordinal)) { if (data.GetCharAt (triggerOffset + length) == ':') length++; } bool blockMode = false; if (data.IsSomethingSelected) { blockMode = data.MainSelection.SelectionMode == Mono.TextEditor.SelectionMode.Block; if (blockMode) { data.Caret.PreserveSelection = true; triggerOffset = data.Caret.Offset - length; } else { if (data.SelectionRange.Offset < ctx.TriggerOffset) triggerOffset = ctx.TriggerOffset - data.SelectionRange.Length; data.DeleteSelectedText (); } length = 0; } // | in the completion text now marks the caret position int idx = completeWord.IndexOf ('|'); if (idx >= 0) { completeWord = completeWord.Remove (idx, 1); } triggerOffset += data.EnsureCaretIsNotVirtual (); if (blockMode) { using (var undo = data.OpenUndoGroup ()) { int minLine = data.MainSelection.MinLine; int maxLine = data.MainSelection.MaxLine; int column = triggerOffset - data.Document.GetLineByOffset (triggerOffset).Offset; for (int lineNumber = minLine; lineNumber <= maxLine; lineNumber++) { DocumentLine lineSegment = data.Document.GetLine (lineNumber); if (lineSegment == null) continue; int offset = lineSegment.Offset + column; data.Replace (offset, length, completeWord); } int minColumn = Math.Min (data.MainSelection.Anchor.Column, data.MainSelection.Lead.Column); data.MainSelection = data.MainSelection.WithRange ( new Mono.TextEditor.DocumentLocation (data.Caret.Line == minLine ? maxLine : minLine, minColumn), data.Caret.Location ); data.Document.CommitMultipleLineUpdate (data.MainSelection.MinLine, data.MainSelection.MaxLine); data.Caret.PreserveSelection = false; } } else { data.Replace (triggerOffset, length, completeWord); } data.Document.CommitLineUpdate (data.Caret.Line); if (idx >= 0) data.Caret.Offset = triggerOffset + idx; }
public static void MoveBlockDown (TextEditorData data) { int lineStart = data.Caret.Line; int lineEnd = data.Caret.Line; bool setSelection = lineStart != lineEnd; DocumentLocation anchor = DocumentLocation.Empty, lead = DocumentLocation.Empty; if (data.IsSomethingSelected) { setSelection = true; lineStart = data.MainSelection.MinLine; lineEnd = data.MainSelection.MaxLine; anchor = data.MainSelection.Anchor; lead = data.MainSelection.Lead; } if (lineStart <= 0) return; using (var undo = data.OpenUndoGroup ()) { //Mono.TextEditor.LineSegment startLine = data.Document.GetLine (lineStart); //int relCaretOffset = data.Caret.Offset - startLine.Offset; Mono.TextEditor.DocumentLine nextLine = data.Document.GetLine (lineEnd + 1); if (nextLine == null) return; string text = data.Document.GetTextAt (nextLine.Offset, nextLine.Length); List<TextLineMarker> prevLineMarkers = new List<TextLineMarker> (nextLine.Markers); nextLine.ClearMarker (); var loc = data.Caret.Location; for (int i = lineEnd + 1; i >= lineStart; i--) { DocumentLine cur = data.Document.GetLine (i); DocumentLine prev = data.Document.GetLine (i - 1); data.Replace (cur.Offset, cur.Length, i != lineStart ? data.Document.GetTextAt (prev.Offset, prev.Length) : text); data.Document.GetLine (i).ClearMarker (); foreach (TextLineMarker marker in (i != lineStart ? data.Document.GetLine (i - 1).Markers : prevLineMarkers)) { data.Document.GetLine (i).AddMarker (marker); } } data.Caret.Location = new DocumentLocation (loc.Line + 1, loc.Column); if (setSelection) data.SetSelection (anchor.Line + 1, anchor.Column, lead.Line + 1, lead.Column); } }
public static void Paste (TextEditorData data) { if (!data.CanEditSelection) return; using (var undo = data.OpenUndoGroup ()) { data.EnsureCaretIsNotVirtual (); PasteFrom (Clipboard.Get (CopyOperation.CLIPBOARD_ATOM), data, true, data.IsSomethingSelected ? data.SelectionRange.Offset : data.Caret.Offset); } }
public static void Delete(TextEditorData data) { if (!data.CanEditSelection) { return; } using (var undoGroup = data.OpenUndoGroup()) { if (data.IsSomethingSelected) { // case: zero width block selection if (data.MainSelection.SelectionMode == SelectionMode.Block && data.MainSelection.Anchor.Column == data.MainSelection.Lead.Column) { var col = data.MainSelection.Lead.Column; if (col <= DocumentLocation.MinColumn) { data.ClearSelection(); return; } bool preserve = data.Caret.PreserveSelection; data.Caret.PreserveSelection = true; col--; for (int lineNumber = data.MainSelection.MinLine; lineNumber <= data.MainSelection.MaxLine; lineNumber++) { DocumentLine lineSegment = data.Document.GetLine(lineNumber); if (col < lineSegment.Length) { data.Remove(lineSegment.Offset + col, 1); } } data.Caret.PreserveSelection = preserve; data.Document.CommitMultipleLineUpdate(data.MainSelection.MinLine, data.MainSelection.MaxLine); return; } data.DeleteSelectedText(data.MainSelection.SelectionMode != SelectionMode.Block); return; } if (data.Caret.Offset >= data.Document.TextLength) { return; } data.EnsureCaretIsNotVirtual(); DocumentLine line = data.Document.GetLine(data.Caret.Line); if (data.Caret.Column == line.Length + 1) { if (data.Caret.Line < data.Document.LineCount) { data.Remove(line.EndOffsetIncludingDelimiter - line.DelimiterLength, line.DelimiterLength); if (line.EndOffsetIncludingDelimiter == data.Document.TextLength) { line.UnicodeNewline = UnicodeNewline.Unknown; } } } else { data.Remove(data.Caret.Offset, 1); data.Document.CommitLineUpdate(data.Caret.Line); } data.FixVirtualIndentation(); } }
public static void Delete(TextEditorData data) { if (!data.CanEditSelection) { return; } using (var undoGroup = data.OpenUndoGroup()) { if (data.IsSomethingSelected) { // case: zero width block selection if (data.MainSelection.SelectionMode == SelectionMode.Block && data.MainSelection.Anchor.Column == data.MainSelection.Lead.Column) { var col = data.MainSelection.Lead.Column; if (col <= DocumentLocation.MinColumn) { data.ClearSelection(); return; } bool preserve = data.Caret.PreserveSelection; data.Caret.PreserveSelection = true; col--; var changes = new List <Microsoft.CodeAnalysis.Text.TextChange> (); for (int lineNumber = data.MainSelection.MinLine; lineNumber <= data.MainSelection.MaxLine; lineNumber++) { DocumentLine lineSegment = data.Document.GetLine(lineNumber); if (col < lineSegment.Length) { changes.Add(new Microsoft.CodeAnalysis.Text.TextChange(new Microsoft.CodeAnalysis.Text.TextSpan(lineSegment.Offset + col, 1), "")); } } data.Document.ApplyTextChanges(changes); data.Caret.PreserveSelection = preserve; data.Document.CommitMultipleLineUpdate(data.MainSelection.MinLine, data.MainSelection.MaxLine); return; } data.DeleteSelectedText(data.MainSelection.SelectionMode != SelectionMode.Block); return; } if (data.Caret.Offset >= data.Document.Length) { return; } data.EnsureCaretIsNotVirtual(); DocumentLine line = data.Document.GetLine(data.Caret.Line); if (data.Caret.Column == line.Length + 1) { if (data.Caret.Line < data.Document.LineCount) { var deletionLength = line.DelimiterLength; // smart backspace (delete indentation) if (data.Options.IndentStyle == IndentStyle.Smart || data.Options.IndentStyle == IndentStyle.Virtual) { var next = line.NextLine; if (next != null) { if (data.HasIndentationTracker) { var lineIndentation = next.GetIndentation(data.Document); if (lineIndentation.StartsWith(data.IndentationTracker.GetIndentationString(next.LineNumber))) { deletionLength += lineIndentation.Length; } } } } data.Remove(line.EndOffsetIncludingDelimiter - line.DelimiterLength, deletionLength); if (line.EndOffsetIncludingDelimiter == data.Document.Length) { line.UnicodeNewline = UnicodeNewline.Unknown; } } } else { var o = data.Caret.Offset; if (((ushort)data.GetCharAt(o) & CaretMoveActions.HighSurrogateMarker) == CaretMoveActions.HighSurrogateMarker) { data.Remove(o, 2); } else { data.Remove(o, 1); } data.Document.CommitLineUpdate(data.Caret.Line); } data.FixVirtualIndentation(); } }
public static void Backspace(TextEditorData data, Action <TextEditorData> removeCharBeforeCaret) { if (!data.CanEditSelection) { return; } DocumentLine line; bool smartBackspace = false; using (var undo = data.OpenUndoGroup()) { if (data.IsSomethingSelected) { var visualAnchorLocation = data.LogicalToVisualLocation(data.MainSelection.Anchor); var visualLeadLocation = data.LogicalToVisualLocation(data.MainSelection.Lead); // case: zero width block selection if (data.MainSelection.SelectionMode == SelectionMode.Block && visualAnchorLocation.Column == visualLeadLocation.Column) { var col = data.MainSelection.Lead.Column; if (col <= DocumentLocation.MinColumn) { data.ClearSelection(); return; } bool preserve = data.Caret.PreserveSelection; data.Caret.PreserveSelection = true; var changes = new List <Microsoft.CodeAnalysis.Text.TextChange> (); for (int lineNumber = data.MainSelection.MinLine; lineNumber <= data.MainSelection.MaxLine; lineNumber++) { var lineSegment = data.Document.GetLine(lineNumber); int insertOffset = lineSegment.GetLogicalColumn(data, visualAnchorLocation.Column - 1) - 1; changes.Add(new Microsoft.CodeAnalysis.Text.TextChange(new Microsoft.CodeAnalysis.Text.TextSpan(lineSegment.Offset + insertOffset, 1), "")); } data.Document.ApplyTextChanges(changes); var visualColumn = data.GetLine(data.Caret.Location.Line).GetVisualColumn(data, col - 1); data.MainSelection = new MonoDevelop.Ide.Editor.Selection( new DocumentLocation(data.MainSelection.Anchor.Line, data.GetLine(data.MainSelection.Anchor.Line).GetLogicalColumn(data, visualColumn)), new DocumentLocation(data.MainSelection.Lead.Line, data.GetLine(data.MainSelection.Lead.Line).GetLogicalColumn(data, visualColumn)), SelectionMode.Block ); data.Caret.PreserveSelection = preserve; data.Document.CommitMultipleLineUpdate(data.MainSelection.MinLine, data.MainSelection.MaxLine); return; } data.DeleteSelectedText(data.MainSelection.SelectionMode != SelectionMode.Block); return; } if (data.Caret.Line == DocumentLocation.MinLine && data.Caret.Column == DocumentLocation.MinColumn) { return; } // Virtual indentation needs to be fixed before to have the same behavior // if it's there or not (otherwise user has to press multiple backspaces in some cases) data.EnsureCaretIsNotVirtual(); line = data.Document.GetLine(data.Caret.Line); // smart backspace (delete indentation) if (data.HasIndentationTracker && (data.IndentationTracker.SupportedFeatures & IndentationTrackerFeatures.SmartBackspace) != 0 && (data.Options.IndentStyle == IndentStyle.Smart || data.Options.IndentStyle == IndentStyle.Virtual) && data.Options.SmartBackspace) { if (data.Caret.Column == data.GetVirtualIndentationColumn(data.Caret.Location)) { bool isAllIndent = line.GetIndentation(data.Document).Length == data.Caret.Column - 1; if (isAllIndent) { if (!data.Options.GenerateFormattingUndoStep) { SmartBackspace(data, line); return; } smartBackspace = true; } } } // normal backspace. if (data.Caret.Column > line.Length + 1) { data.Caret.Column = line.Length + 1; } else if (data.Caret.Offset == line.Offset) { DocumentLine lineAbove = data.Document.GetLine(data.Caret.Line - 1); if (lineAbove.Length == 0 && data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual) { data.Caret.Location = new DocumentLocation(data.Caret.Line - 1, data.GetVirtualIndentationColumn(data.Caret.Line - 1, 1)); data.Replace(lineAbove.EndOffsetIncludingDelimiter - lineAbove.DelimiterLength, lineAbove.DelimiterLength, data.GetIndentationString(data.Caret.Line - 1, 1)); } else { data.Remove(lineAbove.EndOffsetIncludingDelimiter - lineAbove.DelimiterLength, lineAbove.DelimiterLength); } } else { removeCharBeforeCaret(data); } // Needs to be fixed after, the line may just contain the indentation data.FixVirtualIndentation(); } if (data.Options.GenerateFormattingUndoStep && smartBackspace) { using (var undo = data.OpenUndoGroup()) { data.EnsureCaretIsNotVirtual(); SmartBackspace(data, line); } } }
public static void InsertNewLineAtEnd (TextEditorData data) { if (!data.CanEditSelection) return; using (var undoGroup = data.OpenUndoGroup ()) { DocumentLine line = data.Document.GetLine (data.Caret.Line); data.Caret.Column = line.Length + 1; InsertNewLine (data); } }
public static void DuplicateLine (TextEditorData data) { using (var undoGroup = data.OpenUndoGroup ()) { if (data.IsSomethingSelected) { var selectedText = data.SelectedText; data.ClearSelection (); data.InsertAtCaret (selectedText); } else { DocumentLine line = data.Document.GetLine (data.Caret.Line); if (line == null) return; if (line.DelimiterLength == 0) { data.Insert (line.Offset, data.GetTextAt (line.SegmentIncludingDelimiter) + data.EolMarker); } else { data.Insert (line.Offset, data.GetTextAt (line.SegmentIncludingDelimiter)); } } } }
/// <summary> /// Transpose characters (Emacs C-t) /// </summary> public static void TransposeCharacters (TextEditorData data) { if (data.Caret.Offset == 0) return; DocumentLine line = data.Document.GetLine (data.Caret.Line); if (line == null) return; using (var undoGroup = data.OpenUndoGroup ()) { int transposeOffset = data.Caret.Offset - 1; char ch; if (data.Caret.Column == 0) { DocumentLine lineAbove = data.Document.GetLine (data.Caret.Line - 1); if (lineAbove.Length == 0 && line.Length == 0) return; if (line.Length != 0) { ch = data.Document.GetCharAt (data.Caret.Offset); data.Remove (data.Caret.Offset, 1); data.Insert (lineAbove.Offset + lineAbove.Length, ch.ToString ()); data.Document.CommitLineUpdate (data.Caret.Line - 1); return; } int lastCharOffset = lineAbove.Offset + lineAbove.Length - 1; ch = data.Document.GetCharAt (lastCharOffset); data.Remove (lastCharOffset, 1); data.InsertAtCaret (ch.ToString ()); return; } int offset = data.Caret.Offset; if (data.Caret.Column >= line.Length + 1) { offset = line.Offset + line.Length - 1; transposeOffset = offset - 1; // case one char in line: if (transposeOffset < line.Offset) { DocumentLine lineAbove = data.Document.GetLine (data.Caret.Line - 1); transposeOffset = lineAbove.Offset + lineAbove.Length; ch = data.Document.GetCharAt (offset); data.Remove (offset, 1); data.Insert (transposeOffset, ch.ToString ()); data.Caret.Offset = line.Offset; data.Document.CommitLineUpdate (data.Caret.Line - 1); return; } } ch = data.Document.GetCharAt (offset); data.Replace (offset, 1, data.Document.GetCharAt (transposeOffset).ToString ()); data.Replace (transposeOffset, 1, ch.ToString ()); if (data.Caret.Column < line.Length + 1) data.Caret.Offset = offset + 1; } }
static void NewLineSmartIndent (TextEditorData data) { using (var undo = data.OpenUndoGroup ()) { data.EnsureCaretIsNotVirtual (); data.InsertAtCaret (data.EolMarker); data.InsertAtCaret (data.GetIndentationString (data.Caret.Location)); } }
static int PastePlainText (TextEditorData data, int offset, string text) { int inserted; using (var undo = data.OpenUndoGroup ()) { var version = data.Document.Version; data.DeleteSelectedText (!data.IsSomethingSelected || data.MainSelection.SelectionMode != SelectionMode.Block); data.EnsureCaretIsNotVirtual (); offset = version.MoveOffsetTo (data.Document.Version, offset); inserted = data.Insert (offset, text); } data.PasteText (offset, text, inserted); return inserted; }
public static void Backspace (TextEditorData data, Action<TextEditorData> removeCharBeforeCaret) { if (!data.CanEditSelection) return; using (var undo = data.OpenUndoGroup ()) { if (data.IsSomethingSelected) { var visualAnchorLocation = data.LogicalToVisualLocation (data.MainSelection.Anchor); var visualLeadLocation = data.LogicalToVisualLocation (data.MainSelection.Lead); // case: zero width block selection if (data.MainSelection.SelectionMode == SelectionMode.Block && visualAnchorLocation.Column == visualLeadLocation.Column) { var col = data.MainSelection.Lead.Column; if (col <= DocumentLocation.MinColumn) { data.ClearSelection (); return; } bool preserve = data.Caret.PreserveSelection; data.Caret.PreserveSelection = true; for (int lineNumber = data.MainSelection.MinLine; lineNumber <= data.MainSelection.MaxLine; lineNumber++) { var lineSegment = data.Document.GetLine (lineNumber); int insertOffset = lineSegment.GetLogicalColumn (data, visualAnchorLocation.Column - 1) - 1; data.Remove (lineSegment.Offset + insertOffset, 1); } var visualColumn = data.GetLine (data.Caret.Location.Line).GetVisualColumn (data, col - 1); data.MainSelection = new Selection ( new DocumentLocation (data.MainSelection.Anchor.Line, data.GetLine (data.MainSelection.Anchor.Line).GetLogicalColumn (data, visualColumn)), new DocumentLocation (data.MainSelection.Lead.Line, data.GetLine (data.MainSelection.Lead.Line).GetLogicalColumn (data, visualColumn)), SelectionMode.Block ); data.Caret.PreserveSelection = preserve; data.Document.CommitMultipleLineUpdate (data.MainSelection.MinLine, data.MainSelection.MaxLine); return; } data.DeleteSelectedText (data.MainSelection.SelectionMode != SelectionMode.Block); return; } if (data.Caret.Line == DocumentLocation.MinLine && data.Caret.Column == DocumentLocation.MinColumn) return; // Virtual indentation needs to be fixed before to have the same behavior // if it's there or not (otherwise user has to press multiple backspaces in some cases) data.EnsureCaretIsNotVirtual (); DocumentLine line = data.Document.GetLine (data.Caret.Line); if (data.Caret.Column > line.Length + 1) { data.Caret.Column = line.Length + 1; } else if (data.Caret.Offset == line.Offset) { DocumentLine lineAbove = data.Document.GetLine (data.Caret.Line - 1); if (lineAbove.Length == 0 && data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual) { data.Caret.Location = new DocumentLocation (data.Caret.Line - 1, data.IndentationTracker.GetVirtualIndentationColumn (data.Caret.Line - 1, 1)); data.Replace (lineAbove.EndOffsetIncludingDelimiter - lineAbove.DelimiterLength, lineAbove.DelimiterLength, data.IndentationTracker.GetIndentationString (data.Caret.Line - 1, 1)); } else { data.Remove (lineAbove.EndOffsetIncludingDelimiter - lineAbove.DelimiterLength, lineAbove.DelimiterLength); } } else { removeCharBeforeCaret (data); } // Needs to be fixed after, the line may just contain the indentation data.FixVirtualIndentation (); } }
public static void Delete (TextEditorData data) { if (!data.CanEditSelection) return; using (var undoGroup = data.OpenUndoGroup ()) { if (data.IsSomethingSelected) { // case: zero width block selection if (data.MainSelection.SelectionMode == SelectionMode.Block && data.MainSelection.Anchor.Column == data.MainSelection.Lead.Column) { var col = data.MainSelection.Lead.Column; if (col <= DocumentLocation.MinColumn) { data.ClearSelection (); return; } bool preserve = data.Caret.PreserveSelection; data.Caret.PreserveSelection = true; col--; for (int lineNumber = data.MainSelection.MinLine; lineNumber <= data.MainSelection.MaxLine; lineNumber++) { DocumentLine lineSegment = data.Document.GetLine (lineNumber); if (col < lineSegment.Length) data.Remove (lineSegment.Offset + col, 1); } data.Caret.PreserveSelection = preserve; data.Document.CommitMultipleLineUpdate (data.MainSelection.MinLine, data.MainSelection.MaxLine); return; } data.DeleteSelectedText (data.MainSelection.SelectionMode != SelectionMode.Block); return; } if (data.Caret.Offset >= data.Document.TextLength) return; data.EnsureCaretIsNotVirtual (); DocumentLine line = data.Document.GetLine (data.Caret.Line); if (data.Caret.Column == line.Length + 1) { if (data.Caret.Line < data.Document.LineCount) { data.Remove (line.EndOffsetIncludingDelimiter - line.DelimiterLength, line.DelimiterLength); if (line.EndOffsetIncludingDelimiter == data.Document.TextLength) line.UnicodeNewline = UnicodeNewline.Unknown; } } else { data.Remove (data.Caret.Offset, 1); data.Document.CommitLineUpdate (data.Caret.Line); } data.FixVirtualIndentation (); } }
static int PastePlainText (TextEditorData data, int offset, string text, bool preserveSelection = false) { int inserted = 0; using (var undo = data.OpenUndoGroup ()) { var version = data.Document.Version; if (!preserveSelection) data.DeleteSelectedText (!data.IsSomethingSelected || data.MainSelection.SelectionMode != SelectionMode.Block); data.EnsureCaretIsNotVirtual (); if (data.IsSomethingSelected && data.MainSelection.SelectionMode == SelectionMode.Block) { var selection = data.MainSelection; var visualInsertLocation = data.LogicalToVisualLocation (selection.Anchor); for (int lineNumber = selection.MinLine; lineNumber <= selection.MaxLine; lineNumber++) { var lineSegment = data.GetLine (lineNumber); int insertOffset = lineSegment.GetLogicalColumn (data, visualInsertLocation.Column) - 1; string textToInsert; if (lineSegment.Length < insertOffset) { int visualLastColumn = lineSegment.GetVisualColumn (data, lineSegment.Length + 1); int charsToInsert = visualInsertLocation.Column - visualLastColumn; int spaceCount = charsToInsert % data.Options.TabSize; textToInsert = new string ('\t', (charsToInsert - spaceCount) / data.Options.TabSize) + new string (' ', spaceCount) + text; insertOffset = lineSegment.Length; } else { textToInsert = text; } inserted = data.Insert (lineSegment.Offset + insertOffset, textToInsert); } } else { offset = version.MoveOffsetTo (data.Document.Version, offset); inserted = data.PasteText (offset, text); } } return inserted; }
public static void Left(TextEditorData data) { using (var undo = data.OpenUndoGroup()) { if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection) { data.Caret.Offset = System.Math.Min(data.SelectionAnchor, data.Caret.Offset); data.ClearSelection(); return; } if (data.Caret.Column > DocumentLocation.MinColumn) { DocumentLine line = data.Document.GetLine(data.Caret.Line); if (data.Caret.Column > line.Length + 1) { if (data.Caret.AllowCaretBehindLineEnd) { data.Caret.Column--; } else { data.Caret.Column = line.Length + 1; } } else { int offset = data.Caret.Offset - 1; bool foundFolding = false; foreach (var folding in data.Document.GetFoldingsFromOffset(offset).Where(f => f.IsCollapsed && f.Offset < offset)) { offset = System.Math.Min(offset, folding.Offset); foundFolding = true; } if (!foundFolding) { var layout = data.Parent?.TextViewMargin?.GetLayout(line); if (layout != null && data.Caret.Column < line.Length) { uint curIndex = 0, byteIndex = 0; int utf8ByteIndex = (int)layout.TranslateToUTF8Index((uint)(offset - line.Offset), ref curIndex, ref byteIndex); layout.Layout.GetCursorPos(utf8ByteIndex, out var strong_pos, out var weak_pos); if (strong_pos.X != weak_pos.X) { offset--; } } } data.Caret.Offset = offset; } } else if (data.Caret.Line > DocumentLocation.MinLine) { DocumentLine prevLine = data.Document.GetLine(data.Caret.Line - 1); var nextLocation = new DocumentLocation(data.Caret.Line - 1, prevLine.Length + 1); if (data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual && nextLocation.Column == DocumentLocation.MinColumn) { nextLocation = new DocumentLocation(data.Caret.Line - 1, data.GetVirtualIndentationColumn(nextLocation)); } data.Caret.Location = nextLocation; } var curOffset = data.Caret.Offset; if (curOffset > 0 && curOffset < data.Length && IsLowSurrogateMarkerSet(data.GetCharAt(curOffset))) { data.Caret.Offset--; } } }
public static void Right(TextEditorData data) { using (var undo = data.OpenUndoGroup()) { if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection) { data.Caret.Offset = System.Math.Max(data.SelectionAnchor, data.Caret.Offset); data.ClearSelection(); return; } DocumentLine line = data.Document.GetLine(data.Caret.Line); IEnumerable <FoldSegment> foldings = data.Document.GetStartFoldings(line); FoldSegment segment = null; foreach (FoldSegment folding in foldings) { if (folding.IsFolded && folding.Column == data.Caret.Column) { segment = folding; break; } } if (segment != null) { data.Caret.Offset = segment.EndOffset; return; } if (data.Caret.Column >= line.Length + 1) { int nextColumn; if (data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual && data.Caret.Column == DocumentLocation.MinColumn) { nextColumn = data.GetVirtualIndentationColumn(data.Caret.Location); } else if (data.Caret.AllowCaretBehindLineEnd) { nextColumn = data.Caret.Column + 1; } else { nextColumn = line.Length + 1; } if (data.Caret.Column < nextColumn) { data.Caret.Column = nextColumn; } else { if (data.Caret.Line < data.LineCount) { data.Caret.Location = new DocumentLocation(data.Caret.Line + 1, DocumentLocation.MinColumn); } } } else { data.Caret.Column++; } } }
static int PasteFrom(Clipboard clipboard, TextEditorData data, bool preserveSelection, int insertionOffset, bool preserveState) { int result = -1; if (!data.CanEdit(data.Document.OffsetToLineNumber(insertionOffset))) { return(result); } if (clipboard.WaitIsTargetAvailable(CopyOperation.MD_ATOM)) { clipboard.RequestContents(CopyOperation.MD_ATOM, (ClipboardReceivedFunc) delegate(Clipboard clp, SelectionData selectionData) { if (selectionData.Length > 0) { byte[] selBytes = selectionData.Data; var upperBound = System.Math.Max(0, System.Math.Min(selBytes [1], selBytes.Length - 2)); byte[] copyData = new byte[upperBound]; Array.Copy(selBytes, 2, copyData, 0, copyData.Length); var rawTextOffset = 1 + 1 + copyData.Length; string text = Encoding.UTF8.GetString(selBytes, rawTextOffset, selBytes.Length - rawTextOffset); bool pasteBlock = (selBytes [0] & 1) == 1; bool pasteLine = (selBytes [0] & 2) == 2; if (pasteBlock) { using (var undo = data.OpenUndoGroup()) { var version = data.Document.Version; if (!preserveSelection) { data.DeleteSelectedText(!data.IsSomethingSelected || data.MainSelection.SelectionMode != MonoDevelop.Ide.Editor.SelectionMode.Block); } int startLine = data.Caret.Line; data.EnsureCaretIsNotVirtual(); insertionOffset = version.MoveOffsetTo(data.Document.Version, insertionOffset); data.Caret.PreserveSelection = true; var lines = new List <string> (); int offset = 0; while (true) { var delimiter = LineSplitter.NextDelimiter(text, offset); if (delimiter.IsInvalid) { break; } int delimiterEndOffset = delimiter.EndOffset; lines.Add(text.Substring(offset, delimiter.Offset - offset)); offset = delimiterEndOffset; } if (offset < text.Length) { lines.Add(text.Substring(offset, text.Length - offset)); } int lineNr = data.Document.OffsetToLineNumber(insertionOffset); int col = insertionOffset - data.Document.GetLine(lineNr).Offset; int visCol = data.Document.GetLine(lineNr).GetVisualColumn(data, col); DocumentLine curLine; int lineCol = col; result = 0; for (int i = 0; i < lines.Count; i++) { while (data.Document.LineCount <= lineNr + i) { data.Insert((int)data.Document.Length, Environment.NewLine); result += Environment.NewLine.Length; } curLine = data.Document.GetLine(lineNr + i); if (lines [i].Length > 0) { lineCol = curLine.GetLogicalColumn(data, visCol); if (curLine.Length + 1 < lineCol) { result += lineCol - curLine.Length; data.Insert(curLine.Offset + curLine.Length, new string (' ', lineCol - curLine.Length)); } data.Insert(curLine.Offset + lineCol, lines [i]); result += lines [i].Length; } if (!preserveState) { data.Caret.Offset = curLine.Offset + lineCol + lines [i].Length; } } if (!preserveState) { data.ClearSelection(); } data.FixVirtualIndentation(startLine); data.Caret.PreserveSelection = false; } } else if (pasteLine) { using (var undo = data.OpenUndoGroup()) { if (!preserveSelection) { data.DeleteSelectedText(!data.IsSomethingSelected || data.MainSelection.SelectionMode != MonoDevelop.Ide.Editor.SelectionMode.Block); } data.EnsureCaretIsNotVirtual(); data.Caret.PreserveSelection = true; result = text.Length; DocumentLine curLine = data.Document.GetLine(data.Caret.Line); result = PastePlainText(data, curLine.Offset, text + data.EolMarker, preserveSelection, copyData); if (!preserveState) { data.ClearSelection(); } data.Caret.PreserveSelection = false; data.FixVirtualIndentation(curLine.LineNumber); } } else { result = PastePlainText(data, insertionOffset, text, preserveSelection, copyData); } } }); // we got MD_ATOM text - no need to request text. (otherwise buffer may get copied twice). return(result); } if (result < 0 && clipboard.WaitIsTextAvailable()) { clipboard.RequestText(delegate(Clipboard clp, string text) { if (string.IsNullOrEmpty(text)) { return; } result = PastePlainText(data, insertionOffset, text, preserveSelection); }); } return(result); }
public static void PreviousSubword(TextEditorData data) { using (var undo = data.OpenUndoGroup()) { data.Caret.Offset = data.FindPrevSubwordOffset(data.Caret.Offset); } }
public static void IndentSelection (TextEditorData data) { if (!data.IsSomethingSelected) return; int startLineNr, endLineNr; GetSelectedLines (data, out startLineNr, out endLineNr); var anchor = data.MainSelection.Anchor; var lead = data.MainSelection.Lead; var indentationString = data.Options.IndentationString; using (var undo = data.OpenUndoGroup (OperationType.Format)) { foreach (DocumentLine line in data.SelectedLines) { if (data.Options.IndentStyle == IndentStyle.Virtual && line.Length == 0) continue; data.Insert (line.Offset, indentationString); } } int chars = indentationString.Length; var leadCol = lead.Column > 1 || lead < anchor ? lead.Column + chars : 1; var anchorCol = anchor.Column > 1 || anchor < lead ? anchor.Column + chars : 1; data.SetSelection (anchor.Line, anchorCol, lead.Line, leadCol); data.Document.RequestUpdate (new MultipleLineUpdate (startLineNr, endLineNr)); data.Document.CommitDocumentUpdate (); }
public static void Backspace(TextEditorData data, Action <TextEditorData> removeCharBeforeCaret) { if (!data.CanEditSelection) { return; } using (var undo = data.OpenUndoGroup()) { if (data.IsSomethingSelected) { var visualAnchorLocation = data.LogicalToVisualLocation(data.MainSelection.Anchor); var visualLeadLocation = data.LogicalToVisualLocation(data.MainSelection.Lead); // case: zero width block selection if (data.MainSelection.SelectionMode == SelectionMode.Block && visualAnchorLocation.Column == visualLeadLocation.Column) { var col = data.MainSelection.Lead.Column; if (col <= DocumentLocation.MinColumn) { data.ClearSelection(); return; } bool preserve = data.Caret.PreserveSelection; data.Caret.PreserveSelection = true; for (int lineNumber = data.MainSelection.MinLine; lineNumber <= data.MainSelection.MaxLine; lineNumber++) { var lineSegment = data.Document.GetLine(lineNumber); int insertOffset = lineSegment.GetLogicalColumn(data, visualAnchorLocation.Column - 1) - 1; data.Remove(lineSegment.Offset + insertOffset, 1); } var visualColumn = data.GetLine(data.Caret.Location.Line).GetVisualColumn(data, col - 1); data.MainSelection = new Selection( new DocumentLocation(data.MainSelection.Anchor.Line, data.GetLine(data.MainSelection.Anchor.Line).GetLogicalColumn(data, visualColumn)), new DocumentLocation(data.MainSelection.Lead.Line, data.GetLine(data.MainSelection.Lead.Line).GetLogicalColumn(data, visualColumn)), SelectionMode.Block ); data.Caret.PreserveSelection = preserve; data.Document.CommitMultipleLineUpdate(data.MainSelection.MinLine, data.MainSelection.MaxLine); return; } data.DeleteSelectedText(data.MainSelection.SelectionMode != SelectionMode.Block); return; } if (data.Caret.Line == DocumentLocation.MinLine && data.Caret.Column == DocumentLocation.MinColumn) { return; } // Virtual indentation needs to be fixed before to have the same behavior // if it's there or not (otherwise user has to press multiple backspaces in some cases) data.EnsureCaretIsNotVirtual(); DocumentLine line = data.Document.GetLine(data.Caret.Line); if (data.Caret.Column > line.Length + 1) { data.Caret.Column = line.Length + 1; } else if (data.Caret.Offset == line.Offset) { DocumentLine lineAbove = data.Document.GetLine(data.Caret.Line - 1); if (lineAbove.Length == 0 && data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual) { data.Caret.Location = new DocumentLocation(data.Caret.Line - 1, data.IndentationTracker.GetVirtualIndentationColumn(data.Caret.Line - 1, 1)); data.Replace(lineAbove.EndOffsetIncludingDelimiter - lineAbove.DelimiterLength, lineAbove.DelimiterLength, data.IndentationTracker.GetIndentationString(data.Caret.Line - 1, 1)); } else { data.Remove(lineAbove.EndOffsetIncludingDelimiter - lineAbove.DelimiterLength, lineAbove.DelimiterLength); } } else { removeCharBeforeCaret(data); } // Needs to be fixed after, the line may just contain the indentation data.FixVirtualIndentation(); } }
public static void InsertNewLine (TextEditorData data) { if (!data.CanEditSelection) return; using (var undo = data.OpenUndoGroup ()) { if (data.IsSomethingSelected) { var end = data.MainSelection.End; data.DeleteSelectedText (); if (end.Column == 1) { CaretMoveActions.InternalCaretMoveHome (data, true, false); return; } } switch (data.Options.IndentStyle) { case IndentStyle.None: data.InsertAtCaret (data.EolMarker); break; case IndentStyle.Auto: data.EnsureCaretIsNotVirtual (); var indent = data.Document.GetLineIndent (data.Caret.Line); data.InsertAtCaret (data.EolMarker); data.EnsureCaretIsNotVirtual (); if (data.GetLine (data.Caret.Line).Length == 0) data.InsertAtCaret (indent); break; case IndentStyle.Smart: if (!data.HasIndentationTracker) goto case IndentStyle.Auto; NewLineSmartIndent (data); break; case IndentStyle.Virtual: if (!data.HasIndentationTracker) goto case IndentStyle.Auto; var oldLine = data.Caret.Line; var curLine = data.GetLine (oldLine); var indentCol = data.GetVirtualIndentationColumn (data.Caret.Location); if (curLine.Length >= data.Caret.Column) { NewLineSmartIndent (data); data.FixVirtualIndentation (); data.FixVirtualIndentation (oldLine); break; } data.Insert (data.Caret.Offset, data.EolMarker); data.FixVirtualIndentation (oldLine); data.Caret.Column = indentCol; break; default: throw new ArgumentOutOfRangeException (); } } }
static int PasteFrom (Clipboard clipboard, TextEditorData data, bool preserveSelection, int insertionOffset, bool preserveState) { int result = -1; if (!data.CanEdit (data.Document.OffsetToLineNumber (insertionOffset))) return result; if (clipboard.WaitIsTargetAvailable (CopyOperation.MD_ATOM)) { clipboard.RequestContents (CopyOperation.MD_ATOM, delegate(Clipboard clp, SelectionData selectionData) { if (selectionData.Length > 0) { byte[] selBytes = selectionData.Data; string text = System.Text.Encoding.UTF8.GetString (selBytes, 1, selBytes.Length - 1); bool pasteBlock = (selBytes [0] & 1) == 1; bool pasteLine = (selBytes [0] & 2) == 2; using (var undo = data.OpenUndoGroup ()) { if (preserveSelection && data.IsSomethingSelected) data.DeleteSelectedText (); data.Caret.PreserveSelection = true; if (pasteBlock) { string[] lines = text.Split ('\r'); int lineNr = data.Document.OffsetToLineNumber (insertionOffset); int col = insertionOffset - data.Document.GetLine (lineNr).Offset; int visCol = data.Document.GetLine (lineNr).GetVisualColumn (data, col); DocumentLine curLine; int lineCol = col; result = 0; for (int i = 0; i < lines.Length; i++) { while (data.Document.LineCount <= lineNr + i) { data.Insert (data.Document.TextLength, Environment.NewLine); result += Environment.NewLine.Length; } curLine = data.Document.GetLine (lineNr + i); if (lines [i].Length > 0) { lineCol = curLine.GetLogicalColumn (data, visCol); if (curLine.Length + 1 < lineCol) { result += lineCol - curLine.Length; data.Insert (curLine.Offset + curLine.Length, new string (' ', lineCol - curLine.Length)); } data.Insert (curLine.Offset + lineCol, lines [i]); result += lines [i].Length; } if (!preserveState) data.Caret.Offset = curLine.Offset + lineCol + lines [i].Length; } } else if (pasteLine) { result = text.Length; DocumentLine curLine = data.Document.GetLine (data.Caret.Line); data.Insert (curLine.Offset, text + data.EolMarker); } else { int offset = data.Caret.Offset; data.InsertAtCaret (text); data.PasteText (offset, text, data.Caret.Offset - offset); } /* data.MainSelection = new Selection (data.Document.OffsetToLocation (insertionOffset), data.Caret.Location, lines.Length > 1 ? SelectionMode.Block : SelectionMode.Normal);*/ if (!preserveState) data.ClearSelection (); data.Caret.PreserveSelection = false; } } }); // we got MD_ATOM text - no need to request text. (otherwise buffer may get copied twice). return result; } if (result < 0 && clipboard.WaitIsTextAvailable ()) { clipboard.RequestText (delegate(Clipboard clp, string text) { if (string.IsNullOrEmpty (text)) return; using (var undo = data.OpenUndoGroup ()) { int caretPos = data.Caret.Offset; if (data.IsSomethingSelected && data.MainSelection.SelectionMode == SelectionMode.Block) { data.Caret.PreserveSelection = true; data.DeleteSelectedText (false); int textLength = 0; int minLine = data.MainSelection.MinLine; int maxLine = data.MainSelection.MaxLine; var visualInsertLocation = data.LogicalToVisualLocation (data.Caret.Location); for (int lineNumber = minLine; lineNumber <= maxLine; lineNumber++) { DocumentLine lineSegment = data.GetLine (lineNumber); int insertOffset = lineSegment.GetLogicalColumn (data, visualInsertLocation.Column) - 1; if (lineSegment.Length < insertOffset) { int visualLastColumn = lineSegment.GetVisualColumn (data, lineSegment.Length + 1); int charsToInsert = visualInsertLocation.Column - visualLastColumn; int spaceCount = charsToInsert % data.Options.TabSize; string textToInsert = new string ('\t', (charsToInsert - spaceCount) / data.Options.TabSize) + new string (' ', spaceCount) + text; insertOffset = lineSegment.Length; int insertedChars = data.Insert (lineSegment.Offset + insertOffset, textToInsert); data.PasteText (lineSegment.Offset + insertOffset, textToInsert, insertedChars); } else { textLength = data.Insert (lineSegment.Offset + insertOffset, text); data.PasteText (lineSegment.Offset + insertOffset, text, textLength); } } data.MainSelection.Anchor = new DocumentLocation (System.Math.Max (DocumentLocation.MinLine, data.Caret.Line == minLine ? maxLine : minLine), System.Math.Max (DocumentLocation.MinColumn, data.Caret.Column - textLength)); data.MainSelection.Lead = new DocumentLocation (data.Caret.Line, data.Caret.Column); data.Caret.PreserveSelection = false; data.Document.CommitMultipleLineUpdate (data.MainSelection.MinLine, data.MainSelection.MaxLine); } else { TextSegment selection = data.SelectionRange; if (preserveSelection && data.IsSomethingSelected) data.DeleteSelectedText (); data.Caret.PreserveSelection = true; //int oldLine = data.Caret.Line; int textLength = data.Insert (insertionOffset, text); result = textLength; if (data.IsSomethingSelected && data.SelectionRange.Offset >= insertionOffset) data.SelectionRange = new TextSegment (data.SelectionRange.Offset + textLength, data.SelectionRange.Length); if (data.IsSomethingSelected && data.MainSelection.GetAnchorOffset (data) >= insertionOffset) data.MainSelection.Anchor = data.Document.OffsetToLocation (data.MainSelection.GetAnchorOffset (data) + textLength); data.Caret.PreserveSelection = false; if (!preserveState) { } else { if (!selection.IsInvalid) { int offset = selection.Offset; if (offset >= insertionOffset) offset += textLength; data.SelectionRange = new TextSegment (offset, selection.Length); } } data.PasteText (insertionOffset, text, textLength); } } }); } return result; }
public static void InsertNewLine(TextEditorData data) { if (!data.CanEditSelection) { return; } using (var undo = data.OpenUndoGroup()) { if (data.IsSomethingSelected) { var end = data.MainSelection.End; data.DeleteSelectedText(); if (end.Column == 1) { CaretMoveActions.InternalCaretMoveHome(data, true, false); return; } } switch (data.Options.IndentStyle) { case IndentStyle.None: data.InsertAtCaret(data.EolMarker); break; case IndentStyle.Auto: data.EnsureCaretIsNotVirtual(); var indent = data.Document.GetLineIndent(data.Caret.Line); data.InsertAtCaret(data.EolMarker); data.EnsureCaretIsNotVirtual(); if (data.GetLine(data.Caret.Line).Length == 0) { data.InsertAtCaret(indent); } break; case IndentStyle.Smart: if (!data.HasIndentationTracker) { goto case IndentStyle.Auto; } NewLineSmartIndent(data); break; case IndentStyle.Virtual: if (!data.HasIndentationTracker) { goto case IndentStyle.Auto; } var oldLine = data.Caret.Line; var curLine = data.GetLine(oldLine); var indentCol = data.GetVirtualIndentationColumn(data.Caret.Location); if (curLine.Length >= data.Caret.Column) { NewLineSmartIndent(data); data.FixVirtualIndentation(); data.FixVirtualIndentation(oldLine); break; } data.Insert(data.Caret.Offset, data.EolMarker); data.FixVirtualIndentation(oldLine); data.Caret.Column = indentCol; break; default: throw new ArgumentOutOfRangeException(); } } }
static int PasteFrom (Clipboard clipboard, TextEditorData data, bool preserveSelection, int insertionOffset, bool preserveState) { int result = -1; if (!data.CanEdit (data.Document.OffsetToLineNumber (insertionOffset))) return result; if (clipboard.WaitIsTargetAvailable (CopyOperation.MD_ATOM)) { clipboard.RequestContents (CopyOperation.MD_ATOM, delegate(Clipboard clp, SelectionData selectionData) { if (selectionData.Length > 0) { byte[] selBytes = selectionData.Data; string text = System.Text.Encoding.UTF8.GetString (selBytes, 1, selBytes.Length - 1); bool pasteBlock = (selBytes [0] & 1) == 1; bool pasteLine = (selBytes [0] & 2) == 2; // var clearSelection = data.IsSomethingSelected ? data.MainSelection.SelectionMode != SelectionMode.Block : true; if (pasteBlock) { using (var undo = data.OpenUndoGroup ()) { var version = data.Document.Version; data.DeleteSelectedText (!data.IsSomethingSelected || data.MainSelection.SelectionMode != SelectionMode.Block); data.EnsureCaretIsNotVirtual (); insertionOffset = version.MoveOffsetTo (data.Document.Version, insertionOffset); data.Caret.PreserveSelection = true; string[] lines = text.Split ('\r'); int lineNr = data.Document.OffsetToLineNumber (insertionOffset); int col = insertionOffset - data.Document.GetLine (lineNr).Offset; int visCol = data.Document.GetLine (lineNr).GetVisualColumn (data, col); DocumentLine curLine; int lineCol = col; result = 0; for (int i = 0; i < lines.Length; i++) { while (data.Document.LineCount <= lineNr + i) { data.Insert (data.Document.TextLength, Environment.NewLine); result += Environment.NewLine.Length; } curLine = data.Document.GetLine (lineNr + i); if (lines [i].Length > 0) { lineCol = curLine.GetLogicalColumn (data, visCol); if (curLine.Length + 1 < lineCol) { result += lineCol - curLine.Length; data.Insert (curLine.Offset + curLine.Length, new string (' ', lineCol - curLine.Length)); } data.Insert (curLine.Offset + lineCol, lines [i]); result += lines [i].Length; } if (!preserveState) data.Caret.Offset = curLine.Offset + lineCol + lines [i].Length; } if (!preserveState) data.ClearSelection (); data.Caret.PreserveSelection = false; } } else if (pasteLine) { using (var undo = data.OpenUndoGroup ()) { data.DeleteSelectedText (!data.IsSomethingSelected || data.MainSelection.SelectionMode != SelectionMode.Block); data.EnsureCaretIsNotVirtual (); data.Caret.PreserveSelection = true; result = text.Length; DocumentLine curLine = data.Document.GetLine (data.Caret.Line); data.Insert (curLine.Offset, text + data.EolMarker); if (!preserveState) data.ClearSelection (); data.Caret.PreserveSelection = false; } } else { result = PastePlainText (data, insertionOffset, text); } } }); // we got MD_ATOM text - no need to request text. (otherwise buffer may get copied twice). return result; } if (result < 0 && clipboard.WaitIsTextAvailable ()) { clipboard.RequestText (delegate(Clipboard clp, string text) { if (string.IsNullOrEmpty (text)) return; using (var undo = data.OpenUndoGroup ()) { result = PastePlainText (data, insertionOffset, text); } }); } return result; }
/// <summary> /// Transpose characters (Emacs C-t) /// </summary> public static void TransposeCharacters(TextEditorData data) { if (data.Caret.Offset == 0) { return; } DocumentLine line = data.Document.GetLine(data.Caret.Line); if (line == null) { return; } using (var undoGroup = data.OpenUndoGroup()) { int transposeOffset = data.Caret.Offset - 1; char ch; if (data.Caret.Column == 0) { DocumentLine lineAbove = data.Document.GetLine(data.Caret.Line - 1); if (lineAbove.Length == 0 && line.Length == 0) { return; } if (line.Length != 0) { ch = data.Document.GetCharAt(data.Caret.Offset); data.Remove(data.Caret.Offset, 1); data.Insert(lineAbove.Offset + lineAbove.Length, ch.ToString()); data.Document.CommitLineUpdate(data.Caret.Line - 1); return; } int lastCharOffset = lineAbove.Offset + lineAbove.Length - 1; ch = data.Document.GetCharAt(lastCharOffset); data.Remove(lastCharOffset, 1); data.InsertAtCaret(ch.ToString()); return; } int offset = data.Caret.Offset; if (data.Caret.Column >= line.Length + 1) { offset = line.Offset + line.Length - 1; transposeOffset = offset - 1; // case one char in line: if (transposeOffset < line.Offset) { DocumentLine lineAbove = data.Document.GetLine(data.Caret.Line - 1); transposeOffset = lineAbove.Offset + lineAbove.Length; ch = data.Document.GetCharAt(offset); data.Remove(offset, 1); data.Insert(transposeOffset, ch.ToString()); data.Caret.Offset = line.Offset; data.Document.CommitLineUpdate(data.Caret.Line - 1); return; } } ch = data.Document.GetCharAt(offset); data.Replace(offset, 1, data.Document.GetCharAt(transposeOffset).ToString()); data.Replace(transposeOffset, 1, ch.ToString()); if (data.Caret.Column < line.Length + 1) { data.Caret.Offset = offset + 1; } } }
public override void OnTheFlyFormat (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, TextEditorData data, int startOffset, int endOffset) { var parser = new CSharpParser (); var compilationUnit = parser.ParseSnippet (data); if (compilationUnit == null) { Console.WriteLine ("couldn't parse : " + data.Text); return; } if (parser.HasErrors) return; var policy = policyParent.Get<CSharpFormattingPolicy> (mimeTypeChain); var adapter = new TextEditorDataAdapter (data); var formattingVisitor = new ICSharpCode.NRefactory.CSharp.AstFormattingVisitor (policy.CreateOptions (), adapter, new FormattingActionFactory (data)) { HadErrors = parser.HasErrors }; var changes = new List<ICSharpCode.NRefactory.CSharp.Refactoring.Action> (); changes.AddRange (formattingVisitor.Changes. Where (c => (startOffset <= c.Offset && c.Offset < endOffset))); using (var undo = data.OpenUndoGroup ()) { MDRefactoringContext.MdScript.RunActions (changes, null); } }
public static void Right(TextEditorData data) { using (var undo = data.OpenUndoGroup()) { if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection) { data.Caret.Offset = System.Math.Max(data.SelectionAnchor, data.Caret.Offset); data.ClearSelection(); return; } DocumentLine line = data.Document.GetLine(data.Caret.Line); IEnumerable <FoldSegment> foldings = data.Document.GetStartFoldings(line); FoldSegment segment = null; foreach (FoldSegment folding in foldings) { if (folding.IsCollapsed && folding.Offset == data.Caret.Offset) { segment = folding; break; } } if (segment != null) { data.Caret.Offset = segment.EndOffset; return; } if (data.Caret.Column >= line.Length + 1) { int nextColumn; if (data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual && data.Caret.Column == DocumentLocation.MinColumn) { nextColumn = data.GetVirtualIndentationColumn(data.Caret.Location); } else if (data.Caret.AllowCaretBehindLineEnd) { nextColumn = data.Caret.Column + 1; } else { nextColumn = line.Length + 1; } if (data.Caret.Column < nextColumn) { data.Caret.Column = nextColumn; } else { if (data.Caret.Line < data.LineCount) { data.Caret.Location = new DocumentLocation(data.Caret.Line + 1, DocumentLocation.MinColumn); } } } else { data.Caret.Column++; var layout = data.Parent?.TextViewMargin?.GetLayout(line); if (layout != null && data.Caret.Column < line.Length) { uint curIndex = 0, byteIndex = 0; int utf8ByteIndex = (int)layout.TranslateToUTF8Index((uint)data.Caret.Column - 1, ref curIndex, ref byteIndex); layout.Layout.GetCursorPos(utf8ByteIndex, out var strong_pos, out var weak_pos); if (strong_pos.X != weak_pos.X) { data.Caret.Column++; } } } var curOffset = data.Caret.Offset; if (curOffset > 0 && curOffset < data.Length && IsLowSurrogateMarkerSet(data.GetCharAt(curOffset))) { data.Caret.Offset++; } } }