Skip to content

Commit 3afe7a8

Browse files
authored
Add a useCommandline property to the suggestions action (#15027)
_targets #14943_ When this is true, this will re-use the existing commandline to pre-filter the results. This is especially helpful for completing a suggestion based on the text that's already been typed. Like with command history, this requires that shell integration is enabled before it will work.## Summary of the Pull Request ## References and Relevant Issues See also #13445 As spec'd in #14864 ## Validation Steps Performed Tested manually
1 parent 8f4c63e commit 3afe7a8

File tree

16 files changed

+101
-41
lines changed

16 files changed

+101
-41
lines changed

src/buffer/out/textBuffer.cpp

Lines changed: 16 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2985,6 +2985,22 @@ void TextBuffer::_trimMarksOutsideBuffer()
29852985
_marks.end());
29862986
}
29872987

2988+
std::wstring_view TextBuffer::CurrentCommand() const
2989+
{
2990+
if (_marks.size() == 0)
2991+
{
2992+
return L"";
2993+
}
2994+
2995+
const auto& curr{ _marks.back() };
2996+
const auto& start{ curr.end };
2997+
const auto& end{ GetCursor().GetPosition() };
2998+
2999+
const auto line = start.y;
3000+
const auto& row = GetRowByOffset(line);
3001+
return row.GetText(start.x, end.x);
3002+
}
3003+
29883004
void TextBuffer::SetCurrentPromptEnd(const til::point pos) noexcept
29893005
{
29903006
if (_marks.empty())

src/buffer/out/textBuffer.hpp

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -276,6 +276,7 @@ class TextBuffer final
276276
void SetCurrentPromptEnd(const til::point pos) noexcept;
277277
void SetCurrentCommandEnd(const til::point pos) noexcept;
278278
void SetCurrentOutputEnd(const til::point pos, ::MarkCategory category) noexcept;
279+
std::wstring_view CurrentCommand() const;
279280

280281
private:
281282
void _reserve(til::size screenBufferSize, const TextAttribute& defaultAttributes);

src/cascadia/TerminalApp/AppActionHandlers.cpp

Lines changed: 4 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1273,9 +1273,11 @@ namespace winrt::TerminalApp::implementation
12731273
if (const auto& control{ _GetActiveControl() })
12741274
{
12751275
const auto context = control.CommandHistory();
1276+
const auto& currentCmd{ realArgs.UseCommandline() ? context.CurrentCommandline() : L"" };
12761277
_OpenSuggestions(control,
1277-
Command::HistoryToCommands(context.History(), context.CurrentCommandline(), false),
1278-
SuggestionsMode::Palette);
1278+
Command::HistoryToCommands(context.History(), currentCmd, false),
1279+
SuggestionsMode::Palette,
1280+
currentCmd);
12791281
}
12801282
args.Handled(true);
12811283
}

src/cascadia/TerminalApp/SuggestionsControl.cpp

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1051,6 +1051,7 @@ namespace winrt::TerminalApp::implementation
10511051

10521052
void SuggestionsControl::Open(TerminalApp::SuggestionsMode mode,
10531053
const Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::Command>& commands,
1054+
winrt::hstring filter,
10541055
Windows::Foundation::Point anchor,
10551056
Windows::Foundation::Size space,
10561057
float characterHeight)
@@ -1101,5 +1102,8 @@ namespace winrt::TerminalApp::implementation
11011102
newMargin.Top = (_anchor.Y - actualSize.height);
11021103
}
11031104
Margin(newMargin);
1105+
1106+
_searchBox().Text(filter);
11041107
}
1108+
11051109
}

src/cascadia/TerminalApp/SuggestionsControl.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -42,6 +42,7 @@ namespace winrt::TerminalApp::implementation
4242

4343
void Open(TerminalApp::SuggestionsMode mode,
4444
const Windows::Foundation::Collections::IVector<Microsoft::Terminal::Settings::Model::Command>& commands,
45+
winrt::hstring filterText,
4546
Windows::Foundation::Point anchor,
4647
Windows::Foundation::Size space,
4748
float characterHeight);

src/cascadia/TerminalApp/SuggestionsControl.idl

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -40,7 +40,7 @@ namespace TerminalApp
4040
void SetActionMap(Microsoft.Terminal.Settings.Model.IActionMapView actionMap);
4141
void SelectNextItem(Boolean moveDown);
4242

43-
void Open(SuggestionsMode mode, IVector<Microsoft.Terminal.Settings.Model.Command> commands, Windows.Foundation.Point anchor, Windows.Foundation.Size space, Single characterHeight);
43+
void Open(SuggestionsMode mode, IVector<Microsoft.Terminal.Settings.Model.Command> commands, String filterText, Windows.Foundation.Point anchor, Windows.Foundation.Size space, Single characterHeight);
4444

4545
event Windows.Foundation.TypedEventHandler<SuggestionsControl, Microsoft.Terminal.Settings.Model.Command> DispatchCommandRequested;
4646
event Windows.Foundation.TypedEventHandler<Object, Microsoft.Terminal.Settings.Model.Command> PreviewAction;

src/cascadia/TerminalApp/TerminalPage.cpp

Lines changed: 10 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4718,7 +4718,7 @@ namespace winrt::TerminalApp::implementation
47184718
if (const auto& page{ weakThis.get() })
47194719
{
47204720
// Open the Suggestions UI with the commands from the control
4721-
page->_OpenSuggestions(sender.try_as<TermControl>(), commandsCollection, SuggestionsMode::Menu);
4721+
page->_OpenSuggestions(sender.try_as<TermControl>(), commandsCollection, SuggestionsMode::Menu, L"");
47224722
}
47234723
});
47244724
}
@@ -4728,7 +4728,9 @@ namespace winrt::TerminalApp::implementation
47284728
void TerminalPage::_OpenSuggestions(
47294729
const TermControl& sender,
47304730
IVector<Command> commandsCollection,
4731-
winrt::TerminalApp::SuggestionsMode mode)
4731+
winrt::TerminalApp::SuggestionsMode mode,
4732+
winrt::hstring filterText)
4733+
47324734
{
47334735
// ON THE UI THREAD
47344736
assert(Dispatcher().HasThreadAccess());
@@ -4761,7 +4763,12 @@ namespace winrt::TerminalApp::implementation
47614763
const auto realCursorPos{ controlTransform.TransformPoint({ cursorPos.X, cursorPos.Y }) }; // == controlTransform + cursorPos
47624764
const Windows::Foundation::Size windowDimensions{ gsl::narrow_cast<float>(ActualWidth()), gsl::narrow_cast<float>(ActualHeight()) };
47634765

4764-
sxnUi.Open(mode, commandsCollection, realCursorPos, windowDimensions, characterSize.Height);
4766+
sxnUi.Open(mode,
4767+
commandsCollection,
4768+
filterText,
4769+
realCursorPos,
4770+
windowDimensions,
4771+
characterSize.Height);
47654772
}
47664773

47674774
void TerminalPage::_ContextMenuOpened(const IInspectable& sender,

src/cascadia/TerminalApp/TerminalPage.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -519,7 +519,8 @@ namespace winrt::TerminalApp::implementation
519519
void _updatePaneResources(const winrt::Windows::UI::Xaml::ElementTheme& requestedTheme);
520520

521521
winrt::fire_and_forget _ControlCompletionsChangedHandler(const winrt::Windows::Foundation::IInspectable sender, const winrt::Microsoft::Terminal::Control::CompletionsChangedEventArgs args);
522-
void _OpenSuggestions(const Microsoft::Terminal::Control::TermControl& sender, Windows::Foundation::Collections::IVector<winrt::Microsoft::Terminal::Settings::Model::Command> commandsCollection, winrt::TerminalApp::SuggestionsMode mode);
522+
523+
void _OpenSuggestions(const Microsoft::Terminal::Control::TermControl& sender, Windows::Foundation::Collections::IVector<winrt::Microsoft::Terminal::Settings::Model::Command> commandsCollection, winrt::TerminalApp::SuggestionsMode mode, winrt::hstring filterText);
523524

524525
void _ShowWindowChangedHandler(const IInspectable sender, const winrt::Microsoft::Terminal::Control::ShowWindowArgs args);
525526

src/cascadia/TerminalControl/ControlCore.cpp

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1958,6 +1958,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
19581958
const auto& textBuffer = _terminal->GetTextBuffer();
19591959

19601960
std::vector<winrt::hstring> commands;
1961+
19611962
for (const auto& mark : _terminal->GetScrollMarks())
19621963
{
19631964
// The command text is between the `end` (which denotes the end of
@@ -1979,10 +1980,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
19791980
if (strEnd != std::string::npos)
19801981
{
19811982
const auto trimmed = commandText.substr(0, strEnd + 1);
1983+
19821984
commands.push_back(winrt::hstring{ trimmed });
19831985
}
19841986
}
19851987
auto context = winrt::make_self<CommandHistoryContext>(std::move(commands));
1988+
context->CurrentCommandline(winrt::hstring{ _terminal->CurrentCommand() });
19861989

19871990
return *context;
19881991
}

src/cascadia/TerminalCore/Terminal.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1451,6 +1451,16 @@ til::color Terminal::GetColorForMark(const ScrollMark& mark) const
14511451
}
14521452
}
14531453

1454+
std::wstring_view Terminal::CurrentCommand() const
1455+
{
1456+
if (_currentPromptState != PromptState::Command)
1457+
{
1458+
return L"";
1459+
}
1460+
1461+
return _activeBuffer().CurrentCommand();
1462+
}
1463+
14541464
void Terminal::ColorSelection(const TextAttribute& attr, winrt::Microsoft::Terminal::Core::MatchMode matchMode)
14551465
{
14561466
for (const auto [start, end] : _GetSelectionSpans())

src/cascadia/TerminalCore/Terminal.hpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -119,6 +119,8 @@ class Microsoft::Terminal::Core::Terminal final :
119119
const til::point& end,
120120
const bool fromUi);
121121

122+
std::wstring_view CurrentCommand() const;
123+
122124
#pragma region ITerminalApi
123125
// These methods are defined in TerminalApi.cpp
124126
void ReturnResponse(const std::wstring_view response) override;

src/cascadia/TerminalSettingsModel/ActionArgs.cpp

Lines changed: 13 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -709,12 +709,23 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
709709

710710
winrt::hstring SuggestionsArgs::GenerateName() const
711711
{
712+
auto base{ RS_(L"SuggestionsCommandKey") };
712713
switch (Source())
713714
{
714715
case SuggestionsSource::CommandHistory:
715-
return RS_(L"SuggestionsCommandHistoryCommandKey");
716+
base = RS_(L"SuggestionsCommandHistoryCommandKey");
717+
}
718+
719+
if (UseCommandline())
720+
{
721+
return winrt::hstring{
722+
fmt::format(L"{}, useCommandline:true", std::wstring_view(base))
723+
};
724+
}
725+
else
726+
{
727+
return base;
716728
}
717-
return RS_(L"SuggestionsCommandKey");
718729
}
719730

720731
winrt::hstring FindMatchArgs::GenerateName() const

src/cascadia/TerminalSettingsModel/ActionArgs.h

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -215,8 +215,9 @@ private: \
215215
X(CommandPaletteLaunchMode, LaunchMode, "launchMode", false, CommandPaletteLaunchMode::Action)
216216

217217
////////////////////////////////////////////////////////////////////////////////
218-
#define SUGGESTIONS_ARGS(X) \
219-
X(SuggestionsSource, Source, "source", false, SuggestionsSource::Tasks)
218+
#define SUGGESTIONS_ARGS(X) \
219+
X(SuggestionsSource, Source, "source", false, SuggestionsSource::Tasks) \
220+
X(bool, UseCommandline, "useCommandline", false, false)
220221

221222
////////////////////////////////////////////////////////////////////////////////
222223
#define FIND_MATCH_ARGS(X) \

src/cascadia/TerminalSettingsModel/ActionArgs.idl

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -327,8 +327,9 @@ namespace Microsoft.Terminal.Settings.Model
327327
[default_interface] runtimeclass SuggestionsArgs : IActionArgs
328328
{
329329
SuggestionsArgs();
330-
SuggestionsArgs(SuggestionsSource source);
330+
SuggestionsArgs(SuggestionsSource source, Boolean useCommandline);
331331
SuggestionsSource Source { get; };
332+
Boolean UseCommandline { get; };
332333
};
333334

334335
[default_interface] runtimeclass FindMatchArgs : IActionArgs

src/cascadia/TerminalSettingsModel/Command.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -738,7 +738,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
738738
// * If directories is true, we'll prepend "cd " to each command, so that
739739
// the command will be run as a directory change instead.
740740
IVector<Model::Command> Command::HistoryToCommands(IVector<winrt::hstring> history,
741-
winrt::hstring /*currentCommandline*/,
741+
winrt::hstring currentCommandline,
742742
bool directories)
743743
{
744744
std::wstring cdText = directories ? L"cd " : L"";
@@ -747,7 +747,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
747747
// Use this map to discard duplicates.
748748
std::unordered_map<std::wstring_view, bool> foundCommands{};
749749

750-
auto backspaces = std::wstring(::base::saturated_cast<size_t>(0), L'\x7f');
750+
auto backspaces = std::wstring(currentCommandline.size(), L'\x7f');
751751

752752
// Iterate in reverse over the history, so that most recent commands are first
753753
for (auto i = history.Size(); i > 0; i--)

src/cascadia/TerminalSettingsModel/Resources/en-US/Resources.resw

Lines changed: 27 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,17 @@
11
<?xml version="1.0" encoding="utf-8"?>
22
<root>
3-
<!--
4-
Microsoft ResX Schema
5-
3+
<!--
4+
Microsoft ResX Schema
5+
66
Version 2.0
7-
8-
The primary goals of this format is to allow a simple XML format
9-
that is mostly human readable. The generation and parsing of the
10-
various data types are done through the TypeConverter classes
7+
8+
The primary goals of this format is to allow a simple XML format
9+
that is mostly human readable. The generation and parsing of the
10+
various data types are done through the TypeConverter classes
1111
associated with the data types.
12-
12+
1313
Example:
14-
14+
1515
... ado.net/XML headers & schema ...
1616
<resheader name="resmimetype">text/microsoft-resx</resheader>
1717
<resheader name="version">2.0</resheader>
@@ -26,36 +26,36 @@
2626
<value>[base64 mime encoded string representing a byte array form of the .NET Framework object]</value>
2727
<comment>This is a comment</comment>
2828
</data>
29-
30-
There are any number of "resheader" rows that contain simple
29+
30+
There are any number of "resheader" rows that contain simple
3131
name/value pairs.
32-
33-
Each data row contains a name, and value. The row also contains a
34-
type or mimetype. Type corresponds to a .NET class that support
35-
text/value conversion through the TypeConverter architecture.
36-
Classes that don't support this are serialized and stored with the
32+
33+
Each data row contains a name, and value. The row also contains a
34+
type or mimetype. Type corresponds to a .NET class that support
35+
text/value conversion through the TypeConverter architecture.
36+
Classes that don't support this are serialized and stored with the
3737
mimetype set.
38-
39-
The mimetype is used for serialized objects, and tells the
40-
ResXResourceReader how to depersist the object. This is currently not
38+
39+
The mimetype is used for serialized objects, and tells the
40+
ResXResourceReader how to depersist the object. This is currently not
4141
extensible. For a given mimetype the value must be set accordingly:
42-
43-
Note - application/x-microsoft.net.object.binary.base64 is the format
44-
that the ResXResourceWriter will generate, however the reader can
42+
43+
Note - application/x-microsoft.net.object.binary.base64 is the format
44+
that the ResXResourceWriter will generate, however the reader can
4545
read any of the formats listed below.
46-
46+
4747
mimetype: application/x-microsoft.net.object.binary.base64
48-
value : The object must be serialized with
48+
value : The object must be serialized with
4949
: System.Runtime.Serialization.Formatters.Binary.BinaryFormatter
5050
: and then encoded with base64 encoding.
51-
51+
5252
mimetype: application/x-microsoft.net.object.soap.base64
53-
value : The object must be serialized with
53+
value : The object must be serialized with
5454
: System.Runtime.Serialization.Formatters.Soap.SoapFormatter
5555
: and then encoded with base64 encoding.
5656
5757
mimetype: application/x-microsoft.net.object.bytearray.base64
58-
value : The object must be serialized into a byte array
58+
value : The object must be serialized into a byte array
5959
: using a System.ComponentModel.TypeConverter
6060
: and then encoded with base64 encoding.
6161
-->

0 commit comments

Comments
 (0)