@theia/core 1.24.0-next.21 → 1.24.0-next.26

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 (51) hide show
  1. package/README.md +3 -3
  2. package/lib/browser/common-frontend-contribution.d.ts +13 -3
  3. package/lib/browser/common-frontend-contribution.d.ts.map +1 -1
  4. package/lib/browser/common-frontend-contribution.js +63 -4
  5. package/lib/browser/common-frontend-contribution.js.map +1 -1
  6. package/lib/browser/frontend-application-module.d.ts.map +1 -1
  7. package/lib/browser/frontend-application-module.js +4 -1
  8. package/lib/browser/frontend-application-module.js.map +1 -1
  9. package/lib/browser/save-resource-service.d.ts +31 -0
  10. package/lib/browser/save-resource-service.d.ts.map +1 -0
  11. package/lib/browser/save-resource-service.js +52 -0
  12. package/lib/browser/save-resource-service.js.map +1 -0
  13. package/lib/browser/saveable.d.ts +1 -0
  14. package/lib/browser/saveable.d.ts.map +1 -1
  15. package/lib/browser/saveable.js +6 -0
  16. package/lib/browser/saveable.js.map +1 -1
  17. package/lib/browser/shell/application-shell.d.ts +4 -0
  18. package/lib/browser/shell/application-shell.d.ts.map +1 -1
  19. package/lib/browser/shell/application-shell.js +37 -1
  20. package/lib/browser/shell/application-shell.js.map +1 -1
  21. package/lib/browser/shell/side-panel-handler.d.ts +1 -0
  22. package/lib/browser/shell/side-panel-handler.d.ts.map +1 -1
  23. package/lib/browser/shell/side-panel-handler.js +7 -2
  24. package/lib/browser/shell/side-panel-handler.js.map +1 -1
  25. package/lib/browser/shell/tab-bars.d.ts +4 -2
  26. package/lib/browser/shell/tab-bars.d.ts.map +1 -1
  27. package/lib/browser/shell/tab-bars.js +16 -2
  28. package/lib/browser/shell/tab-bars.js.map +1 -1
  29. package/lib/browser/view-container.d.ts.map +1 -1
  30. package/lib/browser/view-container.js +5 -1
  31. package/lib/browser/view-container.js.map +1 -1
  32. package/lib/browser/widgets/widget.d.ts +6 -1
  33. package/lib/browser/widgets/widget.d.ts.map +1 -1
  34. package/lib/browser/widgets/widget.js +30 -1
  35. package/lib/browser/widgets/widget.js.map +1 -1
  36. package/lib/electron-main/theia-electron-window.d.ts +0 -4
  37. package/lib/electron-main/theia-electron-window.d.ts.map +1 -1
  38. package/lib/electron-main/theia-electron-window.js +0 -21
  39. package/lib/electron-main/theia-electron-window.js.map +1 -1
  40. package/package.json +3 -3
  41. package/src/browser/common-frontend-contribution.ts +73 -8
  42. package/src/browser/frontend-application-module.ts +5 -1
  43. package/src/browser/save-resource-service.ts +45 -0
  44. package/src/browser/saveable.ts +5 -0
  45. package/src/browser/shell/application-shell.ts +45 -1
  46. package/src/browser/shell/side-panel-handler.ts +8 -2
  47. package/src/browser/shell/tab-bars.ts +17 -2
  48. package/src/browser/style/tabs.css +12 -2
  49. package/src/browser/view-container.ts +4 -2
  50. package/src/browser/widgets/widget.ts +29 -1
  51. package/src/electron-main/theia-electron-window.ts +1 -22
@@ -1 +1 @@
1
- {"version":3,"file":"theia-electron-window.d.ts","sourceRoot":"","sources":["../../src/electron-main/theia-electron-window.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,EAAoF,UAAU,EAAE,MAAM,gDAAgD,CAAC;AAC9J,OAAO,EAAE,aAAa,EAAE,+BAA+B,EAA2B,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEvI,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,KAAK,EAAa,MAAM,WAAW,CAAC;AAG5E;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,+BAA+B;IAC9E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,yBAAyB,eAAsC,CAAC;AAE7E,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AACzE,oBAAY,uBAAuB,GAAG,yBAAyB,CAAC;AAEhE,qBACa,mBAAmB;IACO,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC;IACxD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IAC5C,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,8BAA8B,CAAC;IAEnG,SAAS,CAAC,iBAAiB,gBAAuB;IAElD,IAAI,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,CAE5B;IAED,SAAS,CAAC,QAAQ,CAAC,SAAS,uBAAoD;IAEhF,SAAS,CAAC,OAAO,EAAE,aAAa,CAAC;IACjC,IAAI,MAAM,IAAI,aAAa,CAE1B;IAED,SAAS,CAAC,gBAAgB,UAAS;IACnC,SAAS,CAAC,gBAAgB,EAAE,wBAAwB,CAAU;IAG9D,SAAS,CAAC,IAAI,IAAI,IAAI;IAWtB;;OAEG;IACH,SAAS,CAAC,iBAAiB,IAAI,IAAI;IAInC,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAetC,SAAS,CAAC,aAAa,IAAI,IAAI;IAK/B;;OAEG;IACH,SAAS,CAAC,qBAAqB,IAAI,IAAI;IAiBvC,KAAK,CAAC,MAAM,GAAE,UAA6B,GAAG,OAAO,CAAC,OAAO,CAAC;IAI9D,SAAS,CAAC,MAAM,IAAI,IAAI;cAOR,iBAAiB,CAAC,cAAc,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAqBtG,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAmB/D,SAAS,CAAC,qBAAqB,IAAI,IAAI;IAQvC,SAAS,CAAC,qBAAqB,IAAI,IAAI;IAQvC,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAQtC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,YAAY,GAAG,OAAO;IAI5C,OAAO,IAAI,IAAI;CAGlB;AAED,MAAM,WAAW,0BAA0B;IACvC,CAAC,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,yBAAyB,GAAG,mBAAmB,CAAC;CAChG;AAED,eAAO,MAAM,0BAA0B,eAAuC,CAAC"}
1
+ {"version":3,"file":"theia-electron-window.d.ts","sourceRoot":"","sources":["../../src/electron-main/theia-electron-window.ts"],"names":[],"mappings":"AAgBA,OAAO,EAAE,yBAAyB,EAAE,MAAM,4BAA4B,CAAC;AACvE,OAAO,EAAE,wBAAwB,EAAE,MAAM,sCAAsC,CAAC;AAChF,OAAO,EAAoF,UAAU,EAAE,MAAM,gDAAgD,CAAC;AAC9J,OAAO,EAAE,aAAa,EAAE,+BAA+B,EAAW,YAAY,EAAE,MAAM,gCAAgC,CAAC;AAEvH,OAAO,EAAE,8BAA8B,EAAE,MAAM,2BAA2B,CAAC;AAC3E,OAAO,EAAE,oBAAoB,EAAE,OAAO,EAAE,KAAK,EAAa,MAAM,WAAW,CAAC;AAG5E;;GAEG;AACH,MAAM,WAAW,yBAA0B,SAAQ,+BAA+B;IAC9E,WAAW,CAAC,EAAE,OAAO,CAAC;IACtB,YAAY,CAAC,EAAE,OAAO,CAAC;IACvB;;;;OAIG;IACH,YAAY,CAAC,EAAE,MAAM,CAAC;CACzB;AAED,eAAO,MAAM,yBAAyB,eAAsC,CAAC;AAE7E,eAAO,MAAM,uBAAuB,eAAoC,CAAC;AACzE,oBAAY,uBAAuB,GAAG,yBAAyB,CAAC;AAEhE,qBACa,mBAAmB;IACO,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,yBAAyB,CAAC;IACxD,SAAS,CAAC,QAAQ,CAAC,MAAM,EAAE,uBAAuB,CAAC;IAC5C,SAAS,CAAC,QAAQ,CAAC,OAAO,EAAE,8BAA8B,CAAC;IAEnG,SAAS,CAAC,iBAAiB,gBAAuB;IAElD,IAAI,UAAU,IAAI,KAAK,CAAC,IAAI,CAAC,CAE5B;IAED,SAAS,CAAC,QAAQ,CAAC,SAAS,uBAAoD;IAEhF,SAAS,CAAC,OAAO,EAAE,aAAa,CAAC;IACjC,IAAI,MAAM,IAAI,aAAa,CAE1B;IAED,SAAS,CAAC,gBAAgB,UAAS;IACnC,SAAS,CAAC,gBAAgB,EAAE,wBAAwB,CAAU;IAG9D,SAAS,CAAC,IAAI,IAAI,IAAI;IAUtB;;OAEG;IACH,SAAS,CAAC,iBAAiB,IAAI,IAAI;IAInC,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAetC,SAAS,CAAC,aAAa,IAAI,IAAI;IAK/B,KAAK,CAAC,MAAM,GAAE,UAA6B,GAAG,OAAO,CAAC,OAAO,CAAC;IAI9D,SAAS,CAAC,MAAM,IAAI,IAAI;cAOR,iBAAiB,CAAC,cAAc,EAAE,MAAM,OAAO,EAAE,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAqBtG,SAAS,CAAC,eAAe,CAAC,MAAM,EAAE,UAAU,GAAG,OAAO,CAAC,OAAO,CAAC;IAmB/D,SAAS,CAAC,qBAAqB,IAAI,IAAI;IAQvC,SAAS,CAAC,qBAAqB,IAAI,IAAI;IAQvC,SAAS,CAAC,oBAAoB,IAAI,IAAI;IAQtC,SAAS,CAAC,QAAQ,CAAC,CAAC,EAAE,YAAY,GAAG,OAAO;IAI5C,OAAO,IAAI,IAAI;CAGlB;AAED,MAAM,WAAW,0BAA0B;IACvC,CAAC,OAAO,EAAE,yBAAyB,EAAE,MAAM,EAAE,yBAAyB,GAAG,mBAAmB,CAAC;CAChG;AAED,eAAO,MAAM,0BAA0B,eAAuC,CAAC"}
@@ -50,7 +50,6 @@ let TheiaElectronWindow = class TheiaElectronWindow {
50
50
  this._window = new electron_1.BrowserWindow(this.options);
51
51
  this._window.setMenuBarVisibility(false);
52
52
  this.attachReadyToShow();
53
- this.attachGlobalShortcuts();
54
53
  this.restoreMaximizedState();
55
54
  this.attachCloseListeners();
56
55
  this.trackApplicationState();
@@ -80,26 +79,6 @@ let TheiaElectronWindow = class TheiaElectronWindow {
80
79
  this.closeIsConfirmed = true;
81
80
  this._window.close();
82
81
  }
83
- /**
84
- * Catch certain keybindings to prevent reloading the window using keyboard shortcuts.
85
- */
86
- attachGlobalShortcuts() {
87
- var _a;
88
- const handler = ((_a = this.config.electron) === null || _a === void 0 ? void 0 : _a.disallowReloadKeybinding)
89
- ? () => { }
90
- : () => this.reload();
91
- const accelerators = ['CmdOrCtrl+R', 'F5'];
92
- (0, event_utils_1.createDisposableListener)(this._window, 'focus', () => {
93
- for (const accelerator of accelerators) {
94
- electron_1.globalShortcut.register(accelerator, handler);
95
- }
96
- }, this.toDispose);
97
- (0, event_utils_1.createDisposableListener)(this._window, 'blur', () => {
98
- for (const accelerator of accelerators) {
99
- electron_1.globalShortcut.unregister(accelerator);
100
- }
101
- }, this.toDispose);
102
- }
103
82
  close(reason = electron_messages_1.StopReason.Close) {
104
83
  return this.handleStopRequest(() => this.doCloseWindow(), reason);
105
84
  }
@@ -1 +1 @@
1
- {"version":3,"file":"theia-electron-window.js","sourceRoot":"","sources":["../../src/electron-main/theia-electron-window.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"theia-electron-window.js","sourceRoot":"","sources":["../../src/electron-main/theia-electron-window.ts"],"names":[],"mappings":"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"}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@theia/core",
3
- "version": "1.24.0-next.21+95383a9d823",
3
+ "version": "1.24.0-next.26+3da6276f571",
4
4
  "description": "Theia is a cloud & desktop IDE framework implemented in TypeScript.",
5
5
  "main": "lib/common/index.js",
6
6
  "typings": "lib/common/index.d.ts",
@@ -17,7 +17,7 @@
17
17
  "@phosphor/virtualdom": "1",
18
18
  "@phosphor/widgets": "1",
19
19
  "@primer/octicons-react": "^9.0.0",
20
- "@theia/application-package": "1.24.0-next.21+95383a9d823",
20
+ "@theia/application-package": "1.24.0-next.26+3da6276f571",
21
21
  "@types/body-parser": "^1.16.4",
22
22
  "@types/cookie": "^0.3.3",
23
23
  "@types/dompurify": "^2.2.2",
@@ -190,5 +190,5 @@
190
190
  "nyc": {
191
191
  "extends": "../../configs/nyc.json"
192
192
  },
193
- "gitHead": "95383a9d8234b59309225058d47c654e050c6741"
193
+ "gitHead": "3da6276f571891af259a3357acb94731e2abf1b0"
194
194
  }
@@ -27,11 +27,11 @@ import { SelectionService } from '../common/selection-service';
27
27
  import { MessageService } from '../common/message-service';
28
28
  import { OpenerService, open } from '../browser/opener-service';
29
29
  import { ApplicationShell } from './shell/application-shell';
30
- import { SHELL_TABBAR_CONTEXT_CLOSE, SHELL_TABBAR_CONTEXT_COPY, SHELL_TABBAR_CONTEXT_SPLIT } from './shell/tab-bars';
30
+ import { SHELL_TABBAR_CONTEXT_CLOSE, SHELL_TABBAR_CONTEXT_COPY, SHELL_TABBAR_CONTEXT_PIN, SHELL_TABBAR_CONTEXT_SPLIT } from './shell/tab-bars';
31
31
  import { AboutDialog } from './about-dialog';
32
32
  import * as browser from './browser';
33
33
  import URI from '../common/uri';
34
- import { ContextKeyService } from './context-key-service';
34
+ import { ContextKey, ContextKeyService } from './context-key-service';
35
35
  import { OS, isOSX, isWindows } from '../common/os';
36
36
  import { ResourceContextKey } from './resource-context-key';
37
37
  import { UriSelection } from '../common/selection';
@@ -50,7 +50,7 @@ import { EncodingRegistry } from './encoding-registry';
50
50
  import { UTF8 } from '../common/encodings';
51
51
  import { EnvVariablesServer } from '../common/env-variables';
52
52
  import { AuthenticationService } from './authentication-service';
53
- import { FormatType, Saveable } from './saveable';
53
+ import { FormatType, Saveable, SaveOptions } from './saveable';
54
54
  import { QuickInputService, QuickPick, QuickPickItem } from './quick-input';
55
55
  import { AsyncLocalizationProvider } from '../common/i18n/localization';
56
56
  import { nls } from '../common/nls';
@@ -59,6 +59,8 @@ import { ConfirmDialog, confirmExit, Dialog } from './dialogs';
59
59
  import { WindowService } from './window/window-service';
60
60
  import { FrontendApplicationConfigProvider } from './frontend-application-config-provider';
61
61
  import { DecorationStyle } from './decoration-style';
62
+ import { isPinned, Title, togglePinned, Widget } from './widgets';
63
+ import { SaveResourceService } from './save-resource-service';
62
64
 
63
65
  export namespace CommonMenus {
64
66
 
@@ -241,6 +243,16 @@ export namespace CommonCommands {
241
243
  category: VIEW_CATEGORY,
242
244
  label: 'Toggle Status Bar Visibility'
243
245
  });
246
+ export const PIN_TAB = Command.toDefaultLocalizedCommand({
247
+ id: 'workbench.action.pinEditor',
248
+ category: VIEW_CATEGORY,
249
+ label: 'Pin Editor'
250
+ });
251
+ export const UNPIN_TAB = Command.toDefaultLocalizedCommand({
252
+ id: 'workbench.action.unpinEditor',
253
+ category: VIEW_CATEGORY,
254
+ label: 'Unpin Editor'
255
+ });
244
256
  export const TOGGLE_MAXIMIZED = Command.toLocalizedCommand({
245
257
  id: 'core.toggleMaximized',
246
258
  category: VIEW_CATEGORY,
@@ -327,7 +339,8 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
327
339
  @inject(MessageService) protected readonly messageService: MessageService,
328
340
  @inject(OpenerService) protected readonly openerService: OpenerService,
329
341
  @inject(AboutDialog) protected readonly aboutDialog: AboutDialog,
330
- @inject(AsyncLocalizationProvider) protected readonly localizationProvider: AsyncLocalizationProvider
342
+ @inject(AsyncLocalizationProvider) protected readonly localizationProvider: AsyncLocalizationProvider,
343
+ @inject(SaveResourceService) protected readonly saveResourceService: SaveResourceService,
331
344
  ) { }
332
345
 
333
346
  @inject(ContextKeyService)
@@ -372,6 +385,8 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
372
385
  @inject(WindowService)
373
386
  protected readonly windowService: WindowService;
374
387
 
388
+ protected pinnedKey: ContextKey<boolean>;
389
+
375
390
  async configure(app: FrontendApplication): Promise<void> {
376
391
  const configDirUri = await this.environments.getConfigDirUri();
377
392
  // Global settings
@@ -385,6 +400,10 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
385
400
  this.contextKeyService.createKey<boolean>('isWindows', OS.type() === OS.Type.Windows);
386
401
  this.contextKeyService.createKey<boolean>('isWeb', !this.isElectron());
387
402
 
403
+ this.pinnedKey = this.contextKeyService.createKey<boolean>('activeEditorIsPinned', false);
404
+ this.updatePinnedKey();
405
+ this.shell.onDidChangeActiveWidget(() => this.updatePinnedKey());
406
+
388
407
  this.initResourceContextKeys();
389
408
  this.registerCtrlWHandling();
390
409
 
@@ -427,6 +446,13 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
427
446
  }
428
447
  }
429
448
 
449
+ protected updatePinnedKey(): void {
450
+ const activeTab = this.shell.findTabBar();
451
+ const pinningTarget = activeTab && this.shell.findTitle(activeTab);
452
+ const value = pinningTarget && isPinned(pinningTarget);
453
+ this.pinnedKey.set(value);
454
+ }
455
+
430
456
  protected updateThemePreference(preferenceName: 'workbench.colorTheme' | 'workbench.iconTheme'): void {
431
457
  const inspect = this.preferenceService.inspect<string | null>(preferenceName);
432
458
  const workspaceValue = inspect && inspect.workspaceValue;
@@ -636,6 +662,16 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
636
662
  label: nls.localizeByDefault('Toggle Menu Bar'),
637
663
  order: '0'
638
664
  });
665
+ registry.registerMenuAction(SHELL_TABBAR_CONTEXT_PIN, {
666
+ commandId: CommonCommands.PIN_TAB.id,
667
+ label: nls.localizeByDefault('Pin'),
668
+ order: '7'
669
+ });
670
+ registry.registerMenuAction(SHELL_TABBAR_CONTEXT_PIN, {
671
+ commandId: CommonCommands.UNPIN_TAB.id,
672
+ label: nls.localizeByDefault('Unpin'),
673
+ order: '8'
674
+ });
639
675
  registry.registerMenuAction(CommonMenus.HELP, {
640
676
  commandId: CommonCommands.ABOUT_COMMAND.id,
641
677
  label: CommonCommands.ABOUT_COMMAND.label,
@@ -855,10 +891,10 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
855
891
  });
856
892
 
857
893
  commandRegistry.registerCommand(CommonCommands.SAVE, {
858
- execute: () => this.shell.save({ formatType: FormatType.ON })
894
+ execute: () => this.save({ formatType: FormatType.ON })
859
895
  });
860
896
  commandRegistry.registerCommand(CommonCommands.SAVE_WITHOUT_FORMATTING, {
861
- execute: () => this.shell.save({ formatType: FormatType.OFF })
897
+ execute: () => this.save({ formatType: FormatType.OFF })
862
898
  });
863
899
  commandRegistry.registerCommand(CommonCommands.SAVE_ALL, {
864
900
  execute: () => this.shell.saveAll({ formatType: FormatType.DIRTY })
@@ -877,16 +913,30 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
877
913
  commandRegistry.registerCommand(CommonCommands.SELECT_ICON_THEME, {
878
914
  execute: () => this.selectIconTheme()
879
915
  });
880
-
916
+ commandRegistry.registerCommand(CommonCommands.PIN_TAB, new CurrentWidgetCommandAdapter(this.shell, {
917
+ isEnabled: title => Boolean(title && !isPinned(title)),
918
+ execute: title => this.togglePinned(title),
919
+ }));
920
+ commandRegistry.registerCommand(CommonCommands.UNPIN_TAB, new CurrentWidgetCommandAdapter(this.shell, {
921
+ isEnabled: title => Boolean(title && isPinned(title)),
922
+ execute: title => this.togglePinned(title),
923
+ }));
881
924
  commandRegistry.registerCommand(CommonCommands.CONFIGURE_DISPLAY_LANGUAGE, {
882
925
  execute: () => this.configureDisplayLanguage()
883
926
  });
884
927
  }
885
928
 
886
- private isElectron(): boolean {
929
+ protected isElectron(): boolean {
887
930
  return environment.electron.is();
888
931
  }
889
932
 
933
+ protected togglePinned(title?: Title<Widget>): void {
934
+ if (title) {
935
+ togglePinned(title);
936
+ this.updatePinnedKey();
937
+ }
938
+ }
939
+
890
940
  registerKeybindings(registry: KeybindingRegistry): void {
891
941
  if (supportCut) {
892
942
  registry.registerKeybinding({
@@ -996,10 +1046,25 @@ export class CommonFrontendContribution implements FrontendApplicationContributi
996
1046
  {
997
1047
  command: CommonCommands.SELECT_COLOR_THEME.id,
998
1048
  keybinding: 'ctrlcmd+k ctrlcmd+t'
1049
+ },
1050
+ {
1051
+ command: CommonCommands.PIN_TAB.id,
1052
+ keybinding: 'ctrlcmd+k shift+enter',
1053
+ when: '!activeEditorIsPinned'
1054
+ },
1055
+ {
1056
+ command: CommonCommands.UNPIN_TAB.id,
1057
+ keybinding: 'ctrlcmd+k shift+enter',
1058
+ when: 'activeEditorIsPinned'
999
1059
  }
1000
1060
  );
1001
1061
  }
1002
1062
 
1063
+ protected async save(options?: SaveOptions): Promise<void> {
1064
+ const widget = this.shell.currentWidget;
1065
+ this.saveResourceService.save(widget, options);
1066
+ }
1067
+
1003
1068
  protected async openAbout(): Promise<void> {
1004
1069
  this.aboutDialog.open();
1005
1070
  }
@@ -120,6 +120,7 @@ import {
120
120
  import { RendererHost } from './widgets';
121
121
  import { TooltipService, TooltipServiceImpl } from './tooltip-service';
122
122
  import { bindFrontendStopwatch, bindBackendStopwatch } from './performance';
123
+ import { SaveResourceService } from './save-resource-service';
123
124
 
124
125
  export { bindResourceProvider, bindMessageService, bindPreferenceService };
125
126
 
@@ -171,7 +172,8 @@ export const frontendApplicationModule = new ContainerModule((bind, unbind, isBo
171
172
  const tabBarDecoratorService = container.get(TabBarDecoratorService);
172
173
  const iconThemeService = container.get(IconThemeService);
173
174
  const selectionService = container.get(SelectionService);
174
- return new TabBarRenderer(contextMenuRenderer, tabBarDecoratorService, iconThemeService, selectionService);
175
+ const commandService = container.get<CommandService>(CommandService);
176
+ return new TabBarRenderer(contextMenuRenderer, tabBarDecoratorService, iconThemeService, selectionService, commandService);
175
177
  });
176
178
 
177
179
  bindContributionProvider(bind, TabBarDecorator);
@@ -394,4 +396,6 @@ export const frontendApplicationModule = new ContainerModule((bind, unbind, isBo
394
396
 
395
397
  bindFrontendStopwatch(bind);
396
398
  bindBackendStopwatch(bind);
399
+
400
+ bind(SaveResourceService).toSelf().inSingletonScope();
397
401
  });
@@ -0,0 +1,45 @@
1
+ /********************************************************************************
2
+ * Copyright (C) 2022 Arm and others.
3
+ *
4
+ * This program and the accompanying materials are made available under the
5
+ * terms of the Eclipse Public License v. 2.0 which is available at
6
+ * http://www.eclipse.org/legal/epl-2.0.
7
+ *
8
+ * This Source Code may also be made available under the following Secondary
9
+ * Licenses when the conditions for such availability set forth in the Eclipse
10
+ * Public License v. 2.0 are satisfied: GNU General Public License, version 2
11
+ * with the GNU Classpath Exception which is available at
12
+ * https://www.gnu.org/software/classpath/license.html.
13
+ *
14
+ * SPDX-License-Identifier: EPL-2.0 OR GPL-2.0 WITH Classpath-exception-2.0
15
+ ********************************************************************************/
16
+
17
+ import { injectable } from 'inversify';
18
+ import { Saveable, SaveOptions } from './saveable';
19
+ import { Widget } from './widgets';
20
+
21
+ @injectable()
22
+ export class SaveResourceService {
23
+
24
+ /**
25
+ * Indicate if the document can be saved ('Save' command should be disable if not).
26
+ */
27
+ canSave(saveable: Saveable): boolean {
28
+ // By default, we never allow a document to be saved if it is untitled.
29
+ return Saveable.isDirty(saveable) && !Saveable.isUntitled(saveable);
30
+ }
31
+
32
+ /**
33
+ * Saves the document.
34
+ *
35
+ * This function is called only if `canSave` returns true, which means the document is not untitled
36
+ * and is thus saveable.
37
+ */
38
+ async save(widget: Widget | undefined, options?: SaveOptions): Promise<void> {
39
+ const saveable = Saveable.get(widget);
40
+ if (saveable && this.canSave(saveable)) {
41
+ await saveable.save(options);
42
+ }
43
+ }
44
+
45
+ }
@@ -21,6 +21,7 @@ import { MaybePromise } from '../common/types';
21
21
  import { Key } from './keyboard/keys';
22
22
  import { AbstractDialog } from './dialogs';
23
23
  import { waitForClosed } from './widgets';
24
+ import { URI } from 'vscode-uri';
24
25
 
25
26
  export interface Saveable {
26
27
  readonly dirty: boolean;
@@ -65,6 +66,10 @@ export namespace Saveable {
65
66
  return !!arg && ('dirty' in arg) && ('onDirtyChanged' in arg);
66
67
  }
67
68
  // eslint-disable-next-line @typescript-eslint/no-explicit-any
69
+ export function isUntitled(arg: any): boolean {
70
+ return !!arg && ('uri' in arg) && URI.parse((arg as { uri: string; }).uri).scheme === 'untitled';
71
+ }
72
+ // eslint-disable-next-line @typescript-eslint/no-explicit-any
68
73
  export function get(arg: any): Saveable | undefined {
69
74
  if (is(arg)) {
70
75
  return arg;
@@ -596,8 +596,10 @@ export class ApplicationShell extends Widget {
596
596
  return {
597
597
  version: applicationShellLayoutVersion,
598
598
  mainPanel: this.mainPanel.saveLayout(),
599
+ mainPanelPinned: this.getPinnedMainWidgets(),
599
600
  bottomPanel: {
600
601
  config: this.bottomPanel.saveLayout(),
602
+ pinned: this.getPinnedBottomWidgets(),
601
603
  size: this.bottomPanel.isVisible ? this.getBottomPanelSize() : this.bottomPanelState.lastPanelSize,
602
604
  expanded: this.isExpanded('bottom')
603
605
  },
@@ -607,6 +609,28 @@ export class ApplicationShell extends Widget {
607
609
  };
608
610
  }
609
611
 
612
+ // Get an array corresponding to main panel widgets' pinned state.
613
+ getPinnedMainWidgets(): boolean[] {
614
+ const pinned: boolean[] = [];
615
+
616
+ toArray(this.mainPanel.widgets()).forEach((a, i) => {
617
+ pinned[i] = a.title.className.indexOf('theia-mod-pinned') >= 0;
618
+ });
619
+
620
+ return pinned;
621
+ }
622
+
623
+ // Get an array corresponding to bottom panel widgets' pinned state.
624
+ getPinnedBottomWidgets(): boolean[] {
625
+ const pinned: boolean[] = [];
626
+
627
+ toArray(this.bottomPanel.widgets()).forEach((a, i) => {
628
+ pinned[i] = a.title.className.indexOf('theia-mod-pinned') >= 0;
629
+ });
630
+
631
+ return pinned;
632
+ }
633
+
610
634
  /**
611
635
  * Compute the current height of the bottom panel. This implementation assumes that the container
612
636
  * of the bottom panel is a `SplitPanel`.
@@ -639,7 +663,7 @@ export class ApplicationShell extends Widget {
639
663
  * Apply a shell layout that has been previously created with `getLayoutData`.
640
664
  */
641
665
  async setLayoutData(layoutData: ApplicationShell.LayoutData): Promise<void> {
642
- const { mainPanel, bottomPanel, leftPanel, rightPanel, activeWidgetId } = layoutData;
666
+ const { mainPanel, mainPanelPinned, bottomPanel, leftPanel, rightPanel, activeWidgetId } = layoutData;
643
667
  if (leftPanel) {
644
668
  this.leftPanelHandler.setLayoutData(leftPanel);
645
669
  this.registerWithFocusTracker(leftPanel);
@@ -663,6 +687,15 @@ export class ApplicationShell extends Widget {
663
687
  } else {
664
688
  this.collapseBottomPanel();
665
689
  }
690
+ const widgets = toArray(this.bottomPanel.widgets());
691
+ if (bottomPanel.pinned && bottomPanel.pinned.length === widgets.length) {
692
+ widgets.forEach((a, i) => {
693
+ if (bottomPanel.pinned![i]) {
694
+ a.title.className += ' theia-mod-pinned';
695
+ a.title.closable = false;
696
+ }
697
+ });
698
+ }
666
699
  this.refreshBottomPanelToggleButton();
667
700
  }
668
701
  // Proceed with the main panel once all others are set up
@@ -670,6 +703,15 @@ export class ApplicationShell extends Widget {
670
703
  if (mainPanel) {
671
704
  this.mainPanel.restoreLayout(mainPanel);
672
705
  this.registerWithFocusTracker(mainPanel.main);
706
+ const widgets = toArray(this.mainPanel.widgets());
707
+ if (mainPanelPinned && mainPanelPinned.length === widgets.length) {
708
+ widgets.forEach((a, i) => {
709
+ if (mainPanelPinned[i]) {
710
+ a.title.className += ' theia-mod-pinned';
711
+ a.title.closable = false;
712
+ }
713
+ });
714
+ }
673
715
  }
674
716
  if (activeWidgetId) {
675
717
  this.activateWidget(activeWidgetId);
@@ -1954,6 +1996,7 @@ export namespace ApplicationShell {
1954
1996
  export interface LayoutData {
1955
1997
  version?: string | ApplicationShellLayoutVersion,
1956
1998
  mainPanel?: DockPanel.ILayoutConfig;
1999
+ mainPanelPinned?: boolean[];
1957
2000
  bottomPanel?: BottomPanelLayoutData;
1958
2001
  leftPanel?: SidePanel.LayoutData;
1959
2002
  rightPanel?: SidePanel.LayoutData;
@@ -1967,6 +2010,7 @@ export namespace ApplicationShell {
1967
2010
  config?: DockPanel.ILayoutConfig;
1968
2011
  size?: number;
1969
2012
  expanded?: boolean;
2013
+ pinned?: boolean[];
1970
2014
  }
1971
2015
 
1972
2016
  /**
@@ -272,7 +272,8 @@ export class SidePanelHandler {
272
272
  const items = toArray(map(this.tabBar.titles, title => <SidePanel.WidgetItem>{
273
273
  widget: title.owner,
274
274
  rank: SidePanelHandler.rankProperty.get(title.owner),
275
- expanded: title === currentTitle
275
+ expanded: title === currentTitle,
276
+ pinned: title.className.indexOf('theia-mod-pinned') >= 0
276
277
  }));
277
278
  // eslint-disable-next-line no-null/no-null
278
279
  const size = currentTitle !== null ? this.getPanelSize() : this.state.lastPanelSize;
@@ -288,7 +289,7 @@ export class SidePanelHandler {
288
289
 
289
290
  let currentTitle: Title<Widget> | undefined;
290
291
  if (layoutData.items) {
291
- for (const { widget, rank, expanded } of layoutData.items) {
292
+ for (const { widget, rank, expanded, pinned } of layoutData.items) {
292
293
  if (widget) {
293
294
  if (rank) {
294
295
  SidePanelHandler.rankProperty.set(widget, rank);
@@ -296,6 +297,10 @@ export class SidePanelHandler {
296
297
  if (expanded) {
297
298
  currentTitle = widget.title;
298
299
  }
300
+ if (pinned) {
301
+ widget.title.className += ' theia-mod-pinned';
302
+ widget.title.closable = false;
303
+ }
299
304
  // Add the widgets directly to the tab bar in the same order as they are stored
300
305
  this.tabBar.addTab(widget.title);
301
306
  }
@@ -725,6 +730,7 @@ export namespace SidePanel {
725
730
  /** Can be undefined in case the widget could not be restored. */
726
731
  widget?: Widget;
727
732
  expanded?: boolean;
733
+ pinned?: boolean;
728
734
  }
729
735
 
730
736
  export interface State {
@@ -17,7 +17,7 @@
17
17
  import PerfectScrollbar from 'perfect-scrollbar';
18
18
  import { TabBar, Title, Widget } from '@phosphor/widgets';
19
19
  import { VirtualElement, h, VirtualDOM, ElementInlineStyle } from '@phosphor/virtualdom';
20
- import { Disposable, DisposableCollection, MenuPath, notEmpty, SelectionService } from '../../common';
20
+ import { Disposable, DisposableCollection, MenuPath, notEmpty, SelectionService, CommandService } from '../../common';
21
21
  import { ContextMenuRenderer } from '../context-menu-renderer';
22
22
  import { Signal, Slot } from '@phosphor/signaling';
23
23
  import { Message, MessageLoop } from '@phosphor/messaging';
@@ -31,6 +31,7 @@ import { IconThemeService } from '../icon-theme-service';
31
31
  import { BreadcrumbsRenderer, BreadcrumbsRendererFactory } from '../breadcrumbs/breadcrumbs-renderer';
32
32
  import { NavigatableWidget } from '../navigatable-types';
33
33
  import { IDragEvent } from '@phosphor/dragdrop';
34
+ import { PINNED_CLASS } from '../widgets/widget';
34
35
 
35
36
  /** The class name added to hidden content nodes, which are required to render vertical side bars. */
36
37
  const HIDDEN_CONTENT_CLASS = 'theia-TabBar-hidden-content';
@@ -87,6 +88,7 @@ export class TabBarRenderer extends TabBar.Renderer {
87
88
  protected readonly decoratorService?: TabBarDecoratorService,
88
89
  protected readonly iconThemeService?: IconThemeService,
89
90
  protected readonly selectionService?: SelectionService,
91
+ protected readonly commandService?: CommandService
90
92
  ) {
91
93
  super();
92
94
  if (this.decoratorService) {
@@ -162,7 +164,10 @@ export class TabBarRenderer extends TabBar.Renderer {
162
164
  this.renderLabel(data, isInSidePanel),
163
165
  this.renderBadge(data, isInSidePanel)
164
166
  ),
165
- this.renderCloseIcon(data)
167
+ h.div({
168
+ className: 'p-TabBar-tabCloseIcon action-item',
169
+ onclick: this.handleCloseClickEvent
170
+ })
166
171
  );
167
172
  }
168
173
 
@@ -467,6 +472,16 @@ export class TabBarRenderer extends TabBar.Renderer {
467
472
  }
468
473
  };
469
474
 
475
+ protected handleCloseClickEvent = (event: MouseEvent) => {
476
+ if (this.tabBar && event.currentTarget instanceof HTMLElement) {
477
+ const id = event.currentTarget.parentElement!.id;
478
+ const title = this.tabBar.titles.find(t => this.createTabId(t) === id);
479
+ if (title?.closable === false && title?.className.includes(PINNED_CLASS) && this.commandService) {
480
+ this.commandService.executeCommand('workbench.action.unpinEditor', event);
481
+ }
482
+ }
483
+ };
484
+
470
485
  protected handleDblClickEvent = (event: MouseEvent) => {
471
486
  if (this.tabBar && event.currentTarget instanceof HTMLElement) {
472
487
  const id = event.currentTarget.id;
@@ -235,7 +235,8 @@ body.theia-editor-highlightModifiedTabs
235
235
  height: inherit;
236
236
  }
237
237
 
238
- .p-TabBar.theia-app-centers .p-TabBar-tab.p-mod-closable > .p-TabBar-tabCloseIcon {
238
+ .p-TabBar.theia-app-centers .p-TabBar-tab.p-mod-closable > .p-TabBar-tabCloseIcon,
239
+ .p-TabBar.theia-app-centers .p-TabBar-tab.theia-mod-pinned > .p-TabBar-tabCloseIcon {
239
240
  padding: 2px;
240
241
  margin-top: 2px;
241
242
  margin-left: 4px;
@@ -258,7 +259,8 @@ body.theia-editor-highlightModifiedTabs
258
259
  background-color: rgba(50%, 50%, 50%, 0.2);
259
260
  }
260
261
 
261
- .p-TabBar.theia-app-centers .p-TabBar-tab.p-mod-closable {
262
+ .p-TabBar.theia-app-centers .p-TabBar-tab.p-mod-closable,
263
+ .p-TabBar.theia-app-centers .p-TabBar-tab.theia-mod-pinned {
262
264
  padding-right: 4px;
263
265
  }
264
266
 
@@ -272,6 +274,14 @@ body.theia-editor-highlightModifiedTabs
272
274
  content: "\ea71";
273
275
  }
274
276
 
277
+ .p-TabBar.theia-app-centers .p-TabBar-tab.theia-mod-pinned > .p-TabBar-tabCloseIcon:before {
278
+ content: "\eba0";
279
+ }
280
+
281
+ .p-TabBar.theia-app-centers .p-TabBar-tab.theia-mod-pinned.theia-mod-dirty > .p-TabBar-tabCloseIcon:before {
282
+ content: "\ebb2";
283
+ }
284
+
275
285
  .p-TabBar-tabIcon.no-icon {
276
286
  display: none !important;
277
287
  }
@@ -18,7 +18,7 @@ import { interfaces, injectable, inject, postConstruct } from 'inversify';
18
18
  import { IIterator, toArray, find, some, every, map, ArrayExt } from '@phosphor/algorithm';
19
19
  import {
20
20
  Widget, EXPANSION_TOGGLE_CLASS, COLLAPSED_CLASS, CODICON_TREE_ITEM_CLASSES, MessageLoop, Message, SplitPanel,
21
- BaseWidget, addEventListener, SplitLayout, LayoutItem, PanelLayout, addKeyListener, waitForRevealed, UnsafeWidgetUtilities, DockPanel
21
+ BaseWidget, addEventListener, SplitLayout, LayoutItem, PanelLayout, addKeyListener, waitForRevealed, UnsafeWidgetUtilities, DockPanel, PINNED_CLASS
22
22
  } from './widgets';
23
23
  import { Event as CommonEvent, Emitter } from '../common/event';
24
24
  import { Disposable, DisposableCollection } from '../common/disposable';
@@ -276,7 +276,9 @@ export class ViewContainer extends BaseWidget implements StatefulWidget, Applica
276
276
  if (title.iconClass) {
277
277
  this.title.iconClass = title.iconClass;
278
278
  }
279
- if (title.closeable !== undefined) {
279
+ if (this.title.className.includes(PINNED_CLASS)) {
280
+ this.title.closable &&= false;
281
+ } else if (title.closeable !== undefined) {
280
282
  this.title.closable = title.closeable;
281
283
  }
282
284
  }
@@ -17,7 +17,7 @@
17
17
  /* eslint-disable @typescript-eslint/no-explicit-any */
18
18
 
19
19
  import { injectable, decorate, unmanaged } from 'inversify';
20
- import { Widget } from '@phosphor/widgets';
20
+ import { Title, Widget } from '@phosphor/widgets';
21
21
  import { Message, MessageLoop } from '@phosphor/messaging';
22
22
  import { Emitter, Event, Disposable, DisposableCollection, MaybePromise } from '../../common';
23
23
  import { KeyCode, KeysOrKeyCodes } from '../keyboard/keys';
@@ -52,6 +52,7 @@ export const BUSY_CLASS = 'theia-mod-busy';
52
52
  export const CODICON_LOADING_CLASSES = codiconArray('loading');
53
53
  export const SELECTED_CLASS = 'theia-mod-selected';
54
54
  export const FOCUS_CLASS = 'theia-mod-focus';
55
+ export const PINNED_CLASS = 'theia-mod-pinned';
55
56
  export const DEFAULT_SCROLL_OPTIONS: PerfectScrollbar.Options = {
56
57
  suppressScrollX: true,
57
58
  minScrollbarLength: 35,
@@ -353,3 +354,30 @@ function waitForVisible(widget: Widget, visible: boolean, attached?: boolean): P
353
354
  waitFor();
354
355
  });
355
356
  }
357
+
358
+ export function isPinned(title: Title<Widget>): boolean {
359
+ const pinnedState = !title.closable && title.className.includes(PINNED_CLASS);
360
+ return pinnedState;
361
+ }
362
+
363
+ export function unpin(title: Title<Widget>): void {
364
+ title.closable = true;
365
+ title.className = title.className.replace(PINNED_CLASS, '').trim();
366
+ }
367
+
368
+ export function pin(title: Title<Widget>): void {
369
+ title.closable = false;
370
+ if (!title.className.includes(PINNED_CLASS)) {
371
+ title.className += ` ${PINNED_CLASS}`;
372
+ }
373
+ }
374
+
375
+ export function togglePinned(title?: Title<Widget>): void {
376
+ if (title) {
377
+ if (isPinned(title)) {
378
+ unpin(title);
379
+ } else {
380
+ pin(title);
381
+ }
382
+ }
383
+ }