Add closeOtherTabs, closeTabsAfter actions (#7176)

## Summary of the Pull Request

Adds support for two actions, `closeOtherTabs` and `closeTabsAfter`. Both these actions accept an `index` parameter.

* `closeOtherTabs`: Close tabs other than `index`
* `closeTabsAfter`: Close tabs after `index` (This is also "Close tabs to the right")

## References
* This PR is being made to unblock @RahulRavishankar in #1912
## PR Checklist
* [x] I work here
* [ ] Tests added/passed
* [x] Requires documentation to be updated
* [ ] We should file an issue for "add an `index` param to `closeTab`" to add similar support to the close tab action
* [ ] We should file an issue for "make the `index` param to `closeOtherTabs`, `closeTabsAfter` optional" to make them both work on the _active_ tab when there's no `index` provided

## Validation Steps Performed
* _Verified that_ closing all tabs when I have the `index`'th tab selected _works as expected_
* _Verified that_ closing all tabs when I have a tab other than the `index`'th tab selected _works as expected_
* _Verified that_ closing tabs to the right when I have the `index`'th tab selected _works as expected_
* _Verified that_ closing tabs to the right when I have a tab other than the `index`'th tab selected _works as expected_
    - This one has one caveat: for whatever reason, if you run this action when the tab that's currently focused is _before_ the `index` param, then the tabs will expand to fill the entire width of the tab row, until you mouse over them. Probably has something to do with tabs not resizing down until there's a mouse exit event.
This commit is contained in:
Mike Griese 2020-08-06 16:47:50 -05:00 committed by GitHub
parent f215b56ca3
commit 0a30b856a9
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
12 changed files with 210 additions and 3 deletions

View file

@ -64,6 +64,8 @@
"renameTab",
"commandPalette",
"wt",
"closeOtherTabs",
"closeTabsAfter",
"unbound"
],
"type": "string"
@ -298,6 +300,40 @@
],
"required": [ "commandline" ]
},
"CloseOtherTabsAction": {
"description": "Arguments for a closeOtherTabs action",
"allOf": [
{ "$ref": "#/definitions/ShortcutAction" },
{
"properties": {
"action": { "type": "string", "pattern": "closeOtherTabs" },
"index": {
"type": "integer",
"default": "",
"description": "close the tabs following the tab at this index"
}
}
}
],
"required": [ "index" ]
},
"CloseTabsAfterAction": {
"description": "Arguments for a closeTabsAfter action",
"allOf": [
{ "$ref": "#/definitions/ShortcutAction" },
{
"properties": {
"action": { "type": "string", "pattern": "closeTabsAfter" },
"index": {
"type": "integer",
"default": "",
"description": "close the tabs other than the one at this index"
}
}
}
],
"required": [ "index" ]
},
"Keybinding": {
"additionalProperties": false,
"properties": {
@ -315,6 +351,8 @@
{ "$ref": "#/definitions/OpenSettingsAction" },
{ "$ref": "#/definitions/SetTabColorAction" },
{ "$ref": "#/definitions/WtAction" },
{ "$ref": "#/definitions/CloseOtherTabsAction" },
{ "$ref": "#/definitions/CloseTabsAfterAction" },
{ "type": "null" }
]
},

View file

@ -40,6 +40,8 @@ static constexpr std::string_view OpenTabColorPickerKey{ "openTabColorPicker" };
static constexpr std::string_view RenameTabKey{ "renameTab" };
static constexpr std::string_view ExecuteCommandlineKey{ "wt" };
static constexpr std::string_view ToggleCommandPaletteKey{ "commandPalette" };
static constexpr std::string_view CloseOtherTabsKey{ "closeOtherTabs" };
static constexpr std::string_view CloseTabsAfterKey{ "closeTabsAfter" };
static constexpr std::string_view ActionKey{ "action" };
@ -92,6 +94,8 @@ namespace winrt::TerminalApp::implementation
{ RenameTabKey, ShortcutAction::RenameTab },
{ ExecuteCommandlineKey, ShortcutAction::ExecuteCommandline },
{ ToggleCommandPaletteKey, ShortcutAction::ToggleCommandPalette },
{ CloseOtherTabsKey, ShortcutAction::CloseOtherTabs },
{ CloseTabsAfterKey, ShortcutAction::CloseTabsAfter },
};
using ParseResult = std::tuple<IActionArgs, std::vector<::TerminalApp::SettingsLoadWarnings>>;
@ -125,6 +129,10 @@ namespace winrt::TerminalApp::implementation
{ ShortcutAction::ExecuteCommandline, winrt::TerminalApp::implementation::ExecuteCommandlineArgs::FromJson },
{ ShortcutAction::CloseOtherTabs, winrt::TerminalApp::implementation::CloseOtherTabsArgs::FromJson },
{ ShortcutAction::CloseTabsAfter, winrt::TerminalApp::implementation::CloseTabsAfterArgs::FromJson },
{ ShortcutAction::Invalid, nullptr },
};
@ -274,6 +282,8 @@ namespace winrt::TerminalApp::implementation
{ ShortcutAction::RenameTab, RS_(L"ResetTabNameCommandKey") },
{ ShortcutAction::ExecuteCommandline, RS_(L"ExecuteCommandlineCommandKey") },
{ ShortcutAction::ToggleCommandPalette, RS_(L"ToggleCommandPaletteCommandKey") },
{ ShortcutAction::CloseOtherTabs, L"" }, // Intentionally omitted, must be generated by GenerateName
{ ShortcutAction::CloseTabsAfter, L"" }, // Intentionally omitted, must be generated by GenerateName
};
}();

View file

@ -272,4 +272,21 @@ namespace winrt::TerminalApp::implementation
return L"";
}
winrt::hstring CloseOtherTabsArgs::GenerateName() const
{
// "Close tabs other than index {0}"
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"CloseOtherTabsCommandKey")),
_Index)
};
}
winrt::hstring CloseTabsAfterArgs::GenerateName() const
{
// "Close tabs after index {0}"
return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"CloseTabsAfterCommandKey")),
_Index)
};
}
}

View file

@ -18,6 +18,8 @@
#include "SetTabColorArgs.g.h"
#include "RenameTabArgs.g.h"
#include "ExecuteCommandlineArgs.g.h"
#include "CloseOtherTabsArgs.g.h"
#include "CloseTabsAfterArgs.g.h"
#include "../../cascadia/inc/cppwinrt_utils.h"
#include "Utils.h"
@ -421,6 +423,62 @@ namespace winrt::TerminalApp::implementation
}
};
struct CloseOtherTabsArgs : public CloseOtherTabsArgsT<CloseOtherTabsArgs>
{
CloseOtherTabsArgs() = default;
GETSET_PROPERTY(uint32_t, Index, 0);
static constexpr std::string_view IndexKey{ "index" };
public:
hstring GenerateName() const;
bool Equals(const IActionArgs& other)
{
auto otherAsUs = other.try_as<CloseOtherTabsArgs>();
if (otherAsUs)
{
return otherAsUs->_Index == _Index;
}
return false;
};
static FromJsonResult FromJson(const Json::Value& json)
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<CloseOtherTabsArgs>();
JsonUtils::GetValueForKey(json, IndexKey, args->_Index);
return { *args, {} };
}
};
struct CloseTabsAfterArgs : public CloseTabsAfterArgsT<CloseTabsAfterArgs>
{
CloseTabsAfterArgs() = default;
GETSET_PROPERTY(uint32_t, Index, 0);
static constexpr std::string_view IndexKey{ "index" };
public:
hstring GenerateName() const;
bool Equals(const IActionArgs& other)
{
auto otherAsUs = other.try_as<CloseTabsAfterArgs>();
if (otherAsUs)
{
return otherAsUs->_Index == _Index;
}
return false;
};
static FromJsonResult FromJson(const Json::Value& json)
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<CloseTabsAfterArgs>();
JsonUtils::GetValueForKey(json, IndexKey, args->_Index);
return { *args, {} };
}
};
}
namespace winrt::TerminalApp::factory_implementation

View file

@ -120,4 +120,14 @@ namespace TerminalApp
{
String Commandline;
};
[default_interface] runtimeclass CloseOtherTabsArgs : IActionArgs
{
UInt32 Index { get; };
};
[default_interface] runtimeclass CloseTabsAfterArgs : IActionArgs
{
UInt32 Index { get; };
};
}

View file

@ -351,4 +351,49 @@ namespace winrt::TerminalApp::implementation
}
}
}
void TerminalPage::_HandleCloseOtherTabs(const IInspectable& /*sender*/,
const TerminalApp::ActionEventArgs& actionArgs)
{
if (const auto& realArgs = actionArgs.ActionArgs().try_as<TerminalApp::CloseOtherTabsArgs>())
{
uint32_t index = realArgs.Index();
// Remove tabs after the current one
while (_tabs.Size() > index + 1)
{
_RemoveTabViewItemByIndex(_tabs.Size() - 1);
}
// Remove all of them leading up to the selected tab
while (_tabs.Size() > 1)
{
_RemoveTabViewItemByIndex(0);
}
actionArgs.Handled(true);
}
}
void TerminalPage::_HandleCloseTabsAfter(const IInspectable& /*sender*/,
const TerminalApp::ActionEventArgs& actionArgs)
{
if (const auto& realArgs = actionArgs.ActionArgs().try_as<TerminalApp::CloseTabsAfterArgs>())
{
uint32_t index = realArgs.Index();
// Remove tabs after the current one
while (_tabs.Size() > index + 1)
{
_RemoveTabViewItemByIndex(_tabs.Size() - 1);
}
// TODO:GH#7182 For whatever reason, if you run this action
// when the tab that's currently focused is _before_ the `index`
// param, then the tabs will expand to fill the entire width of the
// tab row, until you mouse over them. Probably has something to do
// with tabs not resizing down until there's a mouse exit event.
actionArgs.Handled(true);
}
}
}

View file

@ -538,14 +538,22 @@
</data>
<data name="RenameTabCommandKey" xml:space="preserve">
<value>Rename tab to "{0}"</value>
<comment>{0} will be replaced with user-defined string</comment>
<comment>{0} will be replaced with a user-defined string</comment>
</data>
<data name="ResetTabNameCommandKey" xml:space="preserve">
<value>Reset tab title</value>
</data>
<data name="ExecuteCommandlineCommandKey" xml:space="preserve">
<value>Run commandline "{0}" in this window</value>
<comment>{0} will be replaced with user-defined commandline</comment>
<comment>{0} will be replaced with a user-defined commandline</comment>
</data>
<data name="CloseOtherTabsCommandKey" xml:space="preserve">
<value>Close tabs other than index {0}</value>
<comment>{0} will be replaced with a number</comment>
</data>
<data name="CloseTabsAfterCommandKey" xml:space="preserve">
<value>Close tabs after index {0}</value>
<comment>{0} will be replaced with a number</comment>
</data>
<data name="CrimsonColorButton.[using:Windows.UI.Xaml.Controls]ToolTipService.ToolTip" xml:space="preserve">
<value>Crimson</value>

View file

@ -197,6 +197,17 @@ namespace winrt::TerminalApp::implementation
case ShortcutAction::ExecuteCommandline:
{
_ExecuteCommandlineHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::CloseOtherTabs:
{
_CloseOtherTabsHandlers(*this, *eventArgs);
break;
}
case ShortcutAction::CloseTabsAfter:
{
_CloseTabsAfterHandlers(*this, *eventArgs);
break;
}
default:
return false;

View file

@ -55,6 +55,8 @@ namespace winrt::TerminalApp::implementation
TYPED_EVENT(OpenTabColorPicker, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(RenameTab, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(ExecuteCommandline, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(CloseOtherTabs, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
TYPED_EVENT(CloseTabsAfter, TerminalApp::ShortcutActionDispatch, TerminalApp::ActionEventArgs);
// clang-format on
private:

View file

@ -40,7 +40,9 @@ namespace TerminalApp
OpenTabColorPicker,
RenameTab,
ExecuteCommandline,
ToggleCommandPalette
ToggleCommandPalette,
CloseOtherTabs,
CloseTabsAfter
};
[default_interface] runtimeclass ActionAndArgs {
@ -86,5 +88,7 @@ namespace TerminalApp
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> OpenTabColorPicker;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> RenameTab;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> ExecuteCommandline;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> CloseOtherTabs;
event Windows.Foundation.TypedEventHandler<ShortcutActionDispatch, ActionEventArgs> CloseTabsAfter;
}
}

View file

@ -893,6 +893,8 @@ namespace winrt::TerminalApp::implementation
_actionDispatch->OpenTabColorPicker({ this, &TerminalPage::_HandleOpenTabColorPicker });
_actionDispatch->RenameTab({ this, &TerminalPage::_HandleRenameTab });
_actionDispatch->ExecuteCommandline({ this, &TerminalPage::_HandleExecuteCommandline });
_actionDispatch->CloseOtherTabs({ this, &TerminalPage::_HandleCloseOtherTabs });
_actionDispatch->CloseTabsAfter({ this, &TerminalPage::_HandleCloseTabsAfter });
}
// Method Description:

View file

@ -224,6 +224,8 @@ namespace winrt::TerminalApp::implementation
void _HandleRenameTab(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
void _HandleExecuteCommandline(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
void _HandleToggleCommandPalette(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
void _HandleCloseOtherTabs(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
void _HandleCloseTabsAfter(const IInspectable& sender, const TerminalApp::ActionEventArgs& args);
// Make sure to hook new actions up in _RegisterActionCallbacks!
#pragma endregion