Bug fix: Word wrap when dealing with pipe codes

Bug fix: Assumed FES styleizers
This commit is contained in:
Bryan Ashby 2021-01-02 15:04:16 -07:00
parent 14b1b2b145
commit 862031c57f
No known key found for this signature in database
GPG Key ID: B49EB437951D2542
3 changed files with 44 additions and 7 deletions

View File

@ -442,7 +442,7 @@ exports.FullScreenEditorModule = exports.getModule = class FullScreenEditorModul
style = [ style ]; style = [ style ];
} }
while (style.length < len) { while (style.length < len) {
style.push(style); style.push(style[0]);
} }
return style; return style;
}; };

View File

@ -20,6 +20,7 @@ exports.stringFromNullTermBuffer = stringFromNullTermBuffer;
exports.stringToNullTermBuffer = stringToNullTermBuffer; exports.stringToNullTermBuffer = stringToNullTermBuffer;
exports.renderSubstr = renderSubstr; exports.renderSubstr = renderSubstr;
exports.renderStringLength = renderStringLength; exports.renderStringLength = renderStringLength;
exports.ansiRenderStringLength = ansiRenderStringLength;
exports.formatByteSizeAbbr = formatByteSizeAbbr; exports.formatByteSizeAbbr = formatByteSizeAbbr;
exports.formatByteSize = formatByteSize; exports.formatByteSize = formatByteSize;
exports.formatCountAbbr = formatCountAbbr; exports.formatCountAbbr = formatCountAbbr;
@ -297,7 +298,7 @@ function renderStringLength(s) {
let len = 0; let len = 0;
const re = ANSI_OR_PIPE_REGEXP; const re = ANSI_OR_PIPE_REGEXP;
re.lastIndex = 0; // we recycle the rege; reset re.lastIndex = 0; // we recycle the regex; reset
// //
// Loop counting only literal (non-control) sequences // Loop counting only literal (non-control) sequences
@ -312,7 +313,41 @@ function renderStringLength(s) {
len += s.slice(pos, m.index).length; len += s.slice(pos, m.index).length;
} }
if('C' === m[3]) { // ESC[<N>C is foward/right if('C' === m[3]) { // ESC[<N>C is forward/right
len += parseInt(m[2], 10) || 0;
}
}
} while(0 !== re.lastIndex);
if(pos < s.length) {
len += s.slice(pos).length;
}
return len;
}
// Like renderStringLength() but ANSI only (no pipe codes accounted for)
function ansiRenderStringLength(s) {
let m;
let pos;
let len = 0;
const re = ANSI.getFullMatchRegExp();
//
// Loop counting only literal (non-control) sequences
// paying special attention to ESC[<N>C which means forward <N>
//
do {
pos = re.lastIndex;
m = re.exec(s);
if(m) {
if(m.index > pos) {
len += s.slice(pos, m.index).length;
}
if('C' === m[3]) { // ESC[<N>C is forward/right
len += parseInt(m[2], 10) || 0; len += parseInt(m[2], 10) || 0;
} }
} }

View File

@ -1,7 +1,9 @@
/* jslint node: true */ /* jslint node: true */
'use strict'; 'use strict';
const renderStringLength = require('./string_util.js').renderStringLength; const {
ansiRenderStringLength,
} = require('./string_util');
// deps // deps
const assert = require('assert'); const assert = require('assert');
@ -28,7 +30,7 @@ function wordWrapText(text, options) {
//const REGEXP_GOBBLE = new RegExp(`.{0,${options.width}}`, 'g'); //const REGEXP_GOBBLE = new RegExp(`.{0,${options.width}}`, 'g');
// //
// For a given word, match 0->options.width chars -- alwasy include a full trailing ESC // For a given word, match 0->options.width chars -- always include a full trailing ESC
// sequence if present! // sequence if present!
// //
// :TODO: Need to create ansi.getMatchRegex or something - this is used all over // :TODO: Need to create ansi.getMatchRegex or something - this is used all over
@ -49,7 +51,7 @@ function wordWrapText(text, options) {
function appendWord() { function appendWord() {
word.match(REGEXP_GOBBLE).forEach( w => { word.match(REGEXP_GOBBLE).forEach( w => {
renderLen = renderStringLength(w); renderLen = ansiRenderStringLength(w);
if(result.renderLen[i] + renderLen > options.width) { if(result.renderLen[i] + renderLen > options.width) {
if(0 === i) { if(0 === i) {
@ -70,7 +72,7 @@ function wordWrapText(text, options) {
// //
// * Sublime Text 3 for example considers spaces after a word // * Sublime Text 3 for example considers spaces after a word
// part of said word. For example, "word " would be wraped // part of said word. For example, "word " would be wraped
// in it's entirity. // in it's entirety.
// //
// * Tabs in Sublime Text 3 are also treated as a word, so, e.g. // * Tabs in Sublime Text 3 are also treated as a word, so, e.g.
// "\t" may resolve to " " and must fit within the space. // "\t" may resolve to " " and must fit within the space.