@lvce-editor/main-area-worker 8.22.0 → 9.1.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.
- package/dist/mainAreaWorkerMain.js +172 -114
- package/package.json +1 -1
|
@@ -2153,35 +2153,62 @@ const getNextRequestId = () => {
|
|
|
2153
2153
|
return ++requestIdCounter;
|
|
2154
2154
|
};
|
|
2155
2155
|
|
|
2156
|
-
const
|
|
2156
|
+
const getViewletModuleId = async uri => {
|
|
2157
|
+
// Query RendererWorker for viewlet module ID (optional, may fail in tests)
|
|
2158
|
+
let viewletModuleId;
|
|
2157
2159
|
try {
|
|
2158
|
-
|
|
2159
|
-
return get(state.uid).newState;
|
|
2160
|
-
};
|
|
2161
|
-
set(state.uid, oldState, state);
|
|
2162
|
-
const newState = await loadTabContentAsync(tabId, path, requestId, getLatestState);
|
|
2163
|
-
return newState;
|
|
2160
|
+
viewletModuleId = await invoke('Layout.getModuleId', uri);
|
|
2164
2161
|
} catch {
|
|
2165
|
-
//
|
|
2162
|
+
// Viewlet creation is optional - silently ignore if RendererWorker isn't available
|
|
2166
2163
|
}
|
|
2167
|
-
return
|
|
2164
|
+
return viewletModuleId;
|
|
2168
2165
|
};
|
|
2169
2166
|
|
|
2170
|
-
const
|
|
2171
|
-
|
|
2172
|
-
|
|
2173
|
-
|
|
2167
|
+
const DiffEditor = 'DiffEditor';
|
|
2168
|
+
const ExtensionDetail = 'ExtensionDetail';
|
|
2169
|
+
const QuickPick = 'QuickPick';
|
|
2170
|
+
|
|
2171
|
+
const getViewletModuleIdForEditorInput = async editorInput => {
|
|
2172
|
+
switch (editorInput.type) {
|
|
2173
|
+
case 'diff-editor':
|
|
2174
|
+
return DiffEditor;
|
|
2175
|
+
case 'editor':
|
|
2176
|
+
return getViewletModuleId(editorInput.uri);
|
|
2177
|
+
case 'extension-detail-view':
|
|
2178
|
+
return ExtensionDetail;
|
|
2179
|
+
}
|
|
2180
|
+
};
|
|
2181
|
+
|
|
2182
|
+
const shouldLoadContentForTab = tab => {
|
|
2183
|
+
if (tab.editorInput && tab.editorInput.type !== 'editor') {
|
|
2184
|
+
return false;
|
|
2185
|
+
}
|
|
2174
2186
|
if (!tab.uri) {
|
|
2175
2187
|
return false;
|
|
2176
2188
|
}
|
|
2177
2189
|
if (tab.loadingState === 'loading') {
|
|
2178
2190
|
return false;
|
|
2179
2191
|
}
|
|
2180
|
-
if (tab.loadingState === 'loaded') {
|
|
2192
|
+
if (tab.loadingState === 'loaded' && tab.editorUid !== -1) {
|
|
2181
2193
|
return false;
|
|
2182
2194
|
}
|
|
2183
2195
|
return true;
|
|
2184
2196
|
};
|
|
2197
|
+
|
|
2198
|
+
const startContentLoading = async (oldState, state, tabId, path, requestId) => {
|
|
2199
|
+
try {
|
|
2200
|
+
const getLatestState = () => {
|
|
2201
|
+
return get(state.uid).newState;
|
|
2202
|
+
};
|
|
2203
|
+
set(state.uid, oldState, state);
|
|
2204
|
+
const newState = await loadTabContentAsync(tabId, path, requestId, getLatestState);
|
|
2205
|
+
return newState;
|
|
2206
|
+
} catch {
|
|
2207
|
+
// Silently ignore errors - the tab may have been closed or the component unmounted
|
|
2208
|
+
}
|
|
2209
|
+
return state;
|
|
2210
|
+
};
|
|
2211
|
+
|
|
2185
2212
|
const getActiveTabId$1 = state => {
|
|
2186
2213
|
const {
|
|
2187
2214
|
layout
|
|
@@ -2213,9 +2240,10 @@ const selectTab = async (state, groupIndex, index) => {
|
|
|
2213
2240
|
const tab = group.tabs[index];
|
|
2214
2241
|
const groupId = group.id;
|
|
2215
2242
|
const tabId = tab.id;
|
|
2243
|
+
const isAlreadyActive = layout.activeGroupId === groupId && group.activeTabId === tabId;
|
|
2216
2244
|
|
|
2217
|
-
//
|
|
2218
|
-
if (
|
|
2245
|
+
// Allow restored tabs without a live editor to recover even if they are already selected.
|
|
2246
|
+
if (isAlreadyActive && !shouldLoadContentForTab(tab)) {
|
|
2219
2247
|
return state;
|
|
2220
2248
|
}
|
|
2221
2249
|
|
|
@@ -2223,7 +2251,7 @@ const selectTab = async (state, groupIndex, index) => {
|
|
|
2223
2251
|
getActiveTabId$1(state);
|
|
2224
2252
|
|
|
2225
2253
|
// Check if we need to load content for the newly selected tab
|
|
2226
|
-
const needsLoading =
|
|
2254
|
+
const needsLoading = shouldLoadContentForTab(tab);
|
|
2227
2255
|
const requestId = needsLoading ? getNextRequestId() : 0;
|
|
2228
2256
|
|
|
2229
2257
|
// Update the groups array with the new active tab and active group
|
|
@@ -2272,10 +2300,8 @@ const selectTab = async (state, groupIndex, index) => {
|
|
|
2272
2300
|
|
|
2273
2301
|
// If new tab's viewlet isn't ready yet, trigger creation (idempotent)
|
|
2274
2302
|
const newTab = newState.layout.groups[groupIndex].tabs[index];
|
|
2275
|
-
if (newTab.uri && (!newTab.loadingState || newTab.loadingState === 'loading')) {
|
|
2276
|
-
|
|
2277
|
-
|
|
2278
|
-
const viewletModuleId = await invoke('Layout.getModuleId', newTab.uri);
|
|
2303
|
+
if (newTab.uri && (newTab.editorUid === -1 || !newTab.loadingState || newTab.loadingState === 'loading')) {
|
|
2304
|
+
const viewletModuleId = newTab.editorInput ? await getViewletModuleIdForEditorInput(newTab.editorInput) : await invoke('Layout.getModuleId', newTab.uri);
|
|
2279
2305
|
if (viewletModuleId) {
|
|
2280
2306
|
// Calculate bounds: use main area bounds minus 35px for tab height
|
|
2281
2307
|
const TAB_HEIGHT = 35;
|
|
@@ -2459,6 +2485,14 @@ const getBasename$1 = uri => {
|
|
|
2459
2485
|
}
|
|
2460
2486
|
return uri.slice(lastSlashIndex + 1);
|
|
2461
2487
|
};
|
|
2488
|
+
const inlineDiffPrefix = 'inline-diff://';
|
|
2489
|
+
const diffSeparator = '<->';
|
|
2490
|
+
const getInlineDiffLabel = uri => {
|
|
2491
|
+
const content = uri.slice(inlineDiffPrefix.length);
|
|
2492
|
+
const separatorIndex = content.indexOf(diffSeparator);
|
|
2493
|
+
const workingTreeUri = separatorIndex === -1 ? content : content.slice(separatorIndex + diffSeparator.length);
|
|
2494
|
+
return `${getBasename$1(workingTreeUri)} (Working Tree)`;
|
|
2495
|
+
};
|
|
2462
2496
|
const getLabel = uri => {
|
|
2463
2497
|
if (uri.startsWith('settings://')) {
|
|
2464
2498
|
return 'Settings';
|
|
@@ -2472,10 +2506,13 @@ const getLabel = uri => {
|
|
|
2472
2506
|
if (uri.startsWith('language-models://')) {
|
|
2473
2507
|
return 'Language Models';
|
|
2474
2508
|
}
|
|
2509
|
+
if (uri.startsWith(inlineDiffPrefix)) {
|
|
2510
|
+
return getInlineDiffLabel(uri);
|
|
2511
|
+
}
|
|
2475
2512
|
return getBasename$1(uri);
|
|
2476
2513
|
};
|
|
2477
2514
|
|
|
2478
|
-
const createEmptyGroup = (state, uri, requestId, preview = false) => {
|
|
2515
|
+
const createEmptyGroup = (state, uri, requestId, preview = false, title = getLabel(uri), editorType = 'text', editorInput) => {
|
|
2479
2516
|
const {
|
|
2480
2517
|
layout
|
|
2481
2518
|
} = state;
|
|
@@ -2483,11 +2520,11 @@ const createEmptyGroup = (state, uri, requestId, preview = false) => {
|
|
|
2483
2520
|
groups
|
|
2484
2521
|
} = layout;
|
|
2485
2522
|
const groupId = create$1();
|
|
2486
|
-
const title = getLabel(uri);
|
|
2487
2523
|
const tabId = create$1();
|
|
2488
2524
|
const editorUid = create$1();
|
|
2489
2525
|
const newTab = {
|
|
2490
|
-
|
|
2526
|
+
editorInput,
|
|
2527
|
+
editorType,
|
|
2491
2528
|
editorUid,
|
|
2492
2529
|
errorMessage: '',
|
|
2493
2530
|
icon: '',
|
|
@@ -2553,7 +2590,7 @@ const openTab = (state, groupId, tab) => {
|
|
|
2553
2590
|
};
|
|
2554
2591
|
};
|
|
2555
2592
|
|
|
2556
|
-
const ensureActiveGroup = (state, uri, preview = false) => {
|
|
2593
|
+
const ensureActiveGroup = (state, uri, preview = false, title = getLabel(uri), editorType = 'text', editorInput) => {
|
|
2557
2594
|
// Find the active group (by activeGroupId or focused flag)
|
|
2558
2595
|
const {
|
|
2559
2596
|
layout
|
|
@@ -2572,7 +2609,6 @@ const ensureActiveGroup = (state, uri, preview = false) => {
|
|
|
2572
2609
|
if (activeGroup) {
|
|
2573
2610
|
const activeTab = activeGroup.tabs.find(tab => tab.id === activeGroup.activeTabId);
|
|
2574
2611
|
if (activeTab?.isPreview) {
|
|
2575
|
-
const title = getLabel(uri);
|
|
2576
2612
|
const updatedGroups = groups.map(group => {
|
|
2577
2613
|
if (group.id !== activeGroup.id) {
|
|
2578
2614
|
return group;
|
|
@@ -2583,6 +2619,8 @@ const ensureActiveGroup = (state, uri, preview = false) => {
|
|
|
2583
2619
|
}
|
|
2584
2620
|
return {
|
|
2585
2621
|
...tab,
|
|
2622
|
+
editorInput,
|
|
2623
|
+
editorType,
|
|
2586
2624
|
errorMessage: '',
|
|
2587
2625
|
icon: '',
|
|
2588
2626
|
isDirty: false,
|
|
@@ -2609,11 +2647,11 @@ const ensureActiveGroup = (state, uri, preview = false) => {
|
|
|
2609
2647
|
}
|
|
2610
2648
|
|
|
2611
2649
|
// Create a new tab with the URI in the active group
|
|
2612
|
-
const title = getLabel(uri);
|
|
2613
2650
|
const tabId = create$1();
|
|
2614
2651
|
const editorUid = create$1();
|
|
2615
2652
|
const newTab = {
|
|
2616
|
-
|
|
2653
|
+
editorInput,
|
|
2654
|
+
editorType,
|
|
2617
2655
|
editorUid,
|
|
2618
2656
|
errorMessage: '',
|
|
2619
2657
|
icon: '',
|
|
@@ -2627,7 +2665,7 @@ const ensureActiveGroup = (state, uri, preview = false) => {
|
|
|
2627
2665
|
};
|
|
2628
2666
|
newState = openTab(state, activeGroup.id, newTab);
|
|
2629
2667
|
} else {
|
|
2630
|
-
newState = createEmptyGroup(state, uri, requestId, preview);
|
|
2668
|
+
newState = createEmptyGroup(state, uri, requestId, preview, title, editorType, editorInput);
|
|
2631
2669
|
}
|
|
2632
2670
|
return newState;
|
|
2633
2671
|
};
|
|
@@ -2684,6 +2722,42 @@ const getActiveTabId = state => {
|
|
|
2684
2722
|
return activeGroup?.activeTabId;
|
|
2685
2723
|
};
|
|
2686
2724
|
|
|
2725
|
+
const getEditorInputEditorType = editorInput => {
|
|
2726
|
+
switch (editorInput.type) {
|
|
2727
|
+
case 'diff-editor':
|
|
2728
|
+
case 'extension-detail-view':
|
|
2729
|
+
return 'custom';
|
|
2730
|
+
case 'editor':
|
|
2731
|
+
return 'text';
|
|
2732
|
+
}
|
|
2733
|
+
};
|
|
2734
|
+
|
|
2735
|
+
const getEditorInputTitle = editorInput => {
|
|
2736
|
+
switch (editorInput.type) {
|
|
2737
|
+
case 'diff-editor':
|
|
2738
|
+
{
|
|
2739
|
+
const leftTitle = getLabel(editorInput.uriLeft);
|
|
2740
|
+
const rightTitle = getLabel(editorInput.uriRight);
|
|
2741
|
+
return `${leftTitle} - ${rightTitle}`;
|
|
2742
|
+
}
|
|
2743
|
+
case 'editor':
|
|
2744
|
+
return getLabel(editorInput.uri);
|
|
2745
|
+
case 'extension-detail-view':
|
|
2746
|
+
return editorInput.extensionId;
|
|
2747
|
+
}
|
|
2748
|
+
};
|
|
2749
|
+
|
|
2750
|
+
const getEditorInputUri = editorInput => {
|
|
2751
|
+
switch (editorInput.type) {
|
|
2752
|
+
case 'diff-editor':
|
|
2753
|
+
return `diff://?left=${encodeURIComponent(editorInput.uriLeft)}&right=${encodeURIComponent(editorInput.uriRight)}`;
|
|
2754
|
+
case 'editor':
|
|
2755
|
+
return editorInput.uri;
|
|
2756
|
+
case 'extension-detail-view':
|
|
2757
|
+
return `extension-detail://${editorInput.extensionId}`;
|
|
2758
|
+
}
|
|
2759
|
+
};
|
|
2760
|
+
|
|
2687
2761
|
const getIconsCached = (dirents, fileIconCache) => {
|
|
2688
2762
|
return dirents.map(dirent => fileIconCache[dirent]);
|
|
2689
2763
|
};
|
|
@@ -2771,24 +2845,6 @@ const getFileIconsForTabs = async (tabs, fileIconCache) => {
|
|
|
2771
2845
|
};
|
|
2772
2846
|
};
|
|
2773
2847
|
|
|
2774
|
-
const getOptionUriOptions = options => {
|
|
2775
|
-
if (typeof options === 'string') {
|
|
2776
|
-
return options;
|
|
2777
|
-
}
|
|
2778
|
-
return options.uri;
|
|
2779
|
-
};
|
|
2780
|
-
|
|
2781
|
-
const getViewletModuleId = async uri => {
|
|
2782
|
-
// Query RendererWorker for viewlet module ID (optional, may fail in tests)
|
|
2783
|
-
let viewletModuleId;
|
|
2784
|
-
try {
|
|
2785
|
-
viewletModuleId = await invoke('Layout.getModuleId', uri);
|
|
2786
|
-
} catch {
|
|
2787
|
-
// Viewlet creation is optional - silently ignore if RendererWorker isn't available
|
|
2788
|
-
}
|
|
2789
|
-
return viewletModuleId;
|
|
2790
|
-
};
|
|
2791
|
-
|
|
2792
2848
|
const switchTab = (state, groupId, tabId) => {
|
|
2793
2849
|
const {
|
|
2794
2850
|
layout
|
|
@@ -2817,46 +2873,39 @@ const switchTab = (state, groupId, tabId) => {
|
|
|
2817
2873
|
};
|
|
2818
2874
|
};
|
|
2819
2875
|
|
|
2820
|
-
const
|
|
2876
|
+
const openInput = async (state, options) => {
|
|
2821
2877
|
object(state);
|
|
2878
|
+
object(options);
|
|
2822
2879
|
const {
|
|
2823
2880
|
uid
|
|
2824
2881
|
} = state;
|
|
2825
|
-
const
|
|
2826
|
-
|
|
2827
|
-
|
|
2828
|
-
|
|
2882
|
+
const {
|
|
2883
|
+
editorInput
|
|
2884
|
+
} = options;
|
|
2885
|
+
const preview = options.preview ?? false;
|
|
2886
|
+
const uri = getEditorInputUri(editorInput);
|
|
2887
|
+
const title = getEditorInputTitle(editorInput);
|
|
2888
|
+
const editorType = getEditorInputEditorType(editorInput);
|
|
2829
2889
|
const existingTab = findTabByUri(state, uri);
|
|
2830
2890
|
const shouldRetryExistingTab = existingTab && existingTab.tab.loadingState === 'error';
|
|
2831
2891
|
if (existingTab && !shouldRetryExistingTab) {
|
|
2832
|
-
// Tab exists, switch to it and focus its group
|
|
2833
2892
|
const focusedState = focusEditorGroup(state, existingTab.groupId);
|
|
2834
2893
|
return switchTab(focusedState, existingTab.groupId, existingTab.tab.id);
|
|
2835
2894
|
}
|
|
2836
|
-
|
|
2837
|
-
// Get previous active tab ID for viewlet switching
|
|
2838
2895
|
const previousTabId = getActiveTabId(state);
|
|
2839
|
-
|
|
2840
|
-
// Check if there's existing state in the global store
|
|
2841
2896
|
const stateFromStore = get(uid);
|
|
2842
2897
|
let currentState;
|
|
2843
2898
|
if (stateFromStore) {
|
|
2844
2899
|
const storedState = stateFromStore.newState;
|
|
2845
|
-
|
|
2846
|
-
|
|
2847
|
-
// Otherwise use the passed-in state (test setup with initial data)
|
|
2848
|
-
const storedTabCount = storedState.layout.groups.reduce((sum, g) => sum + g.tabs.length, 0);
|
|
2849
|
-
const passedTabCount = state.layout.groups.reduce((sum, g) => sum + g.tabs.length, 0);
|
|
2900
|
+
const storedTabCount = storedState.layout.groups.reduce((sum, group) => sum + group.tabs.length, 0);
|
|
2901
|
+
const passedTabCount = state.layout.groups.reduce((sum, group) => sum + group.tabs.length, 0);
|
|
2850
2902
|
if (storedTabCount > passedTabCount) {
|
|
2851
|
-
// Stored state has more tabs - concurrent calls have added tabs
|
|
2852
2903
|
currentState = storedState;
|
|
2853
2904
|
} else {
|
|
2854
|
-
// Passed-in state has same or more tabs, use it (likely fresh test setup)
|
|
2855
2905
|
currentState = state;
|
|
2856
2906
|
set(uid, state, state);
|
|
2857
2907
|
}
|
|
2858
2908
|
} else {
|
|
2859
|
-
// No state in store yet, register the passed-in state
|
|
2860
2909
|
currentState = state;
|
|
2861
2910
|
set(uid, state, state);
|
|
2862
2911
|
}
|
|
@@ -2865,22 +2914,20 @@ const openUri = async (state, options) => {
|
|
|
2865
2914
|
if (shouldRetryExistingTab && existingTab) {
|
|
2866
2915
|
const focusedState = focusEditorGroup(currentState, existingTab.groupId);
|
|
2867
2916
|
stateWithTab = updateTab(focusedState, existingTab.tab.id, {
|
|
2917
|
+
editorInput,
|
|
2868
2918
|
errorMessage: '',
|
|
2869
|
-
loadingState: 'loading'
|
|
2919
|
+
loadingState: 'loading',
|
|
2920
|
+
title,
|
|
2921
|
+
uri
|
|
2870
2922
|
});
|
|
2871
2923
|
tabId = existingTab.tab.id;
|
|
2872
2924
|
} else {
|
|
2873
|
-
|
|
2874
|
-
stateWithTab = ensureActiveGroup(currentState, uri, preview);
|
|
2925
|
+
stateWithTab = ensureActiveGroup(currentState, uri, preview, title, editorType, editorInput);
|
|
2875
2926
|
tabId = getActiveTabId(stateWithTab);
|
|
2876
2927
|
}
|
|
2877
|
-
|
|
2878
|
-
// Save state immediately after adding tab or retrying
|
|
2879
2928
|
set(uid, state, stateWithTab);
|
|
2880
2929
|
try {
|
|
2881
|
-
const viewletModuleId = await
|
|
2882
|
-
|
|
2883
|
-
// After async call, get the latest state to account for any concurrent changes
|
|
2930
|
+
const viewletModuleId = await getViewletModuleIdForEditorInput(editorInput);
|
|
2884
2931
|
const {
|
|
2885
2932
|
newState: stateAfterModuleId
|
|
2886
2933
|
} = get(uid);
|
|
@@ -2890,8 +2937,6 @@ const openUri = async (state, options) => {
|
|
|
2890
2937
|
loadingState: 'error'
|
|
2891
2938
|
});
|
|
2892
2939
|
}
|
|
2893
|
-
|
|
2894
|
-
// Calculate bounds: use main area bounds minus tab height
|
|
2895
2940
|
const bounds = {
|
|
2896
2941
|
height: stateAfterModuleId.height - stateAfterModuleId.tabHeight,
|
|
2897
2942
|
width: stateAfterModuleId.width,
|
|
@@ -2899,55 +2944,38 @@ const openUri = async (state, options) => {
|
|
|
2899
2944
|
y: stateAfterModuleId.y + stateAfterModuleId.tabHeight
|
|
2900
2945
|
};
|
|
2901
2946
|
const stateWithViewlet = createViewletForTab(stateAfterModuleId, tabId, viewletModuleId, bounds);
|
|
2902
|
-
let
|
|
2903
|
-
|
|
2904
|
-
// Switch viewlet (detach old, attach new if ready)
|
|
2947
|
+
let intermediateState = stateWithViewlet;
|
|
2905
2948
|
const {
|
|
2906
2949
|
newState: switchedState
|
|
2907
|
-
} = switchViewlet(
|
|
2908
|
-
|
|
2909
|
-
set(uid, state,
|
|
2910
|
-
|
|
2911
|
-
// Get the tab to extract editorUid
|
|
2912
|
-
const tabWithViewlet = findTabById(intermediateState1, tabId);
|
|
2950
|
+
} = switchViewlet(intermediateState, previousTabId, tabId);
|
|
2951
|
+
intermediateState = switchedState;
|
|
2952
|
+
set(uid, state, intermediateState);
|
|
2953
|
+
const tabWithViewlet = findTabById(intermediateState, tabId);
|
|
2913
2954
|
if (!tabWithViewlet) {
|
|
2914
|
-
return
|
|
2955
|
+
return intermediateState;
|
|
2915
2956
|
}
|
|
2916
2957
|
const {
|
|
2917
2958
|
editorUid
|
|
2918
2959
|
} = tabWithViewlet.tab;
|
|
2919
2960
|
if (editorUid === -1) {
|
|
2920
|
-
throw new Error(
|
|
2961
|
+
throw new Error('invalid editorUid');
|
|
2921
2962
|
}
|
|
2922
2963
|
await createViewlet(viewletModuleId, editorUid, tabId, bounds, uri);
|
|
2923
|
-
|
|
2924
|
-
// After viewlet is created, get the latest state and mark it as ready
|
|
2925
|
-
// This ensures we have any state updates that occurred during viewlet creation
|
|
2926
2964
|
const {
|
|
2927
2965
|
newState: latestState
|
|
2928
2966
|
} = get(uid);
|
|
2929
|
-
|
|
2930
|
-
// Attachment is handled automatically by virtual DOM reference nodes
|
|
2931
2967
|
const readyState = handleViewletReady(latestState, editorUid);
|
|
2932
|
-
|
|
2933
|
-
// Save state before async icon request
|
|
2934
2968
|
set(uid, state, readyState);
|
|
2935
|
-
|
|
2936
|
-
// Request file icon for the newly opened tab
|
|
2937
2969
|
try {
|
|
2938
2970
|
const newTab = findTabById(readyState, tabId);
|
|
2939
2971
|
if (newTab && newTab.tab.uri) {
|
|
2940
2972
|
const {
|
|
2941
2973
|
newFileIconCache
|
|
2942
2974
|
} = await getFileIconsForTabs([newTab.tab], readyState.fileIconCache);
|
|
2943
|
-
|
|
2944
|
-
// After async call, get the latest state again
|
|
2945
2975
|
const {
|
|
2946
2976
|
newState: stateBeforeIconUpdate
|
|
2947
2977
|
} = get(uid);
|
|
2948
2978
|
const icon = newFileIconCache[newTab.tab.uri] || '';
|
|
2949
|
-
|
|
2950
|
-
// Update the tab with the icon in the latest state
|
|
2951
2979
|
const stateWithIcon = {
|
|
2952
2980
|
...stateBeforeIconUpdate,
|
|
2953
2981
|
fileIconCache: newFileIconCache,
|
|
@@ -2962,16 +2990,12 @@ const openUri = async (state, options) => {
|
|
|
2962
2990
|
}))
|
|
2963
2991
|
}
|
|
2964
2992
|
};
|
|
2965
|
-
|
|
2966
|
-
// Save the state with icon update so concurrent calls can see it
|
|
2967
2993
|
set(uid, state, stateWithIcon);
|
|
2968
2994
|
return stateWithIcon;
|
|
2969
2995
|
}
|
|
2970
2996
|
} catch {
|
|
2971
|
-
//
|
|
2997
|
+
// ignore
|
|
2972
2998
|
}
|
|
2973
|
-
|
|
2974
|
-
// Get final latest state
|
|
2975
2999
|
const {
|
|
2976
3000
|
newState: finalState
|
|
2977
3001
|
} = get(uid);
|
|
@@ -2990,6 +3014,26 @@ const openUri = async (state, options) => {
|
|
|
2990
3014
|
}
|
|
2991
3015
|
};
|
|
2992
3016
|
|
|
3017
|
+
const getOptionUriOptions = options => {
|
|
3018
|
+
if (typeof options === 'string') {
|
|
3019
|
+
return options;
|
|
3020
|
+
}
|
|
3021
|
+
return options.uri;
|
|
3022
|
+
};
|
|
3023
|
+
|
|
3024
|
+
const openUri = async (state, options) => {
|
|
3025
|
+
const uri = getOptionUriOptions(options);
|
|
3026
|
+
const preview = typeof options === 'string' ? false : options.preview ?? false;
|
|
3027
|
+
return openInput(state, {
|
|
3028
|
+
editorInput: {
|
|
3029
|
+
type: 'editor',
|
|
3030
|
+
uri
|
|
3031
|
+
},
|
|
3032
|
+
focu: typeof options === 'string' ? false : options.focu,
|
|
3033
|
+
preview
|
|
3034
|
+
});
|
|
3035
|
+
};
|
|
3036
|
+
|
|
2993
3037
|
const retryOpen = async state => {
|
|
2994
3038
|
const activeTabData = getActiveTab(state);
|
|
2995
3039
|
if (!activeTabData) {
|
|
@@ -2998,6 +3042,13 @@ const retryOpen = async state => {
|
|
|
2998
3042
|
const {
|
|
2999
3043
|
tab
|
|
3000
3044
|
} = activeTabData;
|
|
3045
|
+
if (tab.editorInput) {
|
|
3046
|
+
return openInput(state, {
|
|
3047
|
+
editorInput: tab.editorInput,
|
|
3048
|
+
focu: false,
|
|
3049
|
+
preview: tab.isPreview
|
|
3050
|
+
});
|
|
3051
|
+
}
|
|
3001
3052
|
if (!tab.uri) {
|
|
3002
3053
|
return state;
|
|
3003
3054
|
}
|
|
@@ -3693,6 +3744,19 @@ const isValidMainAreaLayout = layout => {
|
|
|
3693
3744
|
return true;
|
|
3694
3745
|
};
|
|
3695
3746
|
|
|
3747
|
+
const normalizeRestoredTab = tab => {
|
|
3748
|
+
const {
|
|
3749
|
+
errorMessage: _errorMessage,
|
|
3750
|
+
loadingState: _loadingState,
|
|
3751
|
+
...rest
|
|
3752
|
+
} = tab ?? {};
|
|
3753
|
+
return {
|
|
3754
|
+
...rest,
|
|
3755
|
+
editorUid: -1,
|
|
3756
|
+
isDirty: false,
|
|
3757
|
+
isPreview: typeof tab?.isPreview === 'boolean' ? tab.isPreview : false
|
|
3758
|
+
};
|
|
3759
|
+
};
|
|
3696
3760
|
const tryRestoreLayout = savedState => {
|
|
3697
3761
|
if (savedState === undefined || savedState === null) {
|
|
3698
3762
|
return undefined;
|
|
@@ -3727,12 +3791,7 @@ const tryRestoreLayout = savedState => {
|
|
|
3727
3791
|
...(groupDirection === undefined ? {} : {
|
|
3728
3792
|
direction: groupDirection
|
|
3729
3793
|
}),
|
|
3730
|
-
tabs: Array.isArray(group?.tabs) ? group.tabs.map(
|
|
3731
|
-
...tab,
|
|
3732
|
-
editorUid: -1,
|
|
3733
|
-
isDirty: false,
|
|
3734
|
-
isPreview: typeof tab?.isPreview === 'boolean' ? tab.isPreview : false
|
|
3735
|
-
})) : []
|
|
3794
|
+
tabs: Array.isArray(group?.tabs) ? group.tabs.map(normalizeRestoredTab) : []
|
|
3736
3795
|
};
|
|
3737
3796
|
})
|
|
3738
3797
|
};
|
|
@@ -3762,8 +3821,8 @@ const getViewletModuleIds = async layout => {
|
|
|
3762
3821
|
tabs
|
|
3763
3822
|
} = group;
|
|
3764
3823
|
const activeTab = tabs.find(tab => tab.id === group.activeTabId);
|
|
3765
|
-
if (activeTab && activeTab.uri) {
|
|
3766
|
-
const viewletModuleId = await getViewletModuleId(activeTab.uri);
|
|
3824
|
+
if (activeTab && (activeTab.editorInput || activeTab.uri)) {
|
|
3825
|
+
const viewletModuleId = activeTab.editorInput ? await getViewletModuleIdForEditorInput(activeTab.editorInput) : await getViewletModuleId(activeTab.uri);
|
|
3767
3826
|
if (viewletModuleId) {
|
|
3768
3827
|
viewletModuleIds[activeTab.id] = viewletModuleId;
|
|
3769
3828
|
}
|
|
@@ -4006,8 +4065,6 @@ const menuEntrySeparator = {
|
|
|
4006
4065
|
label: ''
|
|
4007
4066
|
};
|
|
4008
4067
|
|
|
4009
|
-
const QuickPick = 'QuickPick';
|
|
4010
|
-
|
|
4011
4068
|
const getArgs = groupId => {
|
|
4012
4069
|
if (groupId === undefined) {
|
|
4013
4070
|
return undefined;
|
|
@@ -5258,6 +5315,7 @@ const commandMap = {
|
|
|
5258
5315
|
'MainArea.initialize': initialize,
|
|
5259
5316
|
'MainArea.loadContent': wrapCommand(loadContent),
|
|
5260
5317
|
'MainArea.newFile': wrapCommand(newFile),
|
|
5318
|
+
'MainArea.openInput': wrapCommand(openInput),
|
|
5261
5319
|
'MainArea.openUri': wrapCommand(openUri),
|
|
5262
5320
|
'MainArea.openUris': wrapCommand(openUris),
|
|
5263
5321
|
'MainArea.refresh': wrapCommand(refresh),
|