diff --git a/src/cascadia/TerminalApp/FilteredCommand.cpp b/src/cascadia/TerminalApp/FilteredCommand.cpp
index 98a7b53de4b..d6c6c38a284 100644
--- a/src/cascadia/TerminalApp/FilteredCommand.cpp
+++ b/src/cascadia/TerminalApp/FilteredCommand.cpp
@@ -21,11 +21,22 @@ namespace winrt::TerminalApp::implementation
{
// This class is a wrapper of PaletteItem, that is used as an item of a filterable list in CommandPalette.
// It manages a highlighted text that is computed by matching search filter characters to item name
- FilteredCommand::FilteredCommand(const winrt::TerminalApp::PaletteItem& item) :
- _Item(item),
- _Filter(L""),
- _Weight(0)
+ FilteredCommand::FilteredCommand(const winrt::TerminalApp::PaletteItem& item)
{
+ // Actually implement the ctor in _constructFilteredCommand
+ _constructFilteredCommand(item);
+ }
+
+ // We need to actually implement the ctor in a separate helper. This is
+ // because we have a FilteredTask class which derives from FilteredCommand.
+ // HOWEVER, for cppwinrt ~ r e a s o n s ~, it doesn't actually derive from
+ // FilteredCommand directly, so we can't just use the FilteredCommand ctor
+ // directly in the base class.
+ void FilteredCommand::_constructFilteredCommand(const winrt::TerminalApp::PaletteItem& item)
+ {
+ _Item = item;
+ _Filter = L"";
+ _Weight = 0;
_HighlightedName = _computeHighlightedName();
// Recompute the highlighted name if the item name changes
diff --git a/src/cascadia/TerminalApp/FilteredCommand.h b/src/cascadia/TerminalApp/FilteredCommand.h
index e5df7bb018a..f304ad032a3 100644
--- a/src/cascadia/TerminalApp/FilteredCommand.h
+++ b/src/cascadia/TerminalApp/FilteredCommand.h
@@ -19,7 +19,7 @@ namespace winrt::TerminalApp::implementation
FilteredCommand() = default;
FilteredCommand(const winrt::TerminalApp::PaletteItem& item);
- void UpdateFilter(const winrt::hstring& filter);
+ virtual void UpdateFilter(const winrt::hstring& filter);
static int Compare(const winrt::TerminalApp::FilteredCommand& first, const winrt::TerminalApp::FilteredCommand& second);
@@ -29,6 +29,9 @@ namespace winrt::TerminalApp::implementation
WINRT_OBSERVABLE_PROPERTY(winrt::TerminalApp::HighlightedText, HighlightedName, PropertyChanged.raise);
WINRT_OBSERVABLE_PROPERTY(int, Weight, PropertyChanged.raise);
+ protected:
+ void _constructFilteredCommand(const winrt::TerminalApp::PaletteItem& item);
+
private:
winrt::TerminalApp::HighlightedText _computeHighlightedName();
int _computeWeight();
diff --git a/src/cascadia/TerminalApp/FilteredCommand.idl b/src/cascadia/TerminalApp/FilteredCommand.idl
index ce2b04b92c1..a63e6e81100 100644
--- a/src/cascadia/TerminalApp/FilteredCommand.idl
+++ b/src/cascadia/TerminalApp/FilteredCommand.idl
@@ -6,7 +6,7 @@ import "HighlightedTextControl.idl";
namespace TerminalApp
{
- [default_interface] runtimeclass FilteredCommand : Windows.UI.Xaml.Data.INotifyPropertyChanged
+ [default_interface] unsealed runtimeclass FilteredCommand : Windows.UI.Xaml.Data.INotifyPropertyChanged
{
FilteredCommand();
FilteredCommand(PaletteItem item);
diff --git a/src/cascadia/TerminalApp/Pane.cpp b/src/cascadia/TerminalApp/Pane.cpp
index eb153ce1ed8..96667a60fa1 100644
--- a/src/cascadia/TerminalApp/Pane.cpp
+++ b/src/cascadia/TerminalApp/Pane.cpp
@@ -2944,7 +2944,8 @@ void Pane::FinalizeConfigurationGivenDefault()
// - Returns true if the pane or one of its descendants is read-only
bool Pane::ContainsReadOnly() const
{
- return _IsLeaf() ? _content.ReadOnly() : (_firstChild->ContainsReadOnly() || _secondChild->ContainsReadOnly());
+ return _IsLeaf() ? (_content == nullptr ? false : _content.ReadOnly()) :
+ (_firstChild->ContainsReadOnly() || _secondChild->ContainsReadOnly());
}
// Method Description:
diff --git a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw
index efe3e1278e2..95babb6e4a6 100644
--- a/src/cascadia/TerminalApp/Resources/en-US/Resources.resw
+++ b/src/cascadia/TerminalApp/Resources/en-US/Resources.resw
@@ -907,6 +907,28 @@
Restart the active pane connection
+
+ Snippets
+ Header for a page that includes small "snippets" of text for the user to enter
+
+
+ Filter snippets...
+ Placeholder text for a text box to filter snippets (on the same page as the 'SnippetPaneTitle')
+
+
+ Input this command
+
+
+ Input this command
+
+
+ No snippets found in your settings.
+ Text shown to user when no snippets are found in their settings
+
+
+ Add some "Send input" actions in your settings to have them show up here.
+ Additional information presented to the user to let them know they can add a "Send input" action in their setting to populate the snippets pane
+
Action saved
diff --git a/src/cascadia/TerminalApp/SnippetsPaneContent.cpp b/src/cascadia/TerminalApp/SnippetsPaneContent.cpp
new file mode 100644
index 00000000000..7e8c1695543
--- /dev/null
+++ b/src/cascadia/TerminalApp/SnippetsPaneContent.cpp
@@ -0,0 +1,199 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+#include "pch.h"
+#include "SnippetsPaneContent.h"
+#include "SnippetsPaneContent.g.cpp"
+#include "FilteredTask.g.cpp"
+#include "Utils.h"
+
+using namespace winrt::Windows::Foundation;
+using namespace winrt::Windows::System;
+using namespace winrt::Microsoft::Terminal::Settings;
+using namespace winrt::Microsoft::Terminal::Settings::Model;
+
+namespace winrt
+{
+ namespace WUX = Windows::UI::Xaml;
+ namespace MUX = Microsoft::UI::Xaml;
+ using IInspectable = Windows::Foundation::IInspectable;
+}
+
+namespace winrt::TerminalApp::implementation
+{
+ SnippetsPaneContent::SnippetsPaneContent()
+ {
+ InitializeComponent();
+
+ WUX::Automation::AutomationProperties::SetName(*this, RS_(L"SnippetPaneTitle/Text"));
+ }
+
+ void SnippetsPaneContent::_updateFilteredCommands()
+ {
+ const auto& queryString = _filterBox().Text();
+
+ // DON'T replace the itemSource here. If you do, it'll un-expand all the
+ // nested items the user has expanded. Instead, just update the filter.
+ // That'll also trigger a PropertyChanged for the Visibility property.
+ for (const auto& t : _allTasks)
+ {
+ auto impl = winrt::get_self(t);
+ impl->UpdateFilter(queryString);
+ }
+ }
+
+ void SnippetsPaneContent::UpdateSettings(const CascadiaSettings& settings)
+ {
+ _settings = settings;
+
+ // You'd think that `FilterToSendInput(queryString)` would work. It
+ // doesn't! That uses the queryString as the current command the user
+ // has typed, then relies on the suggestions UI to _also_ filter with that
+ // string.
+
+ const auto tasks = _settings.GlobalSettings().ActionMap().FilterToSendInput(winrt::hstring{}); // IVector
+ _allTasks = winrt::single_threaded_observable_vector();
+ for (const auto& t : tasks)
+ {
+ const auto& filtered{ winrt::make(t) };
+ _allTasks.Append(filtered);
+ }
+ _treeView().ItemsSource(_allTasks);
+
+ _updateFilteredCommands();
+
+ PropertyChanged.raise(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"HasSnippets" });
+ }
+
+ bool SnippetsPaneContent::HasSnippets() const
+ {
+ return _allTasks.Size() != 0;
+ }
+
+ void SnippetsPaneContent::_filterTextChanged(const IInspectable& /*sender*/,
+ const Windows::UI::Xaml::RoutedEventArgs& /*args*/)
+ {
+ _updateFilteredCommands();
+ }
+
+ winrt::Windows::UI::Xaml::FrameworkElement SnippetsPaneContent::GetRoot()
+ {
+ return *this;
+ }
+ winrt::Windows::Foundation::Size SnippetsPaneContent::MinimumSize()
+ {
+ return { 200, 200 };
+ }
+ void SnippetsPaneContent::Focus(winrt::Windows::UI::Xaml::FocusState reason)
+ {
+ _filterBox().Focus(reason);
+ }
+ void SnippetsPaneContent::Close()
+ {
+ CloseRequested.raise(*this, nullptr);
+ }
+
+ INewContentArgs SnippetsPaneContent::GetNewTerminalArgs(BuildStartupKind /*kind*/) const
+ {
+ return BaseContentArgs(L"snippets");
+ }
+
+ winrt::hstring SnippetsPaneContent::Icon() const
+ {
+ static constexpr std::wstring_view glyph{ L"\xe70b" }; // QuickNote
+ return winrt::hstring{ glyph };
+ }
+
+ winrt::WUX::Media::Brush SnippetsPaneContent::BackgroundBrush()
+ {
+ static const auto key = winrt::box_value(L"UnfocusedBorderBrush");
+ return ThemeLookup(WUX::Application::Current().Resources(),
+ _settings.GlobalSettings().CurrentTheme().RequestedTheme(),
+ key)
+ .try_as();
+ }
+
+ void SnippetsPaneContent::SetLastActiveControl(const Microsoft::Terminal::Control::TermControl& control)
+ {
+ _control = control;
+ }
+
+ void SnippetsPaneContent::_runCommand(const Microsoft::Terminal::Settings::Model::Command& command)
+ {
+ if (const auto& strongControl{ _control.get() })
+ {
+ // By using the last active control as the sender here, the
+ // action dispatch will send this to the active control,
+ // thinking that it is the control that requested this event.
+ strongControl.Focus(winrt::WUX::FocusState::Programmatic);
+ DispatchCommandRequested.raise(strongControl, command);
+ }
+ }
+
+ void SnippetsPaneContent::_runCommandButtonClicked(const Windows::Foundation::IInspectable& sender,
+ const Windows::UI::Xaml::RoutedEventArgs&)
+ {
+ if (const auto& taskVM{ sender.try_as().DataContext().try_as() })
+ {
+ _runCommand(taskVM->Command());
+ }
+ }
+
+ // Called when one of the items in the list is tapped, or enter/space is
+ // pressed on it while focused. Notably, this isn't the Tapped event - it
+ // isn't called when the user clicks the dropdown arrow (that does usually
+ // also trigger a Tapped).
+ //
+ // We'll use this to toggle the expanded state of nested items, since the
+ // tree view arrow is so little
+ void SnippetsPaneContent::_treeItemInvokedHandler(const IInspectable& /*sender*/,
+ const MUX::Controls::TreeViewItemInvokedEventArgs& e)
+ {
+ // The InvokedItem here is the item in the data collection that was
+ // bound itself.
+ if (const auto& taskVM{ e.InvokedItem().try_as() })
+ {
+ if (taskVM->HasChildren())
+ {
+ // We then need to find the actual TreeViewItem for that
+ // FilteredTask.
+ if (const auto& item{ _treeView().ContainerFromItem(*taskVM).try_as() })
+ {
+ item.IsExpanded(!item.IsExpanded());
+ }
+ }
+ }
+ }
+
+ // Raised on individual TreeViewItems. We'll use this event to send the
+ // input on an Enter/Space keypress, when a leaf item is selected.
+ void SnippetsPaneContent::_treeItemKeyUpHandler(const IInspectable& sender,
+ const Windows::UI::Xaml::Input::KeyRoutedEventArgs& e)
+ {
+ const auto& item{ sender.try_as() };
+ if (!item)
+ {
+ return;
+ }
+ const auto& taskVM{ item.DataContext().try_as() };
+ if (!taskVM || taskVM->HasChildren())
+ {
+ return;
+ }
+
+ const auto& key = e.OriginalKey();
+ if (key == VirtualKey::Enter || key == VirtualKey::Space)
+ {
+ if (const auto& button = e.OriginalSource().try_as())
+ {
+ // Let the button handle the Enter key so an eventually attached click handler will be called
+ e.Handled(false);
+ return;
+ }
+
+ _runCommand(taskVM->Command());
+ e.Handled(true);
+ }
+ }
+
+}
diff --git a/src/cascadia/TerminalApp/SnippetsPaneContent.h b/src/cascadia/TerminalApp/SnippetsPaneContent.h
new file mode 100644
index 00000000000..493121c9150
--- /dev/null
+++ b/src/cascadia/TerminalApp/SnippetsPaneContent.h
@@ -0,0 +1,154 @@
+// Copyright (c) Microsoft Corporation.
+// Licensed under the MIT license.
+
+#pragma once
+#include "SnippetsPaneContent.g.h"
+#include "FilteredTask.g.h"
+#include "FilteredCommand.h"
+#include "ActionPaletteItem.h"
+#include
+
+namespace winrt::TerminalApp::implementation
+{
+ struct SnippetsPaneContent : SnippetsPaneContentT
+ {
+ SnippetsPaneContent();
+
+ winrt::Windows::UI::Xaml::FrameworkElement GetRoot();
+
+ void UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings& settings);
+
+ winrt::Windows::Foundation::Size MinimumSize();
+ void Focus(winrt::Windows::UI::Xaml::FocusState reason = winrt::Windows::UI::Xaml::FocusState::Programmatic);
+ void Close();
+ winrt::Microsoft::Terminal::Settings::Model::INewContentArgs GetNewTerminalArgs(BuildStartupKind kind) const;
+
+ winrt::hstring Title() { return RS_(L"SnippetPaneTitle/Text"); }
+ uint64_t TaskbarState() { return 0; }
+ uint64_t TaskbarProgress() { return 0; }
+ bool ReadOnly() { return false; }
+ winrt::hstring Icon() const;
+ Windows::Foundation::IReference TabColor() const noexcept { return nullptr; }
+ winrt::Windows::UI::Xaml::Media::Brush BackgroundBrush();
+
+ void SetLastActiveControl(const Microsoft::Terminal::Control::TermControl& control);
+ bool HasSnippets() const;
+
+ til::typed_event<> ConnectionStateChanged;
+ til::typed_event CloseRequested;
+ til::typed_event BellRequested;
+ til::typed_event TitleChanged;
+ til::typed_event TabColorChanged;
+ til::typed_event TaskbarProgressChanged;
+ til::typed_event ReadOnlyChanged;
+ til::typed_event FocusRequested;
+
+ til::typed_event DispatchCommandRequested;
+
+ til::property_changed_event PropertyChanged;
+
+ private:
+ friend struct SnippetsPaneContentT; // for Xaml to bind events
+
+ winrt::weak_ref _control{ nullptr };
+ winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr };
+ winrt::Windows::Foundation::Collections::IObservableVector _allTasks{ nullptr };
+
+ void _runCommandButtonClicked(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs&);
+ void _filterTextChanged(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& args);
+
+ void _updateFilteredCommands();
+ void _treeItemInvokedHandler(const Windows::Foundation::IInspectable& sender, const Microsoft::UI::Xaml::Controls::TreeViewItemInvokedEventArgs& e);
+ void _treeItemKeyUpHandler(const IInspectable& sender, const Windows::UI::Xaml::Input::KeyRoutedEventArgs& e);
+ void _runCommand(const Microsoft::Terminal::Settings::Model::Command& command);
+ };
+
+ struct FilteredTask : FilteredTaskT
+ {
+ FilteredTask() = default;
+
+ FilteredTask(const winrt::Microsoft::Terminal::Settings::Model::Command& command)
+ {
+ _filteredCommand = winrt::make_self(winrt::make(command, winrt::hstring{}));
+ _command = command;
+
+ // The Children() method must always return a non-null vector
+ _children = winrt::single_threaded_observable_vector();
+ if (_command.HasNestedCommands())
+ {
+ for (const auto& [_, child] : _command.NestedCommands())
+ {
+ auto vm{ winrt::make(child) };
+ _children.Append(vm);
+ }
+ }
+ }
+
+ void UpdateFilter(const winrt::hstring& filter)
+ {
+ _filteredCommand->UpdateFilter(filter);
+ for (const auto& c : _children)
+ {
+ auto impl = winrt::get_self(c);
+ impl->UpdateFilter(filter);
+ }
+
+ PropertyChanged.raise(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Visibility" });
+ }
+
+ winrt::hstring Input()
+ {
+ if (const auto& actionItem{ _filteredCommand->Item().try_as() })
+ {
+ if (const auto& command{ actionItem.Command() })
+ {
+ if (const auto& sendInput{ command.ActionAndArgs().Args().try_as() })
+ {
+ return winrt::hstring{ til::visualize_nonspace_control_codes(sendInput.Input().c_str()) };
+ }
+ }
+ }
+ return winrt::hstring{};
+ };
+
+ winrt::Windows::Foundation::Collections::IObservableVector Children() { return _children; }
+ bool HasChildren() { return _children.Size() > 0; }
+ winrt::Microsoft::Terminal::Settings::Model::Command Command() { return _command; }
+ winrt::TerminalApp::FilteredCommand FilteredCommand() { return *_filteredCommand; }
+
+ int32_t Row() { return HasChildren() ? 2 : 1; } // See the BODGY comment in the .XAML for explanation
+
+ // Used to control if this item is visible in the TreeView. Turns out,
+ // TreeView is in fact sane enough to remove items entirely if they're
+ // Collapsed.
+ winrt::Windows::UI::Xaml::Visibility Visibility()
+ {
+ // Is there no filter, or do we match it?
+ if (_filteredCommand->Filter().empty() || _filteredCommand->Weight() > 0)
+ {
+ return winrt::Windows::UI::Xaml::Visibility::Visible;
+ }
+ // If we don't match, maybe one of our children does
+ auto totalWeight = _filteredCommand->Weight();
+ for (const auto& c : _children)
+ {
+ auto impl = winrt::get_self(c);
+ totalWeight += impl->_filteredCommand->Weight();
+ }
+
+ return totalWeight > 0 ? winrt::Windows::UI::Xaml::Visibility::Visible : winrt::Windows::UI::Xaml::Visibility::Collapsed;
+ };
+
+ til::property_changed_event PropertyChanged;
+
+ private:
+ winrt::Microsoft::Terminal::Settings::Model::Command _command{ nullptr };
+ winrt::com_ptr _filteredCommand{ nullptr };
+ winrt::Windows::Foundation::Collections::IObservableVector _children{ nullptr };
+ };
+}
+
+namespace winrt::TerminalApp::factory_implementation
+{
+ BASIC_FACTORY(SnippetsPaneContent);
+}
diff --git a/src/cascadia/TerminalApp/SnippetsPaneContent.xaml b/src/cascadia/TerminalApp/SnippetsPaneContent.xaml
new file mode 100644
index 00000000000..a887b72b757
--- /dev/null
+++ b/src/cascadia/TerminalApp/SnippetsPaneContent.xaml
@@ -0,0 +1,261 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ #282828
+ #90ef90
+ #8888
+
+
+ #F9F9F9
+ #257f01
+ #88222222
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj
index 238fecf9afc..8549c32cd40 100644
--- a/src/cascadia/TerminalApp/TerminalAppLib.vcxproj
+++ b/src/cascadia/TerminalApp/TerminalAppLib.vcxproj
@@ -71,6 +71,9 @@
Designer
+
+ Designer
+
@@ -161,6 +164,9 @@
TerminalPaneContent.idl
+
+ SnippetsPaneContent.xaml
+
TerminalPaneContent.idl
@@ -274,6 +280,9 @@
TerminalPaneContent.idl
+
+ SnippetsPaneContent.xaml
+
TerminalPaneContent.idl
@@ -352,7 +361,10 @@
-
+
+ TaskPaneContent.xaml
+ Code
+
diff --git a/src/cascadia/TerminalApp/TerminalPage.cpp b/src/cascadia/TerminalApp/TerminalPage.cpp
index aa0bf06cf23..0e3dd5256bc 100644
--- a/src/cascadia/TerminalApp/TerminalPage.cpp
+++ b/src/cascadia/TerminalApp/TerminalPage.cpp
@@ -16,6 +16,7 @@
#include "DebugTapConnection.h"
#include "SettingsPaneContent.h"
#include "ScratchpadContent.h"
+#include "SnippetsPaneContent.h"
#include "TabRowControl.h"
#include "TerminalPage.g.cpp"
@@ -451,10 +452,10 @@ namespace winrt::TerminalApp::implementation
// - command - command to dispatch
// Return Value:
// -
- void TerminalPage::_OnDispatchCommandRequested(const IInspectable& /*sender*/, const Microsoft::Terminal::Settings::Model::Command& command)
+ void TerminalPage::_OnDispatchCommandRequested(const IInspectable& sender, const Microsoft::Terminal::Settings::Model::Command& command)
{
const auto& actionAndArgs = command.ActionAndArgs();
- _actionDispatch->DoAction(actionAndArgs);
+ _actionDispatch->DoAction(sender, actionAndArgs);
}
// Method Description:
@@ -620,9 +621,12 @@ namespace winrt::TerminalApp::implementation
// GH#6586: now that we're done processing all startup commands,
// focus the active control. This will work as expected for both
// commandline invocations and for `wt` action invocations.
- if (const auto control = _GetActiveControl())
+ if (const auto& terminalTab{ _GetFocusedTabImpl() })
{
- control.Focus(FocusState::Programmatic);
+ if (const auto& content{ terminalTab->GetActiveContent() })
+ {
+ content.Focus(FocusState::Programmatic);
+ }
}
}
if (initial)
@@ -2466,16 +2470,16 @@ namespace winrt::TerminalApp::implementation
}
_UnZoomIfNeeded();
- auto [original, _] = activeTab->SplitPane(*realSplitType, splitSize, newPane);
+ auto [original, newGuy] = activeTab->SplitPane(*realSplitType, splitSize, newPane);
// After GH#6586, the control will no longer focus itself
// automatically when it's finished being laid out. Manually focus
// the control here instead.
if (_startupState == StartupState::Initialized)
{
- if (const auto control = _GetActiveControl())
+ if (const auto& content{ newGuy->GetContent() })
{
- control.Focus(FocusState::Programmatic);
+ content.Focus(FocusState::Programmatic);
}
}
}
@@ -3270,6 +3274,8 @@ namespace winrt::TerminalApp::implementation
return resultPane;
}
+ // NOTE: callers of _MakePane should be able to accept nullptr as a return
+ // value gracefully.
std::shared_ptr TerminalPage::_MakePane(const INewContentArgs& contentArgs,
const winrt::TerminalApp::TabBase& sourceTab,
TerminalConnection::ITerminalConnection existingConnection)
@@ -3300,6 +3306,36 @@ namespace winrt::TerminalApp::implementation
{
content = _makeSettingsContent();
}
+ else if (paneType == L"snippets")
+ {
+ // Prevent the user from opening a bunch of snippets panes.
+ //
+ // Look at the focused tab, and if it already has one, then just focus it.
+ const bool found = _GetFocusedTab().try_as()->GetRootPane()->WalkTree([](const auto& p) -> bool {
+ if (const auto& snippets{ p->GetContent().try_as() })
+ {
+ snippets->Focus(FocusState::Programmatic);
+ return true;
+ }
+ return false;
+ });
+ // Bail out if we already found one.
+ if (found)
+ {
+ return nullptr;
+ }
+
+ const auto& tasksContent{ winrt::make_self() };
+ tasksContent->UpdateSettings(_settings);
+ tasksContent->GetRoot().KeyDown({ this, &TerminalPage::_KeyDownHandler });
+ tasksContent->DispatchCommandRequested({ this, &TerminalPage::_OnDispatchCommandRequested });
+ if (const auto& termControl{ _GetActiveControl() })
+ {
+ tasksContent->SetLastActiveControl(termControl);
+ }
+
+ content = *tasksContent;
+ }
assert(content);
diff --git a/src/cascadia/TerminalApp/TerminalPaneContent.idl b/src/cascadia/TerminalApp/TerminalPaneContent.idl
index 0e4738fff42..255ddef547b 100644
--- a/src/cascadia/TerminalApp/TerminalPaneContent.idl
+++ b/src/cascadia/TerminalApp/TerminalPaneContent.idl
@@ -3,6 +3,7 @@
import "IPaneContent.idl";
import "TerminalSettingsCache.idl";
+import "FilteredCommand.idl";
namespace TerminalApp
{
@@ -16,4 +17,22 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler RestartTerminalRequested;
}
+
+ [default_interface] runtimeclass FilteredTask : Windows.UI.Xaml.Data.INotifyPropertyChanged
+ {
+ String Input{ get; };
+ Windows.Foundation.Collections.IObservableVector Children { get; };
+ Boolean HasChildren { get; };
+ Int32 Row { get; };
+ Windows.UI.Xaml.Visibility Visibility { get; };
+ TerminalApp.FilteredCommand FilteredCommand{ get; };
+ }
+
+ [default_interface] runtimeclass SnippetsPaneContent : Windows.UI.Xaml.Controls.UserControl, IPaneContent, Windows.UI.Xaml.Data.INotifyPropertyChanged
+ {
+ SnippetsPaneContent();
+ void SetLastActiveControl(Microsoft.Terminal.Control.TermControl control);
+ Boolean HasSnippets { get; };
+ event Windows.Foundation.TypedEventHandler