completions.ps1
@('npm', 'npm.cmd') | ForEach-Object { Register-ArgumentCompleter -Native -CommandName $_ -ScriptBlock { param($wordToComplete, $commandAst, $cursorPosition) # Search for a file "package.json" in the current directory or parent directories function Get-PackageJsonPath { [string]$packageJsonPath=$pwd; while ($packageJsonPath.Length -gt 0 -and -not (Test-Path "$packageJsonPath\package.json")) { # No package.json found. Look in parent directory next $packageJsonPath=Split-Path $packageJsonPath -Parent } return $packageJsonPath } function Get-PackageJsonScripts { param ( [Parameter(Mandatory=$true, ValueFromPipeline=$true)] [string] $packageJsonPath, [string] $scriptFilter ) if ($packageJsonPath.Length -gt 0) { $packageJson="$packageJsonPath/package.json" $packageJsonContent = Get-Content $packageJson | ConvertFrom-Json # Do we have a "script" section? if ($packageJsonContent.scripts -ne $null) { $allScripts=$packageJsonContent.scripts | Get-Member -MemberType NoteProperty | where Name -like "$scriptFilter" | select -ExpandProperty Name $result=$allScripts | ForEach-Object { # return the script name and the script text. The script text is passed as tooltip later. [tuple]::Create($_, $packageJsonContent.scripts.$_) } return $result } } return @(); } if ($commandAst.ToString() -match "npm(.cmd)?\s+run(-script)?\s*") { $allScripts = Get-PackageJsonPath | Get-PackageJsonScripts -scriptFilter "$wordToComplete*" $result=$allScripts | ForEach-Object { # item1 is the script name, item2 is the script text (passed as tooltip) [System.Management.Automation.CompletionResult]::new($_.item1, $_.item1, 'ParameterValue', $_.item2) } return $result; } . $PSScriptRoot\commands.ps1 $cmds | Where-Object { $_ -like "$wordToComplete*" } | Sort-Object | ForEach-Object { [System.Management.Automation.CompletionResult]::new($_, $_, 'ParameterValue', $_) } } } |