Replace() public method

public Replace ( int offset, int count, string value ) : int
offset int
count int
value string
return int
Example #1
1
		public override void CorrectIndenting (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, 
			TextEditorData data, int line)
		{
			DocumentLine lineSegment = data.Document.GetLine (line);
			if (lineSegment == null)
				return;

			try {
				var policy = policyParent.Get<CSharpFormattingPolicy> (mimeTypeChain);
				var tracker = new CSharpIndentEngine (data.Document, data.CreateNRefactoryTextEditorOptions (),  policy.CreateOptions ());

				tracker.Update (lineSegment.Offset);
				for (int i = lineSegment.Offset; i < lineSegment.Offset + lineSegment.Length; i++) {
					tracker.Push (data.Document.GetCharAt (i));
				}

				string curIndent = lineSegment.GetIndentation (data.Document);

				int nlwsp = curIndent.Length;
				if (!tracker.LineBeganInsideMultiLineComment || (nlwsp < lineSegment.LengthIncludingDelimiter && data.Document.GetCharAt (lineSegment.Offset + nlwsp) == '*')) {
					// Possibly replace the indent
					string newIndent = tracker.ThisLineIndent;
					if (newIndent != curIndent) 
						data.Replace (lineSegment.Offset, nlwsp, newIndent);
				}
			} catch (Exception e) {
				LoggingService.LogError ("Error while indenting", e);
			}
		}
Example #2
1
		public override void CorrectIndenting (PolicyContainer policyParent, IEnumerable<string> mimeTypeChain, 
			TextEditorData data, int line)
		{
			LineSegment lineSegment = data.Document.GetLine (line);
			if (lineSegment == null)
				return;

			var policy = policyParent.Get<CFormattingPolicy> (mimeTypeChain);
			var tracker = new DocumentStateTracker<CIndentEngine> (new CIndentEngine (policy), data);
			tracker.UpdateEngine (lineSegment.Offset);
			for (int i = lineSegment.Offset; i < lineSegment.Offset + lineSegment.EditableLength; i++) {
				tracker.Engine.Push (data.Document.GetCharAt (i));
			}

			string curIndent = lineSegment.GetIndentation (data.Document);

			int nlwsp = curIndent.Length;
			if (!tracker.Engine.LineBeganInsideMultiLineComment || (nlwsp < lineSegment.Length && data.Document.GetCharAt (lineSegment.Offset + nlwsp) == '*')) {
				// Possibly replace the indent
				string newIndent = tracker.Engine.ThisLineIndent;
				if (newIndent != curIndent) 
					data.Replace (lineSegment.Offset, nlwsp, newIndent);
			}
			tracker.Dispose ();
		}
Example #3
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;
			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;
		}
Example #4
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> (data.Document.GetMarkers(nextLine));
                data.Document.ClearMarkers(nextLine);
                var loc = data.Caret.Location;
                for (int i = lineEnd + 1; i >= lineStart; i--)
                {
                    DocumentLine cur  = data.Document.GetLine(i);
                    DocumentLine prev = data.Document.GetLine(i - 1);
                    data.Replace(cur.Offset, cur.Length, i != lineStart ? data.Document.GetTextAt(prev.Offset, prev.Length) : text);
                    data.Document.ClearMarkers(data.Document.GetLine(i));
                    foreach (TextLineMarker marker in (i != lineStart ? data.Document.GetMarkers(data.Document.GetLine(i - 1)) : prevLineMarkers))
                    {
                        data.Document.AddMarker(data.Document.GetLine(i), marker);
                    }
                }

                data.Caret.Location = new DocumentLocation(loc.Line + 1, loc.Column);
                if (setSelection)
                {
                    data.SetSelection(anchor.Line + 1, anchor.Column, lead.Line + 1, lead.Column);
                }
            }
        }
Example #5
0
        public static void MoveBlockDown(TextEditorData data)
        {
            int  lineStart    = data.Caret.Line;
            int  lineEnd      = data.Caret.Line;
            bool setSelection = lineStart != lineEnd;

            if (data.IsSomethingSelected)
            {
                setSelection = true;
                lineStart    = data.MainSelection.MinLine;
                lineEnd      = data.MainSelection.MaxLine;
            }

            if (lineStart <= 0)
            {
                return;
            }
            data.Document.BeginAtomicUndo();

            //Mono.TextEditor.LineSegment startLine = data.Document.GetLine (lineStart);
            //int relCaretOffset = data.Caret.Offset - startLine.Offset;

            Mono.TextEditor.LineSegment nextLine = data.Document.GetLine(lineEnd + 1);
            if (nextLine == null)
            {
                return;
            }
            string            text            = data.Document.GetTextAt(nextLine.Offset, nextLine.EditableLength);
            List <TextMarker> prevLineMarkers = new List <TextMarker> (nextLine.Markers);

            nextLine.ClearMarker();

            for (int i = lineEnd + 1; i >= lineStart; i--)
            {
                LineSegment cur  = data.Document.GetLine(i);
                LineSegment prev = data.Document.GetLine(i - 1);
                data.Replace(cur.Offset, cur.EditableLength, i != lineStart ? data.Document.GetTextAt(prev.Offset, prev.EditableLength) : text);
                data.Document.GetLine(i).ClearMarker();
                foreach (TextMarker marker in (i != lineStart ? data.Document.GetLine(i - 1).Markers : prevLineMarkers))
                {
                    data.Document.GetLine(i).AddMarker(marker);
                }
            }

            data.Caret.Line++;
            if (setSelection)
            {
                data.SetSelection(data.Document.GetLine(lineStart + 1).Offset, data.Document.GetLine(lineEnd + 1).Offset + data.Document.GetLine(lineEnd + 1).EditableLength);
            }
            data.Document.EndAtomicUndo();
        }
Example #6
0
        public static void MoveBlockUp(TextEditorData data)
        {
            int  lineStart    = data.Caret.Line;
            int  lineEnd      = data.Caret.Line;
            bool setSelection = lineStart != lineEnd;

            if (data.IsSomethingSelected)
            {
                setSelection = true;
                lineStart    = data.MainSelection.MinLine;
                lineEnd      = data.MainSelection.MaxLine;
            }

            if (lineStart <= 0)
            {
                return;
            }

            using (var undo = data.OpenUndoGroup()) {
                //Mono.TextEditor.LineSegment startLine = data.Document.GetLine (lineStart);
                //int relCaretOffset = data.Caret.Offset - startLine.Offset;

                Mono.TextEditor.LineSegment prevLine = data.Document.GetLine(lineStart - 1);
                string            text            = data.Document.GetTextAt(prevLine.Offset, prevLine.EditableLength);
                List <TextMarker> prevLineMarkers = new List <TextMarker> (prevLine.Markers);
                prevLine.ClearMarker();

                for (int i = lineStart - 1; i <= lineEnd; i++)
                {
                    LineSegment cur  = data.Document.GetLine(i);
                    LineSegment next = data.Document.GetLine(i + 1);
                    data.Replace(cur.Offset, cur.EditableLength, i != lineEnd ? data.Document.GetTextAt(next.Offset, next.EditableLength) : text);
                    data.Document.GetLine(i).ClearMarker();
                    foreach (TextMarker marker in (i != lineEnd ? data.Document.GetLine(i + 1).Markers : prevLineMarkers))
                    {
                        data.Document.GetLine(i).AddMarker(marker);
                    }
                }

                data.Caret.Line--;
                if (setSelection)
                {
                    data.SetSelection(data.Document.GetLine(lineStart - 1).Offset, data.Document.GetLine(lineEnd - 1).Offset + data.Document.GetLine(lineEnd - 1).EditableLength);
                }
            }
        }
Example #7
0
        public static void SortSelectedLines(TextEditorData data)
        {
            var start = data.MainSelection.Start;
            var end   = data.MainSelection.End;
            var caret = data.Caret.Location;

            int startLine = start.Line;
            int endLine   = end.Line;

            if (startLine == endLine)
            {
                return;
            }

            int length = 0;
            var lines  = new string[endLine - startLine + 1];

            for (int i = startLine; i <= endLine; i++)
            {
                //get lines *with* line endings
                var lineText = data.GetLineText(i, true);
                lines[i - startLine] = lineText;
                length += lineText.Length;
            }

            var linesUnsorted = new string[lines.Length];

            Array.Sort(lines, StringComparer.Ordinal);

            bool changed = false;

            for (int i = 0; i <= lines.Length; i++)
            {
                //can't simply use reference comparison as Array.Sort is not stable
                if (string.Equals(lines[i], linesUnsorted[i], StringComparison.Ordinal))
                {
                    continue;
                }
                changed = true;
                break;
            }
            if (!changed)
            {
                return;
            }


            var sb = new StringBuilder();

            for (int i = 0; i < lines.Length; i++)
            {
                sb.Append(lines[i]);
            }

            var startOffset = data.Document.LocationToOffset(new TextLocation(startLine, 0));

            data.Replace(startOffset, length, sb.ToString());

            data.Caret.Location = LimitColumn(data, caret);
            data.SetSelection(LimitColumn(data, start), LimitColumn(data, end));
        }
		void ConvertVerbatimStringToNormal (TextEditorData textEditorData, int offset)
		{
			var endOffset = offset;
			while (endOffset < textEditorData.Length) {
				char ch = textEditorData.GetCharAt (endOffset);
				if (ch == '"' && (endOffset + 1 < textEditorData.Length && textEditorData.GetCharAt (endOffset + 1) == '"'))  {
					endOffset += 2;
					continue;
				}
				if (ch == '"')
					break;
				endOffset++;
			}
			textEditorData.Replace (offset, endOffset - offset, ConvertToStringLiteral (ConvertFromVerbatimString (textEditorData.GetTextAt (offset, endOffset - offset))));
		}
Example #9
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);
                }
            }
        }
		public static bool FixLineStart (TextEditorData textEditorData, DocumentStateTracker<CSharpIndentEngine> stateTracker, int lineNumber)
		{
			if (lineNumber > DocumentLocation.MinLine) {
				DocumentLine line = textEditorData.Document.GetLine (lineNumber);
				if (line == null)
					return false;

				DocumentLine prevLine = textEditorData.Document.GetLine (lineNumber - 1);
				if (prevLine == null)
					return false;
				string trimmedPreviousLine = textEditorData.Document.GetTextAt (prevLine).TrimStart ();

				//xml doc comments
				//check previous line was a doc comment
				//check there's a following line?
				if (trimmedPreviousLine.StartsWith ("///", StringComparison.Ordinal)) {
					if (textEditorData.GetTextAt (line.Offset, line.Length).TrimStart ().StartsWith ("///", StringComparison.Ordinal))
						return false;
					//check that the newline command actually inserted a newline
					textEditorData.EnsureCaretIsNotVirtual ();
					string nextLine = textEditorData.Document.GetTextAt (textEditorData.Document.GetLine (lineNumber + 1)).TrimStart ();

					if (trimmedPreviousLine.Length > "///".Length || nextLine.StartsWith ("///", StringComparison.Ordinal)) {
						var insertionPoint = line.Offset + line.GetIndentation (textEditorData.Document).Length;
						textEditorData.Insert (insertionPoint, "/// ");
						return true;
					}
					//multi-line comments
				} else if (stateTracker.Engine.IsInsideMultiLineComment) {
					if (textEditorData.GetTextAt (line.Offset, line.Length).TrimStart ().StartsWith ("*", StringComparison.Ordinal))
						return false;
					textEditorData.EnsureCaretIsNotVirtual ();
					string commentPrefix = string.Empty;
					if (trimmedPreviousLine.StartsWith ("* ", StringComparison.Ordinal)) {
						commentPrefix = "* ";
					} else if (trimmedPreviousLine.StartsWith ("/**", StringComparison.Ordinal) || trimmedPreviousLine.StartsWith ("/*", StringComparison.Ordinal)) {
						commentPrefix = " * ";
					} else if (trimmedPreviousLine.StartsWith ("*", StringComparison.Ordinal)) {
						commentPrefix = "*";
					}

					int indentSize = line.GetIndentation (textEditorData.Document).Length;
					var insertedText = prevLine.GetIndentation (textEditorData.Document) + commentPrefix;
					textEditorData.Replace (line.Offset, indentSize, insertedText);
					textEditorData.Caret.Offset = line.Offset + insertedText.Length;
					return true;
				} else if (stateTracker.Engine.IsInsideStringLiteral) {
					var lexer = new CSharpCompletionEngineBase.MiniLexer (textEditorData.Document.GetTextAt (0, prevLine.EndOffset));
					lexer.Parse ();
					if (!lexer.IsInString)
						return false;
					textEditorData.EnsureCaretIsNotVirtual ();
					textEditorData.Insert (prevLine.Offset + prevLine.Length, "\" +");

					int indentSize = line.GetIndentation (textEditorData.Document).Length;
					var insertedText = prevLine.GetIndentation (textEditorData.Document) + (trimmedPreviousLine.StartsWith ("\"", StringComparison.Ordinal) ? "" : "\t") + "\"";
					textEditorData.Replace (line.Offset, indentSize, insertedText);
					return true;
				}
			}
			return false;
		}
Example #11
0
        public static void Join(TextEditorData data)
        {
            int startLine, endLine, startOffset, length;

            if (data.IsSomethingSelected) {
                startLine = data.Document.OffsetToLineNumber (data.SelectionRange.Offset);
                endLine = data.Document.OffsetToLineNumber (data.SelectionRange.EndOffset - 1);
            } else {
                startLine = endLine = data.Caret.Line;
            }

            //single-line joins
            if (endLine == startLine)
                endLine++;

            if (endLine > data.Document.LineCount)
                return;

            DocumentLine seg = data.Document.GetLine (startLine);
            startOffset = seg.Offset;
            StringBuilder sb = new StringBuilder (data.Document.GetTextAt (seg).TrimEnd ());
            //lastSpaceOffset = startOffset + sb.Length;

            for (int i = startLine + 1; i <= endLine; i++) {
                seg = data.Document.GetLine (i);
                //lastSpaceOffset = startOffset + sb.Length;
                sb.Append (" ");
                sb.Append (data.Document.GetTextAt (seg).Trim ());
            }
            length = (seg.Offset - startOffset) + seg.Length;
            // TODO: handle conversion issues ?
            data.Replace (startOffset, length, sb.ToString ());
        }
		static void ConvertNormalToVerbatimString (TextEditorData textEditorData, int offset)
		{
			var endOffset = offset;
			while (endOffset < textEditorData.Length) {
				char ch = textEditorData.GetCharAt (endOffset);
				if (ch == '\\') {
					if (endOffset + 1 < textEditorData.Length && NewLine.IsNewLine (textEditorData.GetCharAt (endOffset + 1)))
						return;

					endOffset += 2;
					continue;
				}
				if (ch == '"')
					break;
				if (NewLine.IsNewLine (ch))
					return;
				endOffset++;
			}
			if (offset > endOffset || endOffset == textEditorData.Length)
				return;
			var plainText = TextPasteUtils.StringLiteralPasteStrategy.Instance.Decode (textEditorData.GetTextAt (offset, endOffset - offset));
			var newText = TextPasteUtils.VerbatimStringStrategy.Encode (plainText);
			textEditorData.Replace (offset, endOffset - offset, newText);
		}
Example #13
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();
            }
        }
		/// <summary>
		/// Transpose characters (Emacs C-t)
		/// </summary>
		public static void TransposeCharacters (TextEditorData data)
		{
			if (data.Caret.Offset == 0)
				return;
			DocumentLine line = data.Document.GetLine (data.Caret.Line);
			if (line == null)
				return;
			int transposeOffset = data.Caret.Offset - 1;
			char ch;
			if (data.Caret.Column == 0) {
				DocumentLine lineAbove = data.Document.GetLine (data.Caret.Line - 1);
				if (lineAbove.Length == 0 && line.Length == 0) 
					return;
				
				if (line.Length != 0) {
					ch = data.Document.GetCharAt (data.Caret.Offset);
					data.Remove (data.Caret.Offset, 1);
					data.Insert (lineAbove.Offset + lineAbove.Length, ch.ToString ());
					data.Document.CommitLineUpdate (data.Caret.Line - 1);
					return;
				}
				
				int lastCharOffset = lineAbove.Offset + lineAbove.Length - 1;
				ch = data.Document.GetCharAt (lastCharOffset);
				data.Remove (lastCharOffset, 1);
				data.InsertAtCaret (ch.ToString ());
				return;
			}
			
			int offset = data.Caret.Offset;
			if (data.Caret.Column >= line.Length + 1) {
				offset = line.Offset + line.Length - 1;
				transposeOffset = offset - 1;
				// case one char in line:
				if (transposeOffset < line.Offset) {
					DocumentLine lineAbove = data.Document.GetLine (data.Caret.Line - 1);
					transposeOffset = lineAbove.Offset + lineAbove.Length;
					ch = data.Document.GetCharAt (offset);
					data.Remove (offset, 1);
					data.Insert (transposeOffset, ch.ToString ());
					data.Caret.Offset = line.Offset;
					data.Document.CommitLineUpdate (data.Caret.Line - 1);
					return;
				}
			}
			
			ch = data.Document.GetCharAt (offset);
			data.Replace (offset, 1, data.Document.GetCharAt (transposeOffset).ToString ());
			data.Replace (transposeOffset, 1, ch.ToString ());
			if (data.Caret.Column < line.Length + 1)
				data.Caret.Offset = offset + 1;
		}
Example #15
0
        public static void ToggleCase(TextEditorData data)
        {
            if (data.IsSomethingSelected) {
                if (!data.CanEditSelection)
                    return;

                StringBuilder sb = new StringBuilder (data.SelectedText);
                for (int i = 0; i < sb.Length; i++) {
                    char ch = sb [i];
                    if (Char.IsLower (ch))
                        sb [i] = Char.ToUpper (ch);
                    else if (Char.IsUpper (ch))
                        sb [i] = Char.ToLower (ch);
                }
                data.Replace (data.SelectionRange.Offset, data.SelectionRange.Length, sb.ToString ());
            } else if (data.CanEdit (data.Caret.Line)) {
                char ch = data.Document.GetCharAt (data.Caret.Offset);
                if (Char.IsLower (ch))
                    ch = Char.ToUpper (ch);
                else if (Char.IsUpper (ch))
                    ch = Char.ToLower (ch);
                var caretOffset = data.Caret.Offset;
                int length = data.Replace (caretOffset, 1, new string (ch, 1));
                DocumentLine seg = data.Document.GetLine (data.Caret.Line);
                if (data.Caret.Column < seg.Length)
                    data.Caret.Offset = caretOffset + length;
            }
        }
Example #16
0
        protected void InsertCharacter(uint unicodeKey)
        {
            if (!textEditorData.CanEdit(Data.Caret.Line))
            {
                return;
            }

            HideMouseCursor();

            Document.BeginAtomicUndo();
            if (textEditorData.IsSomethingSelected && textEditorData.MainSelection.SelectionMode == SelectionMode.Block)
            {
                textEditorData.Caret.PreserveSelection = true;
                if (!textEditorData.MainSelection.IsDirty)
                {
                    textEditorData.DeleteSelectedText(false);
                    textEditorData.MainSelection.IsDirty = true;
                }
            }
            else
            {
                textEditorData.DeleteSelectedText();
            }

            char ch = (char)unicodeKey;

            if (!char.IsControl(ch) && textEditorData.CanEdit(Caret.Line))
            {
                LineSegment line = Document.GetLine(Caret.Line);
                if (Caret.IsInInsertMode || Caret.Column >= line.EditableLength)
                {
                    string text = Caret.Column > line.EditableLength ? textEditorData.GetVirtualSpaces(Caret.Line, Caret.Column) + ch.ToString() : ch.ToString();
                    if (textEditorData.IsSomethingSelected && textEditorData.MainSelection.SelectionMode == SelectionMode.Block)
                    {
                        int length = 0;
                        for (int lineNumber = textEditorData.MainSelection.MinLine; lineNumber <= textEditorData.MainSelection.MaxLine; lineNumber++)
                        {
                            length = textEditorData.Insert(textEditorData.Document.GetLine(lineNumber).Offset + Caret.Column, text);
                        }
                        Caret.Column += length - 1;
                        textEditorData.MainSelection.Lead    = new DocumentLocation(textEditorData.MainSelection.Lead.Line, Caret.Column + 1);
                        textEditorData.MainSelection.IsDirty = true;
                        Document.CommitMultipleLineUpdate(textEditorData.MainSelection.MinLine, textEditorData.MainSelection.MaxLine);
                    }
                    else
                    {
                        int length = textEditorData.Insert(Caret.Offset, text);
                        Caret.Column += length - 1;
                    }
                }
                else
                {
                    int length = textEditorData.Replace(Caret.Offset, 1, ch.ToString());
                    if (length > 1)
                    {
                        Caret.Offset += length - 1;
                    }
                }
                // That causes unnecessary redraws:
                //				bool autoScroll = Caret.AutoScrollToCaret;
                Caret.Column++;
                //				Caret.AutoScrollToCaret = autoScroll;
                //				if (autoScroll)
                //					Editor.ScrollToCaret ();
                //				Document.RequestUpdate (new LineUpdate (Caret.Line));
                //				Document.CommitDocumentUpdate ();
            }
            if (textEditorData.IsSomethingSelected && textEditorData.MainSelection.SelectionMode == SelectionMode.Block)
            {
                textEditorData.Caret.PreserveSelection = false;
            }
            Document.EndAtomicUndo();
            Document.OptimizeTypedUndo();
        }
Example #17
0
		public static void MoveBlockDown (TextEditorData data)
		{
			int lineStart = data.Caret.Line;
			int lineEnd = data.Caret.Line;
			bool setSelection = lineStart != lineEnd;
			if (data.IsSomethingSelected) {
				setSelection = true;
				lineStart = data.MainSelection.MinLine;
				lineEnd = data.MainSelection.MaxLine;
			}
			
			if (lineStart <= 0)
				return;
			data.Document.BeginAtomicUndo ();
			
			Mono.TextEditor.LineSegment startLine = data.Document.GetLine (lineStart);
			int relCaretOffset = data.Caret.Offset - startLine.Offset;
			
			Mono.TextEditor.LineSegment nextLine = data.Document.GetLine (lineEnd + 1);
			string text = data.Document.GetTextAt (nextLine.Offset, nextLine.EditableLength);
			List<TextMarker> prevLineMarkers = new List<TextMarker> (nextLine.Markers);
			nextLine.ClearMarker ();
			
			for (int i = lineEnd + 1; i >= lineStart; i--) {
				LineSegment cur = data.Document.GetLine (i);
				LineSegment prev = data.Document.GetLine (i - 1);
				data.Replace (cur.Offset, cur.EditableLength, i != lineStart ? data.Document.GetTextAt (prev.Offset, prev.EditableLength) : text);
				data.Document.GetLine (i).ClearMarker ();
				foreach (TextMarker marker in (i != lineStart ? data.Document.GetLine (i - 1).Markers : prevLineMarkers)) {
					data.Document.GetLine (i).AddMarker (marker);
				}
			}
			
			data.Caret.Offset = nextLine.Offset + relCaretOffset;
			if (setSelection)
				data.SetSelection (data.Document.GetLine (lineStart + 1).Offset, data.Document.GetLine (lineEnd + 1).Offset + data.Document.GetLine (lineEnd + 1).EditableLength);
			data.Document.EndAtomicUndo ();
		}
Example #18
0
		public static void SortSelectedLines (TextEditorData data)
		{
			var start = data.MainSelection.Start;
			var end = data.MainSelection.End;
			var caret = data.Caret.Location;

			int startLine = start.Line;
			int endLine = end.Line;
			if (startLine == endLine)
				return;

			int length = 0;
			var lines = new string[endLine - startLine + 1];
			for (int i = startLine; i <= endLine; i++) {
				//get lines *with* line endings
				var lineText = data.GetLineText (i, true);
				lines [i - startLine] = lineText;
				length += lineText.Length;
			}

			var linesUnsorted = new string[lines.Length];

			Array.Sort (lines, StringComparer.Ordinal);

			bool changed = false;
			for (int i = 0; i <= lines.Length; i++) {
				//can't simply use reference comparison as Array.Sort is not stable
				if (string.Equals (lines [i], linesUnsorted [i], StringComparison.Ordinal)) {
					continue;
				}
				changed = true;
				break;
			}
			if (!changed) {
				return;
			}


			var sb = new StringBuilder ();
			for (int i = 0; i < lines.Length; i++) {
				sb.Append (lines [i]);
			}

			var startOffset = data.Document.LocationToOffset (new TextLocation (startLine, 0));
			data.Replace (startOffset, length, sb.ToString ());

			data.Caret.Location = LimitColumn (data, caret);
			data.SetSelection (LimitColumn (data, start), LimitColumn (data, end));
		}
		public static void MoveBlockDown (TextEditorData data)
		{
			int lineStart = data.Caret.Line;
			int lineEnd = data.Caret.Line;
			bool setSelection = lineStart != lineEnd;
			DocumentLocation anchor = DocumentLocation.Empty, lead = DocumentLocation.Empty;
			if (data.IsSomethingSelected) {
				setSelection = true;
				lineStart = data.MainSelection.MinLine;
				lineEnd = data.MainSelection.MaxLine;
				anchor = data.MainSelection.Anchor;
				lead = data.MainSelection.Lead;
			}
			
			if (lineStart <= 0)
				return;
			using (var undo = data.OpenUndoGroup ()) {
				
				//Mono.TextEditor.LineSegment startLine = data.Document.GetLine (lineStart);
				//int relCaretOffset = data.Caret.Offset - startLine.Offset;
				
				Mono.TextEditor.DocumentLine nextLine = data.Document.GetLine (lineEnd + 1);
				if (nextLine == null)
					return;
				string text = data.Document.GetTextAt (nextLine.Offset, nextLine.Length);
				List<TextLineMarker> prevLineMarkers = new List<TextLineMarker> (nextLine.Markers);
				nextLine.ClearMarker ();
				var loc = data.Caret.Location;
				for (int i = lineEnd + 1; i >= lineStart; i--) {
					DocumentLine cur = data.Document.GetLine (i);
					DocumentLine prev = data.Document.GetLine (i - 1);
					data.Replace (cur.Offset, cur.Length, i != lineStart ? data.Document.GetTextAt (prev.Offset, prev.Length) : text);
					data.Document.GetLine (i).ClearMarker ();
					foreach (TextLineMarker marker in (i != lineStart ? data.Document.GetLine (i - 1).Markers : prevLineMarkers)) {
						data.Document.GetLine (i).AddMarker (marker);
					}
				}
				
				data.Caret.Location = new DocumentLocation (loc.Line + 1, loc.Column);
				if (setSelection)
					data.SetSelection (anchor.Line + 1, anchor.Column, lead.Line + 1, lead.Column);
			}
		}
Example #20
0
        protected void InsertCharacter(uint unicodeKey)
        {
            if (!textEditorData.CanEdit(Data.Caret.Line))
            {
                return;
            }

            HideMouseCursor();
            using (var undo = Document.OpenUndoGroup()) {
                textEditorData.DeleteSelectedText(textEditorData.IsSomethingSelected ? textEditorData.MainSelection.SelectionMode != SelectionMode.Block : true);

                char ch = (char)unicodeKey;
                if (!char.IsControl(ch) && textEditorData.CanEdit(Caret.Line))
                {
                    LineSegment line = Document.GetLine(Caret.Line);
                    if (Caret.IsInInsertMode || Caret.Column >= line.EditableLength + 1)
                    {
                        string text = Caret.Column > line.EditableLength + 1 ? textEditorData.GetVirtualSpaces(Caret.Line, Caret.Column) + ch.ToString() : ch.ToString();
                        if (textEditorData.IsSomethingSelected && textEditorData.MainSelection.SelectionMode == SelectionMode.Block)
                        {
                            int length = 0;
                            var visualInsertLocation = editor.LogicalToVisualLocation(Caret.Location);
                            for (int lineNumber = textEditorData.MainSelection.MinLine; lineNumber <= textEditorData.MainSelection.MaxLine; lineNumber++)
                            {
                                LineSegment lineSegment  = textEditorData.GetLine(lineNumber);
                                int         insertOffset = lineSegment.GetLogicalColumn(textEditorData, visualInsertLocation.Column) - 1;
                                string      textToInsert;
                                if (lineSegment.EditableLength < insertOffset)
                                {
                                    int visualLastColumn = lineSegment.GetVisualColumn(textEditorData, lineSegment.EditableLength + 1);
                                    int charsToInsert    = visualInsertLocation.Column - visualLastColumn;
                                    int spaceCount       = charsToInsert % editor.Options.TabSize;
                                    textToInsert = new string ('\t', (charsToInsert - spaceCount) / editor.Options.TabSize) + new string (' ', spaceCount) + text;
                                    insertOffset = lineSegment.EditableLength;
                                }
                                else
                                {
                                    textToInsert = text;
                                }
                                length = textEditorData.Insert(lineSegment.Offset + insertOffset, textToInsert);
                            }
                            Caret.PreserveSelection = true;
                            Caret.Column           += length - 1;

                            textEditorData.MainSelection.Lead   = new DocumentLocation(textEditorData.MainSelection.Lead.Line, Caret.Column + 1);
                            textEditorData.MainSelection.Anchor = new DocumentLocation(textEditorData.MainSelection.Anchor.Line, Caret.Column + 1);
                            Document.CommitMultipleLineUpdate(textEditorData.MainSelection.MinLine, textEditorData.MainSelection.MaxLine);
                        }
                        else
                        {
                            int length = textEditorData.Insert(Caret.Offset, text);
                            Caret.Column += length - 1;
                        }
                    }
                    else
                    {
                        int length = textEditorData.Replace(Caret.Offset, 1, ch.ToString());
                        if (length > 1)
                        {
                            Caret.Offset += length - 1;
                        }
                    }
                    // That causes unnecessary redraws:
                    //				bool autoScroll = Caret.AutoScrollToCaret;
                    Caret.Column++;
                    if (Caret.PreserveSelection)
                    {
                        Caret.PreserveSelection = false;
                    }
                    //				Caret.AutoScrollToCaret = autoScroll;
                    //				if (autoScroll)
                    //					Editor.ScrollToCaret ();
                    //				Document.RequestUpdate (new LineUpdate (Caret.Line));
                    //				Document.CommitDocumentUpdate ();
                }
            }
            Document.OptimizeTypedUndo();
        }
		public static void SetCompletionText (TextEditorData data, CodeCompletionContext ctx, string partialWord, string completeWord, int wordOffset)
		{
			if (data == null || data.Document == null)
				return;

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

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

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

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

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

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

		}
Example #22
0
        protected void InsertCharacter(uint unicodeKey)
        {
            if (!textEditorData.CanEdit(Data.Caret.Line))
            {
                return;
            }

            HideMouseCursor();

            using (var undo = Document.OpenUndoGroup()) {
                if (textEditorData.IsSomethingSelected && textEditorData.Options.EnableSelectionWrappingKeys && IsSpecialKeyForSelection(unicodeKey))
                {
                    textEditorData.SelectionSurroundingProvider.HandleSpecialSelectionKey(textEditorData, unicodeKey);
                    return;
                }

                textEditorData.DeleteSelectedText(
                    textEditorData.IsSomethingSelected ? textEditorData.MainSelection.SelectionMode != SelectionMode.Block : true);
                // Needs to be called after delete text, delete text handles virtual caret postitions itself,
                // but afterwards the virtual position may need to be restored.
                textEditorData.EnsureCaretIsNotVirtual();

                char ch = (char)unicodeKey;
                if (!char.IsControl(ch) && textEditorData.CanEdit(Caret.Line))
                {
                    DocumentLine line = Document.GetLine(Caret.Line);
                    if (Caret.IsInInsertMode || Caret.Column >= line.Length + 1)
                    {
                        string text = ch.ToString();
                        if (textEditorData.IsSomethingSelected && textEditorData.MainSelection.SelectionMode == SelectionMode.Block)
                        {
                            var visualInsertLocation = textEditorData.LogicalToVisualLocation(Caret.Location);
                            var selection            = textEditorData.MainSelection;
                            Caret.PreserveSelection = true;
                            for (int lineNumber = selection.MinLine; lineNumber <= selection.MaxLine; lineNumber++)
                            {
                                DocumentLine lineSegment  = textEditorData.GetLine(lineNumber);
                                int          insertOffset = lineSegment.GetLogicalColumn(textEditorData, visualInsertLocation.Column) - 1;
                                string       textToInsert;
                                if (lineSegment.Length < insertOffset)
                                {
                                    int visualLastColumn = lineSegment.GetVisualColumn(textEditorData, lineSegment.Length + 1);
                                    int charsToInsert    = visualInsertLocation.Column - visualLastColumn;
                                    int spaceCount       = charsToInsert % editor.Options.TabSize;
                                    textToInsert = new string ('\t', (charsToInsert - spaceCount) / editor.Options.TabSize) +
                                                   new string (' ', spaceCount) + text;
                                    insertOffset = lineSegment.Length;
                                }
                                else
                                {
                                    textToInsert = text;
                                }
                                textEditorData.Insert(lineSegment.Offset + insertOffset, textToInsert);
                            }
                            var visualColumn = textEditorData.GetLine(Caret.Location.Line).GetVisualColumn(textEditorData, Caret.Column);

                            textEditorData.MainSelection = new Selection(
                                new DocumentLocation(selection.Anchor.Line, textEditorData.GetLine(selection.Anchor.Line).GetLogicalColumn(textEditorData, visualColumn)),
                                new DocumentLocation(selection.Lead.Line, textEditorData.GetLine(selection.Lead.Line).GetLogicalColumn(textEditorData, visualColumn)),
                                SelectionMode.Block
                                );
                            Document.CommitMultipleLineUpdate(textEditorData.MainSelection.MinLine, textEditorData.MainSelection.MaxLine);
                        }
                        else
                        {
                            textEditorData.Insert(Caret.Offset, text);
                        }
                    }
                    else
                    {
                        textEditorData.Replace(Caret.Offset, 1, ch.ToString());
                    }
                    // That causes unnecessary redraws:
                    //				bool autoScroll = Caret.AutoScrollToCaret;
//					Caret.Column++;
                    if (Caret.PreserveSelection)
                    {
                        Caret.PreserveSelection = false;
                    }
                    //				Caret.AutoScrollToCaret = autoScroll;
                    //				if (autoScroll)
                    //					Editor.ScrollToCaret ();
                    //				Document.RequestUpdate (new LineUpdate (Caret.Line));
                    //				Document.CommitDocumentUpdate ();
                }
            }
            Document.OptimizeTypedUndo();
        }
		static void ConvertVerbatimStringToNormal (TextEditorData textEditorData, int offset)
		{
			var endOffset = offset;
			while (endOffset < textEditorData.Length) {
				char ch = textEditorData.GetCharAt (endOffset);
				if (ch == '"' && (endOffset + 1 < textEditorData.Length && textEditorData.GetCharAt (endOffset + 1) == '"')) {
					endOffset += 2;
					continue;
				}
				if (ch == '"') {
					break;
				}
				endOffset++;
			}
			var plainText = TextPasteUtils.VerbatimStringStrategy.Decode (textEditorData.GetTextAt (offset, endOffset - offset));
			var newText = TextPasteUtils.StringLiteralPasteStrategy.Instance.Encode (plainText);
			textEditorData.Replace (offset, endOffset - offset, newText);
		}
		int CorrectFormatting (TextEditorData data, int start, int end)
		{
			int delta = 0;
			int lineNumber = data.OffsetToLineNumber (start);
			LineSegment line = data.GetLine (lineNumber);
			if (line.Offset < start)
				lineNumber++;
			line = data.GetLine (lineNumber);
			if (line == null)
				return 0;
			bool wholeDocument = end >= data.Document.Length;
			do {
				string indent = line.GetIndentation (data.Document);
				StringBuilder newIndent = new StringBuilder ();
				int col = 1;
				if (data.Options.TabsToSpaces) {
					foreach (char ch in indent) {
						if (ch == '\t') {
							int tabWidth = TextViewMargin.GetNextTabstop (data, col) - col;
							newIndent.Append (new string (' ', tabWidth));
							col += tabWidth;
						} else {
							newIndent.Append (ch);
						}
					}
				} else {
					for (int i = 0; i < indent.Length; i++) {
						char ch = indent [i];
						if (ch == '\t') {
							int tabWidth = TextViewMargin.GetNextTabstop (data, col) - col;
							newIndent.Append (ch);
							col += tabWidth;
						} else {
							int tabWidth = TextViewMargin.GetNextTabstop (data, col) - col;
							newIndent.Append ('\t');
							col += tabWidth;
							while (tabWidth-- > 0 && i + 1 < indent.Length) {
								if (indent [i + 1] != ' ')
									break;
								i++;
							}
						}
					}
				}
				if (indent.Length == line.EditableLength)
					newIndent.Length = 0;
				if (line.DelimiterLength != 0) {
					delta -= line.DelimiterLength;
					delta += data.EolMarker.Length;
					data.Replace (line.Offset + line.EditableLength, line.DelimiterLength, data.EolMarker);
					if (!wholeDocument) {
						end -= line.DelimiterLength;
						end += data.EolMarker.Length;
					}
				}

				string replaceWith = newIndent.ToString ();
				if (indent != replaceWith) {
					int count = (indent ?? "").Length;
					delta -= count;
					delta += data.Replace (line.Offset, count, replaceWith);
					if (!wholeDocument)
						end = end - count + replaceWith.Length;
				}

				lineNumber++;
				line = data.GetLine (lineNumber);
			} while (line != null && (wholeDocument || line.EndOffset <= end));
			return delta;
		}
Example #25
0
		static void InsertFormattedText (TextEditorData data, int offset, string formattedText)
		{
			data.Document.BeginAtomicUndo ();
			//			DocumentLocation caretLocation = data.Caret.Location;
			
			int selAnchor = data.IsSomethingSelected ? data.Document.LocationToOffset (data.MainSelection.Anchor) : -1;
			int selLead = data.IsSomethingSelected ? data.Document.LocationToOffset (data.MainSelection.Lead) : -1;
			int textOffset = 0;
			int caretOffset = data.Caret.Offset;
			
//			Console.WriteLine ("formattedText3:" + formattedText.Replace ("\t", "->").Replace (" ", "°").Replace ("\n", "\\n").Replace ("\r", "\\r"));
			while (textOffset < formattedText.Length /*&& offset < caretOffset*/) {
				if (offset < 0) {
					offset++;
					textOffset++;
					continue;
				}
				char ch1 = data.Document.GetCharAt (offset);
				char ch2 = formattedText[textOffset];
				bool isCh1Eol = ch1 == '\n'|| ch1 == '\r';
				
				if (ch1 == '\r' && offset + 1 < data.Document.Length && data.Document.GetCharAt (offset + 1) == '\n')  {
					offset++;
					ch1 = '\n';
				}
				
				if (ch1 == ch2 || (ch2 == '\n' && isCh1Eol)) {
					textOffset++;
					offset++;
					continue;
				} else if (isCh1Eol) {
					
				//	int firstWhitespace = 0;
					
					 // skip all white spaces in formatted text - we had a line break
					int firstWhitespace = -1;
					while (textOffset < formattedText.Length && IsPlainWhitespace (formattedText[textOffset])) {
						if (firstWhitespace < 0)
							firstWhitespace = textOffset;
						textOffset++;
					}
					if (firstWhitespace >= 0 && firstWhitespace != textOffset && formattedText[textOffset] == '\n') {
						int length = textOffset - firstWhitespace - 1;
						data.Insert (offset, formattedText.Substring (firstWhitespace, length) + data.EolMarker);
						data.Document.CommitLineUpdate (data.Document.OffsetToLineNumber (offset));
						length += data.EolMarker.Length;
						if (offset < caretOffset)
							caretOffset += length;
						if (offset < selAnchor)
							selAnchor += length;
						if (offset < selLead)
							selLead += length;
						
						offset += length - 1;
						textOffset++;
					}
					
					offset++;
					while (offset < data.Caret.Offset && IsPlainWhitespace (data.Document.GetCharAt (offset))) {
						offset++;
					}
					continue;
				}
				bool ch1Ws = Char.IsWhiteSpace (ch1);
				bool ch2Ws = Char.IsWhiteSpace (ch2);

				if (ch2Ws && !ch1Ws) {
					if (ch2 == '\n') {
						data.Insert (offset, data.EolMarker);
						data.Document.CommitLineUpdate (data.Document.OffsetToLineNumber (offset));
						if (offset < caretOffset)
							caretOffset += data.EolMarker.Length;
						if (offset < selAnchor)
							selAnchor += data.EolMarker.Length;
						if (offset < selLead)
							selLead += data.EolMarker.Length;
						textOffset++;
						offset += data.EolMarker.Length;
					} else {
						data.Insert (offset, ch2.ToString ());
						data.Document.CommitLineUpdate (data.Document.OffsetToLineNumber (offset));
						if (offset < caretOffset)
							caretOffset++;
						if (offset < selAnchor)
							selAnchor++;
						if (offset < selLead)
							selLead++;
						textOffset++;
						offset++;
					}
					continue;
				}

				if ((!ch2Ws || ch2 == '\n') && ch1Ws) {
					if (offset < caretOffset)
						caretOffset--;
					if (offset < selAnchor)
						selAnchor--;
					if (offset < selLead)
						selLead--;
					data.Remove (offset, 1);
					data.Document.CommitLineUpdate (data.Document.OffsetToLineNumber (offset));
					continue;
				}
				if (ch1Ws && ch2Ws) {
					data.Replace (offset, 1, ch2.ToString ());
					data.Document.CommitLineUpdate (data.Document.OffsetToLineNumber (offset));
					textOffset++;
					offset++;
					continue;
				}
				Console.WriteLine ("BAIL OUT");
				break;
			}
			data.Caret.Offset = caretOffset;
			
			if (selAnchor >= 0)
				data.MainSelection = new Selection (data.Document.OffsetToLocation (selAnchor), data.Document.OffsetToLocation (selLead));
			data.Document.EndAtomicUndo ();
		}
Example #26
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 ();
			}
		}
Example #27
0
 public override void Perform(Script script)
 {
     data.Replace(Offset, RemovedChars, InsertedText);
 }
		public static void MoveBlockUp (TextEditorData data)
		{
			int lineStart = data.Caret.Line;
			int lineEnd = data.Caret.Line;
			bool setSelection = lineStart != lineEnd;
			if (data.IsSomethingSelected) {
				setSelection = true;
				lineStart = data.MainSelection.MinLine;
				lineEnd = data.MainSelection.MaxLine;
			}
			
			if (lineStart <= 0)
				return;
			
			using (var undo = data.OpenUndoGroup ()) {
				//Mono.TextEditor.LineSegment startLine = data.Document.GetLine (lineStart);
				//int relCaretOffset = data.Caret.Offset - startLine.Offset;
				
				Mono.TextEditor.LineSegment prevLine = data.Document.GetLine (lineStart - 1);
				string text = data.Document.GetTextAt (prevLine.Offset, prevLine.EditableLength);
				List<TextMarker> prevLineMarkers = new List<TextMarker> (prevLine.Markers);
				prevLine.ClearMarker ();
				
				for (int i = lineStart - 1; i <= lineEnd; i++) {
					LineSegment cur = data.Document.GetLine (i);
					LineSegment next = data.Document.GetLine (i + 1);
					data.Replace (cur.Offset, cur.EditableLength, i != lineEnd ? data.Document.GetTextAt (next.Offset, next.EditableLength) : text);
					data.Document.GetLine (i).ClearMarker ();
					foreach (TextMarker marker in (i != lineEnd ? data.Document.GetLine (i + 1).Markers : prevLineMarkers)) {
						data.Document.GetLine (i).AddMarker (marker);
					}
				}
				
				data.Caret.Line--;
				if (setSelection)
					data.SetSelection (data.Document.GetLine (lineStart - 1).Offset, data.Document.GetLine (lineEnd - 1).Offset + data.Document.GetLine (lineEnd - 1).EditableLength);
			}
		}