// note: ESM imports broken in xterm-headless - use a require instead. //import { Terminal } from 'xterm-headless'; // ^^^^^^^^ //SyntaxError: Named export 'Terminal' not found. The requested module 'xterm-headless' is a CommonJS module, which may not support all module.exports as named exports. const Terminal = require("xterm-headless").Terminal; async function write(term, str) { return new Promise((resolve, reject) => { term.write(str, resolve); }); } function dump_ascii(term, showCursor) { const rows = term.rows; const cols = term.cols; const buffer = term.buffer.active; const cursorX = buffer.cursorX; const cursorY = buffer.cursorY; console.log( `rows: ${rows}, cols: ${cols} cursorX: ${cursorX}, cursorY: ${cursorY}` ); console.log("+" + "-".repeat(cols) + "+"); for (let row = 0; row < rows; row++) { const line = buffer.getLine(row); let charCount = 0; let str = ""; for (let col = 0; col < cols; col++) { const cursorIsThisCell = row === cursorY && col === cursorX; const chars = line?.getCell(col)?.getChars() || " "; if (cursorIsThisCell && showCursor) { str += "@"; charCount++; } else { if (cursorIsThisCell) { // add invert colors str += "\x1b[7m"; } str += chars; charCount++; if (cursorIsThisCell) { // reset colors str += "\x1b[0m"; } } } console.log("|" + str + "|"); } console.log("+" + "-".repeat(cols) + "+"); } (async () => { const term = new Terminal({ rows: 5, cols: 5, allowProposedApi: true }); await write(term, "ABCD"); dump_ascii(term, true); // rows: 5, cols: 5 cursorX: 4, cursorY: 0 // +-----+ // |ABCD@| // | | // | | // | | // | | // +-----+ term.resize(4, 5); dump_ascii(term, true); // rows: 5, cols: 4 cursorX: 3, cursorY: 0 // +----+ // |ABC@| // NOTE: I believe we expect the cursor to have moved to row 2 // | | // Under the cursor, the 'D' still remains // | | // | | // | | // +----+ term.resize(3, 5); dump_ascii(term, true); // rows: 5, cols: 3 cursorX: 2, cursorY: 0 // +---+ // |AB@| // | | // | | // | | // | | // +---+ term.resize(5, 5); dump_ascii(term, true); // rows: 5, cols: 5 cursorX: 2, cursorY: 0 // +-----+ // |AB@ | // The 'D' is lost, and the 'C' remains under the cursor. // | | // | | // | | // | | // +-----+ })();