@theia/terminal 1.45.1 → 1.46.0-next.137
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/lib/browser/base/terminal-widget.d.ts +10 -0
- package/lib/browser/base/terminal-widget.d.ts.map +1 -1
- package/lib/browser/base/terminal-widget.js.map +1 -1
- package/lib/browser/index.js +2 -11
- package/lib/browser/index.js.map +1 -1
- package/lib/browser/search/terminal-search-widget.js +8 -16
- package/lib/browser/search/terminal-search-widget.js.map +1 -1
- package/lib/browser/terminal-copy-on-selection-handler.js +6 -14
- package/lib/browser/terminal-copy-on-selection-handler.js.map +1 -1
- package/lib/browser/terminal-file-link-provider.d.ts +10 -0
- package/lib/browser/terminal-file-link-provider.d.ts.map +1 -1
- package/lib/browser/terminal-file-link-provider.js +82 -23
- package/lib/browser/terminal-file-link-provider.js.map +1 -1
- package/lib/browser/terminal-frontend-contribution.d.ts +2 -0
- package/lib/browser/terminal-frontend-contribution.d.ts.map +1 -1
- package/lib/browser/terminal-frontend-contribution.js +72 -49
- package/lib/browser/terminal-frontend-contribution.js.map +1 -1
- package/lib/browser/terminal-frontend-module.d.ts.map +1 -1
- package/lib/browser/terminal-frontend-module.js +2 -0
- package/lib/browser/terminal-frontend-module.js.map +1 -1
- package/lib/browser/terminal-link-provider.js +19 -27
- package/lib/browser/terminal-link-provider.js.map +1 -1
- package/lib/browser/terminal-preferences.d.ts.map +1 -1
- package/lib/browser/terminal-preferences.js +2 -1
- package/lib/browser/terminal-preferences.js.map +1 -1
- package/lib/browser/terminal-profile-service.js +4 -12
- package/lib/browser/terminal-profile-service.js.map +1 -1
- package/lib/browser/terminal-quick-open-service.js +13 -21
- package/lib/browser/terminal-quick-open-service.js.map +1 -1
- package/lib/browser/terminal-theme-service.d.ts.map +1 -1
- package/lib/browser/terminal-theme-service.js +12 -16
- package/lib/browser/terminal-theme-service.js.map +1 -1
- package/lib/browser/terminal-url-link-provider.js +4 -12
- package/lib/browser/terminal-url-link-provider.js.map +1 -1
- package/lib/browser/terminal-widget-impl.d.ts +9 -12
- package/lib/browser/terminal-widget-impl.d.ts.map +1 -1
- package/lib/browser/terminal-widget-impl.js +111 -105
- package/lib/browser/terminal-widget-impl.js.map +1 -1
- package/lib/common/terminal-watcher.js +2 -7
- package/lib/common/terminal-watcher.js.map +1 -1
- package/lib/node/base-terminal-server.js +6 -17
- package/lib/node/base-terminal-server.js.map +1 -1
- package/lib/node/index.js +2 -11
- package/lib/node/index.js.map +1 -1
- package/lib/node/shell-process.js +10 -21
- package/lib/node/shell-process.js.map +1 -1
- package/lib/node/shell-terminal-server.js +9 -20
- package/lib/node/shell-terminal-server.js.map +1 -1
- package/lib/node/terminal-backend-contribution.js +6 -14
- package/lib/node/terminal-backend-contribution.js.map +1 -1
- package/lib/node/terminal-server.js +8 -19
- package/lib/node/terminal-server.js.map +1 -1
- package/package.json +14 -12
- package/src/browser/base/terminal-widget.ts +13 -0
- package/src/browser/terminal-file-link-provider.ts +66 -7
- package/src/browser/terminal-frontend-contribution.ts +38 -3
- package/src/browser/terminal-frontend-module.ts +3 -1
- package/src/browser/terminal-preferences.ts +2 -1
- package/src/browser/terminal-theme-service.ts +6 -2
- package/src/browser/terminal-widget-impl.ts +94 -62
- package/src/node/shell-process.ts +1 -1
|
@@ -14,7 +14,7 @@
|
|
|
14
14
|
// SPDX-License-Identifier: EPL-2.0 OR GPL-2.0-only WITH Classpath-exception-2.0
|
|
15
15
|
// *****************************************************************************
|
|
16
16
|
|
|
17
|
-
import { Terminal
|
|
17
|
+
import { Terminal } from 'xterm';
|
|
18
18
|
import { FitAddon } from 'xterm-addon-fit';
|
|
19
19
|
import { inject, injectable, named, postConstruct } from '@theia/core/shared/inversify';
|
|
20
20
|
import { ContributionProvider, Disposable, Event, Emitter, ILogger, DisposableCollection, Channel, OS } from '@theia/core';
|
|
@@ -29,10 +29,11 @@ import { IBaseTerminalServer, TerminalProcessInfo, TerminalExitReason } from '..
|
|
|
29
29
|
import { TerminalWatcher } from '../common/terminal-watcher';
|
|
30
30
|
import {
|
|
31
31
|
TerminalWidgetOptions, TerminalWidget, TerminalDimensions, TerminalExitStatus, TerminalLocationOptions,
|
|
32
|
-
TerminalLocation
|
|
32
|
+
TerminalLocation,
|
|
33
|
+
TerminalBuffer
|
|
33
34
|
} from './base/terminal-widget';
|
|
34
35
|
import { Deferred } from '@theia/core/lib/common/promise-util';
|
|
35
|
-
import { TerminalPreferences
|
|
36
|
+
import { TerminalPreferences } from './terminal-preferences';
|
|
36
37
|
import URI from '@theia/core/lib/common/uri';
|
|
37
38
|
import { TerminalService } from './base/terminal-service';
|
|
38
39
|
import { TerminalSearchWidgetFactory, TerminalSearchWidget } from './search/terminal-search-widget';
|
|
@@ -60,6 +61,23 @@ export interface TerminalContribution {
|
|
|
60
61
|
onCreate(term: TerminalWidgetImpl): void;
|
|
61
62
|
}
|
|
62
63
|
|
|
64
|
+
class TerminalBufferImpl implements TerminalBuffer {
|
|
65
|
+
constructor(private readonly term: Terminal) {
|
|
66
|
+
}
|
|
67
|
+
|
|
68
|
+
get length(): number {
|
|
69
|
+
return this.term.buffer.active.length;
|
|
70
|
+
};
|
|
71
|
+
getLines(start: number, length: number): string[] {
|
|
72
|
+
const result: string[] = [];
|
|
73
|
+
for (let i = 0; i < length && this.length - 1 - i >= 0; i++) {
|
|
74
|
+
result.push(this.term.buffer.active.getLine(this.length - 1 - i)!.translateToString());
|
|
75
|
+
}
|
|
76
|
+
return result;
|
|
77
|
+
}
|
|
78
|
+
|
|
79
|
+
}
|
|
80
|
+
|
|
63
81
|
@injectable()
|
|
64
82
|
export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget, ExtractableWidget, EnhancedPreviewWidget {
|
|
65
83
|
readonly isExtractable: boolean = true;
|
|
@@ -123,6 +141,9 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
|
|
|
123
141
|
protected readonly onDataEmitter = new Emitter<string>();
|
|
124
142
|
readonly onData: Event<string> = this.onDataEmitter.event;
|
|
125
143
|
|
|
144
|
+
protected readonly onOutputEmitter = new Emitter<string>();
|
|
145
|
+
readonly onOutput: Event<string> = this.onOutputEmitter.event;
|
|
146
|
+
|
|
126
147
|
protected readonly onKeyEmitter = new Emitter<{ key: string, domEvent: KeyboardEvent }>();
|
|
127
148
|
readonly onKey: Event<{ key: string, domEvent: KeyboardEvent }> = this.onKeyEmitter.event;
|
|
128
149
|
|
|
@@ -134,6 +155,11 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
|
|
|
134
155
|
|
|
135
156
|
protected readonly toDisposeOnConnect = new DisposableCollection();
|
|
136
157
|
|
|
158
|
+
private _buffer: TerminalBuffer;
|
|
159
|
+
override get buffer(): TerminalBuffer {
|
|
160
|
+
return this._buffer;
|
|
161
|
+
}
|
|
162
|
+
|
|
137
163
|
@postConstruct()
|
|
138
164
|
protected init(): void {
|
|
139
165
|
this.setTitle(this.options.title || TerminalWidgetImpl.LABEL);
|
|
@@ -161,7 +187,7 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
|
|
|
161
187
|
|
|
162
188
|
this.term = new Terminal({
|
|
163
189
|
cursorBlink: this.preferences['terminal.integrated.cursorBlinking'],
|
|
164
|
-
cursorStyle: this.
|
|
190
|
+
cursorStyle: this.preferences['terminal.integrated.cursorStyle'] === 'line' ? 'bar' : this.preferences['terminal.integrated.cursorStyle'],
|
|
165
191
|
cursorWidth: this.preferences['terminal.integrated.cursorWidth'],
|
|
166
192
|
fontFamily: this.preferences['terminal.integrated.fontFamily'],
|
|
167
193
|
fontSize: this.preferences['terminal.integrated.fontSize'],
|
|
@@ -172,9 +198,9 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
|
|
|
172
198
|
lineHeight: this.preferences['terminal.integrated.lineHeight'],
|
|
173
199
|
scrollback: this.preferences['terminal.integrated.scrollback'],
|
|
174
200
|
fastScrollSensitivity: this.preferences['terminal.integrated.fastScrollSensitivity'],
|
|
175
|
-
rendererType: this.getTerminalRendererType(this.preferences['terminal.integrated.rendererType']),
|
|
176
201
|
theme: this.themeService.theme
|
|
177
202
|
});
|
|
203
|
+
this._buffer = new TerminalBufferImpl(this.term);
|
|
178
204
|
|
|
179
205
|
this.fitAddon = new FitAddon();
|
|
180
206
|
this.term.loadAddon(this.fitAddon);
|
|
@@ -182,34 +208,12 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
|
|
|
182
208
|
this.initializeLinkHover();
|
|
183
209
|
|
|
184
210
|
this.toDispose.push(this.preferences.onPreferenceChanged(change => {
|
|
185
|
-
|
|
186
|
-
|
|
187
|
-
|
|
188
|
-
let preferenceValue = change.newValue;
|
|
189
|
-
|
|
190
|
-
if (preferenceName === 'rendererType') {
|
|
191
|
-
const newRendererType = preferenceValue as string;
|
|
192
|
-
if (newRendererType !== this.getTerminalRendererType(newRendererType)) {
|
|
193
|
-
// Given terminal renderer type is not supported or invalid
|
|
194
|
-
preferenceValue = DEFAULT_TERMINAL_RENDERER_TYPE;
|
|
195
|
-
}
|
|
196
|
-
} else if (preferenceName === 'cursorBlinking') {
|
|
197
|
-
// Convert the terminal preference into a valid `xterm` option
|
|
198
|
-
preferenceName = 'cursorBlink';
|
|
199
|
-
} else if (preferenceName === 'cursorStyle') {
|
|
200
|
-
preferenceValue = this.getCursorStyle();
|
|
201
|
-
}
|
|
202
|
-
try {
|
|
203
|
-
this.term.setOption(preferenceName, preferenceValue);
|
|
204
|
-
} catch (e) {
|
|
205
|
-
console.debug(`xterm configuration: '${preferenceName}' with value '${preferenceValue}' is not valid.`);
|
|
206
|
-
}
|
|
207
|
-
this.needsResize = true;
|
|
208
|
-
this.update();
|
|
209
|
-
}
|
|
211
|
+
this.updateConfig();
|
|
212
|
+
this.needsResize = true;
|
|
213
|
+
this.update();
|
|
210
214
|
}));
|
|
211
215
|
|
|
212
|
-
this.toDispose.push(this.themeService.onDidChange(() => this.term.
|
|
216
|
+
this.toDispose.push(this.themeService.onDidChange(() => this.term.options.theme = this.themeService.theme));
|
|
213
217
|
this.attachCustomKeyEventHandler();
|
|
214
218
|
const titleChangeListenerDispose = this.term.onTitleChange((title: string) => {
|
|
215
219
|
if (this.options.useServerTitle) {
|
|
@@ -314,25 +318,38 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
|
|
|
314
318
|
return this.terminalKind;
|
|
315
319
|
}
|
|
316
320
|
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
321
|
+
updateConfig(): void {
|
|
322
|
+
this.setCursorBlink(this.preferences.get('terminal.integrated.cursorBlinking'));
|
|
323
|
+
this.setCursorStyle(this.preferences.get('terminal.integrated.cursorStyle'));
|
|
324
|
+
this.setCursorWidth(this.preferences.get('terminal.integrated.cursorWidth'));
|
|
325
|
+
this.term.options.fontFamily = this.preferences.get('terminal.integrated.fontFamily');
|
|
326
|
+
this.term.options.fontSize = this.preferences.get('terminal.integrated.fontSize');
|
|
327
|
+
this.term.options.fontWeight = this.preferences.get('terminal.integrated.fontWeight');
|
|
328
|
+
this.term.options.fontWeightBold = this.preferences.get('terminal.integrated.fontWeightBold');
|
|
329
|
+
this.term.options.drawBoldTextInBrightColors = this.preferences.get('terminal.integrated.drawBoldTextInBrightColors');
|
|
330
|
+
this.term.options.letterSpacing = this.preferences.get('terminal.integrated.letterSpacing');
|
|
331
|
+
this.term.options.lineHeight = this.preferences.get('terminal.integrated.lineHeight');
|
|
332
|
+
this.term.options.scrollback = this.preferences.get('terminal.integrated.scrollback');
|
|
333
|
+
this.term.options.fastScrollSensitivity = this.preferences.get('terminal.integrated.fastScrollSensitivity');
|
|
324
334
|
}
|
|
325
335
|
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
336
|
+
private setCursorBlink(blink: boolean): void {
|
|
337
|
+
if (this.term.options.cursorBlink !== blink) {
|
|
338
|
+
this.term.options.cursorBlink = blink;
|
|
339
|
+
this.term.refresh(0, this.term.rows - 1);
|
|
340
|
+
}
|
|
341
|
+
}
|
|
342
|
+
|
|
343
|
+
private setCursorStyle(style: 'block' | 'underline' | 'bar' | 'line'): void {
|
|
344
|
+
if (this.term.options.cursorStyle !== style) {
|
|
345
|
+
this.term.options.cursorStyle = (style === 'line') ? 'bar' : style;
|
|
346
|
+
}
|
|
347
|
+
}
|
|
348
|
+
|
|
349
|
+
private setCursorWidth(width: number): void {
|
|
350
|
+
if (this.term.options.cursorWidth !== width) {
|
|
351
|
+
this.term.options.cursorWidth = width;
|
|
334
352
|
}
|
|
335
|
-
return DEFAULT_TERMINAL_RENDERER_TYPE;
|
|
336
353
|
}
|
|
337
354
|
|
|
338
355
|
protected initializeLinkHover(): void {
|
|
@@ -611,8 +628,6 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
|
|
|
611
628
|
if (this.needsResize) {
|
|
612
629
|
this.resizeTerminal();
|
|
613
630
|
this.needsResize = false;
|
|
614
|
-
|
|
615
|
-
this.resizeTerminalProcess();
|
|
616
631
|
}
|
|
617
632
|
}
|
|
618
633
|
|
|
@@ -672,16 +687,34 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
|
|
|
672
687
|
}
|
|
673
688
|
this.term.open(this.node);
|
|
674
689
|
|
|
690
|
+
interface ViewportType {
|
|
691
|
+
register(d: Disposable): void;
|
|
692
|
+
_refreshAnimationFrame: number | null;
|
|
693
|
+
_coreBrowserService: {
|
|
694
|
+
window: Window;
|
|
695
|
+
}
|
|
696
|
+
}
|
|
697
|
+
|
|
698
|
+
// Workaround for https://github.com/xtermjs/xterm.js/issues/4775. Can be removed for releases > 5.3.0
|
|
699
|
+
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
700
|
+
const viewPort: ViewportType = (this.term as any)._core.viewport;
|
|
701
|
+
viewPort.register(Disposable.create(() => {
|
|
702
|
+
if (typeof viewPort._refreshAnimationFrame === 'number') {
|
|
703
|
+
viewPort._coreBrowserService.window.cancelAnimationFrame(viewPort._refreshAnimationFrame);
|
|
704
|
+
}
|
|
705
|
+
}));
|
|
706
|
+
|
|
675
707
|
if (isFirefox) {
|
|
676
708
|
// monkey patching intersection observer handling for secondary window support
|
|
677
709
|
// eslint-disable-next-line @typescript-eslint/no-explicit-any
|
|
678
710
|
const renderService: any = (this.term as any)._core._renderService;
|
|
679
|
-
|
|
711
|
+
|
|
712
|
+
const originalFunc: (entry: IntersectionObserverEntry) => void = renderService._handleIntersectionChange.bind(renderService);
|
|
680
713
|
const replacement = function (entry: IntersectionObserverEntry): void {
|
|
681
714
|
if (entry.target.ownerDocument !== document) {
|
|
682
715
|
// in Firefox, the intersection observer always reports the widget as non-intersecting if the dom element
|
|
683
716
|
// is in a different document from when the IntersectionObserver started observing. Since we know
|
|
684
|
-
// that the widget is always "visible" when in a secondary window, so we
|
|
717
|
+
// that the widget is always "visible" when in a secondary window, so we refresh the rows ourselves
|
|
685
718
|
const patchedEvent: IntersectionObserverEntry = {
|
|
686
719
|
...entry,
|
|
687
720
|
isIntersecting: true,
|
|
@@ -692,7 +725,7 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
|
|
|
692
725
|
}
|
|
693
726
|
};
|
|
694
727
|
|
|
695
|
-
renderService.
|
|
728
|
+
renderService._handleIntersectionChange = replacement.bind(renderService);
|
|
696
729
|
}
|
|
697
730
|
|
|
698
731
|
if (this.initialData) {
|
|
@@ -700,18 +733,12 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
|
|
|
700
733
|
}
|
|
701
734
|
this.termOpened = true;
|
|
702
735
|
this.initialData = '';
|
|
703
|
-
|
|
704
|
-
if (isFirefox) {
|
|
705
|
-
// The software scrollbars don't work with xterm.js, so we disable the scrollbar if we are on firefox.
|
|
706
|
-
if (this.term.element) {
|
|
707
|
-
(this.term.element.children.item(0) as HTMLElement).style.overflow = 'hidden';
|
|
708
|
-
}
|
|
709
|
-
}
|
|
710
736
|
}
|
|
711
737
|
|
|
712
738
|
write(data: string): void {
|
|
713
739
|
if (this.termOpened) {
|
|
714
740
|
this.term.write(data);
|
|
741
|
+
this.onOutputEmitter.fire(data);
|
|
715
742
|
} else {
|
|
716
743
|
this.initialData += data;
|
|
717
744
|
}
|
|
@@ -763,6 +790,7 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
|
|
|
763
790
|
|
|
764
791
|
writeLine(text: string): void {
|
|
765
792
|
this.term.writeln(text);
|
|
793
|
+
this.onOutputEmitter.fire(text + '\n');
|
|
766
794
|
}
|
|
767
795
|
|
|
768
796
|
get onTerminalDidClose(): Event<TerminalWidget> {
|
|
@@ -794,9 +822,13 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
|
|
|
794
822
|
return;
|
|
795
823
|
}
|
|
796
824
|
const geo = this.fitAddon.proposeDimensions();
|
|
797
|
-
|
|
798
|
-
|
|
799
|
-
|
|
825
|
+
if (geo) {
|
|
826
|
+
const cols = geo.cols;
|
|
827
|
+
const rows = geo.rows - 1; // subtract one row for margin
|
|
828
|
+
this.term.resize(cols, rows);
|
|
829
|
+
|
|
830
|
+
this.resizeTerminalProcess();
|
|
831
|
+
}
|
|
800
832
|
}
|
|
801
833
|
|
|
802
834
|
protected resizeTerminalProcess(): void {
|
|
@@ -20,7 +20,7 @@ import { ILogger } from '@theia/core/lib/common/logger';
|
|
|
20
20
|
import { TerminalProcess, TerminalProcessOptions, ProcessManager, MultiRingBuffer } from '@theia/process/lib/node';
|
|
21
21
|
import { isWindows, isOSX } from '@theia/core/lib/common';
|
|
22
22
|
import URI from '@theia/core/lib/common/uri';
|
|
23
|
-
import { FileUri } from '@theia/core/lib/
|
|
23
|
+
import { FileUri } from '@theia/core/lib/common/file-uri';
|
|
24
24
|
import { EnvironmentUtils } from '@theia/core/lib/node/environment-utils';
|
|
25
25
|
import { parseArgs } from '@theia/process/lib/node/utils';
|
|
26
26
|
|