GetVirtualIndentationColumn() public method

public GetVirtualIndentationColumn ( Mono.TextEditor.DocumentLocation loc ) : int
loc Mono.TextEditor.DocumentLocation
return int
        public static void Right(TextEditorData data)
        {
            if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection)
            {
                data.Caret.Offset = System.Math.Max(data.SelectionAnchor, data.Caret.Offset);
                data.ClearSelection();
                return;
            }

            DocumentLine line = data.Document.GetLine(data.Caret.Line);
            IEnumerable <FoldSegment> foldings = data.Document.GetStartFoldings(line);
            FoldSegment segment = null;

            foreach (FoldSegment folding in foldings)
            {
                if (folding.IsFolded && folding.Column == data.Caret.Column)
                {
                    segment = folding;
                    break;
                }
            }
            if (segment != null)
            {
                data.Caret.Offset = segment.EndOffset;
                return;
            }

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

                if (data.Caret.Column < nextColumn)
                {
                    data.Caret.Column = nextColumn;
                }
                else
                {
                    if (data.Caret.Line < data.LineCount)
                    {
                        data.Caret.Location = new DocumentLocation(data.Caret.Line + 1, DocumentLocation.MinColumn);
                    }
                }
            }
            else
            {
                data.Caret.Column++;
            }
        }
Example #2
0
        void CheckColumn()
        {
            var curLine = TextEditorData.Document.GetLine(Line);

            if (TextEditorData.HasIndentationTracker && TextEditorData.Options.IndentStyle == IndentStyle.Virtual && curLine.Length == 0)
            {
                if (column > DocumentLocation.MinColumn)
                {
                    var indentColumn = TextEditorData.GetVirtualIndentationColumn(Location);
                    if (column < indentColumn)
                    {
                        column = indentColumn;
                        UpdateCaretOffset();
                        return;
                    }
                    if (column == indentColumn)
                    {
                        return;
                    }
                }
            }

            if (!AllowCaretBehindLineEnd)
            {
                var max = curLine.Length + 1;
                if (column > max)
                {
                    column = max;
                    UpdateCaretOffset();
                }
            }
        }
Example #3
0
        static void SmartBackspace(TextEditorData data, DocumentLine line)
        {
            var prevLine        = line.PreviousLine;
            var prevLineIsEmpty = prevLine != null && prevLine.Length == 0;

            var startOffset = prevLine != null ? prevLine.EndOffset : 0;
            var count       = data.Caret.Offset - startOffset;

            if (count < 0 || startOffset >= data.Length)
            {
                return;
            }
            data.Remove(startOffset, count);
            if (prevLine != null)
            {
                if (prevLineIsEmpty)
                {
                    if (line.Length - data.Caret.Column - 1 > 0 && data.HasIndentationTracker)
                    {
                        data.InsertAtCaret(data.IndentationTracker.GetIndentationString(data.Caret.Line));
                    }
                    else
                    {
                        data.Caret.Column = data.GetVirtualIndentationColumn(prevLine.Offset);
                    }
                }
                data.FixVirtualIndentation();
            }
        }
		public static void Left (TextEditorData data)
		{
			if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection) {
				data.Caret.Offset = System.Math.Min (data.SelectionAnchor, data.Caret.Offset);
				data.ClearSelection ();
				return;
			}
			
			if (data.Caret.Column > DocumentLocation.MinColumn) {
				DocumentLine line = data.Document.GetLine (data.Caret.Line);
				if (data.Caret.Column > line.Length + 1) {
					if (data.Caret.AllowCaretBehindLineEnd) {
						data.Caret.Column--;
					} else {
						data.Caret.Column = line.Length + 1;
					}
				} else {
					int offset = data.Caret.Offset - 1;
					foreach (var folding in data.Document.GetFoldingsFromOffset (offset).Where (f => f.IsFolded && f.Offset < offset)) {
						offset = System.Math.Min (offset, folding.Offset);
					}
					data.Caret.Offset = offset;
				}
			} else if (data.Caret.Line > DocumentLocation.MinLine) {
				DocumentLine prevLine = data.Document.GetLine (data.Caret.Line - 1);
				var nextLocation = new DocumentLocation (data.Caret.Line - 1, prevLine.Length + 1);
				if (data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual && nextLocation.Column == DocumentLocation.MinColumn)
					nextLocation = new DocumentLocation (data.Caret.Line - 1, data.GetVirtualIndentationColumn (nextLocation));
				data.Caret.Location = nextLocation;
			}
		}
Example #5
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();
                }
            }
        }
Example #6
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));
        }
Example #7
0
        public static void Left(TextEditorData data)
        {
            using (var undo = data.OpenUndoGroup()) {
                if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection)
                {
                    data.Caret.Offset = System.Math.Min(data.SelectionAnchor, data.Caret.Offset);
                    data.ClearSelection();
                    return;
                }

                if (data.Caret.Column > DocumentLocation.MinColumn)
                {
                    DocumentLine line = data.Document.GetLine(data.Caret.Line);
                    if (data.Caret.Column > line.Length + 1)
                    {
                        if (data.Caret.AllowCaretBehindLineEnd)
                        {
                            data.Caret.Column--;
                        }
                        else
                        {
                            data.Caret.Column = line.Length + 1;
                        }
                    }
                    else
                    {
                        int offset = data.Caret.Offset - 1;
                        foreach (var folding in data.Document.GetFoldingsFromOffset(offset).Where(f => f.IsFolded && f.Offset < offset))
                        {
                            offset = System.Math.Min(offset, folding.Offset);
                        }
                        data.Caret.Offset = offset;
                    }
                }
                else if (data.Caret.Line > DocumentLocation.MinLine)
                {
                    DocumentLine prevLine     = data.Document.GetLine(data.Caret.Line - 1);
                    var          nextLocation = new DocumentLocation(data.Caret.Line - 1, prevLine.Length + 1);
                    if (data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual && nextLocation.Column == DocumentLocation.MinColumn)
                    {
                        nextLocation = new DocumentLocation(data.Caret.Line - 1, data.GetVirtualIndentationColumn(nextLocation));
                    }
                    data.Caret.Location = nextLocation;
                }
            }
        }
Example #8
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));
        }
Example #9
0
        public static void LineEnd(TextEditorData data)
        {
            using (var undo = data.OpenUndoGroup()) {
                if (!data.Caret.PreserveSelection)
                {
                    data.ClearSelection();
                }
                var line        = data.Document.GetLine(data.Caret.Line);
                var newLocation = new DocumentLocation(data.Caret.Line, line.Length + 1);

                // handle folding
                IEnumerable <FoldSegment> foldings = data.Document.GetStartFoldings(line);
                FoldSegment segment = null;
                foreach (FoldSegment folding in foldings)
                {
                    if (folding.IsFolded && folding.Contains(data.Document.LocationToOffset(newLocation)))
                    {
                        segment = folding;
                        break;
                    }
                }
                if (segment != null)
                {
                    newLocation = data.Document.OffsetToLocation(segment.EndLine.Offset + segment.EndColumn - 1);
                }
                if (newLocation != data.Caret.Location)
                {
                    data.Caret.Location = newLocation;
                }

                if (data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual)
                {
                    int virtualIndentColumn = data.GetVirtualIndentationColumn(data.Caret.Location);
                    if (virtualIndentColumn > data.Caret.Column)
                    {
                        data.Caret.Column = virtualIndentColumn;
                    }
                }
            }
        }
Example #10
0
        void SetColumn()
        {
            var curLine = TextEditorData.Document.GetLine(Line);

            if (curLine == null)
            {
                return;
            }
            column = System.Math.Max(DocumentLocation.MinColumn, Column);
            column = curLine.GetLogicalColumn(TextEditorData, DesiredColumn);
            if (TextEditorData.HasIndentationTracker && TextEditorData.Options.IndentStyle == IndentStyle.Virtual && curLine.GetVisualColumn(TextEditorData, column) < DesiredColumn)
            {
                column = TextEditorData.GetVirtualIndentationColumn(Line, column);
            }
            else
            {
                if (!AllowCaretBehindLineEnd && Column > curLine.Length + 1)
                {
                    column = System.Math.Min(curLine.Length + 1, column);
                }
            }
        }
Example #11
0
        public void SetToOffsetWithDesiredColumn(int desiredOffset)
        {
            DocumentLocation old = Location;

            int desiredLineNumber = TextEditorData.Document.OffsetToLineNumber(desiredOffset);
            var desiredLine       = TextEditorData.Document.GetLine(desiredLineNumber);
            int newColumn         = desiredOffset - desiredLine.Offset + 1;

            if (desiredLine.Length + 1 < Column && newColumn == 1)
            {
                if (TextEditorData.HasIndentationTracker && TextEditorData.Options.IndentStyle == IndentStyle.Virtual)
                {
                    newColumn = TextEditorData.GetVirtualIndentationColumn(desiredLineNumber, 1);
                }
            }

            line   = desiredLineNumber;
            column = newColumn;
            var logicalDesiredColumn = desiredLine.GetLogicalColumn(TextEditorData, DesiredColumn);

            if (logicalDesiredColumn <= desiredLine.Length + 1)
            {
                int possibleOffset = TextEditorData.LocationToOffset(desiredLineNumber, logicalDesiredColumn);
                if (!TextEditorData.Document.GetFoldingsFromOffset(possibleOffset).Any(f => f.IsCollapsed))
                {
                    column = logicalDesiredColumn;
                }
            }
            else
            {
                column = System.Math.Max(newColumn, desiredLine.Length + 1);
            }

            UpdateCaretOffset();
            OnPositionChanged(new CaretLocationEventArgs(old, currentBuffer ?? TextEditorData.Document.TextBuffer.CurrentSnapshot, CaretChangeReason.Movement));
        }
		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 ();
				}
			}
		}
Example #13
0
        public static void Left(TextEditorData data)
        {
            using (var undo = data.OpenUndoGroup()) {
                if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection)
                {
                    data.Caret.Offset = System.Math.Min(data.SelectionAnchor, data.Caret.Offset);
                    data.ClearSelection();
                    return;
                }

                if (data.Caret.Column > DocumentLocation.MinColumn)
                {
                    DocumentLine line = data.Document.GetLine(data.Caret.Line);
                    if (data.Caret.Column > line.Length + 1)
                    {
                        if (data.Caret.AllowCaretBehindLineEnd)
                        {
                            data.Caret.Column--;
                        }
                        else
                        {
                            data.Caret.Column = line.Length + 1;
                        }
                    }
                    else
                    {
                        int  offset       = data.Caret.Offset - 1;
                        bool foundFolding = false;
                        foreach (var folding in data.Document.GetFoldingsFromOffset(offset).Where(f => f.IsCollapsed && f.Offset < offset))
                        {
                            offset       = System.Math.Min(offset, folding.Offset);
                            foundFolding = true;
                        }

                        if (!foundFolding)
                        {
                            var layout = data.Parent?.TextViewMargin?.GetLayout(line);
                            if (layout != null && data.Caret.Column < line.Length)
                            {
                                uint curIndex = 0, byteIndex = 0;
                                int  utf8ByteIndex = (int)layout.TranslateToUTF8Index((uint)(offset - line.Offset), ref curIndex, ref byteIndex);
                                layout.Layout.GetCursorPos(utf8ByteIndex, out var strong_pos, out var weak_pos);
                                if (strong_pos.X != weak_pos.X)
                                {
                                    offset--;
                                }
                            }
                        }

                        data.Caret.Offset = offset;
                    }
                }
                else if (data.Caret.Line > DocumentLocation.MinLine)
                {
                    DocumentLine prevLine     = data.Document.GetLine(data.Caret.Line - 1);
                    var          nextLocation = new DocumentLocation(data.Caret.Line - 1, prevLine.Length + 1);
                    if (data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual && nextLocation.Column == DocumentLocation.MinColumn)
                    {
                        nextLocation = new DocumentLocation(data.Caret.Line - 1, data.GetVirtualIndentationColumn(nextLocation));
                    }
                    data.Caret.Location = nextLocation;
                }
                var curOffset = data.Caret.Offset;
                if (curOffset > 0 && curOffset < data.Length && IsLowSurrogateMarkerSet(data.GetCharAt(curOffset)))
                {
                    data.Caret.Offset--;
                }
            }
        }
Example #14
0
        public static void Right(TextEditorData data)
        {
            using (var undo = data.OpenUndoGroup()) {
                if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection)
                {
                    data.Caret.Offset = System.Math.Max(data.SelectionAnchor, data.Caret.Offset);
                    data.ClearSelection();
                    return;
                }
                DocumentLine line = data.Document.GetLine(data.Caret.Line);
                IEnumerable <FoldSegment> foldings = data.Document.GetStartFoldings(line);
                FoldSegment segment = null;
                foreach (FoldSegment folding in foldings)
                {
                    if (folding.IsCollapsed && folding.Offset == data.Caret.Offset)
                    {
                        segment = folding;
                        break;
                    }
                }
                if (segment != null)
                {
                    data.Caret.Offset = segment.EndOffset;
                    return;
                }

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

                    if (data.Caret.Column < nextColumn)
                    {
                        data.Caret.Column = nextColumn;
                    }
                    else
                    {
                        if (data.Caret.Line < data.LineCount)
                        {
                            data.Caret.Location = new DocumentLocation(data.Caret.Line + 1, DocumentLocation.MinColumn);
                        }
                    }
                }
                else
                {
                    data.Caret.Column++;
                    var layout = data.Parent?.TextViewMargin?.GetLayout(line);
                    if (layout != null && data.Caret.Column < line.Length)
                    {
                        uint curIndex = 0, byteIndex = 0;
                        int  utf8ByteIndex = (int)layout.TranslateToUTF8Index((uint)data.Caret.Column - 1, ref curIndex, ref byteIndex);
                        layout.Layout.GetCursorPos(utf8ByteIndex, out var strong_pos, out var weak_pos);
                        if (strong_pos.X != weak_pos.X)
                        {
                            data.Caret.Column++;
                        }
                    }
                }
                var curOffset = data.Caret.Offset;
                if (curOffset > 0 && curOffset < data.Length && IsLowSurrogateMarkerSet(data.GetCharAt(curOffset)))
                {
                    data.Caret.Offset++;
                }
            }
        }
Example #15
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();
                }
            }
        }
		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 ();

				var line = data.Document.GetLine (data.Caret.Line);
				// smart backspace (delete indentation)
				if (data.HasIndentationTracker && (data.IndentationTracker.SupportedFeatures & IndentatitonTrackerFeatures.SmartBackspace) != 0 && (data.Options.IndentStyle == IndentStyle.Smart || data.Options.IndentStyle == IndentStyle.Virtual)) {
					if (data.Caret.Column == data.GetVirtualIndentationColumn (data.Caret.Location)) {
						bool isAllIndent = line.GetIndentation (data.Document).Length == data.Caret.Column - 1;

						if (isAllIndent) {
							var prevLine = line.PreviousLine;
							var prevLineIsEmpty = prevLine != null && prevLine.Length == 0;

							var startOffset = prevLine != null ? prevLine.EndOffset : 0;
							data.Remove (startOffset, data.Caret.Offset - startOffset);
							if (prevLine != null) {
								if (prevLineIsEmpty) {
									if (line.Length - data.Caret.Column - 1 > 0 && data.HasIndentationTracker) {
										data.InsertAtCaret (data.IndentationTracker.GetIndentationString (data.Caret.Offset));
									} else {
										data.Caret.Column = data.GetVirtualIndentationColumn (prevLine.Offset);
									}
								}
								data.FixVirtualIndentation ();
							}
							return;
						}
					}
				}

				// 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.IndentationTracker.GetVirtualIndentationColumn (data.Caret.Line - 1, 1));
						data.Replace (lineAbove.EndOffsetIncludingDelimiter - lineAbove.DelimiterLength, lineAbove.DelimiterLength, data.IndentationTracker.GetIndentationString (data.Caret.Line - 1, 1));
					} else {
						data.Remove (lineAbove.EndOffsetIncludingDelimiter - lineAbove.DelimiterLength, lineAbove.DelimiterLength);
					}
				} else {
					removeCharBeforeCaret (data);
				}

				// Needs to be fixed after, the line may just contain the indentation
				data.FixVirtualIndentation ();
			}
		}
Example #17
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);
                }
            }
        }
Example #18
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 ();
				}
			}
		}
		static void SmartBackspace (TextEditorData data, DocumentLine line)
		{
			var prevLine = line.PreviousLine;
			var prevLineIsEmpty = prevLine != null && prevLine.Length == 0;

			var startOffset = prevLine != null ? prevLine.EndOffset : 0;
			var count = data.Caret.Offset - startOffset;
			if (count < 0)
				return;
			data.Remove (startOffset, count);
			if (prevLine != null) {
				if (prevLineIsEmpty) {
					if (line.Length - data.Caret.Column - 1 > 0 && data.HasIndentationTracker) {
						data.InsertAtCaret (data.IndentationTracker.GetIndentationString (data.Caret.Offset));
					} else {
						data.Caret.Column = data.GetVirtualIndentationColumn (prevLine.Offset);
					}
				}
				data.FixVirtualIndentation ();
			}
		}
Example #20
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();

                var line = data.Document.GetLine(data.Caret.Line);
                // smart backspace (delete indentation)
                if (data.HasIndentationTracker && (data.IndentationTracker.SupportedFeatures & IndentatitonTrackerFeatures.SmartBackspace) != 0 && (data.Options.IndentStyle == IndentStyle.Smart || data.Options.IndentStyle == IndentStyle.Virtual))
                {
                    if (data.Caret.Column == data.GetVirtualIndentationColumn(data.Caret.Location))
                    {
                        bool isAllIndent = line.GetIndentation(data.Document).Length == data.Caret.Column - 1;

                        if (isAllIndent)
                        {
                            var prevLine        = line.PreviousLine;
                            var prevLineIsEmpty = prevLine != null && prevLine.Length == 0;

                            var startOffset = prevLine != null ? prevLine.EndOffset : 0;
                            data.Remove(startOffset, data.Caret.Offset - startOffset);
                            if (prevLine != null)
                            {
                                if (prevLineIsEmpty)
                                {
                                    if (line.Length - data.Caret.Column - 1 > 0 && data.HasIndentationTracker)
                                    {
                                        data.InsertAtCaret(data.IndentationTracker.GetIndentationString(data.Caret.Offset));
                                    }
                                    else
                                    {
                                        data.Caret.Column = data.GetVirtualIndentationColumn(prevLine.Offset);
                                    }
                                }
                                data.FixVirtualIndentation();
                            }
                            return;
                        }
                    }
                }

                // 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.IndentationTracker.GetVirtualIndentationColumn(data.Caret.Line - 1, 1));
                        data.Replace(lineAbove.EndOffsetIncludingDelimiter - lineAbove.DelimiterLength, lineAbove.DelimiterLength, data.IndentationTracker.GetIndentationString(data.Caret.Line - 1, 1));
                    }
                    else
                    {
                        data.Remove(lineAbove.EndOffsetIncludingDelimiter - lineAbove.DelimiterLength, lineAbove.DelimiterLength);
                    }
                }
                else
                {
                    removeCharBeforeCaret(data);
                }

                // Needs to be fixed after, the line may just contain the indentation
                data.FixVirtualIndentation();
            }
        }
		public static void LineEnd (TextEditorData data)
		{
			if (!data.Caret.PreserveSelection)
				data.ClearSelection ();
			var line = data.Document.GetLine (data.Caret.Line);
			var newLocation = new DocumentLocation (data.Caret.Line, line.Length + 1);

			// handle folding
			IEnumerable<FoldSegment> foldings = data.Document.GetStartFoldings (line);
			FoldSegment segment = null;
			foreach (FoldSegment folding in foldings) {
				if (folding.IsFolded && folding.Contains (data.Document.LocationToOffset (newLocation))) {
					segment = folding;
					break;
				}
			}
			if (segment != null) 
				newLocation = data.Document.OffsetToLocation (segment.EndLine.Offset + segment.EndColumn - 1); 
			if (newLocation != data.Caret.Location)
				data.Caret.Location = newLocation;
			
			if (data.HasIndentationTracker && data.Options.IndentStyle == IndentStyle.Virtual) {
				int virtualIndentColumn = data.GetVirtualIndentationColumn (data.Caret.Location);
				if (virtualIndentColumn > data.Caret.Column)
					data.Caret.Column = virtualIndentColumn;
			}
			
		}
		public static void Right (TextEditorData data)
		{
			if (Platform.IsMac && data.IsSomethingSelected && !data.Caret.PreserveSelection) {
				data.Caret.Offset = System.Math.Max (data.SelectionAnchor, data.Caret.Offset);
				data.ClearSelection ();
				return;
			}
			
			DocumentLine line = data.Document.GetLine (data.Caret.Line);
			IEnumerable<FoldSegment > foldings = data.Document.GetStartFoldings (line);
			FoldSegment segment = null;
			foreach (FoldSegment folding in foldings) {
				if (folding.IsFolded && folding.Column == data.Caret.Column) {
					segment = folding;
					break;
				}
			}
			if (segment != null) {
				data.Caret.Offset = segment.EndOffset; 
				return;
			}

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

				if (data.Caret.Column < nextColumn) {
					data.Caret.Column = nextColumn;
				} else {
					if (data.Caret.Line < data.LineCount)
						data.Caret.Location = new DocumentLocation (data.Caret.Line + 1, DocumentLocation.MinColumn);
				}
			} else {
				data.Caret.Column++;
			}
		}