mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
restrict cursor movements
This commit is contained in:
@@ -546,4 +546,343 @@ describe('InputHandler', () => {
|
||||
assert.deepEqual(AttributeData.toColorRGB(term.curAttrData.getFgColor()), [5, 0, 0]);
|
||||
});
|
||||
});
|
||||
describe('cursor positioning', () => {
|
||||
let term: TestTerminal;
|
||||
beforeEach(() => {
|
||||
term = new TestTerminal({cols: 10, rows: 10});
|
||||
});
|
||||
function getCursor(term: TestTerminal): number[] {
|
||||
return [
|
||||
term.buffer.x,
|
||||
term.buffer.y
|
||||
];
|
||||
}
|
||||
it('cursor forward (CUF)', () => {
|
||||
term.writeSync('\x1b[C');
|
||||
assert.deepEqual(getCursor(term), [1, 0]);
|
||||
term.writeSync('\x1b[1C');
|
||||
assert.deepEqual(getCursor(term), [2, 0]);
|
||||
term.writeSync('\x1b[4C');
|
||||
assert.deepEqual(getCursor(term), [6, 0]);
|
||||
term.writeSync('\x1b[100C');
|
||||
assert.deepEqual(getCursor(term), [9, 0]);
|
||||
// should not change y
|
||||
term.buffer.x = 8;
|
||||
term.buffer.y = 4;
|
||||
term.writeSync('\x1b[C');
|
||||
assert.deepEqual(getCursor(term), [9, 4]);
|
||||
});
|
||||
it('cursor backward (CUB)', () => {
|
||||
term.writeSync('\x1b[D');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
term.writeSync('\x1b[1D');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
// place cursor at end of first line
|
||||
term.writeSync('\x1b[100C');
|
||||
term.writeSync('\x1b[D');
|
||||
assert.deepEqual(getCursor(term), [8, 0]);
|
||||
term.writeSync('\x1b[1D');
|
||||
assert.deepEqual(getCursor(term), [7, 0]);
|
||||
term.writeSync('\x1b[4D');
|
||||
assert.deepEqual(getCursor(term), [3, 0]);
|
||||
term.writeSync('\x1b[100D');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
// should not change y
|
||||
term.buffer.x = 4;
|
||||
term.buffer.y = 4;
|
||||
term.writeSync('\x1b[D');
|
||||
assert.deepEqual(getCursor(term), [3, 4]);
|
||||
});
|
||||
it('cursor down (CUD)', () => {
|
||||
term.writeSync('\x1b[B');
|
||||
assert.deepEqual(getCursor(term), [0, 1]);
|
||||
term.writeSync('\x1b[1B');
|
||||
assert.deepEqual(getCursor(term), [0, 2]);
|
||||
term.writeSync('\x1b[4B');
|
||||
assert.deepEqual(getCursor(term), [0, 6]);
|
||||
term.writeSync('\x1b[100B');
|
||||
assert.deepEqual(getCursor(term), [0, 9]);
|
||||
// should not change x
|
||||
term.buffer.x = 8;
|
||||
term.buffer.y = 0;
|
||||
term.writeSync('\x1b[B');
|
||||
assert.deepEqual(getCursor(term), [8, 1]);
|
||||
});
|
||||
it('cursor up (CUU)', () => {
|
||||
term.writeSync('\x1b[A');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
term.writeSync('\x1b[1A');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
// place cursor at beginning of last row
|
||||
term.writeSync('\x1b[100B');
|
||||
term.writeSync('\x1b[A');
|
||||
assert.deepEqual(getCursor(term), [0, 8]);
|
||||
term.writeSync('\x1b[1A');
|
||||
assert.deepEqual(getCursor(term), [0, 7]);
|
||||
term.writeSync('\x1b[4A');
|
||||
assert.deepEqual(getCursor(term), [0, 3]);
|
||||
term.writeSync('\x1b[100A');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
// should not change x
|
||||
term.buffer.x = 8;
|
||||
term.buffer.y = 9;
|
||||
term.writeSync('\x1b[A');
|
||||
assert.deepEqual(getCursor(term), [8, 8]);
|
||||
});
|
||||
it('cursor next line (CNL)', () => {
|
||||
term.writeSync('\x1b[E');
|
||||
assert.deepEqual(getCursor(term), [0, 1]);
|
||||
term.writeSync('\x1b[1E');
|
||||
assert.deepEqual(getCursor(term), [0, 2]);
|
||||
term.writeSync('\x1b[4E');
|
||||
assert.deepEqual(getCursor(term), [0, 6]);
|
||||
term.writeSync('\x1b[100E');
|
||||
assert.deepEqual(getCursor(term), [0, 9]);
|
||||
// should reset x to zero
|
||||
term.buffer.x = 8;
|
||||
term.buffer.y = 0;
|
||||
term.writeSync('\x1b[E');
|
||||
assert.deepEqual(getCursor(term), [0, 1]);
|
||||
});
|
||||
it('cursor previous line (CPL)', () => {
|
||||
term.writeSync('\x1b[F');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
term.writeSync('\x1b[1F');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
// place cursor at beginning of last row
|
||||
term.writeSync('\x1b[100E');
|
||||
term.writeSync('\x1b[F');
|
||||
assert.deepEqual(getCursor(term), [0, 8]);
|
||||
term.writeSync('\x1b[1F');
|
||||
assert.deepEqual(getCursor(term), [0, 7]);
|
||||
term.writeSync('\x1b[4F');
|
||||
assert.deepEqual(getCursor(term), [0, 3]);
|
||||
term.writeSync('\x1b[100F');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
// should reset x to zero
|
||||
term.buffer.x = 8;
|
||||
term.buffer.y = 9;
|
||||
term.writeSync('\x1b[F');
|
||||
assert.deepEqual(getCursor(term), [0, 8]);
|
||||
});
|
||||
it('cursor character absolute (CHA)', () => {
|
||||
term.writeSync('\x1b[G');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
term.writeSync('\x1b[1G');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
term.writeSync('\x1b[2G');
|
||||
assert.deepEqual(getCursor(term), [1, 0]);
|
||||
term.writeSync('\x1b[5G');
|
||||
assert.deepEqual(getCursor(term), [4, 0]);
|
||||
term.writeSync('\x1b[100G');
|
||||
assert.deepEqual(getCursor(term), [9, 0]);
|
||||
});
|
||||
it('cursor position (CUP)', () => {
|
||||
term.buffer.x = 5;
|
||||
term.buffer.y = 5;
|
||||
term.writeSync('\x1b[H');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
term.buffer.x = 5;
|
||||
term.buffer.y = 5;
|
||||
term.writeSync('\x1b[1H');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
term.buffer.x = 5;
|
||||
term.buffer.y = 5;
|
||||
term.writeSync('\x1b[1;1H');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
term.buffer.x = 5;
|
||||
term.buffer.y = 5;
|
||||
term.writeSync('\x1b[8H');
|
||||
assert.deepEqual(getCursor(term), [0, 7]);
|
||||
term.buffer.x = 5;
|
||||
term.buffer.y = 5;
|
||||
term.writeSync('\x1b[;8H');
|
||||
assert.deepEqual(getCursor(term), [7, 0]);
|
||||
term.buffer.x = 5;
|
||||
term.buffer.y = 5;
|
||||
term.writeSync('\x1b[100;100H');
|
||||
assert.deepEqual(getCursor(term), [9, 9]);
|
||||
});
|
||||
it('horizontal position absolute (HPA)', () => {
|
||||
term.writeSync('\x1b[`');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
term.writeSync('\x1b[1`');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
term.writeSync('\x1b[2`');
|
||||
assert.deepEqual(getCursor(term), [1, 0]);
|
||||
term.writeSync('\x1b[5`');
|
||||
assert.deepEqual(getCursor(term), [4, 0]);
|
||||
term.writeSync('\x1b[100`');
|
||||
assert.deepEqual(getCursor(term), [9, 0]);
|
||||
});
|
||||
it('horizontal position relative (HPR)', () => {
|
||||
term.writeSync('\x1b[a');
|
||||
assert.deepEqual(getCursor(term), [1, 0]);
|
||||
term.writeSync('\x1b[1a');
|
||||
assert.deepEqual(getCursor(term), [2, 0]);
|
||||
term.writeSync('\x1b[4a');
|
||||
assert.deepEqual(getCursor(term), [6, 0]);
|
||||
term.writeSync('\x1b[100a');
|
||||
assert.deepEqual(getCursor(term), [9, 0]);
|
||||
// should not change y
|
||||
term.buffer.x = 8;
|
||||
term.buffer.y = 4;
|
||||
term.writeSync('\x1b[a');
|
||||
assert.deepEqual(getCursor(term), [9, 4]);
|
||||
});
|
||||
it('vertical position absolute (VPA)', () => {
|
||||
term.writeSync('\x1b[d');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
term.writeSync('\x1b[1d');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
term.writeSync('\x1b[2d');
|
||||
assert.deepEqual(getCursor(term), [0, 1]);
|
||||
term.writeSync('\x1b[5d');
|
||||
assert.deepEqual(getCursor(term), [0, 4]);
|
||||
term.writeSync('\x1b[100d');
|
||||
assert.deepEqual(getCursor(term), [0, 9]);
|
||||
// should not change x
|
||||
term.buffer.x = 8;
|
||||
term.buffer.y = 4;
|
||||
term.writeSync('\x1b[d');
|
||||
assert.deepEqual(getCursor(term), [8, 0]);
|
||||
});
|
||||
it('vertical position relative (VPR)', () => {
|
||||
term.writeSync('\x1b[e');
|
||||
assert.deepEqual(getCursor(term), [0, 1]);
|
||||
term.writeSync('\x1b[1e');
|
||||
assert.deepEqual(getCursor(term), [0, 2]);
|
||||
term.writeSync('\x1b[4e');
|
||||
assert.deepEqual(getCursor(term), [0, 6]);
|
||||
term.writeSync('\x1b[100e');
|
||||
assert.deepEqual(getCursor(term), [0, 9]);
|
||||
// should not change x
|
||||
term.buffer.x = 8;
|
||||
term.buffer.y = 4;
|
||||
term.writeSync('\x1b[e');
|
||||
assert.deepEqual(getCursor(term), [8, 5]);
|
||||
});
|
||||
describe('should clamp cursor into addressible range', () => {
|
||||
it('CUF', () => {
|
||||
term.buffer.x = 10000;
|
||||
term.buffer.y = 10000;
|
||||
term.writeSync('\x1b[C');
|
||||
assert.deepEqual(getCursor(term), [9, 9]);
|
||||
term.buffer.x = -10000;
|
||||
term.buffer.y = -10000;
|
||||
term.writeSync('\x1b[C');
|
||||
assert.deepEqual(getCursor(term), [1, 0]);
|
||||
});
|
||||
it('CUB', () => {
|
||||
term.buffer.x = 10000;
|
||||
term.buffer.y = 10000;
|
||||
term.writeSync('\x1b[D');
|
||||
assert.deepEqual(getCursor(term), [8, 9]);
|
||||
term.buffer.x = -10000;
|
||||
term.buffer.y = -10000;
|
||||
term.writeSync('\x1b[D');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
});
|
||||
it('CUD', () => {
|
||||
term.buffer.x = 10000;
|
||||
term.buffer.y = 10000;
|
||||
term.writeSync('\x1b[B');
|
||||
assert.deepEqual(getCursor(term), [9, 9]);
|
||||
term.buffer.x = -10000;
|
||||
term.buffer.y = -10000;
|
||||
term.writeSync('\x1b[B');
|
||||
assert.deepEqual(getCursor(term), [0, 1]);
|
||||
});
|
||||
it('CUU', () => {
|
||||
term.buffer.x = 10000;
|
||||
term.buffer.y = 10000;
|
||||
term.writeSync('\x1b[A');
|
||||
assert.deepEqual(getCursor(term), [9, 8]);
|
||||
term.buffer.x = -10000;
|
||||
term.buffer.y = -10000;
|
||||
term.writeSync('\x1b[A');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
});
|
||||
it('CNL', () => {
|
||||
term.buffer.x = 10000;
|
||||
term.buffer.y = 10000;
|
||||
term.writeSync('\x1b[E');
|
||||
assert.deepEqual(getCursor(term), [0, 9]);
|
||||
term.buffer.x = -10000;
|
||||
term.buffer.y = -10000;
|
||||
term.writeSync('\x1b[E');
|
||||
assert.deepEqual(getCursor(term), [0, 1]);
|
||||
});
|
||||
it('CPL', () => {
|
||||
term.buffer.x = 10000;
|
||||
term.buffer.y = 10000;
|
||||
term.writeSync('\x1b[F');
|
||||
assert.deepEqual(getCursor(term), [0, 8]);
|
||||
term.buffer.x = -10000;
|
||||
term.buffer.y = -10000;
|
||||
term.writeSync('\x1b[F');
|
||||
assert.deepEqual(getCursor(term), [0, 0]);
|
||||
});
|
||||
it('CHA', () => {
|
||||
term.buffer.x = 10000;
|
||||
term.buffer.y = 10000;
|
||||
term.writeSync('\x1b[5G');
|
||||
assert.deepEqual(getCursor(term), [4, 9]);
|
||||
term.buffer.x = -10000;
|
||||
term.buffer.y = -10000;
|
||||
term.writeSync('\x1b[5G');
|
||||
assert.deepEqual(getCursor(term), [4, 0]);
|
||||
});
|
||||
it('CUP', () => {
|
||||
term.buffer.x = 10000;
|
||||
term.buffer.y = 10000;
|
||||
term.writeSync('\x1b[5;5H');
|
||||
assert.deepEqual(getCursor(term), [4, 4]);
|
||||
term.buffer.x = -10000;
|
||||
term.buffer.y = -10000;
|
||||
term.writeSync('\x1b[5;5H');
|
||||
assert.deepEqual(getCursor(term), [4, 4]);
|
||||
});
|
||||
it('HPA', () => {
|
||||
term.buffer.x = 10000;
|
||||
term.buffer.y = 10000;
|
||||
term.writeSync('\x1b[5`');
|
||||
assert.deepEqual(getCursor(term), [4, 9]);
|
||||
term.buffer.x = -10000;
|
||||
term.buffer.y = -10000;
|
||||
term.writeSync('\x1b[5`');
|
||||
assert.deepEqual(getCursor(term), [4, 0]);
|
||||
});
|
||||
it('HPR', () => {
|
||||
term.buffer.x = 10000;
|
||||
term.buffer.y = 10000;
|
||||
term.writeSync('\x1b[a');
|
||||
assert.deepEqual(getCursor(term), [9, 9]);
|
||||
term.buffer.x = -10000;
|
||||
term.buffer.y = -10000;
|
||||
term.writeSync('\x1b[a');
|
||||
assert.deepEqual(getCursor(term), [1, 0]);
|
||||
});
|
||||
it('VPA', () => {
|
||||
term.buffer.x = 10000;
|
||||
term.buffer.y = 10000;
|
||||
term.writeSync('\x1b[5d');
|
||||
assert.deepEqual(getCursor(term), [9, 4]);
|
||||
term.buffer.x = -10000;
|
||||
term.buffer.y = -10000;
|
||||
term.writeSync('\x1b[5d');
|
||||
assert.deepEqual(getCursor(term), [0, 4]);
|
||||
});
|
||||
it('VPR', () => {
|
||||
term.buffer.x = 10000;
|
||||
term.buffer.y = 10000;
|
||||
term.writeSync('\x1b[e');
|
||||
assert.deepEqual(getCursor(term), [9, 9]);
|
||||
term.buffer.x = -10000;
|
||||
term.buffer.y = -10000;
|
||||
term.writeSync('\x1b[e');
|
||||
assert.deepEqual(getCursor(term), [0, 1]);
|
||||
});
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
+48
-74
@@ -598,6 +598,22 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
this._terminal.updateRange(this._terminal.buffer.y);
|
||||
}
|
||||
|
||||
// restrict cursor changes to addressible cols/rows
|
||||
private _restrictCursor(): void {
|
||||
// cols
|
||||
if (this._terminal.buffer.x < 0) {
|
||||
this._terminal.buffer.x = 0;
|
||||
} else if (this._terminal.buffer.x >= this._terminal.cols) {
|
||||
this._terminal.buffer.x = this._terminal.cols - 1;
|
||||
}
|
||||
// rows
|
||||
if (this._terminal.buffer.y < 0) {
|
||||
this._terminal.buffer.y = 0;
|
||||
} else if (this._terminal.buffer.y >= this._terminal.rows) {
|
||||
this._terminal.buffer.y = this._terminal.rows - 1;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* CSI Ps A
|
||||
* Cursor Up Ps Times (default = 1) (CUU).
|
||||
@@ -607,10 +623,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
if (param < 1) {
|
||||
param = 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
this._terminal.buffer.y -= param;
|
||||
if (this._terminal.buffer.y < 0) {
|
||||
this._terminal.buffer.y = 0;
|
||||
}
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -622,14 +637,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
if (param < 1) {
|
||||
param = 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
this._terminal.buffer.y += param;
|
||||
if (this._terminal.buffer.y >= this._terminal.rows) {
|
||||
this._terminal.buffer.y = this._terminal.rows - 1;
|
||||
}
|
||||
// If the end of the line is hit, prevent this action from wrapping around to the next line.
|
||||
if (this._terminal.buffer.x >= this._terminal.cols) {
|
||||
this._terminal.buffer.x--;
|
||||
}
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -641,10 +651,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
if (param < 1) {
|
||||
param = 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
this._terminal.buffer.x += param;
|
||||
if (this._terminal.buffer.x >= this._terminal.cols) {
|
||||
this._terminal.buffer.x = this._terminal.cols - 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -656,49 +665,42 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
if (param < 1) {
|
||||
param = 1;
|
||||
}
|
||||
// If the end of the line is hit, prevent this action from wrapping around to the next line.
|
||||
if (this._terminal.buffer.x >= this._terminal.cols) {
|
||||
this._terminal.buffer.x--;
|
||||
}
|
||||
this._restrictCursor();
|
||||
this._terminal.buffer.x -= param;
|
||||
if (this._terminal.buffer.x < 0) {
|
||||
this._terminal.buffer.x = 0;
|
||||
}
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* CSI Ps E
|
||||
* Cursor Next Line Ps Times (default = 1) (CNL).
|
||||
* same as CSI Ps B ?
|
||||
* Other than cursorDown (CUD) also set the cursor to first column.
|
||||
*/
|
||||
public cursorNextLine(params: number[]): void {
|
||||
let param = params[0];
|
||||
if (param < 1) {
|
||||
param = 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
this._terminal.buffer.y += param;
|
||||
if (this._terminal.buffer.y >= this._terminal.rows) {
|
||||
this._terminal.buffer.y = this._terminal.rows - 1;
|
||||
}
|
||||
this._terminal.buffer.x = 0;
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
|
||||
/**
|
||||
* CSI Ps F
|
||||
* Cursor Preceding Line Ps Times (default = 1) (CNL).
|
||||
* reuse CSI Ps A ?
|
||||
* Cursor Previous Line Ps Times (default = 1) (CPL).
|
||||
* Other than cursorUp (CUU) also set the cursor to first column.
|
||||
*/
|
||||
public cursorPrecedingLine(params: number[]): void {
|
||||
let param = params[0];
|
||||
if (param < 1) {
|
||||
param = 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
this._terminal.buffer.y -= param;
|
||||
if (this._terminal.buffer.y < 0) {
|
||||
this._terminal.buffer.y = 0;
|
||||
}
|
||||
this._terminal.buffer.x = 0;
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
|
||||
@@ -711,7 +713,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
if (param < 1) {
|
||||
param = 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
this._terminal.buffer.x = param - 1;
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -720,7 +724,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
*/
|
||||
public cursorPosition(params: number[]): void {
|
||||
let col: number;
|
||||
let row: number = params[0] - 1;
|
||||
const row: number = params[0] - 1;
|
||||
|
||||
if (params.length >= 2) {
|
||||
col = params[1] - 1;
|
||||
@@ -728,20 +732,10 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
col = 0;
|
||||
}
|
||||
|
||||
if (row < 0) {
|
||||
row = 0;
|
||||
} else if (row >= this._terminal.rows) {
|
||||
row = this._terminal.rows - 1;
|
||||
}
|
||||
|
||||
if (col < 0) {
|
||||
col = 0;
|
||||
} else if (col >= this._terminal.cols) {
|
||||
col = this._terminal.cols - 1;
|
||||
}
|
||||
|
||||
this._restrictCursor();
|
||||
this._terminal.buffer.x = col;
|
||||
this._terminal.buffer.y = row;
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1017,32 +1011,31 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
/**
|
||||
* CSI Pm ` Character Position Absolute
|
||||
* [column] (default = [row,1]) (HPA).
|
||||
* Currently same functionality as CHA.
|
||||
*/
|
||||
public charPosAbsolute(params: number[]): void {
|
||||
let param = params[0];
|
||||
if (param < 1) {
|
||||
param = 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
this._terminal.buffer.x = param - 1;
|
||||
if (this._terminal.buffer.x >= this._terminal.cols) {
|
||||
this._terminal.buffer.x = this._terminal.cols - 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* CSI Pm a Character Position Relative
|
||||
* [columns] (default = [row,col+1]) (HPR)
|
||||
* reuse CSI Ps C ?
|
||||
* Currently same functionality as CUF.
|
||||
*/
|
||||
public hPositionRelative(params: number[]): void {
|
||||
let param = params[0];
|
||||
if (param < 1) {
|
||||
param = 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
this._terminal.buffer.x += param;
|
||||
if (this._terminal.buffer.x >= this._terminal.cols) {
|
||||
this._terminal.buffer.x = this._terminal.cols - 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1155,10 +1148,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
if (param < 1) {
|
||||
param = 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
this._terminal.buffer.y = param - 1;
|
||||
if (this._terminal.buffer.y >= this._terminal.rows) {
|
||||
this._terminal.buffer.y = this._terminal.rows - 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
@@ -1171,37 +1163,19 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
if (param < 1) {
|
||||
param = 1;
|
||||
}
|
||||
this._restrictCursor();
|
||||
this._terminal.buffer.y += param;
|
||||
if (this._terminal.buffer.y >= this._terminal.rows) {
|
||||
this._terminal.buffer.y = this._terminal.rows - 1;
|
||||
}
|
||||
// If the end of the line is hit, prevent this action from wrapping around to the next line.
|
||||
if (this._terminal.buffer.x >= this._terminal.cols) {
|
||||
this._terminal.buffer.x--;
|
||||
}
|
||||
this._restrictCursor();
|
||||
}
|
||||
|
||||
/**
|
||||
* CSI Ps ; Ps f
|
||||
* Horizontal and Vertical Position [row;column] (default =
|
||||
* [1,1]) (HVP).
|
||||
* Same as CUP.
|
||||
*/
|
||||
public hVPosition(params: number[]): void {
|
||||
if (params.length < 2) {
|
||||
params.push(1);
|
||||
}
|
||||
if (params[0] < 1) params[0] = 1;
|
||||
if (params[1] < 1) params[1] = 1;
|
||||
|
||||
this._terminal.buffer.y = params[0] - 1;
|
||||
if (this._terminal.buffer.y >= this._terminal.rows) {
|
||||
this._terminal.buffer.y = this._terminal.rows - 1;
|
||||
}
|
||||
|
||||
this._terminal.buffer.x = params[1] - 1;
|
||||
if (this._terminal.buffer.x >= this._terminal.cols) {
|
||||
this._terminal.buffer.x = this._terminal.cols - 1;
|
||||
}
|
||||
this.cursorPosition(params);
|
||||
}
|
||||
|
||||
/**
|
||||
|
||||
Reference in New Issue
Block a user