Custom addons
See original GitHub issueHello all!
I’m trying to create a new addon and the documentation doesn’t seem to be terribly clear on what it takes to go from 0-60.
For example, 1) exactly how does the API for add-ons differ from the nominal Terminal API? Does it at all? Will it?* Additionally, 2) is directly modifying Terminals’ prototype the most appropriate way for add-ons to register functionality? It seems to be just asking for collisions. Is there any other namespace registration or dic facility? (I suppose maybe even just adding the addon object eg Terminal.MyAddon.method() for the simplest way, but surely Terminal.addon(‘MyAddon’).method() is much more sound). 3) Also, it doesn’t seem to be clear how to actually add a third party addon, as the names have all been hardcoded… (I have taken to extending Terminal and widening loadAddon (static loadAddon(String): void;
)) I am making assumptions, since the docs don’t say if loadAddon is only for private (non 3rd party) use.
I have reviewed some of the existing add-ons, but they don’t seem to have the most consistent implementations.
*I’m creating a couple add-ons (at least one for custom escape codes) because I wish to add discrete functionality to xTerm.js. It seems far more architecturally sound to do that instead of just making a big abstraction layer on top of xTerm.
Details
- tsc.exe version: 2.6.1
- xterm.js version: 3
Issue Analytics
- State:
- Created 6 years ago
- Comments:39 (33 by maintainers)
Top GitHub Comments
Find below a proposal for proper addons that I wrote up while in the air ✈️ 😄. Any feedback would be greatly appreciated as if go ahead and make mistakes they’ll be hard to change.
/cc @xtermjs/core @jerch @vincentwoo @chabou @amejia1 @jluk
Better Addons Proposal
xterm.js addons are components that use the xterm.js API to provide additional functionality. They follow a particular structure to make developing an addon convenient.
The difference between writing functionality in an addon and just using the API is that the Terminal is aware of addons and can provides additional hooks/functionality that you don’t normally get when just programming against the API. It’s also easy to develop and share your work in a consistent way with the community.
While it’s certainly possible to write addons in JavaScript, TypeScript is encouraged due to the additional compiler type checks and first-class TS support in the core library.
Versioning
Since xterm.js is a living project and breakages do occur (on major versions), there’s a chance an addon could break.
Loading addons
Instead of what was done previously, registering addons in the static
Terminal.applyAddon
function, addons are now passed intoTerminal
in the constructor as an optional 2nd argument:This allows different terminals to have a different set of addons and provides a convenient way to load the addons for each of them. Also note that the
typeof
anITerminalAddon
is providedxterm-base npm module
This module contains declaration files that define the interface of an addon. The only reason this module exists is so addons do not need to depend on the
xterm
module (and create a circular dependency).This can be published to npm in a similar way that the vscode API is published, the source of truth remains in the xterm.js repo (and is referenced directly by xterm.js repo), but is published as a separate module for addons to consume.
Interfaces
Addons define a constructor which is triggered during
Terminal
’s constructor, other hooks should be added usingTerminal.on
.To actually call functions on the addon you need to acquire the addon instance of a terminal. This can be done by leveraging the relatively complex
Terminal.getAddon
which takes an addon constructor and returns the addon instance. The internals ofgetAddon
should be easy to implement:The current “bundled” addons
Bundled addons will each move to the following repos and have published npm modules:
This will have many benefits like:
Moving these into their own repos should also encourage us to open up the API so these core addons are no longer leveraging private API that could break. This would also be a good opportunity to add an API test suite which is a set of tests which use only the public API.
Thoughts
"engines": { "xterm": "..." }
in package.json? We probably can’t pull this out in a nice way without enforcing how things are built.New model is much simpler:
This lets the embedder construct the addon however they wish, and we do away with the complexity of the ctor system and the additional methods. If someone wants to keep a reference around just hold on to the addon after you register:
I’m leaning towards not exposing a bunch of events on the addons themselves but instead allow addons to register their own events during the activate event. The addon author may need to check the state of the terminal before doing it’s thing is all: