diff options
Diffstat (limited to 'lib/internal/readline')
-rw-r--r-- | lib/internal/readline/utils.js | 33 |
1 files changed, 26 insertions, 7 deletions
diff --git a/lib/internal/readline/utils.js b/lib/internal/readline/utils.js index c6cd13a6bd..f72a03bb39 100644 --- a/lib/internal/readline/utils.js +++ b/lib/internal/readline/utils.js @@ -34,13 +34,32 @@ if (internalBinding('config').hasIntl) { const icu = internalBinding('icu'); getStringWidth = function getStringWidth(str, options) { options = options || {}; - if (!Number.isInteger(str)) - str = stripVTControlCharacters(String(str)); - return icu.getStringWidth( - str, - Boolean(options.ambiguousAsFullWidth), - Boolean(options.expandEmojiSequence) - ); + if (Number.isInteger(str)) { + // Provide information about the character with code point 'str'. + return icu.getStringWidth( + str, + Boolean(options.ambiguousAsFullWidth), + false + ); + } + str = stripVTControlCharacters(String(str)); + let width = 0; + for (let i = 0; i < str.length; i++) { + // Try to avoid calling into C++ by first handling the ASCII portion of + // the string. If it is fully ASCII, we skip the C++ part. + const code = str.charCodeAt(i); + if (code < 127) { + width += code >= 32; + continue; + } + width += icu.getStringWidth( + str.slice(i), + Boolean(options.ambiguousAsFullWidth), + Boolean(options.expandEmojiSequence) + ); + break; + } + return width; }; isFullWidthCodePoint = function isFullWidthCodePoint(code, options) { |