Skip to content

Commit e6dc314

Browse files
committed
Merge commit 'b4042ea' into dev/migrie/fhl/non-terminal-panes-2023
2 parents 049c043 + b4042ea commit e6dc314

36 files changed

+942
-376
lines changed

.github/actions/spelling/allow/names.txt

+1
Original file line numberDiff line numberDiff line change
@@ -54,6 +54,7 @@ mikegr
5454
mikemaccana
5555
miloush
5656
miniksa
57+
nguyen
5758
niksa
5859
nvaccess
5960
nvda

README.md

+5-3
Original file line numberDiff line numberDiff line change
@@ -70,6 +70,8 @@ package:
7070
winget install --id Microsoft.WindowsTerminal -e
7171
```
7272

73+
> **Note** Due to a dependency issue, Terminal's current versions cannot be installed via the Windows Package Manager CLI. To install the stable release 1.17 or later, or the Preview release 1.18 or later, please use an alternative installation method.
74+
7375
#### Via Chocolatey (unofficial)
7476

7577
[Chocolatey](https://chocolatey.org) users can download and install the latest
@@ -271,10 +273,10 @@ similar open/closed preexisting issues before creating a new issue.**
271273
If you would like to ask a question that you feel doesn't warrant an issue
272274
(yet), please reach out to us via Twitter:
273275

274-
* Kayla Cinnamon, Program Manager:
275-
[@cinnamon\_msft](https://twitter.com/cinnamon_msft)
276+
* Christopher Nguyen, Product Manager:
277+
[@nguyen_dows](https://twitter.com/nguyen_dows)
276278
* Dustin Howett, Engineering Lead: [@dhowett](https://twitter.com/DHowett)
277-
* Mike Griese, Senior Developer: [@zadjii](https://twitter.com/zadjii)
279+
* Mike Griese, Senior Developer: [@zadjii@mastodon.social](https://mastodon.social/@zadjii)
278280
* Carlos Zamora, Developer: [@cazamor_msft](https://twitter.com/cazamor_msft)
279281
* Pankaj Bhojwani, Developer
280282
* Leonard Hecker, Developer: [@LeonardHecker](https://twitter.com/LeonardHecker)

src/buffer/out/textBuffer.cpp

+114
Original file line numberDiff line numberDiff line change
@@ -2660,6 +2660,9 @@ try
26602660
// Set size back to real size as it will be taking over the rendering duties.
26612661
newCursor.SetSize(ulSize);
26622662

2663+
newBuffer._marks = oldBuffer._marks;
2664+
newBuffer._trimMarksOutsideBuffer();
2665+
26632666
return S_OK;
26642667
}
26652668
CATCH_RETURN()
@@ -2869,3 +2872,114 @@ PointTree TextBuffer::GetPatterns(const til::CoordType firstRow, const til::Coor
28692872
PointTree result(std::move(intervals));
28702873
return result;
28712874
}
2875+
2876+
const std::vector<ScrollMark>& TextBuffer::GetMarks() const noexcept
2877+
{
2878+
return _marks;
2879+
}
2880+
2881+
// Remove all marks between `start` & `end`, inclusive.
2882+
void TextBuffer::ClearMarksInRange(
2883+
const til::point start,
2884+
const til::point end)
2885+
{
2886+
auto inRange = [&start, &end](const ScrollMark& m) {
2887+
return (m.start >= start && m.start <= end) ||
2888+
(m.end >= start && m.end <= end);
2889+
};
2890+
2891+
_marks.erase(std::remove_if(_marks.begin(),
2892+
_marks.end(),
2893+
inRange),
2894+
_marks.end());
2895+
}
2896+
void TextBuffer::ClearAllMarks() noexcept
2897+
{
2898+
_marks.clear();
2899+
}
2900+
2901+
// Adjust all the marks in the y-direction by `delta`. Positive values move the
2902+
// marks down (the positive y direction). Negative values move up. This will
2903+
// trim marks that are no longer have a start in the bounds of the buffer
2904+
void TextBuffer::ScrollMarks(const int delta)
2905+
{
2906+
for (auto& mark : _marks)
2907+
{
2908+
mark.start.y += delta;
2909+
2910+
// If the mark had sub-regions, then move those pointers too
2911+
if (mark.commandEnd.has_value())
2912+
{
2913+
(*mark.commandEnd).y += delta;
2914+
}
2915+
if (mark.outputEnd.has_value())
2916+
{
2917+
(*mark.outputEnd).y += delta;
2918+
}
2919+
}
2920+
_trimMarksOutsideBuffer();
2921+
}
2922+
2923+
// Method Description:
2924+
// - Add a mark to our list of marks, and treat it as the active "prompt". For
2925+
// the sake of shell integration, we need to know which mark represents the
2926+
// current prompt/command/output. Internally, we'll always treat the _last_
2927+
// mark in the list as the current prompt.
2928+
// Arguments:
2929+
// - m: the mark to add.
2930+
void TextBuffer::StartPromptMark(const ScrollMark& m)
2931+
{
2932+
_marks.push_back(m);
2933+
}
2934+
// Method Description:
2935+
// - Add a mark to our list of marks. Don't treat this as the active prompt.
2936+
// This should be used for marks created by the UI or from other user input.
2937+
// By inserting at the start of the list, we can separate out marks that were
2938+
// generated by client programs vs ones created by the user.
2939+
// Arguments:
2940+
// - m: the mark to add.
2941+
void TextBuffer::AddMark(const ScrollMark& m)
2942+
{
2943+
_marks.insert(_marks.begin(), m);
2944+
}
2945+
2946+
void TextBuffer::_trimMarksOutsideBuffer()
2947+
{
2948+
const auto height = GetSize().Height();
2949+
_marks.erase(std::remove_if(_marks.begin(),
2950+
_marks.end(),
2951+
[height](const auto& m) {
2952+
return (m.start.y < 0) ||
2953+
(m.start.y >= height);
2954+
}),
2955+
_marks.end());
2956+
}
2957+
2958+
void TextBuffer::SetCurrentPromptEnd(const til::point pos) noexcept
2959+
{
2960+
if (_marks.empty())
2961+
{
2962+
return;
2963+
}
2964+
auto& curr{ _marks.back() };
2965+
curr.end = pos;
2966+
}
2967+
void TextBuffer::SetCurrentCommandEnd(const til::point pos) noexcept
2968+
{
2969+
if (_marks.empty())
2970+
{
2971+
return;
2972+
}
2973+
auto& curr{ _marks.back() };
2974+
curr.commandEnd = pos;
2975+
}
2976+
void TextBuffer::SetCurrentOutputEnd(const til::point pos, ::MarkCategory category) noexcept
2977+
{
2978+
if (_marks.empty())
2979+
{
2980+
return;
2981+
}
2982+
auto& curr{ _marks.back() };
2983+
curr.outputEnd = pos;
2984+
curr.category = category;
2985+
}

src/buffer/out/textBuffer.hpp

+48
Original file line numberDiff line numberDiff line change
@@ -64,6 +64,41 @@ namespace Microsoft::Console::Render
6464
class Renderer;
6565
}
6666

67+
enum class MarkCategory
68+
{
69+
Prompt = 0,
70+
Error = 1,
71+
Warning = 2,
72+
Success = 3,
73+
Info = 4
74+
};
75+
struct ScrollMark
76+
{
77+
std::optional<til::color> color;
78+
til::point start;
79+
til::point end; // exclusive
80+
std::optional<til::point> commandEnd;
81+
std::optional<til::point> outputEnd;
82+
83+
MarkCategory category{ MarkCategory::Info };
84+
// Other things we may want to think about in the future are listed in
85+
// GH#11000
86+
87+
bool HasCommand() const noexcept
88+
{
89+
return commandEnd.has_value() && *commandEnd != end;
90+
}
91+
bool HasOutput() const noexcept
92+
{
93+
return outputEnd.has_value() && *outputEnd != *commandEnd;
94+
}
95+
std::pair<til::point, til::point> GetExtent() const
96+
{
97+
til::point realEnd{ til::coalesce_value(outputEnd, commandEnd, end) };
98+
return std::make_pair(til::point{ start }, realEnd);
99+
}
100+
};
101+
67102
class TextBuffer final
68103
{
69104
public:
@@ -228,6 +263,16 @@ class TextBuffer final
228263
void CopyPatterns(const TextBuffer& OtherBuffer);
229264
interval_tree::IntervalTree<til::point, size_t> GetPatterns(const til::CoordType firstRow, const til::CoordType lastRow) const;
230265

266+
const std::vector<ScrollMark>& GetMarks() const noexcept;
267+
void ClearMarksInRange(const til::point start, const til::point end);
268+
void ClearAllMarks() noexcept;
269+
void ScrollMarks(const int delta);
270+
void StartPromptMark(const ScrollMark& m);
271+
void AddMark(const ScrollMark& m);
272+
void SetCurrentPromptEnd(const til::point pos) noexcept;
273+
void SetCurrentCommandEnd(const til::point pos) noexcept;
274+
void SetCurrentOutputEnd(const til::point pos, ::MarkCategory category) noexcept;
275+
231276
private:
232277
void _reserve(til::size screenBufferSize, const TextAttribute& defaultAttributes);
233278
void _commit(const std::byte* row);
@@ -251,6 +296,7 @@ class TextBuffer final
251296
til::point _GetWordEndForAccessibility(const til::point target, const std::wstring_view wordDelimiters, const til::point limit) const;
252297
til::point _GetWordEndForSelection(const til::point target, const std::wstring_view wordDelimiters) const;
253298
void _PruneHyperlinks();
299+
void _trimMarksOutsideBuffer();
254300

255301
static void _AppendRTFText(std::ostringstream& contentBuilder, const std::wstring_view& text);
256302

@@ -327,6 +373,8 @@ class TextBuffer final
327373

328374
bool _isActiveBuffer = false;
329375

376+
std::vector<ScrollMark> _marks;
377+
330378
#ifdef UNIT_TESTING
331379
friend class TextBufferTests;
332380
friend class UiaTextRangeTests;

src/cascadia/TerminalApp/CommandPalette.xaml

+1
Original file line numberDiff line numberDiff line change
@@ -75,6 +75,7 @@
7575
HorizontalAlignment="Right"
7676
VerticalAlignment="Center"
7777
AutomationProperties.AccessibilityView="Raw"
78+
Background="{ThemeResource FlyoutPresenterBackground}"
7879
Style="{ThemeResource KeyChordBorderStyle}"
7980
Visibility="{x:Bind Item.KeyChordText, Mode=OneWay, Converter={StaticResource CommandKeyChordVisibilityConverter}}">
8081

src/cascadia/TerminalControl/ControlCore.cpp

+13-13
Original file line numberDiff line numberDiff line change
@@ -2111,7 +2111,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
21112111

21122112
void ControlCore::AddMark(const Control::ScrollMark& mark)
21132113
{
2114-
::Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark m{};
2114+
::ScrollMark m{};
21152115

21162116
if (mark.Color.HasValue)
21172117
{
@@ -2140,7 +2140,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
21402140
const auto currentOffset = ScrollOffset();
21412141
const auto& marks{ _terminal->GetScrollMarks() };
21422142

2143-
std::optional<DispatchTypes::ScrollMark> tgt;
2143+
std::optional<::ScrollMark> tgt;
21442144

21452145
switch (direction)
21462146
{
@@ -2243,7 +2243,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
22432243
const til::point start = HasSelection() ? (goUp ? _terminal->GetSelectionAnchor() : _terminal->GetSelectionEnd()) :
22442244
_terminal->GetTextBuffer().GetCursor().GetPosition();
22452245

2246-
std::optional<DispatchTypes::ScrollMark> nearest{ std::nullopt };
2246+
std::optional<::ScrollMark> nearest{ std::nullopt };
22472247
const auto& marks{ _terminal->GetScrollMarks() };
22482248

22492249
// Early return so we don't have to check for the validity of `nearest` below after the loop exits.
@@ -2283,7 +2283,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
22832283
const til::point start = HasSelection() ? (goUp ? _terminal->GetSelectionAnchor() : _terminal->GetSelectionEnd()) :
22842284
_terminal->GetTextBuffer().GetCursor().GetPosition();
22852285

2286-
std::optional<DispatchTypes::ScrollMark> nearest{ std::nullopt };
2286+
std::optional<::ScrollMark> nearest{ std::nullopt };
22872287
const auto& marks{ _terminal->GetScrollMarks() };
22882288

22892289
static constexpr til::point worst{ til::CoordTypeMax, til::CoordTypeMax };
@@ -2357,8 +2357,8 @@ namespace winrt::Microsoft::Terminal::Control::implementation
23572357

23582358
void ControlCore::_contextMenuSelectMark(
23592359
const til::point& pos,
2360-
bool (*filter)(const DispatchTypes::ScrollMark&),
2361-
til::point_span (*getSpan)(const DispatchTypes::ScrollMark&))
2360+
bool (*filter)(const ::ScrollMark&),
2361+
til::point_span (*getSpan)(const ::ScrollMark&))
23622362
{
23632363
// Do nothing if the caller didn't give us a way to get the span to select for this mark.
23642364
if (!getSpan)
@@ -2391,20 +2391,20 @@ namespace winrt::Microsoft::Terminal::Control::implementation
23912391
{
23922392
_contextMenuSelectMark(
23932393
_contextMenuBufferPosition,
2394-
[](const DispatchTypes::ScrollMark& m) -> bool { return !m.HasCommand(); },
2395-
[](const DispatchTypes::ScrollMark& m) { return til::point_span{ m.end, *m.commandEnd }; });
2394+
[](const ::ScrollMark& m) -> bool { return !m.HasCommand(); },
2395+
[](const ::ScrollMark& m) { return til::point_span{ m.end, *m.commandEnd }; });
23962396
}
23972397
void ControlCore::ContextMenuSelectOutput()
23982398
{
23992399
_contextMenuSelectMark(
24002400
_contextMenuBufferPosition,
2401-
[](const DispatchTypes::ScrollMark& m) -> bool { return !m.HasOutput(); },
2402-
[](const DispatchTypes::ScrollMark& m) { return til::point_span{ *m.commandEnd, *m.outputEnd }; });
2401+
[](const ::ScrollMark& m) -> bool { return !m.HasOutput(); },
2402+
[](const ::ScrollMark& m) { return til::point_span{ *m.commandEnd, *m.outputEnd }; });
24032403
}
24042404

24052405
bool ControlCore::_clickedOnMark(
24062406
const til::point& pos,
2407-
bool (*filter)(const DispatchTypes::ScrollMark&))
2407+
bool (*filter)(const ::ScrollMark&))
24082408
{
24092409
// Don't show this if the click was on the selection
24102410
if (_terminal->IsSelectionActive() &&
@@ -2442,7 +2442,7 @@ namespace winrt::Microsoft::Terminal::Control::implementation
24422442
{
24432443
// Relies on the anchor set in AnchorContextMenu
24442444
return _clickedOnMark(_contextMenuBufferPosition,
2445-
[](const DispatchTypes::ScrollMark& m) -> bool { return !m.HasCommand(); });
2445+
[](const ::ScrollMark& m) -> bool { return !m.HasCommand(); });
24462446
}
24472447

24482448
// Method Description:
@@ -2451,6 +2451,6 @@ namespace winrt::Microsoft::Terminal::Control::implementation
24512451
{
24522452
// Relies on the anchor set in AnchorContextMenu
24532453
return _clickedOnMark(_contextMenuBufferPosition,
2454-
[](const DispatchTypes::ScrollMark& m) -> bool { return !m.HasOutput(); });
2454+
[](const ::ScrollMark& m) -> bool { return !m.HasOutput(); });
24552455
}
24562456
}

src/cascadia/TerminalControl/ControlCore.h

+3-3
Original file line numberDiff line numberDiff line change
@@ -372,10 +372,10 @@ namespace winrt::Microsoft::Terminal::Control::implementation
372372

373373
void _contextMenuSelectMark(
374374
const til::point& pos,
375-
bool (*filter)(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark&),
376-
til::point_span (*getSpan)(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark&));
375+
bool (*filter)(const ::ScrollMark&),
376+
til::point_span (*getSpan)(const ::ScrollMark&));
377377

378-
bool _clickedOnMark(const til::point& pos, bool (*filter)(const ::Microsoft::Console::VirtualTerminal::DispatchTypes::ScrollMark&));
378+
bool _clickedOnMark(const til::point& pos, bool (*filter)(const ::ScrollMark&));
379379

380380
inline bool _IsClosing() const noexcept
381381
{

0 commit comments

Comments
 (0)