public static void Left (TextEditorData data) { if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection) { data.Caret.Offset = System.Math.Min (data.SelectionAnchor, data.Caret.Offset); data.ClearSelection (); return; } LineSegment line = data.Document.GetLine (data.Caret.Line); IEnumerable<FoldSegment> foldings = data.Document.GetEndFoldings (line); FoldSegment segment = null; foreach (FoldSegment folding in foldings) { if (folding.IsFolded && folding.EndColumn == data.Caret.Column) { segment = folding; break; } } if (segment != null) { data.Caret.Location = data.Document.OffsetToLocation (segment.StartLine.Offset + segment.Column); return; } if (data.Caret.Column > 0) { if (data.Caret.Column > line.EditableLength) { data.Caret.Column = line.EditableLength; } else { data.Caret.Column--; } } else if (data.Caret.Line > 0) { LineSegment prevLine = data.Document.GetLine (data.Caret.Line - 1); data.Caret.Location = new DocumentLocation (data.Caret.Line - 1, prevLine.EditableLength); } }
public static void Right(TextEditorData data) { 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++; } }
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)); } } } }
public static void Up(TextEditorData data) { using (var undo = data.OpenUndoGroup()) { int desiredColumn = data.Caret.DesiredColumn; //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.MinLine - 1; data.ClearSelection(); data.Caret.Location = (line >= DocumentLocation.MinLine) ? new DocumentLocation(line, col) : new DocumentLocation(DocumentLocation.MinLine, DocumentLocation.MinColumn); data.Caret.SetToDesiredColumn(desiredColumn); return; } if (data.Caret.Line > DocumentLocation.MinLine) { int visualLine = data.LogicalToVisualLine(data.Caret.Line); int line = data.VisualToLogicalLine(visualLine - 1); int offset = MoveCaretOutOfFolding(data, data.Document.LocationToOffset(line, data.Caret.Column), false); data.Caret.SetToOffsetWithDesiredColumn(offset); } else { ToDocumentStart(data); } } }
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.TextLength; } 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); } } }
public static void Left(TextEditorData data) { 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) { LineSegment line = data.Document.GetLine(data.Caret.Line); if (data.Caret.Column > line.EditableLength + 1) { data.Caret.Column = line.EditableLength + 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) { LineSegment prevLine = data.Document.GetLine(data.Caret.Line - 1); data.Caret.Location = new DocumentLocation(data.Caret.Line - 1, prevLine.EditableLength + 1); } }
public static void Left (TextEditorData data) { 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 virtual int ReplaceAll(string withPattern) { int result = 0; using (var undo = textEditorData.OpenUndoGroup()) { int offset = 0; if (!SearchRequest.SearchRegion.IsInvalid) { offset = SearchRequest.SearchRegion.Offset; } SearchResult searchResult; var text = textEditorData.Text; var args = new TextViewMargin.SearchWorkerArguments() { Text = text }; while (true) { searchResult = SearchForward(null, args, offset); if (searchResult == null || searchResult.SearchWrapped) { break; } Replace(searchResult, withPattern); offset = searchResult.EndOffset; result++; } if (result > 0) { textEditorData.ClearSelection(); } } return(result); }
public static void ToDocumentStart(TextEditorData data) { if (!data.Caret.PreserveSelection) { data.ClearSelection(); } data.Caret.Location = new DocumentLocation(DocumentLocation.MinLine, DocumentLocation.MinColumn); }
public static void ToDocumentEnd(TextEditorData data) { if (!data.Caret.PreserveSelection) { data.ClearSelection(); } data.Caret.Offset = data.Document.TextLength; }
public static void Delete(TextEditorData data) { if (!data.CanEditSelection) { return; } 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++) { LineSegment lineSegment = data.Document.GetLine(lineNumber); if (col < lineSegment.EditableLength) { 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.Length) { return; } LineSegment line = data.Document.GetLine(data.Caret.Line); if (data.Caret.Column == line.EditableLength + 1) { if (data.Caret.Line < data.Document.LineCount) { data.Remove(line.EndOffset - line.DelimiterLength, line.DelimiterLength); if (line.EndOffset == data.Document.Length) { line.DelimiterLength = 0; } } } else { data.Remove(data.Caret.Offset, 1); data.Document.CommitLineUpdate(data.Caret.Line); } }
public static void Backspace(TextEditorData data, Action <TextEditorData> removeCharBeforeCaret) { if (!data.CanEditSelection) { return; } 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++) { data.Remove(data.Document.GetLine(lineNumber).Offset + col - 1, 1); } data.Caret.Column--; data.MainSelection.Lead = new DocumentLocation(data.MainSelection.Lead.Line, col); data.MainSelection.Anchor = new DocumentLocation(data.MainSelection.Anchor.Line, col); 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 == 0) { return; } LineSegment line = data.Document.GetLine(data.Caret.Line); if (data.Caret.Column > line.EditableLength + 1) { data.Caret.Column = line.EditableLength + 1; } else if (data.Caret.Offset == line.Offset) { LineSegment lineAbove = data.Document.GetLine(data.Caret.Line - 1); data.Caret.Location = new DocumentLocation(data.Caret.Line - 1, lineAbove.EditableLength + 1); data.Remove(lineAbove.EndOffset - lineAbove.DelimiterLength, lineAbove.DelimiterLength); } else { removeCharBeforeCaret(data); } }
public static void ToDocumentEnd(TextEditorData data) { using (var undo = data.OpenUndoGroup()) { if (!data.Caret.PreserveSelection) { data.ClearSelection(); } data.Caret.Offset = data.Document.TextLength; } }
public static void ToDocumentStart(TextEditorData data) { using (var undo = data.OpenUndoGroup()) { if (!data.Caret.PreserveSelection) { data.ClearSelection(); } data.Caret.Location = new DocumentLocation(DocumentLocation.MinLine, DocumentLocation.MinColumn); } }
public static void Right(TextEditorData data) { if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection) { data.Caret.Offset = System.Math.Max(data.SelectionAnchor, data.Caret.Offset); data.ClearSelection(); return; } LineSegment 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.Location = data.Document.OffsetToLocation(segment.EndLine.Offset + segment.EndColumn); return; } if (data.Caret.Column < line.EditableLength + 1 || data.Caret.AllowCaretBehindLineEnd) { if (data.Caret.Column >= line.EditableLength + 1) { int nextColumn = data.GetNextVirtualColumn(data.Caret.Line, data.Caret.Column); if (data.Caret.Column != nextColumn) { data.Caret.Column = nextColumn; } else { data.Caret.Location = new DocumentLocation(data.Caret.Line + 1, DocumentLocation.MinColumn); data.Caret.CheckCaretPosition(); } } else { data.Caret.Column++; } } else if (data.Caret.Line + 1 <= data.Document.LineCount) { data.Caret.Location = new DocumentLocation(data.Caret.Line + 1, DocumentLocation.MinColumn); } }
internal static void InternalCaretMoveHome(TextEditorData data, bool firstNonWhitespace, bool hop) { if (!data.Caret.PreserveSelection) { data.ClearSelection(); } DocumentLine line = data.Document.GetLine(data.Caret.Line); int newColumn; if (firstNonWhitespace) { int homeMark = GetHomeMark(data.Document, line); if (hop) { newColumn = data.Caret.Column == homeMark ? DocumentLocation.MinColumn : homeMark; } else { newColumn = homeMark; } } else { newColumn = DocumentLocation.MinColumn; } var newLocation = new DocumentLocation(data.Caret.Line, newColumn); // handle folding IEnumerable <FoldSegment> foldings = data.Document.GetEndFoldings(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.StartLine.Offset); } if (newLocation != data.Caret.Location) { data.Caret.Location = newLocation; } }
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 void DuplicateLine(TextEditorData data) { 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 Left(TextEditorData data) { if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection) { data.Caret.Offset = System.Math.Min(data.SelectionAnchor, data.Caret.Offset); data.ClearSelection(); return; } LineSegment line = data.Document.GetLine(data.Caret.Line); IEnumerable <FoldSegment> foldings = data.Document.GetEndFoldings(line); FoldSegment segment = null; foreach (FoldSegment folding in foldings) { if (folding.IsFolded && folding.EndColumn + 1 == data.Caret.Column) { segment = folding; break; } } if (segment != null) { data.Caret.Location = data.Document.OffsetToLocation(segment.StartLine.Offset + segment.Column - 1); return; } if (data.Caret.Column > DocumentLocation.MinColumn) { if (data.Caret.Column > line.EditableLength + 1) { data.Caret.Column = line.EditableLength + 1; } else { data.Caret.Column--; } } else if (data.Caret.Line > DocumentLocation.MinLine) { LineSegment prevLine = data.Document.GetLine(data.Caret.Line - 1); data.Caret.Location = new DocumentLocation(data.Caret.Line - 1, prevLine.EditableLength + 1); } }
public static void Right (TextEditorData data) { 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++; } }
public static void LineEnd(TextEditorData data) { if (!data.Caret.PreserveSelection) { data.ClearSelection(); } DocumentLocation newLocation = data.Caret.Location; LineSegment line = data.Document.GetLine(data.Caret.Line); newLocation.Column = line.EditableLength + 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); } if (newLocation != data.Caret.Location) { data.Caret.Location = newLocation; } if (data.Caret.AllowCaretBehindLineEnd) { int nextColumn = data.GetNextVirtualColumn(data.Caret.Line, data.Caret.Column); if (nextColumn != data.Caret.Column) { data.Caret.Column = nextColumn; } } }
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 void Right (TextEditorData data) { if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection) { data.Caret.Offset = System.Math.Max (data.SelectionAnchor, data.Caret.Offset); data.ClearSelection (); return; } LineSegment 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.EditableLength + 1 || data.Caret.AllowCaretBehindLineEnd) { if (data.Caret.Column >= line.EditableLength + 1) { int nextColumn = data.GetNextVirtualColumn (data.Caret.Line, data.Caret.Column); if (data.Caret.Column != nextColumn) { data.Caret.Column = nextColumn; } else { data.Caret.Location = new DocumentLocation (data.Caret.Line + 1, DocumentLocation.MinColumn); data.Caret.CheckCaretPosition (); } } else { data.Caret.Column++; } } else if (data.Caret.Line + 1 <= data.Document.LineCount) { data.Caret.Location = new DocumentLocation (data.Caret.Line + 1, DocumentLocation.MinColumn); } }
public static void Left (TextEditorData data) { 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) { LineSegment line = data.Document.GetLine (data.Caret.Line); if (data.Caret.Column > line.EditableLength + 1) { data.Caret.Column = line.EditableLength + 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) { LineSegment prevLine = data.Document.GetLine (data.Caret.Line - 1); data.Caret.Location = new DocumentLocation (data.Caret.Line - 1, prevLine.EditableLength + 1); } }
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; } 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++) { data.Remove(data.Document.GetLine(lineNumber).Offset + col - 1, 1); } data.MainSelection.Lead = new DocumentLocation(data.MainSelection.Lead.Line, col); data.MainSelection.Anchor = new DocumentLocation(data.MainSelection.Anchor.Line, col); 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); 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 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); } } }
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 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 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--; } } }
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; 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; if (!pasteBlock && !pasteLine) return; data.Document.BeginAtomicUndo (); 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); LineSegment curLine; int lineCol = col; result = 0; for (int i = 0; i < lines.Length; i++) { while (data.Document.LineCount <= lineNr + i) { data.Insert (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.EditableLength + 1 < lineCol) { result += lineCol - curLine.EditableLength; data.Insert (curLine.Offset + curLine.EditableLength, new string (' ', lineCol - curLine.EditableLength)); } 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; LineSegment curLine = data.Document.GetLine (data.Caret.Line); data.Insert (curLine.Offset, text + data.EolMarker); if (!preserveState) data.Caret.Offset += text.Length + data.EolMarker.Length; } /* 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; data.Document.EndAtomicUndo (); } }); if (result < 0) { clipboard.WaitIsTextAvailable (); clipboard.RequestText (delegate(Clipboard clp, string text) { if (string.IsNullOrEmpty (text)) return; data.Document.BeginAtomicUndo (); int caretPos = data.Caret.Offset; if (data.IsSomethingSelected && data.MainSelection.SelectionMode == SelectionMode.Block) { data.Caret.PreserveSelection = true; if (!data.MainSelection.IsDirty) { data.DeleteSelectedText (false); data.MainSelection.IsDirty = true; } int textLength = 0; int column = data.Caret.Column; int minLine = data.MainSelection.MinLine; int maxLine = data.MainSelection.MaxLine; for (int lineNumber = minLine; lineNumber <= maxLine; lineNumber++) { int offset = data.Document.GetLine (lineNumber).Offset + column; textLength = data.Insert (offset, text); data.PasteText (offset, text); } data.Caret.Offset += textLength; data.MainSelection.Anchor = new DocumentLocation (data.Caret.Line == minLine ? maxLine : minLine, 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 { ISegment 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.Offset += textLength; 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) { data.Caret.Offset += textLength; } else { if (caretPos >= insertionOffset) data.Caret.Offset += textLength; if (selection != null) { int offset = selection.Offset; if (offset >= insertionOffset) offset += textLength; data.SelectionRange = new Segment (offset, selection.Length); } } data.PasteText (insertionOffset, text); } data.Document.EndAtomicUndo (); }); } return result; }
public static void ClearSelection (TextEditorData data) { data.ClearSelection (); }
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; 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 != 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 (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.FixVirtualIndentation (startLine); data.Caret.PreserveSelection = false; } } else if (pasteLine) { using (var undo = data.OpenUndoGroup ()) { if (!preserveSelection) 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); 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 Delete (TextEditorData data) { if (!data.CanEditSelection) return; 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++) { LineSegment lineSegment = data.Document.GetLine (lineNumber); if (col < lineSegment.EditableLength) 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.Length) return; LineSegment line = data.Document.GetLine (data.Caret.Line); if (data.Caret.Column == line.EditableLength + 1) { if (data.Caret.Line < data.Document.LineCount) { data.Remove (line.EndOffset - line.DelimiterLength, line.DelimiterLength); if (line.EndOffset == data.Document.Length) line.DelimiterLength = 0; } } else { data.Remove (data.Caret.Offset, 1); data.Document.CommitLineUpdate (data.Caret.Line); } }
public static void Down (TextEditorData data) { //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; } return; } if (data.Caret.Line < data.Document.LineCount - 1) { int line = data.Document.VisualToLogicalLine (data.Document.LogicalToVisualLine (data.Caret.Line) + 1); int offset = data.Document.LocationToOffset (line, data.Caret.Column); data.Caret.SetToOffsetWithDesiredColumn (MoveCaretOutOfFolding (data, offset)); } else { ToDocumentEnd (data); } }
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 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 (); } }
public static void ClearSelection(TextEditorData data) { data.ClearSelection(); }
public override void Run (RefactoringOptions options) { fileName = declaringType.CompilationUnit.FileName; var openDocument = IdeApp.Workbench.OpenDocument (fileName); if (openDocument == null) { MessageService.ShowError (string.Format (GettextCatalog.GetString ("Can't open file {0}."), fileName)); return; } data = openDocument.Editor; if (data == null) return; openDocument.RunWhenLoaded (delegate { try { indent = data.Document.GetLine (declaringType.Location.Line).GetIndentation (data.Document) ?? ""; } catch (Exception) { indent = ""; } indent += "\t"; InsertionCursorEditMode mode = new InsertionCursorEditMode (data.Parent, CodeGenerationService.GetInsertionPoints (openDocument, declaringType)); if (fileName == options.Document.FileName) { for (int i = 0; i < mode.InsertionPoints.Count; i++) { var point = mode.InsertionPoints [i]; if (point.Location < data.Caret.Location) { mode.CurIndex = i; } else { break; } } } ModeHelpWindow helpWindow = new ModeHelpWindow (); helpWindow.TransientFor = IdeApp.Workbench.RootWindow; helpWindow.TitleText = GettextCatalog.GetString ("<b>Create Method -- Targeting</b>"); helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Key</b>"), GettextCatalog.GetString ("<b>Behavior</b>"))); helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Up</b>"), GettextCatalog.GetString ("Move to <b>previous</b> target point."))); helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Down</b>"), GettextCatalog.GetString ("Move to <b>next</b> target point."))); helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Enter</b>"), GettextCatalog.GetString ("<b>Declare new method</b> at target point."))); helpWindow.Items.Add (new KeyValuePair<string, string> (GettextCatalog.GetString ("<b>Esc</b>"), GettextCatalog.GetString ("<b>Cancel</b> this refactoring."))); mode.HelpWindow = helpWindow; mode.StartMode (); mode.Exited += delegate(object s, InsertionCursorEventArgs args) { if (args.Success) { SetInsertionPoint (args.InsertionPoint); BaseRun (options); if (string.IsNullOrEmpty (fileName)) return; data.ClearSelection (); data.Caret.Offset = selectionEnd; data.SetSelection (selectionStart, selectionEnd); } }; }); }
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++; } } }
public static void LineEnd (TextEditorData data) { 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; } }
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 ToDocumentEnd (TextEditorData data) { using (var undo = data.OpenUndoGroup ()) { if (!data.Caret.PreserveSelection) data.ClearSelection (); data.Caret.Offset = data.Document.TextLength; } }
public static void DuplicateLine (TextEditorData data) { 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 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)); } } } }
public static void ToDocumentStart (TextEditorData data) { if (!data.Caret.PreserveSelection) data.ClearSelection (); data.Caret.Location = new DocumentLocation (0, 0); }
public static void ToDocumentStart (TextEditorData data) { using (var undo = data.OpenUndoGroup ()) { if (!data.Caret.PreserveSelection) data.ClearSelection (); data.Caret.Location = new DocumentLocation (DocumentLocation.MinLine, DocumentLocation.MinColumn); } }
public static void ToDocumentEnd (TextEditorData data) { if (!data.Caret.PreserveSelection) data.ClearSelection (); data.Caret.Offset = data.Document.Length; }
public static void Backspace (TextEditorData data, Action<TextEditorData> removeCharBeforeCaret) { if (!data.CanEditSelection) return; 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++) { data.Remove (data.Document.GetLine (lineNumber).Offset + col - 1, 1); } data.MainSelection.Lead = new DocumentLocation (data.MainSelection.Lead.Line, col); data.MainSelection.Anchor = new DocumentLocation (data.MainSelection.Anchor.Line, col); 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); 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 (); }
static void InternalCaretMoveHome (TextEditorData data, bool firstNonWhitespace, bool hop) { if (!data.Caret.PreserveSelection) data.ClearSelection (); DocumentLocation newLocation = data.Caret.Location; LineSegment line = data.Document.GetLine (data.Caret.Line); if (firstNonWhitespace) { int homeMark = GetHomeMark (data.Document, line); if (hop) { newLocation.Column = data.Caret.Column == homeMark ? 0 : homeMark; } else { newLocation.Column = homeMark; } } else { newLocation.Column = 0; } // handle folding IEnumerable<FoldSegment> foldings = data.Document.GetEndFoldings (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.StartLine.Offset); if (newLocation != data.Caret.Location) data.Caret.Location = newLocation; }
void ResetEditorState(TextEditorData data) { if (data == null) return; data.ClearSelection (); //Editor can be null during GUI-less tests // Commenting this fixes bug: Bug 622618 - Inline search fails in vi mode // if (Editor != null) // Editor.HighlightSearchPattern = false; if (CaretMode.Block != data.Caret.Mode) { data.Caret.Mode = CaretMode.Block; if (data.Caret.Column > DocumentLocation.MinColumn) data.Caret.Column--; } ViActions.RetreatFromLineEnd (data); }
public static void LineEnd (TextEditorData data) { if (!data.Caret.PreserveSelection) data.ClearSelection (); DocumentLocation newLocation = data.Caret.Location; LineSegment line = data.Document.GetLine (data.Caret.Line); newLocation.Column = line.EditableLength; // 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); if (newLocation != data.Caret.Location) { data.Caret.Location = newLocation; } if (data.Caret.AllowCaretBehindLineEnd) { int nextColumn = data.GetNextVirtualColumn (data.Caret.Line, data.Caret.Column); if (nextColumn != data.Caret.Column) data.Caret.Column = nextColumn; } }
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; if (!pasteBlock && !pasteLine) { return; } data.Document.BeginAtomicUndo(); 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); LineSegment curLine; int lineCol = col; result = 0; for (int i = 0; i < lines.Length; i++) { while (data.Document.LineCount <= lineNr + i) { data.Insert(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.EditableLength + 1 < lineCol) { result += lineCol - curLine.EditableLength; data.Insert(curLine.Offset + curLine.EditableLength, new string (' ', lineCol - curLine.EditableLength)); } 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; LineSegment curLine = data.Document.GetLine(data.Caret.Line); data.Insert(curLine.Offset, text + data.EolMarker); if (!preserveState) { data.Caret.Offset += text.Length + data.EolMarker.Length; } } /* 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; data.Document.EndAtomicUndo(); } }); } if (result < 0 && clipboard.WaitIsTextAvailable()) { clipboard.RequestText(delegate(Clipboard clp, string text) { if (string.IsNullOrEmpty(text)) { return; } data.Document.BeginAtomicUndo(); 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++) { LineSegment lineSegment = data.GetLine(lineNumber); int insertOffset = lineSegment.GetLogicalColumn(data, visualInsertLocation.Column) - 1; if (lineSegment.EditableLength < insertOffset) { int visualLastColumn = lineSegment.GetVisualColumn(data, lineSegment.EditableLength + 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.EditableLength; data.Insert(lineSegment.Offset + insertOffset, textToInsert); data.PasteText(lineSegment.Offset + insertOffset, textToInsert); } else { textLength = data.Insert(lineSegment.Offset + insertOffset, text); data.PasteText(lineSegment.Offset + insertOffset, text); } } data.Caret.Offset += 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 { ISegment 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.Offset += textLength; } 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) { data.Caret.Offset += textLength; } else { if (caretPos >= insertionOffset) { data.Caret.Offset += textLength; } if (selection != null) { int offset = selection.Offset; if (offset >= insertionOffset) { offset += textLength; } data.SelectionRange = new Segment(offset, selection.Length); } } data.PasteText(insertionOffset, text); } data.Document.EndAtomicUndo(); }); } return(result); }
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 Up (TextEditorData data) { int desiredColumn = data.Caret.DesiredColumn; //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.MinLine - 1; data.ClearSelection (); data.Caret.Location = (line >= 0) ? new DocumentLocation (line, col) : new DocumentLocation (0, 0); data.Caret.SetToDesiredColumn (desiredColumn); return; } if (data.Caret.Line > 0) { int line = data.Document.VisualToLogicalLine (data.Document.LogicalToVisualLine (data.Caret.Line) - 1); int offset = data.Document.LocationToOffset (line, data.Caret.Column); data.Caret.Offset = MoveCaretOutOfFolding (data, offset); data.Caret.SetToDesiredColumn (desiredColumn); } else { ToDocumentStart (data); } }
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; }
public static void Backspace (TextEditorData data, Action<TextEditorData> removeCharBeforeCaret) { if (!data.CanEditSelection) return; 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++) { data.Remove (data.Document.GetLine (lineNumber).Offset + col - 1, 1); } data.Caret.Column--; data.MainSelection.Lead = new DocumentLocation (data.MainSelection.Lead.Line, col); data.MainSelection.Anchor = new DocumentLocation (data.MainSelection.Anchor.Line, col); 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 == 0) return; LineSegment line = data.Document.GetLine (data.Caret.Line); if (data.Caret.Column > line.EditableLength + 1) { data.Caret.Column = line.EditableLength + 1; } else if (data.Caret.Offset == line.Offset) { LineSegment lineAbove = data.Document.GetLine (data.Caret.Line - 1); data.Caret.Location = new DocumentLocation (data.Caret.Line - 1, lineAbove.EditableLength + 1); data.Remove (lineAbove.EndOffset - lineAbove.DelimiterLength, lineAbove.DelimiterLength); } else { removeCharBeforeCaret (data); } }