--- /dev/null
+/**
+ * @license MIT
+ */
+import jsdom = require('jsdom');
+import { assert } from 'chai';
+import { ITerminal } from './Interfaces';
+import { CharMeasure } from './utils/CharMeasure';
+import { CircularList } from './utils/CircularList';
+import { SelectionManager } from './SelectionManager';
+
+class TestSelectionManager extends SelectionManager {
+ constructor(
+ terminal: ITerminal,
+ buffer: CircularList<any>,
+ rowContainer: HTMLElement,
+ charMeasure: CharMeasure
+ ) {
+ super(terminal, buffer, rowContainer, charMeasure);
+ }
+
+ public selectWordAt(coords: [number, number]): void { this._selectWordAt(coords); }
+
+ // Disable DOM interaction
+ public enable(): void {}
+ public disable(): void {}
+ public refresh(): void {}
+}
+
+describe('SelectionManager', () => {
+ let window: Window;
+ let document: Document;
+
+ let buffer: CircularList<any>;
+ let rowContainer: HTMLElement;
+ let selectionManager: TestSelectionManager;
+
+ beforeEach(done => {
+ jsdom.env('', (err, w) => {
+ window = w;
+ document = window.document;
+ buffer = new CircularList<any>(100);
+ selectionManager = new TestSelectionManager(null, buffer, rowContainer, null);
+ done();
+ });
+ });
+
+ function stringToRow(text: string): [number, string, number][] {
+ let result: [number, string, number][] = [];
+ for (let i = 0; i < text.length; i++) {
+ result.push([0, text.charAt(i), 1]);
+ }
+ return result;
+ }
+
+ describe('_selectWordAt', () => {
+ it('should expand selection for normal width chars', () => {
+ buffer.push(stringToRow('foo bar'));
+ selectionManager.selectWordAt([0, 0]);
+ assert.equal(selectionManager.selectionText, 'foo');
+ selectionManager.selectWordAt([1, 0]);
+ assert.equal(selectionManager.selectionText, 'foo');
+ selectionManager.selectWordAt([2, 0]);
+ assert.equal(selectionManager.selectionText, 'foo');
+ selectionManager.selectWordAt([3, 0]);
+ assert.equal(selectionManager.selectionText, ' ');
+ selectionManager.selectWordAt([4, 0]);
+ assert.equal(selectionManager.selectionText, 'bar');
+ selectionManager.selectWordAt([5, 0]);
+ assert.equal(selectionManager.selectionText, 'bar');
+ selectionManager.selectWordAt([6, 0]);
+ assert.equal(selectionManager.selectionText, 'bar');
+ });
+ it('should expand selection for whitespace', () => {
+ buffer.push(stringToRow('a b'));
+ selectionManager.selectWordAt([0, 0]);
+ assert.equal(selectionManager.selectionText, 'a');
+ selectionManager.selectWordAt([1, 0]);
+ assert.equal(selectionManager.selectionText, ' ');
+ selectionManager.selectWordAt([2, 0]);
+ assert.equal(selectionManager.selectionText, ' ');
+ selectionManager.selectWordAt([3, 0]);
+ assert.equal(selectionManager.selectionText, ' ');
+ selectionManager.selectWordAt([4, 0]);
+ assert.equal(selectionManager.selectionText, 'b');
+ });
+ it('should expand selection for wide characters', () => {
+ // Wide characters use a special format
+ buffer.push([
+ [null, '中', 2],
+ [null, '', 0],
+ [null, '文', 2],
+ [null, '', 0],
+ [null, ' ', 1],
+ [null, 'a', 1],
+ [null, '中', 2],
+ [null, '', 0],
+ [null, '文', 2],
+ [null, '', 0],
+ [null, 'b', 1],
+ [null, ' ', 1],
+ [null, 'f', 1],
+ [null, 'o', 1],
+ [null, 'o', 1]
+ ]);
+ // Ensure wide characters take up 2 columns
+ selectionManager.selectWordAt([0, 0]);
+ assert.equal(selectionManager.selectionText, '中文');
+ selectionManager.selectWordAt([1, 0]);
+ assert.equal(selectionManager.selectionText, '中文');
+ selectionManager.selectWordAt([2, 0]);
+ assert.equal(selectionManager.selectionText, '中文');
+ selectionManager.selectWordAt([3, 0]);
+ assert.equal(selectionManager.selectionText, '中文');
+ selectionManager.selectWordAt([4, 0]);
+ assert.equal(selectionManager.selectionText, ' ');
+ // Ensure wide characters work when wrapped in normal width characters
+ selectionManager.selectWordAt([5, 0]);
+ assert.equal(selectionManager.selectionText, 'a中文b');
+ selectionManager.selectWordAt([6, 0]);
+ assert.equal(selectionManager.selectionText, 'a中文b');
+ selectionManager.selectWordAt([7, 0]);
+ assert.equal(selectionManager.selectionText, 'a中文b');
+ selectionManager.selectWordAt([8, 0]);
+ assert.equal(selectionManager.selectionText, 'a中文b');
+ selectionManager.selectWordAt([9, 0]);
+ assert.equal(selectionManager.selectionText, 'a中文b');
+ selectionManager.selectWordAt([10, 0]);
+ assert.equal(selectionManager.selectionText, 'a中文b');
+ selectionManager.selectWordAt([11, 0]);
+ assert.equal(selectionManager.selectionText, ' ');
+ // Ensure normal width characters work fine in a line containing wide characters
+ selectionManager.selectWordAt([12, 0]);
+ assert.equal(selectionManager.selectionText, 'foo');
+ selectionManager.selectWordAt([13, 0]);
+ assert.equal(selectionManager.selectionText, 'foo');
+ selectionManager.selectWordAt([14, 0]);
+ assert.equal(selectionManager.selectionText, 'foo');
+ });
+ });
+});
// Calculate the final end col by trimming whitespace on the right of the
// line if needed.
- let finalEndCol = widthAdjustedEndCol || line.length
+ let finalEndCol = widthAdjustedEndCol || line.length;
if (trimRight) {
const rightWhitespaceIndex = lineString.search(/\s+$/);
if (rightWhitespaceIndex !== -1) {
private _setMouseClickCount(): void {
let currentTime = (new Date()).getTime();
- if (currentTime - this._lastMouseDownTime > CLEAR_MOUSE_DOWN_TIME) {
+ if (currentTime - this._lastMouseDownTime > CLEAR_MOUSE_DOWN_TIME) {
this._clickCount = 0;
- }
- this._lastMouseDownTime = currentTime;
+ }
+ this._lastMouseDownTime = currentTime;
this._clickCount++;
// TODO: Invalidate click count if the position is different
/**
* Converts a viewport column to the character index on the buffer line, the
* latter takes into account wide characters.
- * @param coords The coordinates to find the character index for.
+ * @param coords The coordinates to find the 2 index for.
*/
private _convertViewportColToCharacterIndex(bufferLine: any, coords: [number, number]): number {
let charIndex = coords[0];
startIndex--;
startCol--;
}
- while (endIndex < line.length && line.charAt(endIndex + 1) !== ' ') {
+ while (endIndex + 1 < line.length && line.charAt(endIndex + 1) !== ' ') {
if (bufferLine[endCol + 1][LINE_DATA_WIDTH_INDEX] === 2) {
// If the next character is a wide char, record it and skip the column
rightWideCharCount++;