Polish MarkMode interactions with ExpandSelectionToWord and existing selection (#13893)

- fix: if a selection exists, mark mode should promote the existing selection instead of creating one at the cursor
- fix: mark mode --> move to middle of a word --> ExpandSelectionToWord --> Shift+Right/Left had some weird behavior. Fix that
- fix: Ctrl+enter on random selection clears selection. It should try to treat selection as a URL.

## References
#13854

NOTE: 3b53f3c can be serviced
This commit is contained in:
Carlos Zamora
2022-09-07 09:07:52 -07:00
committed by GitHub
parent 2c341c8deb
commit 1ef4a42762
3 changed files with 34 additions and 17 deletions

View File

@@ -435,12 +435,19 @@ namespace winrt::Microsoft::Terminal::Control::implementation
_updateSelectionUI();
return true;
}
else if (vkey == VK_RETURN && mods.IsCtrlPressed() && !mods.IsAltPressed() && !mods.IsShiftPressed() && _terminal->SelectionIsTargetingUrl())
else if (vkey == VK_RETURN && mods.IsCtrlPressed() && !mods.IsAltPressed() && !mods.IsShiftPressed())
{
// Ctrl + Enter --> Open URL
auto lock = _terminal->LockForReading();
const auto uri = _terminal->GetHyperlinkAtBufferPosition(_terminal->GetSelectionAnchor());
_OpenHyperlinkHandlers(*this, winrt::make<OpenHyperlinkEventArgs>(winrt::hstring{ uri }));
if (const auto uri = _terminal->GetHyperlinkAtBufferPosition(_terminal->GetSelectionAnchor()); !uri.empty())
{
_OpenHyperlinkHandlers(*this, winrt::make<OpenHyperlinkEventArgs>(winrt::hstring{ uri }));
}
else
{
const auto selectedText = _terminal->GetTextBuffer().GetPlainText(_terminal->GetSelectionAnchor(), _terminal->GetSelectionEnd());
_OpenHyperlinkHandlers(*this, winrt::make<OpenHyperlinkEventArgs>(winrt::hstring{ selectedText }));
}
return true;
}
else if (vkey == VK_RETURN && !mods.IsCtrlPressed() && !mods.IsAltPressed())

View File

@@ -287,7 +287,6 @@ public:
void ExpandSelectionToWord();
void ToggleMarkMode();
void SelectHyperlink(const SearchDirection dir);
bool SelectionIsTargetingUrl() const noexcept;
using UpdateSelectionParams = std::optional<std::pair<SelectionDirection, SelectionExpansion>>;
UpdateSelectionParams ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey) const;

View File

@@ -321,16 +321,25 @@ void Terminal::ToggleMarkMode()
// Enter Mark Mode
// NOTE: directly set cursor state. We already should have locked before calling this function.
_activeBuffer().GetCursor().SetIsOn(false);
const auto cursorPos{ _activeBuffer().GetCursor().GetPosition() };
_selection = SelectionAnchors{};
_selection->start = cursorPos;
_selection->end = cursorPos;
_selection->pivot = cursorPos;
_ScrollToPoint(cursorPos);
if (!IsSelectionActive())
{
// No selection --> start one at the cursor
const auto cursorPos{ _activeBuffer().GetCursor().GetPosition() };
_selection = SelectionAnchors{};
_selection->start = cursorPos;
_selection->end = cursorPos;
_selection->pivot = cursorPos;
_blockSelection = false;
WI_SetAllFlags(_selectionEndpoint, SelectionEndpoint::Start | SelectionEndpoint::End);
}
else if (WI_AreAllFlagsClear(_selectionEndpoint, SelectionEndpoint::Start | SelectionEndpoint::End))
{
// Selection already existed
WI_SetFlag(_selectionEndpoint, SelectionEndpoint::End);
}
_ScrollToPoint(_selection->start);
_selectionMode = SelectionInteractionMode::Mark;
_blockSelection = false;
_selectionIsTargetingUrl = false;
WI_SetAllFlags(_selectionEndpoint, SelectionEndpoint::Start | SelectionEndpoint::End);
}
}
@@ -367,7 +376,14 @@ void Terminal::ExpandSelectionToWord()
{
const auto& buffer = _activeBuffer();
_selection->start = buffer.GetWordStart(_selection->start, _wordDelimiters);
_selection->pivot = _selection->start;
_selection->end = buffer.GetWordEnd(_selection->end, _wordDelimiters);
// if we're targetting both endpoints, instead just target "end"
if (WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::Start) && WI_IsFlagSet(_selectionEndpoint, SelectionEndpoint::End))
{
_selectionEndpoint = SelectionEndpoint::End;
}
}
}
@@ -517,11 +533,6 @@ void Terminal::SelectHyperlink(const SearchDirection dir)
_ScrollToPoint(_selection->end);
}
bool Terminal::SelectionIsTargetingUrl() const noexcept
{
return _selectionIsTargetingUrl;
}
Terminal::UpdateSelectionParams Terminal::ConvertKeyEventToUpdateSelectionParams(const ControlKeyStates mods, const WORD vkey) const
{
if ((_selectionMode == SelectionInteractionMode::Mark || mods.IsShiftPressed()) && !mods.IsAltPressed())