Skip to content

Commit

Permalink
Add ability to save input action from command line
Browse files Browse the repository at this point in the history
- Save to disk
- If command line is empty use selection
- Show toast
  • Loading branch information
e82eric committed Jan 1, 2024
1 parent 63c3573 commit 83e3b8c
Show file tree
Hide file tree
Showing 14 changed files with 172 additions and 1 deletion.
28 changes: 28 additions & 0 deletions src/cascadia/TerminalApp/AppActionHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1234,6 +1234,34 @@ namespace winrt::TerminalApp::implementation
args.Handled(true);
}
}

void TerminalPage::_HandleSaveTask(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (args)
{
if (const auto& realArgs = args.ActionArgs().try_as<SaveTaskArgs>())
{
if (realArgs.Commandline().empty())
{
if (const auto termControl{ _GetActiveControl() })
{
if (termControl.HasSelection())
{
const auto selections{ termControl.SelectedText(true) };
auto input = std::accumulate(selections.begin(), selections.end(), std::wstring());
realArgs.Commandline(input);
}
}
}

_settings.GlobalSettings().ActionMap().AddSendInputAction(realArgs.GenerateName(), realArgs.Commandline());
_settings.WriteSettingsToDisk();
ActionSaved(realArgs.Commandline());
args.Handled(true);
}
}
}

void TerminalPage::_HandleSelectCommand(const IInspectable& /*sender*/,
const ActionEventArgs& args)
Expand Down
57 changes: 56 additions & 1 deletion src/cascadia/TerminalApp/AppCommandlineArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -209,6 +209,7 @@ void AppCommandlineArgs::_buildParser()
_buildMovePaneParser();
_buildSwapPaneParser();
_buildFocusPaneParser();
_buildSaveParser();
}

// Method Description:
Expand Down Expand Up @@ -537,6 +538,59 @@ void AppCommandlineArgs::_buildFocusPaneParser()
setupSubcommand(_focusPaneShort);
}

void AppCommandlineArgs::_buildSaveParser()
{
_saveCommand = _app.add_subcommand("save", "TODO Desc");

auto setupSubcommand = [this](auto* subcommand) {
subcommand->add_option("command", _commandline, RS_A(L"CmdCommandArgDesc"));
subcommand->positionals_at_end(true);

// When ParseCommand is called, if this subcommand was provided, this
// callback function will be triggered on the same thread. We can be sure
// that `this` will still be safe - this function just lets us know this
// command was parsed.
subcommand->callback([&, this]() {
// Build the NewTab action from the values we've parsed on the commandline.
ActionAndArgs saveAction{};
saveAction.Action(ShortcutAction::SaveTask);
// _getNewTerminalArgs MUST be called before parsing any other options,
// as it might clear those options while finding the commandline
SaveTaskArgs args{};

if (!_commandline.empty())
{
std::ostringstream cmdlineBuffer;

for (const auto& arg : _commandline)
{
if (cmdlineBuffer.tellp() != 0)
{
// If there's already something in here, prepend a space
cmdlineBuffer << ' ';
}

if (arg.find(" ") != std::string::npos)
{
cmdlineBuffer << '"' << arg << '"';
}
else
{
cmdlineBuffer << arg;
}
}

args.Commandline(winrt::to_hstring(cmdlineBuffer.str()));
}

saveAction.Args(args);
_startupActions.push_back(saveAction);
});
};

setupSubcommand(_saveCommand);
}

// Method Description:
// - Add the `NewTerminalArgs` parameters to the given subcommand. This enables
// that subcommand to support all the properties in a NewTerminalArgs.
Expand Down Expand Up @@ -700,7 +754,8 @@ bool AppCommandlineArgs::_noCommandsProvided()
*_focusPaneCommand ||
*_focusPaneShort ||
*_newPaneShort.subcommand ||
*_newPaneCommand.subcommand);
*_newPaneCommand.subcommand ||
*_saveCommand);
}

// Method Description:
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalApp/AppCommandlineArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ class TerminalApp::AppCommandlineArgs final
CLI::App* _swapPaneCommand;
CLI::App* _focusPaneCommand;
CLI::App* _focusPaneShort;
CLI::App* _saveCommand;

// Are you adding a new sub-command? Make sure to update _noCommandsProvided!

Expand Down Expand Up @@ -139,6 +140,7 @@ class TerminalApp::AppCommandlineArgs final
winrt::Microsoft::Terminal::Settings::Model::NewTerminalArgs _getNewTerminalArgs(NewTerminalSubcommand& subcommand);
void _addNewTerminalArgs(NewTerminalSubcommand& subcommand);
void _buildParser();
void _buildSaveParser();
void _buildNewTabParser();
void _buildSplitPaneParser();
void _buildFocusTabParser();
Expand Down
28 changes: 28 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -4205,6 +4205,34 @@ namespace winrt::TerminalApp::implementation
}
}

winrt::fire_and_forget TerminalPage::ActionSaved(winrt::hstring input)
{
auto weakThis{ get_weak() };
co_await wil::resume_foreground(Dispatcher());
if (auto page{ weakThis.get() })
{
// If we haven't ever loaded the TeachingTip, then do so now and
// create the toast for it.
if (page->_actionSavedToast == nullptr)
{
if (auto tip{ page->FindName(L"ActionSavedToast").try_as<MUX::Controls::TeachingTip>() })
{
page->_actionSavedToast = std::make_shared<Toast>(tip);
// Make sure to use the weak ref when setting up this
// callback.
tip.Closed({ page->get_weak(), &TerminalPage::_FocusActiveControl });
}
}
_UpdateTeachingTipTheme(ActionSavedToast().try_as<winrt::Windows::UI::Xaml::FrameworkElement>());
ActionSavedTextBox().Text(input);

if (page->_actionSavedToast != nullptr)
{
page->_actionSavedToast->Open();
}
}
}

// Method Description:
// - Called when an attempt to rename the window has failed. This will open
// the toast displaying a message to the user that the attempt to rename
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -149,6 +149,7 @@ namespace winrt::TerminalApp::implementation
winrt::hstring KeyboardServiceDisabledText();

winrt::fire_and_forget IdentifyWindow();
winrt::fire_and_forget ActionSaved(winrt::hstring input);
winrt::fire_and_forget RenameFailed();
winrt::fire_and_forget ShowTerminalWorkingDirectory();

Expand Down Expand Up @@ -260,6 +261,7 @@ namespace winrt::TerminalApp::implementation
bool _isEmbeddingInboundListener{ false };

std::shared_ptr<Toast> _windowIdToast{ nullptr };
std::shared_ptr<Toast> _actionSavedToast{ nullptr };
std::shared_ptr<Toast> _windowRenameFailedToast{ nullptr };
std::shared_ptr<Toast> _windowCwdToast{ nullptr };

Expand Down
11 changes: 11 additions & 0 deletions src/cascadia/TerminalApp/TerminalPage.xaml
Original file line number Diff line number Diff line change
Expand Up @@ -219,5 +219,16 @@
Title="{x:Bind WindowProperties.VirtualWorkingDirectory, Mode=OneWay}"
x:Load="False"
IsLightDismissEnabled="True" />

<mux:TeachingTip x:Name="ActionSavedToast"
x:Uid="ActionSavedToast"
Title="ActionSaved"
x:Load="False"
IsLightDismissEnabled="True">
<mux:TeachingTip.Content>
<TextBox x:Name="ActionSavedTextBox"
Text="Test Toast Content" />
</mux:TeachingTip.Content>
</mux:TeachingTip>
</Grid>
</Page>
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -52,6 +52,7 @@ static constexpr std::string_view SwitchToTabKey{ "switchToTab" };
static constexpr std::string_view TabSearchKey{ "tabSearch" };
static constexpr std::string_view ToggleAlwaysOnTopKey{ "toggleAlwaysOnTop" };
static constexpr std::string_view ToggleCommandPaletteKey{ "commandPalette" };
static constexpr std::string_view SaveTaskKey{ "saveTask" };
static constexpr std::string_view SuggestionsKey{ "showSuggestions" };
static constexpr std::string_view ToggleFocusModeKey{ "toggleFocusMode" };
static constexpr std::string_view SetFocusModeKey{ "setFocusMode" };
Expand Down Expand Up @@ -388,6 +389,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ ShortcutAction::TabSearch, RS_(L"TabSearchCommandKey") },
{ ShortcutAction::ToggleAlwaysOnTop, RS_(L"ToggleAlwaysOnTopCommandKey") },
{ ShortcutAction::ToggleCommandPalette, MustGenerate },
{ ShortcutAction::SaveTask, MustGenerate },
{ ShortcutAction::Suggestions, MustGenerate },
{ ShortcutAction::ToggleFocusMode, RS_(L"ToggleFocusModeCommandKey") },
{ ShortcutAction::SetFocusMode, MustGenerate },
Expand Down
8 changes: 8 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,7 @@
#include "ScrollToMarkArgs.g.cpp"
#include "AddMarkArgs.g.cpp"
#include "FindMatchArgs.g.cpp"
#include "SaveTaskArgs.g.cpp"
#include "ToggleCommandPaletteArgs.g.cpp"
#include "SuggestionsArgs.g.cpp"
#include "NewWindowArgs.g.cpp"
Expand Down Expand Up @@ -939,6 +940,13 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
}
}

winrt::hstring SaveTaskArgs::GenerateName() const
{
return winrt::hstring{
fmt::format(L"Save Task commandline:{}, name: {}, description: {}", Commandline(), Name(), Description())
};
}

static winrt::hstring _FormatColorString(const Control::SelectionColor& selectionColor)
{
if (!selectionColor)
Expand Down
10 changes: 10 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -33,6 +33,7 @@
#include "ScrollToMarkArgs.g.h"
#include "AddMarkArgs.g.h"
#include "MoveTabArgs.g.h"
#include "SaveTaskArgs.g.h"
#include "ToggleCommandPaletteArgs.g.h"
#include "SuggestionsArgs.g.h"
#include "FindMatchArgs.g.h"
Expand Down Expand Up @@ -214,6 +215,12 @@ private: \
#define TOGGLE_COMMAND_PALETTE_ARGS(X) \
X(CommandPaletteLaunchMode, LaunchMode, "launchMode", false, CommandPaletteLaunchMode::Action)

////////////////////////////////////////////////////////////////////////////////
#define SAVE_TASK_ARGS(X) \
X(winrt::hstring, Name, "name", false, L"") \
X(winrt::hstring, Commandline, "commandline", args->Commandline().empty(), L"") \
X(winrt::hstring, Description, "description", false, L"")

////////////////////////////////////////////////////////////////////////////////
#define SUGGESTIONS_ARGS(X) \
X(SuggestionsSource, Source, "source", false, SuggestionsSource::Tasks) \
Expand Down Expand Up @@ -725,6 +732,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation

ACTION_ARGS_STRUCT(ToggleCommandPaletteArgs, TOGGLE_COMMAND_PALETTE_ARGS);

ACTION_ARGS_STRUCT(SaveTaskArgs, SAVE_TASK_ARGS);

ACTION_ARGS_STRUCT(SuggestionsArgs, SUGGESTIONS_ARGS);

ACTION_ARGS_STRUCT(FindMatchArgs, FIND_MATCH_ARGS);
Expand Down Expand Up @@ -845,6 +854,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
BASIC_FACTORY(CloseTabArgs);
BASIC_FACTORY(MoveTabArgs);
BASIC_FACTORY(OpenSettingsArgs);
BASIC_FACTORY(SaveTaskArgs);
BASIC_FACTORY(FindMatchArgs);
BASIC_FACTORY(NewWindowArgs);
BASIC_FACTORY(FocusPaneArgs);
Expand Down
9 changes: 9 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.idl
Original file line number Diff line number Diff line change
Expand Up @@ -344,6 +344,15 @@ namespace Microsoft.Terminal.Settings.Model
FindMatchDirection Direction { get; };
};

[default_interface] runtimeclass SaveTaskArgs : IActionArgs
{
SaveTaskArgs();
SaveTaskArgs(String Name, String Commandline, String Description);
String Name;
String Commandline;
String Description;
};

[default_interface] runtimeclass NewWindowArgs : IActionArgs
{
NewWindowArgs(NewTerminalArgs terminalArgs);
Expand Down
12 changes: 12 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionMap.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -857,6 +857,18 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
AddAction(*cmd);
}

void ActionMap::AddSendInputAction(winrt::hstring name, winrt::hstring input)
{
auto newAction = winrt::make<ActionAndArgs>();
newAction.Action(ShortcutAction::SendInput);
auto sendInputArgs = winrt::make<SendInputArgs>(input);
newAction.Args(sendInputArgs);
auto cmd{ make_self<Command>() };
cmd->ActionAndArgs(newAction);
cmd->Name(name);
AddAction(*cmd);
}

void ActionMap::_recursiveUpdateCommandKeybindingLabels()
{
const auto& commands{ _ExpandedCommandsCache };
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/ActionMap.h
Original file line number Diff line number Diff line change
Expand Up @@ -74,6 +74,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
bool RebindKeys(const Control::KeyChord& oldKeys, const Control::KeyChord& newKeys);
void DeleteKeyBinding(const Control::KeyChord& keys);
void RegisterKeyBinding(Control::KeyChord keys, Model::ActionAndArgs action);
void AddSendInputAction(winrt::hstring name, winrt::hstring input);

Windows::Foundation::Collections::IVector<Model::Command> ExpandedCommands();
void ExpandCommands(const Windows::Foundation::Collections::IVectorView<Model::Profile>& profiles,
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/ActionMap.idl
Original file line number Diff line number Diff line change
Expand Up @@ -32,5 +32,6 @@ namespace Microsoft.Terminal.Settings.Model
void DeleteKeyBinding(Microsoft.Terminal.Control.KeyChord keys);

void RegisterKeyBinding(Microsoft.Terminal.Control.KeyChord keys, ActionAndArgs action);
void AddSendInputAction(String name, String input);
}
}
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/AllShortcutActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -75,6 +75,7 @@
ON_ALL_ACTIONS(CloseTabsAfter) \
ON_ALL_ACTIONS(TabSearch) \
ON_ALL_ACTIONS(MoveTab) \
ON_ALL_ACTIONS(SaveTask) \
ON_ALL_ACTIONS(BreakIntoDebugger) \
ON_ALL_ACTIONS(TogglePaneReadOnly) \
ON_ALL_ACTIONS(EnablePaneReadOnly) \
Expand Down Expand Up @@ -147,6 +148,7 @@
ON_ALL_ACTIONS_WITH_ARGS(SplitPane) \
ON_ALL_ACTIONS_WITH_ARGS(SwitchToTab) \
ON_ALL_ACTIONS_WITH_ARGS(ToggleCommandPalette) \
ON_ALL_ACTIONS_WITH_ARGS(SaveTask) \
ON_ALL_ACTIONS_WITH_ARGS(FocusPane) \
ON_ALL_ACTIONS_WITH_ARGS(ExportBuffer) \
ON_ALL_ACTIONS_WITH_ARGS(ClearBuffer) \
Expand Down

0 comments on commit 83e3b8c

Please sign in to comment.