PsComplete.psm1

# immediately chain into the next argument if its a switch
# or stop if input is expected
function HandleReplacementArgChain($replacement) {

    if ($replacement.ResultType -eq 'ProviderContainer'){

    }
    

    switch ($replacement.ArgumentType) {
        "psobject" {
            [Microsoft.PowerShell.PSConsoleReadLine]::Insert('.');
            Invoke-GuiPsComplete;
        } 
        "switch" { 
            [Microsoft.PowerShell.PSConsoleReadLine]::Insert(' -');
            Invoke-GuiPsComplete;
        }
        "IDictionary" { 
            [Microsoft.PowerShell.PSConsoleReadLine]::Insert(' @{ "" = "" }');
            [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursorPosition + $replacement.CompletionText.Length + 4);
        }
        "string array" { 
            [Microsoft.PowerShell.PSConsoleReadLine]::Insert(' ');
        }
        { @("CommandTypes", "ActionPreference") -contains $_ } {
            [Microsoft.PowerShell.PSConsoleReadLine]::Insert(' ');
            Invoke-GuiPsComplete;
        }
        Default {
            [Microsoft.PowerShell.PSConsoleReadLine]::Insert(' ');
        }
    }
}

function writeDebug($variable) {
    $variable | ConvertTo-Json -Depth 5 > $env:USERPROFILE/sample.json
}

function Invoke-GuiPsComplete() {
    $buffer = ''
    $cursorPosition = 0
    [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$buffer, [ref]$cursorPosition)
    $completion = TabExpansion2 $buffer $cursorPosition 
    
    if ($completion.CompletionMatches.Count -eq 0) {
        return
    }

    $replacement = 
    Invoke-PsComplete `
        -Content $completion.CompletionMatches `
        -CommandString "$buffer" `
        -CommandCursorPosition $cursorPosition 

    # debug
    # @{r=$replacement; r2=$completion} | ConvertTo-Json -Depth 5 > sample.json
    # Write-Warning "`n`n$replacement.ResultType"
    
    if ($replacement) {
        
        switch ($replacement.ExitKey) {
            Tab {
                [Microsoft.PowerShell.PSConsoleReadLine]::Replace($completion.ReplacementIndex, $completion.ReplacementLength, $replacement.CompletionText)
                
                if ($replacement.ResultType -eq 'Command') {
                    [Microsoft.PowerShell.PSConsoleReadLine]::Insert(' -');
                    Invoke-GuiPsComplete;
                }
                elseif ($replacement.ResultType -eq 'ParameterName') {
                    HandleReplacementArgChain $replacement
                }
                elseif ($replacement.ResultType -eq 'ProviderContainer') {
                    if ([System.Environment]::OSVersion.Platform -eq 'Unix') {
                        [Microsoft.PowerShell.PSConsoleReadLine]::Insert('/');
                        Invoke-GuiPsComplete;
                    }
                    else {
                        [Microsoft.PowerShell.PSConsoleReadLine]::Insert('\');
                        Invoke-GuiPsComplete;
                    }
                }
            }
            Enter {
                [Microsoft.PowerShell.PSConsoleReadLine]::Replace($completion.ReplacementIndex, $completion.ReplacementLength, $replacement.CompletionText)
            }
            Escape {
                [Microsoft.PowerShell.PSConsoleReadLine]::SetCursorPosition($cursorPosition);
            }
            ## if there is a single option
            None {
                [Microsoft.PowerShell.PSConsoleReadLine]::Replace($completion.ReplacementIndex, $completion.ReplacementLength, $replacement.CompletionText)
                if ($replacement.ResultType -eq 'Command') {
                    [Microsoft.PowerShell.PSConsoleReadLine]::Insert(' -');
                    Invoke-GuiPsComplete;
                }
                elseif ($replacement.ResultType -eq 'ProviderContainer') {
                    if ([System.Environment]::OSVersion.Platform -eq 'Unix') {
                        [Microsoft.PowerShell.PSConsoleReadLine]::Insert('/');
                        Invoke-GuiPsComplete;
                    }
                    else {
                        [Microsoft.PowerShell.PSConsoleReadLine]::Insert('\');
                        Invoke-GuiPsComplete;
                    }
                }
            }
        }
    }
}


function Install-PsComplete() {
    $loadedAssemblies = `
        [System.AppDomain]::CurrentDomain.GetAssemblies() `
        | Where-Object Location `
        | ForEach-Object {$_.GetName().Name};
   
    if (!($loadedAssemblies.Contains('FSharp.Core'))) {
        Import-Module "$PSScriptRoot/FSharp.Core.dll"    
    }
    if (!($loadedAssemblies.Contains('aciq.pscomplete'))) {
        Import-Module "$PSScriptRoot/aciq.pscomplete.dll"   
    }

    Set-PSReadLineKeyHandler -Chord 'Tab' -ScriptBlock { 
        Invoke-GuiPsComplete 
    }
}

# Import-Module '/home/ian/f/publicrepos/aciq.pscomplete/src/bin/Debug/net6.0/aciq.pscomplete.dll' -DisableNameChecking
# Import-Module '/home/ian/f/publicrepos/aciq.pscomplete/src/bin/Release/net6.0/aciq.pscomplete.dll' -DisableNameChecking

# Set-PSReadLineKeyHandler -Chord 'Tab' -ScriptBlock { Invoke-GuiPsComplete }
# Set-PSReadLineKeyHandler -Chord 'Ctrl+q' -ScriptBlock { Invoke-GuiPsComplete }