Skip to content

Commit

Permalink
Add "recent commands" to Command Palette in commandline mode (#8317)
Browse files Browse the repository at this point in the history
## 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 #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
  • Loading branch information
Don-Vito authored Nov 25, 2020
1 parent d497dfd commit 274f5a7
Show file tree
Hide file tree
Showing 2 changed files with 53 additions and 43 deletions.
89 changes: 47 additions & 42 deletions src/cascadia/TerminalApp/CommandPalette.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down Expand Up @@ -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)
Expand Down Expand Up @@ -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;
}
Expand All @@ -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())
{
Expand Down Expand Up @@ -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());

// Build the ExecuteCommandline action from the values we've parsed on the commandline.
ExecuteCommandlineArgs args{ cmdline };
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));

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();
}
}
}

if (_dispatch.DoAction(executeActionAndArgs))
std::optional<winrt::TerminalApp::FilteredCommand> CommandPalette::_buildCommandLineCommand(std::wstring const& commandLine)
{
if (commandLine.empty())
{
_close();
return std::nullopt;
}

// Build the ExecuteCommandline action from the values we've parsed on the commandline.
ExecuteCommandlineArgs args{ commandLine };
ActionAndArgs executeActionAndArgs{ ShortcutAction::ExecuteCommandline, args };
Command command{};
command.Action(executeActionAndArgs);
command.Name(commandLine);
return winrt::make<FilteredCommand>(command);
}

// Method Description:
Expand Down Expand Up @@ -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)
{
Expand Down Expand Up @@ -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);
}
Expand All @@ -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.
Expand Down
7 changes: 6 additions & 1 deletion src/cascadia/TerminalApp/CommandPalette.h
Original file line number Diff line number Diff line change
Expand Up @@ -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;
};
}
Expand Down

0 comments on commit 274f5a7

Please sign in to comment.