public IReadOnlyCollection<RCompletion> GetEntries(RCompletionContext context) { List<RCompletion> completions = new List<RCompletion>(); var infoSource = _snippetInformationSource?.InformationSource; // TODO: this is different in the console window where // packages may have been loaded from the command line. // We need an extensibility point here. IEnumerable<IPackageInfo> packages = GetPackages(context); // Get list of functions in the package foreach (IPackageInfo pkg in packages) { Debug.Assert(pkg != null); IEnumerable<INamedItemInfo> functions = pkg.Functions; if (functions != null) { foreach (INamedItemInfo function in functions) { bool isSnippet = false; // Snippets are suppressed if user typed namespace if (!context.IsInNameSpace() && infoSource != null) { isSnippet = infoSource.IsSnippet(function.Name); } if (!isSnippet) { ImageSource glyph = function.ItemType == NamedItemType.Constant ? _constantGlyph : _functionGlyph; var completion = new RFunctionCompletion(function.Name, CompletionUtilities.BacktickName(function.Name), function.Description, glyph, _functionIndex, context.Session); completions.Add(completion); } } } } return completions; }
public IReadOnlyCollection<RCompletion> GetEntries(RCompletionContext context) { List<RCompletion> completions = new List<RCompletion>(); string directory = null; string userDirectory = null; if (_userDirectoryFetchingTask != null) { userDirectory = _userDirectoryFetchingTask.WaitTimeout(500); userDirectory = userDirectory ?? _cachedUserDirectory; } try { if (!string.IsNullOrEmpty(userDirectory)) { _cachedUserDirectory = userDirectory; directory = Path.Combine(userDirectory, _directory); } else { directory = _directory; } if (!string.IsNullOrEmpty(directory)) { IEnumerable<RCompletion> entries = null; if (_forceR || _workflow.RSession.IsRemote) { var t = GetRemoteDirectoryItemsAsync(directory); entries = t.WaitTimeout(_forceR ? 5000 : 1000); } else { entries = GetLocalDirectoryItems(directory); } completions.AddRange(entries); } } catch (IOException) { } catch (UnauthorizedAccessException) { } return completions; }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); if (!context.IsInNameSpace()) { var infoSource = _snippetInformationSource?.InformationSource; ImageSource keyWordGlyph = _glyphService.GetGlyphThreadSafe(StandardGlyphGroup.GlyphKeyword, StandardGlyphItem.GlyphItemPublic); // Union with constants like TRUE and other common things var keywords = Keywords.KeywordList.Concat(Logicals.LogicalsList).Concat(Constants.ConstantsList); foreach (string keyword in keywords) { bool?isSnippet = infoSource?.IsSnippet(keyword); if (!isSnippet.HasValue || !isSnippet.Value) { completions.Add(new RCompletion(keyword, keyword, string.Empty, keyWordGlyph)); } } ImageSource buildInGlyph = _glyphService.GetGlyphThreadSafe(StandardGlyphGroup.GlyphGroupIntrinsic, StandardGlyphItem.GlyphItemPublic); foreach (string s in Builtins.BuiltinList) { completions.Add(new RCompletion(s, s, string.Empty, buildInGlyph)); } } return(completions); }
/// <summary> /// Retrieves names of workspace variables that may be supplying fields to the completion list. /// </summary> /// <remarks> /// For example, in /// dt <- data.table(mtcars) /// dt[c| /// we want to complete for 'cyl'. This expressions can be nested. /// </remarks> private static IEnumerable<string> GetFieldProvidingVariableNames(RCompletionContext context) { var list = new List<string>(); // Traverse AST up to the nearest expression which parent is a scope // (i.e. not nested in other expressions) collecting names of indexed // variables. Example: a[2, b[3, x, | var indexer = context.AstRoot.GetNodeOfTypeFromPosition<Indexer>(context.Position, includeEnd: true); while (indexer != null) { var variable = indexer.RightOperand as Variable; if (variable != null) { list.Add(variable.Name + "$"); } else { break; } var node = (IAstNode)indexer; indexer = null; while (indexer == null && !(node is IScope)) { node = node.Parent; indexer = node as Indexer; } } if (list.Count > 0) { return list; } var name = context.Session.TextView.GetVariableNameBeforeCaret(); return !string.IsNullOrEmpty(name) ? new string[] { name } : Enumerable.Empty<string>(); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); if (!context.IsInNameSpace()) { var infoSource = _snippetInformationSource?.InformationSource; ImageSource keyWordGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphKeyword, StandardGlyphItem.GlyphItemPublic, _shell); foreach (string keyword in Keywords.KeywordList) { bool?isSnippet = infoSource?.IsSnippet(keyword); if (!isSnippet.HasValue || !isSnippet.Value) { completions.Add(new RCompletion(keyword, keyword, string.Empty, keyWordGlyph)); } } ImageSource buildInGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphGroupIntrinsic, StandardGlyphItem.GlyphItemPublic, _shell); foreach (string s in Builtins.BuiltinList) { completions.Add(new RCompletion(s, s, string.Empty, buildInGlyph)); } } return(completions); }
public IReadOnlyCollection<RCompletion> GetEntries(RCompletionContext context) { List<RCompletion> completions = new List<RCompletion>(); ImageSource functionGlyph = _glyphService.GetGlyphThreadSafe(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPublic); ImageSource variableGlyph = _glyphService.GetGlyphThreadSafe(StandardGlyphGroup.GlyphGroupVariable, StandardGlyphItem.GlyphItemPublic); var start = DateTime.Now; _variablesProvider.Initialize(); var names = GetFieldProvidingVariableNames(context); foreach (var variableName in names) { int memberCount = _variablesProvider.GetMemberCount(variableName); IReadOnlyCollection<INamedItemInfo> members = _variablesProvider.GetMembers(variableName, 200); foreach (var v in members) { Debug.Assert(v != null); if (v.Name.Length > 0 && v.Name[0] != '[') { ImageSource glyph = v.ItemType == NamedItemType.Variable ? variableGlyph : functionGlyph; var completion = new RCompletion(v.Name, CompletionUtilities.BacktickName(v.Name), v.Description, glyph); completions.Add(completion); } } } Debug.WriteLine("Variable members fetch: " + (DateTime.Now - start).TotalMilliseconds); return completions; }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); ImageSource functionGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPublic); ImageSource variableGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphGroupVariable, StandardGlyphItem.GlyphItemPublic); string variableName = context.Session.TextView.GetVariableNameBeforeCaret(); VariablesProvider.Initialize(); int memberCount = VariablesProvider.GetMemberCount(variableName); IReadOnlyCollection <INamedItemInfo> members = VariablesProvider.GetMembers(variableName, 200); // Get list of functions in the package foreach (var v in members) { Debug.Assert(v != null); if (v.Name.Length > 0 && v.Name[0] != '[') { ImageSource glyph = v.ItemType == NamedItemType.Variable ? variableGlyph : functionGlyph; var completion = new RCompletion(v.Name, CompletionUtilities.BacktickName(v.Name), v.Description, glyph); completions.Add(completion); } } return(completions); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); ImageSource functionGlyph = _glyphService.GetGlyphThreadSafe(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPublic); ImageSource variableGlyph = _glyphService.GetGlyphThreadSafe(StandardGlyphGroup.GlyphGroupVariable, StandardGlyphItem.GlyphItemPublic); var start = DateTime.Now; _variablesProvider.Initialize(); var names = GetFieldProvidingVariableNames(context); foreach (var variableName in names) { int memberCount = _variablesProvider.GetMemberCount(variableName); IReadOnlyCollection <INamedItemInfo> members = _variablesProvider.GetMembers(variableName, 200); foreach (var v in members) { Debug.Assert(v != null); if (v.Name.Length > 0 && v.Name[0] != '[') { ImageSource glyph = v.ItemType == NamedItemType.Variable ? variableGlyph : functionGlyph; var completion = new RCompletion(v.Name, CompletionUtilities.BacktickName(v.Name), v.Description, glyph); completions.Add(completion); } } } Debug.WriteLine("Variable members fetch: " + (DateTime.Now - start).TotalMilliseconds); return(completions); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); ImageSource functionGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPublic); ImageSource variableGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphGroupVariable, StandardGlyphItem.GlyphItemPublic); var ast = context.AstRoot; // First try simple scope like in 'for(x in 1:10) x|' IScope scope = ast.GetNodeOfTypeFromPosition <SimpleScope>(context.Position, includeEnd: true); // If not found, look for the regular scope scope = scope ?? ast.GetNodeOfTypeFromPosition <IScope>(context.Position); var variables = scope.GetApplicableVariables(context.Position); foreach (var v in variables) { RCompletion completion; RFunction f = v.Value as RFunction; completion = new RCompletion(v.Name, CompletionUtilities.BacktickName(v.Name), string.Empty, f != null ? functionGlyph : variableGlyph); completions.Add(completion); } return(completions); }
/// <summary> /// Retrieves list of packages declared in the file via 'library' statements /// </summary> /// <param name="context"></param> /// <returns></returns> private Task <IEnumerable <IPackageInfo> > GetAllFilePackagesAsync(RCompletionContext context) { IEnumerable <string> loadedPackages = _session?.LoadedPackageNames ?? Enumerable.Empty <string>(); IEnumerable <string> filePackageNames = context.AstRoot.GetFilePackageNames(); IEnumerable <string> allPackageNames = PackageIndex.PreloadedPackages.Union(filePackageNames).Union(loadedPackages); return(_packageIndex.GetPackagesInfoAsync(allPackageNames)); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { ImageSource glyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphLibrary, StandardGlyphItem.GlyphItemPublic, _shell); return(_packageIndex.Packages .Select(p => new RCompletion(p.Name, p.Name, p.Description, glyph)) .ToList()); }
private IEnumerable <IPackageInfo> GetPackages(RCompletionContext context) { if (context.IsInNameSpace()) { return(GetSpecificPackage(context)); } return(GetAllFilePackages(context)); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); ImageSource functionGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphGroupValueType, StandardGlyphItem.GlyphItemPublic); // Safety checks FunctionCall funcCall = context.AstRoot.GetNodeOfTypeFromPosition <FunctionCall>(context.Position); if (funcCall == null || funcCall.OpenBrace == null || funcCall.Arguments == null) { return(completions); } if (context.Position < funcCall.OpenBrace.End || context.Position >= funcCall.SignatureEnd) { return(completions); } // Retrieve parameter positions from the current text buffer snapshot ParameterInfo parametersInfo = SignatureHelp.GetParametersInfoFromBuffer(context.AstRoot, context.TextBuffer.CurrentSnapshot, context.Position); if (parametersInfo == null) { return(completions); } // Get collection of function signatures from documentation (parsed RD file) IFunctionInfo functionInfo = FunctionIndex.GetFunctionInfo(parametersInfo.FunctionName, o => { }, context.Session.TextView); if (functionInfo == null) { return(completions); } // Collect parameter names from all signatures IEnumerable <KeyValuePair <string, IArgumentInfo> > arguments = new Dictionary <string, IArgumentInfo>(); foreach (ISignatureInfo signature in functionInfo.Signatures) { var args = signature.Arguments.ToDictionary(x => x.Name); arguments = arguments.Union(args); } // Add names of arguments that are not yet specified to the completion // list with '=' sign so user can tell them from function names. IEnumerable <string> declaredArguments = funcCall.Arguments.Where(x => x is NamedArgument).Select(x => ((NamedArgument)x).Name); IEnumerable <KeyValuePair <string, IArgumentInfo> > possibleArguments = arguments.Where(x => x.Key != "..." && !declaredArguments.Contains(x.Key)); foreach (KeyValuePair <string, IArgumentInfo> arg in possibleArguments) { string displayText = arg.Key + " ="; string insertionText = arg.Key + " = "; completions.Add(new RCompletion(displayText, insertionText, arg.Value.Description, functionGlyph)); } return(completions); }
public IReadOnlyCollection<RCompletion> GetEntries(RCompletionContext context) { List<RCompletion> completions = new List<RCompletion>(); var infoSource = _snippetInformationSource?.InformationSource; if (!context.IsInNameSpace() && infoSource != null) { foreach (ISnippetInfo info in infoSource.Snippets) { completions.Add(new RCompletion(info.Name, info.Name, info.Description, _snippetGlyph)); } } return completions; }
private IEnumerable <IPackageInfo> GetPackages(RCompletionContext context) { if (context.IsInNameSpace()) { return(GetSpecificPackage(context)); } var t = GetAllFilePackagesAsync(context); t.Wait(_asyncWaitTimeout); return(t.IsCompleted ? t.Result : Enumerable.Empty <IPackageInfo>()); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); ImageSource folderGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphClosedFolder, StandardGlyphItem.GlyphItemPublic); string directory = null; string userDirectory = null; if (_userDirectoryFetchingTask != null) { _userDirectoryFetchingTask.Wait(500); userDirectory = _userDirectoryFetchingTask.IsCompleted ? _userDirectoryFetchingTask.Result : null; userDirectory = userDirectory ?? _cachedUserDirectory; } try { if (!string.IsNullOrEmpty(userDirectory)) { _cachedUserDirectory = userDirectory; directory = Path.Combine(userDirectory, _directory); } else { directory = Path.Combine(RToolsSettings.Current.WorkingDirectory, _directory); } if (Directory.Exists(directory)) { foreach (string dir in Directory.GetDirectories(directory)) { DirectoryInfo di = new DirectoryInfo(dir); if (!di.Attributes.HasFlag(FileAttributes.Hidden) && !di.Attributes.HasFlag(FileAttributes.System)) { string dirName = Path.GetFileName(dir); completions.Add(new RCompletion(dirName, dirName + "/", string.Empty, folderGlyph)); } } foreach (string file in Directory.GetFiles(directory)) { FileInfo di = new FileInfo(file); if (!di.Attributes.HasFlag(FileAttributes.Hidden) && !di.Attributes.HasFlag(FileAttributes.System)) { ImageSource fileGlyph = ImagesProvider?.GetFileIcon(file); string fileName = Path.GetFileName(file); completions.Add(new RCompletion(fileName, fileName, string.Empty, fileGlyph)); } } } } catch (IOException) { } catch (UnauthorizedAccessException) { } return(completions); }
/// <summary> /// Retrieves name of the package in 'package::' statement /// so intellisense can show list of functions available /// in the specific package. /// </summary> private IEnumerable <IPackageInfo> GetSpecificPackage(RCompletionContext context) { List <IPackageInfo> packages = new List <IPackageInfo>(); ITextSnapshot snapshot = context.TextBuffer.CurrentSnapshot; int colons = 0; for (int i = context.Position - 1; i >= 0; i--, colons++) { char ch = snapshot[i]; if (ch != ':') { break; } } if (colons > 1 && colons < 4) { string packageName = string.Empty; int start = 0; int end = context.Position - colons; for (int i = end - 1; i >= 0; i--) { char ch = snapshot[i]; if (char.IsWhiteSpace(ch)) { start = i + 1; break; } } if (start < end) { packageName = snapshot.GetText(Span.FromBounds(start, end)); if (packageName.Length > 0) { if (colons == 3) { context.InternalFunctions = true; } IPackageInfo package = PackageIndex.GetPackageByName(packageName); if (package != null) { packages.Add(package); } } } } return(packages); }
private static bool ShouldProvideCompletions(RCompletionContext context, out FunctionCall funcCall) { // Safety checks funcCall = context.AstRoot.GetNodeOfTypeFromPosition<FunctionCall>(context.Position); if (funcCall == null || funcCall.OpenBrace == null || funcCall.Arguments == null) { return false; } if (context.Position < funcCall.OpenBrace.End || context.Position >= funcCall.SignatureEnd) { return false; } return true; }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); ImageSource glyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphLibrary, StandardGlyphItem.GlyphItemPublic); IEnumerable <IPackageInfo> packages = PackageIndex.Packages; foreach (var packageInfo in packages) { completions.Add(new RCompletion(packageInfo.Name, packageInfo.Name, packageInfo.Description, glyph)); } return(completions); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); var infoSource = _snippetInformationSource?.InformationSource; if (!context.IsInNameSpace() && infoSource != null) { foreach (ISnippetInfo info in infoSource.Snippets) { completions.Add(new RCompletion(info.Name, info.Name, info.Description, _snippetGlyph)); } } return(completions); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { var completions = new List <RCompletion>(); string directory = _enteredDirectory; try { // If we are running async directory fetching, wait a bit _task?.Wait(500); } catch (OperationCanceledException) { } try { // If directory is set, then the async task did complete if (!string.IsNullOrEmpty(_rootDirectory)) { if (_mode == Mode.WorkingDirectory) { directory = Path.Combine(_rootDirectory, _enteredDirectory); } else if (_mode == Mode.UserDirectory) { var subDirectory = _enteredDirectory.Length > 1 ? _enteredDirectory.Substring(2) : _enteredDirectory; directory = Path.Combine(_rootDirectory, subDirectory); } } } catch (ArgumentException) { } try { if (!string.IsNullOrEmpty(directory)) { IEnumerable <RCompletion> entries = null; if (_forceR) { entries = GetRemoteDirectoryItemsAsync(directory).Result; } else if (_workflow.RSession.IsRemote) { var t = GetRemoteDirectoryItemsAsync(directory); entries = t.WaitTimeout(1000); } else { entries = GetLocalDirectoryItems(directory); } completions.AddRange(entries); } } catch (IOException) { } catch (UnauthorizedAccessException) { } catch (ArgumentException) { } catch (TimeoutException) { } return(completions); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); var infoSource = SnippetInformationSource?.InformationSource; if (!context.IsInNameSpace() && infoSource != null) { ImageSource snippetGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphCSharpExpansion, StandardGlyphItem.GlyphItemPublic); foreach (string name in infoSource.SnippetNames) { completions.Add(new RCompletion(name, name, string.Empty, snippetGlyph)); } } return(completions); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); var infoSource = _snippetInformationSource?.InformationSource; if (!context.IsInNameSpace() && infoSource != null) { ImageSource snippetGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphCSharpExpansion, StandardGlyphItem.GlyphItemPublic, _shell); foreach (ISnippetInfo info in infoSource.Snippets) { completions.Add(new RCompletion(info.Name, info.Name, info.Description, snippetGlyph)); } } return(completions); }
/// <summary> /// Retrieves list of packages declared in the file via 'library' statements /// </summary> /// <param name="context"></param> /// <returns></returns> private IEnumerable <IPackageInfo> GetAllFilePackages(RCompletionContext context) { _loadedPackagesProvider?.Initialize(); IEnumerable <string> loadedPackages = _loadedPackagesProvider?.GetPackageNames() ?? Enumerable.Empty <string>(); IEnumerable <string> filePackageNames = context.AstRoot.GetFilePackageNames(); IEnumerable <string> allPackageNames = PackageIndex.PreloadedPackages.Union(filePackageNames).Union(loadedPackages); return(allPackageNames .Select(packageName => GetPackageByName(packageName)) // May be null if user mistyped package name in the library() // statement or package is not installed. .Where(p => p != null) .ToList()); }
private static bool ShouldProvideCompletions(RCompletionContext context, out FunctionCall funcCall) { // Safety checks funcCall = context.AstRoot.GetNodeOfTypeFromPosition <FunctionCall>(context.Position); if (funcCall == null || funcCall.OpenBrace == null || funcCall.Arguments == null) { return(false); } if (context.Position < funcCall.OpenBrace.End || context.Position >= funcCall.SignatureEnd) { return(false); } return(true); }
/// <summary> /// Extracts information on the current function in the completion context, if any. /// </summary> /// <returns></returns> private IFunctionInfo GetFunctionInfo(RCompletionContext context) { // Retrieve parameter positions from the current text buffer snapshot IFunctionInfo functionInfo = null; ParameterInfo parametersInfo = SignatureHelp.GetParametersInfoFromBuffer(context.AstRoot, context.TextBuffer.CurrentSnapshot, context.Position); if (parametersInfo != null) { // User-declared functions take priority functionInfo = context.AstRoot.GetUserFunctionInfo(parametersInfo.FunctionName, context.Position); if (functionInfo == null) { // Get collection of function signatures from documentation (parsed RD file) functionInfo = _functionIndex.GetFunctionInfo(parametersInfo.FunctionName, null, (o, p) => { }, context.Session.TextView); } } return(functionInfo); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); ImageSource folderGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphClosedFolder, StandardGlyphItem.GlyphItemPublic); string currentDir = RToolsSettings.Current.WorkingDirectory; string directory = null; try { string dir = Path.Combine(currentDir, _directory); if (Directory.Exists(dir)) { directory = dir; } } catch (IOException) { } catch (UnauthorizedAccessException) { } catch (ArgumentException) { } if (directory != null) { try { foreach (string dir in Directory.GetDirectories(directory)) { DirectoryInfo di = new DirectoryInfo(dir); if (!di.Attributes.HasFlag(FileAttributes.Hidden) && !di.Attributes.HasFlag(FileAttributes.System)) { string dirName = Path.GetFileName(dir); completions.Add(new RCompletion(dirName, dirName + "/", string.Empty, folderGlyph)); } } foreach (string file in Directory.GetFiles(directory)) { FileInfo di = new FileInfo(file); if (!di.Attributes.HasFlag(FileAttributes.Hidden) && !di.Attributes.HasFlag(FileAttributes.System)) { ImageSource fileGlyph = ImagesProvider?.GetFileIcon(file); string fileName = Path.GetFileName(file); completions.Add(new RCompletion(fileName, fileName, string.Empty, fileGlyph)); } } } catch (IOException) { } catch (UnauthorizedAccessException) { } } return(completions); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); FunctionCall funcCall; var functionGlyph = _imageService.GetImage(ImageType.ValueType) as ImageSource; // Safety checks if (!ShouldProvideCompletions(context, out funcCall)) { return(completions); } // Get collection of function signatures from documentation (parsed RD file) IFunctionInfo functionInfo = GetFunctionInfo(context); if (functionInfo == null) { return(completions); } // Collect parameter names from all signatures IEnumerable <KeyValuePair <string, IArgumentInfo> > arguments = new Dictionary <string, IArgumentInfo>(); foreach (ISignatureInfo signature in functionInfo.Signatures) { var args = signature.Arguments.ToDictionary(x => x.Name); arguments = arguments.Union(args); } // Add names of arguments that are not yet specified to the completion // list with '=' sign so user can tell them from function names. IEnumerable <string> declaredArguments = funcCall.Arguments.Where(x => x is NamedArgument).Select(x => ((NamedArgument)x).Name); var possibleArguments = arguments.Where(x => !x.Key.EqualsOrdinal("...") && !declaredArguments.Contains(x.Key, StringComparer.OrdinalIgnoreCase)); foreach (var arg in possibleArguments) { string displayText = arg.Key + (_settings.FormatOptions.SpacesAroundEquals ? " =" : "="); string insertionText = arg.Key + (_settings.FormatOptions.SpacesAroundEquals ? " = " : "="); completions.Add(new RCompletion(displayText, insertionText, arg.Value.Description, functionGlyph)); } return(completions); }
public IReadOnlyCollection<RCompletion> GetEntries(RCompletionContext context) { List<RCompletion> completions = new List<RCompletion>(); var ast = context.AstRoot; // First try simple scope like in 'for(x in 1:10) x|' IScope scope = ast.GetNodeOfTypeFromPosition<SimpleScope>(context.Position, includeEnd: true); // If not found, look for the regular scope scope = scope ?? ast.GetNodeOfTypeFromPosition<IScope>(context.Position); var variables = scope.GetApplicableVariables(context.Position); foreach (var v in variables) { RCompletion completion; RFunction f = v.Value as RFunction; completion = new RCompletion(v.Name, CompletionUtilities.BacktickName(v.Name), string.Empty, f != null ? _functionGlyph : _variableGlyph); completions.Add(completion); } return completions; }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); string directory = null; string userDirectory = null; if (_userDirectoryFetchingTask != null) { userDirectory = _userDirectoryFetchingTask.WaitTimeout(500); userDirectory = userDirectory ?? _cachedUserDirectory; } try { if (!string.IsNullOrEmpty(userDirectory)) { _cachedUserDirectory = userDirectory; directory = Path.Combine(userDirectory, _directory); } else { directory = _directory; } if (!string.IsNullOrEmpty(directory)) { IEnumerable <RCompletion> entries = null; if (_forceR || _workflow.RSession.IsRemote) { var t = GetRemoteDirectoryItemsAsync(directory); entries = t.WaitTimeout(_forceR ? 5000 : 1000); } else { entries = GetLocalDirectoryItems(directory); } completions.AddRange(entries); } } catch (IOException) { } catch (UnauthorizedAccessException) { } return(completions); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); ImageSource functionGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPublic, _shell); ImageSource constantGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphGroupConstant, StandardGlyphItem.GlyphItemPublic, _shell); ImageSource snippetGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphCSharpExpansion, StandardGlyphItem.GlyphItemPublic, _shell); var infoSource = _snippetInformationSource?.InformationSource; // TODO: this is different in the console window where // packages may have been loaded from the command line. // We need an extensibility point here. IEnumerable <IPackageInfo> packages = GetPackages(context); // Get list of functions in the package foreach (IPackageInfo pkg in packages) { Debug.Assert(pkg != null); IEnumerable <INamedItemInfo> functions = pkg.Functions; if (functions != null) { foreach (INamedItemInfo function in functions) { bool isSnippet = false; // Snippets are suppressed if user typed namespace if (!context.IsInNameSpace() && infoSource != null) { isSnippet = infoSource.IsSnippet(function.Name); } if (!isSnippet) { ImageSource glyph = function.ItemType == NamedItemType.Constant ? constantGlyph : functionGlyph; var completion = new RFunctionCompletion(function.Name, CompletionUtilities.BacktickName(function.Name), function.Description, glyph, _functionIndex, context.Session); completions.Add(completion); } } } } return(completions); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); ImageSource functionGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPublic); ImageSource variableGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphGroupVariable, StandardGlyphItem.GlyphItemPublic); var ast = context.AstRoot; var scope = ast.GetNodeOfTypeFromPosition <IScope>(context.Position); var variables = scope.GetApplicableVariables(context.Position); foreach (var v in variables) { RCompletion completion; RFunction f = v.Value as RFunction; completion = new RCompletion(v.Name, CompletionUtilities.BacktickName(v.Name), string.Empty, f != null ? functionGlyph : variableGlyph); completions.Add(completion); } return(completions); }
/// <summary> /// Retrieves names of workspace variables that may be supplying fields to the completion list. /// </summary> /// <remarks> /// For example, in /// dt <- data.table(mtcars) /// dt[c| /// we want to complete for 'cyl'. This expressions can be nested. /// </remarks> private static IEnumerable <string> GetFieldProvidingVariableNames(RCompletionContext context) { var list = new List <string>(); // Traverse AST up to the nearest expression which parent is a scope // (i.e. not nested in other expressions) collecting names of indexed // variables. Example: a[2, b[3, x, | var indexer = context.AstRoot.GetNodeOfTypeFromPosition <Indexer>(context.Position, includeEnd: true); while (indexer != null) { var variable = indexer.RightOperand as Variable; if (variable != null) { list.Add(variable.Name + "$"); } else { break; } var node = (IAstNode)indexer; indexer = null; while (indexer == null && !(node is IScope)) { node = node.Parent; indexer = node as Indexer; } } if (list.Count > 0) { return(list); } var name = context.Session.TextView.GetVariableNameBeforeCaret(); return(!string.IsNullOrEmpty(name) ? new string[] { name } : Enumerable.Empty <string>()); }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { List <RCompletion> completions = new List <RCompletion>(); ImageSource functionGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphGroupMethod, StandardGlyphItem.GlyphItemPublic); ImageSource variableGlyph = GlyphService.GetGlyph(StandardGlyphGroup.GlyphGroupVariable, StandardGlyphItem.GlyphItemPublic); Selector selector = Selector.Dollar; string variableName = RCompletionContext.GetVariableName(context.Session.TextView, context.TextBuffer.CurrentSnapshot); if (variableName.IndexOfAny(new char[] { '$', '@' }) < 0) { variableName = string.Empty; selector = Selector.None; } else if (variableName.EndsWith("@", StringComparison.Ordinal)) { selector = Selector.At; } VariablesProvider.Initialize(); int memberCount = VariablesProvider.GetMemberCount(variableName); IReadOnlyCollection <INamedItemInfo> members = VariablesProvider.GetMembers(variableName, 200); var filteredList = FilterList(members, selector); // Get list of functions in the package foreach (INamedItemInfo v in filteredList) { Debug.Assert(v != null); if (v.Name.Length > 0 && v.Name[0] != '[') { ImageSource glyph = v.ItemType == NamedItemType.Variable ? variableGlyph : functionGlyph; var completion = new RCompletion(v.Name, CompletionUtilities.BacktickName(v.Name), v.Description, glyph); completions.Add(completion); } } return(completions); }
/// <summary> /// Retrieves list of packages declared in the file via 'library' statements /// </summary> /// <param name="context"></param> /// <returns></returns> private IEnumerable <IPackageInfo> GetAllFilePackages(RCompletionContext context) { List <IPackageInfo> packages = new List <IPackageInfo>(); LoadedPackagesProvider?.Initialize(); IEnumerable <string> loadedPackages = LoadedPackagesProvider?.GetPackageNames() ?? Enumerable.Empty <string>(); IEnumerable <string> filePackageNames = context.AstRoot.GetFilePackageNames(); IEnumerable <string> allPackageNames = Enumerable.Union(_preloadPackages, Enumerable.Union(filePackageNames, loadedPackages)); foreach (string packageName in allPackageNames) { IPackageInfo p = PackageIndex.GetPackageByName(packageName); // May be null if user mistyped package name in the library() // statement or package is not installed. if (p != null) { packages.Add(p); } } return(packages); }
public IReadOnlyCollection<RCompletion> GetEntries(RCompletionContext context) { List<RCompletion> completions = new List<RCompletion>(); FunctionCall funcCall; ImageSource functionGlyph = _glyphService.GetGlyphThreadSafe(StandardGlyphGroup.GlyphGroupValueType, StandardGlyphItem.GlyphItemPublic); // Safety checks if (!ShouldProvideCompletions(context, out funcCall)) { return completions; } // Get collection of function signatures from documentation (parsed RD file) IFunctionInfo functionInfo = GetFunctionInfo(context); if (functionInfo == null) { return completions; } // Collect parameter names from all signatures IEnumerable<KeyValuePair<string, IArgumentInfo>> arguments = new Dictionary<string, IArgumentInfo>(); foreach (ISignatureInfo signature in functionInfo.Signatures) { var args = signature.Arguments.ToDictionary(x => x.Name); arguments = arguments.Union(args); } // Add names of arguments that are not yet specified to the completion // list with '=' sign so user can tell them from function names. IEnumerable<string> declaredArguments = funcCall.Arguments.Where(x => x is NamedArgument).Select(x => ((NamedArgument)x).Name); var possibleArguments = arguments.Where(x => !x.Key.EqualsOrdinal("...") && !declaredArguments.Contains(x.Key, StringComparer.OrdinalIgnoreCase)); foreach (var arg in possibleArguments) { string displayText = arg.Key + " ="; string insertionText = arg.Key + " = "; completions.Add(new RCompletion(displayText, insertionText, arg.Value.Description, functionGlyph)); } return completions; }
public IReadOnlyCollection<RCompletion> GetEntries(RCompletionContext context) { List<RCompletion> completions = new List<RCompletion>(); if (!context.IsInNameSpace()) { var infoSource = _snippetInformationSource?.InformationSource; ImageSource keyWordGlyph = _glyphService.GetGlyphThreadSafe(StandardGlyphGroup.GlyphKeyword, StandardGlyphItem.GlyphItemPublic); // Union with constants like TRUE and other common things var keywords = Keywords.KeywordList.Concat(Logicals.LogicalsList).Concat(Constants.ConstantsList); foreach (string keyword in keywords) { bool? isSnippet = infoSource?.IsSnippet(keyword); if (!isSnippet.HasValue || !isSnippet.Value) { completions.Add(new RCompletion(keyword, keyword, string.Empty, keyWordGlyph)); } } ImageSource buildInGlyph = _glyphService.GetGlyphThreadSafe(StandardGlyphGroup.GlyphGroupIntrinsic, StandardGlyphItem.GlyphItemPublic); foreach (string s in Builtins.BuiltinList) { completions.Add(new RCompletion(s, s, string.Empty, buildInGlyph)); } } return completions; }
public IReadOnlyCollection <RCompletion> GetEntries(RCompletionContext context) { return(_packageIndex.Packages .Select(p => new RCompletion(p.Name, p.Name, p.Description, _glyph)) .ToList()); }
/// <summary> /// Extracts information on the current function in the completion context, if any. /// </summary> /// <returns></returns> private IFunctionInfo GetFunctionInfo(RCompletionContext context) { // Retrieve parameter positions from the current text buffer snapshot IFunctionInfo functionInfo = null; ParameterInfo parametersInfo = SignatureHelp.GetParametersInfoFromBuffer(context.AstRoot, context.TextBuffer.CurrentSnapshot, context.Position); if (parametersInfo != null) { // User-declared functions take priority functionInfo = context.AstRoot.GetUserFunctionInfo(parametersInfo.FunctionName, context.Position); if (functionInfo == null) { // Get collection of function signatures from documentation (parsed RD file) functionInfo = _functionIndex.GetFunctionInfo(parametersInfo.FunctionName, null, (o, p) => { }, context.Session.TextView); } } return functionInfo; }
/// <summary> /// Provides list of completion entries for a given location in the AST. /// </summary> /// <param name="tree">Document tree</param> /// <param name="position">Caret position in the document</param> /// <param name="autoShownCompletion">True if completion is forced (like when typing Ctrl+Space)</param> /// <returns>List of completion entries for a given location in the AST</returns> public static IReadOnlyCollection <IRCompletionListProvider> GetCompletionForLocation(RCompletionContext context, bool autoShownCompletion) { List <IRCompletionListProvider> providers = new List <IRCompletionListProvider>(); if (context.AstRoot.Comments.Contains(context.Position)) { // No completion in comments return(providers); } // First check file completion - it happens inside strings string directory; if (CanShowFileCompletion(context.AstRoot, context.Position, out directory)) { if (!string.IsNullOrEmpty(directory)) { providers.Add(new FilesCompletionProvider(directory)); } return(providers); } // Special case for unterminated strings var tokenNode = context.AstRoot.GetNodeOfTypeFromPosition <TokenNode>(context.Position, includeEnd: true); if (tokenNode != null && context.Position == tokenNode.End && tokenNode.Token.TokenType == RTokenType.String) { var snapshot = context.TextBuffer.CurrentSnapshot; // String token at least has opening quote char quote = snapshot[tokenNode.Start]; if (tokenNode.Length == 1 || quote != snapshot[tokenNode.End - 1]) { // No completion at the end of underminated string return(providers); } } // Now check if position is inside a string or a number and if so, suppress the completion list tokenNode = context.AstRoot.GetNodeOfTypeFromPosition <TokenNode>(context.Position); if (tokenNode != null && (tokenNode.Token.TokenType == RTokenType.String || tokenNode.Token.TokenType == RTokenType.Number || tokenNode.Token.TokenType == RTokenType.Complex)) { // No completion in strings or numbers return(providers); } // We do not want automatic completion inside identifiers such as in a middle // of ab|c or in `abc|`. Manually invoked completion is fine. if (tokenNode != null && tokenNode.Token.TokenType == RTokenType.Identifier && autoShownCompletion) { return(providers); } // Check end of numeric token like 2.- dot should not be bringing completion tokenNode = context.AstRoot.GetNodeOfTypeFromPosition <TokenNode>(Math.Max(0, context.Position - 1)); if (tokenNode != null && (tokenNode.Token.TokenType == RTokenType.Number || tokenNode.Token.TokenType == RTokenType.Complex)) { // No completion in numbers return(providers); } if (IsInFunctionArgumentName <FunctionDefinition>(context.AstRoot, context.Position)) { // No completion in function definition argument names return(providers); } if (IsInObjectMemberName(context.AstRoot.TextProvider, context.Position)) { providers.Add(new WorkspaceVariableCompletionProvider()); return(providers); } if (IsPackageListCompletion(context.TextBuffer, context.Position)) { providers.Add(new PackagesCompletionProvider()); } else { if (IsInFunctionArgumentName <FunctionCall>(context.AstRoot, context.Position)) { providers.Add(new ParameterNameCompletionProvider()); } foreach (var p in CompletionProviders) { providers.Add(p.Value); } if (!context.IsInNameSpace()) { providers.Add(new PackagesCompletionProvider()); } } if (!context.IsInNameSpace()) { providers.Add(new WorkspaceVariableCompletionProvider()); } return(providers); }
internal void PopulateCompletionList(int position, ICompletionSession session, IList<CompletionSet> completionSets, AstRoot ast) { RCompletionContext context = new RCompletionContext(session, _textBuffer, ast, position); bool autoShownCompletion = true; if (session.TextView.Properties.ContainsProperty(CompletionController.AutoShownCompletion)) autoShownCompletion = session.TextView.Properties.GetProperty<bool>(CompletionController.AutoShownCompletion); IReadOnlyCollection<IRCompletionListProvider> providers = RCompletionEngine.GetCompletionForLocation(context, autoShownCompletion); Span applicableSpan = GetApplicableSpan(position, session); ITrackingSpan trackingSpan = _textBuffer.CurrentSnapshot.CreateTrackingSpan(applicableSpan, SpanTrackingMode.EdgeInclusive); List<RCompletion> completions = new List<RCompletion>(); bool sort = true; foreach (IRCompletionListProvider provider in providers) { IReadOnlyCollection<RCompletion> entries = provider.GetEntries(context); Debug.Assert(entries != null); if (entries.Count > 0) { completions.AddRange(entries); } sort &= provider.AllowSorting; } if (sort) { completions.Sort(RCompletion.Compare); completions.RemoveDuplicates(); } CompletionSet completionSet = new RCompletionSet(_textBuffer, trackingSpan, completions); completionSets.Add(completionSet); }
/// <summary> /// Retrieves name of the package in 'package::' statement /// so intellisense can show list of functions available /// in the specific package. /// </summary> private IEnumerable<IPackageInfo> GetSpecificPackage(RCompletionContext context) { List<IPackageInfo> packages = new List<IPackageInfo>(); ITextSnapshot snapshot = context.TextBuffer.CurrentSnapshot; int colons = 0; for (int i = context.Position - 1; i >= 0; i--, colons++) { char ch = snapshot[i]; if (ch != ':') { break; } } if (colons > 1 && colons < 4) { string packageName = string.Empty; int start = 0; int end = context.Position - colons; for (int i = end - 1; i >= 0; i--) { char ch = snapshot[i]; if (!RTokenizer.IsIdentifierCharacter(ch)) { start = i + 1; break; } } if (start < end) { packageName = snapshot.GetText(Span.FromBounds(start, end)); if (packageName.Length > 0) { context.InternalFunctions = colons == 3; var package = GetPackageByName(packageName); if (package != null) { packages.Add(package); } } } } return packages; }
/// <summary> /// Retrieves list of packages declared in the file via 'library' statements /// </summary> /// <param name="context"></param> /// <returns></returns> private Task<IEnumerable<IPackageInfo>> GetAllFilePackagesAsync(RCompletionContext context) { _loadedPackagesProvider?.Initialize(); IEnumerable<string> loadedPackages = _loadedPackagesProvider?.GetPackageNames() ?? Enumerable.Empty<string>(); IEnumerable<string> filePackageNames = context.AstRoot.GetFilePackageNames(); IEnumerable<string> allPackageNames = PackageIndex.PreloadedPackages.Union(filePackageNames).Union(loadedPackages); return _packageIndex.GetPackagesInfoAsync(allPackageNames); }
private IEnumerable<IPackageInfo> GetPackages(RCompletionContext context) { if (context.IsInNameSpace()) { return GetSpecificPackage(context); } var t = GetAllFilePackagesAsync(context); t.Wait(_asyncWaitTimeout); return t.IsCompleted ? t.Result : Enumerable.Empty<IPackageInfo>(); }
public IReadOnlyCollection<RCompletion> GetEntries(RCompletionContext context) { return _packageIndex.Packages .Select(p => new RCompletion(p.Name, p.Name, p.Description, _glyph)) .ToList(); }