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

Introduce switchSelectionEndpoint action #13370

Merged
5 commits merged into from
Jul 1, 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
1 change: 1 addition & 0 deletions doc/cascadia/profiles.schema.json
Original file line number Diff line number Diff line change
Expand Up @@ -354,6 +354,7 @@
"toggleFocusMode",
"selectAll",
"setFocusMode",
"switchSelectionEndpoint",
"toggleFullscreen",
"setFullScreen",
"setMaximized",
Expand Down
10 changes: 10 additions & 0 deletions src/cascadia/TerminalApp/AppActionHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1112,4 +1112,14 @@ namespace winrt::TerminalApp::implementation
args.Handled(handled);
}
}

void TerminalPage::_HandleSwitchSelectionEndpoint(const IInspectable& /*sender*/,
const ActionEventArgs& args)
{
if (const auto& control{ _GetActiveControl() })
{
const auto handled = control.SwitchSelectionEndpoint();
args.Handled(handled);
}
}
}
10 changes: 10 additions & 0 deletions src/cascadia/TerminalControl/ControlCore.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1089,6 +1089,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return static_cast<Control::SelectionInteractionMode>(_terminal->SelectionMode());
}

bool ControlCore::SwitchSelectionEndpoint()
{
if (_terminal->IsSelectionActive())
{
_terminal->SwitchSelectionEndpoint();
return true;
}
return false;
}

// Method Description:
// - Pre-process text pasted (presumably from the clipboard)
// before sending it over the terminal's connection.
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/ControlCore.h
Original file line number Diff line number Diff line change
Expand Up @@ -86,6 +86,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
bool ToggleBlockSelection();
void ToggleMarkMode();
Control::SelectionInteractionMode SelectionMode() const;
bool SwitchSelectionEndpoint();

void GotFocus();
void LostFocus();
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/ControlCore.idl
Original file line number Diff line number Diff line change
Expand Up @@ -92,6 +92,7 @@ namespace Microsoft.Terminal.Control
void ClearSelection();
Boolean ToggleBlockSelection();
void ToggleMarkMode();
Boolean SwitchSelectionEndpoint();
void ClearBuffer(ClearBufferType clearType);

void SetHoveredCell(Microsoft.Terminal.Core.Point terminalPosition);
Expand Down
5 changes: 5 additions & 0 deletions src/cascadia/TerminalControl/TermControl.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -1929,6 +1929,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_core.ToggleMarkMode();
}

bool TermControl::SwitchSelectionEndpoint()
{
return _core.SwitchSelectionEndpoint();
}

void TermControl::Close()
{
if (!_IsClosing())
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/TermControl.h
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void SelectAll();
bool ToggleBlockSelection();
void ToggleMarkMode();
bool SwitchSelectionEndpoint();
void Close();
Windows::Foundation::Size CharacterDimensions() const;
Windows::Foundation::Size MinimumSize();
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalControl/TermControl.idl
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,7 @@ namespace Microsoft.Terminal.Control
void SelectAll();
Boolean ToggleBlockSelection();
void ToggleMarkMode();
Boolean SwitchSelectionEndpoint();
void ClearBuffer(ClearBufferType clearType);
void Close();
Windows.Foundation.Size CharacterDimensions { get; };
Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalCore/Terminal.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Terminal::Terminal() :
_selectionMode{ SelectionInteractionMode::None },
_selection{ std::nullopt },
_selectionEndpoint{ static_cast<SelectionEndpoint>(0) },
_anchorInactiveSelectionEndpoint{ false },
_taskbarState{ 0 },
_taskbarProgress{ 0 },
_trimBlockSelection{ false },
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalCore/Terminal.hpp
Original file line number Diff line number Diff line change
Expand Up @@ -271,6 +271,7 @@ class Microsoft::Terminal::Core::Terminal final :
void UpdateSelection(SelectionDirection direction, SelectionExpansion mode, ControlKeyStates mods);
void SelectAll();
SelectionInteractionMode SelectionMode() const noexcept;
void SwitchSelectionEndpoint();
void ToggleMarkMode();

using UpdateSelectionParams = std::optional<std::pair<SelectionDirection, SelectionExpansion>>;
Expand Down Expand Up @@ -349,6 +350,7 @@ class Microsoft::Terminal::Core::Terminal final :
SelectionExpansion _multiClickSelectionMode;
SelectionInteractionMode _selectionMode;
SelectionEndpoint _selectionEndpoint;
bool _anchorInactiveSelectionEndpoint;
#pragma endregion

std::unique_ptr<TextBuffer> _mainBuffer;
Expand Down
38 changes: 36 additions & 2 deletions src/cascadia/TerminalCore/TerminalSelection.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -309,6 +309,33 @@ void Terminal::ToggleMarkMode()
}
}

// Method Description:
// - switch the targeted selection endpoint with the other one (i.e. start <--> end)
void Terminal::SwitchSelectionEndpoint()
{
if (IsSelectionActive())
{
if (WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::Start) && WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::End))
lhecker marked this conversation as resolved.
Show resolved Hide resolved
{
// moving cursor --> anchor start, move end
_selectionEndpoint = SelectionEndpoint::End;
_anchorInactiveSelectionEndpoint = true;
}
else if (WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::End))
{
// moving end --> now we're moving start
_selectionEndpoint = SelectionEndpoint::Start;
_selection->pivot = _selection->end;
}
else if (WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::Start))
{
// moving start --> now we're moving end
_selectionEndpoint = SelectionEndpoint::End;
_selection->pivot = _selection->start;
}
}
}

Terminal::UpdateSelectionParams Terminal::ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey) const
{
if ((_selectionMode == SelectionInteractionMode::Mark || mods.IsShiftPressed()) && !mods.IsAltPressed())
Expand Down Expand Up @@ -365,14 +392,20 @@ Terminal::UpdateSelectionParams Terminal::ConvertKeyEventToUpdateSelectionParams
// - mods: the key modifiers pressed when performing this update
void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion mode, ControlKeyStates mods)
{
// This is a special variable used to track if we should move the cursor when in mark mode.
// We have special functionality where if you use the "switchSelectionEndpoint" action
// when in mark mode (moving the cursor), we anchor an endpoint and you can use the
// plain arrow keys to move the endpoint. This way, you don't have to hold shift anymore!
const bool shouldMoveBothEndpoints = _selectionMode == SelectionInteractionMode::Mark && !_anchorInactiveSelectionEndpoint && !mods.IsShiftPressed();

// 1. Figure out which endpoint to update
// [Mark Mode]
// - shift pressed --> only move "end" (or "start" if "pivot" == "end")
// - otherwise --> move both "start" and "end" (moving cursor)
// [Quick Edit]
// - just move "end" (or "start" if "pivot" == "end")
_selectionEndpoint = static_cast<SelectionEndpoint>(0);
if (_selectionMode == SelectionInteractionMode::Mark && !mods.IsShiftPressed())
if (shouldMoveBothEndpoints)
{
WI_SetAllFlags(_selectionEndpoint, SelectionEndpoint::Start | SelectionEndpoint::End);
}
Expand Down Expand Up @@ -405,7 +438,7 @@ void Terminal::UpdateSelection(SelectionDirection direction, SelectionExpansion

// 3. Actually modify the selection state
_selectionMode = std::max(_selectionMode, SelectionInteractionMode::Keyboard);
if (_selectionMode == SelectionInteractionMode::Mark && !mods.IsShiftPressed())
if (shouldMoveBothEndpoints)
{
// [Mark Mode] + shift unpressed --> move all three (i.e. just use arrow keys)
_selection->start = targetPos;
Expand Down Expand Up @@ -598,6 +631,7 @@ void Terminal::ClearSelection()
_selection = std::nullopt;
_selectionMode = SelectionInteractionMode::None;
_selectionEndpoint = static_cast<SelectionEndpoint>(0);
_anchorInactiveSelectionEndpoint = false;
}

// Method Description:
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 @@ -82,6 +82,7 @@ static constexpr std::string_view RestoreLastClosedKey{ "restoreLastClosed" };
static constexpr std::string_view SelectAllKey{ "selectAll" };
static constexpr std::string_view MarkModeKey{ "markMode" };
static constexpr std::string_view ToggleBlockSelectionKey{ "toggleBlockSelection" };
static constexpr std::string_view SwitchSelectionEndpointKey{ "switchSelectionEndpoint" };

static constexpr std::string_view ActionKey{ "action" };

Expand Down Expand Up @@ -400,6 +401,7 @@ namespace winrt::Microsoft::Terminal::Settings::Model::implementation
{ ShortcutAction::SelectAll, RS_(L"SelectAllCommandKey") },
{ ShortcutAction::MarkMode, RS_(L"MarkModeCommandKey") },
{ ShortcutAction::ToggleBlockSelection, RS_(L"ToggleBlockSelectionCommandKey") },
{ ShortcutAction::SwitchSelectionEndpoint, RS_(L"SwitchSelectionEndpointCommandKey") },
};
}();

Expand Down
3 changes: 2 additions & 1 deletion src/cascadia/TerminalSettingsModel/AllShortcutActions.h
Original file line number Diff line number Diff line change
Expand Up @@ -95,7 +95,8 @@
ON_ALL_ACTIONS(RestoreLastClosed) \
ON_ALL_ACTIONS(SelectAll) \
ON_ALL_ACTIONS(MarkMode) \
ON_ALL_ACTIONS(ToggleBlockSelection)
ON_ALL_ACTIONS(ToggleBlockSelection) \
ON_ALL_ACTIONS(SwitchSelectionEndpoint)

#define ALL_SHORTCUT_ACTIONS_WITH_ARGS \
ON_ALL_ACTIONS_WITH_ARGS(AdjustFontSize) \
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -564,4 +564,7 @@
<data name="ToggleBlockSelectionCommandKey" xml:space="preserve">
<value>Toggle block selection</value>
</data>
<data name="SwitchSelectionEndpointCommandKey" xml:space="preserve">
<value>Switch selection endpoint</value>
</data>
</root>
1 change: 1 addition & 0 deletions src/cascadia/TerminalSettingsModel/defaults.json
Original file line number Diff line number Diff line change
Expand Up @@ -388,6 +388,7 @@
{ "command": "selectAll", "keys": "ctrl+shift+a" },
{ "command": "markMode", "keys": "ctrl+shift+m" },
{ "command": "toggleBlockSelection" },
{ "command": "switchSelectionEndpoint" },

// Scrollback
{ "command": "scrollDown", "keys": "ctrl+shift+down" },
Expand Down