Skip to content

Commit

Permalink
COOKED_READ: Fix tab not erasing the prompt (#16718)
Browse files Browse the repository at this point in the history
Write "<command that doesn't exist> foo" in cmd.exe, move yours cursor
past the <command> and press tab. The "foo" will still be there but
will be inaccessible. This commit fixes the issue. As far as I can
tell, this never worked in any conhost version ever.

Closes #16704
  • Loading branch information
lhecker authored Feb 21, 2024
1 parent e3ff44b commit 5e9f223
Showing 1 changed file with 8 additions and 1 deletion.
9 changes: 8 additions & 1 deletion src/host/readDataCooked.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -442,10 +442,17 @@ void COOKED_READ_DATA::_handleChar(wchar_t wch, const DWORD modifiers)
// It's unclear whether the original intention was to write at the end of the buffer at all times or to implement an insert mode.
// I went with insert mode.
//
// The old implementation also failed to clear the end of the prompt if you pressed tab in the middle of it.
// You can reproduce this issue by launching cmd in an old conhost build and writing "<command that doesn't exist> foo",
// moving your cursor to the space past the <command> and pressing tab. Nothing will happen but the "foo" will be inaccessible.
// I've now fixed this behavior by adding an additional Replace() before the _flushBuffer() call that removes the tail end.
//
// It is important that we don't actually print that character out though, as it's only for the calling application to see.
// That's why we flush the contents before the insertion and then ensure that the _flushBuffer() call in Read() exits early.
const auto cursor = _buffer.GetCursorPosition();
_buffer.Replace(cursor, npos, nullptr, 0);
_flushBuffer();
_buffer.Replace(_buffer.GetCursorPosition(), 0, &wch, 1);
_buffer.Replace(cursor, 0, &wch, 1);
_buffer.MarkAsClean();

_controlKeyState = modifiers;
Expand Down

0 comments on commit 5e9f223

Please sign in to comment.