Add "recent commands" to Command Palette in commandline mode (#8317)

## Summary of the Pull Request
Add a history to command palette in the command line mode.
Few considerations/limitations
1. In-memory, 10 entries hard-coded
2. MRU
3. List rather than set
4. The user needs explicitly select command from the history

## PR Checklist
* [x] Closes https://github.com/microsoft/terminal/issues/8296
* [x] CLA signed. 
* [x] Tests added/passed
* [ ] Documentation updated - irrelevant
* [ ] Schema updated - irrelevant
* [ ] I've discussed this with core contributors already. 

## Validation Steps Performed
* Manual testing
This commit is contained in:
Don-Vito 2020-11-25 22:30:36 +02:00 committed by GitHub
parent d497dfd113
commit 274f5a74f5
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 54 additions and 44 deletions

View File

@ -29,6 +29,7 @@ namespace winrt::TerminalApp::implementation
_currentNestedCommands = winrt::single_threaded_vector<winrt::TerminalApp::FilteredCommand>();
_allCommands = winrt::single_threaded_vector<winrt::TerminalApp::FilteredCommand>();
_tabActions = winrt::single_threaded_vector<winrt::TerminalApp::FilteredCommand>();
_commandLineHistory = winrt::single_threaded_vector<winrt::TerminalApp::FilteredCommand>();
_switchToMode(CommandPaletteMode::ActionMode);
@ -303,21 +304,9 @@ namespace winrt::TerminalApp::implementation
}
else if (key == VirtualKey::Enter)
{
// Action, TabSwitch or TabSearchMode Mode: Dispatch the action of the selected command.
if (_currentMode != CommandPaletteMode::CommandlineMode)
{
const auto selectedCommand = _filteredActionsView().SelectedItem();
if (const auto filteredCommand = selectedCommand.try_as<winrt::TerminalApp::FilteredCommand>())
{
_dispatchCommand(filteredCommand);
}
}
// Commandline Mode: Use the input to synthesize an ExecuteCommandline action
else if (_currentMode == CommandPaletteMode::CommandlineMode)
{
_dispatchCommandline();
}
const auto selectedCommand = _filteredActionsView().SelectedItem();
const auto filteredCommand = selectedCommand.try_as<winrt::TerminalApp::FilteredCommand>();
_dispatchCommand(filteredCommand);
e.Handled(true);
}
else if (key == VirtualKey::Escape)
@ -538,7 +527,7 @@ namespace winrt::TerminalApp::implementation
case CommandPaletteMode::TabSwitchMode:
return _tabActions;
case CommandPaletteMode::CommandlineMode:
return winrt::single_threaded_vector<winrt::TerminalApp::FilteredCommand>();
return _commandLineHistory;
default:
return _allCommands;
}
@ -555,7 +544,11 @@ namespace winrt::TerminalApp::implementation
// - <none>
void CommandPalette::_dispatchCommand(winrt::TerminalApp::FilteredCommand const& filteredCommand)
{
if (filteredCommand)
if (_currentMode == CommandPaletteMode::CommandlineMode)
{
_dispatchCommandline(filteredCommand);
}
else if (filteredCommand)
{
if (filteredCommand.Command().HasNestedCommands())
{
@ -628,32 +621,48 @@ namespace winrt::TerminalApp::implementation
// Method Description:
// - Dispatch the current search text as a ExecuteCommandline action.
// Arguments:
// - <none>
// - filteredCommand - Selected filtered command - might be null
// Return Value:
// - <none>
void CommandPalette::_dispatchCommandline()
void CommandPalette::_dispatchCommandline(winrt::TerminalApp::FilteredCommand const& command)
{
auto cmdline{ _getTrimmedInput() };
if (cmdline.empty())
const auto filteredCommand = command ? command : _buildCommandLineCommand(_getTrimmedInput());
if (filteredCommand.has_value())
{
return;
if (_commandLineHistory.Size() == CommandLineHistoryLength)
{
_commandLineHistory.RemoveAtEnd();
}
_commandLineHistory.InsertAt(0, filteredCommand.value());
TraceLoggingWrite(
g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
"CommandPaletteDispatchedCommandline",
TraceLoggingDescription("Event emitted when the user runs a commandline in the Command Palette"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
if (_dispatch.DoAction(filteredCommand.value().Command().Action()))
{
_close();
}
}
}
std::optional<winrt::TerminalApp::FilteredCommand> CommandPalette::_buildCommandLineCommand(std::wstring const& commandLine)
{
if (commandLine.empty())
{
return std::nullopt;
}
// Build the ExecuteCommandline action from the values we've parsed on the commandline.
ExecuteCommandlineArgs args{ cmdline };
ExecuteCommandlineArgs args{ commandLine };
ActionAndArgs executeActionAndArgs{ ShortcutAction::ExecuteCommandline, args };
TraceLoggingWrite(
g_hTerminalAppProvider, // handle to TerminalApp tracelogging provider
"CommandPaletteDispatchedCommandline",
TraceLoggingDescription("Event emitted when the user runs a commandline in the Command Palette"),
TraceLoggingKeyword(MICROSOFT_KEYWORD_MEASURES),
TelemetryPrivacyDataTag(PDT_ProductAndServicePerformance));
if (_dispatch.DoAction(executeActionAndArgs))
{
_close();
}
Command command{};
command.Action(executeActionAndArgs);
command.Name(commandLine);
return winrt::make<FilteredCommand>(command);
}
// Method Description:
@ -698,7 +707,9 @@ namespace winrt::TerminalApp::implementation
_lastFilterTextWasEmpty = _searchBox().Text().empty();
_updateFilteredActions();
_filteredActionsView().SelectedIndex(0);
// In the command line mode we want the user to explicitly select the command
_filteredActionsView().SelectedIndex(_currentMode == CommandPaletteMode::CommandlineMode ? -1 : 0);
if (_currentMode == CommandPaletteMode::TabSearchMode || _currentMode == CommandPaletteMode::ActionMode)
{
@ -871,7 +882,7 @@ namespace winrt::TerminalApp::implementation
// We want to present the commands sorted,
// unless we are in the TabSwitcherMode and TabSearchMode,
// in which we want to preserve the original order (to be aligned with the tab view)
if (_currentMode != CommandPaletteMode::TabSearchMode && _currentMode != CommandPaletteMode::TabSwitchMode)
if (_currentMode != CommandPaletteMode::TabSearchMode && _currentMode != CommandPaletteMode::TabSwitchMode && _currentMode != CommandPaletteMode::CommandlineMode)
{
std::sort(actions.begin(), actions.end(), FilteredCommand::Compare);
}
@ -887,12 +898,6 @@ namespace winrt::TerminalApp::implementation
// - <none>
void CommandPalette::_updateFilteredActions()
{
if (_currentMode == CommandPaletteMode::CommandlineMode)
{
_filteredActions.Clear();
return;
}
auto actions = _collectFilteredActions();
// Make _filteredActions look identical to actions, using only Insert and Remove.

View File

@ -117,12 +117,17 @@ namespace winrt::TerminalApp::implementation
winrt::Windows::UI::Xaml::Controls::ListView::SizeChanged_revoker _sizeChangedRevoker;
void _dispatchCommand(winrt::TerminalApp::FilteredCommand const& command);
void _dispatchCommandline();
void _dispatchCommandline(winrt::TerminalApp::FilteredCommand const& command);
std::optional<winrt::TerminalApp::FilteredCommand> _buildCommandLineCommand(std::wstring const& commandLine);
void _dismissPalette();
void _scrollToIndex(uint32_t index);
uint32_t _getNumVisibleItems();
static constexpr int CommandLineHistoryLength = 10;
Windows::Foundation::Collections::IVector<winrt::TerminalApp::FilteredCommand> _commandLineHistory{ nullptr };
friend class TerminalAppLocalTests::TabTests;
};
}