xtralab 0.15.0 → 0.15.2
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/README.md +65 -30
- package/lib/about/icons.d.ts +0 -5
- package/lib/about/icons.js +0 -5
- package/lib/about/index.d.ts +4 -8
- package/lib/about/index.js +6 -17
- package/lib/agentSessions.d.ts +9 -29
- package/lib/agentSessions.js +2 -7
- package/lib/askAgent/editorSelection.d.ts +20 -26
- package/lib/askAgent/editorSelection.js +11 -26
- package/lib/askAgent/icons.d.ts +2 -3
- package/lib/askAgent/icons.js +2 -3
- package/lib/askAgent/index.d.ts +4 -26
- package/lib/askAgent/index.js +54 -158
- package/lib/askAgent/popup.d.ts +12 -16
- package/lib/askAgent/popup.js +18 -37
- package/lib/askAgent/prompt.d.ts +3 -5
- package/lib/askAgent/prompt.js +6 -19
- package/lib/askAgent/queue.d.ts +11 -21
- package/lib/askAgent/queue.js +9 -19
- package/lib/askAgent/queuePanel.d.ts +13 -18
- package/lib/askAgent/queuePanel.js +15 -37
- package/lib/askAgent/targetPicker.d.ts +2 -9
- package/lib/askAgent/targetPicker.js +6 -11
- package/lib/askAgent/tokens.d.ts +32 -46
- package/lib/askAgent/tokens.js +4 -6
- package/lib/commandBar/index.d.ts +4 -13
- package/lib/commandBar/index.js +21 -39
- package/lib/customPanel/index.js +15 -0
- package/lib/editorBreadcrumbs/index.d.ts +3 -6
- package/lib/editorBreadcrumbs/index.js +10 -6
- package/lib/editorBreadcrumbs/widget.d.ts +17 -4
- package/lib/editorBreadcrumbs/widget.js +11 -17
- package/lib/editorIndent/index.d.ts +4 -12
- package/lib/editorIndent/index.js +8 -23
- package/lib/fileBrowser/commands.d.ts +29 -19
- package/lib/fileBrowser/commands.js +83 -97
- package/lib/fileBrowser/contents.d.ts +3 -0
- package/lib/fileBrowser/dragAndDrop.d.ts +17 -4
- package/lib/fileBrowser/dragAndDrop.js +2 -7
- package/lib/fileBrowser/fileBrowser.d.ts +19 -9
- package/lib/fileBrowser/fileBrowser.js +70 -222
- package/lib/fileBrowser/gitStatus.d.ts +16 -10
- package/lib/fileBrowser/gitStatus.js +31 -30
- package/lib/fileBrowser/gitignore.d.ts +4 -17
- package/lib/fileBrowser/gitignore.js +4 -25
- package/lib/fileBrowser/icons.d.ts +7 -17
- package/lib/fileBrowser/icons.js +25 -80
- package/lib/fileBrowser/index.js +2 -4
- package/lib/fileBrowser/widget.d.ts +141 -48
- package/lib/fileBrowser/widget.js +102 -4
- package/lib/fileTypeIcons/index.js +0 -10
- package/lib/git/api.d.ts +5 -13
- package/lib/git/api.js +10 -36
- package/lib/git/askRequest.d.ts +4 -8
- package/lib/git/askRequest.js +6 -20
- package/lib/git/commands.d.ts +45 -5
- package/lib/git/commands.js +20 -13
- package/lib/git/diffModel.js +4 -0
- package/lib/git/diffPreferences.d.ts +90 -0
- package/lib/git/diffPreferences.js +107 -0
- package/lib/git/diffProvider.js +10 -2
- package/lib/git/diffSurface.d.ts +64 -63
- package/lib/git/diffSurface.js +72 -213
- package/lib/git/diffTheme.d.ts +7 -0
- package/lib/git/diffTheme.js +23 -0
- package/lib/git/diffWidget.d.ts +70 -14
- package/lib/git/diffWidget.js +100 -94
- package/lib/git/imageDiff.d.ts +14 -6
- package/lib/git/imageDiff.js +19 -75
- package/lib/git/index.d.ts +0 -3
- package/lib/git/index.js +44 -10
- package/lib/git/notebookDiff.d.ts +110 -33
- package/lib/git/notebookDiff.js +55 -197
- package/lib/git/tokens.d.ts +73 -31
- package/lib/git/tokens.js +2 -3
- package/lib/highlight/index.d.ts +4 -10
- package/lib/highlight/index.js +10 -41
- package/lib/index.d.ts +0 -9
- package/lib/index.js +0 -9
- package/lib/launcher/agents.d.ts +55 -51
- package/lib/launcher/agents.js +15 -57
- package/lib/launcher/availability.d.ts +3 -9
- package/lib/launcher/availability.js +3 -9
- package/lib/launcher/commands.d.ts +7 -32
- package/lib/launcher/commands.js +14 -45
- package/lib/launcher/dashboard.d.ts +19 -24
- package/lib/launcher/dashboard.js +21 -67
- package/lib/launcher/editorRegistry.d.ts +10 -22
- package/lib/launcher/editorRegistry.js +14 -18
- package/lib/launcher/editors.d.ts +39 -45
- package/lib/launcher/editors.js +8 -34
- package/lib/launcher/icons.d.ts +0 -12
- package/lib/launcher/icons.js +5 -39
- package/lib/launcher/index.js +12 -55
- package/lib/launcher/invocation.d.ts +4 -10
- package/lib/launcher/invocation.js +7 -22
- package/lib/launcher/registry.d.ts +9 -7
- package/lib/launcher/registry.js +9 -7
- package/lib/launcher/tokens.d.ts +10 -22
- package/lib/launcher/tokens.js +5 -8
- package/lib/menuBar/index.d.ts +3 -10
- package/lib/menuBar/index.js +11 -28
- package/lib/menus/index.d.ts +3 -9
- package/lib/menus/index.js +14 -30
- package/lib/omnibox/files.d.ts +2 -4
- package/lib/omnibox/files.js +5 -11
- package/lib/omnibox/index.d.ts +4 -14
- package/lib/omnibox/index.js +9 -27
- package/lib/omnibox/model.d.ts +38 -10
- package/lib/omnibox/model.js +15 -33
- package/lib/omnibox/recents.d.ts +15 -17
- package/lib/omnibox/recents.js +12 -17
- package/lib/omnibox/tokens.d.ts +5 -10
- package/lib/omnibox/tokens.js +2 -6
- package/lib/omnibox/widget.d.ts +11 -7
- package/lib/omnibox/widget.js +8 -16
- package/lib/searchReplace/index.d.ts +4 -20
- package/lib/searchReplace/index.js +7 -27
- package/lib/showOutput/index.d.ts +3 -12
- package/lib/showOutput/index.js +6 -22
- package/lib/sidebar/index.d.ts +4 -7
- package/lib/sidebar/index.js +5 -12
- package/lib/terminalNotifications/index.d.ts +4 -10
- package/lib/terminalNotifications/index.js +6 -20
- package/lib/terminals/agentTerminals.d.ts +12 -5
- package/lib/terminals/agentTerminals.js +25 -44
- package/lib/terminals/detection.d.ts +4 -8
- package/lib/terminals/detection.js +4 -8
- package/lib/terminals/index.d.ts +0 -35
- package/lib/terminals/index.js +12 -101
- package/lib/terminals/model.d.ts +64 -139
- package/lib/terminals/model.js +80 -220
- package/lib/terminals/tokens.d.ts +11 -22
- package/lib/terminals/tokens.js +2 -2
- package/lib/terminals/widget.d.ts +43 -13
- package/lib/terminals/widget.js +33 -18
- package/lib/topBar/icons.d.ts +3 -8
- package/lib/topBar/icons.js +3 -8
- package/lib/topBar/index.d.ts +4 -11
- package/lib/topBar/index.js +10 -38
- package/lib/walkthrough/index.d.ts +4 -9
- package/lib/walkthrough/index.js +6 -20
- package/lib/walkthrough/panel.d.ts +40 -9
- package/lib/walkthrough/panel.js +4 -10
- package/package.json +5 -3
- package/schema/git-diff-preferences.json +42 -0
- package/src/about/icons.ts +0 -5
- package/src/about/index.tsx +6 -17
- package/src/agentSessions.ts +9 -29
- package/src/askAgent/editorSelection.ts +22 -29
- package/src/askAgent/icons.ts +2 -3
- package/src/askAgent/index.ts +54 -158
- package/src/askAgent/popup.tsx +23 -45
- package/src/askAgent/prompt.ts +6 -19
- package/src/askAgent/queue.ts +13 -24
- package/src/askAgent/queuePanel.tsx +21 -46
- package/src/askAgent/targetPicker.tsx +5 -15
- package/src/askAgent/tokens.ts +32 -46
- package/src/commandBar/index.ts +24 -39
- package/src/customPanel/index.ts +15 -0
- package/src/editorBreadcrumbs/index.ts +10 -6
- package/src/editorBreadcrumbs/widget.ts +23 -17
- package/src/editorIndent/index.ts +17 -23
- package/src/fileBrowser/commands.ts +119 -96
- package/src/fileBrowser/contents.ts +3 -0
- package/src/fileBrowser/dragAndDrop.ts +17 -7
- package/src/fileBrowser/fileBrowser.tsx +86 -230
- package/src/fileBrowser/gitStatus.ts +36 -33
- package/src/fileBrowser/gitignore.ts +4 -25
- package/src/fileBrowser/icons.ts +25 -80
- package/src/fileBrowser/index.ts +2 -4
- package/src/fileBrowser/widget.tsx +171 -50
- package/src/fileTypeIcons/index.ts +0 -10
- package/src/git/api.ts +10 -36
- package/src/git/askRequest.ts +6 -20
- package/src/git/commands.ts +83 -11
- package/src/git/diffModel.ts +25 -0
- package/src/git/diffPreferences.ts +192 -0
- package/src/git/diffProvider.tsx +11 -2
- package/src/git/diffSurface.tsx +165 -286
- package/src/git/diffTheme.ts +24 -0
- package/src/git/diffWidget.tsx +194 -134
- package/src/git/imageDiff.tsx +56 -84
- package/src/git/index.ts +54 -10
- package/src/git/notebookDiff.tsx +214 -240
- package/src/git/tokens.ts +73 -31
- package/src/highlight/index.ts +10 -41
- package/src/index.ts +0 -9
- package/src/launcher/agents.ts +64 -95
- package/src/launcher/availability.ts +3 -9
- package/src/launcher/commands.ts +14 -51
- package/src/launcher/dashboard.tsx +49 -88
- package/src/launcher/editorRegistry.ts +21 -29
- package/src/launcher/editors.ts +39 -58
- package/src/launcher/icons.ts +5 -39
- package/src/launcher/index.ts +12 -55
- package/src/launcher/invocation.ts +7 -22
- package/src/launcher/registry.ts +9 -7
- package/src/launcher/tokens.ts +10 -22
- package/src/menuBar/index.ts +11 -28
- package/src/menus/index.ts +14 -30
- package/src/omnibox/files.ts +10 -14
- package/src/omnibox/index.ts +9 -27
- package/src/omnibox/model.ts +50 -38
- package/src/omnibox/recents.ts +17 -22
- package/src/omnibox/tokens.ts +5 -10
- package/src/omnibox/widget.tsx +14 -19
- package/src/searchReplace/index.ts +7 -27
- package/src/showOutput/index.ts +6 -22
- package/src/sidebar/index.ts +20 -12
- package/src/terminalNotifications/index.ts +42 -25
- package/src/terminals/agentTerminals.ts +25 -49
- package/src/terminals/detection.ts +4 -8
- package/src/terminals/index.ts +12 -101
- package/src/terminals/model.ts +130 -246
- package/src/terminals/tokens.ts +11 -22
- package/src/terminals/widget.tsx +48 -31
- package/src/topBar/icons.ts +3 -8
- package/src/topBar/index.ts +21 -44
- package/src/walkthrough/index.ts +6 -20
- package/src/walkthrough/panel.ts +40 -10
- package/style/about.css +2 -7
- package/style/askAgent.css +8 -40
- package/style/base.css +9 -45
- package/style/chrome.css +108 -308
- package/style/commandBar.css +4 -20
- package/style/customPanel.css +1 -4
- package/style/git.css +26 -186
- package/style/highlight.css +1 -3
- package/style/launcher.css +6 -70
- package/style/omnibox.css +2 -14
- package/style/showOutput.css +0 -6
- package/style/sidebar.css +29 -9
- package/style/tabs.css +5 -13
- package/style/terminals.css +6 -53
- package/style/topBar.css +2 -22
- package/style/walkthrough.css +0 -8
package/src/git/commands.ts
CHANGED
|
@@ -10,6 +10,7 @@ import { ISignal, Signal } from '@lumino/signaling';
|
|
|
10
10
|
import type { IAskAgent } from '../askAgent/tokens';
|
|
11
11
|
import { getTreeIcon } from '../fileBrowser/icons';
|
|
12
12
|
import { fileChangeToDiffModel } from './diffModel';
|
|
13
|
+
import type { IDiffPreferences } from './diffPreferences';
|
|
13
14
|
import {
|
|
14
15
|
DIFF_WIDGET_CSS_CLASS,
|
|
15
16
|
XtralabDiffWidget,
|
|
@@ -28,16 +29,25 @@ export namespace CommandIDs {
|
|
|
28
29
|
* Argument shapes used by {@link CommandIDs.openDiff}.
|
|
29
30
|
*/
|
|
30
31
|
export namespace CommandArguments {
|
|
32
|
+
/**
|
|
33
|
+
* The arguments for the open-diff command.
|
|
34
|
+
*/
|
|
31
35
|
export interface IOpenDiff {
|
|
36
|
+
/**
|
|
37
|
+
* The server-relative path of the repository containing the change.
|
|
38
|
+
*/
|
|
32
39
|
repoPath: string;
|
|
40
|
+
/**
|
|
41
|
+
* The file change to show.
|
|
42
|
+
*/
|
|
33
43
|
change: IFileChange;
|
|
44
|
+
/**
|
|
45
|
+
* Whether to open the diff as a pinned tab instead of the shared preview.
|
|
46
|
+
*/
|
|
34
47
|
pin?: boolean;
|
|
35
48
|
}
|
|
36
49
|
}
|
|
37
50
|
|
|
38
|
-
/**
|
|
39
|
-
* Widget id of the single, reused preview diff tab.
|
|
40
|
-
*/
|
|
41
51
|
export const PREVIEW_DIFF_WIDGET_ID = 'xtralab:diff:preview';
|
|
42
52
|
|
|
43
53
|
/**
|
|
@@ -70,14 +80,23 @@ export class DiffMainAreaWidget extends MainAreaWidget<XtralabDiffWidget> {
|
|
|
70
80
|
this._trans = trans;
|
|
71
81
|
}
|
|
72
82
|
|
|
83
|
+
/**
|
|
84
|
+
* The file change currently displayed.
|
|
85
|
+
*/
|
|
73
86
|
get change(): IFileChange {
|
|
74
87
|
return this._change;
|
|
75
88
|
}
|
|
76
89
|
|
|
90
|
+
/**
|
|
91
|
+
* Whether the widget is pinned rather than the shared preview.
|
|
92
|
+
*/
|
|
77
93
|
get pinned(): boolean {
|
|
78
94
|
return this._pinned;
|
|
79
95
|
}
|
|
80
96
|
|
|
97
|
+
/**
|
|
98
|
+
* Pin the widget; a no-op when already pinned.
|
|
99
|
+
*/
|
|
81
100
|
pin(): void {
|
|
82
101
|
if (this._pinned) {
|
|
83
102
|
return;
|
|
@@ -86,10 +105,16 @@ export class DiffMainAreaWidget extends MainAreaWidget<XtralabDiffWidget> {
|
|
|
86
105
|
this._pinnedChanged.emit(true);
|
|
87
106
|
}
|
|
88
107
|
|
|
108
|
+
/**
|
|
109
|
+
* A signal emitted when the widget becomes pinned.
|
|
110
|
+
*/
|
|
89
111
|
get pinnedChanged(): ISignal<this, boolean> {
|
|
90
112
|
return this._pinnedChanged;
|
|
91
113
|
}
|
|
92
114
|
|
|
115
|
+
/**
|
|
116
|
+
* Display a new file change and update the tab title, caption, and icon.
|
|
117
|
+
*/
|
|
93
118
|
setChange(repoPath: string, change: IFileChange): void {
|
|
94
119
|
this._change = change;
|
|
95
120
|
this.content.setModel(fileChangeToDiffModel(repoPath, change));
|
|
@@ -104,21 +129,52 @@ export class DiffMainAreaWidget extends MainAreaWidget<XtralabDiffWidget> {
|
|
|
104
129
|
private _pinnedChanged = new Signal<this, boolean>(this);
|
|
105
130
|
}
|
|
106
131
|
|
|
132
|
+
/**
|
|
133
|
+
* The options used to create a diff main area widget.
|
|
134
|
+
*/
|
|
107
135
|
interface ICreateDiffWidgetOptions {
|
|
136
|
+
/**
|
|
137
|
+
* The server-relative path of the repository containing the change.
|
|
138
|
+
*/
|
|
108
139
|
repoPath: string;
|
|
140
|
+
/**
|
|
141
|
+
* The file change to display.
|
|
142
|
+
*/
|
|
109
143
|
change: IFileChange;
|
|
144
|
+
/**
|
|
145
|
+
* Theme manager the diff view follows; may be `null`.
|
|
146
|
+
*/
|
|
110
147
|
themeManager: IThemeManager | null;
|
|
148
|
+
/**
|
|
149
|
+
* Contents manager used to write hunk-discard results.
|
|
150
|
+
*/
|
|
111
151
|
contentsManager: Contents.IManager;
|
|
152
|
+
/**
|
|
153
|
+
* Rendermime registry used by notebook diffs; may be `null`.
|
|
154
|
+
*/
|
|
112
155
|
rendermime: IRenderMimeRegistry | null;
|
|
156
|
+
/**
|
|
157
|
+
* Ask-agent popup for prompting an agent about diff lines; may be `null`.
|
|
158
|
+
*/
|
|
113
159
|
askAgent: IAskAgent | null;
|
|
160
|
+
/**
|
|
161
|
+
* The display choices shared by all diff views.
|
|
162
|
+
*/
|
|
163
|
+
preferences: IDiffPreferences;
|
|
164
|
+
/**
|
|
165
|
+
* Translation bundle for user-facing strings.
|
|
166
|
+
*/
|
|
114
167
|
trans: TranslationBundle;
|
|
168
|
+
/**
|
|
169
|
+
* Whether the widget opens pinned instead of as the shared preview.
|
|
170
|
+
*/
|
|
115
171
|
pinned?: boolean;
|
|
172
|
+
/**
|
|
173
|
+
* Callback invoked when the widget becomes pinned.
|
|
174
|
+
*/
|
|
116
175
|
onPinned?: (widget: DiffMainAreaWidget) => void;
|
|
117
176
|
}
|
|
118
177
|
|
|
119
|
-
/**
|
|
120
|
-
* Build the launcher's diff tab around the shared diff widget.
|
|
121
|
-
*/
|
|
122
178
|
function createDiffWidget(
|
|
123
179
|
options: ICreateDiffWidgetOptions
|
|
124
180
|
): DiffMainAreaWidget {
|
|
@@ -129,12 +185,13 @@ function createDiffWidget(
|
|
|
129
185
|
contentsManager,
|
|
130
186
|
rendermime,
|
|
131
187
|
askAgent,
|
|
188
|
+
preferences,
|
|
132
189
|
trans
|
|
133
190
|
} = options;
|
|
134
191
|
const pinned = options.pinned === true;
|
|
135
192
|
const content = new XtralabDiffWidget(
|
|
136
193
|
fileChangeToDiffModel(repoPath, change),
|
|
137
|
-
{ contentsManager, rendermime, themeManager, askAgent, trans }
|
|
194
|
+
{ contentsManager, rendermime, themeManager, askAgent, preferences, trans }
|
|
138
195
|
);
|
|
139
196
|
const widget = new DiffMainAreaWidget({ content }, change, pinned, trans);
|
|
140
197
|
widget.id = pinned ? pinnedDiffWidgetId(change) : PREVIEW_DIFF_WIDGET_ID;
|
|
@@ -158,7 +215,6 @@ function createDiffWidget(
|
|
|
158
215
|
widget.toolbar.addItem('pin', pinButton);
|
|
159
216
|
addDiffToolbarItems(widget.toolbar, content);
|
|
160
217
|
|
|
161
|
-
// Keep chrome visible only while there is a relevant toolbar control.
|
|
162
218
|
const syncToolbarVisibility = (): void => {
|
|
163
219
|
if (widget.isDisposed) {
|
|
164
220
|
return;
|
|
@@ -186,7 +242,6 @@ function createDiffWidget(
|
|
|
186
242
|
}
|
|
187
243
|
syncToolbarVisibility();
|
|
188
244
|
};
|
|
189
|
-
// Auto-close once a discard leaves nothing to show.
|
|
190
245
|
const onEmptied = (): void => {
|
|
191
246
|
if (!widget.isDisposed) {
|
|
192
247
|
widget.close();
|
|
@@ -206,8 +261,17 @@ function createDiffWidget(
|
|
|
206
261
|
return widget;
|
|
207
262
|
}
|
|
208
263
|
|
|
264
|
+
/**
|
|
265
|
+
* The options for {@link registerGitCommands}.
|
|
266
|
+
*/
|
|
209
267
|
interface IRegisterGitCommandsOptions {
|
|
268
|
+
/**
|
|
269
|
+
* The JupyterLab application, providing the commands registry and shell.
|
|
270
|
+
*/
|
|
210
271
|
app: JupyterFrontEnd;
|
|
272
|
+
/**
|
|
273
|
+
* Theme manager the diff views follow; may be `null`.
|
|
274
|
+
*/
|
|
211
275
|
themeManager: IThemeManager | null;
|
|
212
276
|
/**
|
|
213
277
|
* Contents manager used to write hunk-discard results.
|
|
@@ -221,6 +285,10 @@ interface IRegisterGitCommandsOptions {
|
|
|
221
285
|
* Ask-agent popup for prompting an agent about diff lines; may be `null`.
|
|
222
286
|
*/
|
|
223
287
|
askAgent: IAskAgent | null;
|
|
288
|
+
/**
|
|
289
|
+
* The display choices shared by all diff views.
|
|
290
|
+
*/
|
|
291
|
+
preferences: IDiffPreferences;
|
|
224
292
|
/**
|
|
225
293
|
* Translation bundle for user-facing strings.
|
|
226
294
|
*/
|
|
@@ -233,12 +301,14 @@ interface IRegisterGitCommandsOptions {
|
|
|
233
301
|
* Look up an already-open diff widget for a file change.
|
|
234
302
|
*/
|
|
235
303
|
findDiff(change: IFileChange, pin?: boolean): DiffMainAreaWidget | undefined;
|
|
304
|
+
/**
|
|
305
|
+
* Callback invoked when a preview diff widget becomes pinned.
|
|
306
|
+
*/
|
|
236
307
|
onPinned(widget: DiffMainAreaWidget): void;
|
|
237
308
|
}
|
|
238
309
|
|
|
239
310
|
/**
|
|
240
|
-
* Register the launcher's git diff command
|
|
241
|
-
* registry.
|
|
311
|
+
* Register the launcher's git diff command.
|
|
242
312
|
*/
|
|
243
313
|
export function registerGitCommands(
|
|
244
314
|
options: IRegisterGitCommandsOptions
|
|
@@ -249,6 +319,7 @@ export function registerGitCommands(
|
|
|
249
319
|
contentsManager,
|
|
250
320
|
rendermime,
|
|
251
321
|
askAgent,
|
|
322
|
+
preferences,
|
|
252
323
|
trans,
|
|
253
324
|
trackDiff,
|
|
254
325
|
findDiff,
|
|
@@ -280,6 +351,7 @@ export function registerGitCommands(
|
|
|
280
351
|
contentsManager,
|
|
281
352
|
rendermime,
|
|
282
353
|
askAgent,
|
|
354
|
+
preferences,
|
|
283
355
|
trans,
|
|
284
356
|
pinned: pin,
|
|
285
357
|
onPinned
|
package/src/git/diffModel.ts
CHANGED
|
@@ -80,14 +80,39 @@ class FileChangeDiffModel implements IXtralabDiffModel {
|
|
|
80
80
|
};
|
|
81
81
|
}
|
|
82
82
|
|
|
83
|
+
/**
|
|
84
|
+
* A signal emitted when the reference or challenger changes; this static
|
|
85
|
+
* model never emits it.
|
|
86
|
+
*/
|
|
83
87
|
readonly changed: ISignal<Git.Diff.IModel, Git.Diff.IModelChange> =
|
|
84
88
|
new Signal<Git.Diff.IModel, Git.Diff.IModelChange>(this);
|
|
89
|
+
/**
|
|
90
|
+
* The reference (old) side of the diff.
|
|
91
|
+
*/
|
|
85
92
|
reference: Git.Diff.IContent;
|
|
93
|
+
/**
|
|
94
|
+
* The challenger (new) side of the diff.
|
|
95
|
+
*/
|
|
86
96
|
challenger: Git.Diff.IContent;
|
|
97
|
+
/**
|
|
98
|
+
* Repo-relative path of the changed file.
|
|
99
|
+
*/
|
|
87
100
|
readonly filename: string;
|
|
101
|
+
/**
|
|
102
|
+
* The rename source path; `undefined` for non-renames.
|
|
103
|
+
*/
|
|
88
104
|
readonly oldFilename: string | undefined;
|
|
105
|
+
/**
|
|
106
|
+
* Path of the git repository, relative to the server root.
|
|
107
|
+
*/
|
|
89
108
|
readonly repositoryPath: string;
|
|
109
|
+
/**
|
|
110
|
+
* Whether the file content is binary.
|
|
111
|
+
*/
|
|
90
112
|
readonly isBinary: boolean;
|
|
113
|
+
/**
|
|
114
|
+
* Whether hunks can be discarded through a working-tree save.
|
|
115
|
+
*/
|
|
91
116
|
readonly canDiscard: boolean;
|
|
92
117
|
}
|
|
93
118
|
|
|
@@ -0,0 +1,192 @@
|
|
|
1
|
+
import * as React from 'react';
|
|
2
|
+
|
|
3
|
+
import type { ISettingRegistry } from '@jupyterlab/settingregistry';
|
|
4
|
+
import type { IStateDB } from '@jupyterlab/statedb';
|
|
5
|
+
import { Token } from '@lumino/coreutils';
|
|
6
|
+
import { ISignal, Signal } from '@lumino/signaling';
|
|
7
|
+
|
|
8
|
+
export type DiffStyle = 'split' | 'unified';
|
|
9
|
+
|
|
10
|
+
export type DiffStyleControlMode = 'buttons' | 'toggle';
|
|
11
|
+
|
|
12
|
+
export type NotebookDiffViewMode = 'notebook' | 'json';
|
|
13
|
+
|
|
14
|
+
export type ImageDiffViewMode = '2-up' | 'swipe' | 'onion';
|
|
15
|
+
|
|
16
|
+
export const MIN_SPLIT_RATIO = 0.1;
|
|
17
|
+
export const MAX_SPLIT_RATIO = 0.9;
|
|
18
|
+
export const DEFAULT_SPLIT_RATIO = 0.5;
|
|
19
|
+
|
|
20
|
+
const SPLIT_RATIO_STATE_KEY = 'xtralab:git-diff:split-ratio';
|
|
21
|
+
|
|
22
|
+
/**
|
|
23
|
+
* Display choices shared by every diff view. The toggles live in the
|
|
24
|
+
* plugin settings; the split width lives in the state database.
|
|
25
|
+
*/
|
|
26
|
+
export interface IDiffPreferences {
|
|
27
|
+
/**
|
|
28
|
+
* The current values; a new object after each change.
|
|
29
|
+
*/
|
|
30
|
+
readonly values: IDiffPreferences.IValues;
|
|
31
|
+
/**
|
|
32
|
+
* A signal emitted when any value changes.
|
|
33
|
+
*/
|
|
34
|
+
readonly changed: ISignal<IDiffPreferences, void>;
|
|
35
|
+
/**
|
|
36
|
+
* Change some values and persist them.
|
|
37
|
+
*/
|
|
38
|
+
update(values: Partial<IDiffPreferences.IValues>): void;
|
|
39
|
+
}
|
|
40
|
+
|
|
41
|
+
export namespace IDiffPreferences {
|
|
42
|
+
/**
|
|
43
|
+
* The diff display values.
|
|
44
|
+
*/
|
|
45
|
+
export interface IValues {
|
|
46
|
+
/**
|
|
47
|
+
* Split or unified layout for textual file diffs.
|
|
48
|
+
*/
|
|
49
|
+
diffStyle: DiffStyle;
|
|
50
|
+
/**
|
|
51
|
+
* Two toolbar buttons for the layout, or one button that toggles it.
|
|
52
|
+
*/
|
|
53
|
+
diffStyleControl: DiffStyleControlMode;
|
|
54
|
+
/**
|
|
55
|
+
* Whether long lines wrap instead of scrolling horizontally.
|
|
56
|
+
*/
|
|
57
|
+
lineWrap: boolean;
|
|
58
|
+
/**
|
|
59
|
+
* Rendered or JSON view for notebook diffs.
|
|
60
|
+
*/
|
|
61
|
+
notebookViewMode: NotebookDiffViewMode;
|
|
62
|
+
/**
|
|
63
|
+
* Comparison mode for image diffs.
|
|
64
|
+
*/
|
|
65
|
+
imageViewMode: ImageDiffViewMode;
|
|
66
|
+
/**
|
|
67
|
+
* Width of the left pane in split view, as a fraction of the diff width.
|
|
68
|
+
*/
|
|
69
|
+
splitRatio: number;
|
|
70
|
+
}
|
|
71
|
+
}
|
|
72
|
+
|
|
73
|
+
export const IDiffPreferences = new Token<IDiffPreferences>(
|
|
74
|
+
'xtralab:IDiffPreferences',
|
|
75
|
+
'Display choices shared by the git diff views.'
|
|
76
|
+
);
|
|
77
|
+
|
|
78
|
+
type SettingKey = Exclude<keyof IDiffPreferences.IValues, 'splitRatio'>;
|
|
79
|
+
|
|
80
|
+
const SETTING_KEYS: SettingKey[] = [
|
|
81
|
+
'diffStyle',
|
|
82
|
+
'diffStyleControl',
|
|
83
|
+
'lineWrap',
|
|
84
|
+
'notebookViewMode',
|
|
85
|
+
'imageViewMode'
|
|
86
|
+
];
|
|
87
|
+
|
|
88
|
+
/**
|
|
89
|
+
* {@link IDiffPreferences} backed by the settings registry and the state
|
|
90
|
+
* database. Without them it keeps the values in memory only.
|
|
91
|
+
*/
|
|
92
|
+
export class DiffPreferences implements IDiffPreferences {
|
|
93
|
+
get values(): IDiffPreferences.IValues {
|
|
94
|
+
return this._values;
|
|
95
|
+
}
|
|
96
|
+
|
|
97
|
+
get changed(): ISignal<this, void> {
|
|
98
|
+
return this._changed;
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
update(values: Partial<IDiffPreferences.IValues>): void {
|
|
102
|
+
if (!this._apply(values)) {
|
|
103
|
+
return;
|
|
104
|
+
}
|
|
105
|
+
for (const key of SETTING_KEYS) {
|
|
106
|
+
if (key in values) {
|
|
107
|
+
this._settings?.set(key, this._values[key]).catch(reason => {
|
|
108
|
+
console.error(`xtralab: failed to save the diff ${key}`, reason);
|
|
109
|
+
});
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
if ('splitRatio' in values) {
|
|
113
|
+
this._state
|
|
114
|
+
?.save(SPLIT_RATIO_STATE_KEY, this._values.splitRatio)
|
|
115
|
+
.catch(reason => {
|
|
116
|
+
console.error('xtralab: failed to save the diff split', reason);
|
|
117
|
+
});
|
|
118
|
+
}
|
|
119
|
+
}
|
|
120
|
+
|
|
121
|
+
/**
|
|
122
|
+
* Read the toggles from the plugin settings and follow their changes.
|
|
123
|
+
*/
|
|
124
|
+
connectSettings(settings: ISettingRegistry.ISettings): void {
|
|
125
|
+
this._settings = settings;
|
|
126
|
+
const sync = (): void => {
|
|
127
|
+
this._apply(settings.composite as Partial<IDiffPreferences.IValues>);
|
|
128
|
+
};
|
|
129
|
+
sync();
|
|
130
|
+
settings.changed.connect(sync);
|
|
131
|
+
}
|
|
132
|
+
|
|
133
|
+
/**
|
|
134
|
+
* Restore the split width from the state database and save it there.
|
|
135
|
+
*/
|
|
136
|
+
async connectState(state: IStateDB): Promise<void> {
|
|
137
|
+
this._state = state;
|
|
138
|
+
const ratio = await state.fetch(SPLIT_RATIO_STATE_KEY);
|
|
139
|
+
if (
|
|
140
|
+
typeof ratio === 'number' &&
|
|
141
|
+
ratio >= MIN_SPLIT_RATIO &&
|
|
142
|
+
ratio <= MAX_SPLIT_RATIO
|
|
143
|
+
) {
|
|
144
|
+
this._apply({ splitRatio: ratio });
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
/**
|
|
149
|
+
* Merge values without persisting them; return whether one changed.
|
|
150
|
+
*/
|
|
151
|
+
private _apply(values: Partial<IDiffPreferences.IValues>): boolean {
|
|
152
|
+
const next = { ...this._values, ...values };
|
|
153
|
+
const keys = Object.keys(next) as (keyof IDiffPreferences.IValues)[];
|
|
154
|
+
if (keys.every(key => next[key] === this._values[key])) {
|
|
155
|
+
return false;
|
|
156
|
+
}
|
|
157
|
+
this._values = next;
|
|
158
|
+
this._changed.emit();
|
|
159
|
+
return true;
|
|
160
|
+
}
|
|
161
|
+
|
|
162
|
+
private _values: IDiffPreferences.IValues = {
|
|
163
|
+
diffStyle: 'split',
|
|
164
|
+
diffStyleControl: 'buttons',
|
|
165
|
+
lineWrap: false,
|
|
166
|
+
notebookViewMode: 'notebook',
|
|
167
|
+
imageViewMode: '2-up',
|
|
168
|
+
splitRatio: DEFAULT_SPLIT_RATIO
|
|
169
|
+
};
|
|
170
|
+
private _changed = new Signal<this, void>(this);
|
|
171
|
+
private _settings: ISettingRegistry.ISettings | null = null;
|
|
172
|
+
private _state: IStateDB | null = null;
|
|
173
|
+
}
|
|
174
|
+
|
|
175
|
+
/**
|
|
176
|
+
* Re-render on every preference change and return the current values.
|
|
177
|
+
*/
|
|
178
|
+
export function useDiffPreferences(
|
|
179
|
+
preferences: IDiffPreferences
|
|
180
|
+
): IDiffPreferences.IValues {
|
|
181
|
+
const subscribe = React.useCallback(
|
|
182
|
+
(onChange: () => void) => {
|
|
183
|
+
const slot = (): void => onChange();
|
|
184
|
+
preferences.changed.connect(slot);
|
|
185
|
+
return () => {
|
|
186
|
+
preferences.changed.disconnect(slot);
|
|
187
|
+
};
|
|
188
|
+
},
|
|
189
|
+
[preferences]
|
|
190
|
+
);
|
|
191
|
+
return React.useSyncExternalStore(subscribe, () => preferences.values);
|
|
192
|
+
}
|
package/src/git/diffProvider.tsx
CHANGED
|
@@ -9,6 +9,7 @@ import { Git, IGitExtension } from '@jupyterlab/git';
|
|
|
9
9
|
|
|
10
10
|
import { IAskAgent } from '../askAgent/tokens';
|
|
11
11
|
|
|
12
|
+
import { DiffPreferences, IDiffPreferences } from './diffPreferences';
|
|
12
13
|
import {
|
|
13
14
|
IXtralabDiffContext,
|
|
14
15
|
XtralabDiffWidget,
|
|
@@ -37,14 +38,21 @@ const diffProviderPlugin: JupyterFrontEndPlugin<void> = {
|
|
|
37
38
|
"Replaces jupyterlab-git's notebook, text and image diff plugins with xtralab's renderer.",
|
|
38
39
|
autoStart: true,
|
|
39
40
|
requires: [IGitExtension],
|
|
40
|
-
optional: [
|
|
41
|
+
optional: [
|
|
42
|
+
IRenderMimeRegistry,
|
|
43
|
+
IThemeManager,
|
|
44
|
+
ITranslator,
|
|
45
|
+
IAskAgent,
|
|
46
|
+
IDiffPreferences
|
|
47
|
+
],
|
|
41
48
|
activate: (
|
|
42
49
|
app: JupyterFrontEnd,
|
|
43
50
|
gitExtension: IGitExtension,
|
|
44
51
|
rendermime: IRenderMimeRegistry | null,
|
|
45
52
|
themeManager: IThemeManager | null,
|
|
46
53
|
translator: ITranslator | null,
|
|
47
|
-
askAgent: IAskAgent | null
|
|
54
|
+
askAgent: IAskAgent | null,
|
|
55
|
+
preferences: IDiffPreferences | null
|
|
48
56
|
): void => {
|
|
49
57
|
const trans = (translator ?? nullTranslator).load('jupyterlab');
|
|
50
58
|
const factory = makeXtralabDiffFactory({
|
|
@@ -52,6 +60,7 @@ const diffProviderPlugin: JupyterFrontEndPlugin<void> = {
|
|
|
52
60
|
rendermime,
|
|
53
61
|
themeManager,
|
|
54
62
|
askAgent,
|
|
63
|
+
preferences: preferences ?? new DiffPreferences(),
|
|
55
64
|
trans
|
|
56
65
|
});
|
|
57
66
|
|