예제 #1
0
		bool Intersects(ITrackingSpan span, SnapshotPoint point) {
			if (span == null)
				return false;
			if (point.Snapshot.TextBuffer != span.TextBuffer)
				return false;
			var span2 = span.GetSpan(span.TextBuffer.CurrentSnapshot);
			return span2.IntersectsWith(new SnapshotSpan(point, 0));
		}
 private static void Replace(ITrackingSpan contextSpan, ITextView textView, string atDirective, string fontFamily)
 {
     using (WebEssentialsPackage.UndoContext(("Embed font")))
     {
         textView.TextBuffer.Insert(0, atDirective + Environment.NewLine + Environment.NewLine);
         textView.TextBuffer.Insert(contextSpan.GetSpan(textView.TextBuffer.CurrentSnapshot).Start, fontFamily);
     }
 }
예제 #3
0
		public static bool IsSameTrackingSpan(ITrackingSpan a, ITrackingSpan b) {
			if (a == b)
				return true;
			if (a == null || b == null)
				return false;
			if (a.TextBuffer != b.TextBuffer)
				return false;
			var sa = a.GetSpan(a.TextBuffer.CurrentSnapshot);
			var sb = b.GetSpan(b.TextBuffer.CurrentSnapshot);
			return sa == sb;
		}
예제 #4
0
        public ReverseExpressionParser(ITextSnapshot snapshot, ITextBuffer buffer, ITrackingSpan span)
        {
            _snapshot = snapshot;
            _buffer = buffer;
            _span = span;

            var loc = span.GetSpan(snapshot);
            var line = _curLine = snapshot.GetLineFromPosition(loc.Start);

            var targetSpan = new Span(line.Start.Position, span.GetEndPoint(snapshot).Position - line.Start.Position);
            _tokens = Classifier.GetClassificationSpans(new SnapshotSpan(snapshot, targetSpan));
        }
        private IList<IRHistoryEntry> AddSinglelineEntries(ITrackingSpan entrySpan) {
            var snapshot = entrySpan.TextBuffer.CurrentSnapshot;
            var snapshotEntrySpan = entrySpan.GetSpan(snapshot);
            var spans = snapshot.Lines
                .Where(l => snapshotEntrySpan.Contains(l.Extent))
                .Select(l => snapshot.CreateTrackingSpan(l.Start, l.Length, SpanTrackingMode.EdgeExclusive));

            var entries = new List<IRHistoryEntry>();
            foreach (var span in spans) {
                entries.Add(AddEntry(entrySpan, span));
            }
            return entries;
        }
        private void AddVariableCompletions(ITextSnapshot snapshot, ITrackingSpan tracking, List<Completion> completions)
        {
            var envVars = Environment.GetEnvironmentVariables();

            foreach (DictionaryEntry variable in envVars)
            {
                string displayText = variable.Key.ToString();
                string description = Environment.GetEnvironmentVariable(displayText);
                completions.Add(new Completion(displayText, displayText, description, _environmentGlyph, "automationText"));
            }

            var doc = new SnapshotSpan(snapshot, 0, snapshot.Length);
            var idents = _classifier.GetClassificationSpans(doc).Where(g => g.ClassificationType.IsOfType(PredefinedClassificationTypeNames.SymbolDefinition));

            foreach (var ident in idents.Where(i => !i.Span.IntersectsWith(tracking.GetSpan(snapshot))))
            {
                string text = ident.Span.GetText().Trim();
                string displayText = text.Trim('%');

                if (!completions.Any(c => c.InsertionText == displayText))
                    completions.Add(new Completion(displayText, displayText, null, _keywordGlyph, "automationText"));
            }
        }
예제 #7
0
        public static bool IsContentEqualsOrdinal(this ITextBuffer textBuffer, ITrackingSpan span1, ITrackingSpan span2) {
            var snapshot = textBuffer.CurrentSnapshot;
            var snapshotSpan1 = span1.GetSpan(snapshot);
            var snapshotSpan2 = span2.GetSpan(snapshot);

            if (snapshotSpan1 == snapshotSpan2) {
                return true;
            }

            if (snapshotSpan1.Length != snapshotSpan2.Length) {
                return false;
            }

            var start1 = snapshotSpan1.Start;
            var start2 = snapshotSpan2.Start;
            for (int i = 0; i < snapshotSpan1.Length; i++) {
                if (snapshot[start1 + i] != snapshot[start2 + i]) {
                    return false;
                }
            }

            return true;
        }
 public void Invoke(CancellationToken cancellationToken)
 {
     _mSpan.TextBuffer.Replace(_mSpan.GetSpan(_mSnapshot), _mUpper);
 }
        private void CleanUpEndLocation(ITrackingSpan endTrackingSpan)
        {
            if (endTrackingSpan != null)
            {
                // Find the empty comment and remove it...
                var endSnapshotSpan = endTrackingSpan.GetSpan(SubjectBuffer.CurrentSnapshot);
                SubjectBuffer.Delete(endSnapshotSpan.Span);

                // Remove the whitespace before the comment if necessary. If whitespace is removed,
                // then remember the indentation depth so we can appropriately position the caret
                // in virtual space when the session is ended.
                var line = SubjectBuffer.CurrentSnapshot.GetLineFromPosition(endSnapshotSpan.Start.Position);
                var lineText = line.GetText();

                if (lineText.Trim() == string.Empty)
                {
                    indentCaretOnCommit = true;

                    var document = this.SubjectBuffer.CurrentSnapshot.GetOpenDocumentInCurrentContextWithChanges();
                    if (document != null)
                    {
                        var optionService = document.Project.Solution.Workspace.Services.GetService<IOptionService>();
                        var tabSize = optionService.GetOption(FormattingOptions.TabSize, document.Project.Language);
                        indentDepth = lineText.GetColumnFromLineOffset(lineText.Length, tabSize);
                    }
                    else
                    {
                        // If we don't have a document, then just guess the typical default TabSize value.
                        indentDepth = lineText.GetColumnFromLineOffset(lineText.Length, tabSize: 4);
                    }

                    SubjectBuffer.Delete(new Span(line.Start.Position, line.Length));
                    endSnapshotSpan = SubjectBuffer.CurrentSnapshot.GetSpan(new Span(line.Start.Position, 0));
                }
            }
        }
예제 #10
0
        internal static ITrackingSpan GetEncapsulatingSpan(ITextView textView, ITrackingSpan span1, ITrackingSpan span2)
        {
            // If either of the spans is null, return the other one.  If they're both null, we'll end up returning null
            // (as it should be).
            if (span1 == null)
            {
                var spans = textView.BufferGraph.MapUpToBuffer
                            (
                    span2.GetSpan(span2.TextBuffer.CurrentSnapshot),
                    span2.TrackingMode,
                    textView.TextBuffer
                            );
                Debug.Assert(spans.Count == 1);
                return(spans[0].Snapshot.CreateTrackingSpan(spans[0], span2.TrackingMode));
            }
            if (span2 == null)
            {
                var spans = textView.BufferGraph.MapUpToBuffer
                            (
                    span1.GetSpan(span2.TextBuffer.CurrentSnapshot),
                    span1.TrackingMode,
                    textView.TextBuffer
                            );
                Debug.Assert(spans.Count == 1);
                return(spans[0].Snapshot.CreateTrackingSpan(spans[0], span1.TrackingMode));
            }

            List <SnapshotSpan> surfaceSpans = new List <SnapshotSpan>();

            surfaceSpans.AddRange
            (
                textView.BufferGraph.MapUpToBuffer
                (
                    span1.GetSpan(span1.TextBuffer.CurrentSnapshot),
                    span1.TrackingMode,
                    textView.TextBuffer
                )
            );
            surfaceSpans.AddRange
            (
                textView.BufferGraph.MapUpToBuffer
                (
                    span2.GetSpan(span2.TextBuffer.CurrentSnapshot),
                    span2.TrackingMode,
                    textView.TextBuffer
                )
            );

            ITrackingSpan encapsulatingSpan = null;

            foreach (var span in surfaceSpans)
            {
                encapsulatingSpan = Helpers.GetEncapsulatingSpan
                                    (
                    encapsulatingSpan,
                    span.Snapshot.CreateTrackingSpan(span, span1.TrackingMode)
                                    );
            }

            return(encapsulatingSpan);
        }
        internal static MissingImportAnalysis GetMissingImports(ITextSnapshot snapshot, ITrackingSpan span) {
            ReverseExpressionParser parser = new ReverseExpressionParser(snapshot, snapshot.TextBuffer, span);
            var loc = span.GetSpan(snapshot.Version);
            int dummy;
            SnapshotPoint? dummyPoint;
            string lastKeywordArg;
            bool isParameterName;
            var exprRange = parser.GetExpressionRange(0, out dummy, out dummyPoint, out lastKeywordArg, out isParameterName);
            if (exprRange == null || isParameterName) {
                return MissingImportAnalysis.Empty;
            }

            var analysis = ((IPythonProjectEntry)snapshot.TextBuffer.GetProjectEntry()).Analysis;
            if (analysis == null) {
                return MissingImportAnalysis.Empty;
            }

            var text = exprRange.Value.GetText();
            var analyzer = analysis.ProjectState;
            var index = span.GetStartPoint(snapshot).Position;

            var expr = Statement.GetExpression(
                analysis.GetAstFromTextByIndex(
                    text,
                    TranslateIndex(
                        index,
                        snapshot,
                        analysis
                    )
                ).Body
            );

            if (expr != null && expr is NameExpression) {
                var nameExpr = (NameExpression)expr;

                if (!IsImplicitlyDefinedName(nameExpr)) {
                    var applicableSpan = parser.Snapshot.CreateTrackingSpan(
                        exprRange.Value.Span,
                        SpanTrackingMode.EdgeExclusive
                    );

                    lock (snapshot.TextBuffer.GetAnalyzer()) {
                        index = TranslateIndex(
                            index,
                            snapshot,
                            analysis
                        );
                        var variables = analysis.GetVariablesByIndex(text, index).Where(IsDefinition).Count();

                        var values = analysis.GetValuesByIndex(text, index).ToArray();

                        // if we have type information or an assignment to the variable we won't offer 
                        // an import smart tag.
                        if (values.Length == 0 && variables == 0) {
                            string name = nameExpr.Name;
                            var imports = analysis.ProjectState.FindNameInAllModules(name);

                            return new MissingImportAnalysis(imports, applicableSpan);
                        }
                    }
                }
            }

            // if we have type information don't offer to add imports
            return MissingImportAnalysis.Empty;
        }
        private static CompletionAnalysis GetNormalCompletionContext(ITextSnapshot snapshot, ITrackingSpan applicableSpan, ITrackingPoint point) {
            var span = applicableSpan.GetSpan(snapshot);

            if (IsSpaceCompletion(snapshot, point) && !IntellisenseController.ForceCompletions) {
                return CompletionAnalysis.EmptyCompletionContext;
            }

            GetMemberOptions options = GetMemberOptions.IncludeExpressionKeywords | GetMemberOptions.IncludeStatementKeywords;
            var parser = new ReverseExpressionParser(snapshot, snapshot.TextBuffer, applicableSpan);
            if (parser.IsInGrouping()) {
                options &= ~GetMemberOptions.IncludeStatementKeywords;
            }

            return new NormalCompletionAnalysis(
                snapshot.TextBuffer.GetAnalyzer(),
                snapshot,
                applicableSpan,
                snapshot.TextBuffer,
                options
            );
        }
예제 #13
0
 private void OnClassificationChanged(ITrackingSpan span)
 {
     if ((_caret == 0 || _caret != _lastCaret) && ClassificationChanged != null)
     {
         ClassificationChanged(this, new ClassificationChangedEventArgs(span.GetSpan(span.TextBuffer.CurrentSnapshot)));
         _span = null;
     }
 }
예제 #14
0
        private static CompletionAnalysis TrySpecialCompletions(ITextSnapshot snapshot, ITrackingSpan span, ITrackingPoint point) {
            var snapSpan = span.GetSpan(snapshot);
            var buffer = snapshot.TextBuffer;
            var classifier = buffer.GetNodejsClassifier();
            if (classifier == null) {
                return null;
            }
            var start = snapSpan.Start;

            var parser = new ReverseExpressionParser(snapshot, buffer, span);
            if (parser.IsInGrouping()) {
                var range = parser.GetExpressionRange(nesting: 1);
                if (range != null) {
                    start = range.Value.Start;
                }
            }

            var tokens = classifier.GetClassificationSpans(new SnapshotSpan(start.GetContainingLine().Start, snapSpan.Start));
            if (tokens.Count > 0) {
                // Check for context-sensitive intellisense
                var lastClass = tokens[tokens.Count - 1];

                if (lastClass.ClassificationType == classifier.Provider.Comment) {
                    // No completions in comments
                    return CompletionAnalysis.EmptyCompletionContext;
                } else if (lastClass.ClassificationType == classifier.Provider.StringLiteral) {
                    // String completion
                    return CompletionAnalysis.EmptyCompletionContext;
                }
                return null;
            }

            return null;
        }
예제 #15
0
        public static Span GetCurrentSpan(this ITrackingSpan trackingSpan)
        {
            ITextSnapshot snapshot = trackingSpan.TextBuffer.CurrentSnapshot;

            return(trackingSpan.GetSpan(snapshot).Span);
        }
        void OnVisualBufferChanged(TextContentChangedEventArgs e, ITextSnapshot afterSnapshot)
        {
            if (textSnapshot != null && e != null)
            {
                foreach (ITextChange textChange in e.Changes)
                {
                    Span textChangeCurrentSpan;
                    if (e.Before == textSnapshot)
                    {
                        textChangeCurrentSpan = textChange.OldSpan;
                    }
                    else if (e.After == textSnapshot)
                    {
                        textChangeCurrentSpan = textChange.NewSpan;
                    }
                    else
                    {
                        ITrackingSpan textChangeOldSpan = e.Before.CreateTrackingSpan(textChange.OldSpan, SpanTrackingMode.EdgeInclusive);
                        textChangeCurrentSpan = textChangeOldSpan.GetSpan(textSnapshot);
                    }

                    var startLine = textSnapshot.GetLineFromPosition(textChangeCurrentSpan.Start);
                    var endLine   = startLine;
                    if (startLine.EndIncludingLineBreak.Position < textChangeCurrentSpan.End)
                    {
                        endLine = textSnapshot.GetLineFromPosition(textChangeCurrentSpan.End);
                    }

                    for (int i = startLine.LineNumber; i <= endLine.LineNumber; i++)
                    {
                        modifiedLinesCache.Add(i);
                    }
                }
            }

            // Recreate MdTextViewLine for the current snapshot for all lines except those
            // modified as those will get recreated during render
            foreach (MdTextViewLine line in this)
            {
                int lineNumber = line.LineNumber;
                if (!modifiedLinesCache.Contains(lineNumber - 1))
                {
                    reusedLinesCache.Add(line);
                }
            }

            this.Clear();

            var newSnapshot = afterSnapshot;

            foreach (MdTextViewLine line in reusedLinesCache)
            {
                var snapshotLine    = textSnapshot.GetLineFromLineNumber(line.LineNumber - 1);
                var lineStart       = textSnapshot.CreateTrackingPoint(snapshotLine.Start, PointTrackingMode.Negative);
                var newLineStart    = lineStart.GetPosition(newSnapshot);
                var newSnapshotLine = newSnapshot.GetLineFromPosition(newLineStart);
                int lineNumber      = newSnapshotLine.LineNumber + 1;
                var documentLine    = textEditor.Document.GetLine(lineNumber);

                var newLine = new MdTextViewLine(this, textEditor, documentLine, lineNumber, textEditor.TextViewMargin.GetLayout(documentLine));
                Add(newLine);
            }

            modifiedLinesCache.Clear();
            reusedLinesCache.Clear();

            textSnapshot = newSnapshot;

            // we need this to synchronize MultiSelectionBroker to the new snapshot
            this.textEditor.TextArea.RaiseLayoutChanged();
        }
예제 #17
0
 internal Span GetSpan()
 {
     return(_span.GetSpan(_buffer.CurrentSnapshot).Span);
 }
예제 #18
0
        /// <summary>
        /// Gets the range of the expression to the left of our starting span.
        /// </summary>
        /// <param name="nesting">1 if we have an opening parenthesis for sig completion</param>
        /// <param name="paramIndex">The current parameter index.</param>
        /// <returns></returns>
        public SnapshotSpan?GetExpressionRange(int nesting, out int paramIndex, out SnapshotPoint?sigStart, out string lastKeywordArg, out bool isParameterName, bool forCompletion = true, bool forSignatureHelp = false)
        {
            SnapshotSpan?start = null;

            paramIndex = 0;
            sigStart   = null;
            bool nestingChanged = false, lastTokenWasCommaOrOperator = true, lastTokenWasKeywordArgAssignment = false;
            int  otherNesting = 0;
            bool isSigHelp    = nesting != 0;

            isParameterName = false;
            lastKeywordArg  = null;

            ClassificationSpan lastToken = null;
            // Walks backwards over all the lines
            var enumerator = ReverseClassificationSpanEnumerator(_classifier, _span.GetSpan(_snapshot).End);

            if (enumerator.MoveNext())
            {
                if (enumerator.Current != null && enumerator.Current.ClassificationType == this._classifier.Provider.StringLiteral)
                {
                    return(enumerator.Current.Span);
                }

                lastToken = enumerator.Current;
                while (ShouldSkipAsLastToken(lastToken, forCompletion) && enumerator.MoveNext())
                {
                    // skip trailing new line if the user is hovering at the end of the line
                    if (lastToken == null && (nesting + otherNesting == 0))
                    {
                        // new line out of a grouping...
                        return(_span.GetSpan(_snapshot));
                    }
                    lastToken = enumerator.Current;
                }

                bool lastNewLine = false;
                // Walk backwards over the tokens in the current line
                do
                {
                    var token = enumerator.Current;

                    if (token == null)
                    {
                        // new line
                        lastNewLine = true;
                        continue;
                    }
                    else if (lastNewLine && !lastTokenWasCommaOrOperator && otherNesting == 0)
                    {
                        break;
                    }

                    lastNewLine = false;

                    var text = token.Span.GetText();
                    if (text == "(")
                    {
                        if (nesting != 0)
                        {
                            nesting--;
                            nestingChanged = true;
                            if (nesting == 0)
                            {
                                if (sigStart == null)
                                {
                                    sigStart = token.Span.Start;
                                }
                            }
                        }
                        else
                        {
                            if (start == null && !forCompletion)
                            {
                                // hovering directly over an open paren, don't provide a tooltip
                                return(null);
                            }

                            // figure out if we're a parameter definition
                            isParameterName = IsParameterNameOpenParen(enumerator);
                            break;
                        }
                        lastTokenWasCommaOrOperator      = true;
                        lastTokenWasKeywordArgAssignment = false;
                    }
                    else if (token.IsOpenGrouping())
                    {
                        if (otherNesting != 0)
                        {
                            otherNesting--;
                        }
                        else
                        {
                            if (nesting == 0)
                            {
                                if (start == null)
                                {
                                    return(null);
                                }
                                break;
                            }
                            paramIndex = 0;
                        }
                        nestingChanged = true;
                        lastTokenWasCommaOrOperator      = true;
                        lastTokenWasKeywordArgAssignment = false;
                    }
                    else if (text == ")")
                    {
                        nesting++;
                        nestingChanged = true;
                        lastTokenWasCommaOrOperator      = true;
                        lastTokenWasKeywordArgAssignment = false;
                    }
                    else if (token.IsCloseGrouping())
                    {
                        otherNesting++;
                        nestingChanged = true;
                        lastTokenWasCommaOrOperator      = true;
                        lastTokenWasKeywordArgAssignment = false;
                    }
                    else if ((token.ClassificationType == Classifier.Provider.Keyword &&
                              text != "this" && text != "get" && text != "set" && text != "delete") ||
                             token.ClassificationType == Classifier.Provider.Operator)
                    {
                        if (forCompletion && text == "new")
                        {
                            if (!forSignatureHelp)
                            {
                                start = token.Span;
                            }
                            break;
                        }

                        lastTokenWasKeywordArgAssignment = false;

                        if (nesting == 0 && otherNesting == 0)
                        {
                            if (start == null)
                            {
                                // http://pytools.codeplex.com/workitem/560
                                // yield_value = 42
                                // function *f() {
                                //     yield<ctrl-space>
                                //     yield <ctrl-space>
                                // }
                                //
                                // If we're next to the keyword, just return the keyword.
                                // If we're after the keyword, return the span of the text proceeding
                                //  the keyword so we can complete after it.
                                //
                                // Also repros with "return <ctrl-space>" or "print <ctrl-space>" both
                                // of which we weren't reporting completions for before
                                if (forCompletion)
                                {
                                    if (token.Span.IntersectsWith(_span.GetSpan(_snapshot)))
                                    {
                                        return(token.Span);
                                    }
                                    else
                                    {
                                        return(_span.GetSpan(_snapshot));
                                    }
                                }

                                // hovering directly over a keyword, don't provide a tooltip
                                return(null);
                            }
                            else if ((nestingChanged || forCompletion) && token.ClassificationType == Classifier.Provider.Keyword && text == "function")
                            {
                                return(null);
                            }
                            break;
                        }
                        else if ((token.ClassificationType == Classifier.Provider.Keyword &&
                                  _stmtKeywords.Contains(text)) ||
                                 (token.ClassificationType == Classifier.Provider.Operator && IsAssignmentOperator(text)))
                        {
                            if (start == null || (nestingChanged && nesting != 0 || otherNesting != 0))
                            {
                                return(null);
                            }
                            else
                            {
                                break;
                            }
                        }
                        lastTokenWasCommaOrOperator = true;
                    }
                    else if (token.ClassificationType == Classifier.Provider.DotClassification)
                    {
                        lastTokenWasCommaOrOperator      = true;
                        lastTokenWasKeywordArgAssignment = false;
                    }
                    else if (token.ClassificationType == Classifier.Provider.CommaClassification)
                    {
                        lastTokenWasCommaOrOperator      = true;
                        lastTokenWasKeywordArgAssignment = false;
                        if (nesting == 0 && otherNesting == 0)
                        {
                            if (start == null && !forCompletion)
                            {
                                return(null);
                            }
                            isParameterName = IsParameterNameComma(enumerator);
                            break;
                        }
                        else if (nesting == 1 && otherNesting == 0 && sigStart == null)
                        {
                            paramIndex++;
                        }
                    }
                    else if (token.ClassificationType == Classifier.Provider.Comment)
                    {
                        // Do not update start - if we bail out on the next token we see, we don't want to
                        // count the comment as part of the expression, either.
                        continue;
                    }
                    else if (!lastTokenWasCommaOrOperator)
                    {
                        break;
                    }
                    else
                    {
                        if (lastTokenWasKeywordArgAssignment &&
                            token.ClassificationType.IsOfType(PredefinedClassificationTypeNames.Identifier) &&
                            lastKeywordArg == null)
                        {
                            if (paramIndex == 0)
                            {
                                lastKeywordArg = text;
                            }
                            else
                            {
                                lastKeywordArg = String.Empty;
                            }
                        }
                        lastTokenWasCommaOrOperator = false;
                    }

                    start = token.Span;
                } while (enumerator.MoveNext());
            }

            if (start.HasValue && lastToken != null && (lastToken.Span.End.Position - start.Value.Start.Position) >= 0)
            {
                return(new SnapshotSpan(
                           Snapshot,
                           new Span(
                               start.Value.Start.Position,
                               lastToken.Span.End.Position - start.Value.Start.Position
                               )
                           ));
            }

            return(null);
        }
예제 #19
0
    /// <summary>
    /// Shoe all adornments within the given extent.
    /// </summary>
    public void ShowVisuals(ITrackingSpan extent) {
      Contract.Requires(extent != null);

      var extentSpan = extent.GetSpan(_textView.TextBuffer.CurrentSnapshot.Version);
      foreach (var entry in Adornments) {
        IAdornment adornment = entry.Value;
        var adornmentSpan = adornment.Span.GetSpan(_textView.TextBuffer.CurrentSnapshot);
        if (extentSpan.IntersectsWith(adornmentSpan)) {
          adornment.CollapsedRegionDepth--;
          QueueRefreshLineTransformer();
        }
      }
    }
예제 #20
0
        /// <summary>
        /// Gets the range of the expression to the left of our starting span.
        /// </summary>
        /// <param name="nesting">1 if we have an opening parenthesis for sig completion</param>
        /// <param name="paramIndex">The current parameter index.</param>
        /// <returns></returns>
        public SnapshotSpan?GetExpressionRange(int nesting, out int paramIndex, out SnapshotPoint?sigStart)
        {
            SnapshotSpan?start   = null;
            var          endText = String.Empty;

            paramIndex = 0;
            sigStart   = null;
            bool nestingChanged = false;

            ClassificationSpan lastToken = null;

            // Walks backwards over all the lines
            if (Tokens.Count > 0)
            {
                lastToken = Tokens[Tokens.Count - 1];
                while (true)
                {
                    // Walk backwards over the tokens in the current line
                    for (int t = Tokens.Count - 1; t >= 0; t--)
                    {
                        var token = Tokens[t];
                        var text  = token.Span.GetText();

                        if (token.ClassificationType == Classifier.Provider.Keyword ||
                            (token.ClassificationType == Classifier.Provider.Operator &&
                             text != "[" && text != "]" && text != "}" && text != "{"))
                        {
                            if (nesting == 0)
                            {
                                if (start == null)
                                {
                                    // hovering directly over a keyword, don't provide a tooltip
                                    return(null);
                                }
                                else if (nestingChanged && token.ClassificationType == Classifier.Provider.Keyword && text == "def")
                                {
                                    return(null);
                                }
                                break;
                            }
                        }
                        else if (token.ClassificationType == Classifier.Provider.OpenGroupingClassification || text == "[" || text == "{")
                        {
                            if (nesting != 0)
                            {
                                nesting--;
                                nestingChanged = true;
                                if (nesting == 0 && sigStart == null)
                                {
                                    sigStart = token.Span.Start;
                                }
                            }
                            else
                            {
                                break;
                            }
                        }
                        else if (token.ClassificationType == Classifier.Provider.CloseGroupingClassification ||
                                 text == "]" || text == "}")
                        {
                            nesting++;
                            nestingChanged = true;
                        }
                        else if (token.ClassificationType == Classifier.Provider.CommaClassification)
                        {
                            if (nesting == 0)
                            {
                                if (start == null)
                                {
                                    return(null);
                                }
                                break;
                            }
                            else if (nesting == 1 && sigStart == null)
                            {
                                paramIndex++;
                            }
                        }

                        start = token.Span;
                    }

                    if (nesting == 0 || CurrentLine.LineNumber == 0)
                    {
                        break;
                    }

                    // We're in a nested paren context, continue to the next line
                    // to capture the entire expression
                    endText     = CurrentLine.GetText() + endText;
                    CurrentLine = Snapshot.GetLineFromLineNumber(CurrentLine.LineNumber - 1);

                    var classSpan = new SnapshotSpan(Snapshot, CurrentLine.Start, CurrentLine.Length);
                    Tokens = Classifier.GetClassificationSpans(classSpan);
                }
            }

            if (start.HasValue)
            {
                return(new SnapshotSpan(
                           Snapshot,
                           new Span(
                               start.Value.Start.Position,
                               //_span.GetEndPoint(_snapshot).Position - start.Value.Start.Position
                               lastToken.Span.End.Position - start.Value.Start.Position
                               )
                           ));
            }

            return(_span.GetSpan(_snapshot));
        }
예제 #21
0
 public override void Invoke()
 {
     _span.TextBuffer.Replace(_span.GetSpan(_span.TextBuffer.CurrentSnapshot), GetColorString(_format, _colorModel));
 }
예제 #22
0
		/// <summary>
		/// Adds the new text to the text buffer
		/// </summary>
		/// <param name="replaceSpan">Span to replace with new content</param>
		public virtual void Commit(ITrackingSpan replaceSpan) {
			var buffer = replaceSpan.TextBuffer;
			var span = replaceSpan.GetSpan(buffer.CurrentSnapshot);
			buffer.Replace(span.Span, InsertionText);
		}
예제 #23
0
        private void ExecuteCommandWorker(
            PasteCommandArgs args,
            CommandExecutionContext executionContext,
            ITrackingSpan trackingSpan)
        {
            if (!args.SubjectBuffer.CanApplyChangeDocumentToWorkspace())
            {
                return;
            }

            // Don't perform work if we're inside the interactive window
            if (args.TextView.IsNotSurfaceBufferOfTextView(args.SubjectBuffer))
            {
                return;
            }

            // Applying the post-paste snapshot to the tracking span gives us the span of pasted text.
            var snapshotSpan = trackingSpan.GetSpan(args.SubjectBuffer.CurrentSnapshot);
            var textSpan     = snapshotSpan.Span.ToTextSpan();

            var sourceTextContainer = args.SubjectBuffer.AsTextContainer();

            if (!Workspace.TryGetWorkspace(sourceTextContainer, out var workspace))
            {
                return;
            }

            var document = sourceTextContainer.GetOpenDocumentInCurrentContext();

            if (document is null)
            {
                return;
            }

            using var _ = executionContext.OperationContext.AddScope(allowCancellation: true, DialogText);
            var cancellationToken = executionContext.OperationContext.UserCancellationToken;

            // We're going to log the same thing on success or failure since this blocks the UI thread. This measurement is
            // intended to tell us how long we're blocking the user from typing with this action.
            using var blockLogger = Logger.LogBlock(FunctionId.CommandHandler_Paste_ImportsOnPaste, KeyValueLogMessage.Create(LogType.UserAction), cancellationToken);

            var addMissingImportsService = document.GetRequiredLanguageService <IAddMissingImportsFeatureService>();

#pragma warning disable VSTHRD102 // Implement internal logic asynchronously
            var updatedDocument = _threadingContext.JoinableTaskFactory.Run(async() =>
            {
                var placement = await AddImportPlacementOptions.FromDocumentAsync(document, cancellationToken).ConfigureAwait(false);

                var options = new AddMissingImportsOptions(
                    HideAdvancedMembers: _globalOptions.GetOption(CompletionOptionsStorage.HideAdvancedMembers, document.Project.Language),
                    placement);

                return(await addMissingImportsService.AddMissingImportsAsync(document, textSpan, options, cancellationToken).ConfigureAwait(false));
            });
#pragma warning restore VSTHRD102 // Implement internal logic asynchronously
            if (updatedDocument is null)
            {
                return;
            }

            workspace.TryApplyChanges(updatedDocument.Project.Solution);
        }
 private static void Replace(ITrackingSpan contextSpan, ITextView textView, string atDirective, string fontFamily)
 {
     EditorExtensionsPackage.DTE.UndoContext.Open("Embed font");
     textView.TextBuffer.Insert(0, atDirective + Environment.NewLine + Environment.NewLine);
     textView.TextBuffer.Insert(contextSpan.GetSpan(textView.TextBuffer.CurrentSnapshot).Start, fontFamily);
     EditorExtensionsPackage.DTE.UndoContext.Close();
 }
 public void Invoke()
 {
     trackingSpan.TextBuffer.Replace(trackingSpan.GetSpan(snapShot), m_upper);
 }
        private static CompletionAnalysis TrySpecialCompletions(ITextSnapshot snapshot, ITrackingSpan span, ITrackingPoint point) {
            var snapSpan = span.GetSpan(snapshot);
            var buffer = snapshot.TextBuffer;
            var classifier = buffer.GetNodejsClassifier();
            if (classifier == null) {
                return null;
            }
            var start = snapSpan.Start;

            var parser = new ReverseExpressionParser(snapshot, buffer, span);
            if (parser.IsInGrouping()) {
                var range = parser.GetExpressionRange(nesting: 1);
                if (range != null) {
                    start = range.Value.Start;
                }
            }

            // Get the classifiers from beginning of the line to the beginning of snapSpan.
            // The contents of snapSpan differ depending on what is determined in
            // CompletionSource.GetApplicableSpan.
            //
            // In the case of:
            //      var myIdentifier<cursor>
            // the applicable span will be "myIdentifier", so GetClassificationSpans will operate on "var "
            // 
            // In the case of comments and string literals, the applicable span will be empty,
            // so snapSpan.Start will occur at the current cursor position. 
            var tokens = classifier.GetClassificationSpans(new SnapshotSpan(start.GetContainingLine().Start, snapSpan.Start));
            if (tokens.Count > 0) {
                // Check for context-sensitive intellisense
                var lastClass = tokens[tokens.Count - 1];

                if (lastClass.ClassificationType == classifier.Provider.Comment ||
                    lastClass.ClassificationType == classifier.Provider.StringLiteral ||
                    (lastClass.ClassificationType == classifier.Provider.Keyword &&
                    _emptyCompletionContextKeywords.Contains(lastClass.Span.GetText()))) {
                    // No completions in comments, strings, or directly after certain keywords.
                    return CompletionAnalysis.EmptyCompletionContext;
                }
                return null;
            }

            return null;
        }
예제 #27
0
 internal Span GetSpan()
 => _span.GetSpan(_buffer.CurrentSnapshot).Span;
        public static CompletionAnalysis GetRequireCompletions(ITextSnapshot snapshot, ITrackingSpan applicableSpan, ITrackingPoint point, bool quote) {
            var span = applicableSpan.GetSpan(snapshot);

            if (IsSpaceCompletion(snapshot, point) && !IntellisenseController.ForceCompletions) {
                return CompletionAnalysis.EmptyCompletionContext;
            }

            return new RequireCompletionAnalysis(
                snapshot.TextBuffer.GetAnalyzer(),
                snapshot,
                applicableSpan,
                snapshot.TextBuffer,
                quote
            );
        }
예제 #29
0
 public void Invoke(CancellationToken cancellationToken)
 {
     m_span.TextBuffer.Replace(m_span.GetSpan(m_snapshot), m_lower);
 }
예제 #30
0
        public bool Find()
        {
            if (SearchTerm == null)
            {
                throw new InvalidOperationException();
            }
            if (SearchTerm.Length == 0)
            {
                throw new InvalidOperationException();
            }

            SnapshotPoint startingPosition;

            if (CurrentResult != null)
            {
                if ((SearchOptions & FindOptions.SearchReverse) != 0)
                {
                    if (CurrentResult.Value.End.Position > 0)
                    {
                        startingPosition = CurrentResult.Value.End - 1;
                    }
                    else if ((SearchOptions & FindOptions.Wrap) != 0)
                    {
                        startingPosition = new SnapshotPoint(CurrentResult.Value.Snapshot, CurrentResult.Value.Snapshot.Length);
                    }
                    else
                    {
                        return(FindFailed());
                    }
                }
                else
                {
                    if (CurrentResult.Value.Start.Position != CurrentResult.Value.Snapshot.Length)
                    {
                        startingPosition = CurrentResult.Value.Start + 1;
                    }
                    else if ((SearchOptions & FindOptions.Wrap) != 0)
                    {
                        startingPosition = new SnapshotPoint(CurrentResult.Value.Snapshot, 0);
                    }
                    else
                    {
                        return(FindFailed());
                    }
                }
            }
            else if (StartPoint != null)
            {
                startingPosition = StartPoint.Value;
            }
            else
            {
                startingPosition = new SnapshotPoint(buffer.CurrentSnapshot, 0);
            }
            startingPosition = startingPosition.TranslateTo(buffer.CurrentSnapshot, (SearchOptions & FindOptions.SearchReverse) != 0 ? PointTrackingMode.Negative : PointTrackingMode.Positive);

            var spanToUse = searchSpan?.GetSpan(buffer.CurrentSnapshot) ?? new SnapshotSpan(buffer.CurrentSnapshot, 0, buffer.CurrentSnapshot.Length);

            if (!IsValidStartingPosition(spanToUse, startingPosition))
            {
                return(FindFailed());
            }
            foreach (var result in textSearchService2.FindAll(spanToUse, startingPosition, SearchTerm, SearchOptions))
            {
                currentResult = result;
                return(true);
            }

            return(FindFailed());
        }
        private void CleanUpEndLocation(ITrackingSpan endTrackingSpan)
        {
            if (endTrackingSpan != null)
            {
                // Find the empty comment and remove it...
                var endSnapshotSpan = endTrackingSpan.GetSpan(SubjectBuffer.CurrentSnapshot);
                SubjectBuffer.Delete(endSnapshotSpan.Span);

                // Remove the whitespace before the comment if necessary. If whitespace is removed,
                // then remember the indentation depth so we can appropriately position the caret
                // in virtual space when the session is ended.
                var line = SubjectBuffer.CurrentSnapshot.GetLineFromPosition(endSnapshotSpan.Start.Position);
                var lineText = line.GetText();

                if (lineText.Trim() == string.Empty)
                {
                    indentCaretOnCommit = true;
                    indentDepth = lineText.Length;
                    SubjectBuffer.Delete(new Span(line.Start.Position, line.Length));
                    endSnapshotSpan = SubjectBuffer.CurrentSnapshot.GetSpan(new Span(line.Start.Position, 0));
                }
            }
        }
 public override void Invoke()
 {
     EditorExtensionsPackage.DTE.UndoContext.Open(DisplayText);
     _span.TextBuffer.Replace(_span.GetSpan(_span.TextBuffer.CurrentSnapshot), _hack + _selector.Text);
     EditorExtensionsPackage.DTE.UndoContext.Close();
 }
예제 #33
0
        private static CompletionAnalysis GetNormalCompletionContext(IServiceProvider serviceProvider, ITextSnapshot snapshot, ITrackingSpan applicableSpan, ITrackingPoint point, CompletionOptions options) {
            var span = applicableSpan.GetSpan(snapshot);

            if (IsSpaceCompletion(snapshot, point) && !IntellisenseController.ForceCompletions) {
                return CompletionAnalysis.EmptyCompletionContext;
            }

            var parser = new ReverseExpressionParser(snapshot, snapshot.TextBuffer, applicableSpan);
            if (parser.IsInGrouping()) {
                options = options.Clone();
                options.IncludeStatementKeywords = false;
            }

            return new NormalCompletionAnalysis(
                snapshot.TextBuffer.GetAnalyzer(serviceProvider),
                snapshot,
                applicableSpan,
                snapshot.TextBuffer,
                options,
                serviceProvider
            );
        }
 public void Invoke(CancellationToken cancellationToken)
 {
     span.TextBuffer.Replace(span.GetSpan(span.TextBuffer.CurrentSnapshot), indentedCode);
 }
예제 #35
0
 /// <summary>
 /// This method is executed when action is selected in the context menu
 /// </summary>
 public void Invoke()
 {
     span.TextBuffer.Replace(span.GetSpan(span.TextBuffer.CurrentSnapshot), String.Empty);
 }
        private void SetNewEndPosition(ITrackingSpan endTrackingSpan)
        {
            if (SetEndPositionIfNoneSpecified(ExpansionSession))
            {
                return;
            }

            if (endTrackingSpan != null)
            {
                SnapshotSpan endSpanInSurfaceBuffer;
                if (!TryGetSurfaceBufferSpan(endTrackingSpan.GetSpan(SubjectBuffer.CurrentSnapshot), out endSpanInSurfaceBuffer))
                {
                    return;
                }

                int endLine, endColumn;
                TextView.TextSnapshot.GetLineAndColumn(endSpanInSurfaceBuffer.Start.Position, out endLine, out endColumn);
                ExpansionSession.SetEndSpan(new VsTextSpan
                {
                    iStartLine = endLine,
                    iStartIndex = endColumn,
                    iEndLine = endLine,
                    iEndIndex = endColumn
                });
            }
        }
예제 #37
0
        /// <summary>
        /// Gets the range of the expression to the left of our starting span.
        /// </summary>
        /// <param name="nesting">1 if we have an opening parenthesis for sig completion</param>
        /// <param name="paramIndex">The current parameter index.</param>
        /// <returns></returns>
        public SnapshotSpan?GetExpressionRange(int nesting, out int paramIndex, out SnapshotPoint?sigStart, out string lastKeywordArg, out bool isParameterName, bool forCompletion = true)
        {
            SnapshotSpan?start = null;

            paramIndex = 0;
            sigStart   = null;
            bool nestingChanged = false, lastTokenWasCommaOrOperator = true, lastTokenWasKeywordArgAssignment = false;
            int  otherNesting = 0;
            bool isSigHelp    = nesting != 0;

            isParameterName = false;
            lastKeywordArg  = null;

            ClassificationSpan lastToken = null;
            // Walks backwards over all the lines
            var enumerator = ReverseClassificationSpanEnumerator(Classifier, _span.GetSpan(_snapshot).End);

            if (enumerator.MoveNext())
            {
                if (enumerator.Current != null && enumerator.Current.ClassificationType == this.Classifier.Provider.StringLiteral)
                {
                    return(enumerator.Current.Span);
                }

                lastToken = enumerator.Current;
                while (ShouldSkipAsLastToken(lastToken, forCompletion) && enumerator.MoveNext())
                {
                    // skip trailing new line if the user is hovering at the end of the line
                    if (lastToken == null && (nesting + otherNesting == 0))
                    {
                        // new line out of a grouping...
                        return(_span.GetSpan(_snapshot));
                    }
                    lastToken = enumerator.Current;
                }

                int          currentParamAtLastColon = -1; // used to track the current param index at this last colon, before we hit a lambda.
                SnapshotSpan?startAtLastToken        = null;
                // Walk backwards over the tokens in the current line
                do
                {
                    var token = enumerator.Current;

                    if (token == null)
                    {
                        // new line
                        if (nesting != 0 || otherNesting != 0 || (enumerator.MoveNext() && IsExplicitLineJoin(enumerator.Current)))
                        {
                            // we're in a grouping, or the previous token is an explicit line join, we'll keep going.
                            continue;
                        }
                        else
                        {
                            break;
                        }
                    }

                    var text = token.Span.GetText();
                    if (text == "(")
                    {
                        if (nesting != 0)
                        {
                            nesting--;
                            nestingChanged = true;
                            if (nesting == 0)
                            {
                                if (sigStart == null)
                                {
                                    sigStart = token.Span.Start;
                                }
                            }
                        }
                        else
                        {
                            if (start == null && !forCompletion)
                            {
                                // hovering directly over an open paren, don't provide a tooltip
                                return(null);
                            }

                            // figure out if we're a parameter definition
                            isParameterName = IsParameterNameOpenParen(enumerator);
                            break;
                        }
                        lastTokenWasCommaOrOperator      = true;
                        lastTokenWasKeywordArgAssignment = false;
                    }
                    else if (token.IsOpenGrouping())
                    {
                        if (otherNesting != 0)
                        {
                            otherNesting--;
                        }
                        else
                        {
                            if (nesting == 0)
                            {
                                if (start == null)
                                {
                                    return(null);
                                }
                                break;
                            }
                            paramIndex = 0;
                        }
                        nestingChanged = true;
                        lastTokenWasCommaOrOperator      = true;
                        lastTokenWasKeywordArgAssignment = false;
                    }
                    else if (text == ")")
                    {
                        nesting++;
                        nestingChanged = true;
                        lastTokenWasCommaOrOperator      = true;
                        lastTokenWasKeywordArgAssignment = false;
                    }
                    else if (token.IsCloseGrouping())
                    {
                        otherNesting++;
                        nestingChanged = true;
                        lastTokenWasCommaOrOperator      = true;
                        lastTokenWasKeywordArgAssignment = false;
                    }
                    else if (token.ClassificationType == Classifier.Provider.Keyword ||
                             token.ClassificationType == Classifier.Provider.Operator)
                    {
                        lastTokenWasKeywordArgAssignment = false;

                        if (token.ClassificationType == Classifier.Provider.Keyword && text == "lambda")
                        {
                            if (currentParamAtLastColon != -1)
                            {
                                paramIndex = currentParamAtLastColon;
                                currentParamAtLastColon = -1;
                            }
                            else
                            {
                                // fabcd(lambda a, b, c[PARAMINFO]
                                // We have to be the 1st param.
                                paramIndex = 0;
                            }
                        }

                        if (text == ":")
                        {
                            startAtLastToken        = start;
                            currentParamAtLastColon = paramIndex;
                        }

                        if (nesting == 0 && otherNesting == 0)
                        {
                            if (start == null)
                            {
                                // http://pytools.codeplex.com/workitem/560
                                // yield_value = 42
                                // def f():
                                //     yield<ctrl-space>
                                //     yield <ctrl-space>
                                //
                                // If we're next to the keyword, just return the keyword.
                                // If we're after the keyword, return the span of the text proceeding
                                //  the keyword so we can complete after it.
                                //
                                // Also repros with "return <ctrl-space>" or "print <ctrl-space>" both
                                // of which we weren't reporting completions for before
                                if (forCompletion)
                                {
                                    if (token.Span.IntersectsWith(_span.GetSpan(_snapshot)))
                                    {
                                        return(token.Span);
                                    }
                                    else
                                    {
                                        return(_span.GetSpan(_snapshot));
                                    }
                                }

                                // hovering directly over a keyword, don't provide a tooltip
                                return(null);
                            }
                            else if ((nestingChanged || forCompletion) && token.ClassificationType == Classifier.Provider.Keyword && (text == "def" || text == "class"))
                            {
                                return(null);
                            }
                            if (text == "*" || text == "**")
                            {
                                if (MoveNextSkipExplicitNewLines(enumerator))
                                {
                                    if (enumerator.Current.ClassificationType == Classifier.Provider.CommaClassification)
                                    {
                                        isParameterName = IsParameterNameComma(enumerator);
                                    }
                                    else if (enumerator.Current.IsOpenGrouping() && enumerator.Current.Span.GetText() == "(")
                                    {
                                        isParameterName = IsParameterNameOpenParen(enumerator);
                                    }
                                }
                            }
                            break;
                        }
                        else if ((token.ClassificationType == Classifier.Provider.Keyword &&
                                  PythonKeywords.IsOnlyStatementKeyword(text)) ||
                                 (token.ClassificationType == Classifier.Provider.Operator && IsAssignmentOperator(text)))
                        {
                            if (nesting != 0 && text == "=")
                            {
                                // keyword argument allowed in signatures
                                lastTokenWasKeywordArgAssignment = lastTokenWasCommaOrOperator = true;
                            }
                            else if (start == null || (nestingChanged && nesting != 0))
                            {
                                return(null);
                            }
                            else
                            {
                                break;
                            }
                        }
                        else if (token.ClassificationType == Classifier.Provider.Keyword &&
                                 (text == "if" || text == "else"))
                        {
                            // if and else can be used in an expression context or a statement context
                            if (currentParamAtLastColon != -1)
                            {
                                start = startAtLastToken;
                                if (start == null)
                                {
                                    return(null);
                                }
                                break;
                            }
                        }
                        lastTokenWasCommaOrOperator = true;
                    }
                    else if (token.ClassificationType == Classifier.Provider.DotClassification)
                    {
                        lastTokenWasCommaOrOperator      = true;
                        lastTokenWasKeywordArgAssignment = false;
                    }
                    else if (token.ClassificationType == Classifier.Provider.CommaClassification)
                    {
                        lastTokenWasCommaOrOperator      = true;
                        lastTokenWasKeywordArgAssignment = false;
                        if (nesting == 0 && otherNesting == 0)
                        {
                            if (start == null && !forCompletion)
                            {
                                return(null);
                            }
                            isParameterName = IsParameterNameComma(enumerator);
                            break;
                        }
                        else if (nesting == 1 && otherNesting == 0 && sigStart == null)
                        {
                            paramIndex++;
                        }
                    }
                    else if (token.ClassificationType == Classifier.Provider.Comment)
                    {
                        return(null);
                    }
                    else if (!lastTokenWasCommaOrOperator)
                    {
                        if (nesting == 0 && otherNesting == 0)
                        {
                            break;
                        }
                    }
                    else
                    {
                        if (lastTokenWasKeywordArgAssignment &&
                            token.ClassificationType.IsOfType(PredefinedClassificationTypeNames.Identifier) &&
                            lastKeywordArg == null)
                        {
                            if (paramIndex == 0)
                            {
                                lastKeywordArg = text;
                            }
                            else
                            {
                                lastKeywordArg = "";
                            }
                        }
                        lastTokenWasCommaOrOperator = false;
                    }

                    start = token.Span;
                } while (enumerator.MoveNext());
            }

            if (start.HasValue && lastToken != null && (lastToken.Span.End.Position - start.Value.Start.Position) >= 0)
            {
                return(new SnapshotSpan(
                           Snapshot,
                           new Span(
                               start.Value.Start.Position,
                               lastToken.Span.End.Position - start.Value.Start.Position
                               )
                           ));
            }

            return(_span.GetSpan(_snapshot));
        }
예제 #38
0
 /// <summary>
 /// This method is executed when action is selected in the context menu.
 /// </summary>
 public void Invoke()
 {
     _span.TextBuffer.Replace(_span.GetSpan(_span.TextBuffer.CurrentSnapshot), _replaceWith);
 }
 public override void Invoke()
 {
     using (EditorExtensionsPackage.UndoContext((DisplayText)))
         _span.TextBuffer.Replace(_span.GetSpan(_span.TextBuffer.CurrentSnapshot), _hack + _selector.Text);
 }
예제 #40
0
        private static CompletionAnalysis TrySpecialCompletions(IServiceProvider serviceProvider, ITextSnapshot snapshot, ITrackingSpan span, ITrackingPoint point, CompletionOptions options) {
            var snapSpan = span.GetSpan(snapshot);
            var buffer = snapshot.TextBuffer;
            var classifier = buffer.GetPythonClassifier();
            if (classifier == null) {
                return null;
            }

            var parser = new ReverseExpressionParser(snapshot, buffer, span);
            var statementRange = parser.GetStatementRange();
            if (!statementRange.HasValue) {
                statementRange = snapSpan.Start.GetContainingLine().Extent;
            }
            if (snapSpan.Start < statementRange.Value.Start) {
                return null;
            }

            var tokens = classifier.GetClassificationSpans(new SnapshotSpan(statementRange.Value.Start, snapSpan.Start));
            if (tokens.Count > 0) {
                // Check for context-sensitive intellisense
                var lastClass = tokens[tokens.Count - 1];

                if (lastClass.ClassificationType == classifier.Provider.Comment) {
                    // No completions in comments
                    return CompletionAnalysis.EmptyCompletionContext;
                } else if (lastClass.ClassificationType == classifier.Provider.StringLiteral) {
                    // String completion
                    if (lastClass.Span.Start.GetContainingLine().LineNumber == lastClass.Span.End.GetContainingLine().LineNumber) {
                        return new StringLiteralCompletionList(span, buffer, options);
                    } else {
                        // multi-line string, no string completions.
                        return CompletionAnalysis.EmptyCompletionContext;
                    }
                } else if (lastClass.ClassificationType == classifier.Provider.Operator &&
                    lastClass.Span.GetText() == "@") {

                    if (tokens.Count == 1) {
                    return new DecoratorCompletionAnalysis(span, buffer, options);
                    }
                    // TODO: Handle completions automatically popping up
                    // after '@' when it is used as a binary operator.
                } else if (CompletionAnalysis.IsKeyword(lastClass, "def")) {
                    return new OverrideCompletionAnalysis(span, buffer, options);
                }

                // Import completions
                var first = tokens[0];
                if (CompletionAnalysis.IsKeyword(first, "import")) {
                    return ImportCompletionAnalysis.Make(tokens, span, buffer, options);
                } else if (CompletionAnalysis.IsKeyword(first, "from")) {
                    return FromImportCompletionAnalysis.Make(tokens, span, buffer, options);
                } else if (CompletionAnalysis.IsKeyword(first, "raise") || CompletionAnalysis.IsKeyword(first, "except")) {
                    if (tokens.Count == 1 ||
                        lastClass.ClassificationType.IsOfType(PythonPredefinedClassificationTypeNames.Comma) ||
                        (lastClass.IsOpenGrouping() && tokens.Count < 3)) {
                        return new ExceptionCompletionAnalysis(span, buffer, options);
                    }
                }
                return null;
            } else if ((tokens = classifier.GetClassificationSpans(snapSpan.Start.GetContainingLine().ExtentIncludingLineBreak)).Count > 0 &&
               tokens[0].ClassificationType == classifier.Provider.StringLiteral) {
                // multi-line string, no string completions.
                return CompletionAnalysis.EmptyCompletionContext;
            } else if (snapshot.IsReplBufferWithCommand()) {
                return CompletionAnalysis.EmptyCompletionContext;
            }

            return null;
        }
 private void StateMachine_TrackingSessionCleared(ITrackingSpan trackingSpanToClear)
 {
     TagsChanged(this, new SnapshotSpanEventArgs(trackingSpanToClear.GetSpan(_stateMachine.Buffer.CurrentSnapshot)));
 }
예제 #42
0
        internal static MissingImportAnalysis GetMissingImports(IServiceProvider serviceProvider, ITextSnapshot snapshot, ITrackingSpan span) {
            ReverseExpressionParser parser = new ReverseExpressionParser(snapshot, snapshot.TextBuffer, span);
            var loc = span.GetSpan(snapshot.Version);
            int dummy;
            SnapshotPoint? dummyPoint;
            string lastKeywordArg;
            bool isParameterName;
            var exprRange = parser.GetExpressionRange(0, out dummy, out dummyPoint, out lastKeywordArg, out isParameterName);
            if (exprRange == null || isParameterName) {
                return MissingImportAnalysis.Empty;
            }

            IPythonProjectEntry entry;
            ModuleAnalysis analysis;
            if (!snapshot.TextBuffer.TryGetPythonProjectEntry(out entry) ||
                entry == null ||
                (analysis = entry.Analysis) == null) {
                return MissingImportAnalysis.Empty;
            }

            var text = exprRange.Value.GetText();
            if (string.IsNullOrEmpty(text)) {
                return MissingImportAnalysis.Empty;
            }

            var analyzer = analysis.ProjectState;
            var index = (parser.GetStatementRange() ?? span.GetSpan(snapshot)).Start.Position;

            var location = TranslateIndex(
                index,
                snapshot,
                analysis
            );
            var nameExpr = GetFirstNameExpression(analysis.GetAstFromText(text, location).Body);

            if (nameExpr != null && !IsImplicitlyDefinedName(nameExpr)) {
                var name = nameExpr.Name;
                lock (snapshot.TextBuffer.GetAnalyzer(serviceProvider)) {
                    var hasVariables = analysis.GetVariables(name, location).Any(IsDefinition);
                    var hasValues = analysis.GetValues(name, location).Any();

                    // if we have type information or an assignment to the variable we won't offer 
                    // an import smart tag.
                    if (!hasValues && !hasVariables) {
                        var applicableSpan = parser.Snapshot.CreateTrackingSpan(
                            exprRange.Value.Span,
                            SpanTrackingMode.EdgeExclusive
                        );
                        return new MissingImportAnalysis(name, analysis.ProjectState, applicableSpan);
                    }
                }
            }

            // if we have type information don't offer to add imports
            return MissingImportAnalysis.Empty;
        }
예제 #43
0
 private void MoveToSpan(ITrackingSpan span)
 {
     SnapshotSpan target = span.GetSpan(_view.WpfView.TextBuffer.CurrentSnapshot);
     MoveToSpan(target);
 }