fix(input): let the arrow keys walk the sent-message history again
Reported against v1.11.0: type a command, send it, need it again, and up-arrow does nothing. v1.5.6 recalled it. Everything needed was already in the tree. InputHistoryService holds the last thirty entries with move-to-newest dedup, CompactInputHistoryNavigator owns the cursor maths, and both have their own test mirrors. Neither had a single caller, and the input field never set CallbackHistory, so ImGui had no reason to raise the event in the first place. So: the flag goes on, the callback grows a history branch, and TrySend pushes the trimmed line before it clears the buffer. Editing ends the walk, otherwise down-arrow after changing a recalled line would jump to the next entry and discard the edit. The cursor is per input bar while the history is global. Which line each window is looking at is not something the others should inherit.
This commit is contained in:
@@ -311,6 +311,11 @@ internal sealed class InputBar
|
||||
}
|
||||
}
|
||||
|
||||
// -1 means "not browsing". Per input bar, not shared: the history itself is
|
||||
// global across the main window and every pop-out, but where each of them is
|
||||
// in it is not.
|
||||
private int _historyCursor = -1;
|
||||
|
||||
private void DrawInputField(Tab? activeTab)
|
||||
{
|
||||
if (Activate)
|
||||
@@ -328,7 +333,8 @@ internal sealed class InputBar
|
||||
ImGuiInputTextFlags.EnterReturnsTrue
|
||||
| ImGuiInputTextFlags.CallbackEdit
|
||||
| ImGuiInputTextFlags.CallbackCompletion
|
||||
| ImGuiInputTextFlags.CallbackAlways,
|
||||
| ImGuiInputTextFlags.CallbackAlways
|
||||
| ImGuiInputTextFlags.CallbackHistory,
|
||||
SlashCommandCallback
|
||||
)
|
||||
)
|
||||
@@ -360,6 +366,39 @@ internal sealed class InputBar
|
||||
return 0;
|
||||
}
|
||||
|
||||
// Up and down walk the sent-message history, the way 1.5.6 did. ImGui
|
||||
// only raises this event when CallbackHistory is set on the field, which
|
||||
// is why the arrows did nothing at all before: the service and the
|
||||
// cursor maths were both here and tested, with no caller and no flag.
|
||||
if (data.EventFlag == ImGuiInputTextFlags.CallbackHistory)
|
||||
{
|
||||
var direction =
|
||||
data.EventKey == ImGuiKey.UpArrow
|
||||
? CompactInputHistoryNavigator.Direction.Up
|
||||
: CompactInputHistoryNavigator.Direction.Down;
|
||||
|
||||
var (cursor, replacement) = CompactInputHistoryNavigator.Navigate(
|
||||
direction,
|
||||
_historyCursor,
|
||||
_pendingMessage,
|
||||
() => InputHistoryService.Count,
|
||||
InputHistoryService.Push,
|
||||
InputHistoryService.GetByCursor
|
||||
);
|
||||
|
||||
_historyCursor = cursor;
|
||||
if (replacement is null)
|
||||
return 0;
|
||||
|
||||
// The buffer belongs to ImGui inside a callback; writing the managed
|
||||
// field here would be overwritten on the way out.
|
||||
data.DeleteChars(0, data.BufTextLen);
|
||||
if (replacement.Length > 0)
|
||||
data.InsertChars(0, replacement);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
if (data.EventFlag == ImGuiInputTextFlags.CallbackCompletion)
|
||||
{
|
||||
// CursorPos is a BYTE offset into the UTF-8 buffer. We decode the
|
||||
@@ -381,6 +420,13 @@ internal sealed class InputBar
|
||||
// CallbackEdit (or any remaining event): v1.5.6 character-level slash
|
||||
// detection keeps CommandHelpWindow in sync with what the user is
|
||||
// typing without a per-frame poll.
|
||||
//
|
||||
// Typing also ends the history walk. Without this, down-arrow after
|
||||
// editing a recalled line would jump to the next entry and throw the
|
||||
// edit away.
|
||||
if (data.EventFlag == ImGuiInputTextFlags.CallbackEdit)
|
||||
_historyCursor = -1;
|
||||
|
||||
_commandHelpWindow.IsOpen = false;
|
||||
|
||||
var text = Encoding.UTF8.GetString(data.BufTextSpan);
|
||||
@@ -455,6 +501,12 @@ internal sealed class InputBar
|
||||
return;
|
||||
}
|
||||
ChatBox.SendMessageUnsafe(bytes);
|
||||
|
||||
// Pushed before the buffer is cleared, and the trimmed form is what
|
||||
// goes in: the history is for recalling what you typed, not the
|
||||
// whitespace around it.
|
||||
InputHistoryService.Push(text);
|
||||
_historyCursor = -1;
|
||||
_pendingMessage = string.Empty;
|
||||
|
||||
// 1.5.6 parity (1d3b429:ChatLogWindow.cs:1558): clear the temp channel
|
||||
|
||||
Reference in New Issue
Block a user