public/Invoke-Vim.ps1
<# .SYNOPSIS Start vim .DESCRIPTION Locate and start a vim or gvim excutable passing arguments that are not used by Invoke-Vim. By default, start vim in the current shell. .PARAMETER Arguments Arguments to pass to Vim executable. Defaults to the remaining parameters on the command line. .PARAMETER Path Path to working directory. Defaults to current directory. .PARAMETER VimPath Path to specify vim excutable. E.g., 'vim' usually resolves to vim.bat, which is read to locate vim.exe. The path to the excecutable may be specified. .PARAMETER g Start gvim instead of vim. .PARAMETER NoWindow Do not open a window. Similar to start hidden. .PARAMETER RedirectStandardError Capture stderr stream. .PARAMETER RedirectStandardOutput Capture stdout stream. .PARAMETER Raw Return a PSCustomObject. Defaults to Write-Output and Write-Error, respectively. [pscustomobject]@{ Command = $Command # Invocation string used to start Vim. Output = $stdout Error = $stderr Defaults to return stdout and stderr steams. .PARAMETER Quiet Discard stdout and stderr streams. .PARAMETER UseShellExecute True if the shell should be used when starting the process; false if the process should be created directly from the executable file. The default is true on .NET Framework apps and false on .NET Core apps. Setting this property to false enables you to redirect input, output, and error streams. The word "shell" in this context (UseShellExecute) refers to a graphical shell (similar to the Windows shell) rather than command shells (for example, bash or sh) and lets users launch graphical applications or open documents. See RELATED LINKS for more information. .PARAMETER Split Character used to split stderr and stdout. Defaults to newline character. .EXAMPLE PS C:\> $SwapFile = Invoke-Vim -Raw -RedirectStandardError -RedirectStandardOutput -L PS C:\> $SwapFile.Error Capture stderr from `vim -L` without updating $Error. .LINK Capturing standard out and error with Start-Process (http://stackoverflow.com/questions/8761888/powershell-capturing-standard-out-and-error-with-start-process) .LINK ProcessStartInfo.UseShellExecute Property (https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.useshellexecute?view=netcore-3.1) .LINK System.Diagnostics.ProcessStartInfo (https://docs.microsoft.com/en-us/dotnet/api/system.diagnostics.processstartinfo.useshellexecute?view=netcore-3.1) #> function Invoke-Vim { [cmdletbinding(DefaultParameterSetName = 'UseShellExecute')] param( [Parameter(Position = 0, ValueFromRemainingArguments = $true)] $Arguments , [string]$Path = $PWD.Path , [string]$VimPath = 'vim' , [Parameter(ParameterSetName = 'Gvim')] [switch]$g , [Parameter(ParameterSetName = 'RedirectIO')] [switch]$CreateNoWindow = $false , [Parameter(ParameterSetName = 'RedirectIO')] [switch]$RedirectStandardError = $false , [Parameter(ParameterSetName = 'RedirectIO')] [switch]$RedirectStandardOutput = $false , [Parameter(ParameterSetName = 'RedirectIO')] [switch]$Raw , [Parameter(ParameterSetName = 'RedirectIO')] [switch]$Quiet , [Parameter(ParameterSetName = 'Gvim')] [Parameter(ParameterSetName = 'UseShellExecute')] [switch]$UseShellExecute = $false , [Parameter(ParameterSetName = 'RedirectIO')] [Parameter(ParameterSetName = 'UseShellExecute')] [string]$Split = "`n" ) if ($PSBoundParameters.ContainsKey('g')) { $VimExecutable = 'gvim.exe' if ( $PSBoundParameters.ContainsKey('Arguments') -and ($PSBoundParameters['Arguments'] -match '--nofork') ) { $NoFork = $true } else { $NoFork = $false } } else { $VimExecutable = 'vim.exe' $NoFork = $true } if ( $VimCommand = Get-Command -CommandType Application -Name $VimPath ` -ErrorAction Ignore ) { if ($VimCommand.Extension -eq '.bat') { $Pattern = @( '^set VIM_EXE_DIR=', '^"%VIM_EXE_DIR%\\[a-zA-Z].*\.exe') $VimCommand = $VimCommand | Get-Content | Select-String -Pattern $Pattern $Env:VIM_EXE_DIR = ($VimCommand -split '=')[1] $VimVersion = Split-Path $Env:VIM_EXE_DIR -Leaf if ($Env:VIM -and (Test-Path "$Env:VIM\$VimVersion\$VimExecutable")) { $Env:VIM_EXE_DIR = "$Env:VIM\$VimVersion" } } } elseif ($Env:VIMRUNTIME -and (Test-Path "$Env:VIMRUNTIME\$VimExecutable")) { Write-Warning "Could not find Vim at VimPath [$VimPath]" } else { $Exception = "Could not find Vim at VimPath [$VimPath] or " $Exception += 'in $Env:VIMRUNTIME.' throw "$Exception" } if ($Env:VIMRUNTIME -and (Test-Path "$Env:VIMRUNTIME\$VimExecutable")) { $Env:VIM_EXE_DIR = "$Env:VIMRUNTIME" } $VimCommand = Join-Path $Env:VIM_EXE_DIR $VimExecutable $Path = (Resolve-Path $Path).Path # http://stackoverflow.com/questions/8761888/powershell-capturing-standard-out-and-error-with-start-process $pinfo = New-Object System.Diagnostics.ProcessStartInfo $pinfo.FileName = $VimCommand $Command = $VimCommand $pinfo.CreateNoWindow = $NoWindow $pinfo.RedirectStandardError = $RedirectStandardError $pinfo.RedirectStandardOutput = $RedirectStandardOutput $pinfo.UseShellExecute = $UseShellExecute $pinfo.WorkingDirectory = $Path if ($PSBoundParameters.ContainsKey('Arguments')) { $pinfo.Arguments = $Arguments $Command = "$Command $Arguments" } $p = New-Object System.Diagnostics.Process $p.StartInfo = $pinfo $null = $p.Start() if ( $NoFork ) { $p.WaitForExit() } if ($Quiet) { return } else { #there was a newline in output... if ($null -ne $p.StandardOutput -and ( $stdout = $p.StandardOutput.ReadToEnd()) ) { if ($split) { $stdout = $stdout -split "`n" | Where-Object { $_ } } $stdout = foreach ($item in @($stdout)) { # $item.trim() $item } } if ($null -ne $p.StandardError -and ( $stderr = $p.StandardError.ReadToEnd()) ) { if ($split) { $stderr = $stderr -split "`n" | Where-Object { $_ } } $stderr = foreach ($item in @($stderr)) { # $item.trim() $item } } if ($Raw) { [pscustomobject]@{ Command = $Command Output = $stdout Error = $stderr } } else { if ($stdout) { $stdout } if ($stderr) { foreach ($errLine in $stderr) { # Write-Error $errLine.trim() Write-Error $errLine } } } } } |