mirror of
https://github.com/wavetermdev/xterm.js.git
synced 2026-08-05 13:43:48 -07:00
Merge branch 'master' into options2
This commit is contained in:
@@ -179,7 +179,7 @@ Xterm.js is used in several world-class applications to provide great terminal e
|
||||
- [**WizardWebssh**](https://gitlab.com/mikeramsey/wizardwebssh): A terminal with Pyqt5 Widget for embedding, which can be used as an ssh client to connect to your ssh servers. It is written in Python, based on tornado, paramiko, and xterm.js.
|
||||
- [**Wizard Assistant**](https://wizardassistant.com/): Wizard Assistant comes with advanced automation tools, preloaded common and special time-saving commands, and a built-in SSH terminal. Now you can remotely administer, troubleshoot, and analyze any system with ease.
|
||||
- [**ucli**](https://github.com/tsadarsh/ucli): Command Line for everyone :family_man_woman_girl_boy: at [www.ucli.tech](https://www.ucli.tech).
|
||||
- [**Tess**](https://github.com/SquitchYT/Tess/): Simple Terminal Fully Customizable for Everyone.
|
||||
- [**Tess**](https://github.com/SquitchYT/Tess/): Simple Terminal Fully Customizable for Everyone. Discover more at [tessapp.dev](https://tessapp.dev)
|
||||
- [**HashiCorp Nomad**](https://www.nomadproject.io/): A container orchestrator with the ability to connect to remote tasks via a web interface using websockets and xterm.js.
|
||||
- [**TermPair**](https://github.com/cs01/termpair): View and control terminals from your browser with end-to-end encryption
|
||||
- [**gdbgui**](https://github.com/cs01/gdbgui): Browser-based frontend to gdb (gnu debugger)
|
||||
|
||||
+2
-1
@@ -133,7 +133,8 @@
|
||||
cursor: default;
|
||||
}
|
||||
|
||||
.xterm.xterm-cursor-pointer {
|
||||
.xterm.xterm-cursor-pointer,
|
||||
.xterm .xterm-cursor-pointer {
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
|
||||
@@ -534,7 +534,7 @@ export class Terminal extends CoreTerminal implements ITerminal {
|
||||
this.register(this._mouseZoneManager);
|
||||
this.register(this.onScroll(() => this._mouseZoneManager!.clearAll()));
|
||||
this.linkifier.attachToDom(this.element, this._mouseZoneManager);
|
||||
this.linkifier2.attachToDom(this.element, this._mouseService, this._renderService);
|
||||
this.linkifier2.attachToDom(this.screenElement, this._mouseService, this._renderService);
|
||||
|
||||
// This event listener must be registered aftre MouseZoneManager is created
|
||||
this.register(addDisposableDomListener(this.element, 'mousedown', (e: MouseEvent) => this._selectionService!.onMouseDown(e)));
|
||||
|
||||
@@ -386,6 +386,56 @@ describe('InputHandler', () => {
|
||||
assert.equal(bufferService.buffer.lines.get(2)!.translateToString(false), Array(bufferService.cols + 1).join(' '));
|
||||
|
||||
});
|
||||
it('eraseInLine reflow', async () => {
|
||||
const bufferService = new MockBufferService(80, 30);
|
||||
const inputHandler = new TestInputHandler(
|
||||
bufferService,
|
||||
new MockCharsetService(),
|
||||
new MockCoreService(),
|
||||
new MockDirtyRowService(),
|
||||
new MockLogService(),
|
||||
new MockOptionsService(),
|
||||
new MockCoreMouseService(),
|
||||
new MockUnicodeService()
|
||||
);
|
||||
|
||||
const resetToBaseState = async (): Promise<void> => {
|
||||
// reset and add a wrapped line
|
||||
bufferService.buffer.y = 0;
|
||||
bufferService.buffer.x = 0;
|
||||
await inputHandler.parseP(Array(bufferService.cols + 1).join('a')); // line 0
|
||||
await inputHandler.parseP(Array(bufferService.cols + 10).join('a')); // line 1 and 2
|
||||
for (let i = 3; i < bufferService.rows; ++i) await inputHandler.parseP(Array(bufferService.cols + 1).join('a'));
|
||||
|
||||
// confirm precondition that line 2 is wrapped
|
||||
assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, true);
|
||||
};
|
||||
|
||||
// params[0] - erase from the cursor through the end of the row.
|
||||
await resetToBaseState();
|
||||
bufferService.buffer.y = 2;
|
||||
bufferService.buffer.x = 40;
|
||||
inputHandler.eraseInLine(Params.fromArray([0]));
|
||||
assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, true);
|
||||
bufferService.buffer.y = 2;
|
||||
bufferService.buffer.x = 0;
|
||||
inputHandler.eraseInLine(Params.fromArray([0]));
|
||||
assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, false);
|
||||
|
||||
// params[1] - erase from the beginning of the line through the cursor
|
||||
await resetToBaseState();
|
||||
bufferService.buffer.y = 2;
|
||||
bufferService.buffer.x = 40;
|
||||
inputHandler.eraseInLine(Params.fromArray([1]));
|
||||
assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, true);
|
||||
|
||||
// params[2] - erase complete line
|
||||
await resetToBaseState();
|
||||
bufferService.buffer.y = 2;
|
||||
bufferService.buffer.x = 40;
|
||||
inputHandler.eraseInLine(Params.fromArray([2]));
|
||||
assert.equal(bufferService.buffer.lines.get(2)!.isWrapped, false);
|
||||
});
|
||||
it('eraseInDisplay', async () => {
|
||||
const bufferService = new MockBufferService(80, 7);
|
||||
const inputHandler = new TestInputHandler(
|
||||
|
||||
+12
-12
@@ -25,7 +25,7 @@ import { IBuffer } from 'common/buffer/Types';
|
||||
/**
|
||||
* Map collect to glevel. Used in `selectCharset`.
|
||||
*/
|
||||
const GLEVEL: {[key: string]: number} = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 };
|
||||
const GLEVEL: { [key: string]: number } = { '(': 0, ')': 1, '*': 2, '+': 3, '-': 1, '.': 2 };
|
||||
|
||||
/**
|
||||
* VT commands done by the parser - FIXME: move this to the parser?
|
||||
@@ -167,7 +167,7 @@ class DECRQSS implements IDcsHandler {
|
||||
break;
|
||||
case 'r': // DECSTBM
|
||||
const pt = '' + (this._bufferService.buffer.scrollTop + 1) +
|
||||
';' + (this._bufferService.buffer.scrollBottom + 1) + 'r';
|
||||
';' + (this._bufferService.buffer.scrollBottom + 1) + 'r';
|
||||
this._coreService.triggerDataEvent(`${C0.ESC}P1$r${pt}${C0.ESC}\\`);
|
||||
break;
|
||||
case 'm': // SGR
|
||||
@@ -175,7 +175,7 @@ class DECRQSS implements IDcsHandler {
|
||||
this._coreService.triggerDataEvent(`${C0.ESC}P1$r0m${C0.ESC}\\`);
|
||||
break;
|
||||
case ' q': // DECSCUSR
|
||||
const STYLES: {[key: string]: number} = { 'block': 2, 'underline': 4, 'bar': 6 };
|
||||
const STYLES: { [key: string]: number } = { 'block': 2, 'underline': 4, 'bar': 6 };
|
||||
let style = STYLES[this._optionsService.options.cursorStyle];
|
||||
style -= this._optionsService.options.cursorBlink ? 1 : 0;
|
||||
this._coreService.triggerDataEvent(`${C0.ESC}P1$r${style} q${C0.ESC}\\`);
|
||||
@@ -855,10 +855,9 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* - any cursor movement sequence keeps working as expected
|
||||
*/
|
||||
if (this._activeBuffer.x === 0
|
||||
&& this._activeBuffer.y > this._activeBuffer.scrollTop
|
||||
&& this._activeBuffer.y <= this._activeBuffer.scrollBottom
|
||||
&& this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)?.isWrapped)
|
||||
{
|
||||
&& this._activeBuffer.y > this._activeBuffer.scrollTop
|
||||
&& this._activeBuffer.y <= this._activeBuffer.scrollBottom
|
||||
&& this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)?.isWrapped) {
|
||||
this._activeBuffer.lines.get(this._activeBuffer.ybase + this._activeBuffer.y)!.isWrapped = false;
|
||||
this._activeBuffer.y--;
|
||||
this._activeBuffer.x = this._bufferService.cols - 1;
|
||||
@@ -1195,6 +1194,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
* @param y row index
|
||||
* @param start first cell index to be erased
|
||||
* @param end end - 1 is last erased cell
|
||||
* @param cleanWrap clear the isWrapped flag
|
||||
*/
|
||||
private _eraseInBufferLine(y: number, start: number, end: number, clearWrap: boolean = false): void {
|
||||
const line = this._activeBuffer.lines.get(this._activeBuffer.ybase + y)!;
|
||||
@@ -1320,13 +1320,13 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
this._restrictCursor(this._bufferService.cols);
|
||||
switch (params.params[0]) {
|
||||
case 0:
|
||||
this._eraseInBufferLine(this._activeBuffer.y, this._activeBuffer.x, this._bufferService.cols);
|
||||
this._eraseInBufferLine(this._activeBuffer.y, this._activeBuffer.x, this._bufferService.cols, this._activeBuffer.x === 0);
|
||||
break;
|
||||
case 1:
|
||||
this._eraseInBufferLine(this._activeBuffer.y, 0, this._activeBuffer.x + 1);
|
||||
this._eraseInBufferLine(this._activeBuffer.y, 0, this._activeBuffer.x + 1, false);
|
||||
break;
|
||||
case 2:
|
||||
this._eraseInBufferLine(this._activeBuffer.y, 0, this._bufferService.cols);
|
||||
this._eraseInBufferLine(this._activeBuffer.y, 0, this._bufferService.cols, true);
|
||||
break;
|
||||
}
|
||||
this._dirtyRowService.markDirty(this._activeBuffer.y);
|
||||
@@ -2264,7 +2264,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
}
|
||||
// exit early if can decide color mode with semicolons
|
||||
if ((accu[1] === 5 && advance + cSpace >= 2)
|
||||
|| (accu[1] === 2 && advance + cSpace >= 5)) {
|
||||
|| (accu[1] === 2 && advance + cSpace >= 5)) {
|
||||
break;
|
||||
}
|
||||
// offset colorSpace slot for semicolon mode
|
||||
@@ -2683,7 +2683,7 @@ export class InputHandler extends Disposable implements IInputHandler {
|
||||
const top = params.params[0] || 1;
|
||||
let bottom: number;
|
||||
|
||||
if (params.length < 2 || (bottom = params.params[1]) > this._bufferService.rows || bottom === 0) {
|
||||
if (params.length < 2 || (bottom = params.params[1]) > this._bufferService.rows || bottom === 0) {
|
||||
bottom = this._bufferService.rows;
|
||||
}
|
||||
|
||||
|
||||
Vendored
+1
@@ -46,6 +46,7 @@ export interface IKeyboardEvent {
|
||||
ctrlKey: boolean;
|
||||
shiftKey: boolean;
|
||||
metaKey: boolean;
|
||||
/** @deprecated See KeyboardEvent.keyCode */
|
||||
keyCode: number;
|
||||
key: string;
|
||||
type: string;
|
||||
|
||||
Vendored
+2
-2
@@ -1283,12 +1283,12 @@ declare module 'xterm' {
|
||||
*/
|
||||
interface IBufferCellPosition {
|
||||
/**
|
||||
* The x position within the buffer.
|
||||
* The x position within the buffer (1-based).
|
||||
*/
|
||||
x: number;
|
||||
|
||||
/**
|
||||
* The y position within the buffer.
|
||||
* The y position within the buffer (1-based).
|
||||
*/
|
||||
y: number;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user