public SnapshotPoint?getCharAtColumn(SnapshotSpan line, int column) { ++column; int current = 0; SnapshotPoint result = line.Start; int charwidth = 0; if (result != line.End) { charwidth = getCharacterWidth(result.GetChar()); } while (current + charwidth < column && result < line.End) { current += charwidth; result = result.Add(1); if (result < line.End) { charwidth = getCharacterWidth(result.GetChar()); } } if (result >= line.End) { return(null); } return(result); }
private TextSpan GetTextSpanFromCaret(SnapshotPoint caretPosition, ITextSnapshotLine caretLine) { if (caretLine.Length == 0) { return(TextSpan.FromBounds(caretLine.Start.Position, caretLine.End.Position)); } else if (caretPosition.Position < caretLine.End.Position) { var nextPoint = caretPosition.Add(1); return(TextSpan.FromBounds(caretPosition.Position, nextPoint.Position)); } else { var prevPoint = caretPosition.Add(-1); return(TextSpan.FromBounds(prevPoint.Position, caretPosition.Position)); } }
private void CheckLeadingWhiteSpace(List <ClassificationSpan> result, ITextSnapshotLine line, string text) { int index = 0; SnapshotPoint lineStart = line.Start; SnapshotPoint?startPoint = null; foreach (char ch in text) { // Quit if when we see anything other than a space or tab. if (ch != ' ' && ch != '\t') { break; } // See if we're starting or finishing a span of invalid whitespace characters. if ((ch == '\t' && this.convertTabsToSpaces) || (ch == ' ' && !this.convertTabsToSpaces)) { // We need to keep the earliest start point in the current span. if (startPoint == null) { startPoint = lineStart.Add(index); } } else if (startPoint != null) { // We finished an invalid whitespace span, so add it. SnapshotPoint endPoint = lineStart.Add(index); this.AddClassificationSpan(result, startPoint.Value, endPoint); startPoint = null; } index++; } if (startPoint != null) { SnapshotPoint endPoint = index >= text.Length ? line.End : lineStart.Add(index); this.AddClassificationSpan(result, startPoint.Value, endPoint); } }
/// <summary> /// Skips the chars. /// </summary> public static SnapshotPoint SkipChars(this SnapshotPoint start, char value) { var currentChar = start.GetChar(); while (currentChar == value) { start = start.Add(1); currentChar = start.GetChar(); } return(start); }
private static void OnActiveSessionCommitted(object sender, EventArgs e) { ITextView textView = (sender as ICompletionSession).TextView; SnapshotPoint startPoint = ISESnippetSessionManager.insertSpan.GetStartPoint(textView.TextBuffer.CurrentSnapshot); SnapshotPoint endPoint = ISESnippetSessionManager.insertSpan.GetEndPoint(textView.TextBuffer.CurrentSnapshot); if (ISESnippetSessionManager.selectedSnippet.CaretOffsetFromStart >= 0) { if (endPoint.Position - startPoint.Position < ISESnippetSessionManager.selectedSnippet.CaretOffsetFromStart) { return; } textView.Caret.MoveTo(startPoint.Add(ISESnippetSessionManager.selectedSnippet.CaretOffsetFromStart)); } if (ISESnippetSessionManager.selectedSnippet.Indent && startPoint.Position > startPoint.GetContainingLine().Start.Position) { string indentationPrependText = ISESnippetSessionManager.GetIndentationPrependText(startPoint); string text = ISESnippetSessionManager.insertSpan.GetText(textView.TextBuffer.CurrentSnapshot); Stack <int> stack = new Stack <int>(); int num; for (int i = 0; i < text.Length; i = num + 2) { num = text.IndexOf("\r\n", i, StringComparison.Ordinal); if (num == -1) { break; } stack.Push(num + 2); } ITextEdit textEdit = textView.TextBuffer.CreateEdit(); while (stack.Count > 0) { textEdit.Insert(stack.Pop() + startPoint.Position, indentationPrependText); } textEdit.Apply(); } if (ISESnippetSessionManager.activeSession != null) { ISESnippetSessionManager.activeSession.Committed -= ISESnippetSessionManager.eventHandlerSessionCommitted; ISESnippetSessionManager.activeSession.SelectedCompletionSet.SelectionStatusChanged -= ISESnippetSessionManager.eventHandlerSelectionChanged; } }
/// <summary> /// This method selects the text at the end of the drop operation. /// </summary> /// <remarks> /// This method will only be called if the drop of data resulted in an <see cref="DragDropEffects"/> other than DragDropEffects.None. /// </remarks> /// <param name="insertionPoint">The position at which data was inserted.</param> /// <param name="dataLength">The length of the data inserted in the buffer.</param> /// <param name="virtualSpaceLength">The length of whitespace inserted in the buffer to fill the gap between the closest buffer position /// and the position at which data was dropped. This value will be non-zero only if data was dropped into virtual space.</param> /// <param name="dragDropInfo">The <see cref="DragDropInfo"/> class containing information about the drop.</param> /// <param name="reverse">True if the existing selection prior to the drop was reversed.</param> protected virtual void SelectText(SnapshotPoint insertionPoint, int dataLength, DragDropInfo dragDropInfo, bool reverse) { if (insertionPoint == null) { throw new ArgumentNullException(nameof(insertionPoint)); } if (dragDropInfo == null) { throw new ArgumentNullException(nameof(dragDropInfo)); } VirtualSnapshotPoint anchorPoint = new VirtualSnapshotPoint(insertionPoint); VirtualSnapshotPoint activePoint = new VirtualSnapshotPoint(insertionPoint.Add(dataLength)); if (dragDropInfo.IsInternal && reverse) { _editorOperations.SelectAndMoveCaret(activePoint, anchorPoint, TextSelectionMode.Stream); } else { _editorOperations.SelectAndMoveCaret(anchorPoint, activePoint, TextSelectionMode.Stream); } }
/// <summary> /// Indicates that the drag and drop operation has completed, and that the final tasks, if any, should be performed now. /// </summary> /// <param name="dragDropInfo"> /// Information about the drag and drop operation in progress. /// </param> /// <returns> /// The drag and drop effects of this drop operation. For example, if the drop operation has moved data, /// DragDropPointerEffects.Move should be returned. /// </returns> /// <remarks>This method is called when the user drops the data onto the editor. /// This marks the end of a drag and drop operation. /// The <see cref="IDropHandler"/> is expected to perform the final tasks of the operation. /// </remarks> public virtual DragDropPointerEffects HandleDataDropped(DragDropInfo dragDropInfo) { if (dragDropInfo == null) { throw new ArgumentNullException(nameof(dragDropInfo)); } ITextSelection selection = _cocoaTextView.Selection; //keeps track of the result of this operation DragDropPointerEffects result = DragDropPointerEffects.None; //tracks the location at which the data was dropped VirtualSnapshotPoint dropLocation = dragDropInfo.VirtualBufferPosition; //convert the drag/drop data to text string dragDropText = this.ExtractText(dragDropInfo); bool isReversed = selection.IsReversed; bool copyRequested = (dragDropInfo.KeyStates & NSEventModifierMask.AlternateKeyMask) == NSEventModifierMask.AlternateKeyMask; bool copyAllowed = (dragDropInfo.AllowedEffects & NSDragOperation.Copy) == NSDragOperation.Copy; ITextSnapshot preEditSnapshot = _cocoaTextView.TextSnapshot; // track the point where the data will be inserted ITrackingPoint insertionPoint = preEditSnapshot.CreateTrackingPoint(dropLocation.Position, PointTrackingMode.Negative); // track the currently selected spans before any edits are performed on the buffer List <ITrackingSpan> selectionSpans = new List <ITrackingSpan>(); foreach (SnapshotSpan selectedSpan in selection.SelectedSpans) { selectionSpans.Add(preEditSnapshot.CreateTrackingSpan(selectedSpan, SpanTrackingMode.EdgeExclusive)); } // perform any necessary pre edit actions this.PerformPreEditActions(dragDropInfo); // clear selection before data operations if (!selection.IsEmpty) { selection.Clear(); } // a reference to the snapshot resulting from the edits bool successfulEdit = false; // if the data is being dropped in virtual space, calculate how many whitespace characters will be inserted // to fill the gap between the dropped point and the closest buffer position int virtualSpaceLength = 0; if (dragDropInfo.VirtualBufferPosition.IsInVirtualSpace) { virtualSpaceLength = _editorOperations.GetWhitespaceForVirtualSpace(dragDropInfo.VirtualBufferPosition).Length; } if (copyRequested && copyAllowed) { //copy the data by inserting it in the buffer successfulEdit = this.InsertText(dropLocation, dragDropText); if (successfulEdit) { result = DragDropPointerEffects.Copy; } } else { //the data needs to be moved if (dragDropInfo.IsInternal) { //delete the existing selection, and add the data to the new location successfulEdit = this.MoveText(dropLocation, selectionSpans, dragDropText); } else { //the drag is not from this text view, just insert the data at dropLocation successfulEdit = this.InsertText(dropLocation, dragDropText); } //set the pointer effect to move if the edit was successful since that implies that the data was moved successfully if (successfulEdit) { result = DragDropPointerEffects.Move; } } // finally select the newly inserted data if the operation was successful if (result != DragDropPointerEffects.None) { SnapshotPoint textInsertionPoint = insertionPoint.GetPoint(_cocoaTextView.TextSnapshot); // if the data was inserted in virtual space, offset the selection's anchor point by the whitespace that was inserted // in virtual space if (virtualSpaceLength != 0) { textInsertionPoint = textInsertionPoint.Add(virtualSpaceLength); } this.SelectText(textInsertionPoint, dragDropText.Length, dragDropInfo, isReversed); } // perform any post edit actions as necessary this.PerformPostEditActions(dragDropInfo, successfulEdit); return(result); }