OpenUndoGroup() public method

public OpenUndoGroup ( ) : IDisposable
return IDisposable
		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;
				}
			}
		}
示例#2
0
		public static int RemoveTabInLine (TextEditorData data, DocumentLine line)
		{
			if (line.LengthIncludingDelimiter == 0)
				return 0;
			using (var undoGroup = data.OpenUndoGroup ()) {
				char ch = data.Document.GetCharAt (line.Offset); 
				if (ch == '\t') {
					data.Remove (line.Offset, 1);
					data.Document.CommitLineUpdate (line);
					return 1;
				} else if (ch == ' ') {
					int removeCount = 0;
					for (int i = 0; i < data.Options.IndentationSize;) {
						ch = data.Document.GetCharAt (line.Offset + i);
						if (ch == ' ') {
							removeCount++;
							i++;
						} else if (ch == '\t') {
							removeCount++;
							i += data.Options.TabSize;
						} else {
							break;
						}
					}
					data.Remove (line.Offset, removeCount);
					data.Document.CommitLineUpdate (line);
					return removeCount;
				}
			}
			return 0;
		}
示例#3
0
		static void NextWord (TextEditorData data, bool subword)
		{
			using (var undo = data.OpenUndoGroup ()) {
				int oldLine = data.Caret.Line;
				int caretOffset = data.Caret.Offset;
				int offset = subword ? data.FindNextSubwordOffset (caretOffset) : data.FindNextWordOffset (caretOffset);
				if (caretOffset != offset && data.CanEdit (oldLine) && data.CanEdit (data.Caret.Line)) {
					data.Remove (caretOffset, offset - caretOffset);
				}
			}
		}
示例#4
0
		public static void GotoMatchingBracket (TextEditorData data)
		{
			using (var undoGroup = data.OpenUndoGroup ()) {
				int matchingBracketOffset = data.Document.GetMatchingBracketOffset (data.Caret.Offset);
				if (matchingBracketOffset == -1 && data.Caret.Offset > 0)
					matchingBracketOffset = data.Document.GetMatchingBracketOffset (data.Caret.Offset - 1);

				if (matchingBracketOffset != -1)
					data.Caret.Offset = matchingBracketOffset;
			}
		}
		public static void Select (TextEditorData data, Action<TextEditorData> caretMoveAction)
		{
			using (var undoGroup = data.OpenUndoGroup ()) {
				PositionChangedHandler handler = new PositionChangedHandler (data);
				data.Caret.PositionChanged += handler.DataCaretPositionChanged;

				StartSelection (data);
				caretMoveAction (data);
				data.Caret.PositionChanged -= handler.DataCaretPositionChanged;
				data.Caret.AutoScrollToCaret = true;
				data.Caret.PreserveSelection = false;
			}
		}
		public void Insert (TextEditorData editor, string text)
		{
			int offset = editor.Document.LocationToOffset (Location);
			using (var undo = editor.OpenUndoGroup ()) {
				text = editor.FormatString (Location, text);
				
				LineSegment line = editor.Document.GetLineByOffset (offset);
				int insertionOffset = line.Offset + Location.Column - 1;
				offset = insertionOffset;
				InsertNewLine (editor, LineBefore, ref offset);
				
				offset += editor.Insert (offset, text);
				InsertNewLine (editor, LineAfter, ref offset);
			}
		}
示例#7
0
 public static void Left(TextEditorData editor)
 {
     if (!Platform.IsMac)
     {
         if (DocumentLocation.MinColumn < editor.Caret.Column)
             CaretMoveActions.Left(editor);
     }
     else
     {
         using (var undo = editor.OpenUndoGroup())
         {
             if (editor.Caret.Column > DocumentLocation.MinColumn)
                 editor.Caret.Column = editor.Caret.Column - 1;
         }
     }
 }
示例#8
0
 public static void Up(TextEditorData editor)
 {
     if (!Platform.IsMac)
         CaretMoveActions.Up(editor);
     else
     {
         using (var undo = editor.OpenUndoGroup())
         {
             if (editor.Caret.Line > DocumentLocation.MinLine)
             {
                 int visualLine = editor.LogicalToVisualLine(editor.Caret.Line);
                 int line = editor.VisualToLogicalLine(visualLine - 1);
                 editor.Caret.Line = line;
             }
         }
     }
 }
示例#9
0
 public static void Down(TextEditorData editor)
 {
     if (!Platform.IsMac)
         CaretMoveActions.Down(editor);
     else
     {
         using (var undo = editor.OpenUndoGroup())
         {
             if (editor.Caret.Line < editor.Document.LineCount)
             {
                 int nextLine = editor.LogicalToVisualLine(editor.Caret.Line);
                 int line = editor.VisualToLogicalLine(nextLine + 1);
                 editor.Caret.Line = line;
             }
         }
     }
 }
示例#10
0
		public static void RemoveIndentSelection (TextEditorData data)
		{
			if (!data.IsSomethingSelected)
				return;
			int startLineNr, endLineNr;
			GetSelectedLines (data, out startLineNr, out endLineNr);
			
			using (var undo = data.OpenUndoGroup (OperationType.Format)) {
				var anchor = data.MainSelection.Anchor;
				var lead = data.MainSelection.Lead;
				bool first = true;
				bool removedFromLast = false;
				int removeLast = 0;
				bool removedFromFirst = false;
				int removeFirst = 0;
				foreach (var line in data.SelectedLines) {
					int remove = RemoveTabInLine (data, line);
					removedFromLast |= remove > 0;
					removeLast = remove;
					if (first) {
						removedFromFirst = remove > 0;
						removeFirst = remove;
						first = false;
					}
				}

				var ac = System.Math.Max (DocumentLocation.MinColumn, anchor.Column - (anchor < lead ? removeFirst : removeLast));
				var lc = System.Math.Max (DocumentLocation.MinColumn, lead.Column - (anchor < lead ? removeLast : removeFirst));
				
				if (anchor < lead) {
					if (!removedFromFirst)
						ac = anchor.Column;
					if (!removedFromLast)
						lc = lead.Column;
				} else {
					if (!removedFromFirst)
						lc = lead.Column;
					if (!removedFromLast)
						ac = anchor.Column;
				}
				data.SetSelection (anchor.Line, ac, lead.Line, lc);
			}
			data.Document.RequestUpdate (new MultipleLineUpdate (startLineNr, endLineNr));
			data.Document.CommitDocumentUpdate ();
		}
示例#11
0
        public static void CaretLineToStart(TextEditorData data)
        {
            if (!data.CanEdit(data.Caret.Line))
            {
                return;
            }
            var line = data.Document.GetLine(data.Caret.Line);

            using (var undo = data.OpenUndoGroup()) {
                data.EnsureCaretIsNotVirtual();
                int physColumn = data.Caret.Column - 1;

                var startLine = GetStartOfLineOffset(data, data.Caret.Location);
                data.Remove(startLine, (line.Offset + physColumn) - startLine);
            }

            data.Document.CommitLineUpdate(data.Caret.Line);
        }
        public int Insert(TextEditorData editor, string text)
        {
            int offset = editor.Document.LocationToOffset(Location);

            using (var undo = editor.OpenUndoGroup()) {
                text = editor.FormatString(Location, text);

                DocumentLine line            = editor.Document.GetLineByOffset(offset);
                int          insertionOffset = line.Offset + Location.Column - 1;
                offset = insertionOffset;
                InsertNewLine(editor, LineBefore, ref offset);
                int result = offset - insertionOffset;

                offset += editor.Insert(offset, text);
                InsertNewLine(editor, LineAfter, ref offset);
                return(result);
            }
        }
示例#13
0
        static void NewLineSmartIndent(TextEditorData data)
        {
            using (var undo = data.OpenUndoGroup()) {
                data.EnsureCaretIsNotVirtual();

                var oldCaretLine = data.Caret.Location.Line;

                string indentString = data.GetIndentationString(data.Caret.Location);
                data.InsertAtCaret(data.EolMarker);

                // Don't insert the indent string if the EOL insertion modified the caret location in an unexpected fashion
                //  (This likely means someone has custom logic regarding insertion of the EOL)
                if (data.Caret.Location.Line == oldCaretLine + 1 && data.Caret.Location.Column == 1)
                {
                    data.InsertAtCaret(indentString);
                }
            }
        }
示例#14
0
		public static void InsertNewLine (TextEditorData data)
		{
			if (!data.CanEditSelection)
				return;
			
			using (var undo = data.OpenUndoGroup ()) {
				if (data.IsSomethingSelected)
					data.DeleteSelectedText ();
				switch (data.Options.IndentStyle) {
				case IndentStyle.None:
					data.InsertAtCaret (data.EolMarker);
					break;
				case IndentStyle.Auto:
					data.EnsureCaretIsNotVirtual ();
					var sb = new StringBuilder (data.EolMarker);
					sb.Append (data.Document.GetLineIndent (data.Caret.Line));
					data.InsertAtCaret (sb.ToString ());
					break;
				case IndentStyle.Smart:
					if (!data.HasIndentationTracker)
						goto case IndentStyle.Auto;
					NewLineSmartIndent (data);
					break;
				case IndentStyle.Virtual:
					if (!data.HasIndentationTracker)
						goto case IndentStyle.Auto;
					var oldLine = data.Caret.Line;
					var curLine = data.GetLine (oldLine);
					var indentCol = data.GetVirtualIndentationColumn (data.Caret.Location);
					if (curLine.Length >= data.Caret.Column) {
						NewLineSmartIndent (data);
						data.FixVirtualIndentation ();
						data.FixVirtualIndentation (oldLine);
						break;
					}
					data.Insert (data.Caret.Offset, data.EolMarker);
					data.FixVirtualIndentation (oldLine);
					data.Caret.Column = indentCol;
					break;
				default:
					throw new ArgumentOutOfRangeException ();
				}
			}
		}
示例#15
0
		public static void IndentSelection (TextEditorData data)
		{
			if (!data.IsSomethingSelected)
				return;
			int startLineNr, endLineNr;
			GetSelectedLines (data, out startLineNr, out endLineNr);
			var anchor = data.MainSelection.Anchor;
			var lead = data.MainSelection.Lead;
			using (var undo = data.OpenUndoGroup ()) {
				foreach (DocumentLine line in data.SelectedLines) {
					data.Insert (line.Offset, data.Options.IndentationString);
				}
			}
			var leadCol = lead.Column > 1 || lead < anchor ? lead.Column + 1 : 1;
			var anchorCol = anchor.Column > 1 || anchor < lead ? anchor.Column + 1 : 1;
			data.SetSelection (anchor.Line, anchorCol, lead.Line, leadCol);
			data.Document.RequestUpdate (new MultipleLineUpdate (startLineNr, endLineNr));
			data.Document.CommitDocumentUpdate ();
		}
示例#16
0
		public static void MoveBlockDown (TextEditorData data)
		{
			int lineStart = data.Caret.Line;
			int lineEnd = data.Caret.Line;
			bool setSelection = lineStart != lineEnd;
			DocumentLocation anchor = DocumentLocation.Empty, lead = DocumentLocation.Empty;
			if (data.IsSomethingSelected) {
				setSelection = true;
				lineStart = data.MainSelection.MinLine;
				lineEnd = data.MainSelection.MaxLine;
				anchor = data.MainSelection.Anchor;
				lead = data.MainSelection.Lead;
			}
			
			if (lineStart <= 0)
				return;
			using (var undo = data.OpenUndoGroup ()) {
				
				//Mono.TextEditor.LineSegment startLine = data.Document.GetLine (lineStart);
				//int relCaretOffset = data.Caret.Offset - startLine.Offset;
				
				Mono.TextEditor.DocumentLine nextLine = data.Document.GetLine (lineEnd + 1);
				if (nextLine == null)
					return;
				string text = data.Document.GetTextAt (nextLine.Offset, nextLine.Length);
				List<TextMarker> prevLineMarkers = new List<TextMarker> (nextLine.Markers);
				nextLine.ClearMarker ();
				var loc = data.Caret.Location;
				for (int i = lineEnd + 1; i >= lineStart; i--) {
					DocumentLine cur = data.Document.GetLine (i);
					DocumentLine prev = data.Document.GetLine (i - 1);
					data.Replace (cur.Offset, cur.Length, i != lineStart ? data.Document.GetTextAt (prev.Offset, prev.Length) : text);
					data.Document.GetLine (i).ClearMarker ();
					foreach (TextMarker marker in (i != lineStart ? data.Document.GetLine (i - 1).Markers : prevLineMarkers)) {
						data.Document.GetLine (i).AddMarker (marker);
					}
				}
				
				data.Caret.Location = new DocumentLocation (loc.Line + 1, loc.Column);
				if (setSelection)
					data.SetSelection (anchor.Line + 1, anchor.Column, lead.Line + 1, lead.Column);
			}
		}
示例#17
0
 public static int RemoveTabInLine(TextEditorData data, DocumentLine line)
 {
     if (line.LengthIncludingDelimiter == 0)
     {
         return(0);
     }
     using (var undoGroup = data.OpenUndoGroup())
     {
         char ch = data.Document.GetCharAt(line.Offset);
         if (ch == '\t')
         {
             data.Remove(line.Offset, 1);
             data.Document.CommitLineUpdate(line);
             return(1);
         }
         else if (ch == ' ')
         {
             int removeCount = 0;
             for (int i = 0; i < data.Options.IndentationSize;)
             {
                 ch = data.Document.GetCharAt(line.Offset + i);
                 if (ch == ' ')
                 {
                     removeCount++;
                     i++;
                 }
                 else if (ch == '\t')
                 {
                     removeCount++;
                     i += data.Options.TabSize;
                 }
                 else
                 {
                     break;
                 }
             }
             data.Remove(line.Offset, removeCount);
             data.Document.CommitLineUpdate(line);
             return(removeCount);
         }
     }
     return(0);
 }
示例#18
0
        static int PastePlainText(TextEditorData data, int offset, string text, bool preserveSelection = false, byte[] copyData = null)
        {
            int inserted = 0;
            var undo     = data.OpenUndoGroup();
            var version  = data.Document.Version;

            if (!preserveSelection)
            {
                data.DeleteSelectedText(!data.IsSomethingSelected || data.MainSelection.SelectionMode != SelectionMode.Block);
            }
            data.EnsureCaretIsNotVirtual();
            if (data.IsSomethingSelected && data.MainSelection.SelectionMode == SelectionMode.Block)
            {
                var selection            = data.MainSelection;
                var visualInsertLocation = data.LogicalToVisualLocation(selection.Anchor);
                for (int lineNumber = selection.MinLine; lineNumber <= selection.MaxLine; lineNumber++)
                {
                    var    lineSegment  = data.GetLine(lineNumber);
                    int    insertOffset = lineSegment.GetLogicalColumn(data, visualInsertLocation.Column) - 1;
                    string textToInsert;
                    if (lineSegment.Length < insertOffset)
                    {
                        int visualLastColumn = lineSegment.GetVisualColumn(data, lineSegment.Length + 1);
                        int charsToInsert    = visualInsertLocation.Column - visualLastColumn;
                        int spaceCount       = charsToInsert % data.Options.TabSize;
                        textToInsert = new string ('\t', (charsToInsert - spaceCount) / data.Options.TabSize) + new string (' ', spaceCount) + text;
                        insertOffset = lineSegment.Length;
                    }
                    else
                    {
                        textToInsert = text;
                    }
                    inserted = data.Insert(lineSegment.Offset + insertOffset, textToInsert);
                }
            }
            else
            {
                offset   = version.MoveOffsetTo(data.Document.Version, offset);
                inserted = data.PasteText(offset, text, copyData, ref undo);
            }
            undo.Dispose();
            return(inserted);
        }
示例#19
0
 public static void DuplicateLine(TextEditorData data)
 {
     using (var undoGroup = data.OpenUndoGroup()) {
         if (data.IsSomethingSelected)
         {
             var selectedText = data.SelectedText;
             data.ClearSelection();
             data.InsertAtCaret(selectedText);
         }
         else
         {
             DocumentLine line = data.Document.GetLine(data.Caret.Line);
             if (line == null)
             {
                 return;
             }
             data.Insert(line.Offset, data.GetTextAt(line.SegmentIncludingDelimiter));
         }
     }
 }
示例#20
0
 public static void CaretLine(TextEditorData data)
 {
     if (data.Document.LineCount <= 1 || !data.CanEdit(data.Caret.Line))
     {
         return;
     }
     using (var undo = data.OpenUndoGroup()) {
         if (data.IsSomethingSelected)
         {
             var startLine = data.GetLine(data.MainSelection.Start.Line);
             var endLine   = data.GetLine(data.MainSelection.End.Line);
             data.Remove(startLine.Offset, endLine.EndOffsetIncludingDelimiter - startLine.Offset);
             return;
         }
         var start = GetStartOfLineOffset(data, data.Caret.Location);
         var end   = GetEndOfLineOffset(data, data.Caret.Location);
         data.Remove(start, end - start);
         data.Caret.Column = DocumentLocation.MinColumn;
     }
 }
示例#21
0
		public static void RemoveIndentSelection (TextEditorData data)
		{
			if (!data.IsSomethingSelected)
				return;
			int startLineNr, endLineNr;
			GetSelectedLines (data, out startLineNr, out endLineNr);
			
			using (var undo = data.OpenUndoGroup ()) {
				var anchor = data.MainSelection.Anchor;
				var lead = data.MainSelection.Lead;
				bool first = true;
				bool removedFromLast = false;
				bool removedFromFirst = false;
				foreach (var line in data.SelectedLines) {
					int remove = RemoveTabInLine (data, line);
					removedFromLast |= remove > 0;
					if (first) {
						removedFromFirst = remove > 0;
						first = false;
					}
				}

				var ac = System.Math.Max (DocumentLocation.MinColumn, anchor.Column - 1);
				var lc = System.Math.Max (DocumentLocation.MinColumn, lead.Column - 1);
				
				if (anchor < lead) {
					if (!removedFromFirst)
						ac = anchor.Column;
					if (!removedFromLast)
						lc = lead.Column;
				} else {
					if (!removedFromFirst)
						lc = lead.Column;
					if (!removedFromLast)
						ac = anchor.Column;
				}
				data.SetSelection (anchor.Line, ac, lead.Line, lc);
			}
			data.Document.RequestUpdate (new MultipleLineUpdate (startLineNr, endLineNr));
			data.Document.CommitDocumentUpdate ();
		}
示例#22
0
        public static void InsertTab(TextEditorData data)
        {
            if (!data.CanEditSelection)
            {
                return;
            }
            if (data.IsMultiLineSelection && data.MainSelection.SelectionMode != SelectionMode.Block)
            {
                IndentSelection(data);
                return;
            }
            using (var undo = data.OpenUndoGroup())
            {
                string indentationString  = "\t";
                bool   convertTabToSpaces = data.TabsToSpaces;

                if (!convertTabToSpaces && !data.Options.AllowTabsAfterNonTabs)
                {
                    for (int i = 1; i < data.Caret.Column; i++)
                    {
                        if (data.Document.GetCharAt(data.Caret.Offset - i) != '\t')
                        {
                            convertTabToSpaces = true;
                            break;
                        }
                    }
                }

                if (convertTabToSpaces)
                {
                    DocumentLocation visualLocation = data.LogicalToVisualLocation(data.Caret.Location);
                    int tabWidth = TextViewMargin.GetNextTabstop(data, visualLocation.Column) - visualLocation.Column;
                    indentationString = new string(' ', tabWidth);
                }
                if (data.IsSomethingSelected)
                {
                    data.DeleteSelectedText(data.MainSelection.SelectionMode != SelectionMode.Block);
                }
                data.InsertAtCaret(indentationString);
            }
        }
示例#23
0
        public static void RemoveTab(TextEditorData data)
        {
            if (data.IsSomethingSelected)
            {
                if (data.CanEditSelection)
                {
                    RemoveIndentSelection(data);
                }
                return;
            }
            var line = data.Document.GetLine(data.Caret.Line);

            if (line != null)
            {
                using (var undo = data.OpenUndoGroup()) {
                    data.EnsureCaretIsNotVirtual();
                    data.Document.ApplyTextChanges(new [] { RemoveTabInLine(data, line) });
                    data.FixVirtualIndentation();
                }
            }
        }
示例#24
0
        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;
                    }
                }
            }
        }
示例#25
0
 public static Microsoft.CodeAnalysis.Text.TextChange RemoveTabInLine(TextEditorData data, DocumentLine line)
 {
     if (line.LengthIncludingDelimiter == 0)
     {
         return(default(Microsoft.CodeAnalysis.Text.TextChange));
     }
     using (var undoGroup = data.OpenUndoGroup()) {
         char ch = data.Document.GetCharAt(line.Offset);
         if (ch == '\t')
         {
             return(new Microsoft.CodeAnalysis.Text.TextChange(new TextSpan(line.Offset, 1), ""));
         }
         else if (ch == ' ')
         {
             int removeCount = 0;
             for (int i = 0; i < data.Options.IndentationSize;)
             {
                 ch = data.Document.GetCharAt(line.Offset + i);
                 if (ch == ' ')
                 {
                     removeCount++;
                     i++;
                 }
                 else if (ch == '\t')
                 {
                     removeCount++;
                     i += data.Options.TabSize;
                 }
                 else
                 {
                     break;
                 }
             }
             return(new Microsoft.CodeAnalysis.Text.TextChange(new TextSpan(line.Offset, removeCount), ""));
         }
     }
     return(default(Microsoft.CodeAnalysis.Text.TextChange));
 }
示例#26
0
        public static void InsertNewLine(TextEditorData data)
        {
            if (!data.CanEditSelection)
            {
                return;
            }

            using (var undo = data.OpenUndoGroup()) {
                if (data.IsSomethingSelected)
                {
                    data.DeleteSelectedText();
                }

                data.EnsureCaretIsNotVirtual();
                StringBuilder sb = new StringBuilder(data.EolMarker);
                if (data.Options.AutoIndent)
                {
                    sb.Append(data.Document.GetLineIndent(data.Caret.Line));
                }
                int offset = data.Caret.Offset;
                data.Insert(offset, sb.ToString());
                data.Caret.Offset = offset + sb.Length;
            }
        }
示例#27
0
        public static void Down(TextEditorData data)
        {
            using (var undo = data.OpenUndoGroup()) {
                //on Mac, when deselecting and moving up/down a line, column is always the column of the selection's start
                if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection)
                {
                    int col  = data.MainSelection.Anchor > data.MainSelection.Lead ? data.MainSelection.Lead.Column : data.MainSelection.Anchor.Column;
                    int line = data.MainSelection.MaxLine + 1;
                    data.ClearSelection();
                    if (line <= data.Document.LineCount)
                    {
                        int offset = data.Document.LocationToOffset(line, col);
                        data.Caret.SetToOffsetWithDesiredColumn(MoveCaretOutOfFolding(data, offset));
                    }
                    else
                    {
                        data.Caret.Offset = data.Document.Length;
                    }
                    MoveOutOfUTF32Character(data);
                    return;
                }

                if (data.Caret.Line < data.Document.LineCount)
                {
                    int nextLine = data.LogicalToVisualLine(data.Caret.Line) + 1;
                    int line     = data.VisualToLogicalLine(nextLine);
                    int offset   = MoveCaretOutOfFolding(data, data.LocationToOffset(line, data.Caret.Column), true);
                    data.Caret.SetToOffsetWithDesiredColumn(offset);
                }
                else
                {
                    ToDocumentEnd(data);
                }
                MoveOutOfUTF32Character(data);
            }
        }
示例#28
0
		public static void InsertTab (TextEditorData data)
		{
			if (!data.CanEditSelection)
				return;
			if (data.IsMultiLineSelection && data.MainSelection.SelectionMode != SelectionMode.Block) {
				IndentSelection (data);
				return;
			}
			using (var undo = data.OpenUndoGroup ()) {
				string indentationString = "\t";
				bool convertTabToSpaces = data.TabsToSpaces;
				
				if (!convertTabToSpaces && !data.Options.AllowTabsAfterNonTabs) {
					for (int i = 1; i < data.Caret.Column; i++) {
						if (data.Document.GetCharAt (data.Caret.Offset - i) != '\t') {
							convertTabToSpaces = true;
							break;
						}
					}
				}
					
				if (convertTabToSpaces) {
					DocumentLocation visualLocation = data.LogicalToVisualLocation (data.Caret.Location);
					int tabWidth = TextViewMargin.GetNextTabstop (data, visualLocation.Column) - visualLocation.Column;
					indentationString = new string (' ', tabWidth);
				}
				if (data.IsSomethingSelected)
					data.DeleteSelectedText (data.MainSelection.SelectionMode != SelectionMode.Block);
				data.InsertAtCaret (indentationString);
			}
		}
示例#29
0
		static void NewLineSmartIndent (TextEditorData data)
		{
			using (var undo = data.OpenUndoGroup ()) {
				data.EnsureCaretIsNotVirtual ();
				string indentString;
				if (data.HasIndentationTracker) {
					indentString = data.IndentationTracker.GetIndentationString (data.Caret.Location);
				} else {
					indentString = data.GetIndentationString (data.Caret.Location);
				}
				data.InsertAtCaret (data.EolMarker);
				data.InsertAtCaret (indentString);
			}
		}
示例#30
0
        public static void RemoveIndentSelection(TextEditorData data)
        {
            if (!data.IsSomethingSelected)
            {
                return;
            }
            int startLineNr, endLineNr;

            GetSelectedLines(data, out startLineNr, out endLineNr);

            using (var undo = data.OpenUndoGroup(OperationType.Format)) {
                var          anchor           = data.MainSelection.Anchor;
                var          lead             = data.MainSelection.Lead;
                bool         first            = true;
                bool         removedFromLast  = false;
                int          removeLast       = 0;
                bool         removedFromFirst = false;
                int          removeFirst      = 0;
                var          changes          = new List <Microsoft.CodeAnalysis.Text.TextChange> ();
                DocumentLine last             = null;
                foreach (var line in data.SelectedLines)
                {
                    var remove = RemoveTabInLine(data, line);
                    removedFromLast |= remove.Span.Length > 0;
                    removeLast       = remove.Span.Length;
                    if (first)
                    {
                        removedFromFirst = remove.Span.Length > 0;
                        removeFirst      = remove.Span.Length;
                        first            = false;
                    }
                    if (remove.Span.Length > 0)
                    {
                        changes.Add(remove);
                    }
                    last = line;
                }
                data.Document.ApplyTextChanges(changes);
                if (last != null)
                {
                    data.Document.CommitLineUpdate(last);
                }
                var ac = System.Math.Max(DocumentLocation.MinColumn, anchor.Column - (anchor < lead ? removeFirst : removeLast));
                var lc = System.Math.Max(DocumentLocation.MinColumn, lead.Column - (anchor < lead ? removeLast : removeFirst));

                if (anchor < lead)
                {
                    if (!removedFromFirst)
                    {
                        ac = anchor.Column;
                    }
                    if (!removedFromLast)
                    {
                        lc = lead.Column;
                    }
                }
                else
                {
                    if (!removedFromFirst)
                    {
                        lc = lead.Column;
                    }
                    if (!removedFromLast)
                    {
                        ac = anchor.Column;
                    }
                }
                data.SetSelection(anchor.Line, ac, lead.Line, lc);
            }
            data.Document.RequestUpdate(new MultipleLineUpdate(startLineNr, endLineNr));
            data.Document.CommitDocumentUpdate();
        }
示例#31
0
		public static void CaretLineToEnd (TextEditorData data)
		{
			if (!data.CanEdit (data.Caret.Line))
				return;
			var line = data.Document.GetLine (data.Caret.Line);

			using (var undo = data.OpenUndoGroup ()) {
				data.EnsureCaretIsNotVirtual ();
				int physColumn = data.Caret.Column - 1;
				if (physColumn == line.Length) {
					// Nothing after the cursor, delete the end-of-line sequence
					data.Remove (line.Offset + physColumn, line.LengthIncludingDelimiter - physColumn);
				} else {
					// Delete from cursor position to the end of the line
					var end = GetEndOfLineOffset (data, data.Caret.Location, false);
					data.Remove (line.Offset + physColumn, end - (line.Offset + physColumn));
				}
			}
			data.Document.CommitLineUpdate (data.Caret.Line);
		}
示例#32
0
        static int PasteFrom(Clipboard clipboard, TextEditorData data, bool preserveSelection, int insertionOffset, bool preserveState)
        {
            int result = -1;

            if (!data.CanEdit(data.Document.OffsetToLineNumber(insertionOffset)))
            {
                return(result);
            }
            if (clipboard.WaitIsTargetAvailable(CopyOperation.MD_ATOM))
            {
                clipboard.RequestContents(CopyOperation.MD_ATOM, delegate(Clipboard clp, SelectionData selectionData) {
                    if (selectionData.Length > 0)
                    {
                        byte[] selBytes = selectionData.Data;

                        string text     = System.Text.Encoding.UTF8.GetString(selBytes, 1, selBytes.Length - 1);
                        bool pasteBlock = (selBytes [0] & 1) == 1;
                        bool pasteLine  = (selBytes [0] & 2) == 2;

                        var clearSelection = data.IsSomethingSelected ? data.MainSelection.SelectionMode != SelectionMode.Block : true;
                        using (var undo = data.OpenUndoGroup()) {
                            if (pasteBlock)
                            {
                                data.Caret.PreserveSelection = true;
                                if (preserveSelection && data.IsSomethingSelected)
                                {
                                    data.DeleteSelectedText(clearSelection);
                                }

                                string[] lines = text.Split('\r');
                                int lineNr     = data.Document.OffsetToLineNumber(insertionOffset);
                                int col        = insertionOffset - data.Document.GetLine(lineNr).Offset;
                                int visCol     = data.Document.GetLine(lineNr).GetVisualColumn(data, col);
                                DocumentLine curLine;
                                int lineCol = col;
                                result      = 0;
                                for (int i = 0; i < lines.Length; i++)
                                {
                                    while (data.Document.LineCount <= lineNr + i)
                                    {
                                        data.Insert(data.Document.TextLength, Environment.NewLine);
                                        result += Environment.NewLine.Length;
                                    }
                                    curLine = data.Document.GetLine(lineNr + i);
                                    if (lines [i].Length > 0)
                                    {
                                        lineCol = curLine.GetLogicalColumn(data, visCol);
                                        if (curLine.Length + 1 < lineCol)
                                        {
                                            result += lineCol - curLine.Length;
                                            data.Insert(curLine.Offset + curLine.Length, new string (' ', lineCol - curLine.Length));
                                        }
                                        data.Insert(curLine.Offset + lineCol, lines [i]);
                                        result += lines [i].Length;
                                    }
                                    if (!preserveState)
                                    {
                                        data.Caret.Offset = curLine.Offset + lineCol + lines [i].Length;
                                    }
                                }
                                if (!preserveState)
                                {
                                    data.ClearSelection();
                                }
                                data.Caret.PreserveSelection = false;
                            }
                            else if (pasteLine)
                            {
                                data.Caret.PreserveSelection = true;
                                if (preserveSelection && data.IsSomethingSelected)
                                {
                                    data.DeleteSelectedText(clearSelection);
                                }
                                result = text.Length;
                                DocumentLine curLine = data.Document.GetLine(data.Caret.Line);
                                data.Insert(curLine.Offset, text + data.EolMarker);
                                if (!preserveState)
                                {
                                    data.ClearSelection();
                                }
                                data.Caret.PreserveSelection = false;
                            }
                            else
                            {
                                PastePlainText(data, text);
                            }
                        }
                    }
                });
                // we got MD_ATOM text - no need to request text. (otherwise buffer may get copied twice).
                return(result);
            }

            if (result < 0 && clipboard.WaitIsTextAvailable())
            {
                clipboard.RequestText(delegate(Clipboard clp, string text) {
                    if (string.IsNullOrEmpty(text))
                    {
                        return;
                    }
                    using (var undo = data.OpenUndoGroup()) {
                        PastePlainText(data, text);
                    }
                });
            }

            return(result);
        }
		public static void SetCompletionText (TextEditorData data, CodeCompletionContext ctx, string partialWord, string completeWord, int wordOffset)
		{
			if (data == null || data.Document == null)
				return;

			int triggerOffset = ctx.TriggerOffset;
			int length = String.IsNullOrEmpty (partialWord) ? 0 : partialWord.Length;

			// for named arguments invoke(arg:<Expr>);
			if (completeWord.EndsWith (":", StringComparison.Ordinal)) {
				if (data.GetCharAt (triggerOffset + length) == ':')
					length++;
			}

			bool blockMode = false;
			if (data.IsSomethingSelected) {
				blockMode = data.MainSelection.SelectionMode == Mono.TextEditor.SelectionMode.Block;
				if (blockMode) {
					data.Caret.PreserveSelection = true;
					triggerOffset = data.Caret.Offset - length;
				} else {
					if (data.SelectionRange.Offset < ctx.TriggerOffset)
						triggerOffset = ctx.TriggerOffset - data.SelectionRange.Length;
					data.DeleteSelectedText ();
				}
				length = 0;
			}

			// | in the completion text now marks the caret position
			int idx = completeWord.IndexOf ('|');
			if (idx >= 0) {
				completeWord = completeWord.Remove (idx, 1);
			}
			
			triggerOffset += data.EnsureCaretIsNotVirtual ();
			if (blockMode) {
				using (var undo = data.OpenUndoGroup ()) {

					int minLine = data.MainSelection.MinLine;
					int maxLine = data.MainSelection.MaxLine;
					int column = triggerOffset - data.Document.GetLineByOffset (triggerOffset).Offset;
					for (int lineNumber = minLine; lineNumber <= maxLine; lineNumber++) {
						DocumentLine lineSegment = data.Document.GetLine (lineNumber);
						if (lineSegment == null)
							continue;
						int offset = lineSegment.Offset + column;
						data.Replace (offset, length, completeWord);
					}
					int minColumn = Math.Min (data.MainSelection.Anchor.Column, data.MainSelection.Lead.Column);
					data.MainSelection = data.MainSelection.WithRange (
						new Mono.TextEditor.DocumentLocation (data.Caret.Line == minLine ? maxLine : minLine, minColumn),
						data.Caret.Location
					);

					data.Document.CommitMultipleLineUpdate (data.MainSelection.MinLine, data.MainSelection.MaxLine);
					data.Caret.PreserveSelection = false;
				}
			} else {
				data.Replace (triggerOffset, length, completeWord);
			}
			
			data.Document.CommitLineUpdate (data.Caret.Line);
			if (idx >= 0)
				data.Caret.Offset = triggerOffset + idx;

		}
示例#34
0
		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);
			}
		}
示例#35
0
		public static void Paste (TextEditorData data)
		{
			if (!data.CanEditSelection)
				return;
			using (var undo = data.OpenUndoGroup ()) {
				data.EnsureCaretIsNotVirtual ();
				PasteFrom (Clipboard.Get (CopyOperation.CLIPBOARD_ATOM), data, true, data.IsSomethingSelected ? data.SelectionRange.Offset : data.Caret.Offset);
			}
		}
示例#36
0
        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();
            }
        }
示例#37
0
        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();
            }
        }
示例#38
0
        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);
                }
            }
        }
示例#39
0
		public static void InsertNewLineAtEnd (TextEditorData data)
		{
			if (!data.CanEditSelection)
				return;

			using (var undoGroup = data.OpenUndoGroup ()) {
				DocumentLine line = data.Document.GetLine (data.Caret.Line);
				data.Caret.Column = line.Length + 1;
				InsertNewLine (data);
			}
		}
示例#40
0
		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));
					}
				}
			}
		}
示例#41
0
		/// <summary>
		/// Transpose characters (Emacs C-t)
		/// </summary>
		public static void TransposeCharacters (TextEditorData data)
		{
			if (data.Caret.Offset == 0)
				return;
			DocumentLine line = data.Document.GetLine (data.Caret.Line);
			if (line == null)
				return;
			using (var undoGroup = data.OpenUndoGroup ()) {
				int transposeOffset = data.Caret.Offset - 1;
				char ch;
				if (data.Caret.Column == 0) {
					DocumentLine lineAbove = data.Document.GetLine (data.Caret.Line - 1);
					if (lineAbove.Length == 0 && line.Length == 0)
						return;
				
					if (line.Length != 0) {
						ch = data.Document.GetCharAt (data.Caret.Offset);
						data.Remove (data.Caret.Offset, 1);
						data.Insert (lineAbove.Offset + lineAbove.Length, ch.ToString ());
						data.Document.CommitLineUpdate (data.Caret.Line - 1);
						return;
					}
				
					int lastCharOffset = lineAbove.Offset + lineAbove.Length - 1;
					ch = data.Document.GetCharAt (lastCharOffset);
					data.Remove (lastCharOffset, 1);
					data.InsertAtCaret (ch.ToString ());
					return;
				}
			
				int offset = data.Caret.Offset;
				if (data.Caret.Column >= line.Length + 1) {
					offset = line.Offset + line.Length - 1;
					transposeOffset = offset - 1;
					// case one char in line:
					if (transposeOffset < line.Offset) {
						DocumentLine lineAbove = data.Document.GetLine (data.Caret.Line - 1);
						transposeOffset = lineAbove.Offset + lineAbove.Length;
						ch = data.Document.GetCharAt (offset);
						data.Remove (offset, 1);
						data.Insert (transposeOffset, ch.ToString ());
						data.Caret.Offset = line.Offset;
						data.Document.CommitLineUpdate (data.Caret.Line - 1);
						return;
					}
				}
			
				ch = data.Document.GetCharAt (offset);
				data.Replace (offset, 1, data.Document.GetCharAt (transposeOffset).ToString ());
				data.Replace (transposeOffset, 1, ch.ToString ());
				if (data.Caret.Column < line.Length + 1)
					data.Caret.Offset = offset + 1;
			}
		}
示例#42
0
		static void NewLineSmartIndent (TextEditorData data)
		{
			using (var undo = data.OpenUndoGroup ()) {
				data.EnsureCaretIsNotVirtual ();
				data.InsertAtCaret (data.EolMarker);
				data.InsertAtCaret (data.GetIndentationString (data.Caret.Location));
			}
		}
示例#43
0
		public static void InsertNewLine (TextEditorData data)
		{
			if (!data.CanEditSelection)
				return;
			
			using (var undo = data.OpenUndoGroup ()) {
				if (data.IsSomethingSelected)
					data.DeleteSelectedText ();
				switch (data.Options.IndentStyle) {
				case IndentStyle.None:
					data.InsertAtCaret (data.EolMarker);
					break;
				case IndentStyle.Auto:
					data.EnsureCaretIsNotVirtual ();
					var sb = new StringBuilder (data.EolMarker);
					sb.Append (data.Document.GetLineIndent (data.Caret.Line));
					data.InsertAtCaret (sb.ToString ());
					break;
				case IndentStyle.Smart:
					if (!data.HasIndentationTracker)
						goto case IndentStyle.Auto;
					NewLineSmartIndent (data);
					break;
				case IndentStyle.Virtual:
					if (!data.HasIndentationTracker)
						goto case IndentStyle.Auto;
					var oldLine = data.Caret.Line;
					var curLine = data.GetLine (oldLine);
					var indentCol = data.GetVirtualIndentationColumn (data.Caret.Location);
					if (curLine.Length >= data.Caret.Column) {
						NewLineSmartIndent (data);
						data.FixVirtualIndentation ();
						data.FixVirtualIndentation (oldLine);
						break;
					}
					data.Insert (data.Caret.Offset, data.EolMarker);
					data.FixVirtualIndentation (oldLine);
					data.Caret.Column = indentCol;
					break;
				default:
					throw new ArgumentOutOfRangeException ();
				}
			}
		}
示例#44
0
		static int PastePlainText (TextEditorData data, int offset, string text)
		{
			int inserted;
			using (var undo = data.OpenUndoGroup ()) {
				var version = data.Document.Version;
				data.DeleteSelectedText (!data.IsSomethingSelected || data.MainSelection.SelectionMode != SelectionMode.Block);
				data.EnsureCaretIsNotVirtual ();
				offset = version.MoveOffsetTo (data.Document.Version, offset);
				inserted = data.Insert (offset, text);
			}
			data.PasteText (offset, text, inserted);
			return inserted;
		}
示例#45
0
		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 ();
			}
		}
示例#46
0
		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 ();
			}
		}
示例#47
0
		static int PastePlainText (TextEditorData data, int offset, string text, bool preserveSelection = false)
		{
			int inserted = 0;
			using (var undo = data.OpenUndoGroup ()) {
				var version = data.Document.Version;
				if (!preserveSelection)
					data.DeleteSelectedText (!data.IsSomethingSelected || data.MainSelection.SelectionMode != SelectionMode.Block);
				data.EnsureCaretIsNotVirtual ();
				if (data.IsSomethingSelected && data.MainSelection.SelectionMode == SelectionMode.Block) {
					var selection = data.MainSelection;
					var visualInsertLocation = data.LogicalToVisualLocation (selection.Anchor);
					for (int lineNumber = selection.MinLine; lineNumber <= selection.MaxLine; lineNumber++) {
						var lineSegment = data.GetLine (lineNumber);
						int insertOffset = lineSegment.GetLogicalColumn (data, visualInsertLocation.Column) - 1;
						string textToInsert;
						if (lineSegment.Length < insertOffset) {
							int visualLastColumn = lineSegment.GetVisualColumn (data, lineSegment.Length + 1);
							int charsToInsert = visualInsertLocation.Column - visualLastColumn;
							int spaceCount = charsToInsert % data.Options.TabSize;
							textToInsert = new string ('\t', (charsToInsert - spaceCount) / data.Options.TabSize) + new string (' ', spaceCount) + text;
							insertOffset = lineSegment.Length;
						} else {
							textToInsert = text;
						}
						inserted = data.Insert (lineSegment.Offset + insertOffset, textToInsert);
					}
				} else {
					offset = version.MoveOffsetTo (data.Document.Version, offset);
					inserted = data.PasteText (offset, text);
				}
			}
			return inserted;
		}
示例#48
0
        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--;
                }
            }
        }
示例#49
0
        public static void Right(TextEditorData data)
        {
            using (var undo = data.OpenUndoGroup()) {
                if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection)
                {
                    data.Caret.Offset = System.Math.Max(data.SelectionAnchor, data.Caret.Offset);
                    data.ClearSelection();
                    return;
                }

                DocumentLine line = data.Document.GetLine(data.Caret.Line);
                IEnumerable <FoldSegment> foldings = data.Document.GetStartFoldings(line);
                FoldSegment segment = null;
                foreach (FoldSegment folding in foldings)
                {
                    if (folding.IsFolded && folding.Column == data.Caret.Column)
                    {
                        segment = folding;
                        break;
                    }
                }
                if (segment != null)
                {
                    data.Caret.Offset = segment.EndOffset;
                    return;
                }

                if (data.Caret.Column >= line.Length + 1)
                {
                    int nextColumn;
                    if (data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual && data.Caret.Column == DocumentLocation.MinColumn)
                    {
                        nextColumn = data.GetVirtualIndentationColumn(data.Caret.Location);
                    }
                    else if (data.Caret.AllowCaretBehindLineEnd)
                    {
                        nextColumn = data.Caret.Column + 1;
                    }
                    else
                    {
                        nextColumn = line.Length + 1;
                    }

                    if (data.Caret.Column < nextColumn)
                    {
                        data.Caret.Column = nextColumn;
                    }
                    else
                    {
                        if (data.Caret.Line < data.LineCount)
                        {
                            data.Caret.Location = new DocumentLocation(data.Caret.Line + 1, DocumentLocation.MinColumn);
                        }
                    }
                }
                else
                {
                    data.Caret.Column++;
                }
            }
        }
示例#50
0
        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);
        }
示例#51
0
 public static void PreviousSubword(TextEditorData data)
 {
     using (var undo = data.OpenUndoGroup()) {
         data.Caret.Offset = data.FindPrevSubwordOffset(data.Caret.Offset);
     }
 }
示例#52
0
		public static void IndentSelection (TextEditorData data)
		{
			if (!data.IsSomethingSelected)
				return;
			int startLineNr, endLineNr;
			GetSelectedLines (data, out startLineNr, out endLineNr);
			var anchor = data.MainSelection.Anchor;
			var lead = data.MainSelection.Lead;
			var indentationString = data.Options.IndentationString;
			using (var undo = data.OpenUndoGroup (OperationType.Format)) {
				foreach (DocumentLine line in data.SelectedLines) {
					if (data.Options.IndentStyle == IndentStyle.Virtual && line.Length == 0)
						continue;
					data.Insert (line.Offset, indentationString);
				}
			}
			int chars = indentationString.Length;
			var leadCol = lead.Column > 1 || lead < anchor ? lead.Column + chars : 1;
			var anchorCol = anchor.Column > 1 || anchor < lead ? anchor.Column + chars : 1;
			data.SetSelection (anchor.Line, anchorCol, lead.Line, leadCol);
			data.Document.RequestUpdate (new MultipleLineUpdate (startLineNr, endLineNr));
			data.Document.CommitDocumentUpdate ();
		}
示例#53
0
        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();
            }
        }
示例#54
0
		public static void InsertNewLine (TextEditorData data)
		{
			if (!data.CanEditSelection)
				return;
			
			using (var undo = data.OpenUndoGroup ()) {
				if (data.IsSomethingSelected) {
					var end = data.MainSelection.End;
					data.DeleteSelectedText ();
					if (end.Column == 1) {
						CaretMoveActions.InternalCaretMoveHome (data, true, false);
						return;
					}
				}
				switch (data.Options.IndentStyle) {
				case IndentStyle.None:
					data.InsertAtCaret (data.EolMarker);
					break;
				case IndentStyle.Auto:
					data.EnsureCaretIsNotVirtual ();
					var indent = data.Document.GetLineIndent (data.Caret.Line);
					data.InsertAtCaret (data.EolMarker);
					data.EnsureCaretIsNotVirtual ();
					if (data.GetLine (data.Caret.Line).Length == 0)
						data.InsertAtCaret (indent);
					break;
				case IndentStyle.Smart:
					if (!data.HasIndentationTracker)
						goto case IndentStyle.Auto;
					NewLineSmartIndent (data);
					break;
				case IndentStyle.Virtual:
					if (!data.HasIndentationTracker)
						goto case IndentStyle.Auto;
					var oldLine = data.Caret.Line;
					var curLine = data.GetLine (oldLine);
					var indentCol = data.GetVirtualIndentationColumn (data.Caret.Location);
					if (curLine.Length >= data.Caret.Column) {
						NewLineSmartIndent (data);
						data.FixVirtualIndentation ();
						data.FixVirtualIndentation (oldLine);
						break;
					}
					data.Insert (data.Caret.Offset, data.EolMarker);
					data.FixVirtualIndentation (oldLine);
					data.Caret.Column = indentCol;
					break;
				default:
					throw new ArgumentOutOfRangeException ();
				}
			}
		}
示例#55
0
		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;
		}
示例#56
0
        public static void InsertNewLine(TextEditorData data)
        {
            if (!data.CanEditSelection)
            {
                return;
            }

            using (var undo = data.OpenUndoGroup()) {
                if (data.IsSomethingSelected)
                {
                    var end = data.MainSelection.End;
                    data.DeleteSelectedText();
                    if (end.Column == 1)
                    {
                        CaretMoveActions.InternalCaretMoveHome(data, true, false);
                        return;
                    }
                }
                switch (data.Options.IndentStyle)
                {
                case IndentStyle.None:
                    data.InsertAtCaret(data.EolMarker);
                    break;

                case IndentStyle.Auto:
                    data.EnsureCaretIsNotVirtual();
                    var indent = data.Document.GetLineIndent(data.Caret.Line);
                    data.InsertAtCaret(data.EolMarker);
                    data.EnsureCaretIsNotVirtual();
                    if (data.GetLine(data.Caret.Line).Length == 0)
                    {
                        data.InsertAtCaret(indent);
                    }
                    break;

                case IndentStyle.Smart:
                    if (!data.HasIndentationTracker)
                    {
                        goto case IndentStyle.Auto;
                    }
                    NewLineSmartIndent(data);
                    break;

                case IndentStyle.Virtual:
                    if (!data.HasIndentationTracker)
                    {
                        goto case IndentStyle.Auto;
                    }
                    var oldLine   = data.Caret.Line;
                    var curLine   = data.GetLine(oldLine);
                    var indentCol = data.GetVirtualIndentationColumn(data.Caret.Location);
                    if (curLine.Length >= data.Caret.Column)
                    {
                        NewLineSmartIndent(data);
                        data.FixVirtualIndentation();
                        data.FixVirtualIndentation(oldLine);
                        break;
                    }
                    data.Insert(data.Caret.Offset, data.EolMarker);
                    data.FixVirtualIndentation(oldLine);
                    data.Caret.Column = indentCol;
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
            }
        }
示例#57
0
		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;
		}
示例#58
0
        /// <summary>
        /// Transpose characters (Emacs C-t)
        /// </summary>
        public static void TransposeCharacters(TextEditorData data)
        {
            if (data.Caret.Offset == 0)
            {
                return;
            }
            DocumentLine line = data.Document.GetLine(data.Caret.Line);

            if (line == null)
            {
                return;
            }
            using (var undoGroup = data.OpenUndoGroup()) {
                int  transposeOffset = data.Caret.Offset - 1;
                char ch;
                if (data.Caret.Column == 0)
                {
                    DocumentLine lineAbove = data.Document.GetLine(data.Caret.Line - 1);
                    if (lineAbove.Length == 0 && line.Length == 0)
                    {
                        return;
                    }

                    if (line.Length != 0)
                    {
                        ch = data.Document.GetCharAt(data.Caret.Offset);
                        data.Remove(data.Caret.Offset, 1);
                        data.Insert(lineAbove.Offset + lineAbove.Length, ch.ToString());
                        data.Document.CommitLineUpdate(data.Caret.Line - 1);
                        return;
                    }

                    int lastCharOffset = lineAbove.Offset + lineAbove.Length - 1;
                    ch = data.Document.GetCharAt(lastCharOffset);
                    data.Remove(lastCharOffset, 1);
                    data.InsertAtCaret(ch.ToString());
                    return;
                }

                int offset = data.Caret.Offset;
                if (data.Caret.Column >= line.Length + 1)
                {
                    offset          = line.Offset + line.Length - 1;
                    transposeOffset = offset - 1;
                    // case one char in line:
                    if (transposeOffset < line.Offset)
                    {
                        DocumentLine lineAbove = data.Document.GetLine(data.Caret.Line - 1);
                        transposeOffset = lineAbove.Offset + lineAbove.Length;
                        ch = data.Document.GetCharAt(offset);
                        data.Remove(offset, 1);
                        data.Insert(transposeOffset, ch.ToString());
                        data.Caret.Offset = line.Offset;
                        data.Document.CommitLineUpdate(data.Caret.Line - 1);
                        return;
                    }
                }

                ch = data.Document.GetCharAt(offset);
                data.Replace(offset, 1, data.Document.GetCharAt(transposeOffset).ToString());
                data.Replace(transposeOffset, 1, ch.ToString());
                if (data.Caret.Column < line.Length + 1)
                {
                    data.Caret.Offset = offset + 1;
                }
            }
        }
示例#59
0
		public override void OnTheFlyFormat (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, 
			TextEditorData data, int startOffset, int endOffset)
		{
			var parser = new CSharpParser ();
			var compilationUnit = parser.ParseSnippet (data);
			if (compilationUnit == null) {
				Console.WriteLine ("couldn't parse : " + data.Text);
				return;
			}
			
			if (parser.HasErrors)
				return;
			
			var policy = policyParent.Get<CSharpFormattingPolicy> (mimeTypeChain);
			var adapter = new TextEditorDataAdapter (data);
			
			var formattingVisitor = new ICSharpCode.NRefactory.CSharp.AstFormattingVisitor (policy.CreateOptions (), adapter, new FormattingActionFactory (data)) {
				HadErrors =  parser.HasErrors
			};
			
			var changes = new List<ICSharpCode.NRefactory.CSharp.Refactoring.Action> ();
			changes.AddRange (formattingVisitor.Changes.
				Where (c => (startOffset <= c.Offset && c.Offset < endOffset)));
			using (var undo = data.OpenUndoGroup ()) {
				MDRefactoringContext.MdScript.RunActions (changes, null);
			}
		}
示例#60
0
        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++;
                }
            }
        }