Skip to content

Commit

Permalink
use monaco editor in terminal accessible buffer (#174400)
Browse files Browse the repository at this point in the history
  • Loading branch information
meganrogge authored Feb 16, 2023
1 parent 524f422 commit 855ba20
Show file tree
Hide file tree
Showing 12 changed files with 146 additions and 101 deletions.
4 changes: 2 additions & 2 deletions package.json
Original file line number Diff line number Diff line change
Expand Up @@ -87,13 +87,13 @@
"vscode-proxy-agent": "^0.12.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "8.0.0",
"xterm": "5.2.0-beta.28",
"xterm": "5.2.0-beta.29",
"xterm-addon-canvas": "0.4.0-beta.7",
"xterm-addon-search": "0.11.0",
"xterm-addon-serialize": "0.9.0",
"xterm-addon-unicode11": "0.5.0",
"xterm-addon-webgl": "0.15.0-beta.7",
"xterm-headless": "5.2.0-beta.28",
"xterm-headless": "5.2.0-beta.29",
"yauzl": "^2.9.2",
"yazl": "^2.4.3"
},
Expand Down
4 changes: 2 additions & 2 deletions remote/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -24,13 +24,13 @@
"vscode-proxy-agent": "^0.12.0",
"vscode-regexpp": "^3.1.0",
"vscode-textmate": "8.0.0",
"xterm": "5.2.0-beta.28",
"xterm": "5.2.0-beta.29",
"xterm-addon-canvas": "0.4.0-beta.7",
"xterm-addon-search": "0.11.0",
"xterm-addon-serialize": "0.9.0",
"xterm-addon-unicode11": "0.5.0",
"xterm-addon-webgl": "0.15.0-beta.7",
"xterm-headless": "5.2.0-beta.28",
"xterm-headless": "5.2.0-beta.29",
"yauzl": "^2.9.2",
"yazl": "^2.4.3"
},
Expand Down
2 changes: 1 addition & 1 deletion remote/web/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@
"tas-client-umd": "0.1.6",
"vscode-oniguruma": "1.7.0",
"vscode-textmate": "8.0.0",
"xterm": "5.2.0-beta.28",
"xterm": "5.2.0-beta.29",
"xterm-addon-canvas": "0.4.0-beta.7",
"xterm-addon-search": "0.11.0",
"xterm-addon-unicode11": "0.5.0",
Expand Down
8 changes: 4 additions & 4 deletions remote/web/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -88,7 +88,7 @@ xterm-addon-webgl@0.15.0-beta.7:
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.15.0-beta.7.tgz#ab247b499f61e8eebff92e08ec5ca999d87e06af"
integrity sha512-7WCI/D6uFNp3y9TeTsbSo1h7gCy4h/yP2lWn8ZEjCaiGvO11DbKMq17fbiwaR3YmGWXoRKkcLaNIiqxFnjKO4w==

xterm@5.2.0-beta.28:
version "5.2.0-beta.28"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.2.0-beta.28.tgz#852347e4eaf5aae7d82c90592a42adc9daab2a79"
integrity sha512-aLDxCuqjWHjvnhfWfkxy/y6coNrC+QIhbDe2sdfLPkrxhK6KnYE6qiZD5jXUIQXeq0KmSDcYi/esuKujvobC2A==
xterm@5.2.0-beta.29:
version "5.2.0-beta.29"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.2.0-beta.29.tgz#99764aff5cd8cdb4335f5d59466b134cfcb45e3e"
integrity sha512-zx5RKcQqo78bza4R/m3WtxAJCBAF4U61fy6cxqb1PkqXF9/qdYlySUCVOauMxv+6n6cAxt3EQWwLlgvbvQBbsw==
18 changes: 9 additions & 9 deletions remote/yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -866,15 +866,15 @@ xterm-addon-webgl@0.15.0-beta.7:
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.15.0-beta.7.tgz#ab247b499f61e8eebff92e08ec5ca999d87e06af"
integrity sha512-7WCI/D6uFNp3y9TeTsbSo1h7gCy4h/yP2lWn8ZEjCaiGvO11DbKMq17fbiwaR3YmGWXoRKkcLaNIiqxFnjKO4w==

xterm-headless@5.2.0-beta.28:
version "5.2.0-beta.28"
resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.2.0-beta.28.tgz#d2c149da51ef138f46268b755c4fdc4202eb771c"
integrity sha512-4XcjBhFwuyjpz2ubESwp75UceySOOKdJszKyyxOQ3/7L937uiVEBBLc8T231XU8lSwWUU7czyNjYyCfpszY4+Q==

xterm@5.2.0-beta.28:
version "5.2.0-beta.28"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.2.0-beta.28.tgz#852347e4eaf5aae7d82c90592a42adc9daab2a79"
integrity sha512-aLDxCuqjWHjvnhfWfkxy/y6coNrC+QIhbDe2sdfLPkrxhK6KnYE6qiZD5jXUIQXeq0KmSDcYi/esuKujvobC2A==
xterm-headless@5.2.0-beta.29:
version "5.2.0-beta.29"
resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.2.0-beta.29.tgz#dd08312fdb4292c217e685d9e2e8b1957364e298"
integrity sha512-1P4urIeDTkl2C+zGb4WUnKJMACZMPGYHwVXMjkB0WhMISbkt6M34MH9ljxHhnL99dHwlx2Lvi6wvhnpyZucWCg==

xterm@5.2.0-beta.29:
version "5.2.0-beta.29"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.2.0-beta.29.tgz#99764aff5cd8cdb4335f5d59466b134cfcb45e3e"
integrity sha512-zx5RKcQqo78bza4R/m3WtxAJCBAF4U61fy6cxqb1PkqXF9/qdYlySUCVOauMxv+6n6cAxt3EQWwLlgvbvQBbsw==

yallist@^4.0.0:
version "4.0.0"
Expand Down
3 changes: 1 addition & 2 deletions src/vs/platform/terminal/common/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -112,8 +112,7 @@ export const enum TerminalSettingId {
ShellIntegrationDecorationsEnabled = 'terminal.integrated.shellIntegration.decorationsEnabled',
ShellIntegrationCommandHistory = 'terminal.integrated.shellIntegration.history',
ShellIntegrationSuggestEnabled = 'terminal.integrated.shellIntegration.suggestEnabled',
SmoothScrolling = 'terminal.integrated.smoothScrolling',
AccessibleBufferContentEditable = 'terminal.integrated.accessibleBufferContentEditable'
SmoothScrolling = 'terminal.integrated.smoothScrolling'
}

export const enum TerminalLogConstants {
Expand Down
2 changes: 1 addition & 1 deletion src/vs/workbench/contrib/terminal/browser/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1053,7 +1053,7 @@ export interface IXtermTerminal {
/**
* Focuses the accessible buffer, updating its contents
*/
focusAccessibleBuffer(): void;
focusAccessibleBuffer(): Promise<void>;
}

export interface IInternalXtermTerminal {
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -423,7 +423,7 @@ export function registerTerminalActions() {
});
}
async run(accessor: ServicesAccessor): Promise<void> {
accessor.get(ITerminalService).activeInstance?.xterm?.focusAccessibleBuffer();
await accessor.get(ITerminalService).activeInstance?.xterm?.focusAccessibleBuffer();
}
});
registerAction2(class extends Action2 {
Expand Down
174 changes: 116 additions & 58 deletions src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -38,8 +38,16 @@ import { Emitter } from 'vs/base/common/event';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { SuggestAddon } from 'vs/workbench/contrib/terminal/browser/xterm/suggestAddon';
import { IContextKey } from 'vs/platform/contextkey/common/contextkey';
import { isLinux } from 'vs/base/common/platform';
import { IAccessibilityService } from 'vs/platform/accessibility/common/accessibility';
import { URI } from 'vs/base/common/uri';
import { ITextModel } from 'vs/editor/common/model';
import { IModelService } from 'vs/editor/common/services/model';
import { StringBuilder } from 'vs/editor/common/core/stringBuilder';
import { CodeEditorWidget, ICodeEditorWidgetOptions } from 'vs/editor/browser/widget/codeEditorWidget';
import { EditorExtensionsRegistry } from 'vs/editor/browser/editorExtensions';
import { getSimpleEditorOptions } from 'vs/workbench/contrib/codeEditor/browser/simpleEditorOptions';
import { IEditorConstructionOptions } from 'vs/editor/browser/config/editorConfiguration';
import { LinkDetector } from 'vs/editor/contrib/links/browser/links';
import { SelectionClipboardContributionID } from 'vs/workbench/contrib/codeEditor/browser/selectionClipboard';

const enum RenderConstants {
/**
Expand Down Expand Up @@ -281,7 +289,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
});
}

focusAccessibleBuffer(): void {
async focusAccessibleBuffer(): Promise<void> {
this._accessibileBuffer?.focus();
}

Expand Down Expand Up @@ -312,7 +320,7 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
if (!this._container) {
this.raw.open(container);
}
this._accessibileBuffer = this._instantiationService.createInstance(AccessibleBuffer, this.raw, this.getFont(), this._capabilities);
this._accessibileBuffer = this._instantiationService.createInstance(AccessibleBuffer, this, this._capabilities);
// TODO: Move before open to the DOM renderer doesn't initialize
if (this._shouldLoadWebgl()) {
this._enableWebglRenderer();
Expand Down Expand Up @@ -763,76 +771,126 @@ export class XtermTerminal extends DisposableStore implements IXtermTerminal, II
this.raw.write(data);
}
}

const enum ACCESSIBLE_BUFFER { Scheme = 'terminal-accessible-buffer' }
class AccessibleBuffer extends DisposableStore {

private _accessibleBuffer: HTMLElement | undefined;
private _bufferElementFragment: DocumentFragment | undefined;
private _accessibleBuffer: HTMLElement;
private _bufferEditor: CodeEditorWidget;
private _editorContainer: HTMLElement;
private _registered: boolean = false;
private _font: ITerminalFont;

constructor(
private readonly _terminal: RawXtermTerminal,
private readonly _font: ITerminalFont,
private readonly _terminal: XtermTerminal,
private readonly _capabilities: ITerminalCapabilityStore,
@IAccessibilityService private readonly _accessibilityService: IAccessibilityService,
@IConfigurationService private readonly _configurationService: IConfigurationService
@IInstantiationService private readonly _instantiationService: IInstantiationService,
@IModelService private readonly _modelService: IModelService,
@IConfigurationService configurationService: IConfigurationService
) {
super();
this.add(this._terminal.registerBufferElementProvider({ provideBufferElements: () => this.focus() }));
const codeEditorWidgetOptions: ICodeEditorWidgetOptions = {
isSimpleWidget: true,
contributions: EditorExtensionsRegistry.getSomeEditorContributions([LinkDetector.ID, SelectionClipboardContributionID])
};
this._font = this._terminal.getFont();
const editorOptions: IEditorConstructionOptions = {
...getSimpleEditorOptions(),
lineDecorationsWidth: 6,
dragAndDrop: true,
cursorWidth: 1,
fontSize: this._font.fontSize,
lineHeight: this._font.charHeight ? this._font.charHeight * this._font.lineHeight : 1,
fontFamily: this._font.fontFamily,
wrappingStrategy: 'advanced',
wrappingIndent: 'none',
padding: { top: 2, bottom: 2 },
quickSuggestions: false,
scrollbar: { alwaysConsumeMouseWheel: false },
renderWhitespace: 'none',
dropIntoEditor: { enabled: true },
accessibilitySupport: configurationService.getValue<'auto' | 'off' | 'on'>('editor.accessibilitySupport'),
cursorBlinking: configurationService.getValue('terminal.integrated.cursorBlinking'),
readOnly: true
};
this._accessibleBuffer = this._terminal.raw.element!.querySelector('.xterm-accessible-buffer') as HTMLElement;
this._editorContainer = document.createElement('div');
this._bufferEditor = this._instantiationService.createInstance(CodeEditorWidget, this._editorContainer, editorOptions, codeEditorWidgetOptions);
this.add(configurationService.onDidChangeConfiguration(e => {
if (e.affectedKeys.has(TerminalSettingId.FontFamily)) {
this._font = this._terminal.getFont();
}
}));
}

async focus(): Promise<void> {
await this._updateBufferEditor();
// Updates xterm's accessibleBufferActive property
// such that mouse events do not cause the terminal buffer
// to steal the focus
this._accessibleBuffer.focus();
this._bufferEditor.focus();
}

focus(): DocumentFragment {
if (!this._bufferElementFragment) {
this._bufferElementFragment = document.createDocumentFragment();
private async _updateBufferEditor(): Promise<void> {
if (!this._registered) {
// Registration is delayed until focus so the capability has time to have been added
this.add(this._terminal.raw.registerBufferElementProvider({ provideBufferElements: () => this._editorContainer }));
this._registered = true;
}
this._accessibleBuffer = this._terminal.element?.querySelector('.xterm-accessible-buffer') as HTMLElement || undefined;
if (!this._accessibleBuffer) {
return this._bufferElementFragment;
// When this is created, the element isn't yet attached so the dimensions are tiny
this._bufferEditor.layout({ width: this._accessibleBuffer.clientWidth, height: this._accessibleBuffer.clientHeight });
const commandDetection = this._capabilities.has(TerminalCapability.CommandDetection);
const fragment = commandDetection ? this._getShellIntegrationContent() : this._getAllContent();
const model = await this._getTextModel(URI.from({ scheme: ACCESSIBLE_BUFFER.Scheme, fragment }));
if (model) {
this._bufferEditor.setModel(model);
}
// see https://github.com/microsoft/vscode/issues/173532
const accessibleBufferContentEditable = isLinux ? 'on' : this._configurationService.getValue(TerminalSettingId.AccessibleBufferContentEditable);
this._accessibleBuffer.contentEditable = accessibleBufferContentEditable === 'on' || (accessibleBufferContentEditable === 'auto' && !this._accessibilityService.isScreenReaderOptimized()) ? 'true' : 'false';
// The viewport is undefined when this is focused, so we cannot get the cell height from that. Instead, estimate using the font.
const lineHeight = this._font?.charHeight ? this._font.charHeight * this._font.lineHeight + 'px' : '';
this._accessibleBuffer.style.lineHeight = lineHeight;
}

async _getTextModel(resource: URI): Promise<ITextModel | null> {
const existing = this._modelService.getModel(resource);
if (existing && !existing.isDisposed()) {
return existing;
}

return this._modelService.createModel(resource.fragment, null, resource, false);
}

private _getShellIntegrationContent(): string {
const commands = this._capabilities.get(TerminalCapability.CommandDetection)?.commands;
const sb = new StringBuilder(10000);
let content = localize('terminal.integrated.noContent', "No terminal content available for this session. Run some commands to create content.");
if (!commands?.length) {
const noContent = document.createElement('div');
const noContentLabel = localize('terminal.integrated.noContent', "No terminal content available for this session.");
noContent.textContent = noContentLabel;
this._bufferElementFragment.replaceChildren(noContent);
this._accessibleBuffer.focus();
return this._bufferElementFragment;
}
let header;
let replaceChildren = true;
return content;
}
for (const command of commands) {
header = document.createElement('h2');
// without this, the text area gets focused when keyboard shortcuts are used
header.tabIndex = -1;
header.textContent = command.command.replace(new RegExp(' ', 'g'), '\xA0');
sb.appendString(command.command.replace(new RegExp(' ', 'g'), '\xA0'));
if (command.exitCode !== 0) {
header.textContent += ` exited with code ${command.exitCode}`;
sb.appendString(` exited with code ${command.exitCode}`);
}
const output = document.createElement('div');
// without this, the text area gets focused when keyboard shortcuts are used
output.tabIndex = -1;
output.textContent = command.getOutput()?.replace(new RegExp(' ', 'g'), '\xA0') || '';
if (replaceChildren) {
this._bufferElementFragment.replaceChildren(header, output);
replaceChildren = false;
} else {
this._bufferElementFragment.appendChild(header);
this._bufferElementFragment.appendChild(output);
sb.appendString('\n');
sb.appendString(command.getOutput()?.replace(new RegExp(' ', 'g'), '\xA0') || '');
}
content = sb.build();
return content;
}

private _getAllContent(): string {
const lines: string[] = [];
let currentLine: string = '';
const buffer = this._terminal.raw.buffer.active;
const end = buffer.length;
for (let i = 0; i < end; i++) {
const line = buffer.getLine(i);
if (!line) {
continue;
}
const isWrapped = buffer.getLine(i + 1)?.isWrapped;
currentLine += line.translateToString(!isWrapped);
if (!isWrapped || i === end - 1) {
lines.push(currentLine.replace(new RegExp(' ', 'g'), '\xA0'));
currentLine = '';
}
}
this._accessibleBuffer.focus();
if (this._accessibleBuffer.contentEditable === 'true') {
document.execCommand('selectAll', false, undefined);
document.getSelection()?.collapseToEnd();
} else if (header) {
// focus the cursor line's header
header.tabIndex = 0;
}
return this._bufferElementFragment;
return lines.join('\n');
}
}
1 change: 0 additions & 1 deletion src/vs/workbench/contrib/terminal/common/terminal.ts
Original file line number Diff line number Diff line change
Expand Up @@ -253,7 +253,6 @@ export interface ITerminalConfiguration {
};
useWslProfiles: boolean;
altClickMovesCursor: boolean;
accessibleBufferContentEditable: 'auto' | 'on' | 'off';
macOptionIsMeta: boolean;
macOptionClickForcesSelection: boolean;
gpuAcceleration: 'auto' | 'on' | 'canvas' | 'off';
Expand Down
11 changes: 0 additions & 11 deletions src/vs/workbench/contrib/terminal/common/terminalConfiguration.ts
Original file line number Diff line number Diff line change
Expand Up @@ -579,17 +579,6 @@ const terminalConfiguration: IConfigurationNode = {
markdownDescription: localize('terminal.integrated.smoothScrolling', "Controls whether the terminal will scroll using an animation."),
type: 'boolean',
default: false
},
[TerminalSettingId.AccessibleBufferContentEditable]: {
markdownDescription: localize('terminal.integrated.accessibleBufferContentEditable', "Controls whether the accessible buffer is marks as a `contenteditable` element. This adds a text cursor to the buffer, allowing selection with the keyboard without a screen reader. Screen reader users will typically want to leave this as `auto` or `off` which will treat the buffer similar to a document. By default, on Linux, this will be set to `on` so that it works when using Orca."),
type: 'string',
enum: ['auto', 'on', 'off'],
enumDescriptions: [
localize('accessibleBufferContentEditable.auto', "Automatically enable when a screen reader is not detected."),
localize('accessibleBufferContentEditable.on', "Always on."),
localize('accessibleBufferContentEditable.off', "Always off.")
],
default: 'auto'
}
}
};
Expand Down
18 changes: 9 additions & 9 deletions yarn.lock
Original file line number Diff line number Diff line change
Expand Up @@ -11863,15 +11863,15 @@ xterm-addon-webgl@0.15.0-beta.7:
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.15.0-beta.7.tgz#ab247b499f61e8eebff92e08ec5ca999d87e06af"
integrity sha512-7WCI/D6uFNp3y9TeTsbSo1h7gCy4h/yP2lWn8ZEjCaiGvO11DbKMq17fbiwaR3YmGWXoRKkcLaNIiqxFnjKO4w==

xterm-headless@5.2.0-beta.28:
version "5.2.0-beta.28"
resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.2.0-beta.28.tgz#d2c149da51ef138f46268b755c4fdc4202eb771c"
integrity sha512-4XcjBhFwuyjpz2ubESwp75UceySOOKdJszKyyxOQ3/7L937uiVEBBLc8T231XU8lSwWUU7czyNjYyCfpszY4+Q==

xterm@5.2.0-beta.28:
version "5.2.0-beta.28"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.2.0-beta.28.tgz#852347e4eaf5aae7d82c90592a42adc9daab2a79"
integrity sha512-aLDxCuqjWHjvnhfWfkxy/y6coNrC+QIhbDe2sdfLPkrxhK6KnYE6qiZD5jXUIQXeq0KmSDcYi/esuKujvobC2A==
xterm-headless@5.2.0-beta.29:
version "5.2.0-beta.29"
resolved "https://registry.yarnpkg.com/xterm-headless/-/xterm-headless-5.2.0-beta.29.tgz#dd08312fdb4292c217e685d9e2e8b1957364e298"
integrity sha512-1P4urIeDTkl2C+zGb4WUnKJMACZMPGYHwVXMjkB0WhMISbkt6M34MH9ljxHhnL99dHwlx2Lvi6wvhnpyZucWCg==

xterm@5.2.0-beta.29:
version "5.2.0-beta.29"
resolved "https://registry.yarnpkg.com/xterm/-/xterm-5.2.0-beta.29.tgz#99764aff5cd8cdb4335f5d59466b134cfcb45e3e"
integrity sha512-zx5RKcQqo78bza4R/m3WtxAJCBAF4U61fy6cxqb1PkqXF9/qdYlySUCVOauMxv+6n6cAxt3EQWwLlgvbvQBbsw==

y18n@^3.2.1:
version "3.2.2"
Expand Down

6 comments on commit 855ba20

@rehmsen
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hi @meganrogge ,

I am importing VSCode 1.76.1 into Google and am trying to understand where xterm is going:

  • this commit adds a dependency on xterm.js 5.2.0beta29 - and uses a method Terminal.registerBufferElementProvider()
  • that same method was in the meanwhile removed again from xterm.js master in xtermjs/xterm.js@4037b94

Is the plan to remove this from VSCode again also, or is it coming back to xterm?

It would help me with my import to understand what I should expect.

Cheers
Ole

@meganrogge
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hey @rehmsen sorry for the confusion. We don't plan to have the buffer element provider in xterm.js anymore as it was just adding complexity unnecessarily. That dependency has since been removed in VS Code as well.

@rehmsen
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Thanks for the explanation. We are importing the monthly released versions (and any .1... minor releases as they happen), and would prefer not to import xterm at head (as other internal projects also depend on xterm and I am not sure how stable the beta releases are). What are the plans for making a new 5.2.0 version for xterm? Is there any chance you could release a version of xterm when you make a vscode release, so that only vscode head depends on beta xterm, while vscode stable versions depend on xterm stable versions? I am not exactly sure how xterm is governed and whether that would be feasible at all, but as a user I think it would be nice if I could rely on a stable vscode version to have stable dependencies (which seems to mostly be the case right now - only node-pty and some xterm addons are depending on beta as of 1.76.1).

@meganrogge
Copy link
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@Tyriar can probably better answer this

@Tyriar
Copy link
Member

@Tyriar Tyriar commented on 855ba20 Mar 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

@rehmsen we maintain xterm.js as well, the beta tag just means it's released off of the master branch. The only "stability" that is added from a stable release of xterm.js is that we review the issues assigned to the milestones and then release. Node pty is in the same camp.

I wouldn't think of xterm.js/node-pty "beta" as being unstable, but rather an extension of the VS Code codebase; whatever version VS Code points at is probably very stable once it's been in insiders for a day or 2 and is even more so when VS Code is actually released (the one you import) as it's gone through VS Code's testing process.

@Tyriar
Copy link
Member

@Tyriar Tyriar commented on 855ba20 Mar 13, 2023

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

We typically release xterm.js once every 1-3 months early in the month, because of the timing it's almost never aligned VS Code's release so almost every VS Code release has pointed at a "beta" xterm.js.

Please sign in to comment.