diff --git a/src/buffer/out/textBuffer.cpp b/src/buffer/out/textBuffer.cpp index 7854ae2def5..d120b2e4a98 100644 --- a/src/buffer/out/textBuffer.cpp +++ b/src/buffer/out/textBuffer.cpp @@ -2985,6 +2985,22 @@ void TextBuffer::_trimMarksOutsideBuffer() _marks.end()); } +std::wstring_view TextBuffer::CurrentCommand() const +{ + if (_marks.size() == 0) + { + return L""; + } + + const auto& curr{ _marks.back() }; + const auto& start{ curr.end }; + const auto& end{ GetCursor().GetPosition() }; + + const auto line = start.y; + const auto& row = GetRowByOffset(line); + return row.GetText(start.x, end.x); +} + void TextBuffer::SetCurrentPromptEnd(const til::point pos) noexcept { if (_marks.empty()) diff --git a/src/buffer/out/textBuffer.hpp b/src/buffer/out/textBuffer.hpp index fe8d7e26834..d4cf6f74214 100644 --- a/src/buffer/out/textBuffer.hpp +++ b/src/buffer/out/textBuffer.hpp @@ -276,6 +276,7 @@ class TextBuffer final void SetCurrentPromptEnd(const til::point pos) noexcept; void SetCurrentCommandEnd(const til::point pos) noexcept; void SetCurrentOutputEnd(const til::point pos, ::MarkCategory category) noexcept; + std::wstring_view CurrentCommand() const; private: void _reserve(til::size screenBufferSize, const TextAttribute& defaultAttributes); diff --git a/src/cascadia/TerminalApp/AppActionHandlers.cpp b/src/cascadia/TerminalApp/AppActionHandlers.cpp index 2b953dd24a2..a65c3ddbab0 100644 --- a/src/cascadia/TerminalApp/AppActionHandlers.cpp +++ b/src/cascadia/TerminalApp/AppActionHandlers.cpp @@ -1273,9 +1273,11 @@ namespace winrt::TerminalApp::implementation if (const auto& control{ _GetActiveControl() }) { const auto context = control.CommandHistory(); + const auto& currentCmd{ realArgs.UseCommandline() ? context.CurrentCommandline() : L"" }; _OpenSuggestions(control, - Command::HistoryToCommands(context.History(), context.CurrentCommandline(), false), - SuggestionsMode::Palette); + Command::HistoryToCommands(context.History(), currentCmd, false), + SuggestionsMode::Palette, + currentCmd); } args.Handled(true); } diff --git a/src/cascadia/TerminalApp/SuggestionsControl.cpp b/src/cascadia/TerminalApp/SuggestionsControl.cpp index 528fe9f4b71..d70c9a6bc4d 100644 --- a/src/cascadia/TerminalApp/SuggestionsControl.cpp +++ b/src/cascadia/TerminalApp/SuggestionsControl.cpp @@ -1051,6 +1051,7 @@ namespace winrt::TerminalApp::implementation void SuggestionsControl::Open(TerminalApp::SuggestionsMode mode, const Windows::Foundation::Collections::IVector& commands, + winrt::hstring filter, Windows::Foundation::Point anchor, Windows::Foundation::Size space, float characterHeight) @@ -1101,5 +1102,8 @@ namespace winrt::TerminalApp::implementation newMargin.Top = (_anchor.Y - actualSize.height); } Margin(newMargin); + + _searchBox().Text(filter); } + } diff --git a/src/cascadia/TerminalApp/SuggestionsControl.h b/src/cascadia/TerminalApp/SuggestionsControl.h index 252332493b7..b156ab377c5 100644 --- a/src/cascadia/TerminalApp/SuggestionsControl.h +++ b/src/cascadia/TerminalApp/SuggestionsControl.h @@ -42,6 +42,7 @@ namespace winrt::TerminalApp::implementation void Open(TerminalApp::SuggestionsMode mode, const Windows::Foundation::Collections::IVector& commands, + winrt::hstring filterText, Windows::Foundation::Point anchor, Windows::Foundation::Size space, float characterHeight); diff --git a/src/cascadia/TerminalApp/SuggestionsControl.idl b/src/cascadia/TerminalApp/SuggestionsControl.idl index a565bc3d8b6..d76bb985579 100644 --- a/src/cascadia/TerminalApp/SuggestionsControl.idl +++ b/src/cascadia/TerminalApp/SuggestionsControl.idl @@ -40,7 +40,7 @@ namespace TerminalApp void SetActionMap(Microsoft.Terminal.Settings.Model.IActionMapView actionMap); void SelectNextItem(Boolean moveDown); - void Open(SuggestionsMode mode, IVector commands, Windows.Foundation.Point anchor, Windows.Foundation.Size space, Single characterHeight); + void Open(SuggestionsMode mode, IVector commands, String filterText, Windows.Foundation.Point anchor, Windows.Foundation.Size space, Single characterHeight); event Windows.Foundation.TypedEventHandler DispatchCommandRequested; event Windows.Foundation.TypedEventHandler PreviewAction; diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp index 18515a8afa9..c9c31b85247 100644 --- a/src/cascadia/TerminalApp/TerminalPage.cpp +++ b/src/cascadia/TerminalApp/TerminalPage.cpp @@ -4718,7 +4718,7 @@ namespace winrt::TerminalApp::implementation if (const auto& page{ weakThis.get() }) { // Open the Suggestions UI with the commands from the control - page->_OpenSuggestions(sender.try_as(), commandsCollection, SuggestionsMode::Menu); + page->_OpenSuggestions(sender.try_as(), commandsCollection, SuggestionsMode::Menu, L""); } }); } @@ -4728,7 +4728,9 @@ namespace winrt::TerminalApp::implementation void TerminalPage::_OpenSuggestions( const TermControl& sender, IVector commandsCollection, - winrt::TerminalApp::SuggestionsMode mode) + winrt::TerminalApp::SuggestionsMode mode, + winrt::hstring filterText) + { // ON THE UI THREAD assert(Dispatcher().HasThreadAccess()); @@ -4761,7 +4763,12 @@ namespace winrt::TerminalApp::implementation const auto realCursorPos{ controlTransform.TransformPoint({ cursorPos.X, cursorPos.Y }) }; // == controlTransform + cursorPos const Windows::Foundation::Size windowDimensions{ gsl::narrow_cast(ActualWidth()), gsl::narrow_cast(ActualHeight()) }; - sxnUi.Open(mode, commandsCollection, realCursorPos, windowDimensions, characterSize.Height); + sxnUi.Open(mode, + commandsCollection, + filterText, + realCursorPos, + windowDimensions, + characterSize.Height); } void TerminalPage::_ContextMenuOpened(const IInspectable& sender, diff --git a/src/cascadia/TerminalApp/TerminalPage.h b/src/cascadia/TerminalApp/TerminalPage.h index e14b46fee72..2967954c343 100644 --- a/src/cascadia/TerminalApp/TerminalPage.h +++ b/src/cascadia/TerminalApp/TerminalPage.h @@ -519,7 +519,8 @@ namespace winrt::TerminalApp::implementation void _updatePaneResources(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme); winrt::fire_and_forget _ControlCompletionsChangedHandler(const winrt::Windows::Foundation::IInspectable sender, const winrt::Microsoft::Terminal::Control::CompletionsChangedEventArgs args); - void _OpenSuggestions(const Microsoft::Terminal::Control::TermControl& sender, Windows::Foundation::Collections::IVector commandsCollection, winrt::TerminalApp::SuggestionsMode mode); + + void _OpenSuggestions(const Microsoft::Terminal::Control::TermControl& sender, Windows::Foundation::Collections::IVector commandsCollection, winrt::TerminalApp::SuggestionsMode mode, winrt::hstring filterText); void _ShowWindowChangedHandler(const IInspectable sender, const winrt::Microsoft::Terminal::Control::ShowWindowArgs args); diff --git a/src/cascadia/TerminalControl/ControlCore.cpp b/src/cascadia/TerminalControl/ControlCore.cpp index eefbdd54856..87e98c0a1b7 100644 --- a/src/cascadia/TerminalControl/ControlCore.cpp +++ b/src/cascadia/TerminalControl/ControlCore.cpp @@ -1958,6 +1958,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation const auto& textBuffer = _terminal->GetTextBuffer(); std::vector commands; + for (const auto& mark : _terminal->GetScrollMarks()) { // The command text is between the `end` (which denotes the end of @@ -1979,10 +1980,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation if (strEnd != std::string::npos) { const auto trimmed = commandText.substr(0, strEnd + 1); + commands.push_back(winrt::hstring{ trimmed }); } } auto context = winrt::make_self(std::move(commands)); + context->CurrentCommandline(winrt::hstring{ _terminal->CurrentCommand() }); return *context; } diff --git a/src/cascadia/TerminalCore/Terminal.cpp b/src/cascadia/TerminalCore/Terminal.cpp index 7d35ef502dc..75161e5c7f0 100644 --- a/src/cascadia/TerminalCore/Terminal.cpp +++ b/src/cascadia/TerminalCore/Terminal.cpp @@ -1451,6 +1451,16 @@ til::color Terminal::GetColorForMark(const ScrollMark& mark) const } } +std::wstring_view Terminal::CurrentCommand() const +{ + if (_currentPromptState != PromptState::Command) + { + return L""; + } + + return _activeBuffer().CurrentCommand(); +} + void Terminal::ColorSelection(const TextAttribute& attr, winrt::Microsoft::Terminal::Core::MatchMode matchMode) { for (const auto [start, end] : _GetSelectionSpans()) diff --git a/src/cascadia/TerminalCore/Terminal.hpp b/src/cascadia/TerminalCore/Terminal.hpp index 9535e311cfb..8e63819bdb6 100644 --- a/src/cascadia/TerminalCore/Terminal.hpp +++ b/src/cascadia/TerminalCore/Terminal.hpp @@ -119,6 +119,8 @@ class Microsoft::Terminal::Core::Terminal final : const til::point& end, const bool fromUi); + std::wstring_view CurrentCommand() const; + #pragma region ITerminalApi // These methods are defined in TerminalApi.cpp void ReturnResponse(const std::wstring_view response) override; diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.cpp b/src/cascadia/TerminalSettingsModel/ActionArgs.cpp index 6dc778df909..1088ee27852 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.cpp +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.cpp @@ -709,12 +709,23 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation winrt::hstring SuggestionsArgs::GenerateName() const { + auto base{ RS_(L"SuggestionsCommandKey") }; switch (Source()) { case SuggestionsSource::CommandHistory: - return RS_(L"SuggestionsCommandHistoryCommandKey"); + base = RS_(L"SuggestionsCommandHistoryCommandKey"); + } + + if (UseCommandline()) + { + return winrt::hstring{ + fmt::format(L"{}, useCommandline:true", std::wstring_view(base)) + }; + } + else + { + return base; } - return RS_(L"SuggestionsCommandKey"); } winrt::hstring FindMatchArgs::GenerateName() const diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.h b/src/cascadia/TerminalSettingsModel/ActionArgs.h index 8e278e16a3a..87e1ac4fcfe 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.h +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.h @@ -215,8 +215,9 @@ private: \ X(CommandPaletteLaunchMode, LaunchMode, "launchMode", false, CommandPaletteLaunchMode::Action) //////////////////////////////////////////////////////////////////////////////// -#define SUGGESTIONS_ARGS(X) \ - X(SuggestionsSource, Source, "source", false, SuggestionsSource::Tasks) +#define SUGGESTIONS_ARGS(X) \ + X(SuggestionsSource, Source, "source", false, SuggestionsSource::Tasks) \ + X(bool, UseCommandline, "useCommandline", false, false) //////////////////////////////////////////////////////////////////////////////// #define FIND_MATCH_ARGS(X) \ diff --git a/src/cascadia/TerminalSettingsModel/ActionArgs.idl b/src/cascadia/TerminalSettingsModel/ActionArgs.idl index b061eaae2fe..936165b8b28 100644 --- a/src/cascadia/TerminalSettingsModel/ActionArgs.idl +++ b/src/cascadia/TerminalSettingsModel/ActionArgs.idl @@ -327,8 +327,9 @@ namespace Microsoft.Terminal.Settings.Model [default_interface] runtimeclass SuggestionsArgs : IActionArgs { SuggestionsArgs(); - SuggestionsArgs(SuggestionsSource source); + SuggestionsArgs(SuggestionsSource source, Boolean useCommandline); SuggestionsSource Source { get; }; + Boolean UseCommandline { get; }; }; [default_interface] runtimeclass FindMatchArgs : IActionArgs diff --git a/src/cascadia/TerminalSettingsModel/Command.cpp b/src/cascadia/TerminalSettingsModel/Command.cpp index b34e5a02c2e..63d4e2dea6e 100644 --- a/src/cascadia/TerminalSettingsModel/Command.cpp +++ b/src/cascadia/TerminalSettingsModel/Command.cpp @@ -738,7 +738,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // * If directories is true, we'll prepend "cd " to each command, so that // the command will be run as a directory change instead. IVector Command::HistoryToCommands(IVector history, - winrt::hstring /*currentCommandline*/, + winrt::hstring currentCommandline, bool directories) { std::wstring cdText = directories ? L"cd " : L""; @@ -747,7 +747,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation // Use this map to discard duplicates. std::unordered_map foundCommands{}; - auto backspaces = std::wstring(::base::saturated_cast(0), L'\x7f'); + auto backspaces = std::wstring(currentCommandline.size(), L'\x7f'); // Iterate in reverse over the history, so that most recent commands are first for (auto i = history.Size(); i > 0; i--) diff --git a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw index 74035df755d..887d523fb0e 100644 --- a/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw +++ b/src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw @@ -1,17 +1,17 @@ -