/// <summary> /// Given position in the buffer finds index of the function parameter. /// </summary> public static int ComputeCurrentParameter(this ISignatureInfo signatureInfo, IEditorBufferSnapshot snapshot, AstRoot ast, int position, IREditorSettings settings) { var parameterInfo = ast.GetSignatureInfoFromBuffer(snapshot, position); var index = 0; if (parameterInfo != null) { index = parameterInfo.ParameterIndex; if (parameterInfo.NamedParameter) { // A function f <- function(foo, bar) is said to have formal parameters "foo" and "bar", // and the call f(foo=3, ba=13) is said to have (actual) arguments "foo" and "ba". // R first matches all arguments that have exactly the same name as a formal parameter. // Two identical argument names cause an error. Then, R matches any argument names that // partially matches a(yet unmatched) formal parameter. But if two argument names partially // match the same formal parameter, that also causes an error. Also, it only matches // formal parameters before ... So formal parameters after ... must be specified using // their full names. Then the unnamed arguments are matched in positional order to // the remaining formal arguments. var argumentIndexInSignature = signatureInfo.GetArgumentIndex(parameterInfo.ParameterName, settings.PartialArgumentNameMatch); if (argumentIndexInSignature >= 0) { index = argumentIndexInSignature; } } } return(index); }
private int ComputeActiveParameter(IRIntellisenseContext context, ISignatureInfo signatureInfo) { var settings = _services.GetService <IREditorSettings>(); var parameterIndex = signatureInfo.ComputeCurrentParameter(context.EditorBuffer.CurrentSnapshot, context.AstRoot, context.Position, settings); if (parameterIndex < signatureInfo.Arguments.Count) { return(parameterIndex); } return(signatureInfo.Arguments.Count > 0 ? signatureInfo.Arguments.Count - 1 : 0); }
private RFunctionSignatureHelp(IEditorIntellisenseSession session, IEditorBuffer textBuffer, string functionName, string documentation, ISignatureInfo signatureInfo) { FunctionName = functionName; SignatureInfo = signatureInfo; Documentation = documentation; Parameters = null; _editorBuffer = textBuffer; _view = session.View; Session = session; _signatureBroker = session.Services.GetService <IViewSignatureBroker>(); Debug.Assert(_signatureBroker != null); }
public SignatureHelp(ISignatureHelpSession session, ITextBuffer subjectBuffer, string functionName, string documentation, ISignatureInfo signatureInfo) { FunctionName = functionName; _signatureInfo = signatureInfo; Documentation = documentation; Parameters = null; Session = session; Session.Dismissed += OnSessionDismissed; TextView = session.TextView; TextView.Caret.PositionChanged += OnCaretPositionChanged; SubjectBuffer = subjectBuffer; SubjectBuffer.Changed += OnSubjectBufferChanged; }
public static IReadOnlyList <ISignatureInfo> ParseSignatures(string usageContent, IReadOnlyDictionary <string, string> argumentsDescriptions = null) { // RD signature text may contain \dots sequence which denotes ellipsis. // R parser does not know about it and hence we will replace \dots by ... // Also, signatures may contain S3 method info like // '\method{as.matrix}{data.frame}(x, rownames.force = NA, \dots)' // which we need to filter out since they are irrelevant to intellisense. List <ISignatureInfo> signatures = new List <ISignatureInfo>(); usageContent = usageContent.Replace(@"\dots", "..."); RTokenizer tokenizer = new RTokenizer(separateComments: true); IReadOnlyTextRangeCollection <RToken> collection = tokenizer.Tokenize(usageContent); ITextProvider textProvider = new TextStream(usageContent); TokenStream <RToken> tokens = new TokenStream <RToken>(collection, RToken.EndOfStreamToken); var parseContext = new ParseContext(textProvider, TextRange.FromBounds(tokens.CurrentToken.Start, textProvider.Length), tokens, tokenizer.CommentTokens); while (!tokens.IsEndOfStream()) { // Filter out '\method{...}{}(signature) if (tokens.CurrentToken.TokenType == RTokenType.OpenCurlyBrace) { // Check if { is preceded by \method } if (tokens.CurrentToken.TokenType != RTokenType.Identifier) { break; } string functionName = textProvider.GetText(tokens.CurrentToken); tokens.MoveToNextToken(); ISignatureInfo info = ParseSignature(functionName, parseContext, argumentsDescriptions); if (info != null) { signatures.Add(info); } } return(signatures); }
private ISignature CreateSignature(ISignatureHelpSession session, IFunctionInfo functionInfo, ISignatureInfo signatureInfo, ITrackingSpan span, AstRoot ast, int position) { SignatureHelp sig = new SignatureHelp(session, _textBuffer, functionInfo.Name, string.Empty, signatureInfo); List <IParameter> paramList = new List <IParameter>(); // Locus points in the pretty printed signature (the one displayed in the tooltip) var locusPoints = new List <int>(); string signatureString = signatureInfo.GetSignatureString(locusPoints); sig.Content = signatureString; sig.ApplicableToSpan = span; sig.Documentation = functionInfo.Description?.Wrap(Math.Min(SignatureInfo.MaxSignatureLength, sig.Content.Length)); Debug.Assert(locusPoints.Count == signatureInfo.Arguments.Count + 1); for (int i = 0; i < signatureInfo.Arguments.Count; i++) { IArgumentInfo p = signatureInfo.Arguments[i]; if (p != null) { int locusStart = locusPoints[i]; int locusLength = locusPoints[i + 1] - locusStart; Debug.Assert(locusLength >= 0); Span locus = new Span(locusStart, locusLength); /// VS may end showing very long tooltip so we need to keep /// description reasonably short: typically about /// same length as the function signature. paramList.Add( new SignatureParameter( p.Description.Wrap( Math.Min(SignatureInfo.MaxSignatureLength, sig.Content.Length)), locus, locus, p.Name, sig)); } } sig.Parameters = new ReadOnlyCollection <IParameter>(paramList); sig.ComputeCurrentParameter(ast, position); return(sig); }
private ISignature CreateSignature(ISignatureHelpSession session, string functionName, IFunctionInfo functionInfo, ISignatureInfo signatureInfo, ITrackingSpan span, AstRoot ast, int position) { SignatureHelp sig = new SignatureHelp(session, _textBuffer, functionName, string.Empty, signatureInfo, _shell); List<IParameter> paramList = new List<IParameter>(); // Locus points in the pretty printed signature (the one displayed in the tooltip) var locusPoints = new List<int>(); string signatureString = signatureInfo.GetSignatureString(functionName, locusPoints); sig.Content = signatureString; sig.ApplicableToSpan = span; sig.Documentation = functionInfo.Description?.Wrap(Math.Min(SignatureInfo.MaxSignatureLength, sig.Content.Length)); Debug.Assert(locusPoints.Count == signatureInfo.Arguments.Count + 1); for (int i = 0; i < signatureInfo.Arguments.Count; i++) { IArgumentInfo p = signatureInfo.Arguments[i]; if (p != null) { int locusStart = locusPoints[i]; int locusLength = locusPoints[i + 1] - locusStart; Debug.Assert(locusLength >= 0); Span locus = new Span(locusStart, locusLength); /// VS may end showing very long tooltip so we need to keep /// description reasonably short: typically about /// same length as the function signature. paramList.Add( new SignatureParameter( p.Description.Wrap( Math.Min(SignatureInfo.MaxSignatureLength, sig.Content.Length)), locus, locus, p.Name, sig)); } } sig.Parameters = new ReadOnlyCollection<IParameter>(paramList); sig.ComputeCurrentParameter(ast, position); return sig; }
public static IRFunctionSignatureHelp Create(IRIntellisenseContext context, IFunctionInfo functionInfo, ISignatureInfo signatureInfo, ITrackingTextRange applicableSpan) { var sig = new RFunctionSignatureHelp(context.Session, context.EditorBuffer, functionInfo.Name, string.Empty, signatureInfo); var paramList = new List <ISignatureParameterHelp>(); // Locus points in the pretty printed signature (the one displayed in the tooltip) var locusPoints = new List <int>(); var signatureString = signatureInfo.GetSignatureString(functionInfo.Name, locusPoints); sig.Content = signatureString; sig.ApplicableToRange = applicableSpan; sig.Documentation = functionInfo.Description?.Wrap(Math.Min(MaxSignatureLength, sig.Content.Length)); Debug.Assert(locusPoints.Count == signatureInfo.Arguments.Count + 1); for (var i = 0; i < signatureInfo.Arguments.Count; i++) { var p = signatureInfo.Arguments[i]; if (p != null) { var locusStart = locusPoints[i]; var locusLength = locusPoints[i + 1] - locusStart; Debug.Assert(locusLength >= 0); var locus = new TextRange(locusStart, locusLength); // VS may end showing very long tooltip so we need to keep // description reasonably short: typically about // same length as the function signature. var description = p.Description.Wrap(Math.Min(MaxSignatureLength, sig.Content.Length)); paramList.Add(new RSignatureParameterHelp(description, locus, p.Name, sig)); } } sig.Parameters = new ReadOnlyCollection <ISignatureParameterHelp>(paramList); sig.ComputeCurrentParameter(context.AstRoot, context.Position); return(sig); }