@theia/scm 1.48.2 → 1.49.0

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 (52) hide show
  1. package/lib/browser/decorations/scm-decorations-service.d.ts +9 -3
  2. package/lib/browser/decorations/scm-decorations-service.d.ts.map +1 -1
  3. package/lib/browser/decorations/scm-decorations-service.js +50 -30
  4. package/lib/browser/decorations/scm-decorations-service.js.map +1 -1
  5. package/lib/browser/dirty-diff/content-lines.d.ts +2 -0
  6. package/lib/browser/dirty-diff/content-lines.d.ts.map +1 -1
  7. package/lib/browser/dirty-diff/content-lines.js +7 -0
  8. package/lib/browser/dirty-diff/content-lines.js.map +1 -1
  9. package/lib/browser/dirty-diff/diff-computer.d.ts +23 -14
  10. package/lib/browser/dirty-diff/diff-computer.d.ts.map +1 -1
  11. package/lib/browser/dirty-diff/diff-computer.js +91 -27
  12. package/lib/browser/dirty-diff/diff-computer.js.map +1 -1
  13. package/lib/browser/dirty-diff/diff-computer.spec.js +120 -52
  14. package/lib/browser/dirty-diff/diff-computer.spec.js.map +1 -1
  15. package/lib/browser/dirty-diff/dirty-diff-decorator.d.ts +5 -3
  16. package/lib/browser/dirty-diff/dirty-diff-decorator.d.ts.map +1 -1
  17. package/lib/browser/dirty-diff/dirty-diff-decorator.js +14 -7
  18. package/lib/browser/dirty-diff/dirty-diff-decorator.js.map +1 -1
  19. package/lib/browser/dirty-diff/dirty-diff-module.d.ts.map +1 -1
  20. package/lib/browser/dirty-diff/dirty-diff-module.js +9 -0
  21. package/lib/browser/dirty-diff/dirty-diff-module.js.map +1 -1
  22. package/lib/browser/dirty-diff/dirty-diff-navigator.d.ts +49 -0
  23. package/lib/browser/dirty-diff/dirty-diff-navigator.d.ts.map +1 -0
  24. package/lib/browser/dirty-diff/dirty-diff-navigator.js +292 -0
  25. package/lib/browser/dirty-diff/dirty-diff-navigator.js.map +1 -0
  26. package/lib/browser/dirty-diff/dirty-diff-widget.d.ts +47 -0
  27. package/lib/browser/dirty-diff/dirty-diff-widget.d.ts.map +1 -0
  28. package/lib/browser/dirty-diff/dirty-diff-widget.js +320 -0
  29. package/lib/browser/dirty-diff/dirty-diff-widget.js.map +1 -0
  30. package/lib/browser/scm-colors.d.ts +6 -0
  31. package/lib/browser/scm-colors.d.ts.map +1 -0
  32. package/lib/browser/scm-colors.js +25 -0
  33. package/lib/browser/scm-colors.js.map +1 -0
  34. package/lib/browser/scm-contribution.d.ts +20 -6
  35. package/lib/browser/scm-contribution.d.ts.map +1 -1
  36. package/lib/browser/scm-contribution.js +112 -22
  37. package/lib/browser/scm-contribution.js.map +1 -1
  38. package/lib/browser/scm-tree-widget.js +1 -1
  39. package/lib/browser/scm-tree-widget.js.map +1 -1
  40. package/package.json +8 -6
  41. package/src/browser/decorations/scm-decorations-service.ts +60 -36
  42. package/src/browser/dirty-diff/content-lines.ts +9 -0
  43. package/src/browser/dirty-diff/diff-computer.spec.ts +120 -52
  44. package/src/browser/dirty-diff/diff-computer.ts +88 -40
  45. package/src/browser/dirty-diff/dirty-diff-decorator.ts +17 -10
  46. package/src/browser/dirty-diff/dirty-diff-module.ts +9 -0
  47. package/src/browser/dirty-diff/dirty-diff-navigator.ts +288 -0
  48. package/src/browser/dirty-diff/dirty-diff-widget.ts +364 -0
  49. package/src/browser/scm-colors.ts +21 -0
  50. package/src/browser/scm-contribution.ts +97 -6
  51. package/src/browser/scm-tree-widget.tsx +1 -1
  52. package/src/browser/style/dirty-diff-decorator.css +2 -1
@@ -29,7 +29,7 @@ import {
29
29
  CssStyleCollector
30
30
  } from '@theia/core/lib/browser';
31
31
  import { TabBarToolbarContribution, TabBarToolbarRegistry, TabBarToolbarItem } from '@theia/core/lib/browser/shell/tab-bar-toolbar';
32
- import { CommandRegistry, Command, Disposable, DisposableCollection, CommandService } from '@theia/core/lib/common';
32
+ import { CommandRegistry, Command, Disposable, DisposableCollection, CommandService, MenuModelRegistry } from '@theia/core/lib/common';
33
33
  import { ContextKeyService, ContextKey } from '@theia/core/lib/browser/context-key-service';
34
34
  import { ScmService } from './scm-service';
35
35
  import { ScmWidget } from '../browser/scm-widget';
@@ -38,10 +38,13 @@ import { ScmQuickOpenService } from './scm-quick-open-service';
38
38
  import { ColorContribution } from '@theia/core/lib/browser/color-application-contribution';
39
39
  import { ColorRegistry } from '@theia/core/lib/browser/color-registry';
40
40
  import { Color } from '@theia/core/lib/common/color';
41
+ import { ScmColors } from './scm-colors';
41
42
  import { ScmCommand } from './scm-provider';
42
43
  import { ScmDecorationsService } from '../browser/decorations/scm-decorations-service';
43
44
  import { nls } from '@theia/core/lib/common/nls';
44
45
  import { isHighContrast } from '@theia/core/lib/common/theme';
46
+ import { EditorMainMenu } from '@theia/editor/lib/browser';
47
+ import { DirtyDiffNavigator } from './dirty-diff/dirty-diff-navigator';
45
48
 
46
49
  export const SCM_WIDGET_FACTORY_ID = ScmWidget.ID;
47
50
  export const SCM_VIEW_CONTAINER_ID = 'scm-view-container';
@@ -51,6 +54,10 @@ export const SCM_VIEW_CONTAINER_TITLE_OPTIONS: ViewContainerTitleOptions = {
51
54
  closeable: true
52
55
  };
53
56
 
57
+ export namespace ScmMenus {
58
+ export const CHANGES_GROUP = [...EditorMainMenu.GO, '6_changes_group'];
59
+ }
60
+
54
61
  export namespace SCM_COMMANDS {
55
62
  export const CHANGE_REPOSITORY = {
56
63
  id: 'scm.change.repository',
@@ -85,13 +92,36 @@ export namespace SCM_COMMANDS {
85
92
  label: nls.localizeByDefault('Collapse All'),
86
93
  originalLabel: 'Collapse All'
87
94
  };
95
+ export const GOTO_NEXT_CHANGE = Command.toDefaultLocalizedCommand({
96
+ id: 'workbench.action.editor.nextChange',
97
+ category: 'Source Control',
98
+ label: 'Go to Next Change'
99
+ });
100
+ export const GOTO_PREVIOUS_CHANGE = Command.toDefaultLocalizedCommand({
101
+ id: 'workbench.action.editor.previousChange',
102
+ category: 'Source Control',
103
+ label: 'Go to Previous Change'
104
+ });
105
+ export const SHOW_NEXT_CHANGE = Command.toDefaultLocalizedCommand({
106
+ id: 'editor.action.dirtydiff.next',
107
+ category: 'Source Control',
108
+ label: 'Show Next Change'
109
+ });
110
+ export const SHOW_PREVIOUS_CHANGE = Command.toDefaultLocalizedCommand({
111
+ id: 'editor.action.dirtydiff.previous',
112
+ category: 'Source Control',
113
+ label: 'Show Previous Change'
114
+ });
115
+ export const CLOSE_CHANGE_PEEK_VIEW = {
116
+ id: 'editor.action.dirtydiff.close',
117
+ category: nls.localizeByDefault('Source Control'),
118
+ originalCategory: 'Source Control',
119
+ label: nls.localize('theia/scm/dirtyDiff/close', 'Close Change Peek View'),
120
+ originalLabel: 'Close Change Peek View'
121
+ };
88
122
  }
89
123
 
90
- export namespace ScmColors {
91
- export const editorGutterModifiedBackground = 'editorGutter.modifiedBackground';
92
- export const editorGutterAddedBackground = 'editorGutter.addedBackground';
93
- export const editorGutterDeletedBackground = 'editorGutter.deletedBackground';
94
- }
124
+ export { ScmColors };
95
125
 
96
126
  @injectable()
97
127
  export class ScmContribution extends AbstractViewContribution<ScmWidget> implements
@@ -108,6 +138,7 @@ export class ScmContribution extends AbstractViewContribution<ScmWidget> impleme
108
138
  @inject(CommandRegistry) protected readonly commandRegistry: CommandRegistry;
109
139
  @inject(ContextKeyService) protected readonly contextKeys: ContextKeyService;
110
140
  @inject(ScmDecorationsService) protected readonly scmDecorationsService: ScmDecorationsService;
141
+ @inject(DirtyDiffNavigator) protected readonly dirtyDiffNavigator: DirtyDiffNavigator;
111
142
 
112
143
  protected scmFocus: ContextKey<boolean>;
113
144
 
@@ -144,6 +175,8 @@ export class ScmContribution extends AbstractViewContribution<ScmWidget> impleme
144
175
 
145
176
  this.updateContextKeys();
146
177
  this.shell.onDidChangeCurrentWidget(() => this.updateContextKeys());
178
+
179
+ this.scmDecorationsService.onDirtyDiffUpdate(update => this.dirtyDiffNavigator.handleDirtyDiffUpdate(update));
147
180
  }
148
181
 
149
182
  protected updateContextKeys(): void {
@@ -160,6 +193,39 @@ export class ScmContribution extends AbstractViewContribution<ScmWidget> impleme
160
193
  execute: () => this.acceptInput(),
161
194
  isEnabled: () => !!this.scmFocus.get() && !!this.acceptInputCommand()
162
195
  });
196
+
197
+ // Note that commands for dirty diff navigation need to be always available.
198
+ // This is consistent with behavior in VS Code, and also with other similar commands (such as `Next Problem/Previous Problem`) in Theia.
199
+ // See https://github.com/eclipse-theia/theia/pull/13104#discussion_r1497316614 for a detailed discussion.
200
+ commandRegistry.registerCommand(SCM_COMMANDS.GOTO_NEXT_CHANGE, {
201
+ execute: () => this.dirtyDiffNavigator.gotoNextChange()
202
+ });
203
+ commandRegistry.registerCommand(SCM_COMMANDS.GOTO_PREVIOUS_CHANGE, {
204
+ execute: () => this.dirtyDiffNavigator.gotoPreviousChange()
205
+ });
206
+ commandRegistry.registerCommand(SCM_COMMANDS.SHOW_NEXT_CHANGE, {
207
+ execute: () => this.dirtyDiffNavigator.showNextChange()
208
+ });
209
+ commandRegistry.registerCommand(SCM_COMMANDS.SHOW_PREVIOUS_CHANGE, {
210
+ execute: () => this.dirtyDiffNavigator.showPreviousChange()
211
+ });
212
+ commandRegistry.registerCommand(SCM_COMMANDS.CLOSE_CHANGE_PEEK_VIEW, {
213
+ execute: () => this.dirtyDiffNavigator.closeChangePeekView()
214
+ });
215
+ }
216
+
217
+ override registerMenus(menus: MenuModelRegistry): void {
218
+ super.registerMenus(menus);
219
+ menus.registerMenuAction(ScmMenus.CHANGES_GROUP, {
220
+ commandId: SCM_COMMANDS.SHOW_NEXT_CHANGE.id,
221
+ label: nls.localizeByDefault('Next Change'),
222
+ order: '1'
223
+ });
224
+ menus.registerMenuAction(ScmMenus.CHANGES_GROUP, {
225
+ commandId: SCM_COMMANDS.SHOW_PREVIOUS_CHANGE.id,
226
+ label: nls.localizeByDefault('Previous Change'),
227
+ order: '2'
228
+ });
163
229
  }
164
230
 
165
231
  registerToolbarItems(registry: TabBarToolbarRegistry): void {
@@ -219,6 +285,31 @@ export class ScmContribution extends AbstractViewContribution<ScmWidget> impleme
219
285
  keybinding: 'ctrlcmd+enter',
220
286
  when: 'scmFocus'
221
287
  });
288
+ keybindings.registerKeybinding({
289
+ command: SCM_COMMANDS.GOTO_NEXT_CHANGE.id,
290
+ keybinding: 'alt+f5',
291
+ when: 'editorTextFocus'
292
+ });
293
+ keybindings.registerKeybinding({
294
+ command: SCM_COMMANDS.GOTO_PREVIOUS_CHANGE.id,
295
+ keybinding: 'shift+alt+f5',
296
+ when: 'editorTextFocus'
297
+ });
298
+ keybindings.registerKeybinding({
299
+ command: SCM_COMMANDS.SHOW_NEXT_CHANGE.id,
300
+ keybinding: 'alt+f3',
301
+ when: 'editorTextFocus'
302
+ });
303
+ keybindings.registerKeybinding({
304
+ command: SCM_COMMANDS.SHOW_PREVIOUS_CHANGE.id,
305
+ keybinding: 'shift+alt+f3',
306
+ when: 'editorTextFocus'
307
+ });
308
+ keybindings.registerKeybinding({
309
+ command: SCM_COMMANDS.CLOSE_CHANGE_PEEK_VIEW.id,
310
+ keybinding: 'esc',
311
+ when: 'dirtyDiffVisible'
312
+ });
222
313
  }
223
314
 
224
315
  protected async acceptInput(): Promise<void> {
@@ -605,7 +605,7 @@ export class ScmResourceComponent extends ScmElement<ScmResourceComponent.Props>
605
605
 
606
606
  protected readonly contextMenuPath = ScmTreeWidget.RESOURCE_CONTEXT_MENU;
607
607
  protected get contextMenuArgs(): any[] {
608
- if (!this.props.model.selectedNodes.some(node => ScmFileChangeNode.is(node) && node.sourceUri === this.props.sourceUri)) {
608
+ if (!this.props.model.selectedNodes.some(node => ScmFileChangeNode.is(node) && node === this.props.treeNode)) {
609
609
  // Clicked node is not in selection, so ignore selection and action on just clicked node
610
610
  return this.singleNodeArgs;
611
611
  } else {
@@ -19,6 +19,7 @@
19
19
  border-top: 4px solid transparent;
20
20
  border-bottom: 4px solid transparent;
21
21
  transition: border-top-width 80ms linear, border-bottom-width 80ms linear, bottom 80ms linear;
22
+ pointer-events: none;
22
23
  }
23
24
 
24
25
  .dirty-diff-glyph:before {
@@ -41,7 +42,7 @@
41
42
  position: absolute;
42
43
  content: '';
43
44
  height: 100%;
44
- width: 9px;
45
+ width: 6px;
45
46
  left: -6px;
46
47
  }
47
48