diff --git a/core/ansi_escape_parser.js b/core/ansi_escape_parser.js index 974399c8..44eccfbd 100644 --- a/core/ansi_escape_parser.js +++ b/core/ansi_escape_parser.js @@ -28,7 +28,7 @@ function ANSIEscapeParser(options) { this.graphicRendition = {}; this.parseState = { - re: /(?:\x1b)(?:(?:\x5b([?=;0-9]*?)([ABCDEFGfHJLmMsSTuUYZ]))|([78DEHM]))/g, // eslint-disable-line no-control-regex + re: /(?:\x1b)(?:(?:\x5b([?=;0-9]*?)([ABCDEFGfHJKLmMsSTuUYZ]))|([78DEHM]))/g, // eslint-disable-line no-control-regex }; options = miscUtil.valueWithDefault(options, { @@ -280,7 +280,7 @@ function ANSIEscapeParser(options) { self.parseState = { // ignore anything past EOF marker, if any buffer: input.split(String.fromCharCode(0x1a), 1)[0], - re: /(?:\x1b)(?:(?:\x5b([?=;0-9]*?)([ABCDEFGfHJLmMsSTuUYZ]))|([78DEHM]))/g, // eslint-disable-line no-control-regex + re: /(?:\x1b)(?:(?:\x5b([?=;0-9]*?)([ABCDEFGfHJKLmMsSTuUYZ]))|([78DEHM]))/g, // eslint-disable-line no-control-regex stop: false, }; }; @@ -471,12 +471,30 @@ function ANSIEscapeParser(options) { // erase display/screen case 'J': - // :TODO: Handle other 'J' types! - if (2 === args[0]) { + if(isNaN(args[0]) || 0 === args[0]) { + self.emit('erase rows', self.row, self.termHeight); + } + else if (1 === args[0]) { + self.emit('erase rows', 1, self.row); + } + else if (2 === args[0]) { self.clearScreen(); } break; + // erase text in line + case 'K': + if(isNaN(args[0]) || 0 === args[0]) { + self.emit('erase columns', self.row, self.column, self.termWidth); + } + else if (1 === args[0]) { + self.emit('erase columns', self.row, 1, self.column); + } + else if (2 === args[0]) { + self.emit('erase columns', self.row, 1, self.termWidth); + } + break; + // insert line case 'L': arg = isNaN(args[0]) ? 1 : args[0]; diff --git a/core/art.js b/core/art.js index 114800ee..61471a47 100644 --- a/core/art.js +++ b/core/art.js @@ -316,6 +316,35 @@ function display(client, art, options, cb) { } }); + // Remove any MCI's that are in erased rows + ansiParser.on('erase row', (startRow, endRow) => { + _.forEach(mciMap, (mciInfo, mapKey) => { + if (mciInfo.position[0] >= startRow && mciInfo.position[0] <= endRow) { + delete mciMap[mapKey]; + } + }); + }); + + // Remove any MCI's that are in erased columns + ansiParser.on('erase columns', (row, startCol, endCol) => { + _.forEach(mciMap, (mciInfo, mapKey) => { + if ( + mciInfo.position[0] === row && + mciInfo.position[1] >= startCol && + mciInfo.position[1] <= endCol + ) { + delete mciMap[mapKey]; + } + }); + }); + + // Clear the screen, removing any MCI's + ansiParser.on('clear screen', () => { + _.forEach(mciMap, (mciInfo, mapKey) => { + delete mciMap[mapKey]; + }); + }); + ansiParser.on('scroll', (scrollY) => { _.forEach(mciMap, (mciInfo) => { mciInfo.position[0] -= scrollY;