static TextViewPosition GetPrevCaretPosition(TextView textView, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode, bool enableVirtualSpace)
        {
            int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Backward, mode, enableVirtualSpace);

            if (pos >= 0)
            {
                return(visualLine.GetTextViewPosition(pos));
            }
            else
            {
                // move to end of previous line
                DocumentLine previousDocumentLine = visualLine.FirstDocumentLine.PreviousLine;
                if (previousDocumentLine != null)
                {
                    VisualLine previousLine = textView.GetOrConstructVisualLine(previousDocumentLine);
                    pos = previousLine.GetNextCaretPosition(previousLine.VisualLength + 1, LogicalDirection.Backward, mode, enableVirtualSpace);
                    if (pos < 0)
                    {
                        throw ThrowUtil.NoValidCaretPosition();
                    }
                    return(previousLine.GetTextViewPosition(pos));
                }
                else
                {
                    // at start of document
                    Debug.Assert(visualLine.FirstDocumentLine.Offset == 0);
                    return(new TextViewPosition(0, 0));
                }
            }
        }
        static TextViewPosition GetNextCaretPosition(TextView textView, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode, bool enableVirtualSpace)
        {
            int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Forward, mode, enableVirtualSpace);

            if (pos >= 0)
            {
                return(visualLine.GetTextViewPosition(pos));
            }
            else
            {
                // move to start of next line
                DocumentLine nextDocumentLine = visualLine.LastDocumentLine.NextLine;
                if (nextDocumentLine != null)
                {
                    VisualLine nextLine = textView.GetOrConstructVisualLine(nextDocumentLine);
                    pos = nextLine.GetNextCaretPosition(-1, LogicalDirection.Forward, mode, enableVirtualSpace);
                    if (pos < 0)
                    {
                        throw ThrowUtil.NoValidCaretPosition();
                    }
                    return(nextLine.GetTextViewPosition(pos));
                }
                else
                {
                    // at end of document
                    Debug.Assert(visualLine.LastDocumentLine.Offset + visualLine.LastDocumentLine.TotalLength == textView.Document.TextLength);
                    return(new TextViewPosition(textView.Document.GetLocation(textView.Document.TextLength)));
                }
            }
        }
        static TextViewPosition GetEndOfLineCaretPosition(VisualLine visualLine, TextLine textLine)
        {
            int newVC            = visualLine.GetTextLineVisualStartColumn(textLine) + textLine.Length;
            TextViewPosition pos = visualLine.GetTextViewPosition(newVC);

            pos.IsAtEndOfLine = true;
            return(pos);
        }
Beispiel #4
0
        private static TextViewPosition GetEndOfLineCaretPosition(VisualLine visualLine, TextLine textLine)
        {
            var newVisualCol = visualLine.GetTextLineVisualStartColumn(textLine) + textLine.Length - textLine.TrailingWhitespaceLength;
            var pos          = visualLine.GetTextViewPosition(newVisualCol);

            pos.IsAtEndOfLine = true;
            return(pos);
        }
Beispiel #5
0
        static TextViewPosition GetPrevCaretPosition(TextView textView, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode, bool enableVirtualSpace)
        {
            int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Backward, mode, enableVirtualSpace);

            if (pos >= 0)
            {
                return(visualLine.GetTextViewPosition(pos));
            }
            var previousDocumentLine = visualLine.FirstDocumentLine.PreviousLine;

            if (previousDocumentLine != null)
            {
                var previousLine = textView.GetOrConstructVisualLine(previousDocumentLine);
                pos = previousLine.GetNextCaretPosition(previousLine.VisualLength + 1, LogicalDirection.Backward, mode, enableVirtualSpace);
                return(previousLine.GetTextViewPosition(pos));
            }
            return(new TextViewPosition(0, 0));
        }
        static TextViewPosition GetStartOfLineCaretPosition(int oldVC, VisualLine visualLine, TextLine textLine, bool enableVirtualSpace)
        {
            int newVC = visualLine.GetTextLineVisualStartColumn(textLine);

            if (newVC == 0)
            {
                newVC = visualLine.GetNextCaretPosition(newVC - 1, LogicalDirection.Forward, CaretPositioningMode.WordStart, enableVirtualSpace);
            }
            if (newVC < 0)
            {
                throw ThrowUtil.NoValidCaretPosition();
            }
            // when the caret is already at the start of the text, jump to start before whitespace
            if (newVC == oldVC)
            {
                newVC = 0;
            }
            return(visualLine.GetTextViewPosition(newVC));
        }
        static TextViewPosition GetUpDownCaretPosition(TextView textView, TextViewPosition caretPosition, CaretMovementType direction, VisualLine visualLine, TextLine textLine, bool enableVirtualSpace, ref double xPos)
        {
            // moving up/down happens using the desired visual X position
            if (double.IsNaN(xPos))
            {
                xPos = visualLine.GetTextLineVisualXPosition(textLine, caretPosition.VisualColumn);
            }
            // now find the TextLine+VisualLine where the caret will end up in
            VisualLine targetVisualLine = visualLine;
            TextLine   targetLine;
            int        textLineIndex = visualLine.TextLines.IndexOf(textLine);

            switch (direction)
            {
            case CaretMovementType.LineUp:
            {
                // Move up: move to the previous TextLine in the same visual line
                // or move to the last TextLine of the previous visual line
                int prevLineNumber = visualLine.FirstDocumentLine.LineNumber - 1;
                if (textLineIndex > 0)
                {
                    targetLine = visualLine.TextLines[textLineIndex - 1];
                }
                else if (prevLineNumber >= 1)
                {
                    DocumentLine prevLine = textView.Document.GetLineByNumber(prevLineNumber);
                    targetVisualLine = textView.GetOrConstructVisualLine(prevLine);
                    targetLine       = targetVisualLine.TextLines[targetVisualLine.TextLines.Count - 1];
                }
                else
                {
                    targetLine = null;
                }
                break;
            }

            case CaretMovementType.LineDown:
            {
                // Move down: move to the next TextLine in the same visual line
                // or move to the first TextLine of the next visual line
                int nextLineNumber = visualLine.LastDocumentLine.LineNumber + 1;
                if (textLineIndex < visualLine.TextLines.Count - 1)
                {
                    targetLine = visualLine.TextLines[textLineIndex + 1];
                }
                else if (nextLineNumber <= textView.Document.LineCount)
                {
                    DocumentLine nextLine = textView.Document.GetLineByNumber(nextLineNumber);
                    targetVisualLine = textView.GetOrConstructVisualLine(nextLine);
                    targetLine       = targetVisualLine.TextLines[0];
                }
                else
                {
                    targetLine = null;
                }
                break;
            }

            case CaretMovementType.PageUp:
            case CaretMovementType.PageDown:
            {
                // Page up/down: find the target line using its visual position
                double yPos = visualLine.GetTextLineVisualYPosition(textLine, VisualYPosition.LineMiddle);
                if (direction == CaretMovementType.PageUp)
                {
                    yPos -= textView.RenderSize.Height;
                }
                else
                {
                    yPos += textView.RenderSize.Height;
                }
                DocumentLine newLine = textView.GetDocumentLineByVisualTop(yPos);
                targetVisualLine = textView.GetOrConstructVisualLine(newLine);
                targetLine       = targetVisualLine.GetTextLineByVisualYPosition(yPos);
                break;
            }

            default:
                throw new NotSupportedException(direction.ToString());
            }
            if (targetLine != null)
            {
                double yPos            = targetVisualLine.GetTextLineVisualYPosition(targetLine, VisualYPosition.LineMiddle);
                int    newVisualColumn = targetVisualLine.GetVisualColumn(new Point(xPos, yPos), enableVirtualSpace);

                // prevent wrapping to the next line; TODO: could 'IsAtEnd' help here?
                int targetLineStartCol = targetVisualLine.GetTextLineVisualStartColumn(targetLine);
                if (newVisualColumn >= targetLineStartCol + targetLine.Length)
                {
                    if (newVisualColumn <= targetVisualLine.VisualLength)
                    {
                        newVisualColumn = targetLineStartCol + targetLine.Length - 1;
                    }
                }
                return(targetVisualLine.GetTextViewPosition(newVisualColumn));
            }
            else
            {
                return(caretPosition);
            }
        }