mirror of
https://github.com/microsoft/terminal.git
synced 2026-04-06 14:19:45 +00:00
Compare commits
2 Commits
release-1.
...
dev/migrie
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
ee8082050e | ||
|
|
c365792868 |
@@ -2637,9 +2637,9 @@ HRESULT TextBuffer::Reflow(TextBuffer& oldBuffer,
|
||||
// - Adds or updates a hyperlink in our hyperlink table
|
||||
// Arguments:
|
||||
// - The hyperlink URI, the hyperlink id (could be new or old)
|
||||
void TextBuffer::AddHyperlinkToMap(std::wstring_view uri, uint16_t id)
|
||||
void TextBuffer::AddHyperlinkToMap(LinkData data, uint16_t id)
|
||||
{
|
||||
_hyperlinkMap[id] = uri;
|
||||
_hyperlinkMap[id] = data;
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
@@ -2648,7 +2648,7 @@ void TextBuffer::AddHyperlinkToMap(std::wstring_view uri, uint16_t id)
|
||||
// - The hyperlink ID
|
||||
// Return Value:
|
||||
// - The URI
|
||||
std::wstring TextBuffer::GetHyperlinkUriFromId(uint16_t id) const
|
||||
const LinkData& TextBuffer::GetHyperlinkUriFromId(uint16_t id) const
|
||||
{
|
||||
return _hyperlinkMap.at(id);
|
||||
}
|
||||
|
||||
@@ -64,6 +64,20 @@ namespace Microsoft::Console::Render
|
||||
class Renderer;
|
||||
}
|
||||
|
||||
enum class LinkType
|
||||
{
|
||||
None = 0,
|
||||
Url,
|
||||
SendInput,
|
||||
};
|
||||
|
||||
struct LinkData
|
||||
{
|
||||
std::wstring payload;
|
||||
LinkType type{ LinkType::None };
|
||||
bool IsUrl() const { return type == LinkType::Url; };
|
||||
};
|
||||
|
||||
class TextBuffer final
|
||||
{
|
||||
public:
|
||||
@@ -167,8 +181,8 @@ public:
|
||||
const std::vector<til::inclusive_rect> GetTextRects(til::point start, til::point end, bool blockSelection, bool bufferCoordinates) const;
|
||||
std::vector<til::point_span> GetTextSpans(til::point start, til::point end, bool blockSelection, bool bufferCoordinates) const;
|
||||
|
||||
void AddHyperlinkToMap(std::wstring_view uri, uint16_t id);
|
||||
std::wstring GetHyperlinkUriFromId(uint16_t id) const;
|
||||
void AddHyperlinkToMap(LinkData uri, uint16_t id);
|
||||
const LinkData& GetHyperlinkUriFromId(uint16_t id) const;
|
||||
uint16_t GetHyperlinkId(std::wstring_view uri, std::wstring_view id);
|
||||
void RemoveHyperlinkFromMap(uint16_t id) noexcept;
|
||||
std::wstring GetCustomIdFromId(uint16_t id) const;
|
||||
@@ -242,7 +256,7 @@ private:
|
||||
|
||||
Microsoft::Console::Render::Renderer& _renderer;
|
||||
|
||||
std::unordered_map<uint16_t, std::wstring> _hyperlinkMap;
|
||||
std::unordered_map<uint16_t, LinkData> _hyperlinkMap;
|
||||
std::unordered_map<std::wstring, uint16_t> _hyperlinkCustomIdMap;
|
||||
uint16_t _currentHyperlinkId = 1;
|
||||
|
||||
|
||||
@@ -544,9 +544,9 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
{
|
||||
// Ctrl + Enter --> Open URL
|
||||
auto lock = _terminal->LockForReading();
|
||||
if (const auto uri = _terminal->GetHyperlinkAtBufferPosition(_terminal->GetSelectionAnchor()); !uri.empty())
|
||||
if (const auto uri = _terminal->GetHyperlinkAtBufferPosition(_terminal->GetSelectionAnchor()); !uri.payload.empty())
|
||||
{
|
||||
_OpenHyperlinkHandlers(*this, winrt::make<OpenHyperlinkEventArgs>(winrt::hstring{ uri }));
|
||||
_OpenHyperlinkHandlers(*this, winrt::make<OpenHyperlinkEventArgs>(winrt::hstring{ uri.payload }));
|
||||
}
|
||||
else
|
||||
{
|
||||
@@ -780,11 +780,12 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
winrt::hstring ControlCore::GetHyperlink(const Core::Point pos) const
|
||||
LinkData ControlCore::GetHyperlink(const Core::Point pos) const
|
||||
{
|
||||
// Lock for the duration of our reads.
|
||||
auto lock = _terminal->LockForReading();
|
||||
return winrt::hstring{ _terminal->GetHyperlinkAtViewportPosition(til::point{ pos }) };
|
||||
// return winrt::hstring{ _terminal->GetHyperlinkAtViewportPosition(til::point{ pos }) };
|
||||
return _terminal->GetHyperlinkAtViewportPosition(til::point{ pos });
|
||||
}
|
||||
|
||||
winrt::hstring ControlCore::HoveredUriText() const
|
||||
@@ -792,9 +793,11 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
auto lock = _terminal->LockForReading(); // Lock for the duration of our reads.
|
||||
if (_lastHoveredCell.has_value())
|
||||
{
|
||||
auto uri{ _terminal->GetHyperlinkAtViewportPosition(*_lastHoveredCell) };
|
||||
uri.resize(std::min<size_t>(1024u, uri.size())); // Truncate for display
|
||||
return winrt::hstring{ uri };
|
||||
auto uriData{ _terminal->GetHyperlinkAtViewportPosition(*_lastHoveredCell) };
|
||||
if (!uriData.IsUrl())
|
||||
return {};
|
||||
uriData.payload.resize(std::min<size_t>(1024u, uriData.payload.size())); // Truncate for display
|
||||
return winrt::hstring{ uriData.payload };
|
||||
}
|
||||
return {};
|
||||
}
|
||||
|
||||
@@ -121,7 +121,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
|
||||
void SetHoveredCell(Core::Point terminalPosition);
|
||||
void ClearHoveredCell();
|
||||
winrt::hstring GetHyperlink(const Core::Point position) const;
|
||||
LinkData GetHyperlink(const Core::Point position) const;
|
||||
winrt::hstring HoveredUriText() const;
|
||||
Windows::Foundation::IReference<Core::Point> HoveredCell() const;
|
||||
|
||||
|
||||
@@ -255,16 +255,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const auto ctrlEnabled = modifiers.IsCtrlPressed();
|
||||
|
||||
// GH#9396: we prioritize hyper-link over VT mouse events
|
||||
auto hyperlink = _core->GetHyperlink(terminalPosition.to_core_point());
|
||||
auto hyperlinkData = _core->GetHyperlink(terminalPosition.to_core_point());
|
||||
if (WI_IsFlagSet(buttonState, MouseButtonState::IsLeftButtonDown) &&
|
||||
ctrlEnabled &&
|
||||
!hyperlink.empty())
|
||||
!hyperlinkData.payload.empty())
|
||||
{
|
||||
const auto clickCount = _numberOfClicks(pixelPosition, timestamp);
|
||||
// Handle hyper-link only on the first click to prevent multiple activations
|
||||
if (clickCount == 1)
|
||||
{
|
||||
_hyperlinkHandler(hyperlink);
|
||||
_hyperlinkHandler(hyperlinkData);
|
||||
}
|
||||
}
|
||||
else if (_canSendVTMouseInput(modifiers))
|
||||
@@ -632,9 +632,16 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
}
|
||||
}
|
||||
|
||||
void ControlInteractivity::_hyperlinkHandler(const std::wstring_view uri)
|
||||
void ControlInteractivity::_hyperlinkHandler(const LinkData& uriData)
|
||||
{
|
||||
_OpenHyperlinkHandlers(*this, winrt::make<OpenHyperlinkEventArgs>(winrt::hstring{ uri }));
|
||||
if (uriData.type == LinkType::Url)
|
||||
{
|
||||
_OpenHyperlinkHandlers(*this, winrt::make<OpenHyperlinkEventArgs>(winrt::hstring{ uriData.payload }));
|
||||
}
|
||||
else if (uriData.type == LinkType::SendInput)
|
||||
{
|
||||
_sendPastedTextToConnection(uriData.payload);
|
||||
}
|
||||
}
|
||||
|
||||
bool ControlInteractivity::_canSendVTMouseInput(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers)
|
||||
|
||||
@@ -151,7 +151,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
|
||||
const Core::Point terminalPosition,
|
||||
const bool isLeftButtonPressed);
|
||||
|
||||
void _hyperlinkHandler(const std::wstring_view uri);
|
||||
void _hyperlinkHandler(const LinkData& uri);
|
||||
bool _canSendVTMouseInput(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers);
|
||||
bool _shouldSendAlternateScroll(const ::Microsoft::Terminal::Core::ControlKeyStates modifiers, const int32_t delta);
|
||||
|
||||
|
||||
@@ -561,18 +561,28 @@ bool Terminal::ShouldSendAlternateScroll(const unsigned int uiButton,
|
||||
// - Given a coord, get the URI at that location
|
||||
// Arguments:
|
||||
// - The position relative to the viewport
|
||||
std::wstring Terminal::GetHyperlinkAtViewportPosition(const til::point viewportPos)
|
||||
LinkData Terminal::GetHyperlinkAtViewportPosition(const til::point viewportPos)
|
||||
{
|
||||
return GetHyperlinkAtBufferPosition(_ConvertToBufferCell(viewportPos));
|
||||
}
|
||||
|
||||
std::wstring Terminal::GetHyperlinkAtBufferPosition(const til::point bufferPos)
|
||||
LinkData Terminal::GetHyperlinkAtBufferPosition(const til::point bufferPos)
|
||||
{
|
||||
// Case 1: buffer position has a hyperlink stored in the buffer
|
||||
const auto attr = _activeBuffer().GetCellDataAt(bufferPos)->TextAttr();
|
||||
if (attr.IsHyperlink())
|
||||
{
|
||||
return _activeBuffer().GetHyperlinkUriFromId(attr.GetHyperlinkId());
|
||||
const auto& linkData{ _activeBuffer().GetHyperlinkUriFromId(attr.GetHyperlinkId()) };
|
||||
return linkData;
|
||||
// if (linkData.IsUrl())
|
||||
// {
|
||||
// return linkData.payload;
|
||||
// }
|
||||
// else
|
||||
// {
|
||||
// return {};
|
||||
// }
|
||||
// return _activeBuffer().GetHyperlinkUriFromId(attr.GetHyperlinkId());
|
||||
}
|
||||
|
||||
// Case 2: buffer position may point to an auto-detected hyperlink
|
||||
@@ -619,9 +629,9 @@ std::wstring Terminal::GetHyperlinkAtBufferPosition(const til::point bufferPos)
|
||||
{
|
||||
uri += iter->Chars();
|
||||
}
|
||||
return uri;
|
||||
return LinkData{ uri, LinkType::Url };
|
||||
}
|
||||
return {};
|
||||
return LinkData{};
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -161,8 +161,8 @@ public:
|
||||
|
||||
void FocusChanged(const bool focused) noexcept override;
|
||||
|
||||
std::wstring GetHyperlinkAtViewportPosition(const til::point viewportPos);
|
||||
std::wstring GetHyperlinkAtBufferPosition(const til::point bufferPos);
|
||||
LinkData GetHyperlinkAtViewportPosition(const til::point viewportPos);
|
||||
LinkData GetHyperlinkAtBufferPosition(const til::point bufferPos);
|
||||
uint16_t GetHyperlinkIdAtViewportPosition(const til::point viewportPos);
|
||||
std::optional<interval_tree::IntervalTree<til::point, size_t>::interval> GetHyperlinkIntervalFromViewportPosition(const til::point viewportPos);
|
||||
#pragma endregion
|
||||
|
||||
@@ -89,7 +89,15 @@ const bool Terminal::IsGridLineDrawingAllowed() noexcept
|
||||
|
||||
const std::wstring Microsoft::Terminal::Core::Terminal::GetHyperlinkUri(uint16_t id) const
|
||||
{
|
||||
return _activeBuffer().GetHyperlinkUriFromId(id);
|
||||
const auto& linkData{ _activeBuffer().GetHyperlinkUriFromId(id) };
|
||||
if (linkData.IsUrl())
|
||||
{
|
||||
return linkData.payload;
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
const std::wstring Microsoft::Terminal::Core::Terminal::GetHyperlinkCustomId(uint16_t id) const
|
||||
|
||||
@@ -297,7 +297,15 @@ const std::wstring_view RenderData::GetConsoleTitle() const noexcept
|
||||
const std::wstring RenderData::GetHyperlinkUri(uint16_t id) const
|
||||
{
|
||||
const auto& gci = ServiceLocator::LocateGlobals().getConsoleInformation();
|
||||
return gci.GetActiveOutputBuffer().GetTextBuffer().GetHyperlinkUriFromId(id);
|
||||
const auto& linkData{ gci.GetActiveOutputBuffer().GetTextBuffer().GetHyperlinkUriFromId(id) };
|
||||
if (linkData.IsUrl())
|
||||
{
|
||||
return linkData.payload;
|
||||
}
|
||||
else
|
||||
{
|
||||
return {};
|
||||
}
|
||||
}
|
||||
|
||||
// Method Description:
|
||||
|
||||
@@ -132,6 +132,8 @@ public:
|
||||
|
||||
virtual bool DoFinalTermAction(const std::wstring_view string) = 0;
|
||||
|
||||
virtual bool DoWtAction(const std::wstring_view string) = 0;
|
||||
|
||||
virtual StringHandler DownloadDRCS(const VTInt fontNumber,
|
||||
const VTParameter startChar,
|
||||
const DispatchTypes::DrcsEraseControl eraseControl,
|
||||
|
||||
@@ -3076,7 +3076,7 @@ bool AdaptDispatch::AddHyperlink(const std::wstring_view uri, const std::wstring
|
||||
const auto id = textBuffer.GetHyperlinkId(uri, params);
|
||||
attr.SetHyperlinkId(id);
|
||||
textBuffer.SetCurrentAttributes(attr);
|
||||
textBuffer.AddHyperlinkToMap(uri, id);
|
||||
textBuffer.AddHyperlinkToMap(LinkData{ std::wstring{ uri }, LinkType::Url }, id);
|
||||
return true;
|
||||
}
|
||||
|
||||
@@ -3331,6 +3331,51 @@ bool AdaptDispatch::DoFinalTermAction(const std::wstring_view string)
|
||||
return false;
|
||||
}
|
||||
|
||||
bool AdaptDispatch::DoWtAction(const std::wstring_view string)
|
||||
{
|
||||
// This is not implemented in conhost.
|
||||
if (_api.IsConsolePty())
|
||||
{
|
||||
// Flush the frame manually, to make sure marks end up on the right line, like the alt buffer sequence.
|
||||
_renderer.TriggerFlush(false);
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto parts = Utils::SplitString(string, L';');
|
||||
|
||||
if (parts.size() < 1)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
|
||||
const auto action = til::at(parts, 0);
|
||||
|
||||
if (action == L"a")
|
||||
{
|
||||
if (parts.size() < 2)
|
||||
{
|
||||
return false;
|
||||
}
|
||||
auto uri = til::at(parts, 1);
|
||||
auto& textBuffer = _api.GetTextBuffer();
|
||||
auto attr = textBuffer.GetCurrentAttributes();
|
||||
const auto id = textBuffer.GetHyperlinkId(uri, {});
|
||||
attr.SetHyperlinkId(id);
|
||||
textBuffer.SetCurrentAttributes(attr);
|
||||
textBuffer.AddHyperlinkToMap(LinkData{ std::wstring{ uri }, LinkType::SendInput }, id);
|
||||
return true;
|
||||
}
|
||||
else if (action == L"/a")
|
||||
{
|
||||
auto& textBuffer = _api.GetTextBuffer();
|
||||
auto attr = textBuffer.GetCurrentAttributes();
|
||||
attr.SetHyperlinkId(0);
|
||||
textBuffer.SetCurrentAttributes(attr);
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
// Method Description:
|
||||
// - DECDLD - Downloads one or more characters of a dynamically redefinable
|
||||
// character set (DRCS) with a specified pixel pattern. The pixel array is
|
||||
|
||||
@@ -133,6 +133,8 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
|
||||
bool DoFinalTermAction(const std::wstring_view string) override;
|
||||
|
||||
bool DoWtAction(const std::wstring_view string) override;
|
||||
|
||||
StringHandler DownloadDRCS(const VTInt fontNumber,
|
||||
const VTParameter startChar,
|
||||
const DispatchTypes::DrcsEraseControl eraseControl,
|
||||
|
||||
@@ -125,6 +125,8 @@ public:
|
||||
|
||||
bool DoFinalTermAction(const std::wstring_view /*string*/) override { return false; }
|
||||
|
||||
bool DoWtAction(const std::wstring_view /*string*/) override { return false; }
|
||||
|
||||
StringHandler DownloadDRCS(const VTInt /*fontNumber*/,
|
||||
const VTParameter /*startChar*/,
|
||||
const DispatchTypes::DrcsEraseControl /*eraseControl*/,
|
||||
|
||||
@@ -943,6 +943,11 @@ bool OutputStateMachineEngine::ActionOscDispatch(const wchar_t /*wch*/,
|
||||
success = _dispatch->DoITerm2Action(string);
|
||||
break;
|
||||
}
|
||||
case OscActionCodes::WtAction:
|
||||
{
|
||||
success = _dispatch->DoWtAction(string);
|
||||
break;
|
||||
}
|
||||
case OscActionCodes::FinalTermAction:
|
||||
{
|
||||
success = _dispatch->DoFinalTermAction(string);
|
||||
|
||||
@@ -212,6 +212,7 @@ namespace Microsoft::Console::VirtualTerminal
|
||||
ResetCursorColor = 112,
|
||||
FinalTermAction = 133,
|
||||
ITerm2Action = 1337,
|
||||
WtAction = 9001,
|
||||
};
|
||||
|
||||
bool _GetOscTitle(const std::wstring_view string,
|
||||
|
||||
5
src/tools/scratch/clickable-sendinput.ps1
Normal file
5
src/tools/scratch/clickable-sendinput.ps1
Normal file
@@ -0,0 +1,5 @@
|
||||
write-host "`e[1;31mfatal`e[m: The current branch dev/migrie/fhl-clickable-send-input has no upstream branch."
|
||||
write-host "To push the current branch and set the remote as upstream, use"
|
||||
write-host ""
|
||||
write-host " `e]9001;a;git push --set-upstream origin dev/migrie/fhl-clickable-send-input`e\git push --set-upstream origin dev/migrie/fhl-clickable-send-input`e]9001;/a;`e\"
|
||||
write-host ""
|
||||
Reference in New Issue
Block a user