diff --git a/src/Interfaces.ts b/src/Interfaces.ts index 2f2bef73..4b857674 100644 --- a/src/Interfaces.ts +++ b/src/Interfaces.ts @@ -49,6 +49,10 @@ export interface ITerminal { emit(event: string, data: any); } +export interface ISelectionManager { + selectionText: string; +} + export interface ICharMeasure { width: number; height: number; diff --git a/src/SelectionManager.ts b/src/SelectionManager.ts index 6b8a1dd6..a8724050 100644 --- a/src/SelectionManager.ts +++ b/src/SelectionManager.ts @@ -38,7 +38,30 @@ export class SelectionManager extends EventEmitter { if (!this._selectionStart || !this._selectionEnd) { return null; } - return ''; + // TODO: Handle first row start position properly + const startRowEndCol = this._selectionStart[1] === this._selectionEnd[1] ? this._selectionEnd[0] : null; + let result: string[] = []; + result.push(this._translateBufferLineToString(this._buffer.get(this._selectionStart[1]), this._selectionStart[0], startRowEndCol)); + for (let i = this._selectionStart[1] + 1; i <= this._selectionEnd[1] - 1; i++) { + result.push(this._translateBufferLineToString(this._buffer.get(i))); + } + if (this._selectionStart[1] !== this._selectionEnd[1]) { + result.push(this._translateBufferLineToString(this._buffer.get(this._selectionEnd[1]), 0, this._selectionEnd[1])); + } + console.log('result: ' + result); + return result.join('\n'); + } + + private _translateBufferLineToString(line: any, startCol: number = 0, endCol: number = null): string { + // TODO: This function should live in a buffer or buffer line class + endCol = endCol || line.length + let result = ''; + for (let i = startCol; i < endCol; i++) { + result += line[i][1]; + } + // TODO: Trim line? + return result; + // TODO: Handle the double-width character case } /** @@ -56,7 +79,7 @@ export class SelectionManager extends EventEmitter { private _onTrim(amount: number) { // TODO: Somehow map the selection coordinates with the list that is constantly being trimmed // Maybe we need an ID in the CircularList that starts from 0 for the first entry and increments - console.log('trimmed: ' + amount); + // console.log('trimmed: ' + amount); // Adjust the selection position based on the trimmed amount. this._selectionStart[0] -= amount; @@ -74,12 +97,10 @@ export class SelectionManager extends EventEmitter { if (this._selectionStart[0] < 0) { this._selectionStart[1] = 0; } - - // Maybe SelectionManager could maintain it's own ID concept from 0 (top of - // buffer) to n (size of buffer). On trim just increment the selection if - // necessary. This would reduce complexity and potentially not need the } + // TODO: Handle splice/shiftElements in the buffer (just clear the selection?) + private _getMouseBufferCoords(event: MouseEvent) { const coords = Mouse.getCoords(event, this._rowContainer, this._charMeasure); // Convert to 0-based @@ -106,9 +127,9 @@ export class SelectionManager extends EventEmitter { } private _onMouseUp(event: MouseEvent) { - console.log('mouseup'); - console.log('start', this._selectionStart); - console.log('end', this._selectionEnd); + // console.log('mouseup'); + // console.log('start', this._selectionStart); + // console.log('end', this._selectionEnd); if (!this._selectionStart) { return; } diff --git a/src/handlers/Clipboard.ts b/src/handlers/Clipboard.ts index 719bf2c8..2d1f5bc2 100644 --- a/src/handlers/Clipboard.ts +++ b/src/handlers/Clipboard.ts @@ -5,7 +5,7 @@ * @license MIT */ -import { ITerminal } from '../Interfaces'; +import { ITerminal, ISelectionManager } from '../Interfaces'; interface IWindow extends Window { clipboardData?: { @@ -53,11 +53,10 @@ export function prepareTextForTerminal(text: string, isMSWindows: boolean): stri * Binds copy functionality to the given terminal. * @param {ClipboardEvent} ev The original copy event to be handled */ -export function copyHandler(ev: ClipboardEvent, term: ITerminal) { +export function copyHandler(ev: ClipboardEvent, term: ITerminal, selectionManager: ISelectionManager) { // We cast `window` to `any` type, because TypeScript has not declared the `clipboardData` // property that we use below for Internet Explorer. - let copiedText = window.getSelection().toString(), - text = prepareTextForClipboard(copiedText); + let text = prepareTextForClipboard(selectionManager.selectionText); if (term.browser.isMSIE) { window.clipboardData.setData('Text', text); diff --git a/src/xterm.js b/src/xterm.js index 1749e158..f3b278f1 100644 --- a/src/xterm.js +++ b/src/xterm.js @@ -521,7 +521,7 @@ Terminal.prototype.initGlobal = function() { // Bind clipboard functionality on(this.element, 'copy', function (ev) { - copyHandler.call(this, ev, term); + copyHandler.call(this, ev, term, term.selectionManager); }); on(this.textarea, 'paste', function (ev) { pasteHandler.call(this, ev, term);