Exemplo n.º 1
0
        private void CommaFindBestSignature(int curParam, string lastKeywordArg)
        {
            // see if we have a signature which accomodates this...

            // TODO: We should also get the types of the arguments and use that to
            // pick the best signature when the signature includes types.
            var bestSig = _sigHelpSession.SelectedSignature as PythonSignature;

            if (bestSig != null)
            {
                for (int i = 0; i < bestSig.Parameters.Count; ++i)
                {
                    if (bestSig.Parameters[i].Name == lastKeywordArg ||
                        lastKeywordArg == null && (i == curParam || PythonSignature.IsParamArray(bestSig.Parameters[i].Name))
                        )
                    {
                        bestSig.SetCurrentParameter(bestSig.Parameters[i]);
                        _sigHelpSession.SelectedSignature = bestSig;
                        return;
                    }
                }
            }

            PythonSignature fallback = null;

            foreach (var sig in _sigHelpSession.Signatures.OfType <PythonSignature>().OrderBy(s => s.Parameters.Count))
            {
                fallback = sig;
                for (int i = 0; i < sig.Parameters.Count; ++i)
                {
                    if (sig.Parameters[i].Name == lastKeywordArg ||
                        lastKeywordArg == null && (i == curParam || PythonSignature.IsParamArray(sig.Parameters[i].Name))
                        )
                    {
                        sig.SetCurrentParameter(sig.Parameters[i]);
                        _sigHelpSession.SelectedSignature = sig;
                        return;
                    }
                }
            }

            if (fallback != null)
            {
                fallback.SetCurrentParameter(null);
                _sigHelpSession.SelectedSignature = fallback;
            }
            else
            {
                _sigHelpSession.Dismiss();
            }
        }
Exemplo n.º 2
0
        private bool Backspace()
        {
            if (_sigHelpSession != null)
            {
                if (_textView.Selection.IsActive && !_textView.Selection.IsEmpty)
                {
                    // when deleting a selection don't do anything to pop up signature help again
                    _sigHelpSession.Dismiss();
                    return(false);
                }

                SnapshotPoint?caretPoint = GetCaretPoint();

                if (caretPoint != null && caretPoint.Value.Position != 0)
                {
                    var deleting = caretPoint.Value.Snapshot[caretPoint.Value.Position - 1];
                    if (deleting == ',')
                    {
                        PythonSignature sig = _sigHelpSession.SelectedSignature as PythonSignature;
                        if (sig != null)
                        {
                            int curParam = sig.Parameters.IndexOf(sig.CurrentParameter);

                            if (curParam > 0)
                            {
                                sig.SetCurrentParameter(sig.Parameters[curParam - 1]);
                            }
                        }
                    }
                    else if (deleting == '(')
                    {
                        _sigHelpSession.Dismiss();
                        // delete the ( before triggering help again
                        caretPoint.Value.Snapshot.TextBuffer.Delete(new Span(caretPoint.Value.Position - 1, 1));

                        // Pop to an outer nesting of signature help
                        if (PythonToolsPackage.Instance.LangPrefs.AutoListParams)
                        {
                            TriggerSignatureHelp();
                        }

                        return(true);
                    }
                }
            }
            return(false);
        }
Exemplo n.º 3
0
        /// <summary>
        /// Updates the current parameter assuming the caret is at the provided position.
        ///
        /// This will analyze the buffer for where we are currently located, find the current
        /// parameter that we're entering, and then update the signature.  If our current
        /// signature does not have enough parameters we'll find a signature which does.
        /// </summary>
        private void UpdateCurrentParameter(int position)
        {
            // we advance to the next parameter
            // TODO: Take into account params arrays
            // TODO: need to parse and see if we have keyword arguments entered into the current signature yet
            PythonSignature sig = _sigHelpSession.SelectedSignature as PythonSignature;

            if (sig != null)
            {
                var prevBuffer = sig.ApplicableToSpan.TextBuffer;
                var textBuffer = _textView.TextBuffer;
                if (prevBuffer != textBuffer)
                {
                }

                var targetPt = _textView.BufferGraph.MapDownToFirstMatch(
                    new SnapshotPoint(_textView.TextBuffer.CurrentSnapshot, position),
                    PointTrackingMode.Positive,
                    PythonCoreConstants.IsPythonContent,
                    PositionAffinity.Successor
                    );

                if (targetPt != null)
                {
                    var span = targetPt.Value.Snapshot.CreateTrackingSpan(targetPt.Value.Position, 0, SpanTrackingMode.EdgeInclusive);

                    var sigs     = targetPt.Value.Snapshot.GetSignatures(span);
                    int curParam = sigs.ParameterIndex;

                    if (curParam < sig.Parameters.Count)
                    {
                        sig.SetCurrentParameter(sig.Parameters[curParam]);
                    }
                    else
                    {
                        CommaFindBestSignature(curParam);
                    }
                }
            }
        }
Exemplo n.º 4
0
        private void CommaFindBestSignature(int curParam)
        {
            // see if we have a signature which accomodates this...

            // TODO: We should also take into account param arrays
            // TODO: We should also get the types of the arguments and use that to
            // pick the best signature when the signature includes types.
            foreach (var availableSig in _sigHelpSession.Signatures)
            {
                if (availableSig.Parameters.Count > curParam)
                {
                    _sigHelpSession.SelectedSignature = availableSig;

                    PythonSignature sig = availableSig as PythonSignature;
                    if (sig != null)
                    {
                        sig.SetCurrentParameter(sig.Parameters[curParam]);
                    }
                    break;
                }
            }
        }
Exemplo n.º 5
0
        private static ISignature[] GetLiveSignatures(string text, ICollection <OverloadDoc> liveSigs, int paramIndex, ITrackingSpan span)
        {
            ISignature[] res = new ISignature[liveSigs.Count];
            int          i   = 0;

            foreach (var sig in liveSigs)
            {
                var parameters = new ParameterResult[sig.Parameters.Length];
                int j          = 0;
                foreach (var param in sig.Parameters)
                {
                    parameters[j++] = new ParameterResult(param.Name);
                }

                res[i++] = new PythonSignature(
                    span,
                    new LiveOverloadResult(text, sig.Documentation, parameters),
                    paramIndex
                    );
            }
            return(res);
        }
Exemplo n.º 6
0
 private static ISignature[] GetLiveSignatures(string text, ICollection<OverloadDoc> liveSigs, int paramIndex, ITrackingSpan span, string lastKeywordArg) {
     ISignature[] res = new ISignature[liveSigs.Count];
     int i = 0;
     foreach (var sig in liveSigs) {
         res[i++] = new PythonSignature(
             span,
             new LiveOverloadResult(text, sig.Documentation, sig.Parameters),
             paramIndex,
             lastKeywordArg
         );
     }
     return res;
 }
Exemplo n.º 7
0
        /// <summary>
        /// Updates the current parameter for the caret's current position.
        ///
        /// This will analyze the buffer for where we are currently located, find the current
        /// parameter that we're entering, and then update the signature.  If our current
        /// signature does not have enough parameters we'll find a signature which does.
        /// </summary>
        private void UpdateCurrentParameter()
        {
            if (_sigHelpSession == null)
            {
                // we moved out of the original span for sig help, re-trigger based upon the position
                TriggerSignatureHelp();
                return;
            }

            int position = _textView.Caret.Position.BufferPosition.Position;
            // we advance to the next parameter
            // TODO: Take into account params arrays
            // TODO: need to parse and see if we have keyword arguments entered into the current signature yet
            PythonSignature sig = _sigHelpSession.SelectedSignature as PythonSignature;

            if (sig != null)
            {
                var prevBuffer = sig.ApplicableToSpan.TextBuffer;
                var textBuffer = _textView.TextBuffer;

                var targetPt = _textView.BufferGraph.MapDownToFirstMatch(
                    new SnapshotPoint(_textView.TextBuffer.CurrentSnapshot, position),
                    PointTrackingMode.Positive,
                    EditorExtensions.IsPythonContent,
                    PositionAffinity.Successor
                    );

                if (targetPt == null)
                {
                    return;
                }
                var span = targetPt.Value.Snapshot.CreateTrackingSpan(targetPt.Value.Position, 0, SpanTrackingMode.EdgeInclusive);

                var  sigs      = targetPt.Value.Snapshot.GetSignatures(_serviceProvider, span);
                bool retrigger = false;
                if (sigs.Signatures.Count == _sigHelpSession.Signatures.Count)
                {
                    for (int i = 0; i < sigs.Signatures.Count && !retrigger; i++)
                    {
                        var leftSig  = sigs.Signatures[i];
                        var rightSig = _sigHelpSession.Signatures[i];

                        if (leftSig.Parameters.Count == rightSig.Parameters.Count)
                        {
                            for (int j = 0; j < leftSig.Parameters.Count; j++)
                            {
                                var leftParam  = leftSig.Parameters[j];
                                var rightParam = rightSig.Parameters[j];

                                if (leftParam.Name != rightParam.Name || leftParam.Documentation != rightParam.Documentation)
                                {
                                    retrigger = true;
                                    break;
                                }
                            }
                        }

                        if (leftSig.Content != rightSig.Content || leftSig.Documentation != rightSig.Documentation)
                        {
                            retrigger = true;
                        }
                    }
                }
                else
                {
                    retrigger = true;
                }

                if (retrigger)
                {
                    _sigHelpSession.Dismiss();
                    TriggerSignatureHelp();
                }
                else
                {
                    CommaFindBestSignature(sigs.ParameterIndex, sigs.LastKeywordArgument);
                }
            }
        }