Move charset into own service

This commit is contained in:
Daniel Imms
2019-12-18 10:53:05 +11:00
parent 05e1cd8478
commit 224fb5c6a2
8 changed files with 94 additions and 75 deletions
+10 -10
View File
@@ -13,7 +13,7 @@ import { CellData } from 'common/buffer/CellData';
import { Attributes } from 'common/buffer/Constants';
import { AttributeData } from 'common/buffer/AttributeData';
import { Params } from 'common/parser/Params';
import { MockCoreService, MockBufferService, MockDirtyRowService, MockOptionsService, MockLogService, MockCoreMouseService } from 'common/TestUtils.test';
import { MockCoreService, MockBufferService, MockDirtyRowService, MockOptionsService, MockLogService, MockCoreMouseService, MockCharsetService } from 'common/TestUtils.test';
import { IBufferService } from 'common/services/Services';
import { DEFAULT_OPTIONS } from 'common/services/OptionsService';
import { clone } from 'common/Clone';
@@ -41,7 +41,7 @@ describe('InputHandler', () => {
bufferService.buffer.x = 1;
bufferService.buffer.y = 2;
bufferService.buffer.ybase = 0;
const inputHandler = new InputHandler(terminal, bufferService, new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
const inputHandler = new InputHandler(terminal, bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
// Save cursor position
inputHandler.saveCursor();
assert.equal(bufferService.buffer.x, 1);
@@ -60,7 +60,7 @@ describe('InputHandler', () => {
describe('setCursorStyle', () => {
it('should call Terminal.setOption with correct params', () => {
const optionsService = new MockOptionsService();
const inputHandler = new InputHandler(new MockInputHandlingTerminal(), new MockBufferService(80, 30), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), optionsService, new MockCoreMouseService());
const inputHandler = new InputHandler(new MockInputHandlingTerminal(), new MockBufferService(80, 30), new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), optionsService, new MockCoreMouseService());
inputHandler.setCursorStyle(Params.fromArray([0]));
assert.equal(optionsService.options['cursorStyle'], 'block');
@@ -101,7 +101,7 @@ describe('InputHandler', () => {
it('should toggle Terminal.bracketedPasteMode', () => {
const terminal = new MockInputHandlingTerminal();
terminal.bracketedPasteMode = false;
const inputHandler = new InputHandler(terminal, new MockBufferService(80, 30), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
const inputHandler = new InputHandler(terminal, new MockBufferService(80, 30), new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
// Set bracketed paste mode
inputHandler.setModePrivate(Params.fromArray([2004]));
assert.equal(terminal.bracketedPasteMode, true);
@@ -120,7 +120,7 @@ describe('InputHandler', () => {
it('insertChars', function(): void {
const term = new Terminal();
const bufferService = new MockBufferService(80, 30);
const inputHandler = new InputHandler(term, bufferService, new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
const inputHandler = new InputHandler(term, bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
// insert some data in first and second line
inputHandler.parse(Array(bufferService.cols - 9).join('a'));
@@ -158,7 +158,7 @@ describe('InputHandler', () => {
it('deleteChars', function(): void {
const term = new Terminal();
const bufferService = new MockBufferService(80, 30);
const inputHandler = new InputHandler(term, bufferService, new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
const inputHandler = new InputHandler(term, bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
// insert some data in first and second line
inputHandler.parse(Array(bufferService.cols - 9).join('a'));
@@ -199,7 +199,7 @@ describe('InputHandler', () => {
it('eraseInLine', function(): void {
const term = new Terminal();
const bufferService = new MockBufferService(80, 30);
const inputHandler = new InputHandler(term, bufferService, new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
const inputHandler = new InputHandler(term, bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
// fill 6 lines to test 3 different states
inputHandler.parse(Array(bufferService.cols + 1).join('a'));
@@ -228,7 +228,7 @@ describe('InputHandler', () => {
it('eraseInDisplay', function(): void {
const term = new Terminal({cols: 80, rows: 7});
const bufferService = new MockBufferService(80, 7);
const inputHandler = new InputHandler(term, bufferService, new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
const inputHandler = new InputHandler(term, bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
// fill display with a's
for (let i = 0; i < bufferService.rows; ++i) inputHandler.parse(Array(bufferService.cols + 1).join('a'));
@@ -363,7 +363,7 @@ describe('InputHandler', () => {
describe('print', () => {
it('should not cause an infinite loop (regression test)', () => {
const term = new Terminal();
const inputHandler = new InputHandler(term, new MockBufferService(80, 30), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
const inputHandler = new InputHandler(term, new MockBufferService(80, 30), new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
const container = new Uint32Array(10);
container[0] = 0x200B;
inputHandler.print(container, 0, 1);
@@ -378,7 +378,7 @@ describe('InputHandler', () => {
beforeEach(() => {
term = new Terminal();
bufferService = new MockBufferService(80, 30);
handler = new InputHandler(term, bufferService, new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
handler = new InputHandler(term, bufferService, new MockCharsetService(), new MockCoreService(), new MockDirtyRowService(), new MockLogService(), new MockOptionsService(), new MockCoreMouseService());
});
it('should handle DECSET/DECRST 47 (alt screen buffer)', () => {
handler.parse('\x1b[?47h\r\n\x1b[31mJUNK\x1b[?47lTEST');
+17 -16
View File
@@ -19,7 +19,7 @@ import { NULL_CELL_CODE, NULL_CELL_WIDTH, Attributes, FgFlags, BgFlags, Content
import { CellData } from 'common/buffer/CellData';
import { AttributeData } from 'common/buffer/AttributeData';
import { IAttributeData, IDisposable } from 'common/Types';
import { ICoreService, IBufferService, IOptionsService, ILogService, IDirtyRowService, ICoreMouseService } from 'common/services/Services';
import { ICoreService, IBufferService, IOptionsService, ILogService, IDirtyRowService, ICoreMouseService, ICharsetService } from 'common/services/Services';
import { OscHandler } from 'common/parser/OscParser';
import { DcsHandler } from 'common/parser/DcsParser';
@@ -140,6 +140,7 @@ export class InputHandler extends Disposable implements IInputHandler {
constructor(
protected _terminal: IInputHandlingTerminal,
private readonly _bufferService: IBufferService,
private readonly _charsetService: ICharsetService,
private readonly _coreService: ICoreService,
private readonly _dirtyRowService: IDirtyRowService,
private readonly _logService: ILogService,
@@ -381,7 +382,7 @@ export class InputHandler extends Disposable implements IInputHandler {
let code: number;
let chWidth: number;
const buffer = this._bufferService.buffer;
const charset = this._coreService.charsetModes.charset;
const charset = this._charsetService.charset;
const screenReaderMode = this._optionsService.options.screenReaderMode;
const cols = this._bufferService.cols;
const wraparoundMode = this._terminal.wraparoundMode;
@@ -608,7 +609,7 @@ export class InputHandler extends Disposable implements IInputHandler {
* G1 character set.
*/
public shiftOut(): void {
this._coreService.setgLevel(1);
this._charsetService.setgLevel(1);
}
/**
@@ -617,7 +618,7 @@ export class InputHandler extends Disposable implements IInputHandler {
* character set (the default).
*/
public shiftIn(): void {
this._coreService.setgLevel(0);
this._charsetService.setgLevel(0);
}
/**
@@ -1396,10 +1397,10 @@ export class InputHandler extends Disposable implements IInputHandler {
this._coreService.decPrivateModes.applicationCursorKeys = true;
break;
case 2:
this._coreService.setgCharset(0, DEFAULT_CHARSET);
this._coreService.setgCharset(1, DEFAULT_CHARSET);
this._coreService.setgCharset(2, DEFAULT_CHARSET);
this._coreService.setgCharset(3, DEFAULT_CHARSET);
this._charsetService.setgCharset(0, DEFAULT_CHARSET);
this._charsetService.setgCharset(1, DEFAULT_CHARSET);
this._charsetService.setgCharset(2, DEFAULT_CHARSET);
this._charsetService.setgCharset(3, DEFAULT_CHARSET);
// set VT100 mode here
break;
case 3: // 132 col mode
@@ -1974,7 +1975,7 @@ export class InputHandler extends Disposable implements IInputHandler {
this._bufferService.buffer.scrollBottom = this._bufferService.rows - 1;
this._terminal.curAttrData = DEFAULT_ATTR_DATA.clone();
this._bufferService.buffer.x = this._bufferService.buffer.y = 0; // ?
this._coreService.softReset();
this._charsetService.reset();
}
/**
@@ -2038,7 +2039,7 @@ export class InputHandler extends Disposable implements IInputHandler {
this._bufferService.buffer.savedY = this._bufferService.buffer.ybase + this._bufferService.buffer.y;
this._bufferService.buffer.savedCurAttrData.fg = this._terminal.curAttrData.fg;
this._bufferService.buffer.savedCurAttrData.bg = this._terminal.curAttrData.bg;
this._bufferService.buffer.savedCharset = this._coreService.charsetModes.charset;
this._bufferService.buffer.savedCharset = this._charsetService.charset;
}
@@ -2052,9 +2053,9 @@ export class InputHandler extends Disposable implements IInputHandler {
this._bufferService.buffer.y = Math.max(this._bufferService.buffer.savedY - this._bufferService.buffer.ybase, 0);
this._terminal.curAttrData.fg = this._bufferService.buffer.savedCurAttrData.fg;
this._terminal.curAttrData.bg = this._bufferService.buffer.savedCurAttrData.bg;
this._coreService.charsetModes.charset = (this as any)._savedCharset;
this._charsetService.charset = (this as any)._savedCharset;
if (this._bufferService.buffer.savedCharset) {
this._coreService.charsetModes.charset = this._bufferService.buffer.savedCharset;
this._charsetService.charset = this._bufferService.buffer.savedCharset;
}
this._restrictCursor();
}
@@ -2113,8 +2114,8 @@ export class InputHandler extends Disposable implements IInputHandler {
* therefore ESC % G does the same.
*/
public selectDefaultCharset(): void {
this._coreService.setgLevel(0);
this._coreService.setgCharset(0, DEFAULT_CHARSET); // US (default)
this._charsetService.setgLevel(0);
this._charsetService.setgCharset(0, DEFAULT_CHARSET); // US (default)
}
/**
@@ -2141,7 +2142,7 @@ export class InputHandler extends Disposable implements IInputHandler {
if (collectAndFlag[0] === '/') {
return; // TODO: Is this supported?
}
this._coreService.setgCharset(GLEVEL[collectAndFlag[0]], CHARSETS[collectAndFlag[1]] || DEFAULT_CHARSET);
this._charsetService.setgCharset(GLEVEL[collectAndFlag[0]], CHARSETS[collectAndFlag[1]] || DEFAULT_CHARSET);
return;
}
@@ -2220,7 +2221,7 @@ export class InputHandler extends Disposable implements IInputHandler {
* you use another locking shift. (partly supported)
*/
public setgLevel(level: number): void {
this._coreService.setgLevel(level);
this._charsetService.setgLevel(level);
}
/**
+7 -3
View File
@@ -46,7 +46,7 @@ import { DEFAULT_ATTR_DATA } from 'common/buffer/BufferLine';
import { handleWindowsModeLineFeed } from 'common/WindowsMode';
import { ColorManager } from 'browser/ColorManager';
import { RenderService } from 'browser/services/RenderService';
import { IOptionsService, IBufferService, ICoreMouseService, ICoreService, ILogService, IDirtyRowService, IInstantiationService } from 'common/services/Services';
import { IOptionsService, IBufferService, ICoreMouseService, ICoreService, ILogService, IDirtyRowService, IInstantiationService, ICharsetService } from 'common/services/Services';
import { OptionsService } from 'common/services/OptionsService';
import { ICharSizeService, IRenderService, IMouseService, ISelectionService, ISoundService, ICoreBrowserService } from 'browser/services/Services';
import { CharSizeService } from 'browser/services/CharSizeService';
@@ -64,6 +64,7 @@ import { InstantiationService } from 'common/services/InstantiationService';
import { CoreMouseService } from 'common/services/CoreMouseService';
import { WriteBuffer } from 'common/input/WriteBuffer';
import { CoreBrowserService } from 'browser/services/CoreBrowserService';
import { CharsetService } from 'common/services/CharsetService';
// Let it work inside Node.js for automated testing purposes.
const document = (typeof window !== 'undefined') ? window.document : null;
@@ -96,6 +97,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
// common services
private _bufferService: IBufferService;
private _coreService: ICoreService;
private _charsetService: ICharsetService;
private _coreMouseService: ICoreMouseService;
private _dirtyRowService: IDirtyRowService;
private _instantiationService: IInstantiationService;
@@ -221,6 +223,8 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
this._instantiationService.setService(ICoreMouseService, this._coreMouseService);
this._dirtyRowService = this._instantiationService.createInstance(DirtyRowService);
this._instantiationService.setService(IDirtyRowService, this._dirtyRowService);
this._charsetService = this._instantiationService.createInstance(CharsetService);
this._instantiationService.setService(ICharsetService, this._charsetService);
this._setupOptionsListeners();
this._setup();
@@ -254,7 +258,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
this.bracketedPasteMode = false;
// charset
this._coreService.softReset();
this._charsetService.reset();
this.curAttrData = DEFAULT_ATTR_DATA.clone();
this._eraseAttrData = DEFAULT_ATTR_DATA.clone();
@@ -265,7 +269,7 @@ export class Terminal extends Disposable implements ITerminal, IDisposable, IInp
this._userScrolling = false;
// Register input handler and refire/handle events
this._inputHandler = new InputHandler(this, this._bufferService, this._coreService, this._dirtyRowService, this._logService, this.optionsService, this._coreMouseService);
this._inputHandler = new InputHandler(this, this._bufferService, this._charsetService, this._coreService, this._dirtyRowService, this._logService, this.optionsService, this._coreMouseService);
this._inputHandler.onRequestRefreshRows((start, end) => this.refresh(start, end));
this._inputHandler.onCursorMove(() => this._onCursorMove.fire());
this._inputHandler.onLineFeed(() => this._onLineFeed.fire());
+13 -11
View File
@@ -3,13 +3,13 @@
* @license MIT
*/
import { IBufferService, ICoreService, ILogService, IOptionsService, ITerminalOptions, IPartialTerminalOptions, IDirtyRowService, ICoreMouseService } from 'common/services/Services';
import { IBufferService, ICoreService, ILogService, IOptionsService, ITerminalOptions, IPartialTerminalOptions, IDirtyRowService, ICoreMouseService, ICharsetService } from 'common/services/Services';
import { IEvent, EventEmitter } from 'common/EventEmitter';
import { clone } from 'common/Clone';
import { DEFAULT_OPTIONS } from 'common/services/OptionsService';
import { IBufferSet, IBuffer } from 'common/buffer/Types';
import { BufferSet } from 'common/buffer/BufferSet';
import { IDecPrivateModes, ICoreMouseEvent, CoreMouseEventType, ICharsetModes, ICharset } from 'common/Types';
import { IDecPrivateModes, ICoreMouseEvent, CoreMouseEventType, ICharset } from 'common/Types';
export class MockBufferService implements IBufferService {
serviceBrand: any;
@@ -42,24 +42,26 @@ export class MockCoreMouseService implements ICoreMouseService {
}
}
export class MockCharsetService implements ICharsetService {
serviceBrand: any;
charset: ICharset | undefined;
glevel: number = 0;
charsets: readonly ICharset[] = [];
reset(): void {}
setgLevel(g: number): void {}
setgCharset(g: number, charset: ICharset): void {}
}
export class MockCoreService implements ICoreService {
serviceBrand: any;
isCursorInitialized: boolean = false;
isCursorHidden: boolean = false;
isFocused: boolean = false;
serviceBrand: any;
charsetModes: ICharsetModes = {
charset: undefined,
charsets: [],
glevel: 0
};
decPrivateModes: IDecPrivateModes = {} as any;
onData: IEvent<string> = new EventEmitter<string>().event;
onUserInput: IEvent<void> = new EventEmitter<void>().event;
onBinary: IEvent<string> = new EventEmitter<string>().event;
reset(): void {}
softReset(): void {}
setgLevel(g: number): void {}
setgCharset(g: number, charset: ICharset): void {}
triggerDataEvent(data: string, wasUserInput?: boolean): void {}
triggerBinaryEvent(data: string): void {}
}
+1 -7
View File
@@ -62,13 +62,7 @@ export interface IKeyboardResult {
}
export interface ICharset {
[key: string]: string;
}
export interface ICharsetModes {
charset: ICharset | undefined;
glevel: number;
charsets: ICharset[];
[key: string]: string | undefined;
}
export type CharData = [number, string, number, number];
+33
View File
@@ -0,0 +1,33 @@
/**
* Copyright (c) 2019 The xterm.js authors. All rights reserved.
* @license MIT
*/
import { ICharsetService } from 'common/services/Services';
import { ICharset } from 'common/Types';
export class CharsetService implements ICharsetService {
serviceBrand: any;
public charset: ICharset | undefined;
public charsets: ICharset[] = [];
public glevel: number = 0;
public reset(): void {
this.charset = undefined;
this.charsets = [];
this.glevel = 0;
}
public setgLevel(g: number): void {
this.glevel = g;
this.charset = this.charsets[g];
}
public setgCharset(g: number, charset: ICharset): void {
this.charsets[g] = charset;
if (this.glevel === g) {
this.charset = charset;
}
}
}
+1 -24
View File
@@ -5,7 +5,7 @@
import { ICoreService, ILogService, IOptionsService, IBufferService } from 'common/services/Services';
import { EventEmitter, IEvent } from 'common/EventEmitter';
import { IDecPrivateModes, ICharset, ICharsetModes } from 'common/Types';
import { IDecPrivateModes, ICharset } from 'common/Types';
import { clone } from 'common/Clone';
const DEFAULT_DEC_PRIVATE_MODES: IDecPrivateModes = Object.freeze({
@@ -18,11 +18,6 @@ export class CoreService implements ICoreService {
public isCursorInitialized: boolean = false;
public isCursorHidden: boolean = false;
public decPrivateModes: IDecPrivateModes;
public charsetModes: ICharsetModes = {
charset: undefined,
charsets: [],
glevel: 0
};
private _onData = new EventEmitter<string>();
public get onData(): IEvent<string> { return this._onData.event; }
@@ -45,12 +40,6 @@ export class CoreService implements ICoreService {
this.decPrivateModes = clone(DEFAULT_DEC_PRIVATE_MODES);
}
public softReset(): void {
this.charsetModes.charset = undefined;
this.charsetModes.charsets = [];
this.charsetModes.glevel = 0;
}
public triggerDataEvent(data: string, wasUserInput: boolean = false): void {
// Prevents all events to pty process if stdin is disabled
if (this._optionsService.options.disableStdin) {
@@ -80,16 +69,4 @@ export class CoreService implements ICoreService {
this._logService.debug(`sending binary "${data}"`, () => data.split('').map(e => e.charCodeAt(0)));
this._onBinary.fire(data);
}
public setgLevel(g: number): void {
this.charsetModes.glevel = g;
this.charsetModes.charset = this.charsetModes.charsets[g];
}
public setgCharset(g: number, charset: ICharset): void {
this.charsetModes.charsets[g] = charset;
if (this.charsetModes.glevel === g) {
this.charsetModes.charset = charset;
}
}
}
+12 -4
View File
@@ -5,7 +5,7 @@
import { IEvent } from 'common/EventEmitter';
import { IBuffer, IBufferSet } from 'common/buffer/Types';
import { IDecPrivateModes, ICoreMouseEvent, CoreMouseEncoding, ICoreMouseProtocol, CoreMouseEventType, ICharsetModes, ICharset } from 'common/Types';
import { IDecPrivateModes, ICoreMouseEvent, CoreMouseEncoding, ICoreMouseProtocol, CoreMouseEventType, ICharset } from 'common/Types';
import { createDecorator } from 'common/services/ServiceRegistry';
export const IBufferService = createDecorator<IBufferService>('BufferService');
@@ -65,8 +65,6 @@ export interface ICoreService {
isCursorInitialized: boolean;
isCursorHidden: boolean;
charsetModes: ICharsetModes;
readonly decPrivateModes: IDecPrivateModes;
readonly onData: IEvent<string>;
@@ -74,7 +72,6 @@ export interface ICoreService {
readonly onBinary: IEvent<string>;
reset(): void;
softReset(): void;
/**
* Triggers the onData event in the public API.
@@ -91,6 +88,17 @@ export interface ICoreService {
* @param data The data that is being emitted.
*/
triggerBinaryEvent(data: string): void;
}
export const ICharsetService = createDecorator<ICharsetService>('CharsetService');
export interface ICharsetService {
serviceBrand: any;
charset: ICharset | undefined;
readonly glevel: number;
readonly charsets: ReadonlyArray<ICharset>;
reset(): void;
/**
* Set the G level of the terminal.