Commit graph

14 commits

Author SHA1 Message Date
kofany
20fbea0e2d Move is_combining_char() to core utf8 module
Relocate is_combining_char() from gui-entry.c to src/core/utf8.c
as suggested in code review. This better organizes the codebase by
placing UTF-8 character classification logic with other UTF-8
utilities in the core module.

The function now uses is_utf8() instead of checking term_type
directly, which is the appropriate method for core layer code.

🤖 Generated with [Claude Code](https://claude.com/claude-code)

Co-Authored-By: Claude <noreply@anthropic.com>
2025-10-06 20:39:46 +02:00
kofany
becc4f9068 Fix emoji variation selector width calculation in string_advance
Addresses issue where emoji with variation selectors (like ❣️, ♥️) were
incorrectly calculated as width 1 instead of width 2, causing display
overflow in modern terminals.

- Add variation selector detection (0xFE0F) in string_advance_with_grapheme_support()
- Apply special width handling for base emoji + variation selector combinations
- Ensures consistent width calculation with input field processing
- Fixes chat window overflow issues in terminals like Ghostty

This brings string_advance logic in line with unichar_array_advance_cluster
which already had proper variation selector handling.
2025-09-10 20:55:25 +02:00
kofany
28a793d659 Implement proper UTF-8 grapheme cluster support for modern terminals
This commit addresses critical UTF-8 display and input issues, particularly
with emoji variations and complex Unicode sequences that caused rendering
problems in modern terminals like Ghostty.

Key improvements:
- Enhanced utf8.c with grapheme cluster detection using utf8proc
- Fixed input field handling to preserve emoji variation selectors
- Improved text measurement and cursor positioning for complex Unicode
- Added smart paste processing for multi-codepoint characters
- Bypassed problematic TRANSLIT when not needed for UTF-8 content
- Enhanced GUI entry and readline to handle grapheme clusters properly

The implementation maintains full backward compatibility while providing
proper support for modern Unicode standards, fixing display corruption
that occurred with emoji sequences containing variation selectors.

Tested with emoji sequences like: 💕💋😘🥰💞❣️💓♥️♥️💓❣️🥰🥰😘💋💋
2025-09-10 17:44:46 +02:00
ailin-nemui
7e6e1f2e10 Use full paths to includes 2019-05-01 22:08:45 +02:00
dequis
0d8632943d Add a wrapper of wcwidth() that picks the best implementation
This adds a i_wcwidth() function that replaces mk_wcwidth(), and a
'wcwidth_implementation' setting to pick which one it wraps.

Values:

- old: uses our local mk_wcwidth() which implements unicode 5.0
- system: uses the libc-provided wcwidth(), which may be better or worse
  than ours depending on how up to date the system is.
- auto: tests the system one against two characters that became
  fullwidth in unicode 5.2 and 9.0 respectively. If either of them pass,
  pick the system implementation, otherwise pick ours.

It defaults to auto.

mk_wcwidth() is still preferable in some cases, since the way it uses
ranges for fullwidth characters means most CJK blocks are covered even
if their characters didn't exist back then.

The "system" implementation is also wrapped to never return -1, but to
assume those unknown characters use one cell. Quoting the code:

    /* Treat all unknown characters as taking one cell. This is
     * the reason mk_wcwidth and other outdated implementations
     * mostly worked with newer unicode, while glibc's wcwidth
     * needs updating to recognize new characters.
     *
     * Instead of relying on that, we keep the behavior of assuming
     * one cell even for glibc's implementation, which is still
     * highly accurate and less of a headache overall.
     */
2018-08-23 02:30:26 -03:00
ailin-nemui
02221eae37 fix dist compilation failure
remove illegal wcwidth.c include and compile wcwidth.c
correct #include in wcwidth.c
fallout from #480
2016-05-18 16:50:41 +02:00
Xavier G
a26a387545 Adjust some conditions. 2016-05-13 17:31:11 +02:00
Xavier G
719efc44a3 Introduce string_chars_for_width(). 2016-05-13 03:04:08 +02:00
Xavier G
35b3ccc6a4 Introduce string_length() and string_width(). 2016-05-13 02:47:26 +02:00
Xavier G
21c07c0060 Leverage string_policy(). 2016-05-13 02:27:19 +02:00
Xavier G
2c8648a9c8 Introduce string_policy(). 2016-05-13 02:10:02 +02:00
Xavier G
b0afcc96db Rename advance() into string_advance(). 2016-05-13 01:52:37 +02:00
Xavier G
5c74a3bb88 Move advance() from fe-common/core to core. 2016-05-13 01:39:14 +02:00
Xavier G
5538578820 Move utf8.{h,c} from fe-common/core to core. 2016-05-13 01:26:33 +02:00
Renamed from src/fe-common/core/utf8.c (Browse further)