Merge pull request #5502 from Tyriar/xtversion

Support reporting XTVERSION
This commit is contained in:
Daniel Imms
2025-12-26 11:13:53 -08:00
committed by GitHub
4 changed files with 63 additions and 2 deletions
+14 -2
View File
@@ -30,7 +30,7 @@ const changedFiles = getChangedFilesInCommit('HEAD');
// Always publish xterm, technically this isn't needed if
// `changedFiles.some(e => e.search(/^addons\//)`, but it's here for convenience to get the right
// peer dependencies for addons.
const result = checkAndPublishPackage(path.resolve(__dirname, '..'), repoCommit);
const result = checkAndPublishPackage(path.resolve(__dirname, '..'), repoCommit, undefined, true);
const isStableRelease = result.isStableRelease;
const peerDependencies = result.nextVersion.includes('beta') ? {
'@xterm/xterm': `^${result.nextVersion}`,
@@ -67,7 +67,7 @@ if (isStableRelease) {
updateWebsite();
}
function checkAndPublishPackage(packageDir, repoCommit, peerDependencies) {
function checkAndPublishPackage(packageDir, repoCommit, peerDependencies, updateVersionTs = false) {
const packageJson = require(path.join(packageDir, 'package.json'));
// Determine if this is a stable or beta release
@@ -78,6 +78,18 @@ function checkAndPublishPackage(packageDir, repoCommit, peerDependencies) {
let nextVersion = isStableRelease ? packageJson.version : getNextBetaVersion(packageJson);
log(`Publishing version: ${nextVersion}`, 'green');
// Update Version.ts with the new version
if (updateVersionTs) {
const versionTsPath = path.join(packageDir, 'src/common/Version.ts');
const versionTsContent = fs.readFileSync(versionTsPath, 'utf8');
const updatedVersionTs = versionTsContent.replace(
/export const XTERM_VERSION = '[^']+';/,
`export const XTERM_VERSION = '${nextVersion}';`
);
fs.writeFileSync(versionTsPath, updatedVersionTs);
log(`Updated ${versionTsPath} to version ${nextVersion}`);
}
// Set the version in package.json
const packageJsonFile = path.join(packageDir, 'package.json');
packageJson.version = nextVersion;
+22
View File
@@ -1582,6 +1582,28 @@ describe('InputHandler', () => {
assert.equal(bufferService.cols, 132);
});
});
describe('XTVERSION (CSI > q, CSI > 0 q)', () => {
it('should report xterm.js version', async () => {
const stack: string[] = [];
coreService.onData(data => stack.push(data));
await inputHandler.parseP('\x1b[>q');
assert.strictEqual(stack.length, 1);
assert.ok(stack[0].match(/^\x1bP>\|xterm\.js\(\d+\.\d+\.\d+(-beta\.\d+)?\)\x1b\\/));
});
it('should report xterm.js version for CSI > 0 q', async () => {
const stack: string[] = [];
coreService.onData(data => stack.push(data));
await inputHandler.parseP('\x1b[>0q');
assert.strictEqual(stack.length, 1);
assert.ok(stack[0].match(/^\x1bP>\|xterm\.js\(\d+\.\d+\.\d+(-beta\.\d+)?\)\x1b\\/));
});
it('should not report for CSI > 1 q', async () => {
const stack: string[] = [];
coreService.onData(data => stack.push(data));
await inputHandler.parseP('\x1b[>1q');
assert.strictEqual(stack.length, 0);
});
});
describe('should correctly reset cells taken by wide chars', () => {
beforeEach(async () => {
bufferService.resize(10, 5);
+18
View File
@@ -22,6 +22,7 @@ import { DcsHandler } from 'common/parser/DcsParser';
import { IBuffer } from 'common/buffer/Types';
import { parseColor } from 'common/input/XParseColor';
import { Emitter } from 'vs/base/common/event';
import { XTERM_VERSION } from 'common/Version';
/**
* Map collect to glevel. Used in `selectCharset`.
@@ -256,6 +257,7 @@ export class InputHandler extends Disposable implements IInputHandler {
this._parser.registerCsiHandler({ final: 'n' }, params => this.deviceStatus(params));
this._parser.registerCsiHandler({ prefix: '?', final: 'n' }, params => this.deviceStatusPrivate(params));
this._parser.registerCsiHandler({ intermediates: '!', final: 'p' }, params => this.softReset(params));
this._parser.registerCsiHandler({ prefix: '>', final: 'q' }, params => this.sendXtVersion(params));
this._parser.registerCsiHandler({ intermediates: ' ', final: 'q' }, params => this.setCursorStyle(params));
this._parser.registerCsiHandler({ final: 'r' }, params => this.setScrollRegion(params));
this._parser.registerCsiHandler({ final: 's' }, params => this.saveCursor(params));
@@ -1721,6 +1723,22 @@ export class InputHandler extends Disposable implements IInputHandler {
return true;
}
/**
* CSI > Ps q
* Ps = 0 => Report xterm name and version (XTVERSION).
*
* The response is a DCS sequence identifying the version: DCS > | text ST
*
* @vt: #Y CSI XTVERSION "Report Xterm Version" "CSI > q" "Report the terminal name and version."
*/
public sendXtVersion(params: IParams): boolean {
if (params.params[0] > 0) {
return true;
}
this._coreService.triggerDataEvent(`${C0.ESC}P>|xterm.js(${XTERM_VERSION})${C0.ESC}\\`);
return true;
}
/**
* Evaluate if the current terminal is the given argument.
* @param term The terminal name to evaluate
+9
View File
@@ -0,0 +1,9 @@
/**
* Copyright (c) 2025 The xterm.js authors. All rights reserved.
* @license MIT
*/
/**
* The xterm.js version. This is updated by the publish script from package.json.
*/
export const XTERM_VERSION = '6.0.0';