158 Commits

Author SHA1 Message Date
Salvatore Sanfilippo
dc83cc373a Document test suite in README
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>
2.0
2026-01-07 23:33:27 +01:00
Salvatore Sanfilippo
e1884759b8 Fix VT100 emulator orphaned continuation cell bug
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>
2026-01-07 23:26:48 +01:00
Salvatore Sanfilippo
9348bfcd2d Reduce test terminal size from 80x24 to 60x15
Smaller virtual terminal fits better in normal-sized terminal windows
for users running the test suite.

Updates affected tests:
- test_horizontal_scroll: adjust char counts and cursor positions
- test_multiline_wrap: adjust char counts for 60-col wrapping
- test_multiline_cursor_movement: adjust char counts
- test_multiline_history: adjust char counts

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

Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
2026-01-07 23:22:06 +01:00
Salvatore Sanfilippo
1976997c38 Rename linenoise_example to linenoise-example 2026-01-07 22:50:02 +01:00
Salvatore Sanfilippo
a7b86c1744 Add test framework with VT100 terminal emulator
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>
2026-01-07 21:58:30 +01:00
Salvatore Sanfilippo
c12b66d255 Add UTF-8 and grapheme cluster support
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>
2026-01-07 21:58:20 +01:00
Salvatore Sanfilippo
e26268de5e Merge pull request #245 from matthewnourse/make-linenoiseEditFeed-handle-zero-available-bytes
Multiplexing: make lineNoiseEditFeed handle 0 available bytes.
2025-11-27 17:27:46 +01:00
Matthew Nourse
49202848c8 Fit coding style guidelines 2025-11-27 20:47:36 +11:00
Matthew Nourse
cb7ccfbb9f Multiplexing: if lineNoiseEditFeed is called when there are no bytes available on the open input fd then return linenoiseEditMore rather than NULL. 2025-11-27 16:37:26 +11:00
Salvatore Sanfilippo
880b94130f Merge pull request #240 from gtwilliams/patch-1
Fix CVE-2025-9810
2025-09-10 17:27:26 +02:00
Garry T. Williams
f2558e1e58 Fix CVE-2025-9810 2025-09-10 09:48:24 -04:00
Salvatore Sanfilippo
d895173d67 Merge pull request #221 from 9Ajiang/master
advance enableRawMode() before getColumns()
2024-02-23 08:59:30 +01:00
9A
4111f1d6cd advance enableRawMode() before getColumns() 2024-02-23 15:44:25 +08:00
antirez
93b2db9bd4 Multiplexing: documentation improved. 2023-03-27 13:17:49 +02:00
antirez
3476ccc9c7 Multiplexing: README updated. 2023-03-27 10:36:03 +02:00
antirez
8087db33d8 Multiline: just remember last num of rows, not max.
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.
2023-03-27 10:07:47 +02:00
antirez
81f44df639 Multiplexing: fix line refresh in completion mode. 2023-03-27 09:36:31 +02:00
antirez
a1d8e181c2 Multiplexing: make completion non-blocking as well. 2023-03-27 09:21:31 +02:00
antirez
65db823f8b Some documentation and comments updates. 2023-03-26 23:27:33 +02:00
antirez
c9d36d0681 Multiplexing: API refactoring, no TTY support. 2023-03-26 22:22:40 +02:00
antirez
dbfe83bb67 Multiplexing: fix refreshMultiLine(). 2023-03-26 16:44:29 +02:00
antirez
622c777f41 Multiplexing: implement example using it. 2023-03-26 16:42:22 +02:00
antirez
c9123ec3c6 Multiplexing: hide/show current line. 2023-03-26 13:23:59 +02:00
antirez
0d66aaca11 Multiplexing: code refactored into calls for each step. 2023-03-26 11:04:28 +02:00
antirez
97d2850af1 Use unsigned int instead of uint like rest of code base. 2020-03-12 15:51:45 +01:00
Salvatore Sanfilippo
4ce393a66b Merge pull request #185 from yossigo/fix-c99-warning
Fix compilation in non C99/C11 mode.
2020-03-12 15:48:04 +01:00
Yossi Gottlieb
8c1c63c5fd Fix compilation in non C99/C11 mode. 2020-03-12 14:48:36 +02:00
Salvatore Sanfilippo
fc9667a81d Merge pull request #183 from lifubang/fixmasking
fix masking input when there is no hintsCallback
2020-03-05 10:44:35 +01:00
lifubang
ec5e4e8716 fix masking input when there is no hintsCallback
Signed-off-by: lifubang <lifubang@acmcoder.com>
2020-03-03 11:51:08 +08:00
antirez
4261898b11 A few improvements to mask mode. 2020-03-02 17:06:38 +01:00
Salvatore Sanfilippo
f31e883a08 Merge pull request #182 from lifubang/masking
add mask input mode
2020-03-02 16:56:27 +01:00
lifubang
514b09cd35 add mask input mode
Signed-off-by: lifubang <lifubang@acmcoder.com>
2020-03-01 18:32:11 +08:00
Salvatore Sanfilippo
4a961c0108 Merge pull request #151 from hoelzro/master
Set seq to empty string if color/bold not used
2018-07-18 18:29:05 +02:00
Salvatore Sanfilippo
cc2ea638ee Merge pull request #152 from fbrusch/master
Update README.markdown
2018-07-18 18:27:56 +02:00
fbrusch
cc53ed4bb0 Update README.markdown
Fix little typo
2018-04-22 12:43:43 +02:00
Rob Hoelz
b12f6ba9cb Set seq to empty string if color/bold not used
Otherwise the subsequent abAppend will concatenate whatever junk data
is in seq to ab
2018-02-15 22:38:41 -06:00
antirez
2105ce4458 README: add related projects section. 2017-06-20 11:30:07 +02:00
antirez
c894b9e59f Fix insecure history file creation.
See https://bugs.debian.org/cgi-bin/bugreport.cgi?bug=832460.

This patch was kindly contributed by Chris Lamb (@lamby).
2016-07-29 11:25:35 +02:00
antirez
2eb4956846 Clear hints after newline. 2016-04-13 12:19:04 +02:00
antirez
a64257a8d2 Hints: when only bold is set, use color 37 (white). 2016-04-12 18:44:46 +02:00
antirez
24c52baad6 Linenoise API documented. 2016-04-12 18:39:43 +02:00
antirez
24e401c202 Use sane defaults for hints color and bold. 2016-04-12 18:35:12 +02:00
antirez
ae5f793ec0 linenoiseFree() API introduced. 2016-04-12 18:08:33 +02:00
antirez
12a8680d8a Hints WIP 2016-04-12 17:59:41 +02:00
antirez
d97e7665a8 Copyright info updated. 2016-04-06 13:40:15 +02:00
antirez
94d9ddb256 4096 bytes line limit removed when STDIN is not a tty. 2016-04-06 13:39:09 +02:00
antirez
027dbcef5d Reported to work with Emacs comint mode. 2015-07-13 16:04:24 +02:00
antirez
80fd0569d1 Version 1.0
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.
1.0
2015-04-13 09:38:43 +02:00
antirez
cf1bdf5f89 License file added.
However the files linenose.c and linenose.h already had inline licenses.
2014-10-07 15:23:53 +02:00
antirez
c1c5a026d0 Move to end before return when in multi-line mode.
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.
2014-09-03 11:49:43 +02:00