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/diffTheme.ts
CHANGED
|
@@ -26,6 +26,30 @@ registerCustomCSSVariableTheme(JUPYTERLAB_DIFF_THEME, {
|
|
|
26
26
|
'token-link': 'var(--jp-mirror-editor-link-color)'
|
|
27
27
|
});
|
|
28
28
|
|
|
29
|
+
/**
|
|
30
|
+
* `unsafeCSS` for a taller, always-visible horizontal scrollbar. The library
|
|
31
|
+
* default is 6px and only paints the thumb on hover, in a color close to the
|
|
32
|
+
* background, so users miss that long lines scroll. Same thumb color as the
|
|
33
|
+
* app scrollbars in chrome.css.
|
|
34
|
+
*/
|
|
35
|
+
export const DIFF_SCROLLBAR_CSS = `:host {
|
|
36
|
+
--diffs-scrollbar-gutter-override: 10px;
|
|
37
|
+
--xtralab-diff-scrollbar-thumb: color-mix(in srgb, var(--jp-ui-font-color1) 28%, transparent);
|
|
38
|
+
}
|
|
39
|
+
[data-code]::-webkit-scrollbar-thumb {
|
|
40
|
+
background-color: var(--xtralab-diff-scrollbar-thumb);
|
|
41
|
+
border-width: 2px;
|
|
42
|
+
border-radius: 999px;
|
|
43
|
+
}
|
|
44
|
+
[data-code]::-webkit-scrollbar-thumb:hover {
|
|
45
|
+
background-color: color-mix(in srgb, var(--jp-ui-font-color1) 45%, transparent);
|
|
46
|
+
}
|
|
47
|
+
@supports (-moz-appearance: none) {
|
|
48
|
+
[data-code] {
|
|
49
|
+
scrollbar-color: var(--xtralab-diff-scrollbar-thumb) transparent;
|
|
50
|
+
}
|
|
51
|
+
}`;
|
|
52
|
+
|
|
29
53
|
/**
|
|
30
54
|
* Choose Pierre's palette or the JupyterLab CSS-variable theme.
|
|
31
55
|
*/
|
package/src/git/diffWidget.tsx
CHANGED
|
@@ -15,19 +15,19 @@ import type { SelectedLineRange } from '@pierre/diffs';
|
|
|
15
15
|
import type { IAskAgent } from '../askAgent/tokens';
|
|
16
16
|
|
|
17
17
|
import { buildDiffAskRequest } from './askRequest';
|
|
18
|
+
import {
|
|
19
|
+
useDiffPreferences,
|
|
20
|
+
type IDiffPreferences,
|
|
21
|
+
type ImageDiffViewMode
|
|
22
|
+
} from './diffPreferences';
|
|
18
23
|
import {
|
|
19
24
|
DIFF_WIDGET_CSS_CLASS,
|
|
20
25
|
DiffStyleControl,
|
|
21
26
|
DiffSurface,
|
|
27
|
+
LineWrapControl,
|
|
22
28
|
NotebookViewModeControl,
|
|
23
29
|
isDarkTheme,
|
|
24
|
-
isPierreTheme
|
|
25
|
-
readStoredDiffStyle,
|
|
26
|
-
readStoredNotebookViewMode,
|
|
27
|
-
writeStoredDiffStyle,
|
|
28
|
-
writeStoredNotebookViewMode,
|
|
29
|
-
type DiffStyle,
|
|
30
|
-
type NotebookDiffViewMode
|
|
30
|
+
isPierreTheme
|
|
31
31
|
} from './diffSurface';
|
|
32
32
|
import { imageDataType } from './imageDiff';
|
|
33
33
|
|
|
@@ -37,8 +37,17 @@ export { DIFF_WIDGET_CSS_CLASS };
|
|
|
37
37
|
* `Git.Diff.IModel` plus optional xtralab-only metadata.
|
|
38
38
|
*/
|
|
39
39
|
export interface IXtralabDiffModel extends Git.Diff.IModel {
|
|
40
|
+
/**
|
|
41
|
+
* Whether the file is binary, so no text contents are fetched.
|
|
42
|
+
*/
|
|
40
43
|
isBinary?: boolean;
|
|
44
|
+
/**
|
|
45
|
+
* Whether hunks may be discarded; when absent, a working-tree heuristic decides.
|
|
46
|
+
*/
|
|
41
47
|
canDiscard?: boolean;
|
|
48
|
+
/**
|
|
49
|
+
* The old-side path when the diff represents a rename.
|
|
50
|
+
*/
|
|
42
51
|
oldFilename?: string;
|
|
43
52
|
}
|
|
44
53
|
|
|
@@ -46,14 +55,31 @@ export interface IXtralabDiffModel extends Git.Diff.IModel {
|
|
|
46
55
|
* Application-level services the diff model does not carry.
|
|
47
56
|
*/
|
|
48
57
|
export interface IXtralabDiffContext {
|
|
58
|
+
/**
|
|
59
|
+
* The contents manager used to save hunk-discard results.
|
|
60
|
+
*/
|
|
49
61
|
contentsManager: Contents.IManager;
|
|
62
|
+
/**
|
|
63
|
+
* The rendermime registry for rendered notebook diffs, or `null` to
|
|
64
|
+
* force the textual fallback.
|
|
65
|
+
*/
|
|
50
66
|
rendermime: IRenderMimeRegistry | null;
|
|
67
|
+
/**
|
|
68
|
+
* The theme manager used to track theme changes, or `null` to watch
|
|
69
|
+
* the body attribute instead.
|
|
70
|
+
*/
|
|
51
71
|
themeManager: IThemeManager | null;
|
|
52
72
|
/**
|
|
53
|
-
*
|
|
54
|
-
* "ask an agent about these lines" gutter button.
|
|
73
|
+
* When available, diff line selections get an "ask an agent" gutter button.
|
|
55
74
|
*/
|
|
56
75
|
askAgent: IAskAgent | null;
|
|
76
|
+
/**
|
|
77
|
+
* The display choices shared by all diff views.
|
|
78
|
+
*/
|
|
79
|
+
preferences: IDiffPreferences;
|
|
80
|
+
/**
|
|
81
|
+
* The application translation bundle.
|
|
82
|
+
*/
|
|
57
83
|
trans: TranslationBundle;
|
|
58
84
|
}
|
|
59
85
|
|
|
@@ -68,13 +94,14 @@ export class XtralabDiffWidget
|
|
|
68
94
|
super();
|
|
69
95
|
this._model = model;
|
|
70
96
|
this._context = context;
|
|
71
|
-
this._notebookViewMode = readStoredNotebookViewMode();
|
|
72
|
-
this._diffStyle = readStoredDiffStyle();
|
|
73
97
|
// Reuse jupyterlab-git's host sizing while applying xtralab styling.
|
|
74
98
|
this.addClass('jp-git-diff-root');
|
|
75
99
|
this.addClass(DIFF_WIDGET_CSS_CLASS);
|
|
76
100
|
}
|
|
77
101
|
|
|
102
|
+
/**
|
|
103
|
+
* The git diff model being rendered.
|
|
104
|
+
*/
|
|
78
105
|
get model(): Git.Diff.IModel {
|
|
79
106
|
return this._model;
|
|
80
107
|
}
|
|
@@ -124,27 +151,16 @@ export class XtralabDiffWidget
|
|
|
124
151
|
await done.promise;
|
|
125
152
|
}
|
|
126
153
|
|
|
127
|
-
|
|
128
|
-
|
|
129
|
-
|
|
130
|
-
|
|
131
|
-
setNotebookViewMode(mode: NotebookDiffViewMode): void {
|
|
132
|
-
if (mode === this._notebookViewMode) {
|
|
133
|
-
return;
|
|
134
|
-
}
|
|
135
|
-
this._notebookViewMode = mode;
|
|
136
|
-
writeStoredNotebookViewMode(mode);
|
|
137
|
-
this._notebookViewModeChanged.emit(mode);
|
|
138
|
-
}
|
|
139
|
-
|
|
140
|
-
get notebookViewModeChanged(): ISignal<this, NotebookDiffViewMode> {
|
|
141
|
-
return this._notebookViewModeChanged;
|
|
142
|
-
}
|
|
143
|
-
|
|
154
|
+
/**
|
|
155
|
+
* Whether a rendered notebook view is currently available.
|
|
156
|
+
*/
|
|
144
157
|
get hasNotebookView(): boolean {
|
|
145
158
|
return this._hasNotebookView;
|
|
146
159
|
}
|
|
147
160
|
|
|
161
|
+
/**
|
|
162
|
+
* Set whether a rendered notebook view is available.
|
|
163
|
+
*/
|
|
148
164
|
setHasNotebookView(value: boolean): void {
|
|
149
165
|
if (value === this._hasNotebookView) {
|
|
150
166
|
return;
|
|
@@ -153,34 +169,23 @@ export class XtralabDiffWidget
|
|
|
153
169
|
this._hasNotebookViewChanged.emit(value);
|
|
154
170
|
}
|
|
155
171
|
|
|
172
|
+
/**
|
|
173
|
+
* A signal emitted when rendered-notebook availability changes.
|
|
174
|
+
*/
|
|
156
175
|
get hasNotebookViewChanged(): ISignal<this, boolean> {
|
|
157
176
|
return this._hasNotebookViewChanged;
|
|
158
177
|
}
|
|
159
178
|
|
|
160
|
-
get diffStyle(): DiffStyle {
|
|
161
|
-
return this._diffStyle;
|
|
162
|
-
}
|
|
163
|
-
|
|
164
|
-
setDiffStyle(style: DiffStyle): void {
|
|
165
|
-
if (style === this._diffStyle) {
|
|
166
|
-
return;
|
|
167
|
-
}
|
|
168
|
-
this._diffStyle = style;
|
|
169
|
-
writeStoredDiffStyle(style);
|
|
170
|
-
this._diffStyleChanged.emit(style);
|
|
171
|
-
}
|
|
172
|
-
|
|
173
|
-
get diffStyleChanged(): ISignal<this, DiffStyle> {
|
|
174
|
-
return this._diffStyleChanged;
|
|
175
|
-
}
|
|
176
|
-
|
|
177
179
|
/**
|
|
178
|
-
* Whether the Split/Unified toolbar
|
|
180
|
+
* Whether the Split/Unified and line-wrap toolbar controls currently apply.
|
|
179
181
|
*/
|
|
180
182
|
get fileDiffActive(): boolean {
|
|
181
183
|
return this._fileDiffActive;
|
|
182
184
|
}
|
|
183
185
|
|
|
186
|
+
/**
|
|
187
|
+
* Set whether the textual file diff is the active view.
|
|
188
|
+
*/
|
|
184
189
|
setFileDiffActive(value: boolean): void {
|
|
185
190
|
if (value === this._fileDiffActive) {
|
|
186
191
|
return;
|
|
@@ -189,6 +194,9 @@ export class XtralabDiffWidget
|
|
|
189
194
|
this._fileDiffActiveChanged.emit(value);
|
|
190
195
|
}
|
|
191
196
|
|
|
197
|
+
/**
|
|
198
|
+
* A signal emitted when {@link fileDiffActive} changes.
|
|
199
|
+
*/
|
|
192
200
|
get fileDiffActiveChanged(): ISignal<this, boolean> {
|
|
193
201
|
return this._fileDiffActiveChanged;
|
|
194
202
|
}
|
|
@@ -200,32 +208,49 @@ export class XtralabDiffWidget
|
|
|
200
208
|
return this._emptied;
|
|
201
209
|
}
|
|
202
210
|
|
|
211
|
+
/**
|
|
212
|
+
* Emit the {@link emptied} signal.
|
|
213
|
+
*/
|
|
203
214
|
notifyEmptied(): void {
|
|
204
215
|
this._emptied.emit();
|
|
205
216
|
}
|
|
206
217
|
|
|
218
|
+
/**
|
|
219
|
+
* Resolve and clear the pending `refresh()` promise, if any.
|
|
220
|
+
*/
|
|
207
221
|
settleRefresh(): void {
|
|
208
222
|
const pending = this._pendingRefresh;
|
|
209
223
|
this._pendingRefresh = null;
|
|
210
224
|
pending?.resolve();
|
|
211
225
|
}
|
|
212
226
|
|
|
227
|
+
/**
|
|
228
|
+
* Dispose of the resources held by the widget.
|
|
229
|
+
*/
|
|
213
230
|
dispose(): void {
|
|
214
|
-
//
|
|
215
|
-
//
|
|
216
|
-
// hang when the widget is torn down mid-fetch.
|
|
231
|
+
// jupyterlab-git awaits refresh() to re-show its diff button; release any
|
|
232
|
+
// in-flight awaiter so it does not hang on mid-fetch teardown.
|
|
217
233
|
this.settleRefresh();
|
|
218
234
|
super.dispose();
|
|
219
235
|
}
|
|
220
236
|
|
|
237
|
+
/**
|
|
238
|
+
* A counter incremented on each `refresh()` to trigger a content re-fetch.
|
|
239
|
+
*/
|
|
221
240
|
get reloadNonce(): number {
|
|
222
241
|
return this._reloadNonce;
|
|
223
242
|
}
|
|
224
243
|
|
|
244
|
+
/**
|
|
245
|
+
* The application-level services used by the rendered diff.
|
|
246
|
+
*/
|
|
225
247
|
get context(): IXtralabDiffContext {
|
|
226
248
|
return this._context;
|
|
227
249
|
}
|
|
228
250
|
|
|
251
|
+
/**
|
|
252
|
+
* Render the diff view for the current model.
|
|
253
|
+
*/
|
|
229
254
|
protected render(): React.ReactElement {
|
|
230
255
|
return <ModelDiffView widget={this} />;
|
|
231
256
|
}
|
|
@@ -234,23 +259,32 @@ export class XtralabDiffWidget
|
|
|
234
259
|
private _context: IXtralabDiffContext;
|
|
235
260
|
private _reloadNonce = 0;
|
|
236
261
|
private _pendingRefresh: PromiseDelegate<void> | null = null;
|
|
237
|
-
private _notebookViewMode: NotebookDiffViewMode;
|
|
238
|
-
private _notebookViewModeChanged = new Signal<this, NotebookDiffViewMode>(
|
|
239
|
-
this
|
|
240
|
-
);
|
|
241
262
|
private _hasNotebookView = false;
|
|
242
263
|
private _hasNotebookViewChanged = new Signal<this, boolean>(this);
|
|
243
|
-
private _diffStyle: DiffStyle;
|
|
244
|
-
private _diffStyleChanged = new Signal<this, DiffStyle>(this);
|
|
245
264
|
private _fileDiffActive = false;
|
|
246
265
|
private _fileDiffActiveChanged = new Signal<this, boolean>(this);
|
|
247
266
|
private _emptied = new Signal<this, void>(this);
|
|
248
267
|
}
|
|
249
268
|
|
|
269
|
+
/**
|
|
270
|
+
* Resolved file-contents state for {@link ModelDiffView}.
|
|
271
|
+
*/
|
|
250
272
|
interface IModelDiffState {
|
|
273
|
+
/**
|
|
274
|
+
* Whether the file contents are still being fetched.
|
|
275
|
+
*/
|
|
251
276
|
loading: boolean;
|
|
277
|
+
/**
|
|
278
|
+
* The resolved reference-side text.
|
|
279
|
+
*/
|
|
252
280
|
oldText: string;
|
|
281
|
+
/**
|
|
282
|
+
* The resolved challenger-side text.
|
|
283
|
+
*/
|
|
253
284
|
newText: string;
|
|
285
|
+
/**
|
|
286
|
+
* The fetch error message, or `null` if none.
|
|
287
|
+
*/
|
|
254
288
|
error: string | null;
|
|
255
289
|
}
|
|
256
290
|
|
|
@@ -259,8 +293,15 @@ function ModelDiffView(props: {
|
|
|
259
293
|
}): React.ReactElement {
|
|
260
294
|
const { widget } = props;
|
|
261
295
|
const model = widget.model as IXtralabDiffModel;
|
|
262
|
-
const {
|
|
263
|
-
|
|
296
|
+
const {
|
|
297
|
+
contentsManager,
|
|
298
|
+
rendermime,
|
|
299
|
+
themeManager,
|
|
300
|
+
askAgent,
|
|
301
|
+
preferences,
|
|
302
|
+
trans
|
|
303
|
+
} = widget.context;
|
|
304
|
+
const values = useDiffPreferences(preferences);
|
|
264
305
|
const nonce = widget.reloadNonce;
|
|
265
306
|
|
|
266
307
|
const [state, setState] = React.useState<IModelDiffState>({
|
|
@@ -270,23 +311,6 @@ function ModelDiffView(props: {
|
|
|
270
311
|
error: null
|
|
271
312
|
});
|
|
272
313
|
|
|
273
|
-
// Mirror toolbar-driven notebook view changes into React state.
|
|
274
|
-
const [notebookViewMode, setNotebookViewMode] =
|
|
275
|
-
React.useState<NotebookDiffViewMode>(() => widget.notebookViewMode);
|
|
276
|
-
React.useEffect(() => {
|
|
277
|
-
const handler = (
|
|
278
|
-
sender: XtralabDiffWidget,
|
|
279
|
-
mode: NotebookDiffViewMode
|
|
280
|
-
): void => {
|
|
281
|
-
setNotebookViewMode(mode);
|
|
282
|
-
};
|
|
283
|
-
widget.notebookViewModeChanged.connect(handler);
|
|
284
|
-
setNotebookViewMode(widget.notebookViewMode);
|
|
285
|
-
return () => {
|
|
286
|
-
widget.notebookViewModeChanged.disconnect(handler);
|
|
287
|
-
};
|
|
288
|
-
}, [widget]);
|
|
289
|
-
|
|
290
314
|
const handleNotebookAvailabilityChange = React.useCallback(
|
|
291
315
|
(available: boolean) => {
|
|
292
316
|
widget.setHasNotebookView(available);
|
|
@@ -294,20 +318,19 @@ function ModelDiffView(props: {
|
|
|
294
318
|
[widget]
|
|
295
319
|
);
|
|
296
320
|
|
|
297
|
-
|
|
298
|
-
|
|
299
|
-
|
|
321
|
+
const handleSplitRatioChange = React.useCallback(
|
|
322
|
+
(splitRatio: number) => {
|
|
323
|
+
preferences.update({ splitRatio });
|
|
324
|
+
},
|
|
325
|
+
[preferences]
|
|
326
|
+
);
|
|
327
|
+
|
|
328
|
+
const handleImageViewModeChange = React.useCallback(
|
|
329
|
+
(imageViewMode: ImageDiffViewMode) => {
|
|
330
|
+
preferences.update({ imageViewMode });
|
|
331
|
+
},
|
|
332
|
+
[preferences]
|
|
300
333
|
);
|
|
301
|
-
React.useEffect(() => {
|
|
302
|
-
const handler = (sender: XtralabDiffWidget, style: DiffStyle): void => {
|
|
303
|
-
setDiffStyle(style);
|
|
304
|
-
};
|
|
305
|
-
widget.diffStyleChanged.connect(handler);
|
|
306
|
-
setDiffStyle(widget.diffStyle);
|
|
307
|
-
return () => {
|
|
308
|
-
widget.diffStyleChanged.disconnect(handler);
|
|
309
|
-
};
|
|
310
|
-
}, [widget]);
|
|
311
334
|
|
|
312
335
|
const handleFileDiffActiveChange = React.useCallback(
|
|
313
336
|
(active: boolean) => {
|
|
@@ -343,14 +366,12 @@ function ModelDiffView(props: {
|
|
|
343
366
|
};
|
|
344
367
|
}, [themeManager]);
|
|
345
368
|
|
|
346
|
-
// Image diffs use the server's base64 payloads; other binaries show a placeholder.
|
|
347
369
|
const isImage = React.useMemo(
|
|
348
370
|
() => imageDataType(model.filename) !== null,
|
|
349
371
|
[model.filename]
|
|
350
372
|
);
|
|
351
373
|
const isBinary = model.isBinary === true && !isImage;
|
|
352
374
|
|
|
353
|
-
// Used by the launcher to auto-close an emptied diff after discard.
|
|
354
375
|
const [hunkCount, setHunkCount] = React.useState<number | null>(null);
|
|
355
376
|
const handleMetadataChange = React.useCallback(
|
|
356
377
|
(info: { hunkCount: number | null }) => {
|
|
@@ -359,10 +380,8 @@ function ModelDiffView(props: {
|
|
|
359
380
|
[]
|
|
360
381
|
);
|
|
361
382
|
|
|
362
|
-
// Fetch both sides whenever the model or reload nonce changes.
|
|
363
383
|
React.useEffect(() => {
|
|
364
384
|
let cancelled = false;
|
|
365
|
-
// Non-image binaries do not need content fetches.
|
|
366
385
|
if (isBinary) {
|
|
367
386
|
setState({ loading: false, oldText: '', newText: '', error: null });
|
|
368
387
|
// An in-flight `refresh()` still has to resolve.
|
|
@@ -399,7 +418,6 @@ function ModelDiffView(props: {
|
|
|
399
418
|
});
|
|
400
419
|
} finally {
|
|
401
420
|
if (!cancelled) {
|
|
402
|
-
// Let `refresh()` settle once content has loaded.
|
|
403
421
|
widget.settleRefresh();
|
|
404
422
|
}
|
|
405
423
|
}
|
|
@@ -422,7 +440,6 @@ function ModelDiffView(props: {
|
|
|
422
440
|
}
|
|
423
441
|
}, [state.loading, state.error, isBinary, hunkCount, nonce, widget]);
|
|
424
442
|
|
|
425
|
-
// The launcher sets `canDiscard`; jupyterlab-git models fall back to source.
|
|
426
443
|
const canDiscardHunk =
|
|
427
444
|
model.canDiscard ??
|
|
428
445
|
(model.challenger.source === Git.Diff.SpecialRef.WORKING &&
|
|
@@ -444,7 +461,6 @@ function ModelDiffView(props: {
|
|
|
444
461
|
});
|
|
445
462
|
},
|
|
446
463
|
onAfterSave: () => {
|
|
447
|
-
// Re-pull so the diff reflects the reverted hunk.
|
|
448
464
|
void widget.refresh();
|
|
449
465
|
}
|
|
450
466
|
}),
|
|
@@ -481,8 +497,13 @@ function ModelDiffView(props: {
|
|
|
481
497
|
dark={dark}
|
|
482
498
|
pierreTheme={pierre}
|
|
483
499
|
rendermime={rendermime}
|
|
484
|
-
notebookViewMode={notebookViewMode}
|
|
485
|
-
diffStyle={diffStyle}
|
|
500
|
+
notebookViewMode={values.notebookViewMode}
|
|
501
|
+
diffStyle={values.diffStyle}
|
|
502
|
+
lineWrap={values.lineWrap}
|
|
503
|
+
splitRatio={values.splitRatio}
|
|
504
|
+
onSplitRatioChange={handleSplitRatioChange}
|
|
505
|
+
imageViewMode={values.imageViewMode}
|
|
506
|
+
onImageViewModeChange={handleImageViewModeChange}
|
|
486
507
|
onNotebookAvailabilityChange={handleNotebookAvailabilityChange}
|
|
487
508
|
onFileDiffActiveChange={handleFileDiffActiveChange}
|
|
488
509
|
onMetadataChange={handleMetadataChange}
|
|
@@ -503,6 +524,9 @@ class NotebookViewModeToolbarItem extends ReactWidget {
|
|
|
503
524
|
this.addClass('jp-xtralab-DiffWidget-viewModeToolbarItem');
|
|
504
525
|
}
|
|
505
526
|
|
|
527
|
+
/**
|
|
528
|
+
* Render the Notebook/JSON toggle.
|
|
529
|
+
*/
|
|
506
530
|
protected render(): React.ReactElement {
|
|
507
531
|
return <NotebookViewModeToolbarControl widget={this._widget} />;
|
|
508
532
|
}
|
|
@@ -514,38 +538,27 @@ function NotebookViewModeToolbarControl(props: {
|
|
|
514
538
|
widget: XtralabDiffWidget;
|
|
515
539
|
}): React.ReactElement {
|
|
516
540
|
const { widget } = props;
|
|
517
|
-
const
|
|
518
|
-
|
|
519
|
-
);
|
|
541
|
+
const { preferences, trans } = widget.context;
|
|
542
|
+
const { notebookViewMode } = useDiffPreferences(preferences);
|
|
520
543
|
const [available, setAvailable] = React.useState<boolean>(
|
|
521
544
|
() => widget.hasNotebookView
|
|
522
545
|
);
|
|
523
546
|
React.useEffect(() => {
|
|
524
|
-
const onMode = (
|
|
525
|
-
sender: XtralabDiffWidget,
|
|
526
|
-
next: NotebookDiffViewMode
|
|
527
|
-
): void => {
|
|
528
|
-
setMode(next);
|
|
529
|
-
};
|
|
530
547
|
const onAvailable = (sender: XtralabDiffWidget, next: boolean): void => {
|
|
531
548
|
setAvailable(next);
|
|
532
549
|
};
|
|
533
|
-
widget.notebookViewModeChanged.connect(onMode);
|
|
534
550
|
widget.hasNotebookViewChanged.connect(onAvailable);
|
|
535
|
-
setMode(widget.notebookViewMode);
|
|
536
551
|
setAvailable(widget.hasNotebookView);
|
|
537
552
|
return () => {
|
|
538
|
-
widget.notebookViewModeChanged.disconnect(onMode);
|
|
539
553
|
widget.hasNotebookViewChanged.disconnect(onAvailable);
|
|
540
554
|
};
|
|
541
555
|
}, [widget]);
|
|
542
556
|
|
|
543
|
-
const trans = widget.context.trans;
|
|
544
557
|
return (
|
|
545
558
|
<NotebookViewModeControl
|
|
546
|
-
mode={
|
|
559
|
+
mode={notebookViewMode}
|
|
547
560
|
available={available}
|
|
548
|
-
onChange={next =>
|
|
561
|
+
onChange={next => preferences.update({ notebookViewMode: next })}
|
|
549
562
|
trans={trans}
|
|
550
563
|
/>
|
|
551
564
|
);
|
|
@@ -561,6 +574,9 @@ class DiffStyleToolbarItem extends ReactWidget {
|
|
|
561
574
|
this.addClass('jp-xtralab-DiffWidget-diffStyleToolbarItem');
|
|
562
575
|
}
|
|
563
576
|
|
|
577
|
+
/**
|
|
578
|
+
* Render the Split/Unified toggle.
|
|
579
|
+
*/
|
|
564
580
|
protected render(): React.ReactElement {
|
|
565
581
|
return <DiffStyleToolbarControl widget={this._widget} />;
|
|
566
582
|
}
|
|
@@ -572,42 +588,85 @@ function DiffStyleToolbarControl(props: {
|
|
|
572
588
|
widget: XtralabDiffWidget;
|
|
573
589
|
}): React.ReactElement {
|
|
574
590
|
const { widget } = props;
|
|
575
|
-
const
|
|
576
|
-
const
|
|
577
|
-
|
|
591
|
+
const { preferences, trans } = widget.context;
|
|
592
|
+
const { diffStyle, diffStyleControl } = useDiffPreferences(preferences);
|
|
593
|
+
const available = useFileDiffActive(widget);
|
|
594
|
+
return (
|
|
595
|
+
<DiffStyleControl
|
|
596
|
+
diffStyle={diffStyle}
|
|
597
|
+
control={diffStyleControl}
|
|
598
|
+
available={available}
|
|
599
|
+
onChange={next => preferences.update({ diffStyle: next })}
|
|
600
|
+
trans={trans}
|
|
601
|
+
/>
|
|
578
602
|
);
|
|
579
|
-
|
|
580
|
-
|
|
581
|
-
|
|
582
|
-
|
|
583
|
-
|
|
584
|
-
|
|
585
|
-
|
|
586
|
-
|
|
587
|
-
widget
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
603
|
+
}
|
|
604
|
+
|
|
605
|
+
/**
|
|
606
|
+
* Line-wrap toggle mounted into a host-owned toolbar.
|
|
607
|
+
*/
|
|
608
|
+
class LineWrapToolbarItem extends ReactWidget {
|
|
609
|
+
constructor(widget: XtralabDiffWidget) {
|
|
610
|
+
super();
|
|
611
|
+
this._widget = widget;
|
|
612
|
+
this.addClass('jp-xtralab-DiffWidget-lineWrapToolbarItem');
|
|
613
|
+
}
|
|
614
|
+
|
|
615
|
+
/**
|
|
616
|
+
* Render the line-wrap toggle.
|
|
617
|
+
*/
|
|
618
|
+
protected render(): React.ReactElement {
|
|
619
|
+
return <LineWrapToolbarControl widget={this._widget} />;
|
|
620
|
+
}
|
|
621
|
+
|
|
622
|
+
private _widget: XtralabDiffWidget;
|
|
623
|
+
}
|
|
595
624
|
|
|
596
|
-
|
|
625
|
+
function LineWrapToolbarControl(props: {
|
|
626
|
+
widget: XtralabDiffWidget;
|
|
627
|
+
}): React.ReactElement {
|
|
628
|
+
const { widget } = props;
|
|
629
|
+
const { preferences, trans } = widget.context;
|
|
630
|
+
const { lineWrap } = useDiffPreferences(preferences);
|
|
631
|
+
const available = useFileDiffActive(widget);
|
|
597
632
|
return (
|
|
598
|
-
<
|
|
599
|
-
|
|
633
|
+
<LineWrapControl
|
|
634
|
+
lineWrap={lineWrap}
|
|
600
635
|
available={available}
|
|
601
|
-
onChange={next =>
|
|
636
|
+
onChange={next => preferences.update({ lineWrap: next })}
|
|
602
637
|
trans={trans}
|
|
603
638
|
/>
|
|
604
639
|
);
|
|
605
640
|
}
|
|
606
641
|
|
|
642
|
+
/**
|
|
643
|
+
* Track {@link XtralabDiffWidget.fileDiffActive} for the split/unified and
|
|
644
|
+
* line-wrap controls.
|
|
645
|
+
*/
|
|
646
|
+
function useFileDiffActive(widget: XtralabDiffWidget): boolean {
|
|
647
|
+
const [active, setActive] = React.useState<boolean>(
|
|
648
|
+
() => widget.fileDiffActive
|
|
649
|
+
);
|
|
650
|
+
React.useEffect(() => {
|
|
651
|
+
const onActive = (sender: XtralabDiffWidget, next: boolean): void => {
|
|
652
|
+
setActive(next);
|
|
653
|
+
};
|
|
654
|
+
widget.fileDiffActiveChanged.connect(onActive);
|
|
655
|
+
setActive(widget.fileDiffActive);
|
|
656
|
+
return () => {
|
|
657
|
+
widget.fileDiffActiveChanged.disconnect(onActive);
|
|
658
|
+
};
|
|
659
|
+
}, [widget]);
|
|
660
|
+
return active;
|
|
661
|
+
}
|
|
662
|
+
|
|
607
663
|
/**
|
|
608
664
|
* Structural toolbar type shared across host package boundaries.
|
|
609
665
|
*/
|
|
610
666
|
interface IDiffToolbar {
|
|
667
|
+
/**
|
|
668
|
+
* Add an item to the toolbar under the given name.
|
|
669
|
+
*/
|
|
611
670
|
addItem(name: string, widget: Widget): boolean;
|
|
612
671
|
}
|
|
613
672
|
|
|
@@ -623,4 +682,5 @@ export function addDiffToolbarItems(
|
|
|
623
682
|
new NotebookViewModeToolbarItem(widget)
|
|
624
683
|
);
|
|
625
684
|
toolbar.addItem('xtralab-diff-style', new DiffStyleToolbarItem(widget));
|
|
685
|
+
toolbar.addItem('xtralab-diff-line-wrap', new LineWrapToolbarItem(widget));
|
|
626
686
|
}
|