-
Notifications
You must be signed in to change notification settings - Fork 29.6k
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
readline: improve unicode support and tab completion
1. This reduces the number of write operations used during tab completion. 2. The tab completion calculated the string width using the length of the string instead of using the actual width. That is fixed. 3. The key decoder is now capable of handling characters composed out of two code points. That reduces the number of "keypress" events that are emitted which again lowers the amount of writes triggered. PR-URL: #31288 Reviewed-By: James M Snell <jasnell@gmail.com> Reviewed-By: Rich Trott <rtrott@gmail.com>
- Loading branch information
Showing
3 changed files
with
123 additions
and
71 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,68 @@ | ||
'use strict'; | ||
|
||
// Flags: --expose_internals | ||
|
||
const common = require('../common'); | ||
const readline = require('readline'); | ||
const assert = require('assert'); | ||
const EventEmitter = require('events').EventEmitter; | ||
const { getStringWidth } = require('internal/readline/utils'); | ||
|
||
// This test verifies that the tab completion supports unicode and the writes | ||
// are limited to the minimum. | ||
[ | ||
'あ', | ||
'𐐷', | ||
'🐕' | ||
].forEach((char) => { | ||
[true, false].forEach((lineBreak) => { | ||
const completer = (line) => [ | ||
[ | ||
'First group', | ||
'', | ||
`${char}${'a'.repeat(10)}`, `${char}${'b'.repeat(10)}`, char.repeat(11), | ||
], | ||
line | ||
]; | ||
|
||
let output = ''; | ||
const width = getStringWidth(char) - 1; | ||
|
||
class FakeInput extends EventEmitter { | ||
columns = ((width + 1) * 10 + (lineBreak ? 0 : 10)) * 3 | ||
|
||
write = common.mustCall((data) => { | ||
output += data; | ||
}, 6) | ||
|
||
resume() {} | ||
pause() {} | ||
end() {} | ||
} | ||
|
||
const fi = new FakeInput(); | ||
const rli = new readline.Interface({ | ||
input: fi, | ||
output: fi, | ||
terminal: true, | ||
completer: completer | ||
}); | ||
|
||
const last = '\r\nFirst group\r\n\r\n' + | ||
`${char}${'a'.repeat(10)}${' '.repeat(2 + width * 10)}` + | ||
`${char}${'b'.repeat(10)}` + | ||
(lineBreak ? '\r\n' : ' '.repeat(2 + width * 10)) + | ||
`${char.repeat(11)}\r\n` + | ||
`\r\n\u001b[1G\u001b[0J> ${char}\u001b[${4 + width}G`; | ||
|
||
const expectations = [char, '', last]; | ||
|
||
rli.on('line', common.mustNotCall()); | ||
for (const character of `${char}\t\t`) { | ||
fi.emit('data', character); | ||
assert.strictEqual(output, expectations.shift()); | ||
output = ''; | ||
} | ||
rli.close(); | ||
}); | ||
}); |