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

Implement keybindings to quick edit selection #3758

Closed
wants to merge 20 commits into from
Closed
Show file tree
Hide file tree
Changes from 6 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
14 changes: 7 additions & 7 deletions src/cascadia/LocalTests_TerminalApp/KeyBindingsTests.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -398,7 +398,7 @@ namespace TerminalAppLocalTests
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Vertical, realArgs.SplitStyle());
VERIFY_ARE_EQUAL(SplitState::Vertical, realArgs.SplitStyle());
}
{
KeyChord kc{ true, false, true, static_cast<int32_t>('B') };
Expand All @@ -407,7 +407,7 @@ namespace TerminalAppLocalTests
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Horizontal, realArgs.SplitStyle());
VERIFY_ARE_EQUAL(SplitState::Horizontal, realArgs.SplitStyle());
}
{
KeyChord kc{ true, false, true, static_cast<int32_t>('C') };
Expand All @@ -416,7 +416,7 @@ namespace TerminalAppLocalTests
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::None, realArgs.SplitStyle());
VERIFY_ARE_EQUAL(SplitState::None, realArgs.SplitStyle());
}
{
KeyChord kc{ true, false, true, static_cast<int32_t>('D') };
Expand All @@ -425,7 +425,7 @@ namespace TerminalAppLocalTests
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Vertical, realArgs.SplitStyle());
VERIFY_ARE_EQUAL(SplitState::Vertical, realArgs.SplitStyle());
}
{
KeyChord kc{ true, false, true, static_cast<int32_t>('E') };
Expand All @@ -434,7 +434,7 @@ namespace TerminalAppLocalTests
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::Horizontal, realArgs.SplitStyle());
VERIFY_ARE_EQUAL(SplitState::Horizontal, realArgs.SplitStyle());
}
{
KeyChord kc{ true, false, true, static_cast<int32_t>('F') };
Expand All @@ -443,7 +443,7 @@ namespace TerminalAppLocalTests
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::None, realArgs.SplitStyle());
VERIFY_ARE_EQUAL(SplitState::None, realArgs.SplitStyle());
}
{
KeyChord kc{ true, false, true, static_cast<int32_t>('G') };
Expand All @@ -452,7 +452,7 @@ namespace TerminalAppLocalTests
const auto& realArgs = actionAndArgs.Args().try_as<SplitPaneArgs>();
VERIFY_IS_NOT_NULL(realArgs);
// Verify the args have the expected value
VERIFY_ARE_EQUAL(winrt::TerminalApp::SplitState::None, realArgs.SplitStyle());
VERIFY_ARE_EQUAL(SplitState::None, realArgs.SplitStyle());
}
}

Expand Down
1 change: 1 addition & 0 deletions src/cascadia/TerminalApp/ActionArgs.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -12,4 +12,5 @@
#include "ResizePaneArgs.g.cpp"
#include "MoveFocusArgs.g.cpp"
#include "AdjustFontSizeArgs.g.cpp"
#include "MoveSelectionAnchorArgs.g.cpp"
#include "SplitPaneArgs.g.cpp"
99 changes: 86 additions & 13 deletions src/cascadia/TerminalApp/ActionArgs.h
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,10 @@
#include "ResizePaneArgs.g.h"
#include "MoveFocusArgs.g.h"
#include "AdjustFontSizeArgs.g.h"
#include "MoveSelectionAnchorArgs.g.h"
#include "SplitPaneArgs.g.h"

#include <winrt/Microsoft.Terminal.Settings.h>
#include "../../cascadia/inc/cppwinrt_utils.h"
#include "Utils.h"

Expand Down Expand Up @@ -134,32 +136,32 @@ namespace winrt::TerminalApp::implementation
// - directionString: the string to attempt to parse
// Return Value:
// - The encoded Direction value, or Direction::None if it was an invalid string
static TerminalApp::Direction ParseDirection(const std::string& directionString)
static winrt::Microsoft::Terminal::Settings::Direction ParseDirection(const std::string& directionString)
{
if (directionString == LeftString)
{
return TerminalApp::Direction::Left;
return winrt::Microsoft::Terminal::Settings::Direction::Left;
}
else if (directionString == RightString)
{
return TerminalApp::Direction::Right;
return winrt::Microsoft::Terminal::Settings::Direction::Right;
}
else if (directionString == UpString)
{
return TerminalApp::Direction::Up;
return winrt::Microsoft::Terminal::Settings::Direction::Up;
}
else if (directionString == DownString)
{
return TerminalApp::Direction::Down;
return winrt::Microsoft::Terminal::Settings::Direction::Down;
}
// default behavior for invalid data
return TerminalApp::Direction::None;
return winrt::Microsoft::Terminal::Settings::Direction::None;
};

struct ResizePaneArgs : public ResizePaneArgsT<ResizePaneArgs>
{
ResizePaneArgs() = default;
GETSET_PROPERTY(TerminalApp::Direction, Direction, TerminalApp::Direction::None);
GETSET_PROPERTY(winrt::Microsoft::Terminal::Settings::Direction, Direction, winrt::Microsoft::Terminal::Settings::Direction::None);

static constexpr std::string_view DirectionKey{ "direction" };

Expand Down Expand Up @@ -188,7 +190,7 @@ namespace winrt::TerminalApp::implementation
struct MoveFocusArgs : public MoveFocusArgsT<MoveFocusArgs>
{
MoveFocusArgs() = default;
GETSET_PROPERTY(TerminalApp::Direction, Direction, TerminalApp::Direction::None);
GETSET_PROPERTY(winrt::Microsoft::Terminal::Settings::Direction, Direction, winrt::Microsoft::Terminal::Settings::Direction::None);

static constexpr std::string_view DirectionKey{ "direction" };

Expand Down Expand Up @@ -243,28 +245,99 @@ namespace winrt::TerminalApp::implementation
}
};

// Possible SelectionExpansionMode values
// TODO:GH#2550/#3475 - move these to a centralized deserializing place
static constexpr std::string_view CellString{ "cell" };
static constexpr std::string_view WordString{ "word" };
static constexpr std::string_view ViewportString{ "viewport" };
static constexpr std::string_view BufferString{ "buffer" };

// Function Description:
// - Helper function for parsing a SelectionExpansionMode from a string
// Arguments:
// - directionString: the string to attempt to parse
// Return Value:
// - The encoded Direction value, or Direction::None if it was an invalid string
static winrt::Microsoft::Terminal::Settings::SelectionExpansionMode ParseExpansionMode(const std::string& expansionModeString)
{
if (expansionModeString == CellString)
{
return winrt::Microsoft::Terminal::Settings::SelectionExpansionMode::Cell;
}
else if (expansionModeString == WordString)
{
return winrt::Microsoft::Terminal::Settings::SelectionExpansionMode::Word;
}
else if (expansionModeString == ViewportString)
{
return winrt::Microsoft::Terminal::Settings::SelectionExpansionMode::Viewport;
}
else if (expansionModeString == BufferString)
{
return winrt::Microsoft::Terminal::Settings::SelectionExpansionMode::Buffer;
}
// default behavior for invalid data
return winrt::Microsoft::Terminal::Settings::SelectionExpansionMode::Cell;
};

struct MoveSelectionAnchorArgs : public MoveSelectionAnchorArgsT<MoveSelectionAnchorArgs>
{
MoveSelectionAnchorArgs() = default;
GETSET_PROPERTY(winrt::Microsoft::Terminal::Settings::Direction, Direction, winrt::Microsoft::Terminal::Settings::Direction::None);
GETSET_PROPERTY(winrt::Microsoft::Terminal::Settings::SelectionExpansionMode, ExpansionMode, winrt::Microsoft::Terminal::Settings::SelectionExpansionMode::Cell);

static constexpr std::string_view DirectionKey{ "direction" };
static constexpr std::string_view ExpansionModeKey{ "expansionMode" };

public:
bool Equals(const IActionArgs& other)
{
auto otherAsUs = other.try_as<MoveSelectionAnchorArgs>();
if (otherAsUs)
{
return (otherAsUs->_Direction == _Direction) && (otherAsUs->_ExpansionMode == _ExpansionMode);
}
return false;
};
static winrt::TerminalApp::IActionArgs FromJson(const Json::Value& json)
{
// LOAD BEARING: Not using make_self here _will_ break you in the future!
auto args = winrt::make_self<MoveSelectionAnchorArgs>();
if (auto directionString{ json[JsonKey(DirectionKey)] })
{
args->_Direction = ParseDirection(directionString.asString());

if (auto expansionModeString{ json[JsonKey(ExpansionModeKey)] })
carlos-zamora marked this conversation as resolved.
Show resolved Hide resolved
{
args->_ExpansionMode = ParseExpansionMode(expansionModeString.asString());
}
}
return *args;
}
};

// Possible SplitState values
// TODO:GH#2550/#3475 - move these to a centralized deserializing place
static constexpr std::string_view VerticalKey{ "vertical" };
static constexpr std::string_view HorizontalKey{ "horizontal" };
static TerminalApp::SplitState ParseSplitState(const std::string& stateString)
static winrt::Microsoft::Terminal::Settings::SplitState ParseSplitState(const std::string& stateString)
{
if (stateString == VerticalKey)
{
return TerminalApp::SplitState::Vertical;
return winrt::Microsoft::Terminal::Settings::SplitState::Vertical;
}
else if (stateString == HorizontalKey)
{
return TerminalApp::SplitState::Horizontal;
return winrt::Microsoft::Terminal::Settings::SplitState::Horizontal;
}
// default behavior for invalid data
return TerminalApp::SplitState::None;
return winrt::Microsoft::Terminal::Settings::SplitState::None;
};

struct SplitPaneArgs : public SplitPaneArgsT<SplitPaneArgs>
{
SplitPaneArgs() = default;
GETSET_PROPERTY(winrt::TerminalApp::SplitState, SplitStyle, winrt::TerminalApp::SplitState::None);
GETSET_PROPERTY(winrt::Microsoft::Terminal::Settings::SplitState, SplitStyle, winrt::Microsoft::Terminal::Settings::SplitState::None);

static constexpr std::string_view SplitKey{ "split" };

Expand Down
28 changes: 9 additions & 19 deletions src/cascadia/TerminalApp/ActionArgs.idl
Original file line number Diff line number Diff line change
Expand Up @@ -14,22 +14,6 @@ namespace TerminalApp
IActionArgs ActionArgs { get; };
};

enum Direction
{
None = 0,
Left,
Right,
Up,
Down
};

enum SplitState
{
None = 0,
Vertical = 1,
Horizontal = 2
};

[default_interface] runtimeclass ActionEventArgs : IActionEventArgs
{
ActionEventArgs(IActionArgs args);
Expand All @@ -54,21 +38,27 @@ namespace TerminalApp

[default_interface] runtimeclass ResizePaneArgs : IActionArgs
{
Direction Direction { get; };
Microsoft.Terminal.Settings.Direction Direction { get; };
};

[default_interface] runtimeclass MoveFocusArgs : IActionArgs
{
Direction Direction { get; };
Microsoft.Terminal.Settings.Direction Direction { get; };
};

[default_interface] runtimeclass AdjustFontSizeArgs : IActionArgs
{
Int32 Delta { get; };
};

[default_interface] runtimeclass MoveSelectionAnchorArgs : IActionArgs
{
Microsoft.Terminal.Settings.Direction Direction { get; };
Microsoft.Terminal.Settings.SelectionExpansionMode ExpansionMode { get; };
};

[default_interface] runtimeclass SplitPaneArgs : IActionArgs
{
SplitState SplitStyle { get; };
Microsoft.Terminal.Settings.SplitState SplitStyle { get; };
};
}
14 changes: 12 additions & 2 deletions src/cascadia/TerminalApp/AppActionHandlers.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -169,7 +169,7 @@ namespace winrt::TerminalApp::implementation
{
if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::ResizePaneArgs>())
{
if (realArgs.Direction() == TerminalApp::Direction::None)
if (realArgs.Direction() == Settings::Direction::None)
{
// Do nothing
args.Handled(false);
Expand All @@ -187,7 +187,7 @@ namespace winrt::TerminalApp::implementation
{
if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::MoveFocusArgs>())
{
if (realArgs.Direction() == TerminalApp::Direction::None)
if (realArgs.Direction() == Settings::Direction::None)
{
// Do nothing
args.Handled(false);
Expand Down Expand Up @@ -236,4 +236,14 @@ namespace winrt::TerminalApp::implementation
args.Handled(true);
}

void TerminalPage::_HandleMoveSelectionAnchor(const IInspectable& /*sender*/,
const TerminalApp::ActionEventArgs& args)
{
if (const auto& realArgs = args.ActionArgs().try_as<TerminalApp::MoveSelectionAnchorArgs>())
{
const auto termControl = _GetActiveControl();
const auto handled = termControl.MoveSelectionAnchor(realArgs.Direction(), realArgs.ExpansionMode());
args.Handled(handled);
}
}
}
4 changes: 4 additions & 0 deletions src/cascadia/TerminalApp/AppKeyBindingsSerialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -78,6 +78,7 @@ static constexpr std::string_view MoveFocusRightKey{ "moveFocusRight" }; // Lega
static constexpr std::string_view MoveFocusUpKey{ "moveFocusUp" }; // Legacy
static constexpr std::string_view MoveFocusDownKey{ "moveFocusDown" }; // Legacy
static constexpr std::string_view ToggleFullscreenKey{ "toggleFullscreen" };
static constexpr std::string_view MoveSelectionAnchorKey{ "moveSelectionAnchor" };

// Specifically use a map here over an unordered_map. We want to be able to
// iterate over these entries in-order when we're serializing the keybindings.
Expand Down Expand Up @@ -140,6 +141,7 @@ static const std::map<std::string_view, ShortcutAction, std::less<>> commandName
{ MoveFocusDownKey, ShortcutAction::MoveFocusDown },
{ OpenSettingsKey, ShortcutAction::OpenSettings },
{ ToggleFullscreenKey, ShortcutAction::ToggleFullscreen },
{ MoveSelectionAnchorKey, ShortcutAction::MoveSelectionAnchor },
{ SplitPaneKey, ShortcutAction::SplitPane },
{ UnboundKey, ShortcutAction::Invalid },
};
Expand Down Expand Up @@ -332,6 +334,8 @@ static const std::map<ShortcutAction, std::function<IActionArgs(const Json::Valu
{ ShortcutAction::SplitVertical, LegacyParseSplitPaneArgs(SplitState::Vertical) },
{ ShortcutAction::SplitHorizontal, LegacyParseSplitPaneArgs(SplitState::Horizontal) },

{ ShortcutAction::MoveSelectionAnchor, winrt::TerminalApp::implementation::MoveSelectionAnchorArgs::FromJson },

{ ShortcutAction::Invalid, nullptr },
};

Expand Down
Loading