diff --git a/src/cascadia/TerminalApp/CommandPalette.cpp b/src/cascadia/TerminalApp/CommandPalette.cpp index be16f2f1b..a4b4c0b8f 100644 --- a/src/cascadia/TerminalApp/CommandPalette.cpp +++ b/src/cascadia/TerminalApp/CommandPalette.cpp @@ -1275,15 +1275,39 @@ namespace winrt::TerminalApp::implementation void CommandPalette::_updateRecentCommands(const hstring& command) { const auto recentCommands = ApplicationState::SharedInstance().RecentCommands(); - // If there aren't and recent commands already in the state, then we - // don't need to copy any. - const auto countToCopy = std::min(recentCommands ? recentCommands.Size() : 0, CommandLineHistoryLength - 1); - std::vector newRecentCommands{ countToCopy + 1 }; - til::at(newRecentCommands, 0) = command; - if (countToCopy) + // If this is the first time we've opened the commandline mode and + // there aren't any recent commands, then just store the new command. + if (!recentCommands) { - recentCommands.GetMany(0, { newRecentCommands.data() + 1, countToCopy }); + ApplicationState::SharedInstance().RecentCommands(single_threaded_vector(std::move(std::vector{ command }))); + return; } + + const auto numNewRecentCommands = std::min(recentCommands.Size() + 1, CommandLineHistoryLength); + + std::vector newRecentCommands; + newRecentCommands.reserve(numNewRecentCommands); + + std::unordered_set uniqueCommands; + uniqueCommands.reserve(numNewRecentCommands); + + newRecentCommands.push_back(command); + uniqueCommands.insert(command); + + for (const auto& c : recentCommands) + { + if (newRecentCommands.size() >= CommandLineHistoryLength) + { + // Don't store more than CommandLineHistoryLength commands + break; + } + + if (uniqueCommands.emplace(c).second) + { + newRecentCommands.push_back(c); + } + } + ApplicationState::SharedInstance().RecentCommands(single_threaded_vector(std::move(newRecentCommands))); } }