1'use strict'; 2const stripAnsi = require('strip-ansi'); 3const isFullwidthCodePoint = require('is-fullwidth-code-point'); 4 5module.exports = str => { 6 if (typeof str !== 'string' || str.length === 0) { 7 return 0; 8 } 9 10 str = stripAnsi(str); 11 12 let width = 0; 13 14 for (let i = 0; i < str.length; i++) { 15 const code = str.codePointAt(i); 16 17 // Ignore control characters 18 if (code <= 0x1F || (code >= 0x7F && code <= 0x9F)) { 19 continue; 20 } 21 22 // Ignore combining characters 23 if (code >= 0x300 && code <= 0x36F) { 24 continue; 25 } 26 27 // Surrogates 28 if (code > 0xFFFF) { 29 i++; 30 } 31 32 width += isFullwidthCodePoint(code) ? 2 : 1; 33 } 34 35 return width; 36}; 37