PowerShell / PSReadLine

A bash inspired readline implementation for PowerShell
BSD 2-Clause "Simplified" License
3.75k stars 296 forks source link

Question/Request: Is it possible to remove an item from the history? #1778

Open DJackman123 opened 4 years ago

DJackman123 commented 4 years ago

The [Microsoft.PowerShell.PSConsoleReadLine]::AddToHistory method makes it really easy to add a command to the history. Is there a corresponding method to remove a command from the history?

I would like to write a function to bind to a key that would recall the last command from the history so I can correct it. Sort of like an UndoLastCommand function. I would use this after entering a command with a misspelling or other syntax problem. Such a command has no useful purpose in the history (I would never want to execute it again).

Hopefully this description makes sense. Is such a thing possible today? Or would this require some coding within the PSReadLine module before I could write a PowerShell script to do this?

lzybkr commented 4 years ago

Not exactly - you can edit the history file, but I think that would only take effect in new instances of PowerShell.

This wouldn't be too hard to implement in memory, but deleting from the history file gets a bit tricky because of how shared history works - it relies on knowing the length of the history file and knowing that a new command would start at the next offset beyond that length.

benallred commented 2 years ago

I'm using this to [kind of] remove an item from the history: https://github.com/benallred/configs/blob/f8814951e66d33feb4ed045b456a2ca60bd46658/powershell/PSReadLine.ps1#L67-L82

It's not perfect, due to the reasons lzybkr mentioned:

camp-007 commented 2 years ago

Thanks @benallred for sharing that snippet. That is a very close approximation of the feature I wish was available out of the box. Ideally it would affect the current session, but it is much better than nothing.

FYI, the extra new lines is a quirk of the Set-Content command and can be avoided by changing it to

Set-Content (Get-PSReadLineOption).HistorySavePath $history -NoNewline
tyg6 commented 1 year ago

Delete commands by Id number: Clear-History -Id 3, 5 Clear-History doc

DJackman123 commented 1 year ago

Clear-History is for the wrong history. This post is not talking about the PowerShell session history, but the PSReadLine history that's saved to the (Get-PSReadLineOption).HistorySavePath settting. Clear-History doesn't do anything with that history.

mikesigs commented 4 months ago

I added this to my profile to help remove items from both history sets.

function Remove-PSReadlineHistory {
    param (
        [Parameter(Mandatory = $true)]
        [string]$Pattern
    )

    $historyPath = (Get-PSReadLineOption).HistorySavePath
    $historyLines = [System.IO.File]::ReadAllLines($historyPath)
    $filteredLines = $historyLines | Where-Object { $_ -notmatch $Pattern }
    [System.IO.File]::WriteAllLines($historyPath, $filteredLines)

    Write-Host "Removed $($historyLines.Count - $filteredLines.Count) line(s) from PSReadLine history."
}

function Remove-PSHistory {
    param (
        [Parameter(Mandatory = $true)]
        [string]$Pattern
    )

    $historyLines = Get-History
    $matchingLines = $historyLines | Where-Object { $_.CommandLine -match $Pattern }
    $matchingLines | ForEach-Object { Clear-History -Id $_.Id }
    Write-Host "Removed $($matchingLines.Count) line(s) from PowerShell history."
}

function Remove-History {
    param (
        [Parameter(Mandatory = $true)]
        [string]$Pattern
    )

    Remove-PSReadlineHistory -Pattern $Pattern
    Remove-PSHistory -Pattern $Pattern
}
gwgaston commented 3 months ago

Was hoping you guys had learned a few things from Rex Conn. :)