Support selecting wide characters
This commit is contained in:
+2
-1
@@ -75,8 +75,9 @@ export class InputHandler implements IInputHandler {
|
|||||||
const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();
|
const removed = this._terminal.lines.get(this._terminal.y + this._terminal.ybase).pop();
|
||||||
if (removed[2] === 0
|
if (removed[2] === 0
|
||||||
&& this._terminal.lines.get(row)[this._terminal.cols - 2]
|
&& this._terminal.lines.get(row)[this._terminal.cols - 2]
|
||||||
&& this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2)
|
&& this._terminal.lines.get(row)[this._terminal.cols - 2][2] === 2) {
|
||||||
this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];
|
this._terminal.lines.get(row)[this._terminal.cols - 2] = [this._terminal.curAttr, ' ', 1];
|
||||||
|
}
|
||||||
|
|
||||||
// insert empty cell at cursor
|
// insert empty cell at cursor
|
||||||
this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);
|
this._terminal.lines.get(row).splice(this._terminal.x, 0, [this._terminal.curAttr, ' ', 1]);
|
||||||
|
|||||||
+38
-11
@@ -31,6 +31,10 @@ const DRAG_SCROLL_INTERVAL = 100;
|
|||||||
*/
|
*/
|
||||||
const CLEAR_MOUSE_DOWN_TIME = 400;
|
const CLEAR_MOUSE_DOWN_TIME = 400;
|
||||||
|
|
||||||
|
// TODO: Move these constants elsewhere
|
||||||
|
const LINE_DATA_CHAR_INDEX = 1;
|
||||||
|
const LINE_DATA_WIDTH_INDEX = 2;
|
||||||
|
|
||||||
export class SelectionManager extends EventEmitter {
|
export class SelectionManager extends EventEmitter {
|
||||||
private _model: SelectionModel;
|
private _model: SelectionModel;
|
||||||
|
|
||||||
@@ -124,32 +128,45 @@ export class SelectionManager extends EventEmitter {
|
|||||||
if (start[1] !== end[1]) {
|
if (start[1] !== end[1]) {
|
||||||
result.push(this._translateBufferLineToString(this._buffer.get(end[1]), true, 0, end[0]));
|
result.push(this._translateBufferLineToString(this._buffer.get(end[1]), true, 0, end[0]));
|
||||||
}
|
}
|
||||||
console.log('selectionText result: ' + result);
|
console.log('selectionText result: "' + result + '"');
|
||||||
return result.join('\n');
|
return result.join('\n');
|
||||||
}
|
}
|
||||||
|
|
||||||
private _translateBufferLineToString(line: any, trimRight: boolean, startCol: number = 0, endCol: number = null): string {
|
private _translateBufferLineToString(line: any, trimRight: boolean, startCol: number = 0, endCol: number = null): string {
|
||||||
// TODO: This function should live in a buffer or buffer line class
|
// TODO: This function should live in a buffer or buffer line class
|
||||||
// TODO: Handle the double-width character case
|
|
||||||
|
|
||||||
// Get full line
|
// Get full line
|
||||||
let lineString = '';
|
let lineString = '';
|
||||||
|
let widthAdjustedStartCol = startCol;
|
||||||
|
let widthAdjustedEndCol = endCol;
|
||||||
for (let i = 0; i < line.length; i++) {
|
for (let i = 0; i < line.length; i++) {
|
||||||
lineString += line[i][1];
|
const char = line[i];
|
||||||
|
lineString += char[LINE_DATA_CHAR_INDEX];
|
||||||
|
// Adjust start and end cols for wide characters if they affect their
|
||||||
|
// column indexes
|
||||||
|
if (char[LINE_DATA_WIDTH_INDEX] === 0) {
|
||||||
|
if (startCol >= i) {
|
||||||
|
widthAdjustedStartCol--;
|
||||||
|
}
|
||||||
|
if (endCol >= i) {
|
||||||
|
widthAdjustedEndCol--;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
let finalEndCol = endCol || line.length
|
// Calculate the final end col by trimming whitespace on the right of the
|
||||||
|
// line if needed.
|
||||||
|
let finalEndCol = widthAdjustedEndCol || line.length
|
||||||
if (trimRight) {
|
if (trimRight) {
|
||||||
const rightWhitespaceIndex = lineString.search(/\s+$/);
|
const rightWhitespaceIndex = lineString.search(/\s+$/);
|
||||||
finalEndCol = Math.min(finalEndCol, rightWhitespaceIndex);
|
finalEndCol = Math.min(finalEndCol, rightWhitespaceIndex);
|
||||||
// Return the empty string if only trimmed whitespace is selected
|
// Return the empty string if only trimmed whitespace is selected
|
||||||
if (finalEndCol <= startCol) {
|
if (finalEndCol <= widthAdjustedStartCol) {
|
||||||
return '';
|
return '';
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return lineString.substring(startCol, finalEndCol);
|
return lineString.substring(widthAdjustedStartCol, finalEndCol);
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@@ -241,6 +258,12 @@ export class SelectionManager extends EventEmitter {
|
|||||||
this._model.selectionStart = this._getMouseBufferCoords(event);
|
this._model.selectionStart = this._getMouseBufferCoords(event);
|
||||||
if (this._model.selectionStart) {
|
if (this._model.selectionStart) {
|
||||||
this._model.selectionEnd = null;
|
this._model.selectionEnd = null;
|
||||||
|
// If the mouse is over the second half of a wide character, adjust the
|
||||||
|
// selection to cover the whole character
|
||||||
|
const char = this._buffer.get(this._model.selectionStart[1])[this._model.selectionStart[0]];
|
||||||
|
if (char[LINE_DATA_WIDTH_INDEX] === 0) {
|
||||||
|
this._model.selectionStart[0]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -285,12 +308,16 @@ export class SelectionManager extends EventEmitter {
|
|||||||
} else if (this._dragScrollAmount < 0) {
|
} else if (this._dragScrollAmount < 0) {
|
||||||
this._model.selectionEnd[0] = 0;
|
this._model.selectionEnd[0] = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// If the character is a wide character include the cell to the right in the
|
||||||
|
// selection.
|
||||||
|
const char = this._buffer.get(this._model.selectionEnd[1])[this._model.selectionEnd[0] - 1];
|
||||||
|
if (char[2] === 2) {
|
||||||
|
this._model.selectionEnd[0]++;
|
||||||
|
}
|
||||||
|
|
||||||
// TODO: Only draw here if the selection changes
|
// TODO: Only draw here if the selection changes
|
||||||
this.refresh();
|
this.refresh();
|
||||||
console.log('start: ', this._model.selectionStart);
|
|
||||||
console.log('start final: ', this._model.finalSelectionStart);
|
|
||||||
console.log('end: ', this._model.selectionEnd);
|
|
||||||
console.log('end final: ', this._model.finalSelectionEnd);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private _dragScroll() {
|
private _dragScroll() {
|
||||||
|
|||||||
Reference in New Issue
Block a user