4.0.0
Finally v4 has arrived! This is our biggest release to date with 128 PRs being merged (v3 had 101). The major focuses for this version were:
- Shipping the new addon system, including an experimental version of the WebGL renderer addon
- Improving the build process and minifying the npm distributable
- Making the parser to be more compatible and extensible
- Chipping away at the new layered architecture and enabling TypeScript's strict mode
- Removing deprecated APIs
- Lots of bug fixes
The plan is for each new minor release to now state which addons are compatible with the library at the bottom, this might not be needed in the future but we'll evaluate that later on. We've also added a dedicated Addons section instead of mixing their updates in with the core library.
🚀 Features
New addon system
The new addon system that was introduced in 3.14.0 is now stable (#2377) via @Tyriar. This new system allows encapsulating additional functionality that leverages the xterm.js API into a module that can be shared between users of xterm.js. The API itself is extremely simple but improves over its previous incarnation with first-class TypeScript support and per-terminal lifecycle management.
export class Terminal implements IDisposable {
/**
* Loads an addon into this instance of xterm.js.
* @param addon The addon to load.
*/
loadAddon(addon: ITerminalAddon): void;
}
/**
* An addon that can provide additional functionality to the terminal.
*/
export interface ITerminalAddon extends IDisposable {
/**
* This is called when the addon is activated.
*/
activate(terminal: Terminal): void;
}
Creating an addon is as simple as providing an object with the activate
and dispose
methods available:
class ExampleAddon {
private _terminal: Terminal | undefined;
activate(terminal: Terminal): void {
this._terminal = terminal;
console.log('activated');
}
dispose(): void {
console.log('disposed');
}
}
And used like this:
const terminal = new Terminal();
terminal.loadAddon(new ExampleAddon());
// Logs 'activated'
terminal.dispose();
// Logs 'disposed'
Addons shipped by the xterm.js team are listed at the bottom of release notes and can be installed via npm.
📦 API
- New
wordSeparator
option that defines what a word boundary is when double click selecting (#2244, #2262) via @Maxris// Include ' and " in words const term = new Terminal({ wordSeparator: ' ()[]{}' });
- New
addEscHandler
,addDcsHandler
parser hook APIs and existingaddCsiHandler
andaddOscHandler
APIs have been refined (#2346) via @jerchSee the API documentation for more information.// Do something whenever the cursor move (CUP) sequence is triggered term.parser.addCsiHandler({ final: 'H' }, params => doSomething(params));
- New paste API that lets embedders pass data they want pasted directly to xterm.js (#2391) via @Tyriar. This is useful when paste isn't triggered in the typical fashion.
term.paste(await navigator.clipboard.readText());
🐞 Bug fixes
- Update rows after an ECH sequence, this was causing
cls
under ConPTY to not redraw rows sometimes (#2149) via @Tyriar - Correct API for
IBufferCell.getCell
to correctly indicate it can returnundefined
(#2184) via @Tyriar - Fix repeat preceding character sequence (REP) (#2199) via @jerch
- Fix saved cursor position of the normal screen buffer when a resize occurs on the alternate screen buffer (#2217) via @thekondr
- Added the
style
field to package.json so certain tools can locate the xterm.css file (#2221) via @blink1073 - Fix screen DPR change not trigger a canvas refresh which caused browser zoom to leave the terminal blank (#2228) via @Tyriar
- Lower
z-index
's of xterm components to avoid conflicts with embedder UIs (#2276) via @Tyriar - Guard against floats being used in integer-only APIs (#2277) via @Tyriar
- Reset wrapped line status when using
windowsMode
(#2278) via @Maxris - Fix issue where you could select half of a wide character (#2283) via @lramos15
- Fix edge cases in how we handle several sequences (#2288) via @jerch
- Don't handle the keyup event that is handled by a custom handler (#2294) via @Tyriar
- Rewrite mouse support from the ground up, improving compatibility and testing (#2321, #2323) via @jerch
- Announce characters to screen readers when typing and using backspace (#2329, #2343) via @Tyriar
- Make
dispose
do nothing when called a second time (#2353) via @Tyriar - Fix problems with scroll areas not working due to DECSTBM (#2355) via @jerch
- Fix exception when first click is a shift+click (#2366) via @Tyriar
- Fix cursor not changing correctly when open is called after entering mouse events mode (#2371) via @Tyriar
- Support bubbling scroll events to parent elements when no terminal scroll happens (#2388) via @ShahzadUmair
- Don't execute move to cell (alt+click) when the user has scrolled up (#2402) via @Tyriar
- Fine tune when to scroll to bottom and clear selection when the onData event is emitted (#2247) via @Tyriar
- Fix not rendering when switching from DOM to canvas renderer (#2378) via @Tyriar
- Show text when cursor blinks in DOM renderer (#2227) via @Tyriar
- Fix underline cursor style when blink is enabled in DOM renderer (#2374) via @Tyriar
- Support sequences using colon and mixed colon/semi-colon notation, improving true color compatibility (#2241) via @jerch
📝 Documentation and internal improvements
- Support absolute imports and minify the distributable (#2132, #2159, #2162, #2169, #2405, #2406) via @Tyriar
- Clean up dependencies (#2147) via @Tyriar
- Remove unneeded files from the packaged version of the library (#2153, #2160) via @Tyriar
- Moved the new addons from separate repos into the xtermjs/xterm.js repo (#2164, #2180, #2194, #2195, #2219, #2398, #2404) via @Tyriar
- Improving layering and moving to TS strict mode (#2168, #2171, #2183, #2203, #2205, #2206, #2207, #2208, #2209, #2210, #2211, #2214, #2216, #2229, #2231, #2237, #2238, #2239, #2245, #2246, #2247, #2279, #2287, #2289, #2302, #2303, #2304, #2309, #2310, #2311, #2315, #2348, #2381) via @Tyriar
- Add additional tests and misc test improvements (#2172, #2186, #2188, #2236, #2256, #2274, #2335, #2345, #2376) via @Tyriar
- Support running a specific text via CLI args (#2176) via @jerch
- Clean up parser code (#2177, #2187, #2392, #2397) via @jerch
- Integrate xterm-benchmark into the xtermjs/xterm.js repo to enable convenient performance testing (#2190) via @jerch
- Actioning security alerts for devDependencies (#2191, #2312, #2313, #2314, #2399, #2400) via @Tyriar, @dependabot
- Use
xterm-256color
in demo (#2198) via @jerch - Support dry run publishes and automate addon releases (#2232, #2233) via @Tyriar
- Fix typo in README (#2242) via @VivaLosDoyers
- Include new CSS file location in packaged version of the library (#2268) via @thekondr
- Leverage TypeScript's
declarationMap
compiler option (#2269) via @Tyriar - Enforce
_
prefix for protected members (#2273) via @Tyriar - Create helper script for evaluating mouse mode support (#2316) via @jerch
- Refine what we log in
logLevel
isdebug
(#2328, #2338) via @Tyriar
🛑 Breaking changes
node_modules/xterm/lib/xterm.css
has been moved tonode_modules/xterm/css/xterm.css
(#2132) via @Tyriarnode_modules/xterm/dist/xterm.js
no longer exists andnode_modules/xterm/lib/xterm.js
is now minified (#2132) via @Tyriar- Remove the deprecated old event API (#2029) via @Tyriar
// before 4.0.0 term.on('data', data => console.log(data)); // after 4.0.0 term.onData(data => console.log(data));
- Remove the deprecated destroy API (#2155) via @Tyriar
// before 4.0.0 term.destroy(); // after 4.0.0 term.dispose();
- Remove the deprecated
enableBold
option (#2156) via @Tyriar// before 4.0.0 term.setOption('enableBold', false); // after 4.0.0 term.setOption('fontWeightBold', 'normal');
- Remove the experimentalCharAtlas setting (#2157) via @Tyriar
// before 4.0.0 const term = new Terminal({ experimentalCharAtlas: 'static' }); // after 4.0.0 // No-op, the previous 'dynamic' is the only option available now due to // superior performance in every way.
- Remove the
blankLine
localized string, this improves how screen readers announce blank lines (#2284) via @Tyriar// before 4.0.0 Terminal.strings.blankLine = '<localized string>'; // after 4.0.0 // No-op
- The old
applyAddon
-based addon system has been removed (#2377) via @Tyriar. New addons are installed as separate packages via npm and enabled via the non-staticTerminal.loadAddon
, this improved the overall lifecycle of addons as well as fix issues with typings when working with TypeScript.// before 4.0.0 import { Terminal } from 'xterm'; import * as fit from 'xterm/lib/addons/fit/fit'; Terminal.applyAddon(fit); const terminal = new Terminal(); terminal.fit(); // after 4.0.0 import { Terminal } from 'xterm'; import { FitAddon } from 'xterm-addon-fit'; const terminal = new Terminal(); const fitAddon = new FitAddon(); terminal.loadAddon(fitAddon); fitAddon.fit();
⚠️ Deprecations
- We no longer explicitly support IE11, we expect the core functionality to still work but will not be going out of our way to fix optional features (#2216) via @Tyriar
🎉 New real-world use cases
📥 Addons
xterm-addon-search
- The search result is now centered in the viewport (#2281) via @lramos15
- Searches are now done from the bottom of the buffer for
findPrevious
and the top of the buffer forfindNext
(#2340) via @lramos15 - Don't scroll the terminal if the new search result is inside the current viewport (#2385) via @lramos15
- Added tests (#2344) via @lramos15
xterm-addon-serialize
- A work in progress addon for serializing and restoring the terminal buffer has been merged into the
feat/serialize-addon
branch (#2298) via @JavaCS3
xterm-addon-webgl
After a long time in PR the WebGL renderer has finally been moved to an addon that can be tried out using xterm.js v4 (#1790, #2235, #2285) via @Tyriar
The addon boasts significant performance improvements over the current canvas and DOM renderers but lacks some features and is still a little rough around the edges. Here are some numbers that were measured when the feature was in development (see #1790 for methodology):
Benchmark | Canvas/dynamic (avg ms/frame) | WebGL (avg ms/frame) | Change (c/w-1) |
---|---|---|---|
Macbook 87x26 | 4.80 | 0.69 | 596% faster |
Macbook 300x80 | 15.28 | 3.69 | 314% faster |
Windows 87x26 | 7.31 | 0.73 | 901% faster |
Windows 300x80 | 19.34 | 2.06 | 839% faster |
Macbook 87x26 CJK | 14.63 | 5.93 | 147% faster |
Macbook 87x26 Emoji | 27.47 | 19.28 | 42% faster |
See this query for a list of known issues with the WebGL renderer.