diff --git a/lib/hterm.js b/lib/hterm.js index d9f202c8..68440c4d 100644 --- a/lib/hterm.js +++ b/lib/hterm.js @@ -53,6 +53,84 @@ hterm.Terminal.prototype.onMouse_ = function (e) { function containsNonLatinCodepoints(s) { return /[^\u0000-\u00ff]/.test(s); } + +// hterm Unicode patch +hterm.TextAttributes.splitWidecharString = function (str) { + const context = runes(str).reduce((ctx, rune) => { + const code = rune.codePointAt(0); + if (code < 128 || lib.wc.charWidth(code) === 1) { + ctx.acc += rune; + return ctx; + } + if (ctx.acc) { + context.items.push({str: ctx.acc}); + ctx.acc = ''; + } + context.items.push({str: rune, wcNode: true}); + return ctx; + }, {items: [], acc: ''}); + if (context.acc) { + context.items.push({str: context.acc}); + } + return context.items; +}; + +// hterm Unicode patch +lib.wc.strWidth = function (str) { + const chars = runes(str); + let width = 0; + let rv = 0; + + for (let i = 0; i < chars.length; i++) { + const codePoint = chars[i].codePointAt(0); + width = lib.wc.charWidth(codePoint); + if (width < 0) { + return -1; + } + rv += width * ((codePoint <= 0xffff) ? 1 : 2); + } + return rv; +}; + +// hterm Unicode patch +lib.wc.substr = function (str, start, optWidth) { + const chars = runes(str); + let startIndex; + let endIndex; + let width = 0; + + for (let i = 0; i < chars.length; i++) { + const codePoint = chars[i].codePointAt(0); + const charWidth = lib.wc.charWidth(codePoint); + if ((width + charWidth) > start) { + startIndex = i; + break; + } + width += charWidth; + } + + if (optWidth) { + width = 0; + for (endIndex = startIndex; endIndex < chars.length && width < optWidth; endIndex++) { + width += lib.wc.charWidth(chars[endIndex].charCodeAt(0)); + } + + if (width > optWidth) { + endIndex--; + } + return chars.slice(startIndex, endIndex).join(''); + } + return chars.slice(startIndex).join(''); +}; + +// MacOS emoji bar support +hterm.Keyboard.prototype.onTextInput_ = function (e) { + if (!e.data) { + return; + } + runes(e.data).forEach(this.terminal.onVTKeystroke.bind(this.terminal)); +}; + hterm.Terminal.IO.prototype.writeUTF8 = function (string) { if (this.terminal_.io !== this) { throw new Error('Attempt to print from inactive IO object.');