mirror of
https://github.com/microsoft/terminal.git
synced 2026-03-25 14:00:33 -04:00
make filling chars (and, thus, erase line/char) unset wrap (#2831)
EraseInLine calls `FillConsoleOutputCharacterW()`. In filling the row with chars, we were setting the wrap flag. We need to specifically not do this on ANY _FILL_ operation. Now a fill operation UNSETS the wrap flag if we fill to the end of the line. Originally, we had a boolean `setWrap` that would mean... - **true**: if writing to the end of the row, SET the wrap value to true - **false**: if writing to the end of the row, DON'T CHANGE the wrap value Now we're making this bool a std::optional to allow for a ternary state. This allows for us to handle the following cases completely. Refer to the table below: ,- current wrap value | ,- are we filling the last cell in the row? | | ,- new wrap value | | | ,- comments |-- |-- |-- | | 0 | 0 | 0 | | 0 | 1 | 0 | | 0 | 1 | 1 | THIS CASE WAS HANDLED CORRECTLY | 1 | 0 | 0 | THIS CASE WAS UNHANDLED | 1 | 0 | 1 | | 1 | 1 | 1 | To handle that special case (1-0-0), we need to UNSET the wrap. So now, we have ~setWrap~ `wrap` mean the following: - **true**: if writing to the end of the row, SET the wrap value to TRUE - **false**: if writing to the end of the row, SET the wrap value to FALSE - **nullopt**: leave the wrap value as it is Closes #1126
This commit is contained in:
committed by
Dustin L. Howett (MSFT)
parent
a2f8a943b4
commit
4dd9f9c180
@@ -147,11 +147,11 @@ const UnicodeStorage& ROW::GetUnicodeStorage() const noexcept
|
||||
// Arguments:
|
||||
// - it - custom console iterator to use for seeking input data. bool() false when it becomes invalid while seeking.
|
||||
// - index - column in row to start writing at
|
||||
// - setWrap - set the wrap flags if we hit the end of the row while writing and there's still more data in the iterator.
|
||||
// - wrap - change the wrap flag if we hit the end of the row while writing and there's still more data in the iterator.
|
||||
// - limitRight - right inclusive column ID for the last write in this row. (optional, will just write to the end of row if nullopt)
|
||||
// Return Value:
|
||||
// - iterator to first cell that was not written to this row.
|
||||
OutputCellIterator ROW::WriteCells(OutputCellIterator it, const size_t index, const bool setWrap, std::optional<size_t> limitRight)
|
||||
OutputCellIterator ROW::WriteCells(OutputCellIterator it, const size_t index, const std::optional<bool> wrap, std::optional<size_t> limitRight)
|
||||
{
|
||||
THROW_HR_IF(E_INVALIDARG, index >= _charRow.size());
|
||||
THROW_HR_IF(E_INVALIDARG, limitRight.value_or(0) >= _charRow.size());
|
||||
@@ -202,10 +202,15 @@ OutputCellIterator ROW::WriteCells(OutputCellIterator it, const size_t index, co
|
||||
++it;
|
||||
}
|
||||
|
||||
// If we're asked to set the wrap status and we just filled the last column with some text, set wrap status on the row.
|
||||
if (setWrap && fillingLastColumn)
|
||||
// If we're asked to (un)set the wrap status and we just filled the last column with some text...
|
||||
// NOTE:
|
||||
// - wrap = std::nullopt --> don't change the wrap value
|
||||
// - wrap = true --> we're filling cells as a steam, consider this a wrap
|
||||
// - wrap = false --> we're filling cells as a block, unwrap
|
||||
if (wrap.has_value() && fillingLastColumn)
|
||||
{
|
||||
_charRow.SetWrapForced(true);
|
||||
// set wrap status on the row to parameter's value.
|
||||
_charRow.SetWrapForced(wrap.value());
|
||||
}
|
||||
}
|
||||
else
|
||||
|
||||
@@ -57,7 +57,7 @@ public:
|
||||
UnicodeStorage& GetUnicodeStorage() noexcept;
|
||||
const UnicodeStorage& GetUnicodeStorage() const noexcept;
|
||||
|
||||
OutputCellIterator WriteCells(OutputCellIterator it, const size_t index, const bool setWrap, std::optional<size_t> limitRight = std::nullopt);
|
||||
OutputCellIterator WriteCells(OutputCellIterator it, const size_t index, const std::optional<bool> wrap = std::nullopt, std::optional<size_t> limitRight = std::nullopt);
|
||||
|
||||
friend bool operator==(const ROW& a, const ROW& b) noexcept;
|
||||
|
||||
|
||||
@@ -318,10 +318,12 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt)
|
||||
// Arguments:
|
||||
// - givenIt - Iterator representing output cell data to write
|
||||
// - target - the row/column to start writing the text to
|
||||
// - wrap - change the wrap flag if we hit the end of the row while writing and there's still more data
|
||||
// Return Value:
|
||||
// - The final position of the iterator
|
||||
OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
|
||||
const COORD target)
|
||||
const COORD target,
|
||||
const std::optional<bool> wrap)
|
||||
{
|
||||
// Make mutable copy so we can walk.
|
||||
auto it = givenIt;
|
||||
@@ -336,7 +338,8 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
|
||||
while (it && size.IsInBounds(lineTarget))
|
||||
{
|
||||
// Attempt to write as much data as possible onto this line.
|
||||
it = WriteLine(it, lineTarget, true);
|
||||
// NOTE: if wrap = true/false, we want to set the line's wrap to true/false (respectively) if we reach the end of the line
|
||||
it = WriteLine(it, lineTarget, wrap);
|
||||
|
||||
// Move to the next line down.
|
||||
lineTarget.X = 0;
|
||||
@@ -351,13 +354,13 @@ OutputCellIterator TextBuffer::Write(const OutputCellIterator givenIt,
|
||||
// Arguments:
|
||||
// - givenIt - The iterator that will dereference into cell data to insert
|
||||
// - target - Coordinate targeted within output buffer
|
||||
// - setWrap - Whether we should try to set the wrap flag if we write up to the end of the line and have more data
|
||||
// - wrap - change the wrap flag if we hit the end of the row while writing and there's still more data in the iterator.
|
||||
// - limitRight - Optionally restrict the right boundary for writing (e.g. stop writing earlier than the end of line)
|
||||
// Return Value:
|
||||
// - The iterator, but advanced to where we stopped writing. Use to find input consumed length or cells written length.
|
||||
OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
|
||||
const COORD target,
|
||||
const bool setWrap,
|
||||
const std::optional<bool> wrap,
|
||||
std::optional<size_t> limitRight)
|
||||
{
|
||||
// If we're not in bounds, exit early.
|
||||
@@ -368,7 +371,7 @@ OutputCellIterator TextBuffer::WriteLine(const OutputCellIterator givenIt,
|
||||
|
||||
// Get the row and write the cells
|
||||
ROW& row = GetRowByOffset(target.Y);
|
||||
const auto newIt = row.WriteCells(givenIt, target.X, setWrap, limitRight);
|
||||
const auto newIt = row.WriteCells(givenIt, target.X, wrap, limitRight);
|
||||
|
||||
// Take the cell distance written and notify that it needs to be repainted.
|
||||
const auto written = newIt.GetCellDistance(givenIt);
|
||||
|
||||
@@ -89,11 +89,12 @@ public:
|
||||
OutputCellIterator Write(const OutputCellIterator givenIt);
|
||||
|
||||
OutputCellIterator Write(const OutputCellIterator givenIt,
|
||||
const COORD target);
|
||||
const COORD target,
|
||||
const std::optional<bool> wrap = true);
|
||||
|
||||
OutputCellIterator WriteLine(const OutputCellIterator givenIt,
|
||||
const COORD target,
|
||||
const bool setWrap = false,
|
||||
const std::optional<bool> setWrap = std::nullopt,
|
||||
const std::optional<size_t> limitRight = std::nullopt);
|
||||
|
||||
bool InsertCharacter(const wchar_t wch, const DbcsAttribute dbcsAttribute, const TextAttribute attr);
|
||||
|
||||
Reference in New Issue
Block a user