/// <summary> /// Changes a part of the current document line. /// </summary> /// <param name="startOffset">Start offset of the region to change</param> /// <param name="endOffset">End offset of the region to change</param> /// <param name="action">Action that changes an individual <see cref="VisualLineElement"/>.</param> protected void ChangeLinePart(int startOffset, int endOffset, Action <VisualLineElement> action) { if (startOffset < currentDocumentLineStartOffset || startOffset > currentDocumentLineEndOffset) { /* Az Add Start */ return; /* Az Add End */ //throw new ArgumentOutOfRangeException("startOffset", startOffset, "Value must be between " + currentDocumentLineStartOffset + " and " + currentDocumentLineEndOffset); } if (endOffset < startOffset || endOffset > currentDocumentLineEndOffset) { /* Az Add Start */ return; /* Az Add End */ //throw new ArgumentOutOfRangeException("endOffset", endOffset, "Value must be between " + startOffset + " and " + currentDocumentLineEndOffset); } VisualLine vl = this.CurrentContext.VisualLine; int visualStart = vl.GetVisualColumn(startOffset - firstLineStart); int visualEnd = vl.GetVisualColumn(endOffset - firstLineStart); if (visualStart < visualEnd) { ChangeVisualElements(visualStart, visualEnd, action); } }
/// <summary> /// Changes a part of the current document line. /// </summary> /// <param name="startOffset">Start offset of the region to change</param> /// <param name="endOffset">End offset of the region to change</param> /// <param name="action">Action that changes an individual <see cref="VisualLineElement"/>.</param> protected void ChangeLinePart(int startOffset, int endOffset, IList <VisualLineElement> elements, DocumentContext context, Action <VisualLineElement> action) { if (startOffset < context.CurrentDocumentLineStartOffset || startOffset > context.CurrentDocumentLineEndOffset) { throw new ArgumentOutOfRangeException("startOffset", startOffset, "Value must be between " + context.CurrentDocumentLineStartOffset + " and " + context.CurrentDocumentLineEndOffset); } if (endOffset < startOffset || endOffset > context.CurrentDocumentLineEndOffset) { throw new ArgumentOutOfRangeException("endOffset", endOffset, "Value must be between " + startOffset + " and " + context.CurrentDocumentLineEndOffset); } VisualLine vl = context.CurrentContext.VisualLine; int visualStart = vl.GetVisualColumn(startOffset - context.FirstLineStart); int visualEnd = vl.GetVisualColumn(endOffset - context.FirstLineStart); if (visualStart < visualEnd) { ChangeVisualElements(visualStart, visualEnd, elements, action); } }
/// <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); int firstDocumentLineOffset = visualLine.FirstDocumentLine.Offset; if (position.VisualColumn < 0) { position.VisualColumn = visualLine.GetVisualColumn(caretOffset - firstDocumentLineOffset); } else { int offsetFromVisualColumn = visualLine.GetRelativeOffset(position.VisualColumn); offsetFromVisualColumn += firstDocumentLineOffset; if (offsetFromVisualColumn != caretOffset) { position.VisualColumn = visualLine.GetVisualColumn(caretOffset - firstDocumentLineOffset); } else { if (position.VisualColumn > visualLine.VisualLength) { position.VisualColumn = visualLine.VisualLength; } } } // search possible caret positions int newVisualColumnForwards = visualLine.GetNextCaretPosition(position.VisualColumn - 1, LogicalDirection.Forward, CaretPositioningMode.Normal); // 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); 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); } }
/// <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); int firstDocumentLineOffset = visualLine.FirstDocumentLine.Offset; if (position.VisualColumn < 0) { position.VisualColumn = visualLine.GetVisualColumn(caretOffset - firstDocumentLineOffset); } else { int offsetFromVisualColumn = visualLine.GetRelativeOffset(position.VisualColumn); offsetFromVisualColumn += firstDocumentLineOffset; if (offsetFromVisualColumn != caretOffset) { position.VisualColumn = visualLine.GetVisualColumn(caretOffset - firstDocumentLineOffset); } else { if (position.VisualColumn > visualLine.VisualLength) { position.VisualColumn = visualLine.VisualLength; } } } // search possible caret position (first try forwards) int newVisualColumn = visualLine.GetNextCaretPosition(position.VisualColumn - 1, LogicalDirection.Forward, CaretPositioningMode.Normal); if (newVisualColumn < 0) { // then try backwards newVisualColumn = visualLine.GetNextCaretPosition(position.VisualColumn + 1, LogicalDirection.Backward, CaretPositioningMode.Normal); } if (newVisualColumn < 0) throw ThrowUtil.NoValidCaretPosition(); if (newVisualColumn != position.VisualColumn) { int newOffset = visualLine.GetRelativeOffset(newVisualColumn) + firstDocumentLineOffset; this.Position = new TextViewPosition(textView.Document.GetLocation(newOffset), newVisualColumn); } }