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

Powershell Support #84

Open
Kixiron opened this issue May 9, 2021 · 14 comments
Open

Powershell Support #84

Kixiron opened this issue May 9, 2021 · 14 comments
Labels
enhancement New feature or request help wanted Extra attention is needed shell Shell specific issues or enhancements

Comments

@Kixiron
Copy link

Kixiron commented May 9, 2021

I absolutely love the project and would love to be able to use it within powershell

@conradludgate conradludgate added the shell Shell specific issues or enhancements label May 9, 2021
@ellie ellie added the enhancement New feature or request label May 9, 2021
@iquiw iquiw mentioned this issue May 17, 2021
@gabriel-vanca
Copy link

Any news on PowerShell support?

@conradludgate conradludgate added the help wanted Extra attention is needed label Jul 21, 2023
@conradludgate
Copy link
Collaborator

@ellie and I are not against getting some basic powershell support, but neither of us run powershell or have the time right now to get familiar.

We have started to partially and unofficially support windows builds now, so it'll be the powershell integration that needs investigating.

  1. how can you hook into the prompt and detect key bindings
  2. how can you monitor command start and end events
  3. how can you update the prompt line with the search selection

@stibinator
Copy link

Might be worth noting that Powershell is not a windows-only shell. I use it on my Linux machines and it's available for OSX as well.

@lzybkr
Copy link

lzybkr commented Aug 23, 2023

I've been playing around with PowerShell support, see my prototype - you can import this file from your profile.

This mostly works for adding and updating the history. It's not perfect, e.g. it will include the time to render the prompt, which can be non-trivial in some cases.

I couldn't find a clean way to use redirection to capture the result from an interactive search, so I resorted to using a temporary file. It feels pretty slow on my VM but it seems to work.

One other thing I think PowerShell needs that doesn't apply to any other currently supported shell. PowerShell's notion of the current directory goes beyond the filesystem. atuin should have an explicit parameter like atuin history --cwd hklm:\ -- ... so PowerShell can specify these non-filesystem paths.

@brian6932
Copy link

@ellie and I are not against getting some basic powershell support, but neither of us run powershell or have the time right now to get familiar.

We have started to partially and unofficially support windows builds now, so it'll be the powershell integration that needs investigating.

1. how can you hook into the prompt and detect key bindings

2. how can you monitor command start and end events

3. how can you update the prompt line with the search selection

https://github.com/kelleyma49/PSFzf

@atuin-bot
Copy link

This issue has been mentioned on Atuin Community. There might be relevant details there:

https://forum.atuin.sh/t/terminal-setup/165/2

@k4lizen
Copy link

k4lizen commented Mar 1, 2024

I would also love this feature!

@jbayardo
Copy link

In case people are interested, this almost works:

$env:ATUIN_SESSION = (atuin uuid | Out-String).Trim()
$env:ATUIN_HISTORY_ID = $null

Set-PSReadLineKeyHandler -Chord Enter -ScriptBlock {
    $line = $null
    $cursor = $null
    [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)

    if (-not $env:ATUIN_HISTORY_ID) {
        $env:ATUIN_HISTORY_ID = (atuin history start -- $line | Out-String).Trim()
        $global:ATUIN_HISTORY_ELAPSED = [System.Diagnostics.Stopwatch]::StartNew()
    }

    [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
}

$existingPromptFunction = Get-Item -Path Function:\prompt
Remove-Item -Path Function:\prompt
function prompt {
    if ($env:ATUIN_HISTORY_ID) {
        $durationNs = $global:ATUIN_HISTORY_ELAPSED.ElapsedTicks * 100
        $exitCode = $LASTEXITCODE
        atuin history end --duration $durationNs --exit $exitCode -- $env:ATUIN_HISTORY_ID | Out-Null

        Remove-Item -Path env:ATUIN_HISTORY_ID -ErrorAction SilentlyContinue
    }

    & $existingPromptFunction.ScriptBlock
}

# TODO: Fix all the bindings below
$InvokeAtuinSearch = {
    $keymapMode = "emacs"

    $line = $null
    $cursor = $null
    [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferState([ref]$line, [ref]$cursor)

    $suggestion = (atuin search --keymap-mode=$keymapMode -i -- $line | Out-String).Trim()

    [Microsoft.PowerShell.PSConsoleReadLine]::RevertLine()

    if ($suggestion.StartsWith("__atuin_accept__:")) {
        $suggestion = $suggestion.Substring(16)
        [Microsoft.PowerShell.PSConsoleReadLine]::Insert($suggestion)
        [Microsoft.PowerShell.PSConsoleReadLine]::AcceptLine()
    }
    else {
        [Microsoft.PowerShell.PSConsoleReadLine]::Insert($suggestion)
    }
}

$InvokeAtuinUpSearch = {
    $bufferContent = [Microsoft.PowerShell.PSConsoleReadLine]::GetBufferContent()
    if (-not $bufferContent.Contains("`n")) {
        & $InvokeAtuinSearch -keymapMode "vim-normal"
    }
    else {
        [Microsoft.PowerShell.PSConsoleReadLine]::HistorySearchBackward()
    }
}

Set-PSReadLineKeyHandler -Chord "Ctrl+r" -ScriptBlock $InvokeAtuinSearch -BriefDescription "AtuinSearch" -Description "Invoke Atuin search for command history"
Set-PSReadLineKeyHandler -Chord "UpArrow" -ScriptBlock $InvokeAtuinUpSearch -BriefDescription "AtuinUpSearch" -Description "Invoke Atuin up search or navigate history"

A fight has to be had with PSReadLine to allow Ctrl + R and UpArrow to work, and deal with Vim vs Emacs mode, but running atuin history list seems to record all commands as expected.

Unfortunately, since PowerShell lacks precmd and postcmd hooks, it's hard to implement this in exactly the same way as other shells do. The recorded timing is a bit off: what I observe is the first couple of commands run in a new PowerShell session seem to get the time spent wrong (sometimes by as much as hundreds of ms), but afterwards the error decreases rapidly to about 10ms or 20ms.

@ellie
Copy link
Member

ellie commented Jun 25, 2024

If anyone has been using the above long term, and without major issue, it would be awesome to work towards getting it included

@jbayardo
Copy link

The key bindings don't work in the above, launching atuin interactive search by running Ctrl + R scrambles all characters in the screen. The issue has likely something to do with this: PowerShell/PSReadLine#1576 .

PSFzf does manage to successfully make things work, I think the reason is they are spawning a process within PowersShell with appropriate redirections as part of the PSReadLine chord binding, so whomever has the heart to deal with that might find that technique useful (see here: https://github.com/kelleyma49/PSFzf/blob/master/PSFzf.Base.ps1#L406 ).

@brian6932
Copy link

PSFzf does manage to successfully make things work

Not exactly kelleyma49/PSFzf#189 kelleyma49/PSFzf#274

@Lockszmith-GH
Copy link

But surly we can use a different chord - does it HAVE to be Ctrl+R ?

@gabriel-vanca
Copy link

Would be lovely to get an update on this.

rainersigwald added a commit to rainersigwald/dotfiles that referenced this issue Aug 28, 2024
@atuin-bot
Copy link

This issue has been mentioned on Atuin Community. There might be relevant details there:

https://forum.atuin.sh/t/multiple-shells-across-multiplle-machines/627/2

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
enhancement New feature or request help wanted Extra attention is needed shell Shell specific issues or enhancements
Projects
None yet
Development

No branches or pull requests