private void FormatTrackingSpan(IBraceCompletionSession session, bool shouldHonorAutoFormattingOnCloseBraceOption) { if (!session.SubjectBuffer.GetFeatureOnOffOption(FeatureOnOffOptions.AutoFormattingOnCloseBrace) && shouldHonorAutoFormattingOnCloseBraceOption) { return; } var snapshot = session.SubjectBuffer.CurrentSnapshot; var startPoint = session.OpeningPoint.GetPoint(snapshot); var endPoint = session.ClosingPoint.GetPoint(snapshot); var startPosition = startPoint.Position; var endPosition = endPoint.Position; var document = snapshot.GetOpenDocumentInCurrentContextWithChanges(); var style = document != null ? document.GetOptionsAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None).GetOption(FormattingOptions.SmartIndent) : FormattingOptions.SmartIndent.DefaultValue; if (style == FormattingOptions.IndentStyle.Smart) { // skip whitespace while (startPosition >= 0 && char.IsWhiteSpace(snapshot[startPosition])) { startPosition--; } // skip token startPosition--; while (startPosition >= 0 && !char.IsWhiteSpace(snapshot[startPosition])) { startPosition--; } } session.SubjectBuffer.Format(TextSpan.FromBounds(Math.Max(startPosition, 0), endPosition)); }
/// <summary> /// It is unclear why, but we are sometimes asked to navigate to a <see cref="TextSpan"/> /// that is not inside the bounds of the associated <see cref="Document"/>. This method /// returns a span that is guaranteed to be inside the <see cref="Document"/> bounds. If /// the returned span is different from the given span, then the worst observable behavior /// is either no navigation or navigation to the end of the document. /// See https://github.com/dotnet/roslyn/issues/7660 for more details. /// </summary> private static TextSpan GetSpanWithinDocumentBounds(TextSpan span, int documentLength) { return(TextSpan.FromBounds(GetPositionWithinDocumentBounds(span.Start, documentLength), GetPositionWithinDocumentBounds(span.End, documentLength))); }