Last active
March 23, 2021 01:39
-
-
Save Konfekt/32e8e7ed0a77a3b6967fac0292493106 to your computer and use it in GitHub Desktop.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
param( | |
[parameter(Position=0,Mandatory=$false)][string]$PSReadlineChordProvider = 'Ctrl+t', | |
[parameter(Position=1,Mandatory=$false)][string]$PSReadlineChordReverseHistory = 'Ctrl+r', | |
[parameter(Position=1,Mandatory=$false)][string]$PSReadlineChordSetLocation = 'Alt+c', | |
[parameter(Position=1,Mandatory=$false)][string]$PSReadlineChordReverseHistoryArgs = 'Alt+a') | |
function Invoke-FuzzyEdit() { | |
param($Directory=$null) | |
$files = @() | |
try { | |
if ($Directory) { | |
$prevDir = $PWD.Path | |
cd $Directory | |
} | |
Select-Poco | ForEach-Object { $files += """$_""" } | |
} catch { | |
} | |
finally { | |
if ($prevDir) { | |
cd $prevDir | |
} | |
} | |
if ($null -ne $files) { | |
Invoke-Expression -Command ("$env:EDITOR {0}" -f ($files -join ' ')) | |
} | |
} | |
Set-Alias "fe" Invoke-FuzzyEdit | |
function Invoke-FuzzyHistory() { | |
$result = Get-History | ForEach-Object { $_.CommandLine } | Select-Poco --layout=bottom-up | |
if ($null -ne $result) { | |
Write-Output "Invoking '$result'`n" | |
Invoke-Expression "$result" -Verbose | |
} | |
} | |
Set-Alias "fh" Invoke-FuzzyHistory | |
function Invoke-FuzzyKillProcess() { | |
$result = Get-Process | Where-Object { ![string]::IsNullOrEmpty($_.ProcessName) } | ForEach-Object { "{0}: {1}" -f $_.Id,$_.ProcessName } | Select-Poco | |
$result | ForEach-Object { | |
$id = $_ -replace "([0-9]+)(:)(.*)",'$1' | |
Stop-Process $id -Verbose | |
} | |
} | |
Set-Alias "fk" Invoke-FuzzyKillProcess | |
function Invoke-FuzzySetLocation() { | |
param($Directory=$null) | |
if ($null -eq $Directory) { $Directory = $PWD.Path } | |
$result = $null | |
try { | |
if ([string]::IsNullOrWhiteSpace($env:POCO_DEFAULT_COMMAND)) { | |
Get-ChildItem $Directory -Recurse -ErrorAction Ignore | Where-Object{ $_.PSIsContainer } | Select-Poco | ForEach-Object { $result = $_ } | |
} else { | |
Select-Poco | ForEach-Object { $result = $_ } | |
} | |
} catch { | |
} | |
if ($null -ne $result) { | |
Set-Location $result | |
} | |
} | |
Set-Alias "fd" Invoke-FuzzySetLocation | |
if (Get-Command Search-Everything -ErrorAction Ignore) { | |
function Set-LocationFuzzyEverything() { | |
param($Directory=$null) | |
if ($null -eq $Directory) { | |
$Directory = $PWD.Path | |
$Global = $False | |
} else { | |
$Global = $True | |
} | |
$result = $null | |
try { | |
Search-Everything -Global:$Global -PathInclude $Directory -FolderInclude @('') | Select-Poco | ForEach-Object { $result = $_ } | |
} catch { | |
} | |
if ($null -ne $result) { | |
# use cd in case it's aliased to something else: | |
cd $result | |
} | |
} | |
} | |
Set-Alias "fs" Set-LocationFuzzyEverything | |
$script:IsWindows = ($PSVersionTable.PSVersion.Major -le 5) -or $IsWindows | |
if ($script:IsWindows) { | |
$script:ShellCmd = 'cmd.exe /S /C {0}' | |
$script:DefaultFileSystemCmd = @" | |
dir /s/b "{0}" | |
"@ | |
} else { | |
$script:ShellCmd = '/bin/sh -c "{0}"' | |
$script:DefaultFileSystemCmd = @" | |
find {0} -path '*/\.*' -prune -o -type f -print -o -type l -print 2> /dev/null | |
"@ | |
} | |
function Get-FileSystemCmd { | |
if ([string]::IsNullOrWhiteSpace($env:POCO_DEFAULT_COMMAND)) { | |
$script:DefaultFileSystemCmd | |
} else { | |
$env:POCO_DEFAULT_COMMAND | |
} | |
} | |
$script:PSReadlineHandlerChords = @() | |
$MyInvocation.MyCommand.ScriptBlock.Module.OnRemove = { | |
$script:PSReadlineHandlerChords | ForEach-Object { | |
Remove-PSReadlineKeyHandler $_ | |
} | |
} | |
if (Get-Module -ListAvailable -Name PSReadline) { | |
SetPsReadlineShortcut "$PSReadlineChordProvider" -Override:$PSBoundParameters.ContainsKey('PSReadlineChordProvider') 'Fzf Provider Select' 'Run fzf for current provider based on current token' { Invoke-FzfPsReadlineHandlerProvider } | |
SetPsReadlineShortcut "$PSReadlineChordReverseHistory" -Override:$PSBoundParameters.ContainsKey('PSReadlineChordReverseHistory') 'Fzf Reverse History Select' 'Run fzf to search through PSReadline history' { Invoke-FzfPsReadlineHandlerHistory } | |
SetPsReadlineShortcut "$PSReadlineChordSetLocation" -Override:$PSBoundParameters.ContainsKey('PSReadlineChordSetLocation') 'Fzf Set Location' 'Run fzf to select directory to set current location' { Invoke-FzfPsReadlineHandlerSetLocation } | |
SetPsReadlineShortcut "$PSReadlineChordReverseHistoryArgs" -Override:$PSBoundParameters.ContainsKey('PSReadlineChordReverseHistoryArgs') 'Fzf Reverse History Arg Select' 'Run fzf to search through command line arguments in PSReadline history' { Invoke-FzfPsReadlineHandlerHistoryArgs } | |
} else { | |
Write-Warning "PSReadline module not found - keyboard handlers not installed" | |
} | |
function Invoke-FzfPsReadlineHandlerProvider { | |
$leftCursor = $null | |
$rightCursor = $null | |
$line = $null | |
$cursor = $null | |
[Microsoft.PowerShell.PSConsoleReadline]::GetBufferState([ref]$line, [ref]$cursor) | |
$currentPath = Find-CurrentPath $line $cursor ([ref]$leftCursor) ([ref]$rightCursor) | |
$addSpace = $null -ne $currentPath -and $currentPath.StartsWith(" ") | |
if ([String]::IsNullOrWhitespace($currentPath) -or !(Test-Path $currentPath)) { | |
$currentPath = $PWD | |
} | |
$fileSystemCmd = Get-FileSystemCmd | |
$result = @() | |
try | |
{ | |
if (-not [System.String]::IsNullOrWhiteSpace($env:POCO_CTRL_T_COMMAND)) { | |
Invoke-Expression ($env:POCO_CTRL_T_COMMAND) | Select-Poco | ForEach-Object { $result += $_ } | |
} else { | |
if ([string]::IsNullOrWhiteSpace($currentPath)) { | |
Select-Poco | ForEach-Object { $result += $_ } | |
} else { | |
$resolvedPath = Resolve-Path $currentPath -ErrorAction SilentlyContinue | |
$providerName = $null | |
if ($null -ne $resolvedPath) { | |
$providerName = $resolvedPath.Provider.Name | |
} | |
switch ($providerName) { | |
# Get-ChildItem is way too slow - we optimize for the FileSystem provider by | |
# using batch commands: | |
'FileSystem' { Invoke-Expression ($script:ShellCmd -f ($fileSystemCmd -f $resolvedPath.ProviderPath)) | Select-Poco | ForEach-Object { $result += $_ } } | |
'Registry' { Get-ChildItem $currentPath -Recurse -ErrorAction SilentlyContinue | Select-Object Name -ExpandProperty Name | Select-Poco | ForEach-Object { $result += $_ } } | |
$null { Get-ChildItem $currentPath -Recurse -ErrorAction SilentlyContinue | Select-Object FullName -ExpandProperty FullName | Select-Poco | ForEach-Object { $result += $_ } } | |
Default {} | |
} | |
} | |
} | |
} | |
catch | |
{ | |
# catch custom exception | |
} | |
if ($null -ne $result) { | |
# quote strings if we need to: | |
if ($result -is [system.array]) { | |
for ($i = 0;$i -lt $result.Length;$i++) { | |
if ($result[$i].Contains(" ") -or $result[$i].Contains("`t")) { | |
$result[$i] = "'{0}'" -f $result[$i].Replace("`r`n","") | |
} else { | |
$result[$i] = $result[$i].Replace("`r`n","") | |
} | |
} | |
} else { | |
if ($result.Contains(" ") -or $result.Contains("`t")) { | |
$result = "'{0}'" -f $result.Replace("`r`n","") | |
} else { | |
$result = $result.Replace("`r`n","") | |
} | |
} | |
$str = $result -join ',' | |
if ($addSpace) { | |
$str = ' ' + $str | |
} | |
$replaceLen = $rightCursor - $leftCursor | |
if ($rightCursor -eq 0 -and $leftCursor -eq 0) { | |
[Microsoft.PowerShell.PSConsoleReadLine]::Insert($str) | |
} else { | |
[Microsoft.PowerShell.PSConsoleReadLine]::Replace($leftCursor,$replaceLen+1,$str) | |
} | |
} | |
} | |
function Invoke-FzfPsReadlineHandlerHistory { | |
$result = $null | |
try | |
{ | |
Get-History | Select-Poco | ForEach-Object { $result = $_ } | |
} | |
catch | |
{ | |
# catch custom exception | |
} | |
finally | |
{ | |
# ensure that stream is closed: | |
$reader.Dispose() | |
} | |
if (-not [string]::IsNullOrEmpty($result)) { | |
[Microsoft.PowerShell.PSConsoleReadLine]::Insert($result) | |
} | |
} | |
function Invoke-FzfPsReadlineHandlerHistoryArgs { | |
try | |
{ | |
$line = $null | |
$cursor = $null | |
[Microsoft.PowerShell.PSConsoleReadline]::GetBufferState([ref]$line, [ref]$cursor) | |
$line = $line.Insert($cursor,"{}") # add marker for fzf | |
$contentTable = @{} | |
Get-History | Select-Poco | ForEach-Object { $result = $_ } | |
} | |
catch | |
{ | |
# catch custom exception | |
} | |
finally | |
{ | |
$reader.Dispose() | |
} | |
if (-not [string]::IsNullOrEmpty($result)) { | |
# add quotes: | |
if ($result.Contains(" ") -or $result.Contains("`t")) { | |
$result = "'{0}'" -f $result.Replace("'","''") | |
} | |
[Microsoft.PowerShell.PSConsoleReadLine]::Replace($cursor,0,$result) | |
} | |
} | |
function Invoke-FzfPsReadlineHandlerSetLocation { | |
$result = $null | |
try | |
{ | |
if ($null -eq $env:POCO_ALT_C_COMMAND) { | |
Get-ChildItem . -Recurse -ErrorAction SilentlyContinue -Directory | Select-Poco | ForEach-Object { $result = $_ } | |
} else { | |
Invoke-Expression ($env:POCO_ALT_C_COMMAND + ' ' + $env:POCO_ALT_C_OPTS) | Select-Poco | ForEach-Object { $result = $_ } | |
} | |
} | |
catch | |
{ | |
# catch custom exception | |
} | |
if (-not [string]::IsNullOrEmpty($result)) { | |
Set-Location $result | |
[Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine() | |
} | |
} | |
function SetPsReadlineShortcut($Chord,[switch]$Override,$BriefDesc,$Desc,[scriptblock]$scriptBlock) { | |
if ([string]::IsNullOrEmpty($Chord)) { | |
return | |
} | |
if ((Get-PSReadlineKeyHandler -Bound | Where-Object {$_.Key.ToLower() -eq $Chord}) -and -not $Override) { | |
Write-Warning ("PSReadline chord {0} already in use - keyboard handler not installed. To bind your own keyboard chord, use the -ArgumentList parameter when you call Import-Module." -f $Chord) | |
} else { | |
$script:PSReadlineHandlerChords += $Chord | |
Set-PSReadlineKeyHandler -Key $Chord -Description $Desc -BriefDescription $BriefDesc -ScriptBlock $scriptBlock | |
} | |
} | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment