Initial marker API implementation

Part of #1325
This commit is contained in:
Daniel Imms
2018-03-16 12:53:55 -07:00
parent 888070830d
commit b80832ac4c
5 changed files with 130 additions and 2 deletions
+49
View File
@@ -5,6 +5,8 @@
import { CircularList } from './utils/CircularList';
import { LineData, CharData, ITerminal, IBuffer } from './Types';
import { EventEmitter } from './EventEmitter';
import { IDisposable, IMarker } from 'xterm';
export const CHAR_DATA_ATTR_INDEX = 0;
export const CHAR_DATA_CHAR_INDEX = 1;
@@ -31,6 +33,7 @@ export class Buffer implements IBuffer {
public tabs: any;
public savedY: number;
public savedX: number;
public markers: Marker[] = [];
/**
* Create a new Buffer.
@@ -303,4 +306,50 @@ export class Buffer implements IBuffer {
while (!this.tabs[++x] && x < this._terminal.cols);
return x >= this._terminal.cols ? this._terminal.cols - 1 : x < 0 ? 0 : x;
}
public addMarker(y: number): Marker {
const marker = new Marker(y);
this.markers.push(marker);
marker.disposables.push(this._lines.addDisposableListener('trim', amount => {
marker.line -= amount;
// The marker should be disposed when the line is trimmed from the buffer
if (marker.line < 0) {
marker.dispose();
}
// TODO: handle splice?
}));
marker.on('dispose', () => this._removeMarker(marker));
return marker;
}
private _removeMarker(marker: Marker): void {
// TODO: This could probably be optimized by relying on sort order and trimming the array using .length
this.markers = this.markers.splice(this.markers.indexOf(marker), 1);
}
}
export class Marker extends EventEmitter implements IMarker {
private static NEXT_ID = 1;
private _id: number = Marker.NEXT_ID++;
public isDisposed: boolean = false;
public disposables: IDisposable[] = [];
public get id(): number { return this._id; }
constructor(
public line: number
) {
super();
}
public dispose(): void {
if (this.isDisposed) {
return;
}
this.isDisposed = true;
this.disposables.forEach(d => d.dispose());
this.disposables.length = 0;
this.emit('dispose');
}
}
+10
View File
@@ -292,6 +292,16 @@ export class SelectionManager extends EventEmitter implements ISelectionManager
this._terminal.emit('selection');
}
public selectLines(start: number, end: number): void {
this._model.clearSelection();
start = Math.max(start, 0);
end = Math.min(end, this._terminal.buffer.lines.length - 1);
this._model.selectionStart = [0, start];
this._model.selectionEnd = [this._terminal.cols, end];
this.refresh();
this._terminal.emit('selection');
}
/**
* Handle the buffer being trimmed, adjust the selection position.
* @param amount The amount the buffer is being trimmed.
+28 -1
View File
@@ -45,7 +45,7 @@ import { DEFAULT_ANSI_COLORS } from './renderer/ColorManager';
import { MouseZoneManager } from './input/MouseZoneManager';
import { AccessibilityManager } from './AccessibilityManager';
import { ScreenDprMonitor } from './utils/ScreenDprMonitor';
import { ITheme, ILocalizableStrings } from 'xterm';
import { ITheme, ILocalizableStrings, IMarker } from 'xterm';
// reg + shift key mappings for digits and special chars
const KEYCODE_KEY_MAPPINGS = {
@@ -1241,6 +1241,14 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
this.scrollLines(this.buffer.ybase - this.buffer.ydisp);
}
public scrollToLine(line: number): void {
const scrollAmount = line - this.buffer.ydisp;
console.log('scrollAmount', scrollAmount);
if (scrollAmount !== 0) {
this.scrollLines(scrollAmount);
}
}
/**
* Writes text to the terminal.
* @param {string} data The text to write to the terminal.
@@ -1349,6 +1357,19 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
}
}
public get markers(): IMarker[] {
return this.buffer.markers;
}
public addMarker(cursorYOffset: number): IMarker {
// Disallow markers on the alt buffer
if (this.buffer !== this.buffers.normal) {
return;
}
return this.buffer.addMarker(this.buffer.ybase + this.buffer.y + cursorYOffset);
}
/**
* Gets whether the terminal has an active selection.
*/
@@ -1382,6 +1403,12 @@ export class Terminal extends EventEmitter implements ITerminal, IInputHandlingT
}
}
public selectLines(start: number, end: number): void {
if (this.selectionManager) {
this.selectionManager.selectLines(start, end);
}
}
/**
* Handle a keydown event
* Key Resources:
+11 -1
View File
@@ -7,9 +7,19 @@ import { IColorSet, IRenderer, IRenderDimensions, IColorManager } from '../rende
import { LineData, IInputHandlingTerminal, IViewport, ICompositionHelper, ITerminal, IBuffer, IBufferSet, IBrowser, ICharMeasure, ISelectionManager, ITerminalOptions, ICircularList, ILinkifier, IMouseHelper, ILinkMatcherOptions, XtermListener } from '../Types';
import { Buffer } from '../Buffer';
import * as Browser from '../shared/utils/Browser';
import { ITheme, IDisposable } from 'xterm';
import { ITheme, IDisposable, IMarker } from 'xterm';
export class MockTerminal implements ITerminal {
markers: IMarker[];
addMarker(cursorYOffset: number): IMarker {
throw new Error('Method not implemented.');
}
selectLines(start: number, end: number): void {
throw new Error('Method not implemented.');
}
scrollToLine(line: number): void {
throw new Error('Method not implemented.');
}
static string: any;
getOption(key: any): any {
throw new Error('Method not implemented.');
+32
View File
@@ -235,6 +235,12 @@ declare module 'xterm' {
dispose(): void;
}
export interface IMarker extends IDisposable {
readonly id: number;
readonly isDisposed: boolean;
readonly line: number;
}
export interface ILocalizableStrings {
blankLine: string;
promptLabel: string;
@@ -265,6 +271,12 @@ declare module 'xterm' {
*/
cols: number;
/**
* Get all markers registered against the buffer. If the alt buffer is
* active this will always return [].
*/
markers: IMarker[];
/**
* Natural language strings that can be localized.
*/
@@ -403,6 +415,13 @@ declare module 'xterm' {
*/
deregisterLinkMatcher(matcherId: number): void;
/**
* Adds a marker to the normal buffer and returns it. If the alt buffer is
* active, undefined is returned.
* @param cursorYOffset The y position offset of the marker from the cursor.
*/
addMarker(cursorYOffset: number): IMarker;
/**
* Gets whether the terminal has an active selection.
*/
@@ -424,6 +443,13 @@ declare module 'xterm' {
*/
selectAll(): void;
/**
* Selects text in the buffer between 2 lines.
* @param start The 0-based line index to select from (inclusive).
* @param end The 0-based line index to select to (inclusive).
*/
selectLines(start: number, end: number): void;
/**
* Destroys the terminal and detaches it from the DOM.
*/
@@ -451,6 +477,12 @@ declare module 'xterm' {
*/
scrollToBottom(): void;
/**
* Scrolls to a line within the buffer.
* @param line The 0-based line index to scroll to.
*/
scrollToLine(line: number): void;
/**
* Clear the entire buffer, making the prompt line the new first line.
*/