PSReadLine icon indicating copy to clipboard operation
PSReadLine copied to clipboard

AcceptAndGetNext is skipping

Open Jaykul opened this issue 6 years ago • 6 comments

When I set a hotkey for AcceptAndGetNext I expect to be able to replay a few commands from history in order, by just pressing it repeatedly, but it keeps skipping commands.

Environment data

PS version: 5.1.18950.1000 PSReadline version: 2.0.0-beta4 os: 10.0.18950.1000 (WinBuild.160101.0800) PS file version: 10.0.18950.1000 (WinBuild.160101.0800) BufferWidth: 130 BufferHeight: 6000

And Also

PS version: 7.0.0-preview.2 PSReadline version: 2.0.0-beta4 os: 10.0.18950.1000 (WinBuild.160101.0800) PS file version: 7.0.0.0 BufferWidth: 120 BufferHeight: 27

Steps to reproduce or exception report

When I set a hotkey (e.g. Ctrl+k or Ctrl+Enter) for AcceptAndGetNext

Then I type a few commands and hit enter after each:

Write-Host "One" Write-Host "Two" Write-Host "Three" Write-Host "Four" Write-Host "Five"

Then I hit up-arrow until I get back to "One" and hit the hotkey (e.g. Ctrl+k) a couple of times, it skips from "One" to "Three" to "Five" ...

Jaykul avatar Aug 03 '19 06:08 Jaykul

Weird, I know this used to work and there are even unit tests for this binding that in theory are passing.

lzybkr avatar Oct 19 '19 01:10 lzybkr

Adding some detail:

Set-PSReadLineKeyHandler ctrl+k AcceptAndGetNext
Write-Host "One"
Write-Host "Two"
Write-Host "Three"
Write-Host "Four"
Write-Host "Five"

UpArrow 5 times. Then CTRL+k 5 times, the results are ...

One
Three
Five
Three
Three

At this point there are no more commands left, so the prompt has no further command.

So it seems as though it must be running through the right commands by some index, but then places the wrong command in the buffer...

msftrncs avatar Dec 17 '19 07:12 msftrncs

Quick guess ... AcceptLineImpl() is saving this new line in to the history, or changing up the history indexing, causing the next command to bump up one ?? Maybe a history item at the end is being bumped off? So until your history fills up, its not a problem, and the testing works as expected because its always starting with an empty history.

msftrncs avatar Dec 17 '19 07:12 msftrncs

Not quite what I guessed, but I was close. Once the _history <HistoryQueue> fills, the _head moves, changing the index of every _history item. Every command is moved or copied to the _tail of the queue upon being accepted (but not in AcceptLineImpl(), instead its after returning to InputLoop() from ProcessOneKey()).

In this case, it is useless to save index's to <HistoryQueue>, because they will change once the queue is fully populated.

The problem here is probably that the index value for <HistoryQueue> is absolute, instead of relative. Currently, _history.Count represents the present, and values less than that represent fixed points in the past, but they are only fixed points until the entire history rotates in place when the queue fills.

msftrncs avatar Dec 18 '19 07:12 msftrncs

For what it's worth, this only happens when the history buffer is full.

Jaykul avatar Jan 12 '21 04:01 Jaykul

Still reproduces in PS 7.3.8 and PSReadLine 2.3.4

StevenBucher98 avatar Oct 30 '23 18:10 StevenBucher98