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(); } }
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); }
/// <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); } } } }
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; } } }
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); }
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; }
/// <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); } } }