Releases: xtermjs/xterm.js
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
3.14.5
3.14.4
3.14.2
3.14.1
3.14.0
📢 Our next release will be v4, read more here 👉 #2143.
Compatible new addon versions:
🚀 Features
📦 API
For the complete details on the new APIs, see the typings file. For APIs marked experimental we're hoping to stabilize them in v4 and want feedback from the community to make sure they are useful.
- Support writing raw UTF-8 data directly, which may help avoid an unnecessary conversion to a relatively heavy JS string (#1904) via @jerch
const data = new Uint8Array([102, 111, 111]); term.writeUtf8(data);
- New experimental addon API (#2065, #2116) via @Tyriar
// A simple example addon const addon = { activate: (term: Terminal) => { console.log('addon activated'); }, dispose: () => { } } term.loadAddon(addon);
- New experimental buffer API (#2074) via @Tyriar. Consumers can finally query the textual state of the terminal.
// Print the line that the cursor is on as text term.buffer.getLine(term.buffer.cursorY).translateToString(true);
- New
select
andgetSelectionPosition
APIs (#2078) via @Tyriarterm.select(5, 2, 10); console.log(term.getSelectionPosition()); // {startColumn: 5, startRow: 2, endColumn: 15, endRow: 2}
🐞 Bug fixes
- Add missing typings for
windowsMode
option (#2062) via @Tyriar - Improve spacing between characters in DOM renderer (#2067) via @starpit
- Dispose of old data in the write buffer once it's been written if xterm.js hasn't caught up (#2120) via @jerch
- Fix wrong colors printing for 256 color mode (#2125) via @jerch
- Fix loss of data during a RIS (full reset) (#2127) via @jerch
- Only update the accessibiltiy announcements during an animation frame (#2128) via @Tyriar
- Fix a NPE in reflow (#2131) via @Tyriar
- Ensure underline is rendered correctly in canvas renderer (#2134) via @Tyriar
- Fix a font rendering issue where settings/colors wouldn't be picked up (#2140) via @Tyriar
- webLinks addon
📝 Documentation and internal improvements
- Update terminal dimensions after line height changes in demo (#2050) via @Tyriar
- Replace deprecated prepublish npm script (#2051) via @Tyriar
- Update year in README (#2053) via @Tyriar
- Minor clean up (#2056, #2073, #2101, #2133) via @Tyriar, @jerch
- Refine automated release system (#2057, #2061, #2113) via @Tyriar
- Improving code layering (#2059, #2066, #2092, #2094) via @Tyriar
- Introduce puppeteer-based integrated test system and tests (#2068, #2081, #2110, #2114, #2118, #2130) via @Tyriar
- Support
writeUtf8
in the demo (#2080) via @jerch - Fix coverage reporting (#2088) via @Tyriar
- Introduce a RenderCoordinator that shares common components previously duplicated in each renderer (#2096, #2100) via @Tyriar
- Use logo as favicon in demo (#2098) via @Tyriar
- Update TypeScript to 3.5 (#2141) via @Tyriar
3.13.2
3.13.1
3.13.0
🚀 Features
- True color support (#1895, #2034) via @jerch
- New UTF32 buffer layout (#1878, #2035) via @jerch, this reduces overall memory usage, makes true color possible and improves overall throughput.
- DOM Renderer
📦 API
- A new and improved event API has been introduced that properly types the arguments within the listener (#2008) via @Tyriar
- The new
windowsMode
option replaces the old winptyCompat addon (#1978, #1985, #1993) via @Tyriar, note that there are no longer the previous protections in place to prevent the mode from running on non-Windows operating systems. Terminal.markers
is now aReadonlyArray
(previously[]
) (#2036) via @Tyriar
🐞 Bug fixes
- Prevent unhandled sequence code from being hit incorrectly (#1923) via @jerch
- Fix UTF-8 mouse coordinate support (#1952) via @NickShaffner
- Don't open links when selecting text and releasing the mouse in the middle of the link (#1958) via @nikonso
- Don't do a full refresh when no needed after pausing and resuming rendering (#1976) via @Tyriar
- No longer scroll to the xterm.js text area when it's focused (#1982) via @Tyriar
- Fix the CSI scroll down handler (#1995) via @thekondr
- Properly send the
^_
sequence (emacs undo) (#2052) via @jflatow - search addon
- Fix skipping wrapped line results after resizing the terminal (#1866) via @ntchjb
- Fix find next/previous not selecting correct text after resizing the terminal (#2025) @thebradbain
- webLinks addon
📝 Documentation and internal improvements
- Open the browser automatically when the server is ready when debugging (#1968) via @nikonso
- Tweak rtty messaging (#1973) via @zhaojh329
- Recommend 127.0.0.1 over 0.0.0.0 on Linux and macOS to simplify documentation (#1987) via @Tyriar
- Fix backspace in the demo (#1997) via @Tyriar
- Better integration with VS Code
- Improving project structure
- Releases
🛑 Breaking changes
- The
winptyCompat
addon has been moved into core and is now enabled via thewindowsMode
option:See the API section for more information.// before 3.13.0 import winptyCompat = require('vscode-xterm/lib/addons/winptyCompat/winptyCompat'); Terminal.applyAddon(winptyCompat); const term = new Terminal(); // after 3.13.0 const term = new Terminal({ windowsMode: true });
⚠️ Deprecations
- The
on
,off
,emit
andaddDisposableListener
APIs are now deprecated and are planned to be removed in v4.0.0 (#2008) via @Tyriar, they are replaced with the new "explicit event API".We took this opportunity to slim down the events, cutting out some that we thought are no longer needed. If you are using any events that were not carried over to the new event API please create an issue and let us know how you're using it to see if we should expose it.// deprecated term.on('resize', e => doSomething(e)); // recommended term.onResize(e => doSomething(e));
🎉 New real-world use cases
- LxdMosaic (#1966) via @turtle0x1
- CodeInterview.io (#1999) via @asadm
- Bastillion (#2006) via @skavanagh
- PHP App Server (#2043) via @cubiclesoft
A special thanks to @Eugeny of the Terminus project for trialing the beta release and helping catch some nasty bugs before we released ❤️