PSReadLine icon indicating copy to clipboard operation
PSReadLine copied to clipboard

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

Open DJackman123 opened this issue 5 years ago • 8 comments

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?

DJackman123 avatar Aug 28 '20 13:08 DJackman123

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.

lzybkr avatar Aug 28 '20 17:08 lzybkr

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:

  • It doesn't take effect in the current session
    • Oh, well - at least it makes future sessions nicer
  • It results in some extra new lines in the history file when a new command is saved
    • I haven't noticed this cause any problems, though

benallred avatar Apr 27 '22 19:04 benallred

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

camp-007 avatar Jul 14 '22 13:07 camp-007

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

tyg6 avatar Sep 15 '23 06:09 tyg6

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.

DJackman123 avatar Sep 15 '23 17:09 DJackman123

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
}

mikesigs avatar Jun 24 '24 19:06 mikesigs

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

gwgaston avatar Jul 30 '24 06:07 gwgaston