Merge pull request #2874 from Tyriar/layers2

Move InputHandler into common
This commit is contained in:
Daniel Imms
2020-04-26 09:08:50 -07:00
committed by GitHub
34 changed files with 2093 additions and 2071 deletions
@@ -3,7 +3,7 @@
* @license MIT
*/
import { ITerminalOptions } from '../../../src/Types';
import { ITerminalOptions } from '../../../src/common/Types';
import { ITheme } from 'xterm';
import { assert } from 'chai';
import { openTerminal, pollFor, writeSync, getBrowserType } from '../../../out-test/api/TestUtils';
File diff suppressed because it is too large Load Diff
+88 -6
View File
@@ -121,7 +121,7 @@ describe('Terminal', () => {
assert.equal(e, 'title');
done();
});
term.handleTitle('title');
term.write('\x1b]2;title\x07');
});
});
@@ -140,7 +140,6 @@ describe('Terminal', () => {
};
beforeEach(() => {
term.showCursor = () => { };
term.clearSelection = () => { };
});
@@ -531,7 +530,6 @@ describe('Terminal', () => {
let evKeyPress: any;
beforeEach(() => {
term.showCursor = () => { };
term.clearSelection = () => { };
// term.compositionHelper = {
// isComposing: false,
@@ -991,7 +989,7 @@ describe('Terminal', () => {
term.writeSync(Array(9).join('0123456789').slice(-80));
term.buffer.x = 10;
term.buffer.y = 0;
term.insertMode = true;
term.write('\x1b[4h');
term.writeSync('abcde');
expect(term.buffer.lines.get(0).length).eql(term.cols);
expect(term.buffer.lines.get(0).loadCell(10, cell).getChars()).eql('a');
@@ -1003,7 +1001,7 @@ describe('Terminal', () => {
term.writeSync(Array(9).join('0123456789').slice(-80));
term.buffer.x = 10;
term.buffer.y = 0;
term.insertMode = true;
term.write('\x1b[4h');
term.writeSync('¥¥¥');
expect(term.buffer.lines.get(0).length).eql(term.cols);
expect(term.buffer.lines.get(0).loadCell(10, cell).getChars()).eql('¥');
@@ -1016,7 +1014,7 @@ describe('Terminal', () => {
term.writeSync(Array(41).join('¥'));
term.buffer.x = 10;
term.buffer.y = 0;
term.insertMode = true;
term.write('\x1b[4h');
term.writeSync('a');
expect(term.buffer.lines.get(0).length).eql(term.cols);
expect(term.buffer.lines.get(0).loadCell(10, cell).getChars()).eql('a');
@@ -1403,6 +1401,90 @@ describe('Terminal', () => {
assert.equal(windowsModeTerminal.buffer.lines.get(2).isWrapped, false);
});
});
it('convertEol setting', function(): void {
// not converting
const termNotConverting = new TestTerminal({cols: 15, rows: 10});
termNotConverting.writeSync('Hello\nWorld');
expect(termNotConverting.buffer.lines.get(0).translateToString(false)).equals('Hello ');
expect(termNotConverting.buffer.lines.get(1).translateToString(false)).equals(' World ');
expect(termNotConverting.buffer.lines.get(0).translateToString(true)).equals('Hello');
expect(termNotConverting.buffer.lines.get(1).translateToString(true)).equals(' World');
// converting
const termConverting = new TestTerminal({cols: 15, rows: 10, convertEol: true});
termConverting.writeSync('Hello\nWorld');
expect(termConverting.buffer.lines.get(0).translateToString(false)).equals('Hello ');
expect(termConverting.buffer.lines.get(1).translateToString(false)).equals('World ');
expect(termConverting.buffer.lines.get(0).translateToString(true)).equals('Hello');
expect(termConverting.buffer.lines.get(1).translateToString(true)).equals('World');
});
describe('Terminal InputHandler integration', () => {
function getLines(term: TestTerminal, limit: number = term.rows): string[] {
const res: string[] = [];
for (let i = 0; i < limit; ++i) {
res.push(term.buffer.lines.get(i).translateToString(true));
}
return res;
}
// This suite cannot live in InputHandler unless Terminal.scroll moved into IBufferService
describe('SL/SR/DECIC/DECDC', () => {
let term: TestTerminal;
beforeEach(() => {
term = new TestTerminal({cols: 5, rows: 5, scrollback: 1});
});
it('SL (scrollLeft)', () => {
term.writeSync('12345'.repeat(6));
term.writeSync('\x1b[ @');
assert.deepEqual(getLines(term, term.rows + 1), ['12345', '2345', '2345', '2345', '2345', '2345']);
term.writeSync('\x1b[0 @');
assert.deepEqual(getLines(term, term.rows + 1), ['12345', '345', '345', '345', '345', '345']);
term.writeSync('\x1b[2 @');
assert.deepEqual(getLines(term, term.rows + 1), ['12345', '5', '5', '5', '5', '5']);
});
it('SR (scrollRight)', () => {
term.writeSync('12345'.repeat(6));
term.writeSync('\x1b[ A');
assert.deepEqual(getLines(term, term.rows + 1), ['12345', ' 1234', ' 1234', ' 1234', ' 1234', ' 1234']);
term.writeSync('\x1b[0 A');
assert.deepEqual(getLines(term, term.rows + 1), ['12345', ' 123', ' 123', ' 123', ' 123', ' 123']);
term.writeSync('\x1b[2 A');
assert.deepEqual(getLines(term, term.rows + 1), ['12345', ' 1', ' 1', ' 1', ' 1', ' 1']);
});
it('insertColumns (DECIC)', () => {
term.writeSync('12345'.repeat(6));
term.writeSync('\x1b[3;3H');
term.writeSync('\x1b[\'}');
assert.deepEqual(getLines(term, term.rows + 1), ['12345', '12 34', '12 34', '12 34', '12 34', '12 34']);
term.reset();
term.writeSync('12345'.repeat(6));
term.writeSync('\x1b[3;3H');
term.writeSync('\x1b[1\'}');
assert.deepEqual(getLines(term, term.rows + 1), ['12345', '12 34', '12 34', '12 34', '12 34', '12 34']);
term.reset();
term.writeSync('12345'.repeat(6));
term.writeSync('\x1b[3;3H');
term.writeSync('\x1b[2\'}');
assert.deepEqual(getLines(term, term.rows + 1), ['12345', '12 3', '12 3', '12 3', '12 3', '12 3']);
});
it('deleteColumns (DECDC)', () => {
term.writeSync('12345'.repeat(6));
term.writeSync('\x1b[3;3H');
term.writeSync('\x1b[\'~');
assert.deepEqual(getLines(term, term.rows + 1), ['12345', '1245', '1245', '1245', '1245', '1245']);
term.reset();
term.writeSync('12345'.repeat(6));
term.writeSync('\x1b[3;3H');
term.writeSync('\x1b[1\'~');
assert.deepEqual(getLines(term, term.rows + 1), ['12345', '1245', '1245', '1245', '1245', '1245']);
term.reset();
term.writeSync('12345'.repeat(6));
term.writeSync('\x1b[3;3H');
term.writeSync('\x1b[2\'~');
assert.deepEqual(getLines(term, term.rows + 1), ['12345', '125', '125', '125', '125', '125']);
});
});
});
});
class TestLinkifier extends Linkifier {
+118 -242
View File
File diff suppressed because it is too large Load Diff
+2 -35
View File
@@ -4,9 +4,9 @@
*/
import { IRenderer, IRenderDimensions, CharacterJoinerHandler, IRequestRedrawEvent } from 'browser/renderer/Types';
import { IInputHandlingTerminal, ICompositionHelper, ITerminal, IBrowser, ITerminalOptions } from './Types';
import { ICompositionHelper, ITerminal, IBrowser } from './Types';
import { IBuffer, IBufferStringIterator, IBufferSet } from 'common/buffer/Types';
import { IBufferLine, ICellData, IAttributeData, ICircularList, XtermListener, ICharset } from 'common/Types';
import { IBufferLine, ICellData, IAttributeData, ICircularList, XtermListener, ICharset, ITerminalOptions } from 'common/Types';
import { Buffer } from 'common/buffer/Buffer';
import * as Browser from 'common/Platform';
import { IDisposable, IMarker, IEvent, ISelectionPosition, ILinkProvider } from 'xterm';
@@ -14,7 +14,6 @@ import { Terminal } from './Terminal';
import { AttributeData } from 'common/buffer/AttributeData';
import { IColorManager, IColorSet, ILinkMatcherOptions, ILinkifier, IViewport, ILinkifier2 } from 'browser/Types';
import { IOptionsService, IUnicodeService } from 'common/services/Services';
import { EventEmitter } from 'common/EventEmitter';
import { IParams, IFunctionIdentifier } from 'common/parser/Types';
import { ISelectionService } from 'browser/services/Services';
@@ -190,9 +189,6 @@ export class MockTerminal implements ITerminal {
public reset(): void {
throw new Error('Method not implemented.');
}
public showCursor(): void {
throw new Error('Method not implemented.');
}
public refresh(start: number, end: number): void {
throw new Error('Method not implemented.');
}
@@ -200,35 +196,6 @@ export class MockTerminal implements ITerminal {
public deregisterCharacterJoiner(joinerId: number): void { }
}
export class MockInputHandlingTerminal implements IInputHandlingTerminal {
public onA11yCharEmitter: EventEmitter<string>;
public onA11yTabEmitter: EventEmitter<number>;
public insertMode: boolean;
public bracketedPasteMode: boolean;
public sendFocus: boolean;
public buffers: IBufferSet;
public buffer: IBuffer = new MockBuffer();
public viewport: IViewport;
public scroll(eraseAttr: IAttributeData, isWrapped?: boolean): void {
throw new Error('Method not implemented.');
}
public is(term: string): boolean {
throw new Error('Method not implemented.');
}
public resize(x: number, y: number): void {
throw new Error('Method not implemented.');
}
public showCursor(): void {
throw new Error('Method not implemented.');
}
public handler(data: string): void {
throw new Error('Method not implemented.');
}
public handleTitle(title: string): void {
throw new Error('Method not implemented.');
}
}
export class MockBuffer implements IBuffer {
public markers: IMarker[];
public addMarker(y: number): IMarker {
+4 -120
View File
@@ -3,10 +3,10 @@
* @license MIT
*/
import { ITerminalOptions as IPublicTerminalOptions, IDisposable, IMarker, ISelectionPosition, ILinkProvider } from 'xterm';
import { ICharset, IAttributeData, CharData, CoreMouseEventType } from 'common/Types';
import { IEvent, IEventEmitter } from 'common/EventEmitter';
import { IColorSet, ILinkifier, ILinkMatcherOptions, IViewport, ILinkifier2 } from 'browser/Types';
import { IDisposable, IMarker, ISelectionPosition, ILinkProvider } from 'xterm';
import { IAttributeData, CharData, ITerminalOptions } from 'common/Types';
import { IEvent } from 'common/EventEmitter';
import { ILinkifier, ILinkMatcherOptions, IViewport, ILinkifier2 } from 'browser/Types';
import { IOptionsService, IUnicodeService } from 'common/services/Services';
import { IBuffer, IBufferSet } from 'common/buffer/Types';
import { IParams, IFunctionIdentifier } from 'common/parser/Types';
@@ -15,30 +15,6 @@ export type CustomKeyEventHandler = (event: KeyboardEvent) => boolean;
export type LineData = CharData[];
/**
* This interface encapsulates everything needed from the Terminal by the
* InputHandler. This cleanly separates the large amount of methods needed by
* InputHandler cleanly from the ITerminal interface.
*/
export interface IInputHandlingTerminal {
insertMode: boolean;
bracketedPasteMode: boolean;
sendFocus: boolean;
buffers: IBufferSet;
buffer: IBuffer;
viewport: IViewport;
onA11yCharEmitter: IEventEmitter<string>;
onA11yTabEmitter: IEventEmitter<number>;
scroll(eraseAttr: IAttributeData, isWrapped?: boolean): void;
is(term: string): boolean;
resize(x: number, y: number): void;
showCursor(): void;
handleTitle(title: string): void;
}
export interface ICompositionHelper {
compositionstart(): void;
compositionupdate(ev: CompositionEvent): void;
@@ -47,95 +23,12 @@ export interface ICompositionHelper {
keydown(ev: KeyboardEvent): boolean;
}
/**
* Calls the parser and handles actions generated by the parser.
*/
export interface IInputHandler {
parse(data: string | Uint8Array): void;
print(data: Uint32Array, start: number, end: number): void;
/** C0 BEL */ bell(): void;
/** C0 LF */ lineFeed(): void;
/** C0 CR */ carriageReturn(): void;
/** C0 BS */ backspace(): void;
/** C0 HT */ tab(): void;
/** C0 SO */ shiftOut(): void;
/** C0 SI */ shiftIn(): void;
/** CSI @ */ insertChars(params: IParams): void;
/** CSI SP @ */ scrollLeft(params: IParams): void;
/** CSI A */ cursorUp(params: IParams): void;
/** CSI SP A */ scrollRight(params: IParams): void;
/** CSI B */ cursorDown(params: IParams): void;
/** CSI C */ cursorForward(params: IParams): void;
/** CSI D */ cursorBackward(params: IParams): void;
/** CSI E */ cursorNextLine(params: IParams): void;
/** CSI F */ cursorPrecedingLine(params: IParams): void;
/** CSI G */ cursorCharAbsolute(params: IParams): void;
/** CSI H */ cursorPosition(params: IParams): void;
/** CSI I */ cursorForwardTab(params: IParams): void;
/** CSI J */ eraseInDisplay(params: IParams): void;
/** CSI K */ eraseInLine(params: IParams): void;
/** CSI L */ insertLines(params: IParams): void;
/** CSI M */ deleteLines(params: IParams): void;
/** CSI P */ deleteChars(params: IParams): void;
/** CSI S */ scrollUp(params: IParams): void;
/** CSI T */ scrollDown(params: IParams, collect?: string): void;
/** CSI X */ eraseChars(params: IParams): void;
/** CSI Z */ cursorBackwardTab(params: IParams): void;
/** CSI ` */ charPosAbsolute(params: IParams): void;
/** CSI a */ hPositionRelative(params: IParams): void;
/** CSI b */ repeatPrecedingCharacter(params: IParams): void;
/** CSI c */ sendDeviceAttributesPrimary(params: IParams): void;
/** CSI > c */ sendDeviceAttributesSecondary(params: IParams): void;
/** CSI d */ linePosAbsolute(params: IParams): void;
/** CSI e */ vPositionRelative(params: IParams): void;
/** CSI f */ hVPosition(params: IParams): void;
/** CSI g */ tabClear(params: IParams): void;
/** CSI h */ setMode(params: IParams, collect?: string): void;
/** CSI l */ resetMode(params: IParams, collect?: string): void;
/** CSI m */ charAttributes(params: IParams): void;
/** CSI n */ deviceStatus(params: IParams, collect?: string): void;
/** CSI p */ softReset(params: IParams, collect?: string): void;
/** CSI q */ setCursorStyle(params: IParams, collect?: string): void;
/** CSI r */ setScrollRegion(params: IParams, collect?: string): void;
/** CSI s */ saveCursor(params: IParams): void;
/** CSI u */ restoreCursor(params: IParams): void;
/** CSI ' } */ insertColumns(params: IParams): void;
/** CSI ' ~ */ deleteColumns(params: IParams): void;
/** OSC 0
OSC 2 */ setTitle(data: string): void;
/** ESC E */ nextLine(): void;
/** ESC = */ keypadApplicationMode(): void;
/** ESC > */ keypadNumericMode(): void;
/** ESC % G
ESC % @ */ selectDefaultCharset(): void;
/** ESC ( C
ESC ) C
ESC * C
ESC + C
ESC - C
ESC . C
ESC / C */ selectCharset(collectAndFlag: string): void;
/** ESC D */ index(): void;
/** ESC H */ tabSet(): void;
/** ESC M */ reverseIndex(): void;
/** ESC c */ fullReset(): void;
/** ESC n
ESC o
ESC |
ESC }
ESC ~ */ setgLevel(level: number): void;
/** ESC # 8 */ screenAlignmentPattern(): void;
}
export interface ITerminal extends IPublicTerminal, IElementAccessor, IBufferAccessor, ILinkifierAccessor {
screenElement: HTMLElement;
browser: IBrowser;
buffer: IBuffer;
buffers: IBufferSet;
viewport: IViewport;
bracketedPasteMode: boolean;
optionsService: IOptionsService;
// TODO: We should remove options once components adopt optionsService
options: ITerminalOptions;
@@ -148,7 +41,6 @@ export interface ITerminal extends IPublicTerminal, IElementAccessor, IBufferAcc
scrollLines(disp: number, suppressScrollEvent?: boolean): void;
cancel(ev: Event, force?: boolean): boolean | void;
showCursor(): void;
}
// Portions of the public API that are required by the internal Terminal
@@ -216,14 +108,6 @@ export interface ILinkifierAccessor {
linkifier2: ILinkifier2;
}
// TODO: The options that are not in the public API should be reviewed
export interface ITerminalOptions extends IPublicTerminalOptions {
[key: string]: any;
cancelEvents?: boolean;
convertEol?: boolean;
termName?: string;
}
export interface IBrowser {
isNode: boolean;
userAgent: string;
+4 -4
View File
@@ -42,17 +42,17 @@ export function copyHandler(ev: ClipboardEvent, selectionService: ISelectionServ
* @param ev The original paste event to be handled
* @param term The terminal on which to apply the handled paste event
*/
export function handlePasteEvent(ev: ClipboardEvent, textarea: HTMLTextAreaElement, bracketedPasteMode: boolean, coreService: ICoreService): void {
export function handlePasteEvent(ev: ClipboardEvent, textarea: HTMLTextAreaElement, coreService: ICoreService): void {
ev.stopPropagation();
if (ev.clipboardData) {
const text = ev.clipboardData.getData('text/plain');
paste(text, textarea, bracketedPasteMode, coreService);
paste(text, textarea, coreService);
}
}
export function paste(text: string, textarea: HTMLTextAreaElement, bracketedPasteMode: boolean, coreService: ICoreService): void {
export function paste(text: string, textarea: HTMLTextAreaElement, coreService: ICoreService): void {
text = prepareTextForTerminal(text);
text = bracketTextForPaste(text, bracketedPasteMode);
text = bracketTextForPaste(text, coreService.decPrivateModes.bracketedPasteMode);
coreService.triggerDataEvent(text, true);
textarea.value = '';
}
+3 -3
View File
@@ -9,7 +9,7 @@ import { IRenderDimensions, IRenderer, CharacterJoinerHandler } from 'browser/re
import { IColorSet } from 'browser/Types';
export class MockCharSizeService implements ICharSizeService {
public serviceBrand: any;
public serviceBrand: undefined;
public get hasValidSize(): boolean { return this.width > 0 && this.height > 0; }
public onCharSizeChange: IEvent<void> = new EventEmitter<void>().event;
constructor(public width: number, public height: number) {}
@@ -17,7 +17,7 @@ export class MockCharSizeService implements ICharSizeService {
}
export class MockMouseService implements IMouseService {
public serviceBrand: any;
public serviceBrand: undefined;
public getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined {
throw new Error('Not implemented');
}
@@ -28,7 +28,7 @@ export class MockMouseService implements IMouseService {
}
export class MockRenderService implements IRenderService {
public serviceBrand: any;
public serviceBrand: undefined;
public onDimensionsChange: IEvent<IRenderDimensions> = new EventEmitter<IRenderDimensions>().event;
public onRenderedBufferChange: IEvent<{ start: number, end: number }, void> = new EventEmitter<{ start: number, end: number }>().event;
public onRefreshRequest: IEvent<{ start: number, end: number}, void> = new EventEmitter<{ start: number, end: number }>().event;
+1 -1
View File
@@ -8,7 +8,7 @@ import { IEvent, EventEmitter } from 'common/EventEmitter';
import { ICharSizeService } from 'browser/services/Services';
export class CharSizeService implements ICharSizeService {
public serviceBrand: any;
public serviceBrand: undefined;
public width: number = 0;
public height: number = 0;
+1 -1
View File
@@ -6,7 +6,7 @@
import { ICoreBrowserService } from './Services';
export class CoreBrowserService implements ICoreBrowserService {
public serviceBrand: any;
public serviceBrand: undefined;
constructor(
private _textarea: HTMLTextAreaElement
+1 -1
View File
@@ -7,7 +7,7 @@ import { ICharSizeService, IRenderService, IMouseService } from './Services';
import { getCoords, getRawByteCoords } from 'browser/input/Mouse';
export class MouseService implements IMouseService {
public serviceBrand: any;
public serviceBrand: undefined;
constructor(
@IRenderService private readonly _renderService: IRenderService,
+5 -3
View File
@@ -10,7 +10,7 @@ import { Disposable } from 'common/Lifecycle';
import { ScreenDprMonitor } from 'browser/ScreenDprMonitor';
import { addDisposableDomListener } from 'browser/Lifecycle';
import { IColorSet } from 'browser/Types';
import { IOptionsService } from 'common/services/Services';
import { IOptionsService, IBufferService, ICoreService } from 'common/services/Services';
import { ICharSizeService, IRenderService } from 'browser/services/Services';
interface ISelectionState {
@@ -20,7 +20,7 @@ interface ISelectionState {
}
export class RenderService extends Disposable implements IRenderService {
public serviceBrand: any;
public serviceBrand: undefined;
private _renderDebouncer: RenderDebouncer;
private _screenDprMonitor: ScreenDprMonitor;
@@ -51,7 +51,8 @@ export class RenderService extends Disposable implements IRenderService {
private _rowCount: number,
screenElement: HTMLElement,
@IOptionsService optionsService: IOptionsService,
@ICharSizeService charSizeService: ICharSizeService
@ICharSizeService charSizeService: ICharSizeService,
@IBufferService private readonly _bufferService: IBufferService
) {
super();
this._renderDebouncer = new RenderDebouncer((start, end) => this._renderRows(start, end));
@@ -61,6 +62,7 @@ export class RenderService extends Disposable implements IRenderService {
this._screenDprMonitor.setListener(() => this.onDevicePixelRatioChange());
this.register(this._screenDprMonitor);
this.register(this._bufferService.onResize(e => this._fullRefresh()));
this.register(optionsService.onOptionChange(() => this._renderer.onOptionsChanged()));
this.register(charSizeService.onCharSizeChange(() => this.onCharSizeChanged()));
+1 -1
View File
@@ -67,7 +67,7 @@ export const enum SelectionMode {
* when the selection is ready to be redrawn (on an animation frame).
*/
export class SelectionService implements ISelectionService {
public serviceBrand: any;
public serviceBrand: undefined;
protected _model: SelectionModel;
+6 -6
View File
@@ -12,7 +12,7 @@ import { IDisposable } from 'common/Types';
export const ICharSizeService = createDecorator<ICharSizeService>('CharSizeService');
export interface ICharSizeService {
serviceBrand: any;
serviceBrand: undefined;
readonly width: number;
readonly height: number;
@@ -25,14 +25,14 @@ export interface ICharSizeService {
export const ICoreBrowserService = createDecorator<ICoreBrowserService>('CoreBrowserService');
export interface ICoreBrowserService {
serviceBrand: any;
serviceBrand: undefined;
readonly isFocused: boolean;
}
export const IMouseService = createDecorator<IMouseService>('MouseService');
export interface IMouseService {
serviceBrand: any;
serviceBrand: undefined;
getCoords(event: {clientX: number, clientY: number}, element: HTMLElement, colCount: number, rowCount: number, isSelection?: boolean): [number, number] | undefined;
getRawByteCoords(event: MouseEvent, element: HTMLElement, colCount: number, rowCount: number): { x: number, y: number } | undefined;
@@ -40,7 +40,7 @@ export interface IMouseService {
export const IRenderService = createDecorator<IRenderService>('RenderService');
export interface IRenderService extends IDisposable {
serviceBrand: any;
serviceBrand: undefined;
onDimensionsChange: IEvent<IRenderDimensions>;
/**
@@ -72,7 +72,7 @@ export interface IRenderService extends IDisposable {
export const ISelectionService = createDecorator<ISelectionService>('SelectionService');
export interface ISelectionService {
serviceBrand: any;
serviceBrand: undefined;
readonly selectionText: string;
readonly hasSelection: boolean;
@@ -100,7 +100,7 @@ export interface ISelectionService {
export const ISoundService = createDecorator<ISoundService>('SoundService');
export interface ISoundService {
serviceBrand: any;
serviceBrand: undefined;
playBellSound(): void;
}
+1 -1
View File
@@ -7,7 +7,7 @@ import { IOptionsService } from 'common/services/Services';
import { ISoundService } from 'browser/services/Services';
export class SoundService implements ISoundService {
public serviceBrand: any;
public serviceBrand: undefined;
private static _audioContext: AudioContext;
+4 -1
View File
@@ -14,7 +14,10 @@
"common/*": [ "./common/*" ]
}
},
"include": [ "./**/*" ],
"include": [
"./**/*",
"../../typings/xterm.d.ts"
],
"references": [
{ "path": "../common" }
]
+160
View File
@@ -0,0 +1,160 @@
/**
* Copyright (c) 2014-2020 The xterm.js authors. All rights reserved.
* Copyright (c) 2012-2013, Christopher Jeffrey (MIT License)
* @license MIT
*
* Originally forked from (with the author's permission):
* Fabrice Bellard's javascript vt100 for jslinux:
* http://bellard.org/jslinux/
* Copyright (c) 2011 Fabrice Bellard
* The original design remains. The terminal itself
* has been extended to include xterm CSI codes, among
* other features.
*
* Terminal Emulation References:
* http://vt100.net/
* http://invisible-island.net/xterm/ctlseqs/ctlseqs.txt
* http://invisible-island.net/xterm/ctlseqs/ctlseqs.html
* http://invisible-island.net/vttest/
* http://www.inwap.com/pdp10/ansicode.txt
* http://linux.die.net/man/4/console_codes
* http://linux.die.net/man/7/urxvt
*/
import { Disposable } from 'common/Lifecycle';
import { IInstantiationService, IOptionsService, IBufferService, ILogService, ICharsetService, ICoreService, ICoreMouseService, IUnicodeService, IDirtyRowService } from 'common/services/Services';
import { InstantiationService } from 'common/services/InstantiationService';
import { LogService } from 'common/services/LogService';
import { BufferService, MINIMUM_COLS, MINIMUM_ROWS } from 'common/services/BufferService';
import { OptionsService } from 'common/services/OptionsService';
import { ITerminalOptions, IDisposable } from './Types';
import { CoreService } from 'common/services/CoreService';
import { EventEmitter, IEvent, forwardEvent } from 'common/EventEmitter';
import { CoreMouseService } from 'common/services/CoreMouseService';
import { DirtyRowService } from 'common/services/DirtyRowService';
import { UnicodeService } from 'common/services/UnicodeService';
import { CharsetService } from 'common/services/CharsetService';
import { updateWindowsModeWrappedState } from 'common/WindowsMode';
import { IFunctionIdentifier, IParams } from 'common/parser/Types';
import { IBufferSet } from 'common/buffer/Types';
export abstract class CoreTerminal extends Disposable {
protected readonly _instantiationService: IInstantiationService;
protected readonly _bufferService: IBufferService;
protected readonly _logService: ILogService;
protected readonly _coreService: ICoreService;
protected readonly _charsetService: ICharsetService;
protected readonly _coreMouseService: ICoreMouseService;
protected readonly _dirtyRowService: IDirtyRowService;
public readonly unicodeService: IUnicodeService;
public readonly optionsService: IOptionsService;
private _windowsMode: IDisposable | undefined;
private _onBinary = new EventEmitter<string>();
public get onBinary(): IEvent<string> { return this._onBinary.event; }
private _onData = new EventEmitter<string>();
public get onData(): IEvent<string> { return this._onData.event; }
protected _onLineFeed = new EventEmitter<void>();
public get onLineFeed(): IEvent<void> { return this._onLineFeed.event; }
private _onResize = new EventEmitter<{ cols: number, rows: number }>();
public get onResize(): IEvent<{ cols: number, rows: number }> { return this._onResize.event; }
public get cols(): number { return this._bufferService.cols; }
public get rows(): number { return this._bufferService.rows; }
public get buffers(): IBufferSet { return this._bufferService.buffers; }
constructor(
options: ITerminalOptions
) {
super();
// Setup and initialize services
this._instantiationService = new InstantiationService();
this.optionsService = new OptionsService(options);
this._instantiationService.setService(IOptionsService, this.optionsService);
this._bufferService = this._instantiationService.createInstance(BufferService);
this._instantiationService.setService(IBufferService, this._bufferService);
this._logService = this._instantiationService.createInstance(LogService);
this._instantiationService.setService(ILogService, this._logService);
this._coreService = this._instantiationService.createInstance(CoreService, () => this.scrollToBottom());
this._instantiationService.setService(ICoreService, this._coreService);
this._coreMouseService = this._instantiationService.createInstance(CoreMouseService);
this._instantiationService.setService(ICoreMouseService, this._coreMouseService);
this._dirtyRowService = this._instantiationService.createInstance(DirtyRowService);
this._instantiationService.setService(IDirtyRowService, this._dirtyRowService);
this.unicodeService = this._instantiationService.createInstance(UnicodeService);
this._instantiationService.setService(IUnicodeService, this.unicodeService);
this._charsetService = this._instantiationService.createInstance(CharsetService);
this._instantiationService.setService(ICharsetService, this._charsetService);
// Setup listeners
this.register(forwardEvent(this._bufferService.onResize, this._onResize));
this.register(forwardEvent(this._coreService.onData, this._onData));
this.register(forwardEvent(this._coreService.onBinary, this._onBinary));
this.register(this.optionsService.onOptionChange(key => this._updateOptions(key)));
}
public dispose(): void {
if (this._isDisposed) {
return;
}
super.dispose();
this._windowsMode?.dispose();
this._windowsMode = undefined;
}
public resize(x: number, y: number): void {
if (isNaN(x) || isNaN(y)) {
return;
}
x = Math.max(x, MINIMUM_COLS);
y = Math.max(y, MINIMUM_ROWS);
this._bufferService.resize(x, y);
}
protected _setup(): void {
if (this.optionsService.options.windowsMode) {
this._enableWindowsMode();
}
}
protected _updateOptions(key: string): void {
// TODO: These listeners should be owned by individual components
switch (key) {
case 'scrollback':
this.buffers.resize(this.cols, this.rows);
break;
case 'windowsMode':
if (this.optionsService.options.windowsMode) {
this._enableWindowsMode();
} else {
this._windowsMode?.dispose();
this._windowsMode = undefined;
}
break;
}
}
protected _enableWindowsMode(): void {
if (!this._windowsMode) {
const disposables: IDisposable[] = [];
disposables.push(this.onLineFeed(updateWindowsModeWrappedState.bind(null, this._bufferService)));
disposables.push(this.addCsiHandler({ final: 'H' }, () => {
updateWindowsModeWrappedState(this._bufferService);
return false;
}));
this._windowsMode = {
dispose: () => {
disposables.forEach(d => d.dispose());
}
};
}
}
public abstract scrollToBottom(): void;
public abstract addCsiHandler(id: IFunctionIdentifier, callback: (params: IParams) => boolean): IDisposable;
}
+4
View File
@@ -63,3 +63,7 @@ export class EventEmitter<T, U = void> implements IEventEmitter<T, U> {
this._disposed = true;
}
}
export function forwardEvent<T>(from: IEvent<T>, to: IEventEmitter<T>): IDisposable {
return from(e => to.fire(e));
}
File diff suppressed because it is too large Load Diff
@@ -4,7 +4,7 @@
* @license MIT
*/
import { IInputHandler, IInputHandlingTerminal } from './Types';
import { IInputHandler, IAttributeData, IDisposable, IWindowOptions } from 'common/Types';
import { C0, C1 } from 'common/data/EscapeSequences';
import { CHARSETS, DEFAULT_CHARSET } from 'common/data/Charsets';
import { EscapeSequenceParser } from 'common/parser/EscapeSequenceParser';
@@ -17,11 +17,9 @@ import { IParsingState, IDcsHandler, IEscapeSequenceParser, IParams, IFunctionId
import { NULL_CELL_CODE, NULL_CELL_WIDTH, Attributes, FgFlags, BgFlags, Content } from 'common/buffer/Constants';
import { CellData } from 'common/buffer/CellData';
import { AttributeData } from 'common/buffer/AttributeData';
import { IAttributeData, IDisposable, IWindowOptions } from 'common/Types';
import { ICoreService, IBufferService, IOptionsService, ILogService, IDirtyRowService, ICoreMouseService, ICharsetService, IUnicodeService, IInstantiationService } from 'common/services/Services';
import { ICoreService, IBufferService, IOptionsService, ILogService, IDirtyRowService, ICoreMouseService, ICharsetService, IUnicodeService } from 'common/services/Services';
import { OscHandler } from 'common/parser/OscParser';
import { DcsHandler } from 'common/parser/DcsParser';
import { IRenderService } from 'browser/services/Services';
/**
* Map collect to glevel. Used in `selectCharset`.
@@ -94,7 +92,10 @@ function paramToWindowOption(n: number, opts: IWindowOptions): boolean {
return false;
}
export enum WindowsOptionsReportType {
GET_WIN_SIZE_PIXELS = 0,
GET_CELL_SIZE_PIXELS = 1
}
/**
* DCS subparser implementations
@@ -218,27 +219,39 @@ export class InputHandler extends Disposable implements IInputHandler {
private _workCell: CellData = new CellData();
private _windowTitle = '';
private _iconName = '';
private _windowTitleStack: string[] = [];
private _iconNameStack: string[] = [];
protected _windowTitleStack: string[] = [];
protected _iconNameStack: string[] = [];
private _curAttrData: IAttributeData = DEFAULT_ATTR_DATA.clone();
private _eraseAttrDataInternal: IAttributeData = DEFAULT_ATTR_DATA.clone();
private _onRequestBell = new EventEmitter<void>();
public get onRequestBell(): IEvent<void> { return this._onRequestBell.event; }
private _onRequestRefreshRows = new EventEmitter<number, number>();
public get onRequestRefreshRows(): IEvent<number, number> { return this._onRequestRefreshRows.event; }
private _onRequestReset = new EventEmitter<void>();
public get onRequestReset(): IEvent<void> { return this._onRequestReset.event; }
private _onRequestBell = new EventEmitter<void>();
public get onRequestBell(): IEvent<void> { return this._onRequestBell.event; }
private _onRequestScroll = new EventEmitter<IAttributeData, boolean | void>();
public get onRequestScroll(): IEvent<IAttributeData, boolean | void> { return this._onRequestScroll.event; }
private _onRequestSyncScrollBar = new EventEmitter<void>();
public get onRequestSyncScrollBar(): IEvent<void> { return this._onRequestSyncScrollBar.event; }
private _onRequestWindowsOptionsReport = new EventEmitter<WindowsOptionsReportType>();
public get onRequestWindowsOptionsReport(): IEvent<WindowsOptionsReportType> { return this._onRequestWindowsOptionsReport.event; }
private _onA11yChar = new EventEmitter<string>();
public get onA11yChar(): IEvent<string> { return this._onA11yChar.event; }
private _onA11yTab = new EventEmitter<number>();
public get onA11yTab(): IEvent<number> { return this._onA11yTab.event; }
private _onCursorMove = new EventEmitter<void>();
public get onCursorMove(): IEvent<void> { return this._onCursorMove.event; }
private _onLineFeed = new EventEmitter<void>();
public get onLineFeed(): IEvent<void> { return this._onLineFeed.event; }
private _onScroll = new EventEmitter<number>();
public get onScroll(): IEvent<number> { return this._onScroll.event; }
private _onTitleChange = new EventEmitter<string>();
public get onTitleChange(): IEvent<string> { return this._onTitleChange.event; }
constructor(
private _terminal: IInputHandlingTerminal,
private readonly _bufferService: IBufferService,
private readonly _charsetService: ICharsetService,
private readonly _coreService: ICoreService,
@@ -247,9 +260,8 @@ export class InputHandler extends Disposable implements IInputHandler {
private readonly _optionsService: IOptionsService,
private readonly _coreMouseService: ICoreMouseService,
private readonly _unicodeService: IUnicodeService,
private readonly _instantiationService: IInstantiationService,
private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser())
{
private readonly _parser: IEscapeSequenceParser = new EscapeSequenceParser()
) {
super();
this.register(this._parser);
@@ -489,9 +501,9 @@ export class InputHandler extends Disposable implements IInputHandler {
const screenReaderMode = this._optionsService.options.screenReaderMode;
const cols = this._bufferService.cols;
const wraparoundMode = this._coreService.decPrivateModes.wraparound;
const insertMode = this._terminal.insertMode;
const insertMode = this._coreService.modes.insertMode;
const curAttr = this._curAttrData;
let bufferRow = buffer.lines.get(buffer.ybase + buffer.y);
let bufferRow = buffer.lines.get(buffer.ybase + buffer.y)!;
this._dirtyRowService.markDirty(buffer.y);
@@ -518,7 +530,7 @@ export class InputHandler extends Disposable implements IInputHandler {
}
if (screenReaderMode) {
this._terminal.onA11yCharEmitter.fire(stringFromCodePoint(code));
this._onA11yChar.fire(stringFromCodePoint(code));
}
// insert combining char at last cursor position
@@ -548,17 +560,17 @@ export class InputHandler extends Disposable implements IInputHandler {
buffer.y++;
if (buffer.y === buffer.scrollBottom + 1) {
buffer.y--;
this._terminal.scroll(this._eraseAttrData(), true);
this._onRequestScroll.fire(this._eraseAttrData(), true);
} else {
if (buffer.y >= this._bufferService.rows) {
buffer.y = this._bufferService.rows - 1;
}
// The line already exists (eg. the initial viewport), mark it as a
// wrapped line
buffer.lines.get(buffer.ybase + buffer.y).isWrapped = true;
buffer.lines.get(buffer.ybase + buffer.y)!.isWrapped = true;
}
// row changed, get it again
bufferRow = buffer.lines.get(buffer.ybase + buffer.y);
bufferRow = buffer.lines.get(buffer.ybase + buffer.y)!;
} else {
buffer.x = cols - 1;
if (chWidth === 2) {
@@ -687,7 +699,7 @@ export class InputHandler extends Disposable implements IInputHandler {
buffer.y++;
if (buffer.y === buffer.scrollBottom + 1) {
buffer.y--;
this._terminal.scroll(this._eraseAttrData());
this._onRequestScroll.fire(this._eraseAttrData());
} else if (buffer.y >= this._bufferService.rows) {
buffer.y = this._bufferService.rows - 1;
}
@@ -736,7 +748,7 @@ export class InputHandler extends Disposable implements IInputHandler {
const originalX = this._bufferService.buffer.x;
this._bufferService.buffer.x = this._bufferService.buffer.nextStop();
if (this._optionsService.options.screenReaderMode) {
this._terminal.onA11yTabEmitter.fire(this._bufferService.buffer.x - originalX);
this._onA11yTab.fire(this._bufferService.buffer.x - originalX);
}
}
@@ -1024,7 +1036,7 @@ export class InputHandler extends Disposable implements IInputHandler {
* @param end end - 1 is last erased cell
*/
private _eraseInBufferLine(y: number, start: number, end: number, clearWrap: boolean = false): void {
const line = this._bufferService.buffer.lines.get(this._bufferService.buffer.ybase + y);
const line = this._bufferService.buffer.lines.get(this._bufferService.buffer.ybase + y)!;
line.replaceCells(
start,
end,
@@ -1042,7 +1054,7 @@ export class InputHandler extends Disposable implements IInputHandler {
* @param y row index
*/
private _resetBufferLine(y: number): void {
const line = this._bufferService.buffer.lines.get(this._bufferService.buffer.ybase + y);
const line = this._bufferService.buffer.lines.get(this._bufferService.buffer.ybase + y)!;
line.fill(this._bufferService.buffer.getNullCell(this._eraseAttrData()));
line.isWrapped = false;
}
@@ -1091,7 +1103,7 @@ export class InputHandler extends Disposable implements IInputHandler {
this._eraseInBufferLine(j, 0, this._bufferService.buffer.x + 1, true);
if (this._bufferService.buffer.x + 1 >= this._bufferService.cols) {
// Deleted entire previous line. This next line can no longer be wrapped.
this._bufferService.buffer.lines.get(j + 1).isWrapped = false;
this._bufferService.buffer.lines.get(j + 1)!.isWrapped = false;
}
while (j--) {
this._resetBufferLine(j);
@@ -1343,7 +1355,7 @@ export class InputHandler extends Disposable implements IInputHandler {
}
const param = params.params[0] || 1;
for (let y = buffer.scrollTop; y <= buffer.scrollBottom; ++y) {
const line = buffer.lines.get(buffer.ybase + y);
const line = buffer.lines.get(buffer.ybase + y)!;
line.deleteCells(0, param, buffer.getNullCell(this._eraseAttrData()), this._eraseAttrData());
line.isWrapped = false;
}
@@ -1376,7 +1388,7 @@ export class InputHandler extends Disposable implements IInputHandler {
}
const param = params.params[0] || 1;
for (let y = buffer.scrollTop; y <= buffer.scrollBottom; ++y) {
const line = buffer.lines.get(buffer.ybase + y);
const line = buffer.lines.get(buffer.ybase + y)!;
line.insertCells(0, param, buffer.getNullCell(this._eraseAttrData()), this._eraseAttrData());
line.isWrapped = false;
}
@@ -1399,7 +1411,7 @@ export class InputHandler extends Disposable implements IInputHandler {
}
const param = params.params[0] || 1;
for (let y = buffer.scrollTop; y <= buffer.scrollBottom; ++y) {
const line = this._bufferService.buffer.lines.get(buffer.ybase + y);
const line = this._bufferService.buffer.lines.get(buffer.ybase + y)!;
line.insertCells(buffer.x, param, buffer.getNullCell(this._eraseAttrData()), this._eraseAttrData());
line.isWrapped = false;
}
@@ -1422,7 +1434,7 @@ export class InputHandler extends Disposable implements IInputHandler {
}
const param = params.params[0] || 1;
for (let y = buffer.scrollTop; y <= buffer.scrollBottom; ++y) {
const line = buffer.lines.get(buffer.ybase + y);
const line = buffer.lines.get(buffer.ybase + y)!;
line.deleteCells(buffer.x, param, buffer.getNullCell(this._eraseAttrData()), this._eraseAttrData());
line.isWrapped = false;
}
@@ -1520,9 +1532,9 @@ export class InputHandler extends Disposable implements IInputHandler {
if (params.params[0] > 0) {
return;
}
if (this._terminal.is('xterm') || this._terminal.is('rxvt-unicode') || this._terminal.is('screen')) {
if (this._is('xterm') || this._is('rxvt-unicode') || this._is('screen')) {
this._coreService.triggerDataEvent(C0.ESC + '[?1;2c');
} else if (this._terminal.is('linux')) {
} else if (this._is('linux')) {
this._coreService.triggerDataEvent(C0.ESC + '[?6c');
}
}
@@ -1558,19 +1570,27 @@ export class InputHandler extends Disposable implements IInputHandler {
// xterm and urxvt
// seem to spit this
// out around ~370 times (?).
if (this._terminal.is('xterm')) {
if (this._is('xterm')) {
this._coreService.triggerDataEvent(C0.ESC + '[>0;276;0c');
} else if (this._terminal.is('rxvt-unicode')) {
} else if (this._is('rxvt-unicode')) {
this._coreService.triggerDataEvent(C0.ESC + '[>85;95;0c');
} else if (this._terminal.is('linux')) {
} else if (this._is('linux')) {
// not supported by linux console.
// linux console echoes parameters.
this._coreService.triggerDataEvent(params.params[0] + 'c');
} else if (this._terminal.is('screen')) {
} else if (this._is('screen')) {
this._coreService.triggerDataEvent(C0.ESC + '[>83;40003;0c');
}
}
/**
* Evaluate if the current terminal is the given argument.
* @param term The terminal name to evaluate
*/
private _is(term: string): boolean {
return (this._optionsService.options.termName + '').indexOf(term) === 0;
}
/**
* CSI Pm h Set Mode (SM).
* Ps = 2 -> Keyboard Action Mode (AM).
@@ -1587,15 +1607,12 @@ export class InputHandler extends Disposable implements IInputHandler {
* | 4 | Insert Mode (IRM). | #Y |
* | 12 | Send/receive (SRM). Always off. | #N |
* | 20 | Automatic Newline (LNM). Always off. | #N |
*
*
* FIXME: why is LNM commented out?
*/
public setMode(params: IParams): void {
for (let i = 0; i < params.length; i++) {
switch (params.params[i]) {
case 4:
this._terminal.insertMode = true;
this._coreService.modes.insertMode = true;
break;
case 20:
// this._t.convertEol = true;
@@ -1736,7 +1753,7 @@ export class InputHandler extends Disposable implements IInputHandler {
* through `options.windowsOptions`.
*/
if (this._optionsService.options.windowOptions.setWinLines) {
this._terminal.resize(132, this._bufferService.rows);
this._bufferService.resize(132, this._bufferService.rows);
this._onRequestReset.fire();
}
break;
@@ -1753,7 +1770,7 @@ export class InputHandler extends Disposable implements IInputHandler {
case 66:
this._logService.debug('Serial port requested application keypad.');
this._coreService.decPrivateModes.applicationKeypad = true;
this._terminal.viewport?.syncScrollArea();
this._onRequestSyncScrollBar.fire();
break;
case 9: // X10 Mouse
// no release, no motion, no wheel, no modifiers.
@@ -1774,7 +1791,7 @@ export class InputHandler extends Disposable implements IInputHandler {
case 1004: // send focusin/focusout events
// focusin: ^[[I
// focusout: ^[[O
this._terminal.sendFocus = true;
this._coreService.decPrivateModes.sendFocus = true;
break;
case 1005: // utf8 ext mode mouse - removed in #2507
this._logService.debug('DECSET 1005 not supported (see #2507)');
@@ -1797,12 +1814,12 @@ export class InputHandler extends Disposable implements IInputHandler {
case 47: // alt screen buffer
case 1047: // alt screen buffer
this._bufferService.buffers.activateAltBuffer(this._eraseAttrData());
this._coreService.isCursorInitialized = true;
this._onRequestRefreshRows.fire(0, this._bufferService.rows - 1);
this._terminal.viewport?.syncScrollArea();
this._terminal.showCursor();
this._onRequestSyncScrollBar.fire();
break;
case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)
this._terminal.bracketedPasteMode = true;
this._coreService.decPrivateModes.bracketedPasteMode = true;
break;
}
}
@@ -1833,7 +1850,7 @@ export class InputHandler extends Disposable implements IInputHandler {
for (let i = 0; i < params.length; i++) {
switch (params.params[i]) {
case 4:
this._terminal.insertMode = false;
this._coreService.modes.insertMode = false;
break;
case 20:
// this._t.convertEol = false;
@@ -1963,7 +1980,7 @@ export class InputHandler extends Disposable implements IInputHandler {
* through `options.windowsOptions`.
*/
if (this._optionsService.options.windowOptions.setWinLines) {
this._terminal.resize(80, this._bufferService.rows);
this._bufferService.resize(80, this._bufferService.rows);
this._onRequestReset.fire();
}
break;
@@ -1980,7 +1997,7 @@ export class InputHandler extends Disposable implements IInputHandler {
case 66:
this._logService.debug('Switching back to normal keypad.');
this._coreService.decPrivateModes.applicationKeypad = false;
this._terminal.viewport?.syncScrollArea();
this._onRequestSyncScrollBar.fire();
break;
case 9: // X10 Mouse
case 1000: // vt200 mouse
@@ -1989,7 +2006,7 @@ export class InputHandler extends Disposable implements IInputHandler {
this._coreMouseService.activeProtocol = 'NONE';
break;
case 1004: // send focusin/focusout events
this._terminal.sendFocus = false;
this._coreService.decPrivateModes.sendFocus = false;
break;
case 1005: // utf8 ext mode mouse - removed in #2507
this._logService.debug('DECRST 1005 not supported (see #2507)');
@@ -2015,12 +2032,12 @@ export class InputHandler extends Disposable implements IInputHandler {
if (params.params[i] === 1049) {
this.restoreCursor();
}
this._coreService.isCursorInitialized = true;
this._onRequestRefreshRows.fire(0, this._bufferService.rows - 1);
this._terminal.viewport?.syncScrollArea();
this._terminal.showCursor();
this._onRequestSyncScrollBar.fire();
break;
case 2004: // bracketed paste mode (https://cirw.in/blog/bracketed-paste)
this._terminal.bracketedPasteMode = false;
this._coreService.decPrivateModes.bracketedPasteMode = false;
break;
}
}
@@ -2046,7 +2063,7 @@ export class InputHandler extends Disposable implements IInputHandler {
do {
accu[advance + cSpace] = params.params[pos + advance];
if (params.hasSubParams(pos + advance)) {
const subparams = params.getSubParams(pos + advance);
const subparams = params.getSubParams(pos + advance)!;
let i = 0;
do {
if (accu[1] === 5) {
@@ -2356,8 +2373,7 @@ export class InputHandler extends Disposable implements IInputHandler {
*/
public softReset(params: IParams): void {
this._coreService.isCursorHidden = false;
this._terminal.insertMode = false;
this._terminal.viewport?.syncScrollArea();
this._onRequestSyncScrollBar.fire();
this._bufferService.buffer.scrollTop = 0;
this._bufferService.buffer.scrollBottom = this._bufferService.rows - 1;
this._curAttrData = DEFAULT_ATTR_DATA.clone();
@@ -2471,22 +2487,14 @@ export class InputHandler extends Disposable implements IInputHandler {
return;
}
const second = (params.length > 1) ? params.params[1] : 0;
const rs = this._instantiationService.getService(IRenderService);
switch (params.params[0]) {
case 14: // GetWinSizePixels, returns CSI 4 ; height ; width t
if (rs && second !== 2) {
console.log(rs.dimensions);
const w = rs.dimensions.scaledCanvasWidth.toFixed(0);
const h = rs.dimensions.scaledCanvasHeight.toFixed(0);
this._coreService.triggerDataEvent(`${C0.ESC}[4;${h};${w}t`);
if (second !== 2) {
this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_WIN_SIZE_PIXELS);
}
break;
case 16: // GetCellSizePixels, returns CSI 6 ; height ; width t
if (rs) {
const w = rs.dimensions.scaledCellWidth.toFixed(0);
const h = rs.dimensions.scaledCellHeight.toFixed(0);
this._coreService.triggerDataEvent(`${C0.ESC}[6;${h};${w}t`);
}
this._onRequestWindowsOptionsReport.fire(WindowsOptionsReportType.GET_CELL_SIZE_PIXELS);
break;
case 18: // GetWinSizeChars, returns CSI 8 ; height ; width t
if (this._bufferService) {
@@ -2510,12 +2518,12 @@ export class InputHandler extends Disposable implements IInputHandler {
case 23: // PopTitle
if (second === 0 || second === 2) {
if (this._windowTitleStack.length) {
this.setTitle(this._windowTitleStack.pop());
this.setTitle(this._windowTitleStack.pop()!);
}
}
if (second === 0 || second === 1) {
if (this._iconNameStack.length) {
this.setIconName(this._iconNameStack.pop());
this.setIconName(this._iconNameStack.pop()!);
}
}
break;
@@ -2573,7 +2581,7 @@ export class InputHandler extends Disposable implements IInputHandler {
*/
public setTitle(data: string): void {
this._windowTitle = data;
this._terminal.handleTitle(data);
this._onTitleChange.fire(data);
}
/**
@@ -2606,7 +2614,7 @@ export class InputHandler extends Disposable implements IInputHandler {
public keypadApplicationMode(): void {
this._logService.debug('Serial port requested application keypad.');
this._coreService.decPrivateModes.applicationKeypad = true;
this._terminal.viewport?.syncScrollArea();
this._onRequestSyncScrollBar.fire();
}
/**
@@ -2617,7 +2625,7 @@ export class InputHandler extends Disposable implements IInputHandler {
public keypadNumericMode(): void {
this._logService.debug('Switching back to normal keypad.');
this._coreService.decPrivateModes.applicationKeypad = false;
this._terminal.viewport?.syncScrollArea();
this._onRequestSyncScrollBar.fire();
}
/**
@@ -2674,7 +2682,7 @@ export class InputHandler extends Disposable implements IInputHandler {
this._bufferService.buffer.y++;
if (buffer.y === buffer.scrollBottom + 1) {
buffer.y--;
this._terminal.scroll(this._eraseAttrData());
this._onRequestScroll.fire(this._eraseAttrData());
} else if (buffer.y >= this._bufferService.rows) {
buffer.y = this._bufferService.rows - 1;
}
@@ -2779,8 +2787,11 @@ export class InputHandler extends Disposable implements IInputHandler {
this._setCursor(0, 0);
for (let yOffset = 0; yOffset < this._bufferService.rows; ++yOffset) {
const row = buffer.ybase + buffer.y + yOffset;
buffer.lines.get(row).fill(cell);
buffer.lines.get(row).isWrapped = false;
const line = buffer.lines.get(row);
if (line) {
line.fill(cell);
line.isWrapped = false;
}
}
this._dirtyRowService.markAllDirty();
this._setCursor(0, 0);

Some files were not shown because too many files have changed in this diff Show More