@@ -339,13 +339,35 @@ size_t Screen<Cell, TheScreenType>::emplaceCharsIntoCurrentLine(string_view _cha
339
339
auto columnsAvailable = (_state.margin .horizontal .to .value + 1 ) - _state.cursor .position .column .value ;
340
340
auto const charsToWrite = static_cast <size_t >(min (columnsAvailable, static_cast <int >(_chars.size ())));
341
341
342
- currentLine ().reset (_state.cursor .graphicsRendition ,
343
- _state.cursor .hyperlink ,
344
- crispy::BufferFragment {
345
- _terminal.currentPtyBuffer (),
346
- _chars.substr (0 , charsToWrite),
347
- });
348
- advanceCursorAfterWrite (ColumnCount::cast_from (charsToWrite));
342
+ Line<Cell>& line = currentLine ();
343
+ if (!line.isInflatedBuffer () && line.empty ())
344
+ {
345
+ // Only use fastpath if the currently line hasn't been inflated already.
346
+ // Because we might lose prior-written textual/SGR information otherwise.
347
+ line.reset (_state.cursor .graphicsRendition ,
348
+ _state.cursor .hyperlink ,
349
+ crispy::BufferFragment {
350
+ _terminal.currentPtyBuffer (),
351
+ _chars.substr (0 , charsToWrite),
352
+ });
353
+ advanceCursorAfterWrite (ColumnCount::cast_from (charsToWrite));
354
+ }
355
+ else
356
+ {
357
+ // Transforming _chars input from UTF-8 to UTF-32 even though right now it should only
358
+ // be containing US-ASCII, but soon it'll be any arbitrary textual Unicode codepoints.
359
+ auto utf8DecoderState = unicode::utf8_decoder_state {};
360
+ for (char const ch: _chars)
361
+ {
362
+ auto const result = unicode::from_utf8 (utf8DecoderState, static_cast <uint8_t >(ch));
363
+ if (holds_alternative<unicode::Success>(result))
364
+ writeText (get<unicode::Success>(result).value );
365
+ else if (holds_alternative<unicode::Invalid>(result))
366
+ writeText (U' \uFFFE ' ); // U+FFFE (Not a Character)
367
+ }
368
+ }
369
+ // fmt::print("emplaceCharsIntoCurrentLine ({} cols, {} bytes): \"{}\"\n", cellCount, _chars.size(),
370
+ // _chars);
349
371
return charsToWrite;
350
372
}
351
373
0 commit comments