/// <summary> /// Gets the CommandInfo instance for a command with a particular name. /// </summary> /// <param name="commandName">The name of the command.</param> /// <param name="powerShellContext">The PowerShellContext to use for running Get-Command.</param> /// <returns>A CommandInfo object with details about the specified command.</returns> public static async Task <CommandInfo> GetCommandInfo( string commandName, PowerShellContext powerShellContext) { Validate.IsNotNull(nameof(commandName), commandName); // Make sure the command's noun isn't blacklisted. This is // currently necessary to make sure that Get-Command doesn't // load PackageManagement or PowerShellGet because they cause // a major slowdown in IntelliSense. var commandParts = commandName.Split('-'); if (commandParts.Length == 2 && NounBlackList.Contains(commandParts[1])) { return(null); } PSCommand command = new PSCommand(); command.AddCommand(@"Microsoft.PowerShell.Core\Get-Command"); command.AddArgument(commandName); command.AddParameter("ErrorAction", "Ignore"); return ((await powerShellContext .ExecuteCommand <PSObject>(command, false, false)) .Select(o => o.BaseObject) .OfType <CommandInfo>() .FirstOrDefault()); }
/// <summary> /// Gets the CommandInfo instance for a command with a particular name. /// </summary> /// <param name="commandName">The name of the command.</param> /// <param name="powerShellContext">The PowerShellContext to use for running Get-Command.</param> /// <returns>A CommandInfo object with details about the specified command.</returns> public static async Task <CommandInfo> GetCommandInfo( string commandName, PowerShellContext powerShellContext) { PSCommand command = new PSCommand(); command.AddCommand(@"Microsoft.PowerShell.Core\Get-Command"); command.AddArgument(commandName); var results = await powerShellContext.ExecuteCommand <CommandInfo>(command, false, false); return(results.FirstOrDefault()); }
/// <summary> /// Gets the CommandInfo instance for a command with a particular name. /// </summary> /// <param name="commandName">The name of the command.</param> /// <param name="powerShellContext">The PowerShellContext to use for running Get-Command.</param> /// <returns>A CommandInfo object with details about the specified command.</returns> public static async Task <CommandInfo> GetCommandInfo( string commandName, PowerShellContext powerShellContext) { PSCommand command = new PSCommand(); command.AddCommand(@"Microsoft.PowerShell.Core\Get-Command"); command.AddArgument(commandName); return ((await powerShellContext .ExecuteCommand <PSObject>(command, false, false)) .Select(o => o.BaseObject) .OfType <CommandInfo>() .FirstOrDefault()); }
/// <summary> /// Gets the command's "Synopsis" documentation section. /// </summary> /// <param name="commandInfo">The CommandInfo instance for the command.</param> /// <param name="powerShellContext">The PowerShellContext to use for getting command documentation.</param> /// <returns></returns> public static async Task <string> GetCommandSynopsis( CommandInfo commandInfo, PowerShellContext powerShellContext) { string synopsisString = string.Empty; PSObject helpObject = null; if (commandInfo != null && (commandInfo.CommandType == CommandTypes.Cmdlet || commandInfo.CommandType == CommandTypes.Function || commandInfo.CommandType == CommandTypes.Filter)) { PSCommand command = new PSCommand(); command.AddCommand(@"Microsoft.PowerShell.Core\Get-Help"); command.AddArgument(commandInfo); command.AddParameter("ErrorAction", "Ignore"); var results = await powerShellContext.ExecuteCommand <PSObject>(command, false, false); helpObject = results.FirstOrDefault(); if (helpObject != null) { // Extract the synopsis string from the object synopsisString = (string)helpObject.Properties["synopsis"].Value ?? string.Empty; // Ignore the placeholder value for this field if (string.Equals(synopsisString, "SHORT DESCRIPTION", System.StringComparison.CurrentCultureIgnoreCase)) { synopsisString = string.Empty; } } } return(synopsisString); }
/// <summary> /// Gets completions for the symbol found in the Ast at /// the given file offset. /// </summary> /// <param name="scriptAst"> /// The Ast which will be traversed to find a completable symbol. /// </param> /// <param name="currentTokens"> /// The array of tokens corresponding to the scriptAst parameter. /// </param> /// <param name="fileOffset"> /// The 1-based file offset at which a symbol will be located. /// </param> /// <param name="powerShellContext"> /// The PowerShellContext to use for gathering completions. /// </param> /// <param name="logger">An ILogger implementation used for writing log messages.</param> /// <param name="cancellationToken"> /// A CancellationToken to cancel completion requests. /// </param> /// <returns> /// A CommandCompletion instance that contains completions for the /// symbol at the given offset. /// </returns> static public async Task <CommandCompletion> GetCompletions( Ast scriptAst, Token[] currentTokens, int fileOffset, PowerShellContext powerShellContext, ILogger logger, CancellationToken cancellationToken) { var type = scriptAst.Extent.StartScriptPosition.GetType(); var method = #if CoreCLR type.GetMethod( "CloneWithNewOffset", BindingFlags.Instance | BindingFlags.NonPublic); #else type.GetMethod( "CloneWithNewOffset", BindingFlags.Instance | BindingFlags.NonPublic, null, new[] { typeof(int) }, null); #endif IScriptPosition cursorPosition = (IScriptPosition)method.Invoke( scriptAst.Extent.StartScriptPosition, new object[] { fileOffset }); logger.Write( LogLevel.Verbose, string.Format( "Getting completions at offset {0} (line: {1}, column: {2})", fileOffset, cursorPosition.LineNumber, cursorPosition.ColumnNumber)); CommandCompletion commandCompletion = null; if (powerShellContext.IsDebuggerStopped) { PSCommand command = new PSCommand(); command.AddCommand("TabExpansion2"); command.AddParameter("Ast", scriptAst); command.AddParameter("Tokens", currentTokens); command.AddParameter("PositionOfCursor", cursorPosition); command.AddParameter("Options", null); PSObject outputObject = (await powerShellContext.ExecuteCommand <PSObject>(command, false, false)) .FirstOrDefault(); if (outputObject != null) { ErrorRecord errorRecord = outputObject.BaseObject as ErrorRecord; if (errorRecord != null) { logger.WriteException( "Encountered an error while invoking TabExpansion2 in the debugger", errorRecord.Exception); } else { commandCompletion = outputObject.BaseObject as CommandCompletion; } } } else if (powerShellContext.CurrentRunspace.Runspace.RunspaceAvailability == RunspaceAvailability.Available) { using (RunspaceHandle runspaceHandle = await powerShellContext.GetRunspaceHandle(cancellationToken)) using (PowerShell powerShell = PowerShell.Create()) { powerShell.Runspace = runspaceHandle.Runspace; Stopwatch stopwatch = new Stopwatch(); stopwatch.Start(); commandCompletion = CommandCompletion.CompleteInput( scriptAst, currentTokens, cursorPosition, null, powerShell); stopwatch.Stop(); logger.Write(LogLevel.Verbose, $"IntelliSense completed in {stopwatch.ElapsedMilliseconds}ms."); } } return(commandCompletion); }