From 7908164f9d74b2ecfd899a7bba09f19ee9ac1c83 Mon Sep 17 00:00:00 2001 From: Don-Vito Date: Thu, 2 Sep 2021 06:03:52 +0300 Subject: [PATCH] Teach Command Palette to filter out duplicate command lines (#11116) Closes #11093 --- src/cascadia/TerminalApp/CommandPalette.cpp | 38 +++++++++++++++++---- 1 file changed, 31 insertions(+), 7 deletions(-) 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))); } }