Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

could not init powershell #443

Open
1925381584 opened this issue Oct 8, 2024 · 2 comments
Open

could not init powershell #443

1925381584 opened this issue Oct 8, 2024 · 2 comments

Comments

@1925381584
Copy link

Hi, it could not init powershell in my machine.

commit id : 268ee06
OS: Windows 10.0.19045
Memory: 15.7 GiB
Architecture: x86_64
GPU: Intel(R) Iris(R) Xe Graphics || Intel Corporation || Intel driver

image

@EmileDirigera
Copy link

That is because you are running PowerShell 5.1. The script if build for version 7 or later which added support for new operators.

In version 7.4 of PowerShell, Set-PSReadLineOption from PSReadLine added the parameter PredictionSource which does not exist in 5.1 and McFly does not seem to work properly in 5.1 from my very short testing on version 9.1 (the version that is available via winget at the time of writing this).

My advise, and what I will do, is to install PowerShell Core LTS (7.4) and run McFly there.

If you still want to use McFly, here is a modifed version of the PowerShell script that initiates McFly.

#!/usr/bin/env pwsh

$null = New-Module mcfly {
    # We need PSReadLine for a number of capabilities
    if ($null -eq (Get-Module -Name PSReadLine)) {
        Write-Host "Installing PSReadLine as McFly dependency"
        Install-Module PSReadLine
    }

    # Get history file and make a dummy file for psreadline (hopefully after it has loaded the real history file to its in memory history)
    $env:HISTFILE = if($null -eq $env:HISTFILE -or "" -eq $env:HISTFILE) {(Get-PSReadLineOption).HistorySavePath} else {$env:HISTFILE}
    $psreadline_dummy = New-TemporaryFile
    # Append history to dummy file for compatibility
    Get-Content -Path $Env:HISTFILE | Out-File -FilePath $psreadline_dummy -Force
    Set-PSReadLineOption -HistorySavePath $psreadline_dummy.FullName


    $fileExists = Test-Path -path $env:HISTFILE
    if (-not $fileExists) {
        Write-Host "McFly: ${env:HISTFILE} does not exist or is not readable. Please fix this or set HISTFILE to something else before using McFly.";
        return 1;
    }

    # MCFLY_SESSION_ID is used by McFly internally to keep track of the commands from a particular terminal session.
    $MCFLY_SESSION_ID = new-guid
    $env:MCFLY_SESSION_ID = $MCFLY_SESSION_ID

    $env:MCFLY_HISTORY = New-TemporaryFile
    Get-Content $env:HISTFILE | Select-Object -Last 100 | Set-Content $env:MCFLY_HISTORY

    <#
    .SYNOPSIS
    Cmdlet to run McFly

    .PARAMETER CommandToComplete
    The command to complete

    .EXAMPLE
    Invoke-McFly -CommandToComplete "cargo bu"
    #>
    function Invoke-McFly {
        Param([string]$CommandToComplete)
        $lastExitTmp = $LASTEXITCODE
        $tempFile = New-TemporaryFile
        Start-Process -FilePath 'C:\Users\emile\AppData\Local\Microsoft\WinGet\Packages\cantino.mcfly_Microsoft.Winget.Source_8wekyb3d8bbwe\mcfly.exe' -ArgumentList "search", "$CommandToComplete", -o, "$tempFile" -NoNewWindow -Wait
        foreach($line in Get-Content $tempFile) {
            $key, $value = $line -split ' ', 2
            if ("mode" -eq $key) {
                $mode = $value
            }
            if ("commandline" -eq $key) {
                $commandline = $value
            }
        }
        if(-not ($null -eq $commandline)) {
            [Microsoft.PowerShell.PSConsoleReadLine]::DeleteLine()
            [Microsoft.PowerShell.PSConsoleReadline]::Insert($commandline)
            if("run" -eq $mode) {
                [Microsoft.PowerShell.PSConsoleReadline]::AcceptLine()
            }
        }
        Remove-Item $tempFile
        $LASTEXITCODE = $lastExitTmp
    }

    <#
    .SYNOPSIS
    Add a command to McFly's history.

    .PARAMETER Command
    The string of the command to add to McFly's history

    .PARAMETER ExitCode
    The exit code of the command to add

    .EXAMPLE
    Add-CommandToMcFly -Command "cargo build"
    #>
    function Add-CommandToMcFly {
        Param (
            [string] $Command,
            [int] $ExitCode
        )
        $ExitCode = if ($null -eq $ExitCode) { 0 } else { $ExitCode }
        $Command | Out-File -FilePath $env:MCFLY_HISTORY -Append
        Start-Process -FilePath 'C:\Users\emile\AppData\Local\Microsoft\WinGet\Packages\cantino.mcfly_Microsoft.Winget.Source_8wekyb3d8bbwe\mcfly.exe' -ArgumentList add, --exit, $ExitCode, --append-to-histfile, $env:HISTFILE -NoNewWindow | Write-Host
    }

    # We need to make sure we call out AddToHistoryHandler right after each command is called
    Set-PSReadLineOption -HistorySaveStyle SaveIncrementally

    if($PSVersionTable.PSVersion.Major -ge 7) {
        Set-PSReadLineOption -PredictionSource HistoryAndPlugin
    }

    Set-PSReadLineOption -AddToHistoryHandler {
        Param([string]$Command)
        $lastExitTmp = $LASTEXITCODE
        $Command = $Command.Trim();
        # PSReadLine executes this before the command even runs, so we don't know its exit code - assume 0
        Add-CommandToMcFly -Command $Command -ExitCode 0
        $LASTEXITCODE = $lastExitTmp
        # Tell PSReadLine to save the command to their in-memory history (and also the dummy file)
        return $true
    }

    Set-PSReadLineKeyHandler -Chord "Ctrl+r" -ScriptBlock {
        $line = $null
        $cursor = $null
        [Microsoft.PowerShell.PSConsoleReadline]::GetBufferState([ref]$line, [ref]$cursor)
        "#mcfly: $line" | Out-File -FilePath $env:MCFLY_HISTORY -Append
        Invoke-McFly -CommandToComplete "`"$line`""
    }

    Export-ModuleMember -Function @(
        "Invoke-McFly"
        "Add-CommandToMcFly"
    )
}

The modifications are as follows:
Line 11: ? not present in 5.1

$env:HISTFILE = if($null -eq $env:HISTFILE -or "" -eq $env:HISTFILE) {(Get-PSReadLineOption).HistorySavePath} else {$env:HISTFILE}

Line 84: ?? not present in 5.1.

$ExitCode = if ($null -eq $ExitCode) { 0 } else { $ExitCode }

Line 92: Set-PSReadLineOption does not have the option -PredictionSource HistoryAndPlugin in 5.1.

if($PSVersionTable.PSVersion.Major -ge 7) {
  Set-PSReadLineOption -PredictionSource HistoryAndPlugin
}

@cantino Perhaps add a note about minimum supported PowerShell version?

@cantino
Copy link
Owner

cantino commented Dec 21, 2024

Added a comment to the README in #447

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants