diff --git a/lib/internal/readline/utils.js b/lib/internal/readline/utils.js index e4d718d94f400b..7c24a8e195a301 100644 --- a/lib/internal/readline/utils.js +++ b/lib/internal/readline/utils.js @@ -36,6 +36,29 @@ CSI.kClearToLineEnd = CSI`0K`; CSI.kClearLine = CSI`2K`; CSI.kClearScreenDown = CSI`0J`; +// TODO(BridgeAR): Treat combined characters as single character, i.e, +// 'a\u0301' and '\u0301a' (both have the same visual output). +// Check Canonical_Combining_Class in +// http://userguide.icu-project.org/strings/properties +function charLengthLeft(str, i) { + if (i <= 0) + return 0; + if ((i > 1 && str.codePointAt(i - 2) >= kUTF16SurrogateThreshold) || + str.codePointAt(i - 1) >= kUTF16SurrogateThreshold) { + return 2; + } + return 1; +} + +function charLengthAt(str, i) { + if (str.length <= i) { + // Pretend to move to the right. This is necessary to autocomplete while + // moving to the right. + return 1; + } + return str.codePointAt(i) >= kUTF16SurrogateThreshold ? 2 : 1; +} + if (internalBinding('config').hasIntl) { const icu = internalBinding('icu'); // icu.getStringWidth(string, ambiguousAsFullWidth, expandEmojiSequence) @@ -452,6 +475,8 @@ function commonPrefix(strings) { } module.exports = { + charLengthAt, + charLengthLeft, commonPrefix, emitKeys, getStringWidth, diff --git a/lib/readline.js b/lib/readline.js index 4533557690f455..6b50f30b21508a 100644 --- a/lib/readline.js +++ b/lib/readline.js @@ -49,6 +49,8 @@ const { validateString } = require('internal/validators'); const { inspect } = require('internal/util/inspect'); const EventEmitter = require('events'); const { + charLengthAt, + charLengthLeft, commonPrefix, CSI, emitKeys, @@ -591,25 +593,6 @@ Interface.prototype._wordRight = function() { } }; -function charLengthLeft(str, i) { - if (i <= 0) - return 0; - if ((i > 1 && str.codePointAt(i - 2) >= kUTF16SurrogateThreshold) || - str.codePointAt(i - 1) >= kUTF16SurrogateThreshold) { - return 2; - } - return 1; -} - -function charLengthAt(str, i) { - if (str.length <= i) { - // Pretend to move to the right. This is necessary to autocomplete while - // moving to the right. - return 1; - } - return str.codePointAt(i) >= kUTF16SurrogateThreshold ? 2 : 1; -} - Interface.prototype._deleteLeft = function() { if (this.cursor > 0 && this.line.length > 0) { // The number of UTF-16 units comprising the character to the left