Files
terminal/src/cascadia/TerminalApp/SnippetsPaneContent.h
2026-06-16 09:15:51 -05:00

150 lines
7.0 KiB
C++

// Copyright (c) Microsoft Corporation.
// Licensed under the MIT license.
#pragma once
#include "SnippetsPaneContent.g.h"
#include "FilteredTask.g.h"
#include "BasicPaneEvents.h"
#include "FilteredCommand.h"
#include "CommandPaletteItems.h"
namespace winrt::TerminalApp::implementation
{
struct SnippetsPaneContent : SnippetsPaneContentT<SnippetsPaneContent>, BasicPaneEvents
{
SnippetsPaneContent();
winrt::Windows::UI::Xaml::FrameworkElement GetRoot();
safe_void_coroutine UpdateSettings(const winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings& settings,
const winrt::Microsoft::Terminal::Settings::Model::WindowSettings& windowSettings);
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<winrt::Windows::UI::Color> TabColor() const noexcept { return nullptr; }
winrt::Windows::UI::Xaml::Media::Brush BackgroundBrush();
void SetLastActiveControl(const Microsoft::Terminal::Control::TermControl& control);
bool HasSnippets() const;
// See BasicPaneEvents for most generic event definitions
til::property_changed_event PropertyChanged;
private:
friend struct SnippetsPaneContentT<SnippetsPaneContent>; // for Xaml to bind events
winrt::weak_ref<Microsoft::Terminal::Control::TermControl> _control{ nullptr };
winrt::Microsoft::Terminal::Settings::Model::CascadiaSettings _settings{ nullptr };
winrt::Microsoft::Terminal::Settings::Model::WindowSettings _windowSettings{ nullptr };
winrt::Windows::Foundation::Collections::IObservableVector<TerminalApp::FilteredTask> _allTasks{ nullptr };
void _runCommandButtonClicked(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs&);
void _closePaneClick(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>
{
FilteredTask() = default;
FilteredTask(const winrt::Microsoft::Terminal::Settings::Model::Command& command)
{
_filteredCommand = winrt::make_self<implementation::FilteredCommand>(winrt::make<ActionPaletteItem>(command, winrt::hstring{}));
_command = command;
// The Children() method must always return a non-null vector
_children = winrt::single_threaded_observable_vector<TerminalApp::FilteredTask>();
if (_command.HasNestedCommands())
{
for (const auto& [_, child] : _command.NestedCommands())
{
auto vm{ winrt::make<FilteredTask>(child) };
_children.Append(vm);
}
}
}
void UpdateFilter(std::shared_ptr<fzf::matcher::Pattern> pattern)
{
_pattern = std::move(pattern);
_filteredCommand->UpdateFilter(_pattern);
for (const auto& c : _children)
{
auto impl = winrt::get_self<implementation::FilteredTask>(c);
impl->UpdateFilter(_pattern);
}
PropertyChanged.raise(*this, Windows::UI::Xaml::Data::PropertyChangedEventArgs{ L"Visibility" });
}
winrt::hstring Input()
{
// **SAFETY GUARANTEE** We constructed this filtered command ourselves; we know what's inside it.
const auto actionItem{ winrt::get_self<ActionPaletteItem>(_filteredCommand->Item()) };
if (const auto& command{ actionItem->Command() })
{
if (const auto& sendInput{ command.ActionAndArgs().Args().try_as<winrt::Microsoft::Terminal::Settings::Model::SendInputArgs>() })
{
return winrt::hstring{ til::visualize_nonspace_control_codes(std::wstring{ sendInput.Input() }) };
}
}
return winrt::hstring{};
};
winrt::Windows::Foundation::Collections::IObservableVector<TerminalApp::FilteredTask> Children() { return _children; }
bool HasChildren() { return _children.Size() > 0; }
winrt::Microsoft::Terminal::Settings::Model::Command Command() { return _command; }
winrt::TerminalApp::FilteredCommand FilteredCommand() { return *_filteredCommand; }
std::shared_ptr<fzf::matcher::Pattern> _pattern;
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 ((!_pattern || _pattern->terms.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<implementation::FilteredTask>(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<winrt::TerminalApp::implementation::FilteredCommand> _filteredCommand{ nullptr };
winrt::Windows::Foundation::Collections::IObservableVector<TerminalApp::FilteredTask> _children{ nullptr };
};
}
namespace winrt::TerminalApp::factory_implementation
{
BASIC_FACTORY(SnippetsPaneContent);
}