Skip to content

Fix AcceptAndGetNext for Forward/ReverseSearchHistory - #5210

Draft
sharpchen (sharpchen) wants to merge 1 commit into
PowerShell:masterfrom
sharpchen:accept-and-get-next-for-history-search
Draft

sharpchen (sharpchen) wants to merge 1 commit into
PowerShell:masterfrom
sharpchen:accept-and-get-next-for-history-search

Conversation

@sharpchen

@sharpchen sharpchen (sharpchen) commented Sep 13, 2026

Copy link
Copy Markdown
Contributor

PR Summary

Fixes #514

The Context

To get AcceptAndGetNext work, _currentHistoryIndex is required to be set before line accepted.

if (_singleton._currentHistoryIndex < (_singleton._history.Count - 1))

For Previous/NextHistory, _currentHistoryIndex is set by HistoryRecall:

_currentHistoryIndex = newHistoryIndex;

For Forward/ReverseSearchHistory, _currentHistoryIndex is set by UpdateHistoryDuringInteractiveSearch:

_currentHistoryIndex = searchFromPoint;

Current Behaviour

  1. ✔️ Triggering AcceptAndGetNext during the interactive search works as expected.
  2. ❌ Quit the interactive search and press any key doesn't edit the line(e.g. right arrow), it can't load next history after AcceptAndGetNext as expected.
  3. ❌ If Behaviour 2 is fixed, when a match from interactive search is accepted by e.g. esc, any edit based on the match doesn't reset _currentHistoryIndex, so AcceptAndGetNext would still proceed from the index of search result.

The Problem

For Behaviour 2, I located the problem come from:

if (_anyHistoryCommandCount > 0)
{
ClearSavedCurrentLine();
_hashedHistory = null;
_currentHistoryIndex = _history.Count;
}

The problem is InteractiveHistorySearch calls SaveCurrentLine() which increments _anyHistoryCommandCount, triggering the reset of _currentHistoryIndex in next input loop, even though the new input didn't edit the current line.

The Solution

_currentHistoryIndex is expected to be reset here only if _savedCurrentLine is identical to the current _buffer.

So the fix simple, just add a guard on it.

    if (_anyHistoryCommandCount > 0)
    {
-        ClearSavedCurrentLine();
-        _hashedHistory = null;
-        _currentHistoryIndex = _history.Count;
+        if (_savedCurrentLine.CommandLine == _buffer.ToString()) {
+            ClearSavedCurrentLine();
+            _hashedHistory = null;
+            _currentHistoryIndex = _history.Count;
+        }
    }
    _anyHistoryCommandCount = 0;

Note

I really doubt this piece of code should be executed after line accepted instead of on any input?
What is the point of trying clearing _savedCurrentLine on every key press?
BTW the name _anyHistoryCommandCount is really confusing, please consider refactoring it to a better name or add comment for why it exists.

PR Checklist

  • PR has a meaningful title
    • Use the present tense and imperative mood when describing your changes
  • Summarized changes
  • Make sure you've added one or more new tests
  • Make sure you've tested these changes in terminals that PowerShell is commonly used in (i.e. conhost.exe, Windows Terminal, Visual Studio Code Integrated Terminal, etc.)
  • User-facing changes
    • Not Applicable
    • OR
    • Documentation needed at PowerShell-Docs
      • Doc Issue filed:
Microsoft Reviewers: Open in CodeFlow

@sharpchen
sharpchen (sharpchen) marked this pull request as draft September 17, 2026 14:28
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

Successfully merging this pull request may close these issues.

AcceptAndGetNext should work to continue from ReverseSearchHistory

1 participant