Add first pane movement for MoveFocus/SwapPane. (#11044)

This commit adds the ability to target the first pane in the tree,
always.

I wasn't able to find an existing issue for this, it is just a personal
feature for me. I won't be heartbroken if it does not get merged.

As motivation, I frequently have setups where the thing I am primarily
working on is a large pane on the left and everything else is in smaller
panes positioned elsewhere. I like to have one hotkey where I can go to
any pane and then make it the "primary" pane if I am changing what I am
working on or need to focus on another set of code/documentation/etc.

## Validation Steps Performed
Confirmed that the move focus and swap pane variants both affect the
correct pane.
This commit is contained in:
Schuyler Rosefield 2021-08-26 13:58:56 -04:00 committed by GitHub
parent 6f42367ab8
commit 07dc0601f9
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 55 additions and 15 deletions

View File

@ -299,7 +299,8 @@
"down", "down",
"previous", "previous",
"nextInOrder", "nextInOrder",
"previousInOrder" "previousInOrder",
"first"
], ],
"type": "string" "type": "string"
}, },

View File

@ -399,8 +399,10 @@ static const std::map<std::string, FocusDirection> focusDirectionMap = {
{ "right", FocusDirection::Right }, { "right", FocusDirection::Right },
{ "up", FocusDirection::Up }, { "up", FocusDirection::Up },
{ "down", FocusDirection::Down }, { "down", FocusDirection::Down },
{ "previous", FocusDirection::Previous },
{ "nextInOrder", FocusDirection::NextInOrder }, { "nextInOrder", FocusDirection::NextInOrder },
{ "previousInOrder", FocusDirection::PreviousInOrder }, { "previousInOrder", FocusDirection::PreviousInOrder },
{ "first", FocusDirection::First },
}; };
// Method Description: // Method Description:

View File

@ -251,6 +251,27 @@ std::shared_ptr<Pane> Pane::NavigateDirection(const std::shared_ptr<Pane> source
return PreviousPane(sourcePane); return PreviousPane(sourcePane);
} }
if (direction == FocusDirection::First)
{
std::shared_ptr<Pane> firstPane = nullptr;
WalkTree([&](auto p) {
if (p->_IsLeaf())
{
firstPane = p;
return true;
}
return false;
});
// Don't need to do any movement if we are the source and target pane.
if (firstPane == sourcePane)
{
return nullptr;
}
return firstPane;
}
// We are left with directional traversal now // We are left with directional traversal now
// If the focus direction does not match the split direction, the source pane // If the focus direction does not match the split direction, the source pane
// and its neighbor must necessarily be contained within the same child. // and its neighbor must necessarily be contained within the same child.

View File

@ -296,7 +296,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return RS_(L"MoveFocusNextInOrder"); return RS_(L"MoveFocusNextInOrder");
case FocusDirection::PreviousInOrder: case FocusDirection::PreviousInOrder:
return RS_(L"MoveFocusPreviousInOrder"); return RS_(L"MoveFocusPreviousInOrder");
case FocusDirection::First:
return RS_(L"MoveFocusFirstPane");
} }
return winrt::hstring{ return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"MoveFocusWithArgCommandKey")), fmt::format(std::wstring_view(RS_(L"MoveFocusWithArgCommandKey")),
directionString) directionString)
@ -326,7 +329,10 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
return RS_(L"SwapPaneNextInOrder"); return RS_(L"SwapPaneNextInOrder");
case FocusDirection::PreviousInOrder: case FocusDirection::PreviousInOrder:
return RS_(L"SwapPanePreviousInOrder"); return RS_(L"SwapPanePreviousInOrder");
case FocusDirection::First:
return RS_(L"SwapPaneFirstPane");
} }
return winrt::hstring{ return winrt::hstring{
fmt::format(std::wstring_view(RS_(L"SwapPaneWithArgCommandKey")), fmt::format(std::wstring_view(RS_(L"SwapPaneWithArgCommandKey")),
directionString) directionString)

View File

@ -35,7 +35,8 @@ namespace Microsoft.Terminal.Settings.Model
Down, Down,
Previous, Previous,
PreviousInOrder, PreviousInOrder,
NextInOrder NextInOrder,
First
}; };
enum SplitState enum SplitState

View File

@ -246,6 +246,15 @@
<data name="MoveFocusToLastUsedPane" xml:space="preserve"> <data name="MoveFocusToLastUsedPane" xml:space="preserve">
<value>Move focus to the last used pane</value> <value>Move focus to the last used pane</value>
</data> </data>
<data name="MoveFocusNextInOrder" xml:space="preserve">
<value>Move focus to the next pane in order</value>
</data>
<data name="MoveFocusPreviousInOrder" xml:space="preserve">
<value>Move focus to the previous pane in order</value>
</data>
<data name="MoveFocusFirstPane" xml:space="preserve">
<value>Move focus to the first pane</value>
</data>
<data name="SwapPaneCommandKey" xml:space="preserve"> <data name="SwapPaneCommandKey" xml:space="preserve">
<value>Swap pane</value> <value>Swap pane</value>
</data> </data>
@ -256,6 +265,15 @@
<data name="SwapPaneToLastUsedPane" xml:space="preserve"> <data name="SwapPaneToLastUsedPane" xml:space="preserve">
<value>Swap panes with the last used pane</value> <value>Swap panes with the last used pane</value>
</data> </data>
<data name="SwapPaneNextInOrder" xml:space="preserve">
<value>Swap panes with the next pane in order</value>
</data>
<data name="SwapPanePreviousInOrder" xml:space="preserve">
<value>Swap panes with the previous pane in order</value>
</data>
<data name="SwapPaneFirstPane" xml:space="preserve">
<value>Swap panes with the first pane</value>
</data>
<data name="NewTabCommandKey" xml:space="preserve"> <data name="NewTabCommandKey" xml:space="preserve">
<value>New tab</value> <value>New tab</value>
</data> </data>
@ -436,18 +454,6 @@
<value>Windows Console Host</value> <value>Windows Console Host</value>
<comment>Name describing the usage of the classic windows console as the terminal UI. (`conhost.exe`)</comment> <comment>Name describing the usage of the classic windows console as the terminal UI. (`conhost.exe`)</comment>
</data> </data>
<data name="MoveFocusNextInOrder" xml:space="preserve">
<value>Move focus to the next pane in order</value>
</data>
<data name="MoveFocusPreviousInOrder" xml:space="preserve">
<value>Move focus to the previous pane in order</value>
</data>
<data name="SwapPaneNextInOrder" xml:space="preserve">
<value>Swap panes with the next pane in order</value>
</data>
<data name="SwapPanePreviousInOrder" xml:space="preserve">
<value>Swap panes with the previous pane in order</value>
</data>
<data name="MinimizeToTrayCommandKey" xml:space="preserve"> <data name="MinimizeToTrayCommandKey" xml:space="preserve">
<value>Minimize current window to tray</value> <value>Minimize current window to tray</value>
</data> </data>

View File

@ -337,7 +337,7 @@ struct ::Microsoft::Terminal::Settings::Model::JsonUtils::ConversionTrait<::winr
// Possible FocusDirection values // Possible FocusDirection values
JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::FocusDirection) JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::FocusDirection)
{ {
JSON_MAPPINGS(7) = { JSON_MAPPINGS(8) = {
pair_type{ "left", ValueType::Left }, pair_type{ "left", ValueType::Left },
pair_type{ "right", ValueType::Right }, pair_type{ "right", ValueType::Right },
pair_type{ "up", ValueType::Up }, pair_type{ "up", ValueType::Up },
@ -345,6 +345,7 @@ JSON_ENUM_MAPPER(::winrt::Microsoft::Terminal::Settings::Model::FocusDirection)
pair_type{ "previous", ValueType::Previous }, pair_type{ "previous", ValueType::Previous },
pair_type{ "previousInOrder", ValueType::PreviousInOrder }, pair_type{ "previousInOrder", ValueType::PreviousInOrder },
pair_type{ "nextInOrder", ValueType::NextInOrder }, pair_type{ "nextInOrder", ValueType::NextInOrder },
pair_type{ "first", ValueType::First },
}; };
}; };

View File

@ -348,6 +348,7 @@
{ "command": { "action": "moveFocus", "direction": "previous" }, "keys": "ctrl+alt+left"}, { "command": { "action": "moveFocus", "direction": "previous" }, "keys": "ctrl+alt+left"},
{ "command": { "action": "moveFocus", "direction": "previousInOrder" } }, { "command": { "action": "moveFocus", "direction": "previousInOrder" } },
{ "command": { "action": "moveFocus", "direction": "nextInOrder" } }, { "command": { "action": "moveFocus", "direction": "nextInOrder" } },
{ "command": { "action": "moveFocus", "direction": "first" } },
{ "command": { "action": "swapPane", "direction": "down" } }, { "command": { "action": "swapPane", "direction": "down" } },
{ "command": { "action": "swapPane", "direction": "left" } }, { "command": { "action": "swapPane", "direction": "left" } },
{ "command": { "action": "swapPane", "direction": "right" } }, { "command": { "action": "swapPane", "direction": "right" } },
@ -355,6 +356,7 @@
{ "command": { "action": "swapPane", "direction": "previous"} }, { "command": { "action": "swapPane", "direction": "previous"} },
{ "command": { "action": "swapPane", "direction": "previousInOrder"} }, { "command": { "action": "swapPane", "direction": "previousInOrder"} },
{ "command": { "action": "swapPane", "direction": "nextInOrder"} }, { "command": { "action": "swapPane", "direction": "nextInOrder"} },
{ "command": { "action": "swapPane", "direction": "first" } },
{ "command": "togglePaneZoom" }, { "command": "togglePaneZoom" },
{ "command": "toggleSplitOrientation" }, { "command": "toggleSplitOrientation" },
{ "command": "toggleReadOnlyMode" }, { "command": "toggleReadOnlyMode" },