From 9bfcdbf2131ae6c08040226be6e92447db625b18 Mon Sep 17 00:00:00 2001 From: Richard Qin Date: Mon, 26 Oct 2026 21:27:00 +0800 Subject: feat(tui): add reusable text input component --- src/tui/text.cc | 20 ++++++++++++++++++++ 1 file changed, 20 insertions(+) (limited to 'src/tui/text.cc') diff --git a/src/tui/text.cc b/src/tui/text.cc index b2c64b8..95b324b 100644 --- a/src/tui/text.cc +++ b/src/tui/text.cc @@ -24,6 +24,7 @@ #include #include #include +#include #include #include @@ -65,6 +66,25 @@ WordKind word_kind( UChar32 codepoint ) TextService::TextService( std::size_t glyph_capacity ) : glyph_capacity_( glyph_capacity ) {} +std::string TextService::encode( std::u32string_view input ) const +{ + // ICU's UTF-32 conversion takes a signed 32-bit length, like its break iterator. + if ( input.size() > INT32_MAX ) { + throw std::length_error( "Input exceeds ICU conversion length capacity" ); + } + const std::vector codepoints( input.begin(), input.end() ); + // fromUTF32 requires a non-null pointer even for a zero-length input. + const UChar32 empty = 0; + const auto converted = icu::UnicodeString::fromUTF32( codepoints.empty() ? &empty : codepoints.data(), + static_cast( codepoints.size() ) ); + if ( converted.isBogus() ) { + throw std::runtime_error( "ICU could not convert editor input" ); + } + std::string result; + converted.toUTF8String( result ); + return result; +} + TextAnalysis TextService::analyze( std::string_view utf8, bool line_breaks, bool tabs ) const { // ICU BreakIterator exposes int32_t native offsets even with a UTF-8 UText. -- cgit v1.2.3