예제 #1
0
        private bool FindMatchingPair(BraceKind brace, SnapshotPoint position, int direction, out SnapshotSpan leftSpan, out SnapshotSpan rightSpan)
        {
            leftSpan  = new SnapshotSpan(position, position);
            rightSpan = leftSpan;

            var buffer = PythonTextBufferInfo.ForBuffer(_site, position.Snapshot.TextBuffer);

            if (buffer == null)
            {
                return(false);
            }

            if (!(buffer.GetTokenAtPoint(position)?.Trigger ?? TokenTriggers.None).HasFlag(TokenTriggers.MatchBraces))
            {
                return(false);
            }

            var snapshot = position.Snapshot;
            int depth    = 0;

            foreach (var token in (direction > 0 ? buffer.GetTokensForwardFromPoint(position) : buffer.GetTokensInReverseFromPoint(position - 1)))
            {
                if (!token.Trigger.HasFlag(TokenTriggers.MatchBraces))
                {
                    continue;
                }

                var tokenSpan = token.ToSnapshotSpan(snapshot);
                var txt       = tokenSpan.GetText();
                var kind      = GetBraceKind(txt);
                if (kind == BraceKind.None)
                {
                    return(false);
                }

                if (kind == brace)
                {
                    if (txt.IsCloseGrouping())
                    {
                        depth -= direction;
                    }
                    else
                    {
                        depth += direction;
                    }
                }

                if (depth == 0)
                {
                    leftSpan  = tokenSpan;
                    rightSpan = new SnapshotSpan(snapshot, position - 1, 1);
                    return(true);
                }
            }

            return(false);
        }
예제 #2
0
파일: SmartIndent.cs 프로젝트: int19h/PTVS
 public int?GetDesiredIndentation(ITextSnapshotLine line)
 {
     if (_pyService.LangPrefs.IndentMode == vsIndentStyle.vsIndentStyleSmart)
     {
         return(AutoIndent.GetLineIndentation(PythonTextBufferInfo.ForBuffer(_pyService.Site, line.Snapshot.TextBuffer), line, _textView));
     }
     else
     {
         return(null);
     }
 }
예제 #3
0
        public bool TryCreateContext(ITextView textView, SnapshotPoint openingPoint, char openingBrace, char closingBrace, out IBraceCompletionContext context)
        {
            var bi = PythonTextBufferInfo.ForBuffer(Site, openingPoint.Snapshot.TextBuffer);

            if (IsValidBraceCompletionContext(bi, openingPoint, openingBrace))
            {
                context = new BraceCompletionContext();
                return(true);
            }
            else
            {
                context = null;
                return(false);
            }
        }
예제 #4
0
 public PythonTextBufferInfo GetBufferInfo(ITextBuffer textBuffer)
 {
     return(PythonTextBufferInfo.ForBuffer(this, textBuffer));
 }
예제 #5
0
        public bool TryTriggerExpansion(ITextView textView)
        {
            if (textView == null)
            {
                throw new ArgumentNullException(nameof(textView));
            }

            if (_vsExpansionMgr == null)
            {
                return(false);
            }

            if (!textView.Selection.IsEmpty || textView.Caret.Position.BufferPosition <= 0)
            {
                return(false);
            }

            var snapshot  = textView.TextBuffer.CurrentSnapshot;
            var caretSpan = new SnapshotSpan(snapshot, new Span(textView.Caret.Position.BufferPosition.Position - 1, 1));

            var bufferInfo = PythonTextBufferInfo.ForBuffer(_site, textView.TextBuffer);
            var tokens     = bufferInfo.GetTrackingTokens(caretSpan);

            if (!tokens.Any())
            {
                return(false);
            }

            var token     = tokens.First();
            var tokenSpan = token.ToSnapshotSpan(snapshot);

            if (tokenSpan.End.Position != caretSpan.End.Position)
            {
                // Match C# behavior and only trigger snippet
                // if caret is at the end of an identifier. Otherwise,
                // a TAB should be inserted even if the token matches
                // a snippet shortcut.
                return(false);
            }

            var text = tokenSpan.GetText();

            var textSpan = new TextSpan[1];

            textSpan[0].iStartLine  = tokenSpan.Start.GetContainingLine().LineNumber;
            textSpan[0].iStartIndex = tokenSpan.Start.Position - tokenSpan.Start.GetContainingLine().Start;
            textSpan[0].iEndLine    = tokenSpan.End.GetContainingLine().LineNumber;
            textSpan[0].iEndIndex   = tokenSpan.End.Position - tokenSpan.End.GetContainingLine().Start;

            var client = GetOrCreateExpansionClient(textView);
            int hr     = _vsExpansionMgr.GetExpansionByShortcut(
                client,
                CommonGuidList.guidPythonLanguageServiceGuid,
                text,
                _editorAdaptersFactoryService.GetViewAdapter(textView),
                textSpan,
                1,
                out string expansionPath,
                out string title
                );

            if (ErrorHandler.Succeeded(hr))
            {
                // hr may be S_FALSE if there are multiple expansions,
                // so we don't want to InsertNamedExpansion yet. VS will
                // pop up a selection dialog in this case.
                if (hr == VSConstants.S_OK)
                {
                    return(ErrorHandler.Succeeded(client.InsertNamedExpansion(title, expansionPath, textSpan[0])));
                }
                return(true);
            }

            return(false);
        }