Esempio n. 1
0
        /// <summary>
        /// Validates the visual column of the caret using the specified visual line.
        /// The visual line must contain the caret offset.
        /// </summary>
        void RevalidateVisualColumn(VisualLine visualLine)
        {
            if (visualLine == null)
                throw new ArgumentNullException("visualLine");

            // mark column as validated
            visualColumnValid = true;

            int caretOffset = textView.Document.GetOffset(position.Location);
            int firstDocumentLineOffset = visualLine.FirstDocumentLine.Offset;
            position.VisualColumn = visualLine.ValidateVisualColumn(position, textArea.Selection.EnableVirtualSpace);

            // search possible caret positions
            int newVisualColumnForwards = visualLine.GetNextCaretPosition(position.VisualColumn - 1, LogicalDirection.Forward, CaretPositioningMode.Normal, textArea.Selection.EnableVirtualSpace);
            // If position.VisualColumn was valid, we're done with validation.
            if (newVisualColumnForwards != position.VisualColumn) {
                // also search backwards so that we can pick the better match
                int newVisualColumnBackwards = visualLine.GetNextCaretPosition(position.VisualColumn + 1, LogicalDirection.Backward, CaretPositioningMode.Normal, textArea.Selection.EnableVirtualSpace);

                if (newVisualColumnForwards < 0 && newVisualColumnBackwards < 0)
                    throw ThrowUtil.NoValidCaretPosition();

                // determine offsets for new visual column positions
                int newOffsetForwards;
                if (newVisualColumnForwards >= 0)
                    newOffsetForwards = visualLine.GetRelativeOffset(newVisualColumnForwards) + firstDocumentLineOffset;
                else
                    newOffsetForwards = -1;
                int newOffsetBackwards;
                if (newVisualColumnBackwards >= 0)
                    newOffsetBackwards = visualLine.GetRelativeOffset(newVisualColumnBackwards) + firstDocumentLineOffset;
                else
                    newOffsetBackwards = -1;

                int newVisualColumn, newOffset;
                // if there's only one valid position, use it
                if (newVisualColumnForwards < 0) {
                    newVisualColumn = newVisualColumnBackwards;
                    newOffset = newOffsetBackwards;
                } else if (newVisualColumnBackwards < 0) {
                    newVisualColumn = newVisualColumnForwards;
                    newOffset = newOffsetForwards;
                } else {
                    // two valid positions: find the better match
                    if (Math.Abs(newOffsetBackwards - caretOffset) < Math.Abs(newOffsetForwards - caretOffset)) {
                        // backwards is better
                        newVisualColumn = newVisualColumnBackwards;
                        newOffset = newOffsetBackwards;
                    } else {
                        // forwards is better
                        newVisualColumn = newVisualColumnForwards;
                        newOffset = newOffsetForwards;
                    }
                }
                this.Position = new TextViewPosition(textView.Document.GetLocation(newOffset), newVisualColumn);
            }
            isInVirtualSpace = (position.VisualColumn > visualLine.VisualLength);
        }
 static void MoveCaretRight(TextArea textArea, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode)
 {
     int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Forward, mode, textArea.Selection.EnableVirtualSpace);
     if (pos >= 0) {
         SetCaretPosition(textArea, pos, visualLine.GetRelativeOffset(pos) + visualLine.FirstDocumentLine.Offset);
     } else {
         // move to start of next line
         DocumentLine nextDocumentLine = visualLine.LastDocumentLine.NextLine;
         if (nextDocumentLine != null) {
             VisualLine nextLine = textArea.TextView.GetOrConstructVisualLine(nextDocumentLine);
             pos = nextLine.GetNextCaretPosition(-1, LogicalDirection.Forward, mode, textArea.Selection.EnableVirtualSpace);
             if (pos < 0)
                 throw ThrowUtil.NoValidCaretPosition();
             SetCaretPosition(textArea, pos, nextLine.GetRelativeOffset(pos) + nextLine.FirstDocumentLine.Offset);
         } else {
             // at end of document
             Debug.Assert(visualLine.LastDocumentLine.Offset + visualLine.LastDocumentLine.TotalLength == textArea.Document.TextLength);
             SetCaretPosition(textArea, -1, textArea.Document.TextLength);
         }
     }
 }
 static void MoveCaretToStartOfLine(TextArea textArea, VisualLine visualLine)
 {
     int newVC = visualLine.GetNextCaretPosition(-1, LogicalDirection.Forward, CaretPositioningMode.WordStart, textArea.Selection.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 == textArea.Caret.VisualColumn)
         newVC = 0;
     int offset = visualLine.FirstDocumentLine.Offset + visualLine.GetRelativeOffset(newVC);
     SetCaretPosition(textArea, newVC, offset);
 }
 static void MoveCaretLeft(TextArea textArea, TextViewPosition caretPosition, VisualLine visualLine, CaretPositioningMode mode)
 {
     int pos = visualLine.GetNextCaretPosition(caretPosition.VisualColumn, LogicalDirection.Backward, mode, textArea.Selection.EnableVirtualSpace);
     if (pos >= 0) {
         SetCaretPosition(textArea, pos, visualLine.GetRelativeOffset(pos) + visualLine.FirstDocumentLine.Offset);
     } else {
         // move to end of previous line
         DocumentLine previousDocumentLine = visualLine.FirstDocumentLine.PreviousLine;
         if (previousDocumentLine != null) {
             VisualLine previousLine = textArea.TextView.GetOrConstructVisualLine(previousDocumentLine);
             pos = previousLine.GetNextCaretPosition(previousLine.VisualLength + 1, LogicalDirection.Backward, mode, textArea.Selection.EnableVirtualSpace);
             if (pos < 0)
                 throw ThrowUtil.NoValidCaretPosition();
             SetCaretPosition(textArea, pos, previousLine.GetRelativeOffset(pos) + previousLine.FirstDocumentLine.Offset);
         } else {
             // at start of document
             Debug.Assert(visualLine.FirstDocumentLine.Offset == 0);
             SetCaretPosition(textArea, 0, 0);
         }
     }
 }