Skip to content

Commit

Permalink
Make Mark Mode keybindings precede custom keybindings
Browse files Browse the repository at this point in the history
  • Loading branch information
carlos-zamora committed Aug 2, 2022
1 parent 55f1b8d commit a8cd0cf
Show file tree
Hide file tree
Showing 4 changed files with 69 additions and 51 deletions.
93 changes: 54 additions & 39 deletions src/cascadia/TerminalControl/ControlCore.cpp
Expand Up @@ -389,6 +389,60 @@ namespace winrt::Microsoft::Terminal::Control::implementation
return _terminal->SendCharEvent(ch, scanCode, modifiers);
}

bool ControlCore::TryMarkModeKeybinding(const WORD vkey,
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers)
{
if (HasSelection() &&
!KeyEvent::IsModifierKey(vkey) &&
vkey != VK_SNAPSHOT &&
_terminal->SelectionMode() == ::Terminal::SelectionInteractionMode::Mark)
{
if (modifiers.IsCtrlPressed() && vkey == 'A')
{
// Ctrl + A --> Select all
auto lock = _terminal->LockForWriting();
_terminal->SelectAll();
_updateSelectionUI();
return true;
}
else if (vkey == VK_TAB && _settings->DetectURLs())
{
// [Shift +] Tab --> next/previous hyperlink
auto lock = _terminal->LockForWriting();
const auto direction = modifiers.IsShiftPressed() ? ::Terminal::SearchDirection::Backward : ::Terminal::SearchDirection::Forward;
_terminal->SelectHyperlink(direction);
_updateSelectionUI();
return true;
}
else if (vkey == VK_RETURN && modifiers.IsCtrlPressed() && _terminal->IsTargetingUrl())
{
// Ctrl + Enter --> Open URL
auto lock = _terminal->LockForReading();
const auto uri = _terminal->GetHyperlinkAtBufferPosition(_terminal->GetSelectionAnchor());
_OpenHyperlinkHandlers(*this, winrt::make<OpenHyperlinkEventArgs>(winrt::hstring{ uri }));
return true;
}
else if (vkey == VK_RETURN)
{
// [Shift +] Enter --> copy text
// Don't lock here! CopySelectionToClipboard already locks for you!
CopySelectionToClipboard(modifiers.IsShiftPressed(), nullptr);
_terminal->ClearSelection();
_updateSelectionUI();
return true;
}
else if (const auto updateSlnParams{ _terminal->ConvertKeyEventToUpdateSelectionParams(modifiers, vkey) })
{
// try to update the selection
auto lock = _terminal->LockForWriting();
_terminal->UpdateSelection(updateSlnParams->first, updateSlnParams->second, modifiers);
_updateSelectionUI();
return true;
}
}
return false;
}

// Method Description:
// - Send this particular key event to the terminal.
// See Terminal::SendKeyEvent for more information.
Expand Down Expand Up @@ -417,45 +471,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
vkey != VK_SNAPSHOT &&
keyDown)
{
const auto isInMarkMode = _terminal->SelectionMode() == ::Terminal::SelectionInteractionMode::Mark;
if (isInMarkMode)
{
if (modifiers.IsCtrlPressed() && vkey == 'A')
{
// Ctrl + A --> Select all
auto lock = _terminal->LockForWriting();
_terminal->SelectAll();
_updateSelectionUI();
return true;
}
else if (vkey == VK_TAB && _settings->DetectURLs())
{
// [Shift +] Tab --> next/previous hyperlink
auto lock = _terminal->LockForWriting();
const auto direction = modifiers.IsShiftPressed() ? ::Terminal::SearchDirection::Backward : ::Terminal::SearchDirection::Forward;
_terminal->SelectHyperlink(direction);
_updateSelectionUI();
return true;
}
else if (vkey == VK_RETURN && modifiers.IsCtrlPressed() && _terminal->IsTargetingUrl())
{
// Ctrl + Enter --> Open URL
auto lock = _terminal->LockForReading();
const auto uri = _terminal->GetHyperlinkAtBufferPosition(_terminal->GetSelectionAnchor());
_OpenHyperlinkHandlers(*this, winrt::make<OpenHyperlinkEventArgs>(winrt::hstring{ uri }));
return true;
}
else if (vkey == VK_RETURN)
{
// [Shift +] Enter --> copy text
// Don't lock here! CopySelectionToClipboard already locks for you!
CopySelectionToClipboard(modifiers.IsShiftPressed(), nullptr);
_terminal->ClearSelection();
_updateSelectionUI();
return true;
}
}

// try to update the selection
if (const auto updateSlnParams{ _terminal->ConvertKeyEventToUpdateSelectionParams(modifiers, vkey) })
{
Expand Down
2 changes: 2 additions & 0 deletions src/cascadia/TerminalControl/ControlCore.h
Expand Up @@ -87,6 +87,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
void ToggleMarkMode();
Control::SelectionInteractionMode SelectionMode() const;
bool SwitchSelectionEndpoint();
bool TryMarkModeKeybinding(const WORD vkey,
const ::Microsoft::Terminal::Core::ControlKeyStates modifiers);

void GotFocus();
void LostFocus();
Expand Down
20 changes: 9 additions & 11 deletions src/cascadia/TerminalControl/ControlCore.idl
Expand Up @@ -14,9 +14,7 @@ namespace Microsoft.Terminal.Control
// !! LOAD BEARING !! If you make this a struct with Booleans (like they
// make the most sense as), then the app will crash trying to toss one of
// these across the process boundary. I haven't the damndest idea why.
[flags]
enum MouseButtonState
{
[flags] enum MouseButtonState {
IsLeftButtonDown = 0x1,
IsMiddleButtonDown = 0x2,
IsRightButtonDown = 0x4
Expand All @@ -37,9 +35,7 @@ namespace Microsoft.Terminal.Control
Mark
};

[flags]
enum SelectionEndpointTarget
{
[flags] enum SelectionEndpointTarget {
Start = 0x1,
End = 0x2
};
Expand Down Expand Up @@ -79,13 +75,15 @@ namespace Microsoft.Terminal.Control
Double Opacity { get; };
Boolean UseAcrylic { get; };

Boolean TryMarkModeKeybinding(Int16 vkey,
Microsoft.Terminal.Core.ControlKeyStates modifiers);
Boolean TrySendKeyEvent(Int16 vkey,
Int16 scanCode,
Microsoft.Terminal.Core.ControlKeyStates modifiers,
Boolean keyDown);
Int16 scanCode,
Microsoft.Terminal.Core.ControlKeyStates modifiers,
Boolean keyDown);
Boolean SendCharEvent(Char ch,
Int16 scanCode,
Microsoft.Terminal.Core.ControlKeyStates modifiers);
Int16 scanCode,
Microsoft.Terminal.Core.ControlKeyStates modifiers);
void SendInput(String text);
void PasteText(String text);
void SelectAll();
Expand Down
5 changes: 4 additions & 1 deletion src/cascadia/TerminalControl/TermControl.cpp
Expand Up @@ -1085,7 +1085,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
// keybindings on the keyUp, then we'll still send the keydown to the
// connected terminal application, and something like ctrl+shift+T will
// emit a ^T to the pipe.
if (!modifiers.IsAltGrPressed() && keyDown && _TryHandleKeyBinding(vkey, scanCode, modifiers))
if (!modifiers.IsAltGrPressed() &&
keyDown &&
(_core.TryMarkModeKeybinding(vkey, modifiers) ||
_TryHandleKeyBinding(vkey, scanCode, modifiers)))
{
e.Handled(true);
return;
Expand Down

0 comments on commit a8cd0cf

Please sign in to comment.