The xterm.js team is happy to push out our biggest release yet!
As well as a bunch of features, this release is a major bump and we're using this as an opportunity to clean up APIs and debt items that can cause breaking changes, so many sure you review the ⚠️ Breaking changes section if you're upgrading from version 2.
🆕 Features
New Canvas-based Rendering Engine
The rendering code has been completely re-written, moving from DOM-based rendering to canvas-based. Various tricks are used to boost performance significantly, When benchmarked there was a 5 to 45 times improvement depending on the situation.
You can read more about these changes on the Visual Studio Code blog.
Themes
Since xterm.js now renders everything in a canvas, it needs to know what the colors for everything are. As such there is now a theme API which can be set just like any other option:
var term = new Terminal({
theme: {
background: '#000'
}
});
// or
term.setOption('theme', {
background: '#FFF'
});
Refer to the xterm.d.ts
file for an overview of the keys that can be set.
Bell support
The terminal bell can now be enabled:
var term = new Terminal({
bellStyle: 'sound'
});
// or
term.setOption('bellStyle', 'sound');
You can also set it to a custom sound using a data URI:
var term = new Terminal({
bellSound: 'data:audio/wav;base64,...'
});
This was a community contribution from @npezza93 ❤️, visual bell support was also added but this broke during the rendering changes. Hopefully it shall return soon 😃
Proper TypeScript typings
Previously we shipped typings that were generated by TypeScript itself. These exported absolutely everything, including unstable private APIs which you should not depend on. As of this release we now ship handwritten TypeScript typings that export only the public API. This should make working with xterm.js a much more pleasant experience in an editor that supports typings.
Other features
- #869: Regular selection can be forced using the shift key on Windows/Linux, this is useful when a program such as
tmux
is intercepting mouse events - #1044: Letter spacing is now supported
- #1048: Bold can now be disabled via the
enableBold
option - #1097: Bracketed paste mode is now supported
- #1043: Dim/faint characters are now supported
🆕 API
- #878: New option
bellStyle
can set the terminal's bell style, valid values:'sound'
|'none'
- #878: New option
bellSound
can set the bell sound whenbellStyle
is'sound'
- #1044: New option
letterSpacing
- #1048: New option
enableBold
- #1093: A
selection
event is now omitted when the user makes a selection - #1095: There is a new addon
winptyCompat
which attempts to get wraparoundMode working when winpty is running the shell
🪲 Bug fixes
- #475: Fixed issue where spaces could appear in between rows
- #654: Links that have different text styles throughout are now parsed correctly
- #681: Fixed problem where focus/blur state could be incorrect
- #730 Bold character width is now enforced to be the same as non-bold width
- #759: Reverse color mode now works correctly when using a light theme
- #802: The alternate screen buffer now always has 0 scrollback as per the spec
- #847: Buffer size is now defined as the number of rows + scrollback like most other terminals, previously it was just scrollback
- #848: Scrolling in tmux when the document has a scroll bar will no longer scroll the page as well
- #851: Fixed a crash that could occur when setting a negative tab stop
- #893: Fixed an exception when switching to the alt buffer before
Terminal.open
is called - #911: A negative scrollback value is now prevented
- #913:
mousedown
event now continues propagation when the terminal has selection and a right click, allowing the context menu to be canceled - #919, #920: Fixed several exceptions related to managing the terminal lines in the DOM
- #930: Fixed tab stops in the alt buffer
- #936: Actual FG and BG colors are now used when inverting text
- #937: Characters should now be laid out on a pixel perfect grid
- #935: Sub-pixel anti-aliasing should now always work as well, previously it was somewhat flaky
- #947: Fixed
CSI Ps M
to delete the correct line - #948 via @nikonso: Scrollback now has an upperbound of
2^32 - 1
- #978: Auto scrolling while the user is scrolled up will now stay put unless the viewport reaches the end of the buffer
- #959: Link underlines should now clear on scroll
- #960: Only the link from the current line will update when typing
- #986: Fixed an exception when dragging below the viewport
- #1025: Fixed issue where links would sometimes not be applied
- #1110: Delete chars escape sequence now refreshes the line
📝 Documentation and internal improvements
- #335, #862, #1130: All remaining JavaScript has been converted to TypeScript
- #1068: CSS is now more general, using
.xterm
over.terminal
- #850 via @peterbaumgarten: Mark that a C++ compiler is required to build
- We have a new logo, source files are located at https://github.com/xtermjs/xtermjs-branding
🎉 New real-world use cases
- Proxmox VE #1149 via @flumm
- Theia #956 via @marcdumais-work
- vterm #888 via @lucat1
- Whack Whack Terminal #886 via @dgriffen
- script-runner #879 via @ioquatix
⚠️ Breaking changes
As always make sure you pull in the latest changes from xterm.css if you have forked it, the file size has reduced significantly due to theme/color information moving from CSS to JS.
-
#406: We no longer ship xterm.js to Bower
-
#646:
Terminal.open
no longer accepts the secondfocus
argument, callTerminal.focus
instead:// v2 term.open(element, true); // v3 term.open(element); term.focus();
-
#744:
attachCustomKeydownHandler
has been removed, useattachCustomKeyEventHandler
instead:// v2 term.attachCustomKeydownHandler(f); // v3 term.attachCustomKeyEventHandler(f);
-
#841:
geometry
has been removed as an option in theTerminal
constructor, usecols
androws
instead:// v2 var term = new Terminal({geometry: [10, 5]}); // v3 var term = new Terminal({ cols: 10, rows: 5 });
-
#902:
scrollDisp
has been renamed toscrollLines
:// v2 term.scrollDisp(1); // v3 term.scrollLines(1);
-
#901: The
open
event has been removed, put your code immediately after the call toTerminal.open
instead:// v2 term.on('open', f); term.open(element); // v3 term.open(element); f();
-
#903: The
refresh
event no longer gives theelement
in its data object, use theTerminal
object instead:// v2 term.on('refresh', e => console.log(e.element)); // v3 term.on('refresh', () => console.log(term.element));
-
#903: The
resize
event no longer gives theterminal
in its data object, use theTerminal
object instead:// v2 term.on('resize', e => console.log(e.terminal)); // v3 term.on('resize', () => console.log(term));
-
#1159: The
lineFeed
event has been renamed tolinefeed
:// v2 term.on('lineFeed', () => {}); // v3 term.on('linefeed', () => {});
❤️ Thanks
A special thanks to everyone who helped put this release together including the core team (myself, @parisk, @mofux), contributors who created PRs (@peterbaumgarten, @npezza93, @dgriffen, @lucat1, @dcylabs, @marcdumais-work, @ricktbaker, @jgillich, @jdanbrown, @martin31821, @nikonso, @flumm) and everyone who participated in reporting and discussing issues!