예제 #1
0
        public void OnReturn(IBraceCompletionSession session) {
            if (NodejsPackage.Instance.FormattingGeneralOptionsPage.FormatOnEnter) {
                // reshape code from
                // {
                // |}
                // 
                // to
                // {
                //     |
                // }
                // where | indicates caret position.

                var closingPointPosition = session.ClosingPoint.GetPosition(session.SubjectBuffer.CurrentSnapshot);

                Debug.Assert(
                    condition: closingPointPosition > 0,
                    message: "The closing point position should always be greater than zero",
                    detailMessage: "The closing point position should always be greater than zero, " +
                                   "since there is also an opening point for this brace completion session");

                // Insert an extra newline and indent the closing brace manually.           
                session.SubjectBuffer.Insert(
                    closingPointPosition - 1,
                    VsExtensions.GetNewLineText(session.TextView.TextSnapshot));

                // Format before setting the caret.
                Format(session);

                // After editing, set caret to the correct position.
                SetCaretPosition(session);
            }
        }
 /// <summary>
 /// Called by the editor when return is pressed while both 
 /// braces are on the same line and no typing has occurred 
 /// in the session.
 /// </summary>
 /// <remarks>
 /// Called after the newline has been inserted into the buffer.
 /// Formatting for scenarios where the closing brace needs to be 
 /// moved down an additional line past the caret should be done here.
 /// </remarks>
 /// <param name="session">Default brace completion session</param>
 public void OnReturn(IBraceCompletionSession session) {
     if (session.OpeningBrace == '{' && REditorSettings.AutoFormat) {
         AutoFormat.IgnoreOnce = true;
         EnsureTreeReady(session.SubjectBuffer);
         FormatOperations.FormatCurrentScope(session.TextView, session.SubjectBuffer, indentCaret: true);
     }
 }
예제 #3
0
        private static void SetCaretPosition(IBraceCompletionSession session) {
            // Find next line from brace.
            var snapshot = session.SubjectBuffer.CurrentSnapshot;
            var openCurlyLine = session.OpeningPoint.GetPoint(snapshot).GetContainingLine();
            var nextLineNumber = openCurlyLine.LineNumber + 1;

            bool nextLineExists = nextLineNumber < snapshot.LineCount;
            Debug.Assert(nextLineExists, "There are no lines after this brace completion's opening brace, no place to seek caret to.");
            if (!nextLineExists) {
                // Don't move the caret as we have somehow ended up without a line following our opening brace.
                return;
            }

            // Get indent for this line.
            ITextSnapshotLine nextLine = snapshot.GetLineFromLineNumber(nextLineNumber);
            var indentation = GetIndentationLevelForLine(session, nextLine);
            if (indentation > 0) {
                // before deleting, make sure this line is only whitespace.
                bool lineIsWhitepace = string.IsNullOrWhiteSpace(nextLine.GetText());
                Debug.Assert(lineIsWhitepace, "The line after the brace should be empty.");
                if (lineIsWhitepace) {
                    session.SubjectBuffer.Delete(nextLine.Extent);
                    MoveCaretTo(session.TextView, nextLine.End, indentation);
                }
            } else {
                MoveCaretTo(session.TextView, nextLine.End);
            }
        }
 /// <summary>
 /// Called before the session is added to the stack.
 /// </summary>
 /// <remarks>
 /// If additional formatting is required for the opening or 
 /// closing brace it should be done here.
 /// </remarks>
 /// <param name="session">Default brace completion session</param>
 public void Start(IBraceCompletionSession session) {
     if (session.OpeningBrace == '{' && REditorSettings.AutoFormat) {
         AutoFormat.IgnoreOnce = false;
         EnsureTreeReady(session.SubjectBuffer);
         FormatOperations.FormatCurrentNode<IStatement>(session.TextView, session.SubjectBuffer);
     }
 }
 /// <summary>
 /// Called after the session has been removed from the stack.
 /// </summary>
 /// <param name="session">Default brace completion session</param>
 public void Finish(IBraceCompletionSession session) {
     //if (session.OpeningBrace == '{' && REditorSettings.AutoFormat) {
     //    AutoFormat.IgnoreOnce = false;
     //    EnsureTreeReady(session.SubjectBuffer);
     //    FormatOperations.FormatCurrentScope(session.TextView, session.SubjectBuffer, indentCaret: false);
     //}
 }
        public override void AfterReturn(IBraceCompletionSession session, CancellationToken cancellationToken)
        {
            // check whether shape of the braces are what we support
            // shape must be either "{|}" or "{ }". | is where caret is. otherwise, we don't do any special behavior
            if (!ContainsOnlyWhitespace(session))
            {
                return;
            }

            // alright, it is in right shape.
            var undoHistory = GetUndoHistory(session.TextView);
            using (var transaction = undoHistory.CreateTransaction(EditorFeaturesResources.Brace_Completion))
            {
                var document = session.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
                if (document != null)
                {
                    document.InsertText(session.ClosingPoint.GetPosition(session.SubjectBuffer.CurrentSnapshot) - 1, Environment.NewLine, cancellationToken);
                    FormatTrackingSpan(session, shouldHonorAutoFormattingOnCloseBraceOption: false, rules: GetFormattingRules(document));

                    // put caret at right indentation
                    PutCaretOnLine(session, session.OpeningPoint.GetPoint(session.SubjectBuffer.CurrentSnapshot).GetContainingLineNumber() + 1);

                    transaction.Complete();
                }
            }
        }
        private static bool ContainsOnlyWhitespace(IBraceCompletionSession session)
        {
            var span = session.GetSessionSpan();

            var snapshot = span.Snapshot;

            var start = span.Start.Position;
            start = snapshot[start] == session.OpeningBrace ? start + 1 : start;

            var end = span.End.Position - 1;
            end = snapshot[end] == session.ClosingBrace ? end - 1 : end;

            if (!start.PositionInSnapshot(snapshot) ||
                !end.PositionInSnapshot(snapshot))
            {
                return false;
            }

            for (int i = start; i <= end; i++)
            {
                if (!char.IsWhiteSpace(snapshot[i]))
                {
                    return false;
                }
            }

            return true;
        }
        public bool TryCreateSession(ITextView textView, SnapshotPoint openingPoint, char openingBrace, char closingBrace, out IBraceCompletionSession session)
        {
            this.AssertIsForeground();

            var textSnapshot = openingPoint.Snapshot;
            var document = textSnapshot.GetOpenDocumentInCurrentContextWithChanges();
            if (document != null)
            {
                var editorSessionFactory = document.GetLanguageService<IEditorBraceCompletionSessionFactory>();
                if (editorSessionFactory != null)
                {
                    // Brace completion is (currently) not cancellable.
                    var cancellationToken = CancellationToken.None;

                    var editorSession = editorSessionFactory.TryCreateSession(document, openingPoint, openingBrace, cancellationToken);
                    if (editorSession != null)
                    {
                        var undoHistory = _undoManager.GetTextBufferUndoManager(textView.TextBuffer).TextBufferUndoHistory;
                        session = new BraceCompletionSession(
                            textView, openingPoint.Snapshot.TextBuffer, openingPoint, openingBrace, closingBrace,
                            undoHistory, _editorOperationsFactoryService,
                            editorSession);
                        return true;
                    }
                }
            }

            session = null;
            return false;
        }
        public override bool CheckOpeningPoint(IBraceCompletionSession session, CancellationToken cancellationToken)
        {
            var snapshot = session.SubjectBuffer.CurrentSnapshot;
            var position = session.OpeningPoint.GetPosition(snapshot);
            var token = snapshot.FindToken(position, cancellationToken);

            // check token at the opening point first
            if (!IsValidToken(token) ||
                token.RawKind != OpeningTokenKind ||
                token.SpanStart != position || token.Parent == null)
            {
                return false;
            }

            // now check whether parser think whether there is already counterpart closing parenthesis
            var pair = token.Parent.GetParentheses();

            // if pair is on the same line, then the closing parenthesis must belong to other tracker.
            // let it through
            if (snapshot.GetLineNumberFromPosition(pair.Item1.SpanStart) == snapshot.GetLineNumberFromPosition(pair.Item2.Span.End))
            {
                return true;
            }

            return (int)pair.Item2.Kind() != ClosingTokenKind || pair.Item2.Span.Length == 0;
        }
        public bool CheckOpeningPoint(IBraceCompletionSession session, CancellationToken cancellationToken)
        {
            var snapshot = session.SubjectBuffer.CurrentSnapshot;
            var position = session.OpeningPoint.GetPosition(snapshot);
            var token = snapshot.FindToken(position, cancellationToken);

            return token.IsKind(SyntaxKind.InterpolatedStringStartToken, SyntaxKind.InterpolatedVerbatimStringStartToken)
                && token.Span.End - 1 == position;
        }
        internal void CheckBackspace(IBraceCompletionSession session)
        {
            session.TextView.TryMoveCaretToAndEnsureVisible(session.OpeningPoint.GetPoint(session.SubjectBuffer.CurrentSnapshot).Add(1));
            session.PreBackspace(out var handled);
            if (!handled)
            {
                session.PostBackspace();
            }

            Assert.Null(session.OpeningPoint);
            Assert.Null(session.ClosingPoint);
        }
예제 #12
0
 private void Format(IBraceCompletionSession session) {
     var buffer = session.SubjectBuffer;
     EditFilter.ApplyEdits(
         buffer,
         Formatter.GetEditsAfterEnter(
             buffer.CurrentSnapshot.GetText(),
             session.OpeningPoint.GetPosition(buffer.CurrentSnapshot),
             session.ClosingPoint.GetPosition(buffer.CurrentSnapshot),
             EditFilter.CreateFormattingOptions(session.TextView.Options, session.TextView.TextSnapshot)
         )
     );
 }
        public virtual bool CheckOpeningPoint(IBraceCompletionSession session, CancellationToken cancellationToken)
        {
            var snapshot = session.SubjectBuffer.CurrentSnapshot;
            var position = session.OpeningPoint.GetPosition(snapshot);
            var token = snapshot.FindToken(position, cancellationToken);

            if (!IsValidToken(token))
            {
                return false;
            }

            return token.RawKind == OpeningTokenKind && token.SpanStart == position;
        }
        protected bool CheckClosingTokenKind(IBraceCompletionSession session, CancellationToken cancellationToken)
        {
            var document = session.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
            if (document != null)
            {
                var root = document.GetSyntaxRootSynchronously(cancellationToken);
                var position = session.ClosingPoint.GetPosition(session.SubjectBuffer.CurrentSnapshot);

                return root.FindTokenFromEnd(position, includeZeroWidth: false, findInsideTrivia: true).RawKind == this.ClosingTokenKind;
            }

            return true;
        }
        protected bool CheckCurrentPosition(IBraceCompletionSession session, CancellationToken cancellationToken)
        {
            var document = session.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
            if (document != null)
            {
                // make sure auto closing is called from a valid position
                var tree = document.GetSyntaxRootSynchronously(cancellationToken).SyntaxTree;

                return !_syntaxFactsService.IsInNonUserCode(tree, session.GetCaretPosition().Value, cancellationToken);
            }

            return true;
        }
        internal void CheckStart(IBraceCompletionSession session, bool expectValidSession = true)
        {
            Type(session, session.OpeningBrace.ToString());

            session.Start();

            if (expectValidSession)
            {
                var closingPoint = session.ClosingPoint.GetPoint(session.SubjectBuffer.CurrentSnapshot).Subtract(1);
                Assert.Equal(closingPoint.GetChar(), session.ClosingBrace);
            }
            else
            {
                Assert.Null(session.OpeningPoint);
                Assert.Null(session.ClosingPoint);
            }
        }
        public override bool CheckOpeningPoint(IBraceCompletionSession session, CancellationToken cancellationToken)
        {
            var snapshot = session.SubjectBuffer.CurrentSnapshot;
            var position = session.OpeningPoint.GetPosition(snapshot);
            var token = snapshot.FindToken(position, cancellationToken);

            // check what parser thinks about the newly typed "<" and only proceed if parser thinks it is "<" of 
            // type argument or parameter list
            if (!token.CheckParent<TypeParameterListSyntax>(n => n.LessThanToken == token) &&
                !token.CheckParent<TypeArgumentListSyntax>(n => n.LessThanToken == token) &&
                !PossibleTypeArgument(snapshot, token, cancellationToken))
            {
                return false;
            }

            return true;
        }
        public override bool CheckOpeningPoint(IBraceCompletionSession session, CancellationToken cancellationToken)
        {
            var snapshot = session.SubjectBuffer.CurrentSnapshot;
            var position = session.OpeningPoint.GetPosition(snapshot);
            var token = snapshot.FindToken(position, cancellationToken);

            if (!IsValidToken(token) || token.RawKind != OpeningTokenKind)
            {
                return false;
            }

            if (token.SpanStart == position)
            {
                return true;
            }

            return token.SpanStart + 1 == position && snapshot[token.SpanStart] == VerbatimStringPrefix;
        }
        internal void CheckTab(IBraceCompletionSession session, bool allowTab = true)
        {
            session.PreTab(out var handled);
            if (!handled)
            {
                session.PostTab();
            }

            var caret = session.TextView.GetCaretPoint(session.SubjectBuffer).Value;
            if (allowTab)
            {
                Assert.Equal(session.ClosingPoint.GetPosition(session.SubjectBuffer.CurrentSnapshot), caret.Position);
            }
            else
            {
                Assert.True(caret.Position < session.ClosingPoint.GetPosition(session.SubjectBuffer.CurrentSnapshot));
            }
        }
        internal void CheckReturn(IBraceCompletionSession session, int indentation, string result = null)
        {
            session.PreReturn(out var handled);

            Type(session, Environment.NewLine);

            if (!handled)
            {
                session.PostReturn();
            }

            var virtualCaret = session.TextView.GetVirtualCaretPoint(session.SubjectBuffer).Value;
            Assert.Equal(indentation, virtualCaret.VirtualSpaces);

            if (result != null)
            {
                Assert.Equal(result, session.SubjectBuffer.CurrentSnapshot.GetText());
            }
        }
예제 #21
0
        public void OnReturn(IBraceCompletionSession session)
        {
            // check whether shape of the braces are what we support
            // shape must be either "{|}" or "{ }". | is where caret is. otherwise, we don't do any special behavior
            if (!ContainsOnlyWhitespace(session))
                return;

            // alright, it is in right shape.
            var undoHistory = GetUndoHistory(session.TextView);
            using (var transaction = undoHistory.CreateTransaction("Brace completion"))
            {
                session.SubjectBuffer.Insert(session.ClosingPoint.GetPosition(session.SubjectBuffer.CurrentSnapshot) - 1, Environment.NewLine);
                FormatTrackingSpan(session, false);

                // put caret at right indentation
                PutCaretOnLine(session, session.OpeningPoint.GetPoint(session.SubjectBuffer.CurrentSnapshot).GetContainingLine().LineNumber + 1);

                transaction.Complete();
            }
        }
        private bool IsOpeningBraceOfType(IBraceCompletionSession session)
        {
            var snapshot = session.SubjectBuffer.CurrentSnapshot;
            var startPoint = session.OpeningPoint.GetPoint(snapshot);

            var classifier = startPoint.Snapshot.TextBuffer.GetSyntaxTagger();
            var snapshotSpan = new SnapshotSpan(startPoint - 1, 1);
            var classificationSpans = classifier
                .GetTags(new NormalizedSnapshotSpanCollection(snapshotSpan))
                .Where(x => x.Span.Start < startPoint);

            foreach (var span in classificationSpans.Reverse())
            {
                if (span.Tag.ClassificationType.IsOfType(_classificationService.WhiteSpace.Classification))
                    continue;
                if (span.Tag.ClassificationType.IsOfType(_classificationService.Identifier.Classification))
                    continue;

                if (span.Tag.ClassificationType.IsOfType(_classificationService.Keyword.Classification))
                {
                    switch (span.Span.GetText())
                    {
                        case "class":
                        case "struct":
                        case "interface":
                        case "cbuffer":
                            return true;

                        default:
                            return false;
                    }
                }

                return false;
            }

            return false;
        }
예제 #23
0
 internal static void CheckText(IBraceCompletionSession session, string result)
 => Assert.Equal(result, session.SubjectBuffer.CurrentSnapshot.GetText());
예제 #24
0
 public Holder(TestWorkspace workspace, IBraceCompletionSession session)
 {
     this.Workspace = workspace;
     this.Session   = session;
 }
 public bool AllowOverType(IBraceCompletionSession session, CancellationToken cancellationToken)
 {
     return true;
 }
예제 #26
0
 public static SnapshotPoint?GetCaretPosition(this IBraceCompletionSession session)
 {
     return(GetCaretPoint(session, session.SubjectBuffer));
 }
예제 #27
0
 // get the caret position within the given buffer
 private static SnapshotPoint?GetCaretPoint(this IBraceCompletionSession session, ITextBuffer buffer)
 {
     return(session.TextView.Caret.Position.Point.GetPoint(buffer, PositionAffinity.Predecessor));
 }
 public void Start(IBraceCompletionSession session)
 {
     // If user has just typed opening brace of a type, then (depending on user settings) add a semicolon after the close brace.
     if (session.OpeningBrace == BraceKind.CurlyBrackets.Open && _optionsService.AdvancedOptions.AddSemicolonForTypes && IsOpeningBraceOfType(session))
         session.SubjectBuffer.Insert(session.ClosingPoint.GetPosition(session.SubjectBuffer.CurrentSnapshot), ";");
 }
 public override bool AllowOverType(IBraceCompletionSession session, CancellationToken cancellationToken)
 {
     return CheckCurrentPosition(session, cancellationToken);
 }
예제 #30
0
 public static SnapshotPoint?GetCaretPosition(this IBraceCompletionSession session)
 {
     return(session.TextView.Caret.Position.Point.GetPoint(session.SubjectBuffer, PositionAffinity.Successor));
 }
예제 #31
0
 public void AfterStart(IBraceCompletionSession session, CancellationToken cancellationToken)
 {
 }
 public void Finish(IBraceCompletionSession session)
 {
     
 }
예제 #33
0
        public bool TryCreateSession(ITextView textView, SnapshotPoint openingPoint, char openingBrace, char closingBrace, out IBraceCompletionSession session)
        {
            _threadingContext.ThrowIfNotOnUIThread();
            var textSnapshot = openingPoint.Snapshot;
            var document     = textSnapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document != null)
            {
                var editorSessionFactory = document.GetLanguageService <IBraceCompletionServiceFactory>();
                if (editorSessionFactory != null)
                {
                    // Brace completion is (currently) not cancellable.
                    var cancellationToken = CancellationToken.None;

                    var editorSession = editorSessionFactory.TryGetServiceAsync(document, openingPoint, openingBrace, cancellationToken).WaitAndGetResult(cancellationToken);
                    if (editorSession != null)
                    {
                        var undoHistory = _undoManager.GetTextBufferUndoManager(textView.TextBuffer).TextBufferUndoHistory;
                        session = new BraceCompletionSession(
                            textView, openingPoint.Snapshot.TextBuffer, openingPoint, openingBrace, closingBrace,
                            undoHistory, _editorOperationsFactoryService,
                            editorSession, _globalOptions, _threadingContext);
                        return(true);
                    }
                }
            }

            session = null;
            return(false);
        }
예제 #34
0
 public override bool AllowOverType(IBraceCompletionSession session, CancellationToken cancellationToken)
 {
     return(CheckCurrentPosition(session, cancellationToken));
 }
 public bool CheckOpeningPoint(IBraceCompletionSession session, CancellationToken cancellationToken)
 {
     return true;
 }
        public override void AfterStart(IBraceCompletionSession session, CancellationToken cancellationToken)
        {
            FormatTrackingSpan(session, shouldHonorAutoFormattingOnCloseBraceOption: true);

            //session.TryMoveCaret(session.ClosingPoint - 1);
        }
        private void PutCaretOnLine(IBraceCompletionSession session, int lineNumber)
        {
            var lineOnSubjectBuffer = session.SubjectBuffer.CurrentSnapshot.GetLineFromLineNumber(lineNumber);

            var indentation = GetDesiredIndentation(session, lineOnSubjectBuffer);

            session.TextView.TryMoveCaretToAndEnsureVisible(new VirtualSnapshotPoint(lineOnSubjectBuffer, indentation));
        }
        public bool TryCreateSession(ITextView textView, SnapshotPoint openingPoint, char openingBrace, char closingBrace, out IBraceCompletionSession session)
        {
            this.AssertIsForeground();

            var textSnapshot = openingPoint.Snapshot;
            var document     = textSnapshot.GetOpenDocumentInCurrentContextWithChanges();

            if (document != null)
            {
                var editorSessionFactory = document.GetLanguageService <IEditorBraceCompletionSessionFactory>();
                if (editorSessionFactory != null)
                {
                    // Brace completion is (currently) not cancellable.
                    var cancellationToken = CancellationToken.None;

                    var editorSession = editorSessionFactory.TryCreateSession(document, openingPoint, openingBrace, cancellationToken);
                    if (editorSession != null)
                    {
                        var undoHistory = _undoManager.GetTextBufferUndoManager(textView.TextBuffer).TextBufferUndoHistory;
                        session = new BraceCompletionSession(
                            textView, openingPoint.Snapshot.TextBuffer, openingPoint, openingBrace, closingBrace,
                            undoHistory, _editorOperationsFactoryService,
                            editorSession);
                        return(true);
                    }
                }
            }

            session = null;
            return(false);
        }
        public override void AfterStart(IBraceCompletionSession session, CancellationToken cancellationToken)
        {
            FormatTrackingSpan(session, shouldHonorAutoFormattingOnCloseBraceOption: true);

            session.TextView.TryMoveCaretToAndEnsureVisible(session.ClosingPoint.GetPoint(session.SubjectBuffer.CurrentSnapshot).Subtract(1));
        }
 public virtual bool AllowOverType(IBraceCompletionSession session, CancellationToken cancellationToken)
 {
     return(CheckCurrentPosition(session, cancellationToken) && CheckClosingTokenKind(session, cancellationToken));
 }
예제 #41
0
 public override void Start(IBraceCompletionSession session)
 {
     base.LanguageInfo.TryFormat(session.GetSessionSpan());
 }
 public bool AllowOverType(IBraceCompletionSession session)
 {
     return true;
 }
예제 #43
0
        public override void AfterStart(IBraceCompletionSession session, CancellationToken cancellationToken)
        {
            FormatTrackingSpan(session, shouldHonorAutoFormattingOnCloseBraceOption: true);

            session.TextView.TryMoveCaretToAndEnsureVisible(session.ClosingPoint.GetPoint(session.SubjectBuffer.CurrentSnapshot).Subtract(1));
        }
        /// <summary>
        /// Attempt to create a session using the provider that best matches the buffer content type for
        /// the given opening brace. This is called only for appropriate buffers in the view's buffer graph.
        /// </summary>
        public bool TryCreateSession(ITextView textView, SnapshotPoint openingPoint, char openingBrace, out IBraceCompletionSession session)
        {
            ITextBuffer  buffer            = openingPoint.Snapshot.TextBuffer;
            IContentType bufferContentType = buffer.ContentType;

            List <IContentType> contentTypes;

            if (_contentTypeCache.TryGetValue(openingBrace, out contentTypes))
            {
                foreach (IContentType providerContentType in contentTypes)
                {
                    // find a matching content type
                    if (bufferContentType.IsOfType(providerContentType.TypeName))
                    {
                        // try all providers for that type
                        List <ProviderHelper> providersForBrace;
                        if (_providerCache[openingBrace].TryGetValue(providerContentType, out providersForBrace))
                        {
                            foreach (ProviderHelper provider in providersForBrace)
                            {
                                IBraceCompletionSession curSession = null;
                                if (provider.TryCreate(_factory, textView, openingPoint, openingBrace, out curSession))
                                {
                                    session = curSession;
                                    return(true);
                                }
                            }
                        }

                        // only try the best match
                        break;
                    }
                }
            }

            session = null;
            return(false);
        }
 public void AfterReturn(IBraceCompletionSession session, CancellationToken cancellationToken)
 {
     
 }
 public override bool AllowOverType(IBraceCompletionSession session, CancellationToken cancellationToken)
 {
     return(true);
 }
예제 #47
0
 public void Start(IBraceCompletionSession session)
 {
 }
        private void FormatTrackingSpan(IBraceCompletionSession session, bool shouldHonorAutoFormattingOnCloseBraceOption, IEnumerable<IFormattingRule> rules = null)
        {
            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;

            // Do not format within the braces if they're on the same line for array/collection/object initializer expressions.
            // This is a heuristic to prevent brace completion from breaking user expectation/muscle memory in common scenarios.
            // see bug Devdiv:823958
            if (startPoint.GetContainingLineNumber() == endPoint.GetContainingLineNumber())
            {
                // Brace completion is not cancellable
                var startToken = snapshot.FindToken(startPosition, CancellationToken.None);
                if (startToken.IsKind(SyntaxKind.OpenBraceToken) &&
                    (startToken.Parent.IsInitializerForArrayOrCollectionCreationExpression() ||
                     startToken.Parent is AnonymousObjectCreationExpressionSyntax))
                {
                    // format everything but the brace pair.
                    var endToken = snapshot.FindToken(endPosition, CancellationToken.None);
                    if (endToken.IsKind(SyntaxKind.CloseBraceToken))
                    {
                        endPosition = endPosition - (endToken.Span.Length + startToken.Span.Length);
                    }
                }
            }

            var document = snapshot.GetOpenDocumentInCurrentContextWithChanges();
            var style = document != null ? document.GetOptionsAsync(CancellationToken.None).WaitAndGetResult(CancellationToken.None).GetOption(SmartIndent)
                                         : SmartIndent.DefaultValue;

            if (style == 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), rules);
        }
예제 #49
0
 public bool AllowOverType(IBraceCompletionSession session)
 {
     return(true);
 }
        private int GetDesiredIndentation(IBraceCompletionSession session, ITextSnapshotLine lineOnSubjectBuffer)
        {
            // first try VS's smart indentation service
            var indentation = session.TextView.GetDesiredIndentation(_smartIndentationService, lineOnSubjectBuffer);
            if (indentation.HasValue)
            {
                return indentation.Value;
            }

            // do poor man's indentation
            var openingPoint = session.OpeningPoint.GetPoint(lineOnSubjectBuffer.Snapshot);
            var openingSpanLine = openingPoint.GetContainingLine();

            return openingPoint - openingSpanLine.Start;
        }
예제 #51
0
 public void Finish(IBraceCompletionSession session)
 {
 }
        private void PutCaretOnLine(IBraceCompletionSession session, SourceText text, TextLine line)
        {
            var indentation = GetDesiredIndentation(session, text);

            session.TryMoveCaret(line.Start + indentation);
        }
예제 #53
0
 public void OnReturn(IBraceCompletionSession session)
 {
 }
            // Create the session
            public bool TryCreate(BraceCompletionAggregatorFactory factory, ITextView textView, SnapshotPoint openingPoint, char openingBrace, out IBraceCompletionSession session)
            {
                char closingBrace = GetClosingBrace(Metadata, openingBrace);

                if (IsSession)
                {
                    bool created = false;
                    IBraceCompletionSession currentSession = null;

                    factory.GuardedOperations.CallExtensionPoint(() =>
                    {
                        created = _sessionPair.Value.TryCreateSession(textView, openingPoint, openingBrace, closingBrace, out currentSession);
                    });

                    if (created)
                    {
                        session = currentSession;
                        return(true);
                    }

                    session = null;
                    return(false);
                }
                else if (IsContext)
                {
                    // Get a language specific context and add it to a default session.
                    IBraceCompletionContext context = null;

                    // check AllowDefaultSession to avoid starting a new "" session next to a "
                    if (AllowDefaultSession(openingPoint, openingBrace, closingBrace))
                    {
                        bool created = false;

                        factory.GuardedOperations.CallExtensionPoint(() =>
                        {
                            created = _contextPair.Value.TryCreateContext(textView, openingPoint, openingBrace, closingBrace, out context);
                        });

                        if (created)
                        {
                            session = new BraceCompletionDefaultSession(textView, openingPoint.Snapshot.TextBuffer, openingPoint, openingBrace,
                                                                        closingBrace, factory.UndoManager, factory.EditorOperationsFactoryService, context);

                            return(true);
                        }
                    }

                    session = null;
                    return(false);
                }
                else if (IsDefault)
                {
                    // perform some basic checks on the buffer before going in
                    if (AllowDefaultSession(openingPoint, openingBrace, closingBrace))
                    {
                        session = new BraceCompletionDefaultSession(textView, openingPoint.Snapshot.TextBuffer, openingPoint, openingBrace,
                                                                    closingBrace, factory.UndoManager, factory.EditorOperationsFactoryService);

                        return(true);
                    }
                }

                session = null;
                return(false);
            }
예제 #55
0
 /// <summary>
 /// Called by the editor when the closing brace character has been typed.
 /// </summary>
 /// <remarks>
 /// The closing brace character will not be inserted into the buffer
 /// until after this returns. Does not occur if there is any non-whitespace
 /// between the caret and the closing brace. Language-specific decisions
 /// may be made here to take into account scenarios such as an escaped
 /// closing char.
 /// </remarks>
 /// <param name="session">Default brace completion session</param>
 /// <returns>Returns true if the context is a valid overtype scenario.</returns>
 public bool AllowOverType(IBraceCompletionSession session) => true;