GetLine() 공개 메소드

public GetLine ( int lineNumber ) : Mono.TextEditor.DocumentLine
lineNumber int
리턴 Mono.TextEditor.DocumentLine
예제 #1
1
        public static CommandRange InnerBlock(TextEditorData editor, char openingChar, char closingChar)
        {
            var range = Block(editor, openingChar, closingChar);
            if (range.Length == 0)
                return CommandRange.Empty;
            int start = range.Start + 1;
            int end = range.End - 2;
            var line = editor.GetLine(editor.OffsetToLineNumber(range.Start));

            // exclude newline if it comes just after opening char
            if (line.EndOffsetIncludingDelimiter - start <= line.DelimiterLength)
                start += line.DelimiterLength;

            // exclude whitespace that comes just before the closing char...
            line = editor.GetLine(editor.OffsetToLineNumber(range.End));
            while (Char.IsWhiteSpace(editor.Text[end]) && end >= line.Offset)
                end--;
            //.. but only if newline comes after it
            if (end >= line.Offset)
                end = range.End - 2;
            else
                end -= line.PreviousLine.DelimiterLength;

            if (start > end + 1)
                return new CommandRange(start, start);

            return new CommandRange(start, end+1);
        }
        public static CommandRange QuotedString(TextEditorData editor, char quotationChar)
        {
            var start = editor.Caret.Offset;
            var end = editor.Caret.Offset;
            var lineOffset = editor.GetLine(editor.Caret.Line).Offset;
            var lineEndOffset = editor.GetLine(editor.Caret.Line).EndOffset - 1; // Line includes \n
            if (editor.Text[start] == quotationChar)
            {
                // Check if we're on closing char
                start = lineOffset;
                var openingCandidate = -1;
                while (start < end)
                {
                    if (editor.Text[start] == quotationChar & openingCandidate != -1)
                        openingCandidate = -1;
                    else if (editor.Text[start] == quotationChar)
                        openingCandidate = start;
                    start = start + 1;
                }
                if (openingCandidate != -1)
                {
                    start = openingCandidate;
                }
                else
                {
                    // not on closing char, let's find closing one
                    start = editor.Caret.Offset;
                    end = start + 1;
                    while (end < lineEndOffset & editor.Text[end] != quotationChar)
                        end++;
                }
            }
            else
            {
                while (start >= lineOffset & editor.Text[start] != quotationChar)
                    start--;

                while (end < lineEndOffset & editor.Text[end] != quotationChar)
                    end++;
            }

            if (start < 0 || end > lineEndOffset || start == end)
                return CommandRange.Empty;

            var endIncludingTrailingWhiteSpace = end;
            var startIncludingTrailingWhiteSpace = start;

            // expand to include all trailing white space
            while (endIncludingTrailingWhiteSpace < lineEndOffset && Char.IsWhiteSpace(editor.Text[endIncludingTrailingWhiteSpace + 1]))
                endIncludingTrailingWhiteSpace++;

            // if there's no trailing white space then include leading
            if (endIncludingTrailingWhiteSpace == end)
            {
                while (startIncludingTrailingWhiteSpace > lineOffset && Char.IsWhiteSpace(editor.Text[startIncludingTrailingWhiteSpace - 1]))
                    startIncludingTrailingWhiteSpace--;
            }

            return new CommandRange(Math.Min(start, startIncludingTrailingWhiteSpace), Math.Max(end, endIncludingTrailingWhiteSpace) + 1);
        }
예제 #3
1
		static void RemoveCharBeforCaret (TextEditorData data)
		{
			if (!data.IsSomethingSelected && MonoDevelop.Ide.Editor.DefaultSourceEditorOptions.Instance.AutoInsertMatchingBracket) {
				if (data.Caret.Offset > 0) {
					var line = data.GetLine (data.Caret.Line);
					var stack = line.StartSpan.Clone();
					if (stack.Any (s => s.Color == "string.other")) {
						DeleteActions.Backspace (data);
						return;
					}
					stack = line.StartSpan.Clone();
					if (stack.Any (s => s.Color == "string.other")) {
						DeleteActions.Backspace (data);
						return;
					}
					
					char ch = data.Document.GetCharAt (data.Caret.Offset - 1);
					int idx = open.IndexOf (ch);
					
					if (idx >= 0) {
						int nextCharOffset = GetNextNonWsCharOffset (data, data.Caret.Offset);
						if (nextCharOffset >= 0 && closing[idx] == data.Document.GetCharAt (nextCharOffset)) {
							data.Remove (data.Caret.Offset, nextCharOffset - data.Caret.Offset + 1);
						}
					}
				}
			}
			DeleteActions.Backspace (data);
		}
예제 #4
1
		static void RemoveCharBeforCaret (TextEditorData data)
		{
			if (((ISourceEditorOptions)data.Options).AutoInsertMatchingBracket) {
				if (data.Caret.Offset > 0) {
					var line = data.GetLine (data.Caret.Line);
					var stack = line.StartSpan.Clone();
					if (stack.Any (s => s.Color == "string.other")) {
						DeleteActions.Backspace (data);
						return;
					}
					stack = line.StartSpan.Clone();
					if (stack.Any (s => s.Color == "string.other")) {
						DeleteActions.Backspace (data);
						return;
					}
					
					char ch = data.Document.GetCharAt (data.Caret.Offset - 1);
					int idx = open.IndexOf (ch);
					
					if (idx >= 0) {
						int nextCharOffset = GetNextNonWsCharOffset (data, data.Caret.Offset);
						if (nextCharOffset >= 0 && closing[idx] == data.Document.GetCharAt (nextCharOffset)) {
							bool updateToEnd = data.Document.OffsetToLineNumber (nextCharOffset) != data.Caret.Line;
							data.Remove (data.Caret.Offset, nextCharOffset - data.Caret.Offset + 1);
						}
					}
				}
			}
			DeleteActions.Backspace (data);
		}
예제 #5
0
        // TODO: move this somewhere else? extend TextEditor?
        public static void SetSelectLines(TextEditorData editor, int start, int end)
        {
            start = Math.Min(start, editor.LineCount);
            end = Math.Min(end, editor.LineCount);

            var startLine = start > end ? editor.GetLine(end) : editor.GetLine(start);
            var endLine = start > end ? editor.GetLine(start) : editor.GetLine(end);

            editor.SetSelection(startLine.Offset, endLine.EndOffsetIncludingDelimiter);
        }
예제 #6
0
        static void NewLineSmartIndent(TextEditorData data)
        {
            using (var undo = data.OpenUndoGroup()) {
                data.EnsureCaretIsNotVirtual();

                var oldCaretLine = data.Caret.Location.Line;
                var indentString = data.IndentationTracker.GetIndentationString(data.Caret.Line);
                data.InsertAtCaret(data.EolMarker);

                if (data.HasIndentationTracker)
                {
                    // 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)
                    {
                        var line                    = data.GetLine(data.Caret.Line);
                        var currentIndent           = line.GetIndentation(data.Document);
                        var currentCalculatedIndent = data.IndentationTracker.GetIndentationString(data.Caret.Line);
                        if (!string.IsNullOrEmpty(currentCalculatedIndent))
                        {
                            indentString = currentCalculatedIndent;
                        }
                        if (indentString != currentIndent)
                        {
                            data.InsertAtCaret(indentString);
                        }
                    }
                }
            }
        }
예제 #7
0
        internal static int GetStartOfLineOffset(TextEditorData data, DocumentLocation loc)
        {
            var line = data.Document.GetLine(loc.Line);

            loc = new DocumentLocation(loc.Line, line.Length + 1);

            // handle folding
            var         foldings = data.Document.GetFoldingsFromOffset(line.Offset);
            FoldSegment segment  = null;

            foreach (FoldSegment folding in foldings)
            {
                if (folding.IsFolded)
                {
                    if (segment != null && segment.Offset < folding.Offset)
                    {
                        continue;
                    }
                    segment = folding;
                }
            }
            if (segment != null)
            {
                loc = data.Document.OffsetToLocation(segment.StartLine.Offset);
            }
            line = data.GetLine(loc.Line);
            return(line.Offset);
        }
예제 #8
0
        internal static int GetEndOfLineOffset(TextEditorData data, DocumentLocation loc, bool includeDelimiter = true)
        {
            var line = data.Document.GetLine(loc.Line);

            loc = new DocumentLocation(loc.Line, line.Length + 1);

            // handle folding
            var         foldings = data.Document.GetStartFoldings(loc.Line);
            FoldSegment segment  = null;

            foreach (FoldSegment folding in foldings)
            {
                if (folding.IsFolded && folding.Contains(data.Document.LocationToOffset(loc)))
                {
                    segment = folding;
                    break;
                }
            }
            if (segment != null)
            {
                loc = data.Document.OffsetToLocation(segment.EndLine.Offset + segment.EndColumn - 1);
            }
            line = data.GetLine(loc.Line);
            return(includeDelimiter ? line.EndOffsetIncludingDelimiter : line.EndOffset);
        }
예제 #9
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();
                }
            }
        }
예제 #10
0
        public static void LineStart(TextEditorData editor)
        {
            CaretMoveActions.LineStart(editor);

            var line = editor.GetLine(editor.Caret.Line);

            while (editor.Caret.Offset < line.EndOffset && Char.IsWhiteSpace(editor.Text[editor.Caret.Offset]))
                editor.Caret.Offset++;
        }
예제 #11
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;
     }
 }
예제 #12
0
        static int PastePlainText(TextEditorData data, int offset, string text, bool preserveSelection = false, byte[] copyData = null)
        {
            int inserted = 0;
            var undo     = data.OpenUndoGroup();

            try {
                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();
                if (data.IsSomethingSelected && data.MainSelection.SelectionMode == MonoDevelop.Ide.Editor.SelectionMode.Block)
                {
                    var selection            = data.MainSelection;
                    var visualInsertLocation = data.LogicalToVisualLocation(selection.Anchor);
                    var changes = new List <Microsoft.CodeAnalysis.Text.TextChange> ();

                    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;
                        }
                        changes.Add(new Microsoft.CodeAnalysis.Text.TextChange(new Microsoft.CodeAnalysis.Text.TextSpan(lineSegment.Offset + insertOffset, 0), textToInsert));
                        inserted = textToInsert.Length;
                    }
                    data.Document.ApplyTextChanges(changes);
                }
                else
                {
                    offset   = version.MoveOffsetTo(data.Document.Version, offset);
                    inserted = data.PasteText(offset, text, copyData, ref undo);
                }
                data.FixVirtualIndentation(startLine);
            } finally {
                undo.Dispose();
            }
            return(inserted);
        }
예제 #13
0
        public static CommandRange QuotedString(TextEditorData editor, char quotationChar)
        {
            CommandRange range = FindQuotes(editor, quotationChar);
            var lineOffset = editor.GetLine(editor.Caret.Line).Offset;
            var lineEndOffset = editor.GetLine(editor.Caret.Line).EndOffset - 1; // Line includes \n

            var endIncludingTrailingWhiteSpace = range.End;
            var startIncludingTrailingWhiteSpace = range.Start;

            // expand to include all trailing white space
            while (endIncludingTrailingWhiteSpace < lineEndOffset && Char.IsWhiteSpace(editor.Text[endIncludingTrailingWhiteSpace + 1]))
                endIncludingTrailingWhiteSpace++;

            // if there's no trailing white space then include leading
            if (endIncludingTrailingWhiteSpace == range.End)
            {
                while (startIncludingTrailingWhiteSpace > lineOffset && Char.IsWhiteSpace(editor.Text[startIncludingTrailingWhiteSpace - 1]))
                    startIncludingTrailingWhiteSpace--;
            }

            return new CommandRange(Math.Min(range.Start, startIncludingTrailingWhiteSpace), Math.Max(range.End, endIncludingTrailingWhiteSpace) + 1);
        }
        public static void ExpandSelectionToLine(TextEditorData data)
        {
            var curLineSegment = data.GetLine(data.Caret.Line).SegmentIncludingDelimiter;
            var range          = data.SelectionRange;
            var selection      = TextSegment.FromBounds(
                System.Math.Min(range.Offset, curLineSegment.Offset),
                System.Math.Max(range.EndOffset, curLineSegment.EndOffset));

            data.Caret.PreserveSelection = true;
            data.Caret.Offset            = selection.EndOffset;
            data.Caret.PreserveSelection = false;
            data.SelectionRange          = selection;
        }
        string GetIndent(int lineNumber, int column)
        {
            var line = data.GetLine(lineNumber);

            if (line == null)
            {
                return("");
            }
            int offset = line.Offset + Math.Min(line.Length, column - 1);

            stateTracker.Update(offset);
            return(stateTracker.NextLineIndent);
        }
예제 #16
0
        internal void UpdateCaretPosition(DocumentChangeEventArgs e)
        {
            if (e.AnchorMovementType == AnchorMovementType.BeforeInsertion && caretOffset == e.Offset)
            {
                return;
            }
            var curVersion = TextEditorData.Version;

            if (offsetVersion == null)
            {
                offsetVersion = curVersion;
                return;
            }
            var newOffset = offsetVersion.MoveOffsetTo(curVersion, caretOffset);

            offsetVersion = curVersion;
            if (newOffset == caretOffset || !AutoUpdatePosition)
            {
                return;
            }
            DocumentLocation old = Location;
            var newLocation      = TextEditorData.OffsetToLocation(newOffset);
            int newColumn        = newLocation.Column;

            var curLine = TextEditorData.GetLine(newLocation.Line);

            if (TextEditorData.HasIndentationTracker && TextEditorData.Options.IndentStyle == IndentStyle.Virtual && curLine.Length == 0)
            {
                var indentColumn = TextEditorData.GetVirtualIndentationColumn(Location);
                if (column == indentColumn)
                {
                    newColumn = indentColumn;
                }
            }
            if (AllowCaretBehindLineEnd)
            {
                if (curLine != null && column > curLine.Length)
                {
                    newColumn = column;
                }
            }

            line   = newLocation.Line;
            column = newColumn;

            SetDesiredColumn();
            UpdateCaretOffset();
            OnPositionChanged(new DocumentLocationEventArgs(old));
        }
예제 #17
0
        public virtual void HandleSpecialSelectionKey(TextEditorData textEditorData, int unicodeKey)
        {
            string start, end;

            GetSelectionSurroundings(textEditorData, unicodeKey, out start, out end);

            if (textEditorData.MainSelection.SelectionMode == SelectionMode.Block)
            {
                var selection = textEditorData.MainSelection;
                int startCol  = System.Math.Min(selection.Anchor.Column, selection.Lead.Column) - 1;
                int endCol    = System.Math.Max(selection.Anchor.Column, selection.Lead.Column);
                for (int lineNumber = selection.MinLine; lineNumber <= selection.MaxLine; lineNumber++)
                {
                    DocumentLine lineSegment = textEditorData.GetLine(lineNumber);

                    if (lineSegment.Offset + startCol < lineSegment.EndOffset)
                    {
                        textEditorData.Insert(lineSegment.Offset + startCol, start);
                    }
                    if (lineSegment.Offset + endCol < lineSegment.EndOffset)
                    {
                        textEditorData.Insert(lineSegment.Offset + endCol, end);
                    }
                }

                textEditorData.MainSelection = new Selection(
                    new DocumentLocation(selection.Anchor.Line, endCol == selection.Anchor.Column ? endCol + start.Length : startCol + 1 + start.Length),
                    new DocumentLocation(selection.Lead.Line, endCol == selection.Anchor.Column ? startCol + 1 + start.Length : endCol + start.Length),
                    Mono.TextEditor.SelectionMode.Block);
                textEditorData.Document.CommitMultipleLineUpdate(textEditorData.MainSelection.MinLine, textEditorData.MainSelection.MaxLine);
            }
            else
            {
                int anchorOffset = textEditorData.MainSelection.GetAnchorOffset(textEditorData);
                int leadOffset   = textEditorData.MainSelection.GetLeadOffset(textEditorData);
                if (leadOffset < anchorOffset)
                {
                    int tmp = anchorOffset;
                    anchorOffset = leadOffset;
                    leadOffset   = tmp;
                }
                textEditorData.Insert(anchorOffset, start);
                textEditorData.Insert(leadOffset >= anchorOffset ? leadOffset + start.Length : leadOffset, end);
                textEditorData.SetSelection(anchorOffset + start.Length, leadOffset + start.Length);
            }
        }
예제 #18
0
 public static void Right(TextEditorData editor)
 {
     if (!Platform.IsMac)
     {
         if (editor.Caret.Offset < editor.GetLine(editor.Caret.Line).EndOffset)
             CaretMoveActions.Right(editor);
     }
     else
     {
         using (var undo = editor.OpenUndoGroup())
         {
             DocumentLine line = editor.GetLine(editor.Caret.Line);
             if (editor.Caret.Column < line.Length)
                 editor.Caret.Column = editor.Caret.Column + 1;
         }
     }
 }
예제 #19
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);
        }
예제 #20
0
        internal void UpdateCaretPosition(TextChangeEventArgs e)
        {
            //if (e.AnchorMovementType == AnchorMovementType.BeforeInsertion && caretOffset == e.Offset) {
            //	offsetVersion = TextEditorData.Version;
            //	return;
            //}
            var curVersion = TextEditorData.Version;
            var newOffset  = e.GetNewOffset(caretOffset);

            if (!AutoUpdatePosition)
            {
                return;
            }

            DocumentLocation old = Location;
            var newLocation      = TextEditorData.OffsetToLocation(newOffset);
            int newColumn        = newLocation.Column;

            var curLine = TextEditorData.GetLine(newLocation.Line);

            if (TextEditorData.HasIndentationTracker && TextEditorData.Options.IndentStyle == IndentStyle.Virtual && curLine.Length == 0)
            {
                var indentColumn = TextEditorData.GetVirtualIndentationColumn(newLocation);
                if (column == indentColumn)
                {
                    newColumn = indentColumn;
                }
            }
            if (AllowCaretBehindLineEnd)
            {
                if (curLine != null && column > curLine.Length)
                {
                    newColumn = column;
                }
            }
            line   = newLocation.Line;
            column = newColumn;

            SetDesiredColumn();
            UpdateCaretOffset();
            OnPositionChanged(new CaretLocationEventArgs(old, currentBuffer ?? TextEditorData.Document.TextBuffer.CurrentSnapshot, CaretChangeReason.BufferChange));
        }
		public override void HandleSpecialSelectionKey (TextEditorData textEditorData,uint unicodeKey)
		{
			string start, end;
			GetSelectionSurroundings (textEditorData, unicodeKey, out start, out end);
			var selection = textEditorData.MainSelection;

			if (textEditorData.MainSelection.SelectionMode == SelectionMode.Block) {
				int startCol = System.Math.Min (selection.Anchor.Column, selection.Lead.Column) - 1;
				int endCol = System.Math.Max (selection.Anchor.Column, selection.Lead.Column);
				for (int lineNumber = selection.MinLine; lineNumber <= selection.MaxLine; lineNumber++) {
					DocumentLine lineSegment = textEditorData.GetLine (lineNumber);

					if (lineSegment.Offset + startCol < lineSegment.EndOffset)
						textEditorData.Insert (lineSegment.Offset + startCol, start);
					if (lineSegment.Offset + endCol < lineSegment.EndOffset)
						textEditorData.Insert (lineSegment.Offset + endCol, end);
				}

				textEditorData.MainSelection = new Selection (
					new DocumentLocation (selection.Anchor.Line, endCol == selection.Anchor.Column ? endCol + start.Length : startCol + 1 + start.Length),
					new DocumentLocation (selection.Lead.Line, endCol == selection.Anchor.Column ? startCol + 1 + start.Length : endCol + start.Length),
					Mono.TextEditor.SelectionMode.Block);
				textEditorData.Document.CommitMultipleLineUpdate (textEditorData.MainSelection.MinLine, textEditorData.MainSelection.MaxLine);
			} else {
				int anchorOffset = selection.GetAnchorOffset (textEditorData);
				int leadOffset = selection.GetLeadOffset (textEditorData);
				if (leadOffset < anchorOffset) {
					int tmp = anchorOffset;
					anchorOffset = leadOffset;
					leadOffset = tmp;
				}
				textEditorData.Insert (anchorOffset, start);
				textEditorData.Insert (leadOffset >= anchorOffset ? leadOffset + start.Length : leadOffset, end);
			//	textEditorData.SetSelection (anchorOffset + start.Length, leadOffset + start.Length);
				if (CSharpTextEditorIndentation.OnTheFlyFormatting) {
					var l1 = textEditorData.GetLineByOffset (anchorOffset);
					var l2 = textEditorData.GetLineByOffset (leadOffset);
					OnTheFlyFormatter.Format (document, l1.Offset, l2.EndOffsetIncludingDelimiter);
				}
			}
		}
예제 #22
0
        // for markup syntax mode the syntax highlighting information need to be taken into account
        // when calculating the selection offsets.
        static int PosToOffset(TextEditorData data, DocumentLocation loc)
        {
            DocumentLine line = data.GetLine(loc.Line);

            if (line == null)
            {
                return(0);
            }
            var startChunk = data.GetChunks(line, line.Offset, line.LengthIncludingDelimiter);
            int col        = 1;

            foreach (var chunk in startChunk)
            {
                if (col <= loc.Column && loc.Column < col + chunk.Length)
                {
                    return(chunk.Offset - col + loc.Column);
                }
                col += chunk.Length;
            }
            return(line.Offset + line.Length);
        }
예제 #23
0
        // for markup syntax mode the syntax highlighting information need to be taken into account
        // when calculating the selection offsets.
        int PosToOffset(TextEditorData data, DocumentLocation loc)
        {
            LineSegment line = data.GetLine(loc.Line);

            if (line == null)
            {
                return(0);
            }
            Chunk startChunk = data.Document.SyntaxMode.GetChunks(data.Document, data.Parent.ColorStyle, line, line.Offset, line.Length);
            int   col        = 1;

            for (Chunk chunk = startChunk; chunk != null; chunk = chunk != null ? chunk.Next : null)
            {
                if (col <= loc.Column && loc.Column < col + chunk.Length)
                {
                    return(chunk.Offset - col + loc.Column);
                }
                col += chunk.Length;
            }
            return(line.Offset + line.EditableLength);
        }
예제 #24
0
		public static List<InsertionPoint> GetInsertionPoints (TextEditorData data, ParsedDocument parsedDocument, IType type)
		{
			if (data == null)
				throw new ArgumentNullException ("data");
			if (parsedDocument == null)
				throw new ArgumentNullException ("parsedDocument");
			if (type == null)
				throw new ArgumentNullException ("type");
			List<InsertionPoint> result = new List<InsertionPoint> ();
			int offset = data.LocationToOffset (type.BodyRegion.Start.Line, type.BodyRegion.Start.Column);
			if (offset < 0)
				return result;
			
			while (offset < data.Length && data.GetCharAt (offset) != '{') {
				offset++;
			}
			
			var realStartLocation = data.OffsetToLocation (offset);
			result.Add (GetInsertionPosition (data.Document, realStartLocation.Line, realStartLocation.Column));
			result[0].LineBefore = NewLineInsertion.None;
			foreach (IMember member in type.Members) {
				DomLocation domLocation = member.BodyRegion.End;
				if (domLocation.Line <= 0) {
					LineSegment lineSegment = data.GetLine (member.Location.Line);
					if (lineSegment == null)
						continue;
					domLocation = new DomLocation (member.Location.Line, lineSegment.EditableLength + 1);
				}
				result.Add (GetInsertionPosition (data.Document, domLocation.Line, domLocation.Column));
			}
			result[result.Count - 1].LineAfter = NewLineInsertion.None;
			CheckStartPoint (data.Document, result[0], result.Count == 1);
			if (result.Count > 1) {
				result.RemoveAt (result.Count - 1); 
				NewLineInsertion insertLine;
				var lineBefore = data.GetLine (type.BodyRegion.End.Line - 1);
				if (lineBefore != null && lineBefore.EditableLength == lineBefore.GetIndentation (data.Document).Length) {
					insertLine = NewLineInsertion.None;
				} else {
					insertLine = NewLineInsertion.Eol;
				}
				// search for line start
				var line = data.GetLine (type.BodyRegion.End.Line);
				int col = type.BodyRegion.End.Column - 1;
				while (col > 1 && char.IsWhiteSpace (data.GetCharAt (line.Offset + col - 2)))
					col--;
				result.Add (new InsertionPoint (new DocumentLocation (type.BodyRegion.End.Line, col), insertLine, NewLineInsertion.Eol));
				CheckEndPoint (data.Document, result[result.Count - 1], result.Count == 1);
			}
			
			foreach (var region in parsedDocument.UserRegions.Where (r => type.BodyRegion.Contains (r.Region))) {
				result.Add (new InsertionPoint (new DocumentLocation (region.Region.Start.Line + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol));
				result.Add (new InsertionPoint (new DocumentLocation (region.Region.End.Line, 1), NewLineInsertion.Eol, NewLineInsertion.Eol));
				result.Add (new InsertionPoint (new DocumentLocation (region.Region.End.Line + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol));
			}
			result.Sort ((left, right) => left.Location.CompareTo (right.Location));
			return result;
		}
예제 #25
0
		public static List<InsertionPoint> GetInsertionPoints (TextEditorData data, ParsedDocument parsedDocument, IUnresolvedTypeDefinition type)
		{
			if (data == null)
				throw new ArgumentNullException ("data");
			if (parsedDocument == null)
				throw new ArgumentNullException ("parsedDocument");
			if (type == null)
				throw new ArgumentNullException ("type");
			
			// update type from parsed document, since this is always newer.
			//type = parsedDocument.GetInnermostTypeDefinition (type.GetLocation ()) ?? type;
			List<InsertionPoint> result = new List<InsertionPoint> ();
			int offset = data.LocationToOffset (type.Region.Begin);
			if (offset < 0 || type.BodyRegion.IsEmpty)
				return result;
			while (offset < data.Length && data.GetCharAt (offset) != '{') {
				offset++;
			}
			var realStartLocation = data.OffsetToLocation (offset);
			result.Add (GetInsertionPosition (data.Document, realStartLocation.Line, realStartLocation.Column));
			result [0].LineBefore = NewLineInsertion.None;
			
			foreach (var member in type.Members) {
				TextLocation domLocation = member.BodyRegion.End;
				if (domLocation.Line <= 0) {
					DocumentLine lineSegment = data.GetLine (member.Region.BeginLine);
					if (lineSegment == null)
						continue;
					domLocation = new TextLocation (member.Region.BeginLine, lineSegment.Length + 1);
				}
				result.Add (GetInsertionPosition (data.Document, domLocation.Line, domLocation.Column));
			}

			foreach (var nestedType in type.NestedTypes) {
				TextLocation domLocation = nestedType.BodyRegion.End;
				if (domLocation.Line <= 0) {
					DocumentLine lineSegment = data.GetLine (nestedType.Region.BeginLine);
					if (lineSegment == null)
						continue;
					domLocation = new TextLocation (nestedType.Region.BeginLine, lineSegment.Length + 1);
				}
				result.Add (GetInsertionPosition (data.Document, domLocation.Line, domLocation.Column));
			}

			result [result.Count - 1].LineAfter = NewLineInsertion.None;
			CheckStartPoint (data.Document, result [0], result.Count == 1);
			if (result.Count > 1) {
				result.RemoveAt (result.Count - 1); 
				NewLineInsertion insertLine;
				var lineBefore = data.GetLine (type.BodyRegion.EndLine - 1);
				if (lineBefore != null && lineBefore.Length == lineBefore.GetIndentation (data.Document).Length) {
					insertLine = NewLineInsertion.None;
				} else {
					insertLine = NewLineInsertion.Eol;
				}
				// search for line start
				int col = type.BodyRegion.EndColumn - 1;
				var line = data.GetLine (type.BodyRegion.EndLine);
				if (line != null) {
					while (col > 1 && char.IsWhiteSpace (data.GetCharAt (line.Offset + col - 2)))
						col--;
				}
				result.Add (new InsertionPoint (new DocumentLocation (type.BodyRegion.EndLine, col), insertLine, NewLineInsertion.Eol));
				CheckEndPoint (data.Document, result [result.Count - 1], result.Count == 1);
			}
			
			foreach (var region in parsedDocument.UserRegions.Where (r => type.BodyRegion.IsInside (r.Region.Begin))) {
				result.Add (new InsertionPoint (new DocumentLocation (region.Region.BeginLine + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol));
				result.Add (new InsertionPoint (new DocumentLocation (region.Region.EndLine, 1), NewLineInsertion.Eol, NewLineInsertion.Eol));
				result.Add (new InsertionPoint (new DocumentLocation (region.Region.EndLine + 1, 1), NewLineInsertion.Eol, NewLineInsertion.Eol));
			}
			result.Sort ((left, right) => left.Location.CompareTo (right.Location));
			return result;
		}
예제 #26
0
		// for markup syntax mode the syntax highlighting information need to be taken into account
		// when calculating the selection offsets.
		int PosToOffset (TextEditorData data, DocumentLocation loc) 
		{
			LineSegment line = data.GetLine (loc.Line);
			if (line == null)
				return 0;
			Chunk startChunk = data.Document.SyntaxMode.GetChunks (data.Document, data.Parent.ColorStyle, line, line.Offset, line.Length);
			int col = 1;
			for (Chunk chunk = startChunk; chunk != null; chunk = chunk != null ? chunk.Next : null) {
				if (col <= loc.Column && loc.Column < col + chunk.Length)
					return chunk.Offset - col + loc.Column;
				col += chunk.Length;
			}
			return line.Offset + line.EditableLength;
		}
예제 #27
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();
            }
        }
예제 #28
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 ();
			}
		}
예제 #29
0
		static DocumentLocation LimitColumn (TextEditorData data, DocumentLocation loc)
		{
			return new DocumentLocation (loc.Line, System.Math.Min (loc.Column, data.GetLine (loc.Line).Length + 1));
		}
예제 #30
0
		internal static int GetStartOfLineOffset (TextEditorData data, DocumentLocation loc)
		{
			var line = data.Document.GetLine (loc.Line);
			loc = new DocumentLocation (loc.Line, line.Length + 1);

			// handle folding
			var foldings = data.Document.GetFoldingsFromOffset (line.Offset);
			FoldSegment segment = null;
			foreach (FoldSegment folding in foldings) {
				if (folding.IsFolded) {
					if (segment != null && segment.Offset < folding.Offset)
						continue;
					segment = folding;
				}
			}
			if (segment != null) 
				loc = data.Document.OffsetToLocation (segment.StartLine.Offset); 
			line = data.GetLine (loc.Line);
			return line.Offset;
		}
예제 #31
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;
			}
		}
예제 #32
0
        private static CommandRange FindQuotes(TextEditorData editor, char quotationChar)
        {
            var start = editor.Caret.Offset;
            var end = editor.Caret.Offset;
            var lineOffset = editor.GetLine(editor.Caret.Line).Offset;
            var lineEndOffset = editor.GetLine(editor.Caret.Line).EndOffset - 1; // Line includes \n

            if (editor.Text[start] == quotationChar)
            {
                // Check if we're on closing char
                start = lineOffset;
                var openingCandidate = -1;
                while (start < end)
                {
                    if (editor.Text[start] == quotationChar & openingCandidate != -1)
                        openingCandidate = -1;
                    else if (editor.Text[start] == quotationChar)
                        openingCandidate = start;
                    start = start + 1;
                }
                if (openingCandidate != -1)
                {
                    start = openingCandidate;
                }
                else
                {
                    // not on closing char, let's find closing one
                    start = editor.Caret.Offset;
                    end = start + 1;
                    while (end < lineEndOffset & editor.Text[end] != quotationChar)
                        end++;
                }
            }
            else
            {
                while (start >= lineOffset & editor.Text[start] != quotationChar)
                    start--;

                while (end < lineEndOffset & editor.Text[end] != quotationChar)
                    end++;
            }

            if (start < lineOffset || end > lineEndOffset || start == end)
                return CommandRange.Empty;

            return new CommandRange(start, end);
        }
 private Tuple<DocumentLine, NumberBookmark> GetLineWithBookmark(TextEditorData editor)
 {
     var bookmark = BookmarkService.Instance.GetBookmarkLocal(editor.FileName, this.BookmarkNumber);
     if (bookmark == null)
         return null;
     return new Tuple<DocumentLine, NumberBookmark>(editor.GetLine(bookmark.LineNumber), bookmark);
 }
예제 #34
0
		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;
		}
예제 #35
0
		static void IndentCode (TextEditorData data, string lineIndent)
		{
			for (int i = 1; i < data.LineCount; i++) {
				var line = data.GetLine (i + 1);
				if (line.Length > 0)
					data.Insert (line.Offset, lineIndent);
			}
		}
예제 #36
0
		internal static int GetEndOfLineOffset (TextEditorData data, DocumentLocation loc, bool includeDelimiter = true)
		{
			var line = data.Document.GetLine (loc.Line);
			loc = new DocumentLocation (loc.Line, line.Length + 1);

			// handle folding
			var foldings = data.Document.GetStartFoldings (loc.Line);
			FoldSegment segment = null;
			foreach (FoldSegment folding in foldings) {
				if (folding.IsFolded && folding.Contains (data.Document.LocationToOffset (loc))) {
					segment = folding;
					break;
				}
			}
			if (segment != null) 
				loc = data.Document.OffsetToLocation (segment.EndLine.Offset + segment.EndColumn - 1); 
			line = data.GetLine (loc.Line);
			return includeDelimiter ? line.EndOffsetIncludingDelimiter : line.EndOffset;
		}
예제 #37
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();
                }
            }
        }
예제 #38
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();
        }
예제 #39
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 ();
				}
			}
		}
예제 #40
0
		// for markup syntax mode the syntax highlighting information need to be taken into account
		// when calculating the selection offsets.
		int PosToOffset (TextEditorData data, DocumentLocation loc) 
		{
			LineSegment line = data.GetLine (loc.Line);
			if (line == null)
				return 0;
			var startChunk = data.GetChunks (line, line.Offset, line.LengthIncludingDelimiter);
			int col = 1;
			foreach (Chunk chunk in startChunk) {
				if (col <= loc.Column && loc.Column < col + chunk.Length)
					return chunk.Offset - col + loc.Column;
				col += chunk.Length;
			}
			return line.Offset + line.Length;
		}
예제 #41
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;
		}
예제 #42
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;
                        if (!pasteBlock && !pasteLine)
                        {
                            return;
                        }

                        data.Document.BeginAtomicUndo();
                        if (preserveSelection && data.IsSomethingSelected)
                        {
                            data.DeleteSelectedText();
                        }

                        data.Caret.PreserveSelection = true;
                        if (pasteBlock)
                        {
                            string[] lines = text.Split('\r');
                            int lineNr     = data.Document.OffsetToLineNumber(insertionOffset);
                            int col        = insertionOffset - data.Document.GetLine(lineNr).Offset;
                            int visCol     = data.Document.GetLine(lineNr).GetVisualColumn(data, col);
                            LineSegment curLine;
                            int lineCol = col;
                            result      = 0;
                            for (int i = 0; i < lines.Length; i++)
                            {
                                while (data.Document.LineCount <= lineNr + i)
                                {
                                    data.Insert(data.Document.Length, Environment.NewLine);
                                    result += Environment.NewLine.Length;
                                }
                                curLine = data.Document.GetLine(lineNr + i);
                                if (lines [i].Length > 0)
                                {
                                    lineCol = curLine.GetLogicalColumn(data, visCol);
                                    if (curLine.EditableLength + 1 < lineCol)
                                    {
                                        result += lineCol - curLine.EditableLength;
                                        data.Insert(curLine.Offset + curLine.EditableLength, new string (' ', lineCol - curLine.EditableLength));
                                    }
                                    data.Insert(curLine.Offset + lineCol, lines [i]);
                                    result += lines [i].Length;
                                }
                                if (!preserveState)
                                {
                                    data.Caret.Offset = curLine.Offset + lineCol + lines [i].Length;
                                }
                            }
                        }
                        else if (pasteLine)
                        {
                            result = text.Length;
                            LineSegment curLine = data.Document.GetLine(data.Caret.Line);
                            data.Insert(curLine.Offset, text + data.EolMarker);
                            if (!preserveState)
                            {
                                data.Caret.Offset += text.Length + data.EolMarker.Length;
                            }
                        }

                        /*				data.MainSelection = new Selection (data.Document.OffsetToLocation (insertionOffset),
                         *                                  data.Caret.Location,
                         *                                  lines.Length > 1 ? SelectionMode.Block : SelectionMode.Normal);*/
                        if (!preserveState)
                        {
                            data.ClearSelection();
                        }
                        data.Caret.PreserveSelection = false;
                        data.Document.EndAtomicUndo();
                    }
                });
            }

            if (result < 0 && clipboard.WaitIsTextAvailable())
            {
                clipboard.RequestText(delegate(Clipboard clp, string text) {
                    if (string.IsNullOrEmpty(text))
                    {
                        return;
                    }
                    data.Document.BeginAtomicUndo();
                    int caretPos = data.Caret.Offset;
                    if (data.IsSomethingSelected && data.MainSelection.SelectionMode == SelectionMode.Block)
                    {
                        data.Caret.PreserveSelection = true;
                        data.DeleteSelectedText(false);
                        int textLength           = 0;
                        int minLine              = data.MainSelection.MinLine;
                        int maxLine              = data.MainSelection.MaxLine;
                        var visualInsertLocation = data.LogicalToVisualLocation(data.Caret.Location);
                        for (int lineNumber = minLine; lineNumber <= maxLine; lineNumber++)
                        {
                            LineSegment lineSegment = data.GetLine(lineNumber);
                            int insertOffset        = lineSegment.GetLogicalColumn(data, visualInsertLocation.Column) - 1;
                            if (lineSegment.EditableLength < insertOffset)
                            {
                                int visualLastColumn = lineSegment.GetVisualColumn(data, lineSegment.EditableLength + 1);
                                int charsToInsert    = visualInsertLocation.Column - visualLastColumn;
                                int spaceCount       = charsToInsert % data.Options.TabSize;
                                string textToInsert  = new string ('\t', (charsToInsert - spaceCount) / data.Options.TabSize) + new string (' ', spaceCount) + text;
                                insertOffset         = lineSegment.EditableLength;
                                data.Insert(lineSegment.Offset + insertOffset, textToInsert);
                                data.PasteText(lineSegment.Offset + insertOffset, textToInsert);
                            }
                            else
                            {
                                textLength = data.Insert(lineSegment.Offset + insertOffset, text);
                                data.PasteText(lineSegment.Offset + insertOffset, text);
                            }
                        }

                        data.Caret.Offset           += textLength;
                        data.MainSelection.Anchor    = new DocumentLocation(System.Math.Max(DocumentLocation.MinLine, data.Caret.Line == minLine ? maxLine : minLine), System.Math.Max(DocumentLocation.MinColumn, data.Caret.Column - textLength));
                        data.MainSelection.Lead      = new DocumentLocation(data.Caret.Line, data.Caret.Column);
                        data.Caret.PreserveSelection = false;
                        data.Document.CommitMultipleLineUpdate(data.MainSelection.MinLine, data.MainSelection.MaxLine);
                    }
                    else
                    {
                        ISegment selection = data.SelectionRange;
                        if (preserveSelection && data.IsSomethingSelected)
                        {
                            data.DeleteSelectedText();
                        }
                        data.Caret.PreserveSelection = true;
                        //int oldLine = data.Caret.Line;
                        int textLength = data.Insert(insertionOffset, text);
                        result         = textLength;

                        if (data.IsSomethingSelected && data.SelectionRange.Offset >= insertionOffset)
                        {
                            data.SelectionRange.Offset += textLength;
                        }
                        if (data.IsSomethingSelected && data.MainSelection.GetAnchorOffset(data) >= insertionOffset)
                        {
                            data.MainSelection.Anchor = data.Document.OffsetToLocation(data.MainSelection.GetAnchorOffset(data) + textLength);
                        }

                        data.Caret.PreserveSelection = false;
                        if (!preserveState)
                        {
                            data.Caret.Offset += textLength;
                        }
                        else
                        {
                            if (caretPos >= insertionOffset)
                            {
                                data.Caret.Offset += textLength;
                            }
                            if (selection != null)
                            {
                                int offset = selection.Offset;
                                if (offset >= insertionOffset)
                                {
                                    offset += textLength;
                                }
                                data.SelectionRange = new Segment(offset, selection.Length);
                            }
                        }
                        data.PasteText(insertionOffset, text);
                    }
                    data.Document.EndAtomicUndo();
                });
            }

            return(result);
        }
예제 #43
0
 public static void Right(TextEditorData editor)
 {
     if (editor.GetLine(editor.Caret.Line).EndOffset - editor.Caret.Offset - 1 > 0)
         CaretMoveActions.Right(editor);
 }
예제 #44
0
 static DocumentLocation LimitColumn(TextEditorData data, DocumentLocation loc)
 {
     return(new DocumentLocation(loc.Line, System.Math.Min(loc.Column, data.GetLine(loc.Line).Length + 1)));
 }
예제 #45
0
		public static void ExpandSelectionToLine (TextEditorData data)
		{
			using (var undoGroup = data.OpenUndoGroup ()) {
				var curLineSegment = data.GetLine (data.Caret.Line).SegmentIncludingDelimiter;
				var range = data.SelectionRange;
				var selection = TextSegment.FromBounds (
					               System.Math.Min (range.Offset, curLineSegment.Offset),
					               System.Math.Max (range.EndOffset, curLineSegment.EndOffset));
				data.Caret.PreserveSelection = true;
				data.Caret.Offset = selection.EndOffset;
				data.Caret.PreserveSelection = false;
				data.SelectionRange = selection;
			}
		}
예제 #46
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 ();
				}
			}
		}
예제 #47
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;
		}
예제 #48
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);
                }
            }
        }
예제 #49
0
        private InsertionPoint GetInsertionPoint(MonoDevelop.Ide.Gui.Document document, IType type)
        {
            data = document.Editor;
            if (data == null) {
                throw new System.ArgumentNullException ("data");
            }
            var parsedDocument = document.ParsedDocument;
            if (parsedDocument == null) {
                throw new System.ArgumentNullException ("parsedDocument");
            }
            if (type == null) {
                throw new System.ArgumentNullException ("type");
            }
            type = (parsedDocument.CompilationUnit.GetTypeAt (type.Location) ?? type);
            DomRegion domRegion = type.BodyRegion;
            var start = type.BodyRegion.Start.Line;
            indent = data.GetLine(start).GetIndentation(data.Document);
            DomLocation domLocation = domRegion.End;
            int num = data.LocationToOffset (domLocation.Line, 1);
            while (num < data.Length && data.GetCharAt(num) != '}') {
                num++;
            }
            num++;
            DocumentLocation documentLocation = data.OffsetToLocation (num);

            LineSegment lineAfterClassEnd = data.GetLine (domLocation.Line + 1);
            NewLineInsertion lineAfter;
            if (lineAfterClassEnd != null && lineAfterClassEnd.EditableLength == lineAfterClassEnd.GetIndentation (data.Document).Length)
                lineAfter = NewLineInsertion.BlankLine;
            else
                lineAfter = NewLineInsertion.None;

            return new InsertionPoint (documentLocation, NewLineInsertion.None, lineAfter);
        }
예제 #50
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();
        }