mirror of
https://github.com/microsoft/terminal.git
synced 2026-02-05 05:37:12 +00:00
PRE-MERGE #16848 Add support for custom CommandNotFound OSC
This commit is contained in:
@@ -174,6 +174,23 @@
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<!-- We need to include some additional files in the package for things like WinGet's Command Not Found -->
|
||||
<Target Name="IncludeAdditionalFilesInPackage">
|
||||
<PropertyGroup>
|
||||
<WinGetAdditionalPackageFileRoot>$(SolutionDir)\src\cascadia\TerminalControl</WinGetAdditionalPackageFileRoot>
|
||||
</PropertyGroup>
|
||||
<ItemGroup>
|
||||
<WinGetAdditionalPackageFile Include="$(WinGetAdditionalPackageFileRoot)\Microsoft.Management.Deployment.winmd">
|
||||
<PackagePath>Microsoft.Management.Deployment.winmd</PackagePath>
|
||||
</WinGetAdditionalPackageFile>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<AppxPackagePayload Include="%(WinGetAdditionalPackageFile.Identity))">
|
||||
<TargetPath>%(WinGetAdditionalPackageFile.PackagePath)</TargetPath>
|
||||
</AppxPackagePayload>
|
||||
</ItemGroup>
|
||||
</Target>
|
||||
|
||||
<!-- This is required to get the package dependency in the AppXManifest. -->
|
||||
<Import Project="$(OpenConsoleDir)src\common.nugetversions.targets" />
|
||||
|
||||
|
||||
@@ -1388,7 +1388,7 @@ namespace winrt::TerminalApp::implementation
|
||||
// requires context from the control)
|
||||
// then get that here.
|
||||
const bool shouldGetContext = realArgs.UseCommandline() ||
|
||||
WI_IsFlagSet(source, SuggestionsSource::CommandHistory);
|
||||
WI_IsAnyFlagSet(source, SuggestionsSource::CommandHistory | SuggestionsSource::QuickFixes);
|
||||
if (shouldGetContext)
|
||||
{
|
||||
if (const auto& control{ _GetActiveControl() })
|
||||
@@ -1421,7 +1421,19 @@ namespace winrt::TerminalApp::implementation
|
||||
if (WI_IsFlagSet(source, SuggestionsSource::CommandHistory) &&
|
||||
context != nullptr)
|
||||
{
|
||||
const auto recentCommands = Command::HistoryToCommands(context.History(), currentCommandline, false);
|
||||
// \ue81c --> History icon
|
||||
const auto recentCommands = Command::HistoryToCommands(context.History(), currentCommandline, false, hstring{ L"\ue81c" });
|
||||
for (const auto& t : recentCommands)
|
||||
{
|
||||
commandsCollection.push_back(t);
|
||||
}
|
||||
}
|
||||
|
||||
if (WI_IsFlagSet(source, SuggestionsSource::QuickFixes) &&
|
||||
context != nullptr)
|
||||
{
|
||||
// \ue74c --> OEM icon
|
||||
const auto recentCommands = Command::HistoryToCommands(context.QuickFixes(), hstring{ L"" }, false, hstring{ L"\ue74c" });
|
||||
for (const auto& t : recentCommands)
|
||||
{
|
||||
commandsCollection.push_back(t);
|
||||
|
||||
@@ -1743,6 +1743,8 @@ namespace winrt::TerminalApp::implementation
|
||||
|
||||
term.ShowWindowChanged({ get_weak(), &TerminalPage::_ShowWindowChangedHandler });
|
||||
|
||||
term.SearchMissingCommand({ get_weak(), &TerminalPage::_SearchMissingCommandHandler });
|
||||
|
||||
// Don't even register for the event if the feature is compiled off.
|
||||
if constexpr (Feature_ShellCompletions::IsEnabled())
|
||||
{
|
||||
@@ -1761,6 +1763,12 @@ namespace winrt::TerminalApp::implementation
|
||||
page->_PopulateContextMenu(weakTerm.get(), sender.try_as<MUX::Controls::CommandBarFlyout>(), true);
|
||||
}
|
||||
});
|
||||
term.QuickFixMenu().Opening([weak = get_weak(), weakTerm](auto&& sender, auto&& /*args*/) {
|
||||
if (const auto& page{ weak.get() })
|
||||
{
|
||||
page->_PopulateQuickFixMenu(weakTerm.get(), sender.try_as<Controls::MenuFlyout>());
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -2993,6 +3001,30 @@ namespace winrt::TerminalApp::implementation
|
||||
ShowWindowChanged.raise(*this, args);
|
||||
}
|
||||
|
||||
winrt::fire_and_forget TerminalPage::_SearchMissingCommandHandler(const IInspectable /*sender*/, const Microsoft::Terminal::Control::SearchMissingCommandEventArgs args)
|
||||
{
|
||||
assert(!Dispatcher().HasThreadAccess());
|
||||
|
||||
if (!Feature_QuickFix::IsEnabled())
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
|
||||
std::vector<hstring> suggestions;
|
||||
suggestions.reserve(1);
|
||||
suggestions.emplace_back(fmt::format(L"winget install {}", args.MissingCommand()));
|
||||
|
||||
co_await wil::resume_foreground(Dispatcher());
|
||||
|
||||
auto term = _GetActiveControl();
|
||||
if (!term)
|
||||
{
|
||||
co_return;
|
||||
}
|
||||
term.UpdateWinGetSuggestions(single_threaded_vector<hstring>(std::move(suggestions)));
|
||||
term.ShowQuickFixMenu();
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Paste text from the Windows Clipboard to the focused terminal
|
||||
void TerminalPage::_PasteText()
|
||||
@@ -4982,6 +5014,62 @@ namespace winrt::TerminalApp::implementation
|
||||
makeItem(RS_(L"TabClose"), L"\xE711", ActionAndArgs{ ShortcutAction::CloseTab, CloseTabArgs{ _GetFocusedTabIndex().value() } });
|
||||
}
|
||||
|
||||
void TerminalPage::_PopulateQuickFixMenu(const TermControl& control,
|
||||
const Controls::MenuFlyout& menu)
|
||||
{
|
||||
if (!control || !menu)
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
// Helper lambda for dispatching a SendInput ActionAndArgs onto the
|
||||
// ShortcutActionDispatch. Used below to wire up each menu entry to the
|
||||
// respective action. Then clear the quick fix menu.
|
||||
auto weak = get_weak();
|
||||
auto makeCallback = [weak](const hstring& suggestion) {
|
||||
return [weak, suggestion](auto&&, auto&&) {
|
||||
if (auto page{ weak.get() })
|
||||
{
|
||||
const auto actionAndArgs = ActionAndArgs{ ShortcutAction::SendInput, SendInputArgs{ hstring{ L"\u0003" } + suggestion } };
|
||||
page->_actionDispatch->DoAction(actionAndArgs);
|
||||
if (auto ctrl = page->_GetActiveControl())
|
||||
{
|
||||
ctrl.ClearQuickFix();
|
||||
}
|
||||
}
|
||||
};
|
||||
};
|
||||
|
||||
auto makeItem = [&menu, &makeCallback](const winrt::hstring& label,
|
||||
const winrt::hstring& icon,
|
||||
const winrt::hstring& suggestion) {
|
||||
MenuFlyoutItem item{};
|
||||
|
||||
if (!icon.empty())
|
||||
{
|
||||
auto iconElement = UI::IconPathConverter::IconWUX(icon);
|
||||
Automation::AutomationProperties::SetAccessibilityView(iconElement, Automation::Peers::AccessibilityView::Raw);
|
||||
item.Icon(iconElement);
|
||||
}
|
||||
|
||||
item.Text(label);
|
||||
item.Click(makeCallback(suggestion));
|
||||
menu.Items().Append(item);
|
||||
};
|
||||
|
||||
// Wire up each item to the action that should be performed. By actually
|
||||
// connecting these to actions, we ensure the implementation is
|
||||
// consistent. This also leaves room for customizing this menu with
|
||||
// actions in the future.
|
||||
|
||||
menu.Items().Clear();
|
||||
const auto quickFixes = control.CommandHistory().QuickFixes();
|
||||
for (const auto& qf : quickFixes)
|
||||
{
|
||||
makeItem(qf, L"\ue74c", qf);
|
||||
}
|
||||
}
|
||||
|
||||
// Handler for our WindowProperties's PropertyChanged event. We'll use this
|
||||
// to pop the "Identify Window" toast when the user renames our window.
|
||||
winrt::fire_and_forget TerminalPage::_windowPropertyChanged(const IInspectable& /*sender*/,
|
||||
|
||||
@@ -529,6 +529,7 @@ namespace winrt::TerminalApp::implementation
|
||||
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);
|
||||
|
||||
void _ShowWindowChangedHandler(const IInspectable sender, const winrt::Microsoft::Terminal::Control::ShowWindowArgs args);
|
||||
winrt::fire_and_forget _SearchMissingCommandHandler(const IInspectable sender, const winrt::Microsoft::Terminal::Control::SearchMissingCommandEventArgs args);
|
||||
|
||||
winrt::fire_and_forget _windowPropertyChanged(const IInspectable& sender, const winrt::Windows::UI::Xaml::Data::PropertyChangedEventArgs& args);
|
||||
|
||||
@@ -546,6 +547,7 @@ namespace winrt::TerminalApp::implementation
|
||||
void _sendDraggedTabToWindow(const winrt::hstring& windowId, const uint32_t tabIndex, std::optional<til::point> dragPoint);
|
||||
|
||||
void _PopulateContextMenu(const Microsoft::Terminal::Control::TermControl& control, const Microsoft::UI::Xaml::Controls::CommandBarFlyout& sender, const bool withSelection);
|
||||
void _PopulateQuickFixMenu(const Microsoft::Terminal::Control::TermControl& control, const Windows::UI::Xaml::Controls::MenuFlyout& sender);
|
||||
winrt::Windows::UI::Xaml::Controls::MenuFlyout _CreateRunAsAdminFlyout(int profileIndex);
|
||||
|
||||
winrt::Microsoft::Terminal::Control::TermControl _senderOrActiveControl(const winrt::Windows::Foundation::IInspectable& sender);
|
||||
|
||||
@@ -13,6 +13,7 @@
|
||||
#include <unicode.hpp>
|
||||
#include <utils.hpp>
|
||||
#include <WinUser.h>
|
||||
//#include <winrt/Microsoft.Management.Deployment.h>
|
||||
|
||||
#include "EventArgs.h"
|
||||
#include "../../renderer/atlas/AtlasEngine.h"
|
||||
@@ -23,6 +24,7 @@
|
||||
#include "ControlCore.g.cpp"
|
||||
#include "SelectionColor.g.cpp"
|
||||
|
||||
//using namespace winrt::Microsoft::Management::Deployment;
|
||||
using namespace ::Microsoft::Console::Types;
|
||||
using namespace ::Microsoft::Console::VirtualTerminal;
|
||||
using namespace ::Microsoft::Terminal::Core;
|
||||
@@ -128,6 +130,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
auto pfnCompletionsChanged = [=](auto&& menuJson, auto&& replaceLength) { _terminalCompletionsChanged(menuJson, replaceLength); };
|
||||
_terminal->CompletionsChangedCallback(pfnCompletionsChanged);
|
||||
|
||||
auto pfnSearchMissingCommand = [this](auto&& PH1) { _terminalSearchMissingCommand(std::forward<decltype(PH1)>(PH1)); };
|
||||
_terminal->SetSearchMissingCommandCallback(pfnSearchMissingCommand);
|
||||
|
||||
auto pfnClearQuickFix = [this] { _terminalClearQuickFix(); };
|
||||
_terminal->SetClearQuickFixCallback(pfnClearQuickFix);
|
||||
|
||||
// MSFT 33353327: Initialize the renderer in the ctor instead of Initialize().
|
||||
// We need the renderer to be ready to accept new engines before the SwapChainPanel is ready to go.
|
||||
// If we wait, a screen reader may try to get the AutomationPeer (aka the UIA Engine), and we won't be able to attach
|
||||
@@ -1627,6 +1635,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_midiAudio.PlayNote(reinterpret_cast<HWND>(_owningHwnd), noteNumber, velocity, std::chrono::duration_cast<std::chrono::milliseconds>(duration));
|
||||
}
|
||||
|
||||
void ControlCore::_terminalSearchMissingCommand(std::wstring_view missingCommand)
|
||||
{
|
||||
SearchMissingCommand.raise(*this, make<implementation::SearchMissingCommandEventArgs>(hstring{ missingCommand }));
|
||||
}
|
||||
|
||||
void ControlCore::_terminalClearQuickFix()
|
||||
{
|
||||
ClearQuickFix.raise(*this, nullptr);
|
||||
}
|
||||
|
||||
bool ControlCore::HasSelection() const
|
||||
{
|
||||
const auto lock = _terminal->LockForReading();
|
||||
@@ -2295,11 +2313,20 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
commands.pop_back();
|
||||
}
|
||||
|
||||
|
||||
auto context = winrt::make_self<CommandHistoryContext>(std::move(commands));
|
||||
context->CurrentCommandline(trimmedCurrentCommand);
|
||||
// TODO CARLOS: should we delete this after a new command is run? Or delete it after a suggestion is used? Or just after the next winget suggestion (current impl)?
|
||||
// No clue which we should do. Thoughts?
|
||||
context->QuickFixes(_cachedQuickFixes);
|
||||
return *context;
|
||||
}
|
||||
|
||||
void ControlCore::UpdateQuickFixes(const Windows::Foundation::Collections::IVector<hstring>& quickFixes)
|
||||
{
|
||||
_cachedQuickFixes = quickFixes;
|
||||
}
|
||||
|
||||
Core::Scheme ControlCore::ColorScheme() const noexcept
|
||||
{
|
||||
Core::Scheme s;
|
||||
|
||||
@@ -68,6 +68,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
til::property<Windows::Foundation::Collections::IVector<winrt::hstring>> History;
|
||||
til::property<winrt::hstring> CurrentCommandline;
|
||||
til::property<Windows::Foundation::Collections::IVector<winrt::hstring>> QuickFixes;
|
||||
|
||||
CommandHistoryContext(std::vector<winrt::hstring>&& history)
|
||||
{
|
||||
@@ -241,6 +242,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
hstring ReadEntireBuffer() const;
|
||||
Control::CommandHistoryContext CommandHistory() const;
|
||||
void UpdateQuickFixes(const Windows::Foundation::Collections::IVector<hstring>& quickFixes);
|
||||
|
||||
void AdjustOpacity(const float opacity, const bool relative);
|
||||
|
||||
@@ -283,6 +285,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::typed_event<IInspectable, Control::UpdateSelectionMarkersEventArgs> UpdateSelectionMarkers;
|
||||
til::typed_event<IInspectable, Control::OpenHyperlinkEventArgs> OpenHyperlink;
|
||||
til::typed_event<IInspectable, Control::CompletionsChangedEventArgs> CompletionsChanged;
|
||||
til::typed_event<IInspectable, Control::SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
til::typed_event<> ClearQuickFix;
|
||||
|
||||
til::typed_event<> CloseTerminalRequested;
|
||||
til::typed_event<> RestartTerminalRequested;
|
||||
@@ -352,6 +356,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
til::point _contextMenuBufferPosition{ 0, 0 };
|
||||
|
||||
Windows::Foundation::Collections::IVector<int32_t> _cachedSearchResultRows{ nullptr };
|
||||
Windows::Foundation::Collections::IVector<hstring> _cachedQuickFixes{ nullptr };
|
||||
|
||||
void _setupDispatcherAndCallbacks();
|
||||
|
||||
bool _setFontSizeUnderLock(float fontSize);
|
||||
@@ -375,6 +382,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _terminalPlayMidiNote(const int noteNumber,
|
||||
const int velocity,
|
||||
const std::chrono::microseconds duration);
|
||||
void _terminalSearchMissingCommand(std::wstring_view missingCommand);
|
||||
void _terminalClearQuickFix();
|
||||
|
||||
winrt::fire_and_forget _terminalCompletionsChanged(std::wstring_view menuJson, unsigned int replaceLength);
|
||||
|
||||
|
||||
@@ -70,6 +70,7 @@ namespace Microsoft.Terminal.Control
|
||||
{
|
||||
IVector<String> History { get; };
|
||||
String CurrentCommandline { get; };
|
||||
IVector<String> QuickFixes { get; };
|
||||
};
|
||||
|
||||
[default_interface] runtimeclass ControlCore : ICoreState
|
||||
@@ -174,6 +175,8 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> TaskbarProgressChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> RendererEnteredErrorState;
|
||||
event Windows.Foundation.TypedEventHandler<Object, ShowWindowArgs> ShowWindowChanged;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
event Windows.Foundation.TypedEventHandler<Object, Object> ClearQuickFix;
|
||||
|
||||
// These events are always called from the UI thread (bugs aside)
|
||||
event Windows.Foundation.TypedEventHandler<Object, FontSizeChangedArgs> FontSizeChanged;
|
||||
|
||||
@@ -18,3 +18,4 @@
|
||||
#include "KeySentEventArgs.g.cpp"
|
||||
#include "CharSentEventArgs.g.cpp"
|
||||
#include "StringSentEventArgs.g.cpp"
|
||||
#include "SearchMissingCommandEventArgs.g.cpp"
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
#include "KeySentEventArgs.g.h"
|
||||
#include "CharSentEventArgs.g.h"
|
||||
#include "StringSentEventArgs.g.h"
|
||||
#include "SearchMissingCommandEventArgs.g.h"
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
@@ -211,6 +212,15 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
WINRT_PROPERTY(winrt::hstring, Text);
|
||||
};
|
||||
|
||||
struct SearchMissingCommandEventArgs : public SearchMissingCommandEventArgsT<SearchMissingCommandEventArgs>
|
||||
{
|
||||
public:
|
||||
SearchMissingCommandEventArgs(const winrt::hstring& missingCommand) :
|
||||
_MissingCommand(missingCommand) {}
|
||||
|
||||
WINRT_PROPERTY(winrt::hstring, MissingCommand);
|
||||
};
|
||||
}
|
||||
|
||||
namespace winrt::Microsoft::Terminal::Control::factory_implementation
|
||||
|
||||
@@ -126,4 +126,9 @@ namespace Microsoft.Terminal.Control
|
||||
{
|
||||
String Text { get; };
|
||||
}
|
||||
|
||||
runtimeclass SearchMissingCommandEventArgs
|
||||
{
|
||||
String MissingCommand { get; };
|
||||
}
|
||||
}
|
||||
|
||||
Binary file not shown.
@@ -296,6 +296,12 @@ Please either install the missing font or choose another one.</value>
|
||||
<value>Select output</value>
|
||||
<comment>The tooltip for a button for selecting all of a command's output</comment>
|
||||
</data>
|
||||
<data name="QuickFixButton.ToolTipService.ToolTip" xml:space="preserve">
|
||||
<value>Quick fix</value>
|
||||
</data>
|
||||
<data name="QuickFixButton.[using:Windows.UI.Xaml.Automation]AutomationProperties.Name" xml:space="preserve">
|
||||
<value>Quick fix</value>
|
||||
</data>
|
||||
<data name="SessionRestoreMessage" xml:space="preserve">
|
||||
<value>Restored</value>
|
||||
<comment>"Restored" as in "This content was restored"</comment>
|
||||
|
||||
@@ -40,6 +40,9 @@ constexpr const auto UpdatePatternLocationsInterval = std::chrono::milliseconds(
|
||||
// The minimum delay between emitting warning bells
|
||||
constexpr const auto TerminalWarningBellInterval = std::chrono::milliseconds(1000);
|
||||
|
||||
constexpr std::wstring_view StateNormal{ L"Normal" };
|
||||
constexpr std::wstring_view StateCollapsed{ L"Collapsed" };
|
||||
|
||||
DEFINE_ENUM_FLAG_OPERATORS(winrt::Microsoft::Terminal::Control::CopyFormat);
|
||||
DEFINE_ENUM_FLAG_OPERATORS(winrt::Microsoft::Terminal::Control::MouseButtonState);
|
||||
|
||||
@@ -220,9 +223,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_revokers.CloseTerminalRequested = _core.CloseTerminalRequested(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleCloseTerminalRequested });
|
||||
_revokers.CompletionsChanged = _core.CompletionsChanged(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleCompletionsChanged });
|
||||
_revokers.RestartTerminalRequested = _core.RestartTerminalRequested(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleRestartTerminalRequested });
|
||||
_revokers.SearchMissingCommand = _core.SearchMissingCommand(winrt::auto_revoke, { get_weak(), &TermControl::_bubbleSearchMissingCommand });
|
||||
|
||||
_revokers.PasteFromClipboard = _interactivity.PasteFromClipboard(winrt::auto_revoke, { get_weak(), &TermControl::_bubblePasteFromClipboard });
|
||||
|
||||
_revokers.ClearQuickFix = _core.ClearQuickFix(winrt::auto_revoke, { get_weak(), &TermControl::_clearQuickFix });
|
||||
|
||||
// Initialize the terminal only once the swapchainpanel is loaded - that
|
||||
// way, we'll be able to query the real pixel size it got on layout
|
||||
_layoutUpdatedRevoker = SwapChainPanel().LayoutUpdated(winrt::auto_revoke, [this](auto /*s*/, auto /*e*/) {
|
||||
@@ -332,6 +338,29 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
});
|
||||
|
||||
if (Feature_QuickFix::IsEnabled())
|
||||
{
|
||||
auto quickFixBtn{ QuickFixButton() };
|
||||
quickFixBtn.PointerEntered({ get_weak(), &TermControl::QuickFixButton_PointerEntered });
|
||||
quickFixBtn.PointerExited({ get_weak(), &TermControl::QuickFixButton_PointerExited });
|
||||
}
|
||||
}
|
||||
|
||||
void TermControl::QuickFixButton_PointerEntered(const IInspectable& /*sender*/, const PointerRoutedEventArgs& /*e*/)
|
||||
{
|
||||
if (!_IsClosing() && _quickFixButtonCollapsible)
|
||||
{
|
||||
VisualStateManager::GoToState(*this, StateNormal, false);
|
||||
}
|
||||
}
|
||||
|
||||
void TermControl::QuickFixButton_PointerExited(const IInspectable& /*sender*/, const PointerRoutedEventArgs& /*e*/)
|
||||
{
|
||||
if (!_IsClosing() && _quickFixButtonCollapsible)
|
||||
{
|
||||
VisualStateManager::GoToState(*this, StateCollapsed, false);
|
||||
}
|
||||
}
|
||||
|
||||
// Function Description:
|
||||
@@ -808,6 +837,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
// When we hot reload the settings, the core will send us a scrollbar
|
||||
// update. If we enabled scrollbar marks, then great, when we handle
|
||||
// that message, we'll redraw them.
|
||||
|
||||
if (Feature_QuickFix::IsEnabled())
|
||||
{
|
||||
// update the position of the quick fix menu (in case we changed the padding)
|
||||
ShowQuickFixMenu();
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -2313,6 +2348,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
_updateSelectionMarkers(nullptr, winrt::make<UpdateSelectionMarkersEventArgs>(false));
|
||||
}
|
||||
|
||||
ShowQuickFixMenu();
|
||||
}
|
||||
|
||||
hstring TermControl::Title()
|
||||
@@ -3472,7 +3509,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const Control::FontSizeChangedArgs& args)
|
||||
{
|
||||
// scale the selection markers to be the size of a cell
|
||||
auto scaleMarker = [args, dpiScale{ SwapChainPanel().CompositionScaleX() }](const Windows::UI::Xaml::Shapes::Path& shape) {
|
||||
const auto dpiScale = SwapChainPanel().CompositionScaleX();
|
||||
auto scaleMarker = [args, &dpiScale](const Windows::UI::Xaml::Shapes::Path& shape) {
|
||||
// The selection markers were designed to be 5x14 in size,
|
||||
// so use those dimensions below for the scaling
|
||||
const auto scaleX = args.Width() / 5.0 / dpiScale;
|
||||
@@ -3488,6 +3526,14 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
};
|
||||
scaleMarker(SelectionStartMarker());
|
||||
scaleMarker(SelectionEndMarker());
|
||||
|
||||
if (Feature_QuickFix::IsEnabled())
|
||||
{
|
||||
auto quickFixBtn = QuickFixButton();
|
||||
quickFixBtn.Height(args.Height() / dpiScale);
|
||||
QuickFixIcon().FontSize(std::min(static_cast<double>(args.Width() / dpiScale), GetPadding().Left));
|
||||
ShowQuickFixMenu();
|
||||
}
|
||||
}
|
||||
|
||||
void TermControl::_coreRaisedNotice(const IInspectable& /*sender*/,
|
||||
@@ -3556,6 +3602,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
return _core.CommandHistory();
|
||||
}
|
||||
|
||||
void TermControl::UpdateWinGetSuggestions(Windows::Foundation::Collections::IVector<hstring> suggestions)
|
||||
{
|
||||
get_self<ControlCore>(_core)->UpdateQuickFixes(suggestions);
|
||||
}
|
||||
|
||||
Core::Scheme TermControl::ColorScheme() const noexcept
|
||||
{
|
||||
return _core.ColorScheme();
|
||||
@@ -3770,6 +3821,67 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
_showContextMenuAt(_toControlOrigin(cursorPos));
|
||||
}
|
||||
|
||||
double TermControl::CalculateQuickFixButtonWidth()
|
||||
{
|
||||
return GetPadding().Left;
|
||||
}
|
||||
|
||||
double TermControl::CalculateQuickFixButtonCollapsedWidth()
|
||||
{
|
||||
return GetPadding().Left / 3.0;
|
||||
}
|
||||
|
||||
void TermControl::ShowQuickFixMenu()
|
||||
{
|
||||
if (!_quickFixesAvailable)
|
||||
{
|
||||
QuickFixButton().Visibility(Visibility::Collapsed);
|
||||
return;
|
||||
}
|
||||
|
||||
auto quickFixBtn{ QuickFixButton() };
|
||||
|
||||
// If the gutter is narrow, display the collapsed version
|
||||
const auto& termPadding = GetPadding();
|
||||
|
||||
_quickFixButtonCollapsible = termPadding.Left < CharacterDimensions().Width;
|
||||
VisualStateManager::GoToState(*this, !_quickFixButtonCollapsible ? StateNormal : StateCollapsed, false);
|
||||
|
||||
const auto rd = get_self<ControlCore>(_core)->GetRenderData();
|
||||
rd->LockConsole();
|
||||
const auto viewportBufferPosition = rd->GetViewport();
|
||||
const auto cursorBufferPosition = rd->GetCursorPosition();
|
||||
rd->UnlockConsole();
|
||||
if (cursorBufferPosition.y < viewportBufferPosition.Top() || cursorBufferPosition.y > viewportBufferPosition.BottomExclusive())
|
||||
{
|
||||
quickFixBtn.Visibility(Visibility::Collapsed);
|
||||
return;
|
||||
}
|
||||
|
||||
// draw the button in the gutter
|
||||
const auto& cursorPosInDips = CursorPositionInDips();
|
||||
Controls::Canvas::SetLeft(quickFixBtn, -termPadding.Left);
|
||||
Controls::Canvas::SetTop(quickFixBtn, cursorPosInDips.Y);
|
||||
quickFixBtn.Visibility(Visibility::Visible);
|
||||
}
|
||||
|
||||
void TermControl::_bubbleSearchMissingCommand(const IInspectable& /*sender*/, const Control::SearchMissingCommandEventArgs& args)
|
||||
{
|
||||
_quickFixesAvailable = true;
|
||||
SearchMissingCommand.raise(*this, args);
|
||||
}
|
||||
|
||||
void TermControl::_clearQuickFix(const IInspectable& /*sender*/, const IInspectable& /*args*/)
|
||||
{
|
||||
_quickFixesAvailable = false;
|
||||
ShowQuickFixMenu();
|
||||
}
|
||||
|
||||
void TermControl::ClearQuickFix()
|
||||
{
|
||||
_clearQuickFix(nullptr, nullptr);
|
||||
}
|
||||
|
||||
void TermControl::_PasteCommandHandler(const IInspectable& /*sender*/,
|
||||
const IInspectable& /*args*/)
|
||||
{
|
||||
|
||||
@@ -75,6 +75,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
float SnapDimensionToGrid(const bool widthOrHeight, const float dimension);
|
||||
|
||||
Windows::Foundation::Point CursorPositionInDips();
|
||||
double CalculateQuickFixButtonWidth();
|
||||
double CalculateQuickFixButtonCollapsedWidth();
|
||||
|
||||
void WindowVisibilityChanged(const bool showOrHide);
|
||||
|
||||
@@ -167,6 +169,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
hstring ReadEntireBuffer() const;
|
||||
Control::CommandHistoryContext CommandHistory() const;
|
||||
void UpdateWinGetSuggestions(Windows::Foundation::Collections::IVector<hstring> suggestions);
|
||||
|
||||
winrt::Microsoft::Terminal::Core::Scheme ColorScheme() const noexcept;
|
||||
void ColorScheme(const winrt::Microsoft::Terminal::Core::Scheme& scheme) const noexcept;
|
||||
@@ -178,6 +181,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void RawWriteString(const winrt::hstring& text);
|
||||
|
||||
void ShowContextMenu();
|
||||
void ShowQuickFixMenu();
|
||||
void ClearQuickFix();
|
||||
|
||||
void Detach();
|
||||
|
||||
@@ -202,17 +207,18 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
til::typed_event<IInspectable, Control::KeySentEventArgs> KeySent;
|
||||
til::typed_event<IInspectable, Control::CharSentEventArgs> CharSent;
|
||||
til::typed_event<IInspectable, Control::StringSentEventArgs> StringSent;
|
||||
til::typed_event<IInspectable, Control::SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
|
||||
// UNDER NO CIRCUMSTANCES SHOULD YOU ADD A (PROJECTED_)FORWARDED_TYPED_EVENT HERE
|
||||
// Those attach the handler to the core directly, and will explode if
|
||||
// the core ever gets detached & reattached to another window.
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(TitleChanged, IInspectable, Control::TitleChangedEventArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(TabColorChanged, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(ConnectionStateChanged, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(ShowWindowChanged, IInspectable, Control::ShowWindowArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(CloseTerminalRequested, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(CompletionsChanged, IInspectable, Control::CompletionsChangedEventArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(TitleChanged, IInspectable, Control::TitleChangedEventArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(TabColorChanged, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(SetTaskbarProgress, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(ConnectionStateChanged, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(ShowWindowChanged, IInspectable, Control::ShowWindowArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(CloseTerminalRequested, IInspectable, IInspectable);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(CompletionsChanged, IInspectable, Control::CompletionsChangedEventArgs);
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(RestartTerminalRequested, IInspectable, IInspectable);
|
||||
|
||||
BUBBLED_FORWARDED_TYPED_EVENT(PasteFromClipboard, IInspectable, Control::PasteFromClipboardEventArgs);
|
||||
@@ -242,6 +248,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
bool _closing{ false };
|
||||
bool _focused{ false };
|
||||
bool _initializedTerminal{ false };
|
||||
bool _quickFixButtonCollapsible{ false };
|
||||
bool _quickFixesAvailable{ false };
|
||||
|
||||
std::shared_ptr<ThrottledFuncLeading> _playWarningBell;
|
||||
|
||||
@@ -332,6 +340,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _MouseWheelHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
|
||||
void _ScrollbarChangeHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Controls::Primitives::RangeBaseValueChangedEventArgs& e);
|
||||
|
||||
void QuickFixButton_PointerEntered(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
|
||||
void QuickFixButton_PointerExited(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::Input::PointerRoutedEventArgs& e);
|
||||
|
||||
void _GotFocusHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
void _LostFocusHandler(const Windows::Foundation::IInspectable& sender, const Windows::UI::Xaml::RoutedEventArgs& e);
|
||||
|
||||
@@ -394,6 +405,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
void _contextMenuHandler(IInspectable sender, Control::ContextMenuRequestedEventArgs args);
|
||||
void _showContextMenuAt(const til::point& controlRelativePos);
|
||||
|
||||
void _bubbleSearchMissingCommand(const IInspectable& sender, const Control::SearchMissingCommandEventArgs& args);
|
||||
void _clearQuickFix(const IInspectable& sender, const IInspectable& args);
|
||||
|
||||
void _PasteCommandHandler(const IInspectable& sender, const IInspectable& args);
|
||||
void _CopyCommandHandler(const IInspectable& sender, const IInspectable& args);
|
||||
void _SearchCommandHandler(const IInspectable& sender, const IInspectable& args);
|
||||
@@ -423,6 +437,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
Control::ControlCore::CloseTerminalRequested_revoker CloseTerminalRequested;
|
||||
Control::ControlCore::CompletionsChanged_revoker CompletionsChanged;
|
||||
Control::ControlCore::RestartTerminalRequested_revoker RestartTerminalRequested;
|
||||
Control::ControlCore::SearchMissingCommand_revoker SearchMissingCommand;
|
||||
Control::ControlCore::ClearQuickFix_revoker ClearQuickFix;
|
||||
|
||||
// These are set up in _InitializeTerminal
|
||||
Control::ControlCore::RendererWarning_revoker RendererWarning;
|
||||
|
||||
@@ -69,10 +69,12 @@ namespace Microsoft.Terminal.Control
|
||||
event Windows.Foundation.TypedEventHandler<Object, KeySentEventArgs> KeySent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, CharSentEventArgs> CharSent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, StringSentEventArgs> StringSent;
|
||||
event Windows.Foundation.TypedEventHandler<Object, SearchMissingCommandEventArgs> SearchMissingCommand;
|
||||
|
||||
|
||||
Microsoft.UI.Xaml.Controls.CommandBarFlyout ContextMenu { get; };
|
||||
Microsoft.UI.Xaml.Controls.CommandBarFlyout SelectionContextMenu { get; };
|
||||
Windows.UI.Xaml.Controls.MenuFlyout QuickFixMenu { get; };
|
||||
|
||||
event Windows.Foundation.TypedEventHandler<TermControl, Windows.UI.Xaml.RoutedEventArgs> Initialized;
|
||||
// This is an event handler forwarder for the underlying connection.
|
||||
@@ -125,6 +127,7 @@ namespace Microsoft.Terminal.Control
|
||||
|
||||
String ReadEntireBuffer();
|
||||
CommandHistoryContext CommandHistory();
|
||||
void UpdateWinGetSuggestions(Windows.Foundation.Collections.IVector<String> suggestions);
|
||||
|
||||
void AdjustOpacity(Single Opacity, Boolean relative);
|
||||
|
||||
@@ -141,8 +144,12 @@ namespace Microsoft.Terminal.Control
|
||||
void ColorSelection(SelectionColor fg, SelectionColor bg, Microsoft.Terminal.Core.MatchMode matchMode);
|
||||
|
||||
Windows.Foundation.Point CursorPositionInDips { get; };
|
||||
Double CalculateQuickFixButtonWidth { get; };
|
||||
Double CalculateQuickFixButtonCollapsedWidth { get; };
|
||||
|
||||
void ShowContextMenu();
|
||||
void ShowQuickFixMenu();
|
||||
void ClearQuickFix();
|
||||
|
||||
void Detach();
|
||||
}
|
||||
|
||||
@@ -1279,6 +1279,28 @@
|
||||
</ToolTip>
|
||||
</ToolTipService.ToolTip>
|
||||
</Border>
|
||||
|
||||
<Button x:Name="QuickFixButton"
|
||||
x:Uid="QuickFixButton"
|
||||
Width="{x:Bind CalculateQuickFixButtonWidth}"
|
||||
Padding="0"
|
||||
HorizontalContentAlignment="Center"
|
||||
VerticalContentAlignment="Center"
|
||||
AllowFocusOnInteraction="False"
|
||||
CornerRadius="0,5,5,0"
|
||||
Style="{StaticResource AccentButtonStyle}"
|
||||
Visibility="Collapsed">
|
||||
<Button.Content>
|
||||
<FontIcon x:Name="QuickFixIcon"
|
||||
HorizontalAlignment="Center"
|
||||
VerticalAlignment="Center"
|
||||
FontFamily="{ThemeResource SymbolThemeFontFamily}"
|
||||
Glyph="" />
|
||||
</Button.Content>
|
||||
<Button.Flyout>
|
||||
<MenuFlyout x:Name="QuickFixMenu" />
|
||||
</Button.Flyout>
|
||||
</Button>
|
||||
</Canvas>
|
||||
|
||||
<Canvas x:Name="SelectionCanvas"
|
||||
@@ -1353,6 +1375,18 @@
|
||||
</Border>
|
||||
</Grid>
|
||||
|
||||
<VisualStateManager.VisualStateGroups>
|
||||
<VisualStateGroup x:Name="QuickFixButtonStates">
|
||||
<VisualState x:Name="Normal" />
|
||||
<VisualState x:Name="Collapsed">
|
||||
<VisualState.Setters>
|
||||
<Setter Target="QuickFixButton.Width" Value="{x:Bind CalculateQuickFixButtonCollapsedWidth}" />
|
||||
<Setter Target="QuickFixButton.Background" Value="{ThemeResource SystemAccentColor}" />
|
||||
<Setter Target="QuickFixIcon.Visibility" Value="Collapsed" />
|
||||
</VisualState.Setters>
|
||||
</VisualState>
|
||||
</VisualStateGroup>
|
||||
</VisualStateManager.VisualStateGroups>
|
||||
</Grid>
|
||||
|
||||
</UserControl>
|
||||
|
||||
@@ -171,6 +171,13 @@
|
||||
<Private>false</Private>
|
||||
</ProjectReference>
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<Reference Include="$(OpenConsoleDir)src\cascadia\TerminalControl\Microsoft.Management.Deployment.winmd">
|
||||
<IsWinMDFile>true</IsWinMDFile>
|
||||
<Private>false</Private>
|
||||
<CopyLocalSatelliteAssemblies>false</CopyLocalSatelliteAssemblies>
|
||||
</Reference>
|
||||
</ItemGroup>
|
||||
<!-- ====================== Compiler & Linker Flags ===================== -->
|
||||
<ItemDefinitionGroup>
|
||||
<ClCompile>
|
||||
|
||||
@@ -699,34 +699,44 @@ TerminalInput::OutputType Terminal::SendCharEvent(const wchar_t ch, const WORD s
|
||||
vkey = _VirtualKeyFromCharacter(ch);
|
||||
}
|
||||
|
||||
// GH#1527: When the user has auto mark prompts enabled, we're going to try
|
||||
// and heuristically detect if this was the line the prompt was on.
|
||||
// * If the key was an Enter keypress (Terminal.app also marks ^C keypresses
|
||||
// as prompts. That's omitted for now.)
|
||||
// * AND we're not in the alt buffer
|
||||
//
|
||||
// Then treat this line like it's a prompt mark.
|
||||
if (_autoMarkPrompts && vkey == VK_RETURN && !_inAltBuffer())
|
||||
if (vkey == VK_RETURN && !_inAltBuffer())
|
||||
{
|
||||
// We need to be a little tricky here, to try and support folks that are
|
||||
// auto-marking prompts, but don't necessarily have the rest of shell
|
||||
// integration enabled.
|
||||
//
|
||||
// We'll set the current attributes to Output, so that the output after
|
||||
// here is marked as the command output. But we also need to make sure
|
||||
// that a mark was started.
|
||||
// We can't just check if the current row has a mark - there could be a
|
||||
// multiline prompt.
|
||||
//
|
||||
// (TextBuffer::_createPromptMarkIfNeeded does that work for us)
|
||||
|
||||
const bool createdMark = _activeBuffer().StartOutput();
|
||||
if (createdMark)
|
||||
// Treat VK_RETURN as a new prompt,
|
||||
// so we should clear the quick fix UI if it's visible.
|
||||
if (_pfnClearQuickFix)
|
||||
{
|
||||
_activeBuffer().ManuallyMarkRowAsPrompt(_activeBuffer().GetCursor().GetPosition().y);
|
||||
_pfnClearQuickFix();
|
||||
}
|
||||
|
||||
// This changed the scrollbar marks - raise a notification to update them
|
||||
_NotifyScrollEvent();
|
||||
// GH#1527: When the user has auto mark prompts enabled, we're going to try
|
||||
// and heuristically detect if this was the line the prompt was on.
|
||||
// * If the key was an Enter keypress (Terminal.app also marks ^C keypresses
|
||||
// as prompts. That's omitted for now.)
|
||||
// * AND we're not in the alt buffer
|
||||
//
|
||||
// Then treat this line like it's a prompt mark.
|
||||
if (_autoMarkPrompts)
|
||||
{
|
||||
// We need to be a little tricky here, to try and support folks that are
|
||||
// auto-marking prompts, but don't necessarily have the rest of shell
|
||||
// integration enabled.
|
||||
//
|
||||
// We'll set the current attributes to Output, so that the output after
|
||||
// here is marked as the command output. But we also need to make sure
|
||||
// that a mark was started.
|
||||
// We can't just check if the current row has a mark - there could be a
|
||||
// multiline prompt.
|
||||
//
|
||||
// (TextBuffer::_createPromptMarkIfNeeded does that work for us)
|
||||
|
||||
const bool createdMark = _activeBuffer().StartOutput();
|
||||
if (createdMark)
|
||||
{
|
||||
_activeBuffer().ManuallyMarkRowAsPrompt(_activeBuffer().GetCursor().GetPosition().y);
|
||||
|
||||
// This changed the scrollbar marks - raise a notification to update them
|
||||
_NotifyScrollEvent();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1227,6 +1237,16 @@ void Microsoft::Terminal::Core::Terminal::CompletionsChangedCallback(std::functi
|
||||
_pfnCompletionsChanged.swap(pfn);
|
||||
}
|
||||
|
||||
void Microsoft::Terminal::Core::Terminal::SetSearchMissingCommandCallback(std::function<void(std::wstring_view)> pfn) noexcept
|
||||
{
|
||||
_pfnSearchMissingCommand.swap(pfn);
|
||||
}
|
||||
|
||||
void Microsoft::Terminal::Core::Terminal::SetClearQuickFixCallback(std::function<void()> pfn) noexcept
|
||||
{
|
||||
_pfnClearQuickFix.swap(pfn);
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Stores the search highlighted regions in the terminal
|
||||
void Terminal::SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept
|
||||
|
||||
@@ -157,6 +157,8 @@ public:
|
||||
|
||||
void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override;
|
||||
|
||||
void SearchMissingCommand(const std::wstring_view command) override;
|
||||
|
||||
#pragma endregion
|
||||
|
||||
void ClearMark();
|
||||
@@ -229,6 +231,8 @@ public:
|
||||
void SetShowWindowCallback(std::function<void(bool)> pfn) noexcept;
|
||||
void SetPlayMidiNoteCallback(std::function<void(const int, const int, const std::chrono::microseconds)> pfn) noexcept;
|
||||
void CompletionsChangedCallback(std::function<void(std::wstring_view, unsigned int)> pfn) noexcept;
|
||||
void SetSearchMissingCommandCallback(std::function<void(std::wstring_view)> pfn) noexcept;
|
||||
void SetClearQuickFixCallback(std::function<void()> pfn) noexcept;
|
||||
void SetSearchHighlights(const std::vector<til::point_span>& highlights) noexcept;
|
||||
void SetSearchHighlightFocused(const size_t focusedIdx);
|
||||
|
||||
@@ -338,6 +342,8 @@ private:
|
||||
std::function<void(bool)> _pfnShowWindowChanged;
|
||||
std::function<void(const int, const int, const std::chrono::microseconds)> _pfnPlayMidiNote;
|
||||
std::function<void(std::wstring_view, unsigned int)> _pfnCompletionsChanged;
|
||||
std::function<void(std::wstring_view)> _pfnSearchMissingCommand;
|
||||
std::function<void()> _pfnClearQuickFix;
|
||||
|
||||
RenderSettings _renderSettings;
|
||||
std::unique_ptr<::Microsoft::Console::VirtualTerminal::StateMachine> _stateMachine;
|
||||
|
||||
@@ -333,6 +333,14 @@ void Terminal::InvokeCompletions(std::wstring_view menuJson, unsigned int replac
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::SearchMissingCommand(const std::wstring_view command)
|
||||
{
|
||||
if (_pfnSearchMissingCommand)
|
||||
{
|
||||
_pfnSearchMissingCommand(command);
|
||||
}
|
||||
}
|
||||
|
||||
void Terminal::NotifyBufferRotation(const int delta)
|
||||
{
|
||||
// Update our selection, so it doesn't move as the buffer is cycled
|
||||
|
||||
@@ -937,6 +937,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
|
||||
BASIC_FACTORY(SetTabColorArgs);
|
||||
BASIC_FACTORY(RenameTabArgs);
|
||||
BASIC_FACTORY(SwapPaneArgs);
|
||||
BASIC_FACTORY(SendInputArgs);
|
||||
BASIC_FACTORY(SplitPaneArgs);
|
||||
BASIC_FACTORY(SetFocusModeArgs);
|
||||
BASIC_FACTORY(SetFullScreenArgs);
|
||||
|
||||
@@ -119,6 +119,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Tasks = 0x1,
|
||||
CommandHistory = 0x2,
|
||||
DirectoryHistory = 0x4,
|
||||
QuickFixes = 0x8,
|
||||
All = 0xffffffff,
|
||||
};
|
||||
|
||||
@@ -225,6 +226,8 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
|
||||
[default_interface] runtimeclass SendInputArgs : IActionArgs
|
||||
{
|
||||
SendInputArgs(String input);
|
||||
|
||||
String Input { get; };
|
||||
};
|
||||
|
||||
|
||||
@@ -665,7 +665,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
// the command will be run as a directory change instead.
|
||||
IVector<Model::Command> Command::HistoryToCommands(IVector<winrt::hstring> history,
|
||||
winrt::hstring currentCommandline,
|
||||
bool directories)
|
||||
bool directories,
|
||||
hstring iconPath)
|
||||
{
|
||||
std::wstring cdText = directories ? L"cd " : L"";
|
||||
auto result = std::vector<Model::Command>();
|
||||
@@ -697,9 +698,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
auto command = winrt::make_self<Command>();
|
||||
command->_ActionAndArgs = actionAndArgs;
|
||||
command->_name = winrt::hstring{ line };
|
||||
command->_iconPath = directories ?
|
||||
L"\ue8da" : // OpenLocal (a folder with an arrow pointing up)
|
||||
L"\ue81c"; // History icon
|
||||
command->_iconPath = iconPath;
|
||||
result.push_back(*command);
|
||||
foundCommands[line] = true;
|
||||
}
|
||||
|
||||
@@ -78,7 +78,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
|
||||
static Windows::Foundation::Collections::IVector<Model::Command> ParsePowerShellMenuComplete(winrt::hstring json, int32_t replaceLength);
|
||||
static Windows::Foundation::Collections::IVector<Model::Command> HistoryToCommands(Windows::Foundation::Collections::IVector<winrt::hstring> history,
|
||||
winrt::hstring currentCommandline,
|
||||
bool directories);
|
||||
bool directories,
|
||||
hstring iconPath);
|
||||
|
||||
WINRT_PROPERTY(ExpandCommandType, IterateOn, ExpandCommandType::None);
|
||||
WINRT_PROPERTY(Model::ActionAndArgs, ActionAndArgs);
|
||||
|
||||
@@ -45,7 +45,7 @@ namespace Microsoft.Terminal.Settings.Model
|
||||
Windows.Foundation.Collections.IMapView<String, Command> NestedCommands { get; };
|
||||
|
||||
static IVector<Command> ParsePowerShellMenuComplete(String json, Int32 replaceLength);
|
||||
static IVector<Command> HistoryToCommands(IVector<String> commandHistory, String commandline, Boolean directories);
|
||||
static IVector<Command> HistoryToCommands(IVector<String> commandHistory, String commandline, Boolean directories, String iconPath);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -501,11 +501,12 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::FindMatchDirecti
|
||||
|
||||
JSON_FLAG_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::SuggestionsSource)
|
||||
{
|
||||
static constexpr std::array<pair_type, 5> mappings = {
|
||||
static constexpr std::array<pair_type, 6> mappings = {
|
||||
pair_type{ "none", AllClear },
|
||||
pair_type{ "tasks", ValueType::Tasks },
|
||||
pair_type{ "commandHistory", ValueType::CommandHistory },
|
||||
pair_type{ "directoryHistory", ValueType::DirectoryHistory },
|
||||
pair_type{ "quickFix", ValueType::QuickFixes },
|
||||
pair_type{ "all", AllSet },
|
||||
};
|
||||
};
|
||||
|
||||
@@ -166,4 +166,15 @@
|
||||
</alwaysEnabledBrandingTokens>
|
||||
</feature>
|
||||
|
||||
<feature>
|
||||
<name>Feature_QuickFix</name>
|
||||
<description>Enables the Quick Fix menu</description>
|
||||
<id>16599</id>
|
||||
<stage>AlwaysDisabled</stage>
|
||||
<alwaysEnabledBrandingTokens>
|
||||
<brandingToken>Dev</brandingToken>
|
||||
<brandingToken>Canary</brandingToken>
|
||||
</alwaysEnabledBrandingTokens>
|
||||
</feature>
|
||||
|
||||
</featureStaging>
|
||||
|
||||
@@ -419,3 +419,7 @@ void ConhostInternalGetSet::InvokeCompletions(std::wstring_view /*menuJson*/, un
|
||||
{
|
||||
// Not implemented for conhost.
|
||||
}
|
||||
void ConhostInternalGetSet::SearchMissingCommand(std::wstring_view /*missingCommand*/)
|
||||
{
|
||||
// Not implemented for conhost.
|
||||
}
|
||||
|
||||
@@ -70,6 +70,8 @@ public:
|
||||
|
||||
void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) override;
|
||||
|
||||
void SearchMissingCommand(std::wstring_view missingCommand) override;
|
||||
|
||||
private:
|
||||
Microsoft::Console::IIoProvider& _io;
|
||||
};
|
||||
|
||||
@@ -147,6 +147,8 @@ public:
|
||||
|
||||
virtual bool DoVsCodeAction(const std::wstring_view string) = 0;
|
||||
|
||||
virtual bool DoWTAction(const std::wstring_view string) = 0;
|
||||
|
||||
virtual StringHandler DownloadDRCS(const VTInt fontNumber,
|
||||
const VTParameter startChar,
|
||||
const DispatchTypes::DrcsEraseControl eraseControl,
|
||||
|
||||
@@ -88,5 +88,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
virtual void NotifyBufferRotation(const int delta) = 0;
|
||||
|
||||
virtual void InvokeCompletions(std::wstring_view menuJson, unsigned int replaceLength) = 0;
|
||||
|
||||
virtual void SearchMissingCommand(const std::wstring_view command) = 0;
|
||||
};
|
||||
}
|
||||
|
||||
@@ -3996,6 +3996,54 @@ bool AdaptDispatch::DoVsCodeAction(const std::wstring_view string)
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - Performs a Windows Terminal action
|
||||
// - Currently, the actions we support are:
|
||||
// * CmdNotFound: A protocol for passing commands that the shell couldn't resolve
|
||||
// to the terminal. The command is then shared with WinGet to see if it can
|
||||
// find a package that provides that command, which is then displayed to the
|
||||
// user.
|
||||
// - Not actually used in conhost
|
||||
// Arguments:
|
||||
// - string: contains the parameters that define which action we do
|
||||
// Return Value:
|
||||
// - false in conhost, true for the CmdNotFound action, otherwise false.
|
||||
bool AdaptDispatch::DoWTAction(const std::wstring_view string)
|
||||
{
|
||||
// This is not implemented in conhost.
|
||||
if (_api.IsConsolePty())
|
||||
{
|
||||
// Flush the frame manually to make sure this action happens at the right time.
|
||||
_renderer.TriggerFlush(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto parts = Utils::SplitString(string, L';');
|
||||
|
||||
if (parts.size() < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto action = til::at(parts, 0);
|
||||
|
||||
if (action == L"CmdNotFound")
|
||||
{
|
||||
// The structure of the message is as follows:
|
||||
// `e]9001;
|
||||
// 0: CmdNotFound;
|
||||
// 1: $($cmdNotFound.missingCmd);
|
||||
if (parts.size() >= 2)
|
||||
{
|
||||
std::wstring_view missingCmd = til::at(parts, 1);
|
||||
_api.SearchMissingCommand(missingCmd);
|
||||
}
|
||||
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
// - DECDLD - Downloads one or more characters of a dynamically redefinable
|
||||
// character set (DRCS) with a specified pixel pattern. The pixel array is
|
||||
|
||||
@@ -150,6 +150,8 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
|
||||
bool DoVsCodeAction(const std::wstring_view string) override;
|
||||
|
||||
bool DoWTAction(const std::wstring_view string) override;
|
||||
|
||||
StringHandler DownloadDRCS(const VTInt fontNumber,
|
||||
const VTParameter startChar,
|
||||
const DispatchTypes::DrcsEraseControl eraseControl,
|
||||
|
||||
@@ -140,6 +140,8 @@ public:
|
||||
|
||||
bool DoVsCodeAction(const std::wstring_view /*string*/) override { return false; }
|
||||
|
||||
bool DoWTAction(const std::wstring_view /*string*/) override { return false; }
|
||||
|
||||
StringHandler DownloadDRCS(const VTInt /*fontNumber*/,
|
||||
const VTParameter /*startChar*/,
|
||||
const DispatchTypes::DrcsEraseControl /*eraseControl*/,
|
||||
|
||||
@@ -913,6 +913,11 @@ bool OutputStateMachineEngine::ActionOscDispatch(const size_t parameter, const s
|
||||
success = _dispatch->DoVsCodeAction(string);
|
||||
break;
|
||||
}
|
||||
case OscActionCodes::WTAction:
|
||||
{
|
||||
success = _dispatch->DoWTAction(string);
|
||||
break;
|
||||
}
|
||||
default:
|
||||
// If no functions to call, overall dispatch was a failure.
|
||||
success = false;
|
||||
|
||||
@@ -229,6 +229,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
FinalTermAction = 133,
|
||||
VsCodeAction = 633,
|
||||
ITerm2Action = 1337,
|
||||
WTAction = 9001,
|
||||
};
|
||||
|
||||
bool _GetOscSetColorTable(const std::wstring_view string,
|
||||
|
||||
Reference in New Issue
Block a user