@@ -566,8 +566,7 @@ void Screen<Cell>::writeTextInternal(char32_t sourceCodepoint)
566566 else
567567 {
568568 auto const extendedWidth = usePreviousCell ().appendCharacter (codepoint);
569- if (extendedWidth > 0 )
570- clearAndAdvance (extendedWidth);
569+ clearAndAdvance (0 , extendedWidth);
571570 _terminal->markCellDirty (_lastCursorPosition);
572571 }
573572
@@ -592,17 +591,19 @@ void Screen<Cell>::writeCharToCurrentAndAdvance(char32_t codepoint) noexcept
592591 {
593592 // Erase the left half of the wide char.
594593 Cell& prevCell = line.useCellAt (_cursor.position .column - 1 );
595- prevCell.reset ();
594+ prevCell.reset (_cursor. graphicsRendition );
596595 }
597596
597+ auto const oldWidth = cell.width ();
598+
598599 cell.write (_cursor.graphicsRendition ,
599600 codepoint,
600601 static_cast <uint8_t >(unicode::width (codepoint)),
601602 _cursor.hyperlink );
602603
603604 _lastCursorPosition = _cursor.position ;
604605
605- clearAndAdvance (cell.width ());
606+ clearAndAdvance (oldWidth, cell.width ());
606607
607608 // TODO: maybe move selector API up? So we can make this call conditional,
608609 // and only call it when something is selected?
@@ -614,32 +615,23 @@ void Screen<Cell>::writeCharToCurrentAndAdvance(char32_t codepoint) noexcept
614615
615616template <typename Cell>
616617CRISPY_REQUIRES (CellConcept<Cell>)
617- void Screen<Cell>::clearAndAdvance(int offset ) noexcept
618+ void Screen<Cell>::clearAndAdvance(int oldWidth, int newWidth ) noexcept
618619{
619- if (offset == 0 )
620- return ;
621-
622620 bool const cursorInsideMargin =
623621 _terminal->isModeEnabled (DECMode::LeftRightMargin) && isCursorInsideMargins ();
624622 auto const cellsAvailable = cursorInsideMargin ? *(margin ().horizontal .to - _cursor.position .column ) - 1
625623 : *pageSize ().columns - *_cursor.position .column - 1 ;
626- auto const n = min (offset, cellsAvailable);
627624
628- if (n == offset)
629- {
630- _cursor.position .column ++;
631- auto & line = currentLine ();
632- for (int i = 1 ; i < n; ++i) // XXX It's not even clear if other TEs are doing that, too.
633- {
634- line.useCellAt (_cursor.position .column )
635- .reset (_cursor.graphicsRendition .with (CellFlag::WideCharContinuation), _cursor.hyperlink );
636- _cursor.position .column ++;
637- }
638- }
625+ auto const sgr = newWidth > 1 ? _cursor.graphicsRendition .with (CellFlag::WideCharContinuation)
626+ : _cursor.graphicsRendition ;
627+ auto & line = currentLine ();
628+ for (int i = 1 ; i < min (max (oldWidth, newWidth), cellsAvailable); ++i)
629+ line.useCellAt (_cursor.position .column + i).reset (sgr, _cursor.hyperlink );
630+
631+ if (newWidth == min (newWidth, cellsAvailable))
632+ _cursor.position .column += ColumnOffset::cast_from (newWidth);
639633 else if (_cursor.autoWrap )
640- {
641634 _cursor.wrapPending = true ;
642- }
643635}
644636
645637template <typename Cell>
0 commit comments