Add "Running the tests" section explaining:
- How to run tests (make test)
- What the tests cover (editing, UTF-8, emoji, scrolling, multiline)
- How the VT100 emulator-based test harness works
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
When a regular character (width=1) overwrote a wide character (width=2),
the continuation cell at the next position kept its width=0 state. During
rendering, this orphaned cell was skipped, causing one visual column to
be lost and misaligning the terminal border.
Fix: Before placing any character, check if:
1. Current cell is a continuation (width=0) - convert to space
2. Current cell was a wide char (width=2) - clear its continuation
This ensures proper column accounting when wide characters are replaced.
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement comprehensive test suite for linenoise:
VT100 Terminal Emulator:
- Column-based UTF-8 representation with display width tracking
- Each screen cell stores complete UTF-8 characters (up to 32 bytes)
- Proper handling of wide characters (emoji, CJK) as 2-column cells
- ZWJ tracking for grapheme cluster storage
- Escape sequence parsing for cursor movement and screen clearing
Test Harness:
- Fork/pipe architecture for testing via LINENOISE_ASSUME_TTY
- Visual rendering to real terminal for debugging failed tests
- Assertion helpers for screen content and cursor position
Test Coverage (72 tests):
- Basic typing and cursor movement
- UTF-8 input and navigation (é, 中, 🎉)
- Emoji cursor movement and deletion
- Grapheme clusters (heart+VS, thumbs up+skin tone, rainbow flag)
- Horizontal scrolling with long lines
- Horizontal scrolling with UTF-8 content
- Multiline mode basics
- Multiline history navigation (regression test)
- Word/line deletion (Ctrl-W, Ctrl-U)
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
Implement comprehensive UTF-8 handling for linenoise:
Core UTF-8 support:
- Proper multi-byte character navigation (left/right arrows)
- Correct backspace deletion for multi-byte characters
- Display width calculation for cursor positioning
- Wide character support (CJK, emoji) as 2-column display
Grapheme cluster support for complex emoji:
- Variation selectors (U+FE0E, U+FE0F) for emoji style
- Skin tone modifiers (U+1F3FB-U+1F3FF)
- Zero Width Joiner (U+200D) sequences like rainbow flag
- Regional indicators for flag emoji
- Combining diacritical marks
Navigation and deletion now treat entire grapheme clusters as single
units. For example, 🏳️🌈 (14 bytes, 4 codepoints) is handled as one
character for cursor movement and backspace.
Multiline mode fixes:
- Fix history navigation regression where going from multi-row to
single-row entries left dirty rows on screen
- Save actual cursor row position (oldrpos) instead of recalculating
Updates to linenoise.c:
- Add helper functions for UTF-8 decoding and grapheme detection
- Rewrite utf8PrevCharLen/utf8NextCharLen for grapheme clusters
- Add utf8CharWidth with proper zero-width character handling
- Add utf8StrWidth with ZWJ sequence support
- Fix refreshMultiLine cursor row tracking
Updates to linenoise.h:
- Add oldrpos field to linenoiseState for multiline cursor tracking
Updates to README:
- Document UTF-8 support for multi-byte characters and emoji
- Update line count from ~850 to ~1100
- Add "Running the tests" section
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
For some reason, the old code was always cleaning the maximum number of
rows used so far while editing in multi line mode. Actually we need to
clean just the number of rows used by the last line. The old behavior
created problems in multiplexing mode, where the line is refreshed at a
different row, if the user used linenoiseHide() / show() in order to
print something. With the new behavior, all looks fine, so far.
Linenoise is used in multiple projects for enough time, let's tag this
commit with a version number as requested into issue #88, so that we
have an initial reference.
Given the nature of the library, the version was also added in the
linenoise C and header file as well so that it is easy to realize for
people having a copy embedded somewhere if they are using the latest
version.
This makes sure that if we are editing in multi-line mode a line that
actually spawns across multiple lines, the next output performed by the
application using linenoise will not overwrite the edited line.