public override void CorrectIndenting (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, TextEditorData data, int line) { DocumentLine lineSegment = data.Document.GetLine (line); if (lineSegment == null) return; try { var policy = policyParent.Get<CSharpFormattingPolicy> (mimeTypeChain); var tracker = new CSharpIndentEngine (data.Document, data.CreateNRefactoryTextEditorOptions (), policy.CreateOptions ()); tracker.Update (lineSegment.Offset); for (int i = lineSegment.Offset; i < lineSegment.Offset + lineSegment.Length; i++) { tracker.Push (data.Document.GetCharAt (i)); } string curIndent = lineSegment.GetIndentation (data.Document); int nlwsp = curIndent.Length; if (!tracker.LineBeganInsideMultiLineComment || (nlwsp < lineSegment.LengthIncludingDelimiter && data.Document.GetCharAt (lineSegment.Offset + nlwsp) == '*')) { // Possibly replace the indent string newIndent = tracker.ThisLineIndent; if (newIndent != curIndent) data.Replace (lineSegment.Offset, nlwsp, newIndent); } } catch (Exception e) { LoggingService.LogError ("Error while indenting", e); } }
public override void CorrectIndenting (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, TextEditorData data, int line) { LineSegment lineSegment = data.Document.GetLine (line); if (lineSegment == null) return; var policy = policyParent.Get<CFormattingPolicy> (mimeTypeChain); var tracker = new DocumentStateTracker<CIndentEngine> (new CIndentEngine (policy), data); tracker.UpdateEngine (lineSegment.Offset); for (int i = lineSegment.Offset; i < lineSegment.Offset + lineSegment.EditableLength; i++) { tracker.Engine.Push (data.Document.GetCharAt (i)); } string curIndent = lineSegment.GetIndentation (data.Document); int nlwsp = curIndent.Length; if (!tracker.Engine.LineBeganInsideMultiLineComment || (nlwsp < lineSegment.Length && data.Document.GetCharAt (lineSegment.Offset + nlwsp) == '*')) { // Possibly replace the indent string newIndent = tracker.Engine.ThisLineIndent; if (newIndent != curIndent) data.Replace (lineSegment.Offset, nlwsp, newIndent); } tracker.Dispose (); }
/// <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; 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 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> (data.Document.GetMarkers(nextLine)); data.Document.ClearMarkers(nextLine); 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.ClearMarkers(data.Document.GetLine(i)); foreach (TextLineMarker marker in (i != lineStart ? data.Document.GetMarkers(data.Document.GetLine(i - 1)) : prevLineMarkers)) { data.Document.AddMarker(data.Document.GetLine(i), 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 MoveBlockDown(TextEditorData data) { int lineStart = data.Caret.Line; int lineEnd = data.Caret.Line; bool setSelection = lineStart != lineEnd; if (data.IsSomethingSelected) { setSelection = true; lineStart = data.MainSelection.MinLine; lineEnd = data.MainSelection.MaxLine; } if (lineStart <= 0) { return; } data.Document.BeginAtomicUndo(); //Mono.TextEditor.LineSegment startLine = data.Document.GetLine (lineStart); //int relCaretOffset = data.Caret.Offset - startLine.Offset; Mono.TextEditor.LineSegment nextLine = data.Document.GetLine(lineEnd + 1); if (nextLine == null) { return; } string text = data.Document.GetTextAt(nextLine.Offset, nextLine.EditableLength); List <TextMarker> prevLineMarkers = new List <TextMarker> (nextLine.Markers); nextLine.ClearMarker(); for (int i = lineEnd + 1; i >= lineStart; i--) { LineSegment cur = data.Document.GetLine(i); LineSegment prev = data.Document.GetLine(i - 1); data.Replace(cur.Offset, cur.EditableLength, i != lineStart ? data.Document.GetTextAt(prev.Offset, prev.EditableLength) : 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.Line++; if (setSelection) { data.SetSelection(data.Document.GetLine(lineStart + 1).Offset, data.Document.GetLine(lineEnd + 1).Offset + data.Document.GetLine(lineEnd + 1).EditableLength); } data.Document.EndAtomicUndo(); }
public static void MoveBlockUp(TextEditorData data) { int lineStart = data.Caret.Line; int lineEnd = data.Caret.Line; bool setSelection = lineStart != lineEnd; if (data.IsSomethingSelected) { setSelection = true; lineStart = data.MainSelection.MinLine; lineEnd = data.MainSelection.MaxLine; } 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.LineSegment prevLine = data.Document.GetLine(lineStart - 1); string text = data.Document.GetTextAt(prevLine.Offset, prevLine.EditableLength); List <TextMarker> prevLineMarkers = new List <TextMarker> (prevLine.Markers); prevLine.ClearMarker(); for (int i = lineStart - 1; i <= lineEnd; i++) { LineSegment cur = data.Document.GetLine(i); LineSegment next = data.Document.GetLine(i + 1); data.Replace(cur.Offset, cur.EditableLength, i != lineEnd ? data.Document.GetTextAt(next.Offset, next.EditableLength) : text); data.Document.GetLine(i).ClearMarker(); foreach (TextMarker marker in (i != lineEnd ? data.Document.GetLine(i + 1).Markers : prevLineMarkers)) { data.Document.GetLine(i).AddMarker(marker); } } data.Caret.Line--; if (setSelection) { data.SetSelection(data.Document.GetLine(lineStart - 1).Offset, data.Document.GetLine(lineEnd - 1).Offset + data.Document.GetLine(lineEnd - 1).EditableLength); } } }
public static void SortSelectedLines(TextEditorData data) { var start = data.MainSelection.Start; var end = data.MainSelection.End; var caret = data.Caret.Location; int startLine = start.Line; int endLine = end.Line; if (startLine == endLine) { return; } int length = 0; var lines = new string[endLine - startLine + 1]; for (int i = startLine; i <= endLine; i++) { //get lines *with* line endings var lineText = data.GetLineText(i, true); lines[i - startLine] = lineText; length += lineText.Length; } var linesUnsorted = new string[lines.Length]; Array.Sort(lines, StringComparer.Ordinal); bool changed = false; for (int i = 0; i <= lines.Length; i++) { //can't simply use reference comparison as Array.Sort is not stable if (string.Equals(lines[i], linesUnsorted[i], StringComparison.Ordinal)) { continue; } changed = true; break; } if (!changed) { return; } var sb = new StringBuilder(); for (int i = 0; i < lines.Length; i++) { sb.Append(lines[i]); } var startOffset = data.Document.LocationToOffset(new TextLocation(startLine, 0)); data.Replace(startOffset, length, sb.ToString()); data.Caret.Location = LimitColumn(data, caret); data.SetSelection(LimitColumn(data, start), LimitColumn(data, end)); }
void ConvertVerbatimStringToNormal (TextEditorData textEditorData, int offset) { var endOffset = offset; while (endOffset < textEditorData.Length) { char ch = textEditorData.GetCharAt (endOffset); if (ch == '"' && (endOffset + 1 < textEditorData.Length && textEditorData.GetCharAt (endOffset + 1) == '"')) { endOffset += 2; continue; } if (ch == '"') break; endOffset++; } textEditorData.Replace (offset, endOffset - offset, ConvertToStringLiteral (ConvertFromVerbatimString (textEditorData.GetTextAt (offset, endOffset - offset)))); }
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 bool FixLineStart (TextEditorData textEditorData, DocumentStateTracker<CSharpIndentEngine> stateTracker, int lineNumber) { if (lineNumber > DocumentLocation.MinLine) { DocumentLine line = textEditorData.Document.GetLine (lineNumber); if (line == null) return false; DocumentLine prevLine = textEditorData.Document.GetLine (lineNumber - 1); if (prevLine == null) return false; string trimmedPreviousLine = textEditorData.Document.GetTextAt (prevLine).TrimStart (); //xml doc comments //check previous line was a doc comment //check there's a following line? if (trimmedPreviousLine.StartsWith ("///", StringComparison.Ordinal)) { if (textEditorData.GetTextAt (line.Offset, line.Length).TrimStart ().StartsWith ("///", StringComparison.Ordinal)) return false; //check that the newline command actually inserted a newline textEditorData.EnsureCaretIsNotVirtual (); string nextLine = textEditorData.Document.GetTextAt (textEditorData.Document.GetLine (lineNumber + 1)).TrimStart (); if (trimmedPreviousLine.Length > "///".Length || nextLine.StartsWith ("///", StringComparison.Ordinal)) { var insertionPoint = line.Offset + line.GetIndentation (textEditorData.Document).Length; textEditorData.Insert (insertionPoint, "/// "); return true; } //multi-line comments } else if (stateTracker.Engine.IsInsideMultiLineComment) { if (textEditorData.GetTextAt (line.Offset, line.Length).TrimStart ().StartsWith ("*", StringComparison.Ordinal)) return false; textEditorData.EnsureCaretIsNotVirtual (); string commentPrefix = string.Empty; if (trimmedPreviousLine.StartsWith ("* ", StringComparison.Ordinal)) { commentPrefix = "* "; } else if (trimmedPreviousLine.StartsWith ("/**", StringComparison.Ordinal) || trimmedPreviousLine.StartsWith ("/*", StringComparison.Ordinal)) { commentPrefix = " * "; } else if (trimmedPreviousLine.StartsWith ("*", StringComparison.Ordinal)) { commentPrefix = "*"; } int indentSize = line.GetIndentation (textEditorData.Document).Length; var insertedText = prevLine.GetIndentation (textEditorData.Document) + commentPrefix; textEditorData.Replace (line.Offset, indentSize, insertedText); textEditorData.Caret.Offset = line.Offset + insertedText.Length; return true; } else if (stateTracker.Engine.IsInsideStringLiteral) { var lexer = new CSharpCompletionEngineBase.MiniLexer (textEditorData.Document.GetTextAt (0, prevLine.EndOffset)); lexer.Parse (); if (!lexer.IsInString) return false; textEditorData.EnsureCaretIsNotVirtual (); textEditorData.Insert (prevLine.Offset + prevLine.Length, "\" +"); int indentSize = line.GetIndentation (textEditorData.Document).Length; var insertedText = prevLine.GetIndentation (textEditorData.Document) + (trimmedPreviousLine.StartsWith ("\"", StringComparison.Ordinal) ? "" : "\t") + "\""; textEditorData.Replace (line.Offset, indentSize, insertedText); return true; } } return false; }
public static void Join(TextEditorData data) { int startLine, endLine, startOffset, length; if (data.IsSomethingSelected) { startLine = data.Document.OffsetToLineNumber (data.SelectionRange.Offset); endLine = data.Document.OffsetToLineNumber (data.SelectionRange.EndOffset - 1); } else { startLine = endLine = data.Caret.Line; } //single-line joins if (endLine == startLine) endLine++; if (endLine > data.Document.LineCount) return; DocumentLine seg = data.Document.GetLine (startLine); startOffset = seg.Offset; StringBuilder sb = new StringBuilder (data.Document.GetTextAt (seg).TrimEnd ()); //lastSpaceOffset = startOffset + sb.Length; for (int i = startLine + 1; i <= endLine; i++) { seg = data.Document.GetLine (i); //lastSpaceOffset = startOffset + sb.Length; sb.Append (" "); sb.Append (data.Document.GetTextAt (seg).Trim ()); } length = (seg.Offset - startOffset) + seg.Length; // TODO: handle conversion issues ? data.Replace (startOffset, length, sb.ToString ()); }
static void ConvertNormalToVerbatimString (TextEditorData textEditorData, int offset) { var endOffset = offset; while (endOffset < textEditorData.Length) { char ch = textEditorData.GetCharAt (endOffset); if (ch == '\\') { if (endOffset + 1 < textEditorData.Length && NewLine.IsNewLine (textEditorData.GetCharAt (endOffset + 1))) return; endOffset += 2; continue; } if (ch == '"') break; if (NewLine.IsNewLine (ch)) return; endOffset++; } if (offset > endOffset || endOffset == textEditorData.Length) return; var plainText = TextPasteUtils.StringLiteralPasteStrategy.Instance.Decode (textEditorData.GetTextAt (offset, endOffset - offset)); var newText = TextPasteUtils.VerbatimStringStrategy.Encode (plainText); textEditorData.Replace (offset, endOffset - offset, newText); }
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 ToggleCase(TextEditorData data) { if (data.IsSomethingSelected) { if (!data.CanEditSelection) return; StringBuilder sb = new StringBuilder (data.SelectedText); for (int i = 0; i < sb.Length; i++) { char ch = sb [i]; if (Char.IsLower (ch)) sb [i] = Char.ToUpper (ch); else if (Char.IsUpper (ch)) sb [i] = Char.ToLower (ch); } data.Replace (data.SelectionRange.Offset, data.SelectionRange.Length, sb.ToString ()); } else if (data.CanEdit (data.Caret.Line)) { char ch = data.Document.GetCharAt (data.Caret.Offset); if (Char.IsLower (ch)) ch = Char.ToUpper (ch); else if (Char.IsUpper (ch)) ch = Char.ToLower (ch); var caretOffset = data.Caret.Offset; int length = data.Replace (caretOffset, 1, new string (ch, 1)); DocumentLine seg = data.Document.GetLine (data.Caret.Line); if (data.Caret.Column < seg.Length) data.Caret.Offset = caretOffset + length; } }
protected void InsertCharacter(uint unicodeKey) { if (!textEditorData.CanEdit(Data.Caret.Line)) { return; } HideMouseCursor(); Document.BeginAtomicUndo(); if (textEditorData.IsSomethingSelected && textEditorData.MainSelection.SelectionMode == SelectionMode.Block) { textEditorData.Caret.PreserveSelection = true; if (!textEditorData.MainSelection.IsDirty) { textEditorData.DeleteSelectedText(false); textEditorData.MainSelection.IsDirty = true; } } else { textEditorData.DeleteSelectedText(); } char ch = (char)unicodeKey; if (!char.IsControl(ch) && textEditorData.CanEdit(Caret.Line)) { LineSegment line = Document.GetLine(Caret.Line); if (Caret.IsInInsertMode || Caret.Column >= line.EditableLength) { string text = Caret.Column > line.EditableLength ? textEditorData.GetVirtualSpaces(Caret.Line, Caret.Column) + ch.ToString() : ch.ToString(); if (textEditorData.IsSomethingSelected && textEditorData.MainSelection.SelectionMode == SelectionMode.Block) { int length = 0; for (int lineNumber = textEditorData.MainSelection.MinLine; lineNumber <= textEditorData.MainSelection.MaxLine; lineNumber++) { length = textEditorData.Insert(textEditorData.Document.GetLine(lineNumber).Offset + Caret.Column, text); } Caret.Column += length - 1; textEditorData.MainSelection.Lead = new DocumentLocation(textEditorData.MainSelection.Lead.Line, Caret.Column + 1); textEditorData.MainSelection.IsDirty = true; Document.CommitMultipleLineUpdate(textEditorData.MainSelection.MinLine, textEditorData.MainSelection.MaxLine); } else { int length = textEditorData.Insert(Caret.Offset, text); Caret.Column += length - 1; } } else { int length = textEditorData.Replace(Caret.Offset, 1, ch.ToString()); if (length > 1) { Caret.Offset += length - 1; } } // That causes unnecessary redraws: // bool autoScroll = Caret.AutoScrollToCaret; Caret.Column++; // Caret.AutoScrollToCaret = autoScroll; // if (autoScroll) // Editor.ScrollToCaret (); // Document.RequestUpdate (new LineUpdate (Caret.Line)); // Document.CommitDocumentUpdate (); } if (textEditorData.IsSomethingSelected && textEditorData.MainSelection.SelectionMode == SelectionMode.Block) { textEditorData.Caret.PreserveSelection = false; } Document.EndAtomicUndo(); Document.OptimizeTypedUndo(); }
public static void MoveBlockDown (TextEditorData data) { int lineStart = data.Caret.Line; int lineEnd = data.Caret.Line; bool setSelection = lineStart != lineEnd; if (data.IsSomethingSelected) { setSelection = true; lineStart = data.MainSelection.MinLine; lineEnd = data.MainSelection.MaxLine; } if (lineStart <= 0) return; data.Document.BeginAtomicUndo (); Mono.TextEditor.LineSegment startLine = data.Document.GetLine (lineStart); int relCaretOffset = data.Caret.Offset - startLine.Offset; Mono.TextEditor.LineSegment nextLine = data.Document.GetLine (lineEnd + 1); string text = data.Document.GetTextAt (nextLine.Offset, nextLine.EditableLength); List<TextMarker> prevLineMarkers = new List<TextMarker> (nextLine.Markers); nextLine.ClearMarker (); for (int i = lineEnd + 1; i >= lineStart; i--) { LineSegment cur = data.Document.GetLine (i); LineSegment prev = data.Document.GetLine (i - 1); data.Replace (cur.Offset, cur.EditableLength, i != lineStart ? data.Document.GetTextAt (prev.Offset, prev.EditableLength) : 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.Offset = nextLine.Offset + relCaretOffset; if (setSelection) data.SetSelection (data.Document.GetLine (lineStart + 1).Offset, data.Document.GetLine (lineEnd + 1).Offset + data.Document.GetLine (lineEnd + 1).EditableLength); data.Document.EndAtomicUndo (); }
public static void SortSelectedLines (TextEditorData data) { var start = data.MainSelection.Start; var end = data.MainSelection.End; var caret = data.Caret.Location; int startLine = start.Line; int endLine = end.Line; if (startLine == endLine) return; int length = 0; var lines = new string[endLine - startLine + 1]; for (int i = startLine; i <= endLine; i++) { //get lines *with* line endings var lineText = data.GetLineText (i, true); lines [i - startLine] = lineText; length += lineText.Length; } var linesUnsorted = new string[lines.Length]; Array.Sort (lines, StringComparer.Ordinal); bool changed = false; for (int i = 0; i <= lines.Length; i++) { //can't simply use reference comparison as Array.Sort is not stable if (string.Equals (lines [i], linesUnsorted [i], StringComparison.Ordinal)) { continue; } changed = true; break; } if (!changed) { return; } var sb = new StringBuilder (); for (int i = 0; i < lines.Length; i++) { sb.Append (lines [i]); } var startOffset = data.Document.LocationToOffset (new TextLocation (startLine, 0)); data.Replace (startOffset, length, sb.ToString ()); data.Caret.Location = LimitColumn (data, caret); data.SetSelection (LimitColumn (data, start), LimitColumn (data, end)); }
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); } }
protected void InsertCharacter(uint unicodeKey) { if (!textEditorData.CanEdit(Data.Caret.Line)) { return; } HideMouseCursor(); using (var undo = Document.OpenUndoGroup()) { textEditorData.DeleteSelectedText(textEditorData.IsSomethingSelected ? textEditorData.MainSelection.SelectionMode != SelectionMode.Block : true); char ch = (char)unicodeKey; if (!char.IsControl(ch) && textEditorData.CanEdit(Caret.Line)) { LineSegment line = Document.GetLine(Caret.Line); if (Caret.IsInInsertMode || Caret.Column >= line.EditableLength + 1) { string text = Caret.Column > line.EditableLength + 1 ? textEditorData.GetVirtualSpaces(Caret.Line, Caret.Column) + ch.ToString() : ch.ToString(); if (textEditorData.IsSomethingSelected && textEditorData.MainSelection.SelectionMode == SelectionMode.Block) { int length = 0; var visualInsertLocation = editor.LogicalToVisualLocation(Caret.Location); for (int lineNumber = textEditorData.MainSelection.MinLine; lineNumber <= textEditorData.MainSelection.MaxLine; lineNumber++) { LineSegment lineSegment = textEditorData.GetLine(lineNumber); int insertOffset = lineSegment.GetLogicalColumn(textEditorData, visualInsertLocation.Column) - 1; string textToInsert; if (lineSegment.EditableLength < insertOffset) { int visualLastColumn = lineSegment.GetVisualColumn(textEditorData, lineSegment.EditableLength + 1); int charsToInsert = visualInsertLocation.Column - visualLastColumn; int spaceCount = charsToInsert % editor.Options.TabSize; textToInsert = new string ('\t', (charsToInsert - spaceCount) / editor.Options.TabSize) + new string (' ', spaceCount) + text; insertOffset = lineSegment.EditableLength; } else { textToInsert = text; } length = textEditorData.Insert(lineSegment.Offset + insertOffset, textToInsert); } Caret.PreserveSelection = true; Caret.Column += length - 1; textEditorData.MainSelection.Lead = new DocumentLocation(textEditorData.MainSelection.Lead.Line, Caret.Column + 1); textEditorData.MainSelection.Anchor = new DocumentLocation(textEditorData.MainSelection.Anchor.Line, Caret.Column + 1); Document.CommitMultipleLineUpdate(textEditorData.MainSelection.MinLine, textEditorData.MainSelection.MaxLine); } else { int length = textEditorData.Insert(Caret.Offset, text); Caret.Column += length - 1; } } else { int length = textEditorData.Replace(Caret.Offset, 1, ch.ToString()); if (length > 1) { Caret.Offset += length - 1; } } // That causes unnecessary redraws: // bool autoScroll = Caret.AutoScrollToCaret; Caret.Column++; if (Caret.PreserveSelection) { Caret.PreserveSelection = false; } // Caret.AutoScrollToCaret = autoScroll; // if (autoScroll) // Editor.ScrollToCaret (); // Document.RequestUpdate (new LineUpdate (Caret.Line)); // Document.CommitDocumentUpdate (); } } Document.OptimizeTypedUndo(); }
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; }
protected void InsertCharacter(uint unicodeKey) { if (!textEditorData.CanEdit(Data.Caret.Line)) { return; } HideMouseCursor(); using (var undo = Document.OpenUndoGroup()) { if (textEditorData.IsSomethingSelected && textEditorData.Options.EnableSelectionWrappingKeys && IsSpecialKeyForSelection(unicodeKey)) { textEditorData.SelectionSurroundingProvider.HandleSpecialSelectionKey(textEditorData, unicodeKey); return; } textEditorData.DeleteSelectedText( textEditorData.IsSomethingSelected ? textEditorData.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. textEditorData.EnsureCaretIsNotVirtual(); char ch = (char)unicodeKey; if (!char.IsControl(ch) && textEditorData.CanEdit(Caret.Line)) { DocumentLine line = Document.GetLine(Caret.Line); if (Caret.IsInInsertMode || Caret.Column >= line.Length + 1) { string text = ch.ToString(); if (textEditorData.IsSomethingSelected && textEditorData.MainSelection.SelectionMode == SelectionMode.Block) { var visualInsertLocation = textEditorData.LogicalToVisualLocation(Caret.Location); var selection = textEditorData.MainSelection; Caret.PreserveSelection = true; for (int lineNumber = selection.MinLine; lineNumber <= selection.MaxLine; lineNumber++) { DocumentLine lineSegment = textEditorData.GetLine(lineNumber); int insertOffset = lineSegment.GetLogicalColumn(textEditorData, visualInsertLocation.Column) - 1; string textToInsert; if (lineSegment.Length < insertOffset) { int visualLastColumn = lineSegment.GetVisualColumn(textEditorData, lineSegment.Length + 1); int charsToInsert = visualInsertLocation.Column - visualLastColumn; int spaceCount = charsToInsert % editor.Options.TabSize; textToInsert = new string ('\t', (charsToInsert - spaceCount) / editor.Options.TabSize) + new string (' ', spaceCount) + text; insertOffset = lineSegment.Length; } else { textToInsert = text; } textEditorData.Insert(lineSegment.Offset + insertOffset, textToInsert); } var visualColumn = textEditorData.GetLine(Caret.Location.Line).GetVisualColumn(textEditorData, Caret.Column); textEditorData.MainSelection = new Selection( new DocumentLocation(selection.Anchor.Line, textEditorData.GetLine(selection.Anchor.Line).GetLogicalColumn(textEditorData, visualColumn)), new DocumentLocation(selection.Lead.Line, textEditorData.GetLine(selection.Lead.Line).GetLogicalColumn(textEditorData, visualColumn)), SelectionMode.Block ); Document.CommitMultipleLineUpdate(textEditorData.MainSelection.MinLine, textEditorData.MainSelection.MaxLine); } else { textEditorData.Insert(Caret.Offset, text); } } else { textEditorData.Replace(Caret.Offset, 1, ch.ToString()); } // That causes unnecessary redraws: // bool autoScroll = Caret.AutoScrollToCaret; // Caret.Column++; if (Caret.PreserveSelection) { Caret.PreserveSelection = false; } // Caret.AutoScrollToCaret = autoScroll; // if (autoScroll) // Editor.ScrollToCaret (); // Document.RequestUpdate (new LineUpdate (Caret.Line)); // Document.CommitDocumentUpdate (); } } Document.OptimizeTypedUndo(); }
static void ConvertVerbatimStringToNormal (TextEditorData textEditorData, int offset) { var endOffset = offset; while (endOffset < textEditorData.Length) { char ch = textEditorData.GetCharAt (endOffset); if (ch == '"' && (endOffset + 1 < textEditorData.Length && textEditorData.GetCharAt (endOffset + 1) == '"')) { endOffset += 2; continue; } if (ch == '"') { break; } endOffset++; } var plainText = TextPasteUtils.VerbatimStringStrategy.Decode (textEditorData.GetTextAt (offset, endOffset - offset)); var newText = TextPasteUtils.StringLiteralPasteStrategy.Instance.Encode (plainText); textEditorData.Replace (offset, endOffset - offset, newText); }
int CorrectFormatting (TextEditorData data, int start, int end) { int delta = 0; int lineNumber = data.OffsetToLineNumber (start); LineSegment line = data.GetLine (lineNumber); if (line.Offset < start) lineNumber++; line = data.GetLine (lineNumber); if (line == null) return 0; bool wholeDocument = end >= data.Document.Length; do { string indent = line.GetIndentation (data.Document); StringBuilder newIndent = new StringBuilder (); int col = 1; if (data.Options.TabsToSpaces) { foreach (char ch in indent) { if (ch == '\t') { int tabWidth = TextViewMargin.GetNextTabstop (data, col) - col; newIndent.Append (new string (' ', tabWidth)); col += tabWidth; } else { newIndent.Append (ch); } } } else { for (int i = 0; i < indent.Length; i++) { char ch = indent [i]; if (ch == '\t') { int tabWidth = TextViewMargin.GetNextTabstop (data, col) - col; newIndent.Append (ch); col += tabWidth; } else { int tabWidth = TextViewMargin.GetNextTabstop (data, col) - col; newIndent.Append ('\t'); col += tabWidth; while (tabWidth-- > 0 && i + 1 < indent.Length) { if (indent [i + 1] != ' ') break; i++; } } } } if (indent.Length == line.EditableLength) newIndent.Length = 0; if (line.DelimiterLength != 0) { delta -= line.DelimiterLength; delta += data.EolMarker.Length; data.Replace (line.Offset + line.EditableLength, line.DelimiterLength, data.EolMarker); if (!wholeDocument) { end -= line.DelimiterLength; end += data.EolMarker.Length; } } string replaceWith = newIndent.ToString (); if (indent != replaceWith) { int count = (indent ?? "").Length; delta -= count; delta += data.Replace (line.Offset, count, replaceWith); if (!wholeDocument) end = end - count + replaceWith.Length; } lineNumber++; line = data.GetLine (lineNumber); } while (line != null && (wholeDocument || line.EndOffset <= end)); return delta; }
static void InsertFormattedText (TextEditorData data, int offset, string formattedText) { data.Document.BeginAtomicUndo (); // DocumentLocation caretLocation = data.Caret.Location; int selAnchor = data.IsSomethingSelected ? data.Document.LocationToOffset (data.MainSelection.Anchor) : -1; int selLead = data.IsSomethingSelected ? data.Document.LocationToOffset (data.MainSelection.Lead) : -1; int textOffset = 0; int caretOffset = data.Caret.Offset; // Console.WriteLine ("formattedText3:" + formattedText.Replace ("\t", "->").Replace (" ", "°").Replace ("\n", "\\n").Replace ("\r", "\\r")); while (textOffset < formattedText.Length /*&& offset < caretOffset*/) { if (offset < 0) { offset++; textOffset++; continue; } char ch1 = data.Document.GetCharAt (offset); char ch2 = formattedText[textOffset]; bool isCh1Eol = ch1 == '\n'|| ch1 == '\r'; if (ch1 == '\r' && offset + 1 < data.Document.Length && data.Document.GetCharAt (offset + 1) == '\n') { offset++; ch1 = '\n'; } if (ch1 == ch2 || (ch2 == '\n' && isCh1Eol)) { textOffset++; offset++; continue; } else if (isCh1Eol) { // int firstWhitespace = 0; // skip all white spaces in formatted text - we had a line break int firstWhitespace = -1; while (textOffset < formattedText.Length && IsPlainWhitespace (formattedText[textOffset])) { if (firstWhitespace < 0) firstWhitespace = textOffset; textOffset++; } if (firstWhitespace >= 0 && firstWhitespace != textOffset && formattedText[textOffset] == '\n') { int length = textOffset - firstWhitespace - 1; data.Insert (offset, formattedText.Substring (firstWhitespace, length) + data.EolMarker); data.Document.CommitLineUpdate (data.Document.OffsetToLineNumber (offset)); length += data.EolMarker.Length; if (offset < caretOffset) caretOffset += length; if (offset < selAnchor) selAnchor += length; if (offset < selLead) selLead += length; offset += length - 1; textOffset++; } offset++; while (offset < data.Caret.Offset && IsPlainWhitespace (data.Document.GetCharAt (offset))) { offset++; } continue; } bool ch1Ws = Char.IsWhiteSpace (ch1); bool ch2Ws = Char.IsWhiteSpace (ch2); if (ch2Ws && !ch1Ws) { if (ch2 == '\n') { data.Insert (offset, data.EolMarker); data.Document.CommitLineUpdate (data.Document.OffsetToLineNumber (offset)); if (offset < caretOffset) caretOffset += data.EolMarker.Length; if (offset < selAnchor) selAnchor += data.EolMarker.Length; if (offset < selLead) selLead += data.EolMarker.Length; textOffset++; offset += data.EolMarker.Length; } else { data.Insert (offset, ch2.ToString ()); data.Document.CommitLineUpdate (data.Document.OffsetToLineNumber (offset)); if (offset < caretOffset) caretOffset++; if (offset < selAnchor) selAnchor++; if (offset < selLead) selLead++; textOffset++; offset++; } continue; } if ((!ch2Ws || ch2 == '\n') && ch1Ws) { if (offset < caretOffset) caretOffset--; if (offset < selAnchor) selAnchor--; if (offset < selLead) selLead--; data.Remove (offset, 1); data.Document.CommitLineUpdate (data.Document.OffsetToLineNumber (offset)); continue; } if (ch1Ws && ch2Ws) { data.Replace (offset, 1, ch2.ToString ()); data.Document.CommitLineUpdate (data.Document.OffsetToLineNumber (offset)); textOffset++; offset++; continue; } Console.WriteLine ("BAIL OUT"); break; } data.Caret.Offset = caretOffset; if (selAnchor >= 0) data.MainSelection = new Selection (data.Document.OffsetToLocation (selAnchor), data.Document.OffsetToLocation (selLead)); data.Document.EndAtomicUndo (); }
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 override void Perform(Script script) { data.Replace(Offset, RemovedChars, InsertedText); }
public static void MoveBlockUp (TextEditorData data) { int lineStart = data.Caret.Line; int lineEnd = data.Caret.Line; bool setSelection = lineStart != lineEnd; if (data.IsSomethingSelected) { setSelection = true; lineStart = data.MainSelection.MinLine; lineEnd = data.MainSelection.MaxLine; } 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.LineSegment prevLine = data.Document.GetLine (lineStart - 1); string text = data.Document.GetTextAt (prevLine.Offset, prevLine.EditableLength); List<TextMarker> prevLineMarkers = new List<TextMarker> (prevLine.Markers); prevLine.ClearMarker (); for (int i = lineStart - 1; i <= lineEnd; i++) { LineSegment cur = data.Document.GetLine (i); LineSegment next = data.Document.GetLine (i + 1); data.Replace (cur.Offset, cur.EditableLength, i != lineEnd ? data.Document.GetTextAt (next.Offset, next.EditableLength) : text); data.Document.GetLine (i).ClearMarker (); foreach (TextMarker marker in (i != lineEnd ? data.Document.GetLine (i + 1).Markers : prevLineMarkers)) { data.Document.GetLine (i).AddMarker (marker); } } data.Caret.Line--; if (setSelection) data.SetSelection (data.Document.GetLine (lineStart - 1).Offset, data.Document.GetLine (lineEnd - 1).Offset + data.Document.GetLine (lineEnd - 1).EditableLength); } }