diff --git a/src/public/Terminal.ts b/src/public/Terminal.ts index 673e56f0c..f19c8ce31 100644 --- a/src/public/Terminal.ts +++ b/src/public/Terminal.ts @@ -3,7 +3,7 @@ * @license MIT */ -import { Terminal as ITerminalApi, ITerminalOptions, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings, ITerminalAddon, ISelectionPosition, IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi, Parser } from 'xterm'; +import { Terminal as ITerminalApi, ITerminalOptions, IMarker, IDisposable, ILinkMatcherOptions, ITheme, ILocalizableStrings, ITerminalAddon, ISelectionPosition, IBuffer as IBufferApi, IBufferLine as IBufferLineApi, IBufferCell as IBufferCellApi, IParser, IFunctionIdentifier } from 'xterm'; import { ITerminal } from '../Types'; import { IBufferLine } from 'common/Types'; import { IBuffer } from 'common/buffer/Types'; @@ -11,17 +11,17 @@ import { Terminal as TerminalCore } from '../Terminal'; import * as Strings from '../browser/LocalizableStrings'; import { IEvent } from 'common/EventEmitter'; import { AddonManager } from './AddonManager'; -import { IParams, IEscapeSequenceParser } from 'common/parser/Types'; -import { OscHandler } from 'common/parser/OscParser'; -import { DcsHandler } from 'common/parser/DcsParser'; +import { IParams } from 'common/parser/Types'; export class Terminal implements ITerminalApi { private _core: ITerminal; private _addonManager: AddonManager; + private _parser: IParser; constructor(options?: ITerminalOptions) { this._core = new TerminalCore(options); this._addonManager = new AddonManager(); + this._parser = new ParserApi(this._core); } public get onCursorMove(): IEvent { return this._core.onCursorMove; } @@ -35,7 +35,7 @@ export class Terminal implements ITerminalApi { public get onResize(): IEvent<{ cols: number, rows: number }> { return this._core.onResize; } public get element(): HTMLElement { return this._core.element; } - public get parser(): Parser.IParser { return new ParserApi((this._core as any)._inputHandler._parser); } + public get parser(): IParser { return this._parser; } public get textarea(): HTMLTextAreaElement { return this._core.textarea; } public get rows(): number { return this._core.rows; } public get cols(): number { return this._core.cols; } @@ -218,19 +218,19 @@ class BufferCellApiView implements IBufferCellApi { public get width(): number { return this._line.getWidth(this._x); } } -class ParserApi implements Parser.IParser { - constructor(private _parser: IEscapeSequenceParser) {} +class ParserApi implements IParser { + constructor(private _core: ITerminal) {} - public addCsiHandler(id: Parser.IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean): IDisposable { - return this._parser.addCsiHandler(id, (params: IParams) => callback(params.toArray())); + public addCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean): IDisposable { + return this._core.addCsiHandler(id, (params: IParams) => callback(params.toArray())); } - public addDcsHandler(id: Parser.IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean): IDisposable { - return this._parser.addDcsHandler(id, new DcsHandler((data: string, params: IParams) => callback(data, params.toArray()))); + public addDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean): IDisposable { + return this._core.addDcsHandler(id, (data: string, params: IParams) => callback(data, params.toArray())); } - public addEscHandler(id: Parser.IFunctionIdentifier, handler: () => boolean): IDisposable { - return this._parser.addEscHandler(id, handler); + public addEscHandler(id: IFunctionIdentifier, handler: () => boolean): IDisposable { + return this._core.addEscHandler(id, handler); } public addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable { - return this._parser.addOscHandler(ident, new OscHandler(callback)); + return this._core.addOscHandler(ident, callback); } } diff --git a/typings/xterm.d.ts b/typings/xterm.d.ts index de767f598..1ba4be1f4 100644 --- a/typings/xterm.d.ts +++ b/typings/xterm.d.ts @@ -207,47 +207,47 @@ declare module 'xterm' { */ export interface ITheme { /** The default foreground color */ - foreground?: string, + foreground?: string; /** The default background color */ - background?: string, + background?: string; /** The cursor color */ - cursor?: string, + cursor?: string; /** The accent color of the cursor (fg color for a block cursor) */ - cursorAccent?: string, + cursorAccent?: string; /** The selection background color (can be transparent) */ - selection?: string, + selection?: string; /** ANSI black (eg. `\x1b[30m`) */ - black?: string, + black?: string; /** ANSI red (eg. `\x1b[31m`) */ - red?: string, + red?: string; /** ANSI green (eg. `\x1b[32m`) */ - green?: string, + green?: string; /** ANSI yellow (eg. `\x1b[33m`) */ - yellow?: string, + yellow?: string; /** ANSI blue (eg. `\x1b[34m`) */ - blue?: string, + blue?: string; /** ANSI magenta (eg. `\x1b[35m`) */ - magenta?: string, + magenta?: string; /** ANSI cyan (eg. `\x1b[36m`) */ - cyan?: string, + cyan?: string; /** ANSI white (eg. `\x1b[37m`) */ - white?: string, + white?: string; /** ANSI bright black (eg. `\x1b[1;30m`) */ - brightBlack?: string, + brightBlack?: string; /** ANSI bright red (eg. `\x1b[1;31m`) */ - brightRed?: string, + brightRed?: string; /** ANSI bright green (eg. `\x1b[1;32m`) */ - brightGreen?: string, + brightGreen?: string; /** ANSI bright yellow (eg. `\x1b[1;33m`) */ - brightYellow?: string, + brightYellow?: string; /** ANSI bright blue (eg. `\x1b[1;34m`) */ - brightBlue?: string, + brightBlue?: string; /** ANSI bright magenta (eg. `\x1b[1;35m`) */ - brightMagenta?: string, + brightMagenta?: string; /** ANSI bright cyan (eg. `\x1b[1;36m`) */ - brightCyan?: string, + brightCyan?: string; /** ANSI bright white (eg. `\x1b[1;37m`) */ - brightWhite?: string + brightWhite?: string; } /** @@ -778,7 +778,7 @@ declare module 'xterm' { /** * Perform a full reset (RIS, aka '\x1bc'). */ - reset(): void + reset(): void; /** * Applies an addon to the Terminal prototype, making it available to all @@ -927,120 +927,114 @@ declare module 'xterm' { } /** - * Parser namespace, contains all parser related bits. + * Data type to register a CSI, DCS or ESC callback in the parser in the form: + * ESC I..I F + * CSI Prefix P..P I..I F + * DCS Prefix P..P I..I F data_bytes ST + * + * with these rules/restrictions: + * - prefix can only be used with CSI and DCS + * - only one leading prefix byte is recognized by the parser + * before any other parameter bytes (P..P) + * - intermediate bytes are recognized up to 2 + * + * For custom sequences make sure to read ECMA-48 and the resources at + * vt100.net to not clash with existing sequences or reserved address space. + * General recommendations: + * - use private address space (see ECMA-48) + * - use max one intermediate byte (technically not limited by the spec, + * in practice there are no sequences with more than one intermediate byte, + * thus parsers might get confused with more intermediates) + * - test against other common emulators to check whether they escape/ignore + * the sequence correctly + * + * Notes: OSC command registration is handled differently (see addOscHandler) + * APC, PM or SOS is currently not supported. */ - export namespace Parser { + export interface IFunctionIdentifier { + /** + * Optional prefix byte, must be in range \x3c .. \x3f. + * Usable in CSI and DCS. + */ + prefix?: string; + /** + * Optional intermediate bytes, must be in range \x20 .. \x2f. + * Usable in CSI, DCS and ESC. + */ + intermediates?: string; + /** + * Final byte, must be in range \x40 .. \x7e for CSI and DCS, + * \x30 .. \x7e for ESC. + */ + final: string; + } + + /** + * Parser interface. + */ + export interface IParser { + /** + * Adds a handler for CSI escape sequences. + * @param id Specifies the function identifier under which the callback + * gets registered, e.g. {final: 'm'} for SGR. + * @param callback The function to handle the sequence. The callback is + * called with the numerical params. If the sequence has subparams the + * array will contain subarrays with their numercial values. + * Return true if the sequence was handled; false if we should try + * a previous handler (set by addCsiHandler or setCsiHandler). + * The most recently-added handler is tried first. + * @return An IDisposable you can call to remove this handler. + */ + addCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean): IDisposable; /** - * Data type to register a CSI, DCS or ESC callback in the parser in the form: - * ESC I..I F - * CSI Prefix P..P I..I F - * DCS Prefix P..P I..I F data_bytes ST - * - * with these rules/restrictions: - * - prefix can only be used with CSI and DCS - * - only one leading prefix byte is recognized by the parser - * before any other parameter bytes (P..P) - * - intermediate bytes are recognized up to 2 - * - * For custom sequences make sure to read ECMA-48 and the resources at - * vt100.net to not clash with existing sequences or reserved address space. - * General recommendations: - * - use private address space (see ECMA-48) - * - use max one intermediate byte (technically not limited by the spec, - * in practice there are no sequences with more than one intermediate byte, - * thus parsers might get confused with more intermediates) - * - test against other common emulators to check whether they escape/ignore - * the sequence correctly - * - * Notes: OSC command registration is handled differently (see addOscHandler) - * APC, PM or SOS is currently not supported. + * Adds a handler for DCS escape sequences. + * @param id Specifies the function identifier under which the callback + * gets registered, e.g. {intermediates: '$' final: 'q'} for DECRQSS. + * @param callback The function to handle the sequence. Note that the + * function will only be called once if the sequence finished sucessfully. + * There is currently no way to intercept smaller data chunks, data chunks + * will be stored up until the sequence is finished. Since DCS sequences + * are not limited by the amount of data this might impose a problem for + * big payloads. Currently xterm.js limits DCS payload to 10 MB + * which should give enough room for most use cases. + * The function gets the payload and numerical parameters as arguments. + * Return true if the sequence was handled; false if we should try + * a previous handler (set by addDcsHandler or setDcsHandler). + * The most recently-added handler is tried first. + * @return An IDisposable you can call to remove this handler. */ - export interface IFunctionIdentifier { - /** - * Optional prefix byte, must be in range \x3c .. \x3f. - * Usable in CSI and DCS. - */ - prefix?: string; - /** - * Optional intermediate bytes, must be in range \x20 .. \x2f. - * Usable in CSI, DCS and ESC. - */ - intermediates?: string; - /** - * Final byte, must be in range \x40 .. \x7e for CSI and DCS, - * \x30 .. \x7e for ESC. - */ - final: string; - } + addDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean): IDisposable; /** - * Parser interface. + * Adds a handler for ESC escape sequences. + * @param id Specifies the function identifier under which the callback + * gets registered, e.g. {intermediates: '%' final: 'G'} for + * default charset selection. + * @param callback The function to handle the sequence. + * Return true if the sequence was handled; false if we should try + * a previous handler (set by addEscHandler or setEscHandler). + * The most recently-added handler is tried first. + * @return An IDisposable you can call to remove this handler. */ - export interface IParser { - /** - * Adds a handler for CSI escape sequences. - * @param id Specifies the function identifier under which the callback - * gets registered, e.g. {final: 'm'} for SGR. - * @param callback The function to handle the sequence. The callback is - * called with the numerical params. If the sequence has subparams the - * array will contain subarrays with their numercial values. - * Return true if the sequence was handled; false if we should try - * a previous handler (set by addCsiHandler or setCsiHandler). - * The most recently-added handler is tried first. - * @return An IDisposable you can call to remove this handler. - */ - addCsiHandler(id: IFunctionIdentifier, callback: (params: (number | number[])[]) => boolean): IDisposable; + addEscHandler(id: IFunctionIdentifier, handler: () => boolean): IDisposable; - /** - * Adds a handler for DCS escape sequences. - * @param id Specifies the function identifier under which the callback - * gets registered, e.g. {intermediates: '$' final: 'q'} for DECRQSS. - * @param callback The function to handle the sequence. Note that the - * function will only be called once if the sequence finished sucessfully. - * There is currently no way to intercept smaller data chunks, data chunks - * will be stored up until the sequence is finished. Since DCS sequences - * are not limited by the amount of data this might impose a problem for - * big payloads. Currently xterm.js limits DCS payload to 10 MB - * which should give enough room for most use cases. - * The function gets the payload and numerical parameters as arguments. - * Return true if the sequence was handled; false if we should try - * a previous handler (set by addDcsHandler or setDcsHandler). - * The most recently-added handler is tried first. - * @return An IDisposable you can call to remove this handler. - */ - addDcsHandler(id: IFunctionIdentifier, callback: (data: string, param: (number | number[])[]) => boolean): IDisposable; - - /** - * Adds a handler for ESC escape sequences. - * @param id Specifies the function identifier under which the callback - * gets registered, e.g. {intermediates: '%' final: 'G'} for - * default charset selection. - * @param callback The function to handle the sequence. - * Return true if the sequence was handled; false if we should try - * a previous handler (set by addEscHandler or setEscHandler). - * The most recently-added handler is tried first. - * @return An IDisposable you can call to remove this handler. - */ - addEscHandler(id: IFunctionIdentifier, handler: () => boolean): IDisposable; - - /** - * Adds a handler for OSC escape sequences. - * @param ident The number (first parameter) of the sequence. - * @param callback The function to handle the sequence. Note that the - * function will only be called once if the sequence finished sucessfully. - * There is currently no way to intercept smaller data chunks, data chunks - * will be stored up until the sequence is finished. Since OSC sequences - * are not limited by the amount of data this might impose a problem for - * big payloads. Currently xterm.js limits OSC payload to 10 MB - * which should give enough room for most use cases. - * The callback is called with OSC data string. - * Return true if the sequence was handled; false if we should try - * a previous handler (set by addOscHandler or setOscHandler). - * The most recently-added handler is tried first. - * @return An IDisposable you can call to remove this handler. - */ - addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable; - } + /** + * Adds a handler for OSC escape sequences. + * @param ident The number (first parameter) of the sequence. + * @param callback The function to handle the sequence. Note that the + * function will only be called once if the sequence finished sucessfully. + * There is currently no way to intercept smaller data chunks, data chunks + * will be stored up until the sequence is finished. Since OSC sequences + * are not limited by the amount of data this might impose a problem for + * big payloads. Currently xterm.js limits OSC payload to 10 MB + * which should give enough room for most use cases. + * The callback is called with OSC data string. + * Return true if the sequence was handled; false if we should try + * a previous handler (set by addOscHandler or setOscHandler). + * The most recently-added handler is tried first. + * @return An IDisposable you can call to remove this handler. + */ + addOscHandler(ident: number, callback: (data: string) => boolean): IDisposable; } }