@theia/terminal 1.45.1 → 1.46.0-next.106

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.
Files changed (50) hide show
  1. package/lib/browser/index.js +2 -11
  2. package/lib/browser/index.js.map +1 -1
  3. package/lib/browser/search/terminal-search-widget.js +8 -16
  4. package/lib/browser/search/terminal-search-widget.js.map +1 -1
  5. package/lib/browser/terminal-copy-on-selection-handler.js +6 -14
  6. package/lib/browser/terminal-copy-on-selection-handler.js.map +1 -1
  7. package/lib/browser/terminal-file-link-provider.js +8 -16
  8. package/lib/browser/terminal-file-link-provider.js.map +1 -1
  9. package/lib/browser/terminal-frontend-contribution.d.ts +2 -0
  10. package/lib/browser/terminal-frontend-contribution.d.ts.map +1 -1
  11. package/lib/browser/terminal-frontend-contribution.js +72 -49
  12. package/lib/browser/terminal-frontend-contribution.js.map +1 -1
  13. package/lib/browser/terminal-link-provider.js +19 -27
  14. package/lib/browser/terminal-link-provider.js.map +1 -1
  15. package/lib/browser/terminal-preferences.d.ts.map +1 -1
  16. package/lib/browser/terminal-preferences.js +2 -1
  17. package/lib/browser/terminal-preferences.js.map +1 -1
  18. package/lib/browser/terminal-profile-service.js +4 -12
  19. package/lib/browser/terminal-profile-service.js.map +1 -1
  20. package/lib/browser/terminal-quick-open-service.js +13 -21
  21. package/lib/browser/terminal-quick-open-service.js.map +1 -1
  22. package/lib/browser/terminal-theme-service.d.ts.map +1 -1
  23. package/lib/browser/terminal-theme-service.js +12 -16
  24. package/lib/browser/terminal-theme-service.js.map +1 -1
  25. package/lib/browser/terminal-url-link-provider.js +4 -12
  26. package/lib/browser/terminal-url-link-provider.js.map +1 -1
  27. package/lib/browser/terminal-widget-impl.d.ts +4 -11
  28. package/lib/browser/terminal-widget-impl.d.ts.map +1 -1
  29. package/lib/browser/terminal-widget-impl.js +87 -105
  30. package/lib/browser/terminal-widget-impl.js.map +1 -1
  31. package/lib/common/terminal-watcher.js +2 -7
  32. package/lib/common/terminal-watcher.js.map +1 -1
  33. package/lib/node/base-terminal-server.js +6 -17
  34. package/lib/node/base-terminal-server.js.map +1 -1
  35. package/lib/node/index.js +2 -11
  36. package/lib/node/index.js.map +1 -1
  37. package/lib/node/shell-process.js +10 -21
  38. package/lib/node/shell-process.js.map +1 -1
  39. package/lib/node/shell-terminal-server.js +9 -20
  40. package/lib/node/shell-terminal-server.js.map +1 -1
  41. package/lib/node/terminal-backend-contribution.js +6 -14
  42. package/lib/node/terminal-backend-contribution.js.map +1 -1
  43. package/lib/node/terminal-server.js +8 -19
  44. package/lib/node/terminal-server.js.map +1 -1
  45. package/package.json +13 -12
  46. package/src/browser/terminal-frontend-contribution.ts +38 -3
  47. package/src/browser/terminal-preferences.ts +2 -1
  48. package/src/browser/terminal-theme-service.ts +6 -2
  49. package/src/browser/terminal-widget-impl.ts +64 -61
  50. 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, RendererType } from 'xterm';
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';
@@ -32,7 +32,7 @@ import {
32
32
  TerminalLocation
33
33
  } from './base/terminal-widget';
34
34
  import { Deferred } from '@theia/core/lib/common/promise-util';
35
- import { TerminalPreferences, TerminalRendererType, isTerminalRendererType, DEFAULT_TERMINAL_RENDERER_TYPE, CursorStyle } from './terminal-preferences';
35
+ import { TerminalPreferences } from './terminal-preferences';
36
36
  import URI from '@theia/core/lib/common/uri';
37
37
  import { TerminalService } from './base/terminal-service';
38
38
  import { TerminalSearchWidgetFactory, TerminalSearchWidget } from './search/terminal-search-widget';
@@ -161,7 +161,7 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
161
161
 
162
162
  this.term = new Terminal({
163
163
  cursorBlink: this.preferences['terminal.integrated.cursorBlinking'],
164
- cursorStyle: this.getCursorStyle(),
164
+ cursorStyle: this.preferences['terminal.integrated.cursorStyle'] === 'line' ? 'bar' : this.preferences['terminal.integrated.cursorStyle'],
165
165
  cursorWidth: this.preferences['terminal.integrated.cursorWidth'],
166
166
  fontFamily: this.preferences['terminal.integrated.fontFamily'],
167
167
  fontSize: this.preferences['terminal.integrated.fontSize'],
@@ -172,7 +172,6 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
172
172
  lineHeight: this.preferences['terminal.integrated.lineHeight'],
173
173
  scrollback: this.preferences['terminal.integrated.scrollback'],
174
174
  fastScrollSensitivity: this.preferences['terminal.integrated.fastScrollSensitivity'],
175
- rendererType: this.getTerminalRendererType(this.preferences['terminal.integrated.rendererType']),
176
175
  theme: this.themeService.theme
177
176
  });
178
177
 
@@ -182,34 +181,12 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
182
181
  this.initializeLinkHover();
183
182
 
184
183
  this.toDispose.push(this.preferences.onPreferenceChanged(change => {
185
- const lastSeparator = change.preferenceName.lastIndexOf('.');
186
- if (lastSeparator > 0) {
187
- let preferenceName = change.preferenceName.substring(lastSeparator + 1);
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
- }
184
+ this.updateConfig();
185
+ this.needsResize = true;
186
+ this.update();
210
187
  }));
211
188
 
212
- this.toDispose.push(this.themeService.onDidChange(() => this.term.setOption('theme', this.themeService.theme)));
189
+ this.toDispose.push(this.themeService.onDidChange(() => this.term.options.theme = this.themeService.theme));
213
190
  this.attachCustomKeyEventHandler();
214
191
  const titleChangeListenerDispose = this.term.onTitleChange((title: string) => {
215
192
  if (this.options.useServerTitle) {
@@ -314,25 +291,38 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
314
291
  return this.terminalKind;
315
292
  }
316
293
 
317
- /**
318
- * Get the cursor style compatible with `xterm`.
319
- * @returns CursorStyle
320
- */
321
- private getCursorStyle(): CursorStyle {
322
- const value = this.preferences['terminal.integrated.cursorStyle'];
323
- return value === 'line' ? 'bar' : value;
294
+ updateConfig(): void {
295
+ this.setCursorBlink(this.preferences.get('terminal.integrated.cursorBlinking'));
296
+ this.setCursorStyle(this.preferences.get('terminal.integrated.cursorStyle'));
297
+ this.setCursorWidth(this.preferences.get('terminal.integrated.cursorWidth'));
298
+ this.term.options.fontFamily = this.preferences.get('terminal.integrated.fontFamily');
299
+ this.term.options.fontSize = this.preferences.get('terminal.integrated.fontSize');
300
+ this.term.options.fontWeight = this.preferences.get('terminal.integrated.fontWeight');
301
+ this.term.options.fontWeightBold = this.preferences.get('terminal.integrated.fontWeightBold');
302
+ this.term.options.drawBoldTextInBrightColors = this.preferences.get('terminal.integrated.drawBoldTextInBrightColors');
303
+ this.term.options.letterSpacing = this.preferences.get('terminal.integrated.letterSpacing');
304
+ this.term.options.lineHeight = this.preferences.get('terminal.integrated.lineHeight');
305
+ this.term.options.scrollback = this.preferences.get('terminal.integrated.scrollback');
306
+ this.term.options.fastScrollSensitivity = this.preferences.get('terminal.integrated.fastScrollSensitivity');
324
307
  }
325
308
 
326
- /**
327
- * Returns given renderer type if it is valid and supported or default renderer otherwise.
328
- *
329
- * @param terminalRendererType desired terminal renderer type
330
- */
331
- private getTerminalRendererType(terminalRendererType?: string | TerminalRendererType): RendererType {
332
- if (terminalRendererType && isTerminalRendererType(terminalRendererType)) {
333
- return terminalRendererType;
309
+ private setCursorBlink(blink: boolean): void {
310
+ if (this.term.options.cursorBlink !== blink) {
311
+ this.term.options.cursorBlink = blink;
312
+ this.term.refresh(0, this.term.rows - 1);
313
+ }
314
+ }
315
+
316
+ private setCursorStyle(style: 'block' | 'underline' | 'bar' | 'line'): void {
317
+ if (this.term.options.cursorStyle !== style) {
318
+ this.term.options.cursorStyle = (style === 'line') ? 'bar' : style;
319
+ }
320
+ }
321
+
322
+ private setCursorWidth(width: number): void {
323
+ if (this.term.options.cursorWidth !== width) {
324
+ this.term.options.cursorWidth = width;
334
325
  }
335
- return DEFAULT_TERMINAL_RENDERER_TYPE;
336
326
  }
337
327
 
338
328
  protected initializeLinkHover(): void {
@@ -611,8 +601,6 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
611
601
  if (this.needsResize) {
612
602
  this.resizeTerminal();
613
603
  this.needsResize = false;
614
-
615
- this.resizeTerminalProcess();
616
604
  }
617
605
  }
618
606
 
@@ -672,16 +660,34 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
672
660
  }
673
661
  this.term.open(this.node);
674
662
 
663
+ interface ViewportType {
664
+ register(d: Disposable): void;
665
+ _refreshAnimationFrame: number | null;
666
+ _coreBrowserService: {
667
+ window: Window;
668
+ }
669
+ }
670
+
671
+ // Workaround for https://github.com/xtermjs/xterm.js/issues/4775. Can be removed for releases > 5.3.0
672
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
673
+ const viewPort: ViewportType = (this.term as any)._core.viewport;
674
+ viewPort.register(Disposable.create(() => {
675
+ if (typeof viewPort._refreshAnimationFrame === 'number') {
676
+ viewPort._coreBrowserService.window.cancelAnimationFrame(viewPort._refreshAnimationFrame);
677
+ }
678
+ }));
679
+
675
680
  if (isFirefox) {
676
681
  // monkey patching intersection observer handling for secondary window support
677
682
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
678
683
  const renderService: any = (this.term as any)._core._renderService;
679
- const originalFunc: (entry: IntersectionObserverEntry) => void = renderService._onIntersectionChange.bind(renderService);
684
+
685
+ const originalFunc: (entry: IntersectionObserverEntry) => void = renderService._handleIntersectionChange.bind(renderService);
680
686
  const replacement = function (entry: IntersectionObserverEntry): void {
681
687
  if (entry.target.ownerDocument !== document) {
682
688
  // in Firefox, the intersection observer always reports the widget as non-intersecting if the dom element
683
689
  // 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 mark the entry as "intersecting"
690
+ // that the widget is always "visible" when in a secondary window, so we refresh the rows ourselves
685
691
  const patchedEvent: IntersectionObserverEntry = {
686
692
  ...entry,
687
693
  isIntersecting: true,
@@ -692,7 +698,7 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
692
698
  }
693
699
  };
694
700
 
695
- renderService._onIntersectionChange = replacement;
701
+ renderService._handleIntersectionChange = replacement.bind(renderService);
696
702
  }
697
703
 
698
704
  if (this.initialData) {
@@ -700,13 +706,6 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
700
706
  }
701
707
  this.termOpened = true;
702
708
  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
709
  }
711
710
 
712
711
  write(data: string): void {
@@ -794,9 +793,13 @@ export class TerminalWidgetImpl extends TerminalWidget implements StatefulWidget
794
793
  return;
795
794
  }
796
795
  const geo = this.fitAddon.proposeDimensions();
797
- const cols = geo.cols;
798
- const rows = geo.rows - 1; // subtract one row for margin
799
- this.term.resize(cols, rows);
796
+ if (geo) {
797
+ const cols = geo.cols;
798
+ const rows = geo.rows - 1; // subtract one row for margin
799
+ this.term.resize(cols, rows);
800
+
801
+ this.resizeTerminalProcess();
802
+ }
800
803
  }
801
804
 
802
805
  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/node/file-uri';
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