Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add an exportBuffer action #12097

Merged
4 commits merged into from
Jan 12, 2022
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
58 changes: 58 additions & 0 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -281,6 +281,7 @@
"ShortcutActionName": {
"enum": [
"adjustFontSize",
"clearBuffer",
"closeOtherTabs",
"closePane",
"closeTab",
Expand All @@ -289,6 +290,7 @@
"commandPalette",
"copy",
"duplicateTab",
"exportBuffer",
"find",
"findMatch",
"focusPane",
Expand Down Expand Up @@ -430,6 +432,14 @@
],
"type": "string"
},
"ClearBufferType": {
"enum": [
"all",
"screen",
"scrollback"
],
"type": "string"
},
"NewTerminalArgs": {
"properties": {
"commandline": {
Expand Down Expand Up @@ -1197,6 +1207,48 @@
}
]
},
"ClearBufferAction": {
"description": "Arguments corresponding to a clearBuffer Action",
"allOf": [
{
"$ref": "#/$defs/ShortcutAction"
},
{
"properties": {
"action": {
"type": "string",
"const": "clearBuffer"
},
"clear": {
"$ref": "#/$defs/ClearBufferType",
"default": "all",
"description": "What to clear. Accepts one of `screen`, `scrollback` or `all` (for both)."
}
}
}
]
},
"ExportBufferAction": {
"description": "Arguments corresponding to a exportBuffer Action",
"allOf": [
{
"$ref": "#/$defs/ShortcutAction"
},
{
"properties": {
"action": {
"type": "string",
"const": "exportBuffer"
},
"path": {
"type": "string",
"default": "",
"description": "The path to export the text buffer to. If left blank, the Terminal will open a file picker to choose the path."
}
}
}
]
},
"GlobalSummonAction": {
"description": "This is a special action that works globally in the OS, rather than only in the context of the terminal window. When pressed, this action will summon the terminal window.",
"allOf": [
Expand Down Expand Up @@ -1360,6 +1412,12 @@
{
"$ref": "#/$defs/FocusPaneAction"
},
{
"$ref": "#/$defs/ExportBufferAction"
},
{
"$ref": "#/$defs/ClearBufferAction"
},
{
"$ref": "#/$defs/GlobalSummonAction"
},
Expand Down
21 changes: 21 additions & 0 deletions src/cascadia/TerminalApp/AppActionHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -860,6 +860,27 @@ namespace winrt::TerminalApp::implementation
args.Handled(true);
}

void TerminalPage::_HandleExportBuffer(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto activeTab{ _GetFocusedTabImpl() })
{
if (args)
{
if (const auto& realArgs = args.ActionArgs().try_as<ExportBufferArgs>())
{
_ExportTab(*activeTab, realArgs.Path());
args.Handled(true);
return;
}
}

// If we didn't have args, or the args weren't ExportBufferArgs (somehow)
_ExportTab(*activeTab, L"");
args.Handled(true);
}
}

void TerminalPage::_HandleClearBuffer(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
Expand Down
57 changes: 36 additions & 21 deletions src/cascadia/TerminalApp/TabManagement.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -183,7 +183,9 @@ namespace winrt::TerminalApp::implementation

if (page && tab)
{
page->_ExportTab(*tab);
// Passing null args to the ExportBuffer handler will default it
// to prompting for the path
page->_HandleExportBuffer(nullptr, nullptr);
}
});

Expand Down Expand Up @@ -345,7 +347,7 @@ namespace winrt::TerminalApp::implementation
// - Exports the content of the Terminal Buffer inside the tab
// Arguments:
// - tab: tab to export
winrt::fire_and_forget TerminalPage::_ExportTab(const TerminalTab& tab)
winrt::fire_and_forget TerminalPage::_ExportTab(const TerminalTab& tab, winrt::hstring filepath)
{
// This will be used to set up the file picker "filter", to select .txt
// files by default.
Expand All @@ -362,25 +364,38 @@ namespace winrt::TerminalApp::implementation
{
if (const auto control{ tab.GetActiveTerminalControl() })
{
// GH#11356 - we can't use the UWP apis for writing the file,
// because they don't work elevated (shocker) So just use the
// shell32 file picker manually.
auto path = co_await SaveFilePicker(*_hostingHwnd, [control](auto&& dialog) {
THROW_IF_FAILED(dialog->SetClientGuid(clientGuidExportFile));
try
{
// Default to the Downloads folder
auto folderShellItem{ winrt::capture<IShellItem>(&SHGetKnownFolderItem, FOLDERID_Downloads, KF_FLAG_DEFAULT, nullptr) };
dialog->SetDefaultFolder(folderShellItem.get());
}
CATCH_LOG(); // non-fatal
THROW_IF_FAILED(dialog->SetFileTypes(ARRAYSIZE(supportedFileTypes), supportedFileTypes));
THROW_IF_FAILED(dialog->SetFileTypeIndex(1)); // the array is 1-indexed
THROW_IF_FAILED(dialog->SetDefaultExtension(L"txt"));

// Default to using the tab title as the file name
THROW_IF_FAILED(dialog->SetFileName((control.Title() + L".txt").c_str()));
});
auto path = filepath;

if (path.empty())
{
// GH#11356 - we can't use the UWP apis for writing the file,
// because they don't work elevated (shocker) So just use the
// shell32 file picker manually.
path = co_await SaveFilePicker(*_hostingHwnd, [control](auto&& dialog) {
THROW_IF_FAILED(dialog->SetClientGuid(clientGuidExportFile));
try
{
// Default to the Downloads folder
auto folderShellItem{ winrt::capture<IShellItem>(&SHGetKnownFolderItem, FOLDERID_Downloads, KF_FLAG_DEFAULT, nullptr) };
dialog->SetDefaultFolder(folderShellItem.get());
}
CATCH_LOG(); // non-fatal
THROW_IF_FAILED(dialog->SetFileTypes(ARRAYSIZE(supportedFileTypes), supportedFileTypes));
THROW_IF_FAILED(dialog->SetFileTypeIndex(1)); // the array is 1-indexed
THROW_IF_FAILED(dialog->SetDefaultExtension(L"txt"));

// Default to using the tab title as the file name
THROW_IF_FAILED(dialog->SetFileName((control.Title() + L".txt").c_str()));
});
}
else
{
// The file picker isn't going to give us paths with
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Honestly wouldn't hurt you to call this on either path just in case, but it's fine.

// environment variables, but the user might have set one in
// the settings. Expand those here.

path = { wil::ExpandEnvironmentStringsW<std::wstring>(path.c_str()) };
}

if (!path.empty())
{
Expand Down
2 changes: 1 addition & 1 deletion src/cascadia/TerminalApp/TerminalPage.h
Original file line number Diff line number Diff line change
Expand Up @@ -249,7 +249,7 @@ namespace winrt::TerminalApp::implementation
void _DuplicateTab(const TerminalTab& tab);

void _SplitTab(TerminalTab& tab);
winrt::fire_and_forget _ExportTab(const TerminalTab& tab);
winrt::fire_and_forget _ExportTab(const TerminalTab& tab, winrt::hstring filepath);

winrt::Windows::Foundation::IAsyncAction _HandleCloseTabRequested(winrt::TerminalApp::TabBase tab);
void _CloseTabAtIndex(uint32_t index);
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionAndArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -66,6 +66,7 @@ static constexpr std::string_view GlobalSummonKey{ "globalSummon" };
static constexpr std::string_view QuakeModeKey{ "quakeMode" };
static constexpr std::string_view FocusPaneKey{ "focusPane" };
static constexpr std::string_view OpenSystemMenuKey{ "openSystemMenu" };
static constexpr std::string_view ExportBufferKey{ "exportBuffer" };
static constexpr std::string_view ClearBufferKey{ "clearBuffer" };
static constexpr std::string_view MultipleActionsKey{ "multipleActions" };
static constexpr std::string_view QuitKey{ "quit" };
Expand Down Expand Up @@ -371,6 +372,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ ShortcutAction::QuakeMode, RS_(L"QuakeModeCommandKey") },
{ ShortcutAction::FocusPane, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::OpenSystemMenu, RS_(L"OpenSystemMenuCommandKey") },
{ ShortcutAction::ExportBuffer, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::ClearBuffer, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::MultipleActions, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::Quit, RS_(L"QuitCommandKey") },
Expand Down
19 changes: 19 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,7 @@
#include "RenameWindowArgs.g.cpp"
#include "GlobalSummonArgs.g.cpp"
#include "FocusPaneArgs.g.cpp"
#include "ExportBufferArgs.g.cpp"
#include "ClearBufferArgs.g.cpp"
#include "MultipleActionsArgs.g.cpp"

Expand Down Expand Up @@ -697,6 +698,24 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
Id())
};
}

winrt::hstring ExportBufferArgs::GenerateName() const
{
if (!Path().empty())
{
// "Export text to {path}"
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"ExportBufferToPathCommandKey")),
Path())
};
}
else
{
// "Export text"
return RS_(L"ExportBufferCommandKey");
}
}

winrt::hstring ClearBufferArgs::GenerateName() const
{
// "Clear Buffer"
Expand Down
8 changes: 8 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@
#include "RenameWindowArgs.g.h"
#include "GlobalSummonArgs.g.h"
#include "FocusPaneArgs.g.h"
#include "ExportBufferArgs.g.h"
#include "ClearBufferArgs.g.h"
#include "MultipleActionsArgs.g.h"

Expand Down Expand Up @@ -191,6 +192,10 @@ private:
#define FOCUS_PANE_ARGS(X) \
X(uint32_t, Id, "id", false, 0u)

////////////////////////////////////////////////////////////////////////////////
#define EXPORT_BUFFER_ARGS(X) \
X(winrt::hstring, Path, "path", false, L"")

////////////////////////////////////////////////////////////////////////////////
#define CLEAR_BUFFER_ARGS(X) \
X(winrt::Microsoft::Terminal::Control::ClearBufferType, Clear, "clear", false, winrt::Microsoft::Terminal::Control::ClearBufferType::All)
Expand Down Expand Up @@ -599,6 +604,8 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation

ACTION_ARGS_STRUCT(FocusPaneArgs, FOCUS_PANE_ARGS);

ACTION_ARGS_STRUCT(ExportBufferArgs, EXPORT_BUFFER_ARGS);

ACTION_ARGS_STRUCT(ClearBufferArgs, CLEAR_BUFFER_ARGS);

struct MultipleActionsArgs : public MultipleActionsArgsT<MultipleActionsArgs>
Expand Down Expand Up @@ -677,6 +684,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::factory_implementation
BASIC_FACTORY(FocusPaneArgs);
BASIC_FACTORY(PrevTabArgs);
BASIC_FACTORY(NextTabArgs);
BASIC_FACTORY(ExportBufferArgs);
BASIC_FACTORY(ClearBufferArgs);
BASIC_FACTORY(MultipleActionsArgs);
}
6 changes: 6 additions & 0 deletions src/cascadia/TerminalSettingsModel/ActionArgs.idl
Original file line number Diff line number Diff line change
Expand Up @@ -316,6 +316,12 @@ namespace Microsoft.Terminal.Settings.Model
UInt32 Id { get; };
};

[default_interface] runtimeclass ExportBufferArgs : IActionArgs
{
ExportBufferArgs(String path);
String Path { get; };
};

[default_interface] runtimeclass ClearBufferArgs : IActionArgs
{
ClearBufferArgs(Microsoft.Terminal.Control.ClearBufferType clear);
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalSettingsModel/AllShortcutActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -80,6 +80,7 @@
ON_ALL_ACTIONS(QuakeMode) \
ON_ALL_ACTIONS(FocusPane) \
ON_ALL_ACTIONS(OpenSystemMenu) \
ON_ALL_ACTIONS(ExportBuffer) \
ON_ALL_ACTIONS(ClearBuffer) \
ON_ALL_ACTIONS(MultipleActions) \
ON_ALL_ACTIONS(Quit)
Expand Down Expand Up @@ -114,5 +115,6 @@
ON_ALL_ACTIONS_WITH_ARGS(SwitchToTab) \
ON_ALL_ACTIONS_WITH_ARGS(ToggleCommandPalette) \
ON_ALL_ACTIONS_WITH_ARGS(FocusPane) \
ON_ALL_ACTIONS_WITH_ARGS(ExportBuffer) \
ON_ALL_ACTIONS_WITH_ARGS(ClearBuffer) \
ON_ALL_ACTIONS_WITH_ARGS(MultipleActions)
Original file line number Diff line number Diff line change
Expand Up @@ -455,6 +455,13 @@
<value>Focus pane {0}</value>
<comment>{0} will be replaced with a user-specified number</comment>
</data>
<data name="ExportBufferToPathCommandKey" xml:space="preserve">
<value>Export text to {0}</value>
<comment>{0} will be replaced with a user-specified file path</comment>
</data>
<data name="ExportBufferCommandKey" xml:space="preserve">
<value>Export text</value>
</data>
<data name="ClearAllCommandKey" xml:space="preserve">
<value>Clear buffer</value>
<comment>A command to clear the entirety of the Terminal output buffer</comment>
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/defaults.json
Original file line number Diff line number Diff line change
Expand Up @@ -392,6 +392,7 @@
{ "command": "scrollToTop", "keys": "ctrl+shift+home" },
{ "command": "scrollToBottom", "keys": "ctrl+shift+end" },
{ "command": { "action": "clearBuffer", "clear": "all" } },
{ "command": "exportBuffer" },

// Visual Adjustments
{ "command": { "action": "adjustFontSize", "delta": 1 }, "keys": "ctrl+plus" },
Expand Down