@lvce-editor/main-area-worker 9.24.0 → 9.28.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 +843 -631
- package/package.json +1 -1
|
@@ -3,10 +3,67 @@ const toCommandId = key => {
|
|
|
3
3
|
return key.slice(dotIndex + 1);
|
|
4
4
|
};
|
|
5
5
|
const create$f = () => {
|
|
6
|
+
const commandQueues = new Map();
|
|
7
|
+
const generations = Object.create(null);
|
|
6
8
|
const states = Object.create(null);
|
|
7
9
|
const commandMapRef = {};
|
|
10
|
+
const getGeneration = uid => generations[uid] || 0;
|
|
11
|
+
const isCurrentGeneration = (uid, generation) => {
|
|
12
|
+
return states[uid] !== undefined && getGeneration(uid) === generation;
|
|
13
|
+
};
|
|
14
|
+
const updateState = (uid, generation, fallbackState, updater) => {
|
|
15
|
+
if (!isCurrentGeneration(uid, generation)) {
|
|
16
|
+
return Promise.resolve(fallbackState);
|
|
17
|
+
}
|
|
18
|
+
const current = states[uid];
|
|
19
|
+
const updatedState = updater(current.newState);
|
|
20
|
+
if (updatedState !== current.newState) {
|
|
21
|
+
states[uid] = {
|
|
22
|
+
newState: updatedState,
|
|
23
|
+
oldState: current.oldState,
|
|
24
|
+
scheduledState: updatedState
|
|
25
|
+
};
|
|
26
|
+
}
|
|
27
|
+
return Promise.resolve(updatedState);
|
|
28
|
+
};
|
|
29
|
+
const createAsyncCommandContext = (uid, generation) => {
|
|
30
|
+
let latestState = states[uid].newState;
|
|
31
|
+
return {
|
|
32
|
+
getState: () => {
|
|
33
|
+
if (isCurrentGeneration(uid, generation)) {
|
|
34
|
+
latestState = states[uid].newState;
|
|
35
|
+
}
|
|
36
|
+
return latestState;
|
|
37
|
+
},
|
|
38
|
+
updateState: async updater => {
|
|
39
|
+
latestState = await updateState(uid, generation, latestState, updater);
|
|
40
|
+
return latestState;
|
|
41
|
+
}
|
|
42
|
+
};
|
|
43
|
+
};
|
|
44
|
+
const enqueueCommand = async (uid, command) => {
|
|
45
|
+
const previous = commandQueues.get(uid) || Promise.resolve();
|
|
46
|
+
const run = async () => {
|
|
47
|
+
try {
|
|
48
|
+
await previous;
|
|
49
|
+
} catch {
|
|
50
|
+
// The previous caller receives its error; later commands must still run.
|
|
51
|
+
}
|
|
52
|
+
await command();
|
|
53
|
+
};
|
|
54
|
+
const current = run();
|
|
55
|
+
commandQueues.set(uid, current);
|
|
56
|
+
try {
|
|
57
|
+
await current;
|
|
58
|
+
} finally {
|
|
59
|
+
if (commandQueues.get(uid) === current) {
|
|
60
|
+
commandQueues.delete(uid);
|
|
61
|
+
}
|
|
62
|
+
}
|
|
63
|
+
};
|
|
8
64
|
return {
|
|
9
65
|
clear() {
|
|
66
|
+
commandQueues.clear();
|
|
10
67
|
for (const key of Object.keys(states)) {
|
|
11
68
|
delete states[key];
|
|
12
69
|
}
|
|
@@ -26,6 +83,7 @@ const create$f = () => {
|
|
|
26
83
|
return diffResult;
|
|
27
84
|
},
|
|
28
85
|
dispose(uid) {
|
|
86
|
+
commandQueues.delete(uid);
|
|
29
87
|
delete states[uid];
|
|
30
88
|
},
|
|
31
89
|
get(uid) {
|
|
@@ -43,14 +101,27 @@ const create$f = () => {
|
|
|
43
101
|
Object.assign(commandMapRef, commandMap);
|
|
44
102
|
},
|
|
45
103
|
set(uid, oldState, newState, scheduledState) {
|
|
104
|
+
const current = states[uid];
|
|
105
|
+
if (!current || oldState === newState && newState !== current.newState) {
|
|
106
|
+
generations[uid] = getGeneration(uid) + 1;
|
|
107
|
+
}
|
|
46
108
|
states[uid] = {
|
|
47
109
|
newState,
|
|
48
110
|
oldState,
|
|
49
111
|
scheduledState: scheduledState ?? newState
|
|
50
112
|
};
|
|
51
113
|
},
|
|
114
|
+
wrapAsyncCommand(fn) {
|
|
115
|
+
const wrapped = async (uid, ...args) => {
|
|
116
|
+
const generation = getGeneration(uid);
|
|
117
|
+
const context = createAsyncCommandContext(uid, generation);
|
|
118
|
+
await fn(context, ...args);
|
|
119
|
+
};
|
|
120
|
+
return wrapped;
|
|
121
|
+
},
|
|
52
122
|
wrapCommand(fn) {
|
|
53
123
|
const wrapped = async (uid, ...args) => {
|
|
124
|
+
const generation = getGeneration(uid);
|
|
54
125
|
const {
|
|
55
126
|
newState,
|
|
56
127
|
oldState
|
|
@@ -59,6 +130,9 @@ const create$f = () => {
|
|
|
59
130
|
if (oldState === newerState || newState === newerState) {
|
|
60
131
|
return;
|
|
61
132
|
}
|
|
133
|
+
if (!isCurrentGeneration(uid, generation)) {
|
|
134
|
+
return;
|
|
135
|
+
}
|
|
62
136
|
const latestOld = states[uid];
|
|
63
137
|
const latestNew = {
|
|
64
138
|
...latestOld.newState,
|
|
@@ -83,6 +157,7 @@ const create$f = () => {
|
|
|
83
157
|
},
|
|
84
158
|
wrapLoadContent(fn) {
|
|
85
159
|
const wrapped = async (uid, ...args) => {
|
|
160
|
+
const generation = getGeneration(uid);
|
|
86
161
|
const {
|
|
87
162
|
newState,
|
|
88
163
|
oldState
|
|
@@ -97,6 +172,11 @@ const create$f = () => {
|
|
|
97
172
|
error
|
|
98
173
|
};
|
|
99
174
|
}
|
|
175
|
+
if (!isCurrentGeneration(uid, generation)) {
|
|
176
|
+
return {
|
|
177
|
+
error
|
|
178
|
+
};
|
|
179
|
+
}
|
|
100
180
|
const latestOld = states[uid];
|
|
101
181
|
const latestNew = {
|
|
102
182
|
...latestOld.newState,
|
|
@@ -112,6 +192,51 @@ const create$f = () => {
|
|
|
112
192
|
};
|
|
113
193
|
};
|
|
114
194
|
return wrapped;
|
|
195
|
+
},
|
|
196
|
+
wrapSerialAsyncCommand(fn) {
|
|
197
|
+
const wrapped = async (uid, ...args) => {
|
|
198
|
+
await enqueueCommand(uid, async () => {
|
|
199
|
+
if (!states[uid]) {
|
|
200
|
+
return;
|
|
201
|
+
}
|
|
202
|
+
const generation = getGeneration(uid);
|
|
203
|
+
const context = createAsyncCommandContext(uid, generation);
|
|
204
|
+
await fn(context, ...args);
|
|
205
|
+
});
|
|
206
|
+
};
|
|
207
|
+
return wrapped;
|
|
208
|
+
},
|
|
209
|
+
wrapSerialCommand(fn) {
|
|
210
|
+
const wrapped = async (uid, ...args) => {
|
|
211
|
+
await enqueueCommand(uid, async () => {
|
|
212
|
+
if (!states[uid]) {
|
|
213
|
+
return;
|
|
214
|
+
}
|
|
215
|
+
const generation = getGeneration(uid);
|
|
216
|
+
const {
|
|
217
|
+
newState,
|
|
218
|
+
oldState
|
|
219
|
+
} = states[uid];
|
|
220
|
+
const newerState = await fn(newState, ...args);
|
|
221
|
+
if (oldState === newerState || newState === newerState) {
|
|
222
|
+
return;
|
|
223
|
+
}
|
|
224
|
+
if (!isCurrentGeneration(uid, generation)) {
|
|
225
|
+
return;
|
|
226
|
+
}
|
|
227
|
+
const latestOld = states[uid];
|
|
228
|
+
const latestNew = {
|
|
229
|
+
...latestOld.newState,
|
|
230
|
+
...newerState
|
|
231
|
+
};
|
|
232
|
+
states[uid] = {
|
|
233
|
+
newState: latestNew,
|
|
234
|
+
oldState: latestOld.oldState,
|
|
235
|
+
scheduledState: latestNew
|
|
236
|
+
};
|
|
237
|
+
});
|
|
238
|
+
};
|
|
239
|
+
return wrapped;
|
|
115
240
|
}
|
|
116
241
|
};
|
|
117
242
|
};
|
|
@@ -474,7 +599,14 @@ class IpcError extends VError {
|
|
|
474
599
|
const cause = new Error(message);
|
|
475
600
|
// @ts-ignore
|
|
476
601
|
cause.code = code;
|
|
477
|
-
|
|
602
|
+
if (stack) {
|
|
603
|
+
Object.defineProperty(cause, 'stack', {
|
|
604
|
+
configurable: true,
|
|
605
|
+
enumerable: false,
|
|
606
|
+
value: stack,
|
|
607
|
+
writable: true
|
|
608
|
+
});
|
|
609
|
+
}
|
|
478
610
|
super(cause, betterMessage);
|
|
479
611
|
} else {
|
|
480
612
|
super(betterMessage);
|
|
@@ -1773,123 +1905,463 @@ const closeTab = (state, groupId, tabId) => {
|
|
|
1773
1905
|
return withGroups(stateWithClosedTab, newGroups);
|
|
1774
1906
|
};
|
|
1775
1907
|
|
|
1776
|
-
const
|
|
1777
|
-
|
|
1778
|
-
|
|
1779
|
-
|
|
1780
|
-
const group = layout.groups.find(g => g.id === groupId);
|
|
1781
|
-
return group?.tabs.find(t => t.id === tabId);
|
|
1908
|
+
const handleAttach = async command => {
|
|
1909
|
+
// TODO find a better way to append editors
|
|
1910
|
+
const parentNodeSelector = '.editor-groups-container, .EditorGroup';
|
|
1911
|
+
await invoke('Layout.attachViewlet', parentNodeSelector, command.instanceId);
|
|
1782
1912
|
};
|
|
1783
1913
|
|
|
1784
|
-
const
|
|
1785
|
-
|
|
1914
|
+
const getTitle$1 = async editorUid => {
|
|
1915
|
+
try {
|
|
1916
|
+
const title = await invoke('Viewlet.getTitle', editorUid);
|
|
1917
|
+
return typeof title === 'string' && title ? title : undefined;
|
|
1918
|
+
} catch {
|
|
1919
|
+
return undefined;
|
|
1920
|
+
}
|
|
1921
|
+
};
|
|
1922
|
+
const createViewlet = async (viewletModuleId, editorUid, tabId, bounds, uri) => {
|
|
1923
|
+
await invoke('Layout.createViewlet', viewletModuleId, editorUid, tabId, bounds, uri);
|
|
1924
|
+
return getTitle$1(editorUid);
|
|
1786
1925
|
};
|
|
1787
1926
|
|
|
1788
|
-
const
|
|
1789
|
-
|
|
1790
|
-
|
|
1791
|
-
|
|
1792
|
-
|
|
1793
|
-
|
|
1794
|
-
|
|
1795
|
-
|
|
1796
|
-
|
|
1797
|
-
|
|
1798
|
-
|
|
1799
|
-
|
|
1927
|
+
const {
|
|
1928
|
+
get,
|
|
1929
|
+
getCommandIds,
|
|
1930
|
+
getKeys: getKeys$1,
|
|
1931
|
+
registerCommands,
|
|
1932
|
+
set,
|
|
1933
|
+
wrapAsyncCommand,
|
|
1934
|
+
wrapGetter,
|
|
1935
|
+
wrapSerialAsyncCommand,
|
|
1936
|
+
wrapSerialCommand
|
|
1937
|
+
} = create$f();
|
|
1938
|
+
|
|
1939
|
+
const create$2 = () => {
|
|
1940
|
+
return Math.random();
|
|
1800
1941
|
};
|
|
1801
1942
|
|
|
1802
|
-
const
|
|
1943
|
+
const updateTab = (state, tabId, updates) => {
|
|
1803
1944
|
const {
|
|
1804
1945
|
layout
|
|
1805
1946
|
} = state;
|
|
1806
1947
|
const {
|
|
1807
1948
|
groups
|
|
1808
1949
|
} = layout;
|
|
1809
|
-
|
|
1810
|
-
|
|
1811
|
-
|
|
1812
|
-
|
|
1813
|
-
|
|
1814
|
-
|
|
1815
|
-
|
|
1816
|
-
|
|
1817
|
-
|
|
1818
|
-
|
|
1819
|
-
|
|
1820
|
-
|
|
1821
|
-
|
|
1822
|
-
|
|
1823
|
-
|
|
1824
|
-
|
|
1825
|
-
|
|
1826
|
-
|
|
1827
|
-
const entries = state.layout.groups.flatMap((group, groupIndex) => {
|
|
1828
|
-
return group.tabs.map((tab, tabIndex) => ({
|
|
1829
|
-
group,
|
|
1830
|
-
groupIndex,
|
|
1831
|
-
tab,
|
|
1832
|
-
tabIndex
|
|
1833
|
-
}));
|
|
1950
|
+
const updatedGroups = groups.map(group => {
|
|
1951
|
+
const tabIndex = group.tabs.findIndex(t => t.id === tabId);
|
|
1952
|
+
if (tabIndex === -1) {
|
|
1953
|
+
return group;
|
|
1954
|
+
}
|
|
1955
|
+
const updatedTabs = group.tabs.map((tab, index) => {
|
|
1956
|
+
if (index === tabIndex) {
|
|
1957
|
+
return {
|
|
1958
|
+
...tab,
|
|
1959
|
+
...updates
|
|
1960
|
+
};
|
|
1961
|
+
}
|
|
1962
|
+
return tab;
|
|
1963
|
+
});
|
|
1964
|
+
return {
|
|
1965
|
+
...group,
|
|
1966
|
+
tabs: updatedTabs
|
|
1967
|
+
};
|
|
1834
1968
|
});
|
|
1835
|
-
return
|
|
1836
|
-
|
|
1837
|
-
|
|
1838
|
-
|
|
1839
|
-
|
|
1840
|
-
|
|
1841
|
-
|
|
1842
|
-
...group,
|
|
1843
|
-
size: baseSize + (index === groups.length - 1 ? remainder : 0)
|
|
1844
|
-
}));
|
|
1969
|
+
return {
|
|
1970
|
+
...state,
|
|
1971
|
+
layout: {
|
|
1972
|
+
...layout,
|
|
1973
|
+
groups: updatedGroups
|
|
1974
|
+
}
|
|
1975
|
+
};
|
|
1845
1976
|
};
|
|
1846
1977
|
|
|
1847
|
-
const
|
|
1848
|
-
if (Number.isNaN(groupId)) {
|
|
1849
|
-
return state;
|
|
1850
|
-
}
|
|
1978
|
+
const findTab = (state, tabId) => {
|
|
1851
1979
|
const {
|
|
1852
1980
|
layout
|
|
1853
1981
|
} = state;
|
|
1854
1982
|
const {
|
|
1855
|
-
activeGroupId,
|
|
1856
1983
|
groups
|
|
1857
1984
|
} = layout;
|
|
1858
|
-
const
|
|
1859
|
-
|
|
1860
|
-
|
|
1985
|
+
for (const group of groups) {
|
|
1986
|
+
const tab = group.tabs.find(t => t.id === tabId);
|
|
1987
|
+
if (tab) {
|
|
1988
|
+
return tab;
|
|
1989
|
+
}
|
|
1861
1990
|
}
|
|
1862
|
-
|
|
1863
|
-
|
|
1864
|
-
|
|
1865
|
-
|
|
1991
|
+
return undefined;
|
|
1992
|
+
};
|
|
1993
|
+
const loadFileContent = async path => {
|
|
1994
|
+
const content = await readFile(path);
|
|
1995
|
+
return content;
|
|
1996
|
+
};
|
|
1997
|
+
const getLoadFileErrorMessage = error => {
|
|
1998
|
+
if (!(error instanceof Error)) {
|
|
1999
|
+
return 'Failed to load file content';
|
|
2000
|
+
}
|
|
2001
|
+
if (error.message.includes('EISDIR') || error.message.includes('illegal operation on a directory') || error.message.includes('is a directory')) {
|
|
2002
|
+
return 'Expected a file but received a folder';
|
|
2003
|
+
}
|
|
2004
|
+
return error.message;
|
|
1866
2005
|
};
|
|
2006
|
+
const loadTabContentAsync = async (tabId, path, requestId, getLatestState) => {
|
|
2007
|
+
try {
|
|
2008
|
+
await loadFileContent(path);
|
|
1867
2009
|
|
|
1868
|
-
|
|
1869
|
-
|
|
2010
|
+
// Check for race condition: get the latest state
|
|
2011
|
+
const latestState = getLatestState();
|
|
2012
|
+
const latestTab = findTab(latestState, tabId);
|
|
2013
|
+
|
|
2014
|
+
// If the tab no longer exists, discard this result
|
|
2015
|
+
if (!latestTab) {
|
|
2016
|
+
return latestState;
|
|
2017
|
+
}
|
|
2018
|
+
|
|
2019
|
+
// If the tab is no longer in loading state, discard this result (newer request started)
|
|
2020
|
+
if (latestTab.loadingState !== 'loading') {
|
|
2021
|
+
return latestState;
|
|
2022
|
+
}
|
|
2023
|
+
|
|
2024
|
+
// Assign editorUid if tab doesn't have one yet
|
|
2025
|
+
const editorUid = latestTab.editorUid === -1 ? create$2() : latestTab.editorUid;
|
|
2026
|
+
return updateTab(latestState, tabId, {
|
|
2027
|
+
editorUid,
|
|
2028
|
+
errorMessage: undefined,
|
|
2029
|
+
loadingState: 'loaded'
|
|
2030
|
+
});
|
|
2031
|
+
} catch (error) {
|
|
2032
|
+
// Check for race condition before updating with error
|
|
2033
|
+
const latestState = getLatestState();
|
|
2034
|
+
const latestTab = findTab(latestState, tabId);
|
|
2035
|
+
if (!latestTab) {
|
|
2036
|
+
return latestState;
|
|
2037
|
+
}
|
|
2038
|
+
|
|
2039
|
+
// If the tab is no longer in loading state, discard this result (newer request started)
|
|
2040
|
+
if (latestTab.loadingState !== 'loading') {
|
|
2041
|
+
return latestState;
|
|
2042
|
+
}
|
|
2043
|
+
const errorMessage = getLoadFileErrorMessage(error);
|
|
2044
|
+
return updateTab(latestState, tabId, {
|
|
2045
|
+
errorMessage,
|
|
2046
|
+
loadingState: 'error'
|
|
2047
|
+
});
|
|
2048
|
+
}
|
|
1870
2049
|
};
|
|
1871
|
-
|
|
1872
|
-
|
|
1873
|
-
|
|
1874
|
-
|
|
1875
|
-
|
|
1876
|
-
|
|
1877
|
-
|
|
1878
|
-
|
|
1879
|
-
if (!focusedGroup) {
|
|
2050
|
+
|
|
2051
|
+
/**
|
|
2052
|
+
* SAFE: Create viewlet for a tab (no visible side effects)
|
|
2053
|
+
* Can be called eagerly when tab is opened - the viewlet loads in the background.
|
|
2054
|
+
*/
|
|
2055
|
+
const createViewletForTab = (state, tabId, viewletModuleId, bounds) => {
|
|
2056
|
+
const tab = findTab(state, tabId);
|
|
2057
|
+
if (!tab) {
|
|
1880
2058
|
return state;
|
|
1881
2059
|
}
|
|
1882
|
-
|
|
1883
|
-
|
|
1884
|
-
|
|
1885
|
-
if (activeTabId === undefined) {
|
|
2060
|
+
|
|
2061
|
+
// If tab already has an editorUid or is loading/loaded, don't recreate
|
|
2062
|
+
if (tab.editorUid !== -1 || tab.loadingState === 'loading' || tab.loadingState === 'loaded') {
|
|
1886
2063
|
return state;
|
|
1887
2064
|
}
|
|
1888
|
-
|
|
2065
|
+
const editorUid = create$2();
|
|
2066
|
+
const newState = updateTab(state, tabId, {
|
|
2067
|
+
editorUid
|
|
2068
|
+
});
|
|
2069
|
+
return newState;
|
|
1889
2070
|
};
|
|
1890
2071
|
|
|
1891
|
-
|
|
1892
|
-
|
|
2072
|
+
/**
|
|
2073
|
+
* Called when switching tabs.
|
|
2074
|
+
* With reference nodes, attachment/detachment is handled automatically by virtual DOM rendering.
|
|
2075
|
+
* No attach/detach commands needed - virtual DOM will render the correct reference at each position.
|
|
2076
|
+
*/
|
|
2077
|
+
const switchViewlet = (state, fromTabId, toTabId) => {
|
|
2078
|
+
// No commands needed - virtual DOM reference nodes handle attachment automatically
|
|
2079
|
+
// Virtual DOM will:
|
|
2080
|
+
// 1. Remove the old reference node from the previous active tab
|
|
2081
|
+
// 2. Add the new reference node for the now-active tab
|
|
2082
|
+
// This achieves the same effect as detach/attach without explicit commands
|
|
2083
|
+
|
|
2084
|
+
return {
|
|
2085
|
+
commands: [],
|
|
2086
|
+
newState: state
|
|
2087
|
+
};
|
|
2088
|
+
};
|
|
2089
|
+
|
|
2090
|
+
const findTabByEditorUid = (state, editorUid) => {
|
|
2091
|
+
const {
|
|
2092
|
+
layout
|
|
2093
|
+
} = state;
|
|
2094
|
+
const {
|
|
2095
|
+
groups
|
|
2096
|
+
} = layout;
|
|
2097
|
+
for (const group of groups) {
|
|
2098
|
+
const tab = group.tabs.find(t => t.editorUid === editorUid);
|
|
2099
|
+
if (tab) {
|
|
2100
|
+
return tab;
|
|
2101
|
+
}
|
|
2102
|
+
}
|
|
2103
|
+
return undefined;
|
|
2104
|
+
};
|
|
2105
|
+
|
|
2106
|
+
/**
|
|
2107
|
+
* Called when renderer reports viewlet finished creating.
|
|
2108
|
+
* With reference nodes, attachment is handled automatically by virtual DOM rendering.
|
|
2109
|
+
* No commands needed - state update is sufficient.
|
|
2110
|
+
*/
|
|
2111
|
+
const handleViewletReady = (state, editorUid, title) => {
|
|
2112
|
+
if (editorUid === -1) {
|
|
2113
|
+
throw new Error('Invalid editorUid -1');
|
|
2114
|
+
}
|
|
2115
|
+
// Find the tab by viewletRequestId
|
|
2116
|
+
const tab = findTabByEditorUid(state, editorUid);
|
|
2117
|
+
if (!tab) {
|
|
2118
|
+
// Tab was closed, dispose viewlet
|
|
2119
|
+
return state;
|
|
2120
|
+
}
|
|
2121
|
+
|
|
2122
|
+
// Mark viewlet as ready and set instance id
|
|
2123
|
+
// Reference nodes will handle rendering at the correct position automatically
|
|
2124
|
+
const newState = updateTab(state, tab.id, {
|
|
2125
|
+
editorUid,
|
|
2126
|
+
loadingState: 'loaded',
|
|
2127
|
+
...(title && {
|
|
2128
|
+
title
|
|
2129
|
+
})
|
|
2130
|
+
});
|
|
2131
|
+
|
|
2132
|
+
// No attach commands needed - virtual DOM reference nodes handle positioning
|
|
2133
|
+
return newState;
|
|
2134
|
+
};
|
|
2135
|
+
|
|
2136
|
+
/**
|
|
2137
|
+
* Dispose viewlet when tab is closed.
|
|
2138
|
+
*/
|
|
2139
|
+
const disposeViewletForTab = (state, tabId) => {
|
|
2140
|
+
const tab = findTab(state, tabId);
|
|
2141
|
+
if (!tab || tab.editorUid === -1) {
|
|
2142
|
+
return {
|
|
2143
|
+
commands: [],
|
|
2144
|
+
newState: state
|
|
2145
|
+
};
|
|
2146
|
+
}
|
|
2147
|
+
const commands = [{
|
|
2148
|
+
instanceId: tab.editorUid,
|
|
2149
|
+
type: 'dispose'
|
|
2150
|
+
}];
|
|
2151
|
+
return {
|
|
2152
|
+
commands,
|
|
2153
|
+
newState: state
|
|
2154
|
+
};
|
|
2155
|
+
};
|
|
2156
|
+
|
|
2157
|
+
const handleCreate = async command => {
|
|
2158
|
+
// Safe to call - no visible side effects
|
|
2159
|
+
|
|
2160
|
+
const title = await createViewlet(command.viewletModuleId, command.editorUid, command.tabId, command.bounds, command.uri || '');
|
|
2161
|
+
|
|
2162
|
+
// After viewlet is created, mark it as ready
|
|
2163
|
+
// Attachment is handled automatically by virtual DOM reference nodes
|
|
2164
|
+
const {
|
|
2165
|
+
newState: state,
|
|
2166
|
+
oldState
|
|
2167
|
+
} = get(command.uid);
|
|
2168
|
+
const readyState = handleViewletReady(state, command.editorUid, title);
|
|
2169
|
+
set(command.uid, oldState, readyState);
|
|
2170
|
+
return readyState;
|
|
2171
|
+
};
|
|
2172
|
+
|
|
2173
|
+
const handleDetach = async command => {
|
|
2174
|
+
// Hides viewlet but keeps it alive
|
|
2175
|
+
|
|
2176
|
+
await invoke('Viewlet.detach', command.instanceId);
|
|
2177
|
+
};
|
|
2178
|
+
|
|
2179
|
+
const handleDispose = async command => {
|
|
2180
|
+
// Fully destroys viewlet
|
|
2181
|
+
|
|
2182
|
+
await invoke('Viewlet.dispose', command.instanceId);
|
|
2183
|
+
};
|
|
2184
|
+
|
|
2185
|
+
const handleSetBounds = async command => {
|
|
2186
|
+
await invoke('Viewlet.setBounds', command.instanceId, command.bounds);
|
|
2187
|
+
};
|
|
2188
|
+
|
|
2189
|
+
const executeViewletCommand = async command => {
|
|
2190
|
+
switch (command.type) {
|
|
2191
|
+
case 'attach':
|
|
2192
|
+
await handleAttach(command);
|
|
2193
|
+
return;
|
|
2194
|
+
case 'create':
|
|
2195
|
+
await handleCreate(command);
|
|
2196
|
+
return;
|
|
2197
|
+
case 'detach':
|
|
2198
|
+
await handleDetach(command);
|
|
2199
|
+
return;
|
|
2200
|
+
case 'dispose':
|
|
2201
|
+
await handleDispose(command);
|
|
2202
|
+
return;
|
|
2203
|
+
case 'setBounds':
|
|
2204
|
+
await handleSetBounds(command);
|
|
2205
|
+
return;
|
|
2206
|
+
}
|
|
2207
|
+
};
|
|
2208
|
+
const executeViewletCommands = async commands => {
|
|
2209
|
+
for (const command of commands) {
|
|
2210
|
+
await executeViewletCommand(command);
|
|
2211
|
+
}
|
|
2212
|
+
};
|
|
2213
|
+
|
|
2214
|
+
const findTabInState = (state, groupId, tabId) => {
|
|
2215
|
+
const {
|
|
2216
|
+
layout
|
|
2217
|
+
} = state;
|
|
2218
|
+
const group = layout.groups.find(g => g.id === groupId);
|
|
2219
|
+
return group?.tabs.find(t => t.id === tabId);
|
|
2220
|
+
};
|
|
2221
|
+
|
|
2222
|
+
const closeTabWithViewlet = async (state, groupId, tabId) => {
|
|
2223
|
+
const tab = findTabInState(state, groupId, tabId);
|
|
2224
|
+
const commands = [];
|
|
2225
|
+
if (tab && tab.editorUid !== -1) {
|
|
2226
|
+
const {
|
|
2227
|
+
commands: disposeCommands
|
|
2228
|
+
} = disposeViewletForTab(state, tabId);
|
|
2229
|
+
commands.push(...disposeCommands);
|
|
2230
|
+
}
|
|
2231
|
+
const newState = closeTab(state, groupId, tabId);
|
|
2232
|
+
const group = state.layout.groups.find(g => g.id === groupId);
|
|
2233
|
+
const wasActiveTab = group?.activeTabId === tabId;
|
|
2234
|
+
if (wasActiveTab) {
|
|
2235
|
+
const newGroup = newState.layout.groups.find(g => g.id === groupId);
|
|
2236
|
+
const newActiveTabId = newGroup?.activeTabId;
|
|
2237
|
+
if (newActiveTabId !== undefined) {
|
|
2238
|
+
const {
|
|
2239
|
+
commands: switchCommands,
|
|
2240
|
+
newState: switchedState
|
|
2241
|
+
} = switchViewlet(newState);
|
|
2242
|
+
commands.push(...switchCommands);
|
|
2243
|
+
await executeViewletCommands(commands);
|
|
2244
|
+
return switchedState;
|
|
2245
|
+
}
|
|
2246
|
+
}
|
|
2247
|
+
if (commands.length > 0) {
|
|
2248
|
+
await executeViewletCommands(commands);
|
|
2249
|
+
}
|
|
2250
|
+
return newState;
|
|
2251
|
+
};
|
|
2252
|
+
|
|
2253
|
+
const saveEditor = async editorUid => {
|
|
2254
|
+
return invoke('Editor.save', editorUid);
|
|
2255
|
+
};
|
|
2256
|
+
|
|
2257
|
+
const closeTabAndSave = async (state, groupId, tabId) => {
|
|
2258
|
+
const tab = findTabInState(state, groupId, tabId);
|
|
2259
|
+
if (!tab) {
|
|
2260
|
+
return state;
|
|
2261
|
+
}
|
|
2262
|
+
if (tab.editorUid !== -1 && tab.isDirty) {
|
|
2263
|
+
const editorState = await saveEditor(tab.editorUid);
|
|
2264
|
+
if (!editorState?.modified && tab.uri) {
|
|
2265
|
+
await handleModifiedStatusChange$1(tab.uri, false);
|
|
2266
|
+
}
|
|
2267
|
+
}
|
|
2268
|
+
if (tab.uri?.startsWith('simple-browser://')) {
|
|
2269
|
+
return closeTabWithViewlet(state, groupId, tabId);
|
|
2270
|
+
}
|
|
2271
|
+
return closeTab(state, groupId, tabId);
|
|
2272
|
+
};
|
|
2273
|
+
|
|
2274
|
+
const getFocusedGroup = state => {
|
|
2275
|
+
const {
|
|
2276
|
+
layout
|
|
2277
|
+
} = state;
|
|
2278
|
+
const {
|
|
2279
|
+
groups
|
|
2280
|
+
} = layout;
|
|
2281
|
+
return groups.find(group => group.focused);
|
|
2282
|
+
};
|
|
2283
|
+
|
|
2284
|
+
const closeActiveEditor = async state => {
|
|
2285
|
+
const focusedGroup = getFocusedGroup(state);
|
|
2286
|
+
if (!focusedGroup) {
|
|
2287
|
+
return state;
|
|
2288
|
+
}
|
|
2289
|
+
const {
|
|
2290
|
+
activeTabId
|
|
2291
|
+
} = focusedGroup;
|
|
2292
|
+
if (activeTabId === undefined) {
|
|
2293
|
+
return state;
|
|
2294
|
+
}
|
|
2295
|
+
return closeTabAndSave(state, focusedGroup.id, activeTabId);
|
|
2296
|
+
};
|
|
2297
|
+
|
|
2298
|
+
const closeAll$1 = state => {
|
|
2299
|
+
const entries = state.layout.groups.flatMap((group, groupIndex) => {
|
|
2300
|
+
return group.tabs.map((tab, tabIndex) => ({
|
|
2301
|
+
group,
|
|
2302
|
+
groupIndex,
|
|
2303
|
+
tab,
|
|
2304
|
+
tabIndex
|
|
2305
|
+
}));
|
|
2306
|
+
});
|
|
2307
|
+
return withEmptyGroups(addClosedTabs(state, entries));
|
|
2308
|
+
};
|
|
2309
|
+
|
|
2310
|
+
const redistributeSizesWithRemainder = groups => {
|
|
2311
|
+
const baseSize = Math.floor(100 / groups.length);
|
|
2312
|
+
const remainder = 100 % groups.length;
|
|
2313
|
+
return groups.map((group, index) => ({
|
|
2314
|
+
...group,
|
|
2315
|
+
size: baseSize + (index === groups.length - 1 ? remainder : 0)
|
|
2316
|
+
}));
|
|
2317
|
+
};
|
|
2318
|
+
|
|
2319
|
+
const closeEditorGroup$1 = (state, groupId) => {
|
|
2320
|
+
if (Number.isNaN(groupId)) {
|
|
2321
|
+
return state;
|
|
2322
|
+
}
|
|
2323
|
+
const {
|
|
2324
|
+
layout
|
|
2325
|
+
} = state;
|
|
2326
|
+
const {
|
|
2327
|
+
activeGroupId,
|
|
2328
|
+
groups
|
|
2329
|
+
} = layout;
|
|
2330
|
+
const groupIndex = getGroupIndexById(state, groupId);
|
|
2331
|
+
if (groupIndex === -1 || groups.length <= 1) {
|
|
2332
|
+
return state;
|
|
2333
|
+
}
|
|
2334
|
+
const remainingGroups = groups.filter(group => group.id !== groupId);
|
|
2335
|
+
const redistributedGroups = redistributeSizesWithRemainder(remainingGroups);
|
|
2336
|
+
const newActiveGroupId = activeGroupId === groupId ? remainingGroups[0].id : activeGroupId;
|
|
2337
|
+
return withGroupsAndActiveGroup(state, redistributedGroups, newActiveGroupId);
|
|
2338
|
+
};
|
|
2339
|
+
|
|
2340
|
+
const isFocused = group => {
|
|
2341
|
+
return group.focused;
|
|
2342
|
+
};
|
|
2343
|
+
const closeFocusedTab = async state => {
|
|
2344
|
+
const {
|
|
2345
|
+
layout
|
|
2346
|
+
} = state;
|
|
2347
|
+
const {
|
|
2348
|
+
groups
|
|
2349
|
+
} = layout;
|
|
2350
|
+
const focusedGroup = groups.find(isFocused);
|
|
2351
|
+
if (!focusedGroup) {
|
|
2352
|
+
return state;
|
|
2353
|
+
}
|
|
2354
|
+
const {
|
|
2355
|
+
activeTabId
|
|
2356
|
+
} = focusedGroup;
|
|
2357
|
+
if (activeTabId === undefined) {
|
|
2358
|
+
return state;
|
|
2359
|
+
}
|
|
2360
|
+
return closeTabAndSave(state, focusedGroup.id, activeTabId);
|
|
2361
|
+
};
|
|
2362
|
+
|
|
2363
|
+
const closeOtherTabs = (state, groupId) => {
|
|
2364
|
+
const {
|
|
1893
2365
|
layout
|
|
1894
2366
|
} = state;
|
|
1895
2367
|
const {
|
|
@@ -2098,359 +2570,90 @@ const copyRelativePath$1 = async (state, path) => {
|
|
|
2098
2570
|
// TODO use clipboard worker
|
|
2099
2571
|
const relativePath = await invoke('Workspace.pathBaseName', path);
|
|
2100
2572
|
await invoke('ClipBoard.writeText', relativePath);
|
|
2101
|
-
return state;
|
|
2102
|
-
};
|
|
2103
|
-
|
|
2104
|
-
const Horizontal = 1;
|
|
2105
|
-
const Vertical = 2;
|
|
2106
|
-
const isLayoutDirection = direction => {
|
|
2107
|
-
return direction === Horizontal || direction === Vertical;
|
|
2108
|
-
};
|
|
2109
|
-
const normalizeLayoutDirection = direction => {
|
|
2110
|
-
if (isLayoutDirection(direction)) {
|
|
2111
|
-
return direction;
|
|
2112
|
-
}
|
|
2113
|
-
if (direction === 'horizontal') {
|
|
2114
|
-
return Horizontal;
|
|
2115
|
-
}
|
|
2116
|
-
if (direction === 'vertical') {
|
|
2117
|
-
return Vertical;
|
|
2118
|
-
}
|
|
2119
|
-
return undefined;
|
|
2120
|
-
};
|
|
2121
|
-
|
|
2122
|
-
const {
|
|
2123
|
-
get,
|
|
2124
|
-
getCommandIds,
|
|
2125
|
-
getKeys: getKeys$1,
|
|
2126
|
-
registerCommands,
|
|
2127
|
-
set,
|
|
2128
|
-
wrapCommand,
|
|
2129
|
-
wrapGetter
|
|
2130
|
-
} = create$f();
|
|
2131
|
-
|
|
2132
|
-
const create$2 = (uid, uri, x, y, width, height, platform, assetDir, tabHeight = 35) => {
|
|
2133
|
-
const state = {
|
|
2134
|
-
assetDir,
|
|
2135
|
-
closedTabs: [],
|
|
2136
|
-
fileIconCache: {},
|
|
2137
|
-
height,
|
|
2138
|
-
homeDirUri: '',
|
|
2139
|
-
iframes: [],
|
|
2140
|
-
initial: true,
|
|
2141
|
-
layout: {
|
|
2142
|
-
activeGroupId: undefined,
|
|
2143
|
-
direction: Horizontal,
|
|
2144
|
-
groups: []
|
|
2145
|
-
},
|
|
2146
|
-
maxOpenEditorGroups: Infinity,
|
|
2147
|
-
maxOpenEditors: Infinity,
|
|
2148
|
-
minGroupHeightPx: 80,
|
|
2149
|
-
minGroupWidthPx: 250,
|
|
2150
|
-
platform,
|
|
2151
|
-
splitButtonEnabled: false,
|
|
2152
|
-
tabHeight,
|
|
2153
|
-
uid,
|
|
2154
|
-
width,
|
|
2155
|
-
workspaceuri: uri,
|
|
2156
|
-
x,
|
|
2157
|
-
y
|
|
2158
|
-
};
|
|
2159
|
-
set(uid, state, state);
|
|
2160
|
-
};
|
|
2161
|
-
|
|
2162
|
-
const isEqual$1 = (oldState, newState) => {
|
|
2163
|
-
return false;
|
|
2164
|
-
};
|
|
2165
|
-
|
|
2166
|
-
const isEqual = (oldState, newState) => {
|
|
2167
|
-
return oldState.layout === newState.layout;
|
|
2168
|
-
};
|
|
2169
|
-
|
|
2170
|
-
const RenderItems = 4;
|
|
2171
|
-
const RenderCss = 10;
|
|
2172
|
-
const RenderIncremental = 11;
|
|
2173
|
-
|
|
2174
|
-
const modules = [isEqual, isEqual$1];
|
|
2175
|
-
const numbers = [RenderIncremental, RenderCss];
|
|
2176
|
-
|
|
2177
|
-
const diff = (oldState, newState) => {
|
|
2178
|
-
const diffResult = [];
|
|
2179
|
-
for (let i = 0; i < modules.length; i++) {
|
|
2180
|
-
const fn = modules[i];
|
|
2181
|
-
if (!fn(oldState, newState)) {
|
|
2182
|
-
diffResult.push(numbers[i]);
|
|
2183
|
-
}
|
|
2184
|
-
}
|
|
2185
|
-
return diffResult;
|
|
2186
|
-
};
|
|
2187
|
-
|
|
2188
|
-
const diff2 = uid => {
|
|
2189
|
-
const {
|
|
2190
|
-
newState,
|
|
2191
|
-
oldState
|
|
2192
|
-
} = get(uid);
|
|
2193
|
-
const result = diff(oldState, newState);
|
|
2194
|
-
return result;
|
|
2195
|
-
};
|
|
2196
|
-
|
|
2197
|
-
const handleAttach = async command => {
|
|
2198
|
-
// TODO find a better way to append editors
|
|
2199
|
-
const parentNodeSelector = '.editor-groups-container, .EditorGroup';
|
|
2200
|
-
await invoke('Layout.attachViewlet', parentNodeSelector, command.instanceId);
|
|
2201
|
-
};
|
|
2202
|
-
|
|
2203
|
-
const create$1 = () => {
|
|
2204
|
-
return Math.random();
|
|
2205
|
-
};
|
|
2206
|
-
|
|
2207
|
-
const updateTab = (state, tabId, updates) => {
|
|
2208
|
-
const {
|
|
2209
|
-
layout
|
|
2210
|
-
} = state;
|
|
2211
|
-
const {
|
|
2212
|
-
groups
|
|
2213
|
-
} = layout;
|
|
2214
|
-
const updatedGroups = groups.map(group => {
|
|
2215
|
-
const tabIndex = group.tabs.findIndex(t => t.id === tabId);
|
|
2216
|
-
if (tabIndex === -1) {
|
|
2217
|
-
return group;
|
|
2218
|
-
}
|
|
2219
|
-
const updatedTabs = group.tabs.map((tab, index) => {
|
|
2220
|
-
if (index === tabIndex) {
|
|
2221
|
-
return {
|
|
2222
|
-
...tab,
|
|
2223
|
-
...updates
|
|
2224
|
-
};
|
|
2225
|
-
}
|
|
2226
|
-
return tab;
|
|
2227
|
-
});
|
|
2228
|
-
return {
|
|
2229
|
-
...group,
|
|
2230
|
-
tabs: updatedTabs
|
|
2231
|
-
};
|
|
2232
|
-
});
|
|
2233
|
-
return {
|
|
2234
|
-
...state,
|
|
2235
|
-
layout: {
|
|
2236
|
-
...layout,
|
|
2237
|
-
groups: updatedGroups
|
|
2238
|
-
}
|
|
2239
|
-
};
|
|
2240
|
-
};
|
|
2241
|
-
|
|
2242
|
-
const findTab = (state, tabId) => {
|
|
2243
|
-
const {
|
|
2244
|
-
layout
|
|
2245
|
-
} = state;
|
|
2246
|
-
const {
|
|
2247
|
-
groups
|
|
2248
|
-
} = layout;
|
|
2249
|
-
for (const group of groups) {
|
|
2250
|
-
const tab = group.tabs.find(t => t.id === tabId);
|
|
2251
|
-
if (tab) {
|
|
2252
|
-
return tab;
|
|
2253
|
-
}
|
|
2254
|
-
}
|
|
2255
|
-
return undefined;
|
|
2256
|
-
};
|
|
2257
|
-
const loadFileContent = async path => {
|
|
2258
|
-
const content = await readFile(path);
|
|
2259
|
-
return content;
|
|
2260
|
-
};
|
|
2261
|
-
const getLoadFileErrorMessage = error => {
|
|
2262
|
-
if (!(error instanceof Error)) {
|
|
2263
|
-
return 'Failed to load file content';
|
|
2264
|
-
}
|
|
2265
|
-
if (error.message.includes('EISDIR') || error.message.includes('illegal operation on a directory') || error.message.includes('is a directory')) {
|
|
2266
|
-
return 'Expected a file but received a folder';
|
|
2267
|
-
}
|
|
2268
|
-
return error.message;
|
|
2269
|
-
};
|
|
2270
|
-
const loadTabContentAsync = async (tabId, path, requestId, getLatestState) => {
|
|
2271
|
-
try {
|
|
2272
|
-
await loadFileContent(path);
|
|
2273
|
-
|
|
2274
|
-
// Check for race condition: get the latest state
|
|
2275
|
-
const latestState = getLatestState();
|
|
2276
|
-
const latestTab = findTab(latestState, tabId);
|
|
2277
|
-
|
|
2278
|
-
// If the tab no longer exists, discard this result
|
|
2279
|
-
if (!latestTab) {
|
|
2280
|
-
return latestState;
|
|
2281
|
-
}
|
|
2282
|
-
|
|
2283
|
-
// If the tab is no longer in loading state, discard this result (newer request started)
|
|
2284
|
-
if (latestTab.loadingState !== 'loading') {
|
|
2285
|
-
return latestState;
|
|
2286
|
-
}
|
|
2287
|
-
|
|
2288
|
-
// Assign editorUid if tab doesn't have one yet
|
|
2289
|
-
const editorUid = latestTab.editorUid === -1 ? create$1() : latestTab.editorUid;
|
|
2290
|
-
return updateTab(latestState, tabId, {
|
|
2291
|
-
editorUid,
|
|
2292
|
-
errorMessage: undefined,
|
|
2293
|
-
loadingState: 'loaded'
|
|
2294
|
-
});
|
|
2295
|
-
} catch (error) {
|
|
2296
|
-
// Check for race condition before updating with error
|
|
2297
|
-
const latestState = getLatestState();
|
|
2298
|
-
const latestTab = findTab(latestState, tabId);
|
|
2299
|
-
if (!latestTab) {
|
|
2300
|
-
return latestState;
|
|
2301
|
-
}
|
|
2302
|
-
|
|
2303
|
-
// If the tab is no longer in loading state, discard this result (newer request started)
|
|
2304
|
-
if (latestTab.loadingState !== 'loading') {
|
|
2305
|
-
return latestState;
|
|
2306
|
-
}
|
|
2307
|
-
const errorMessage = getLoadFileErrorMessage(error);
|
|
2308
|
-
return updateTab(latestState, tabId, {
|
|
2309
|
-
errorMessage,
|
|
2310
|
-
loadingState: 'error'
|
|
2311
|
-
});
|
|
2312
|
-
}
|
|
2313
|
-
};
|
|
2314
|
-
|
|
2315
|
-
/**
|
|
2316
|
-
* SAFE: Create viewlet for a tab (no visible side effects)
|
|
2317
|
-
* Can be called eagerly when tab is opened - the viewlet loads in the background.
|
|
2318
|
-
*/
|
|
2319
|
-
const createViewletForTab = (state, tabId, viewletModuleId, bounds) => {
|
|
2320
|
-
const tab = findTab(state, tabId);
|
|
2321
|
-
if (!tab) {
|
|
2322
|
-
return state;
|
|
2323
|
-
}
|
|
2324
|
-
|
|
2325
|
-
// If tab already has an editorUid or is loading/loaded, don't recreate
|
|
2326
|
-
if (tab.editorUid !== -1 || tab.loadingState === 'loading' || tab.loadingState === 'loaded') {
|
|
2327
|
-
return state;
|
|
2328
|
-
}
|
|
2329
|
-
const editorUid = create$1();
|
|
2330
|
-
const newState = updateTab(state, tabId, {
|
|
2331
|
-
editorUid
|
|
2332
|
-
});
|
|
2333
|
-
return newState;
|
|
2334
|
-
};
|
|
2335
|
-
|
|
2336
|
-
/**
|
|
2337
|
-
* Called when switching tabs.
|
|
2338
|
-
* With reference nodes, attachment/detachment is handled automatically by virtual DOM rendering.
|
|
2339
|
-
* No attach/detach commands needed - virtual DOM will render the correct reference at each position.
|
|
2340
|
-
*/
|
|
2341
|
-
const switchViewlet = (state, fromTabId, toTabId) => {
|
|
2342
|
-
// No commands needed - virtual DOM reference nodes handle attachment automatically
|
|
2343
|
-
// Virtual DOM will:
|
|
2344
|
-
// 1. Remove the old reference node from the previous active tab
|
|
2345
|
-
// 2. Add the new reference node for the now-active tab
|
|
2346
|
-
// This achieves the same effect as detach/attach without explicit commands
|
|
2347
|
-
|
|
2348
|
-
return {
|
|
2349
|
-
commands: [],
|
|
2350
|
-
newState: state
|
|
2351
|
-
};
|
|
2352
|
-
};
|
|
2353
|
-
|
|
2354
|
-
const findTabByEditorUid = (state, editorUid) => {
|
|
2355
|
-
const {
|
|
2356
|
-
layout
|
|
2357
|
-
} = state;
|
|
2358
|
-
const {
|
|
2359
|
-
groups
|
|
2360
|
-
} = layout;
|
|
2361
|
-
for (const group of groups) {
|
|
2362
|
-
const tab = group.tabs.find(t => t.editorUid === editorUid);
|
|
2363
|
-
if (tab) {
|
|
2364
|
-
return tab;
|
|
2365
|
-
}
|
|
2366
|
-
}
|
|
2367
|
-
return undefined;
|
|
2573
|
+
return state;
|
|
2368
2574
|
};
|
|
2369
2575
|
|
|
2370
|
-
|
|
2371
|
-
|
|
2372
|
-
|
|
2373
|
-
|
|
2374
|
-
|
|
2375
|
-
const
|
|
2376
|
-
if (
|
|
2377
|
-
|
|
2576
|
+
const Horizontal = 1;
|
|
2577
|
+
const Vertical = 2;
|
|
2578
|
+
const isLayoutDirection = direction => {
|
|
2579
|
+
return direction === Horizontal || direction === Vertical;
|
|
2580
|
+
};
|
|
2581
|
+
const normalizeLayoutDirection = direction => {
|
|
2582
|
+
if (isLayoutDirection(direction)) {
|
|
2583
|
+
return direction;
|
|
2378
2584
|
}
|
|
2379
|
-
|
|
2380
|
-
|
|
2381
|
-
if (!tab) {
|
|
2382
|
-
// Tab was closed, dispose viewlet
|
|
2383
|
-
return state;
|
|
2585
|
+
if (direction === 'horizontal') {
|
|
2586
|
+
return Horizontal;
|
|
2384
2587
|
}
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
2389
|
-
editorUid,
|
|
2390
|
-
loadingState: 'loaded'
|
|
2391
|
-
});
|
|
2392
|
-
|
|
2393
|
-
// No attach commands needed - virtual DOM reference nodes handle positioning
|
|
2394
|
-
return newState;
|
|
2588
|
+
if (direction === 'vertical') {
|
|
2589
|
+
return Vertical;
|
|
2590
|
+
}
|
|
2591
|
+
return undefined;
|
|
2395
2592
|
};
|
|
2396
2593
|
|
|
2397
|
-
const
|
|
2398
|
-
|
|
2399
|
-
|
|
2400
|
-
|
|
2401
|
-
|
|
2402
|
-
|
|
2403
|
-
|
|
2404
|
-
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2412
|
-
|
|
2594
|
+
const create$1 = (uid, uri, x, y, width, height, platform, assetDir, tabHeight = 35) => {
|
|
2595
|
+
const state = {
|
|
2596
|
+
assetDir,
|
|
2597
|
+
closedTabs: [],
|
|
2598
|
+
fileIconCache: {},
|
|
2599
|
+
height,
|
|
2600
|
+
homeDirUri: '',
|
|
2601
|
+
iframes: [],
|
|
2602
|
+
initial: true,
|
|
2603
|
+
layout: {
|
|
2604
|
+
activeGroupId: undefined,
|
|
2605
|
+
direction: Horizontal,
|
|
2606
|
+
groups: []
|
|
2607
|
+
},
|
|
2608
|
+
maxOpenEditorGroups: Infinity,
|
|
2609
|
+
maxOpenEditors: Infinity,
|
|
2610
|
+
minGroupHeightPx: 80,
|
|
2611
|
+
minGroupWidthPx: 250,
|
|
2612
|
+
platform,
|
|
2613
|
+
splitButtonEnabled: false,
|
|
2614
|
+
tabHeight,
|
|
2615
|
+
uid,
|
|
2616
|
+
width,
|
|
2617
|
+
workspaceuri: uri,
|
|
2618
|
+
x,
|
|
2619
|
+
y
|
|
2620
|
+
};
|
|
2621
|
+
set(uid, state, state);
|
|
2413
2622
|
};
|
|
2414
2623
|
|
|
2415
|
-
const
|
|
2416
|
-
|
|
2417
|
-
|
|
2418
|
-
await invoke('Viewlet.detach', command.instanceId);
|
|
2624
|
+
const isEqual$1 = (oldState, newState) => {
|
|
2625
|
+
return false;
|
|
2419
2626
|
};
|
|
2420
2627
|
|
|
2421
|
-
const
|
|
2422
|
-
|
|
2423
|
-
|
|
2424
|
-
await invoke('Viewlet.dispose', command.instanceId);
|
|
2628
|
+
const isEqual = (oldState, newState) => {
|
|
2629
|
+
return oldState.layout === newState.layout;
|
|
2425
2630
|
};
|
|
2426
2631
|
|
|
2427
|
-
const
|
|
2428
|
-
|
|
2429
|
-
|
|
2632
|
+
const RenderItems = 4;
|
|
2633
|
+
const RenderCss = 10;
|
|
2634
|
+
const RenderIncremental = 11;
|
|
2430
2635
|
|
|
2431
|
-
const
|
|
2432
|
-
|
|
2433
|
-
|
|
2434
|
-
|
|
2435
|
-
|
|
2436
|
-
|
|
2437
|
-
|
|
2438
|
-
|
|
2439
|
-
|
|
2440
|
-
|
|
2441
|
-
return;
|
|
2442
|
-
case 'dispose':
|
|
2443
|
-
await handleDispose(command);
|
|
2444
|
-
return;
|
|
2445
|
-
case 'setBounds':
|
|
2446
|
-
await handleSetBounds(command);
|
|
2447
|
-
return;
|
|
2636
|
+
const modules = [isEqual, isEqual$1];
|
|
2637
|
+
const numbers = [RenderIncremental, RenderCss];
|
|
2638
|
+
|
|
2639
|
+
const diff = (oldState, newState) => {
|
|
2640
|
+
const diffResult = [];
|
|
2641
|
+
for (let i = 0; i < modules.length; i++) {
|
|
2642
|
+
const fn = modules[i];
|
|
2643
|
+
if (!fn(oldState, newState)) {
|
|
2644
|
+
diffResult.push(numbers[i]);
|
|
2645
|
+
}
|
|
2448
2646
|
}
|
|
2647
|
+
return diffResult;
|
|
2449
2648
|
};
|
|
2450
|
-
|
|
2451
|
-
|
|
2452
|
-
|
|
2453
|
-
|
|
2649
|
+
|
|
2650
|
+
const diff2 = uid => {
|
|
2651
|
+
const {
|
|
2652
|
+
newState,
|
|
2653
|
+
oldState
|
|
2654
|
+
} = get(uid);
|
|
2655
|
+
const result = diff(oldState, newState);
|
|
2656
|
+
return result;
|
|
2454
2657
|
};
|
|
2455
2658
|
|
|
2456
2659
|
const requestIdState = {
|
|
@@ -2685,10 +2888,6 @@ const getUpdatedGroups = (groups, groupIndex, needsLoading, tabId) => {
|
|
|
2685
2888
|
});
|
|
2686
2889
|
};
|
|
2687
2890
|
|
|
2688
|
-
const createViewlet = async (viewletModuleId, editorUid, tabId, bounds, uri) => {
|
|
2689
|
-
await invoke('Layout.createViewlet', viewletModuleId, editorUid, tabId, bounds, uri);
|
|
2690
|
-
};
|
|
2691
|
-
|
|
2692
2891
|
const findTabById = (state, tabId) => {
|
|
2693
2892
|
const {
|
|
2694
2893
|
layout
|
|
@@ -2803,8 +3002,8 @@ const maybeCreateViewletForSelectedTab = async (state, newState, groupIndex, ind
|
|
|
2803
3002
|
editorUid
|
|
2804
3003
|
} = tabWithViewlet.tab;
|
|
2805
3004
|
if (editorUid !== -1 && selectedTab.uri) {
|
|
2806
|
-
await createViewlet(viewletModuleId, editorUid, tabId, bounds, selectedTab.uri);
|
|
2807
|
-
stateWithViewlet = handleViewletReady(stateWithViewlet, editorUid);
|
|
3005
|
+
const title = await createViewlet(viewletModuleId, editorUid, tabId, bounds, selectedTab.uri);
|
|
3006
|
+
stateWithViewlet = handleViewletReady(stateWithViewlet, editorUid, title);
|
|
2808
3007
|
set(uid, state, stateWithViewlet);
|
|
2809
3008
|
}
|
|
2810
3009
|
}
|
|
@@ -3348,9 +3547,9 @@ const createEmptyGroup$1 = (state, uri, requestId, preview = false, title = getL
|
|
|
3348
3547
|
const {
|
|
3349
3548
|
groups
|
|
3350
3549
|
} = layout;
|
|
3351
|
-
const groupId = create$
|
|
3352
|
-
const tabId = create$
|
|
3353
|
-
const editorUid = create$
|
|
3550
|
+
const groupId = create$2();
|
|
3551
|
+
const tabId = create$2();
|
|
3552
|
+
const editorUid = create$2();
|
|
3354
3553
|
const newTab = {
|
|
3355
3554
|
editorInput,
|
|
3356
3555
|
editorType,
|
|
@@ -3391,7 +3590,7 @@ const openTab = (state, groupId, tab) => {
|
|
|
3391
3590
|
};
|
|
3392
3591
|
const newTab = 'id' in normalizedTab && normalizedTab.id !== undefined ? normalizedTab : {
|
|
3393
3592
|
...normalizedTab,
|
|
3394
|
-
id: create$
|
|
3593
|
+
id: create$2()
|
|
3395
3594
|
};
|
|
3396
3595
|
const {
|
|
3397
3596
|
layout
|
|
@@ -3478,8 +3677,8 @@ const ensureActiveGroup = (state, uri, preview = false, title = getLabel(uri), e
|
|
|
3478
3677
|
}
|
|
3479
3678
|
|
|
3480
3679
|
// Create a new tab with the URI in the active group
|
|
3481
|
-
const tabId = create$
|
|
3482
|
-
const editorUid = create$
|
|
3680
|
+
const tabId = create$2();
|
|
3681
|
+
const editorUid = create$2();
|
|
3483
3682
|
const newTab = {
|
|
3484
3683
|
editorInput,
|
|
3485
3684
|
editorType,
|
|
@@ -3669,7 +3868,7 @@ const getFileIconsForTabs = async (tabs, fileIconCache) => {
|
|
|
3669
3868
|
};
|
|
3670
3869
|
};
|
|
3671
3870
|
|
|
3672
|
-
const updateTabIcon = async (
|
|
3871
|
+
const updateTabIcon = async (context, readyState, tabId) => {
|
|
3673
3872
|
const newTab = findTabById(readyState, tabId);
|
|
3674
3873
|
if (!newTab || !newTab.tab.uri) {
|
|
3675
3874
|
return undefined;
|
|
@@ -3678,9 +3877,7 @@ const updateTabIcon = async (uid, state, readyState, tabId) => {
|
|
|
3678
3877
|
const {
|
|
3679
3878
|
newFileIconCache
|
|
3680
3879
|
} = await getFileIconsForTabs([newTab.tab], readyState.fileIconCache);
|
|
3681
|
-
const
|
|
3682
|
-
newState: stateBeforeIconUpdate
|
|
3683
|
-
} = get(uid);
|
|
3880
|
+
const stateBeforeIconUpdate = context.getState();
|
|
3684
3881
|
const icon = newFileIconCache[newTab.tab.uri] || '';
|
|
3685
3882
|
const stateWithIcon = {
|
|
3686
3883
|
...stateBeforeIconUpdate,
|
|
@@ -3696,19 +3893,16 @@ const updateTabIcon = async (uid, state, readyState, tabId) => {
|
|
|
3696
3893
|
}))
|
|
3697
3894
|
}
|
|
3698
3895
|
};
|
|
3699
|
-
|
|
3700
|
-
return stateWithIcon;
|
|
3896
|
+
return context.updateState(() => stateWithIcon);
|
|
3701
3897
|
} catch {
|
|
3702
3898
|
return undefined;
|
|
3703
3899
|
}
|
|
3704
3900
|
};
|
|
3705
3901
|
|
|
3706
|
-
const
|
|
3902
|
+
const openInputWithContext = async (context, options) => {
|
|
3903
|
+
const state = context.getState();
|
|
3707
3904
|
object(state);
|
|
3708
3905
|
object(options);
|
|
3709
|
-
const {
|
|
3710
|
-
uid
|
|
3711
|
-
} = state;
|
|
3712
3906
|
const {
|
|
3713
3907
|
editorInput
|
|
3714
3908
|
} = options;
|
|
@@ -3716,40 +3910,40 @@ const openInput = async (state, options) => {
|
|
|
3716
3910
|
const uri = getEditorInputUri(editorInput);
|
|
3717
3911
|
const title = getEditorInputTitle(editorInput);
|
|
3718
3912
|
const editorType = getEditorInputEditorType(editorInput);
|
|
3719
|
-
const currentState =
|
|
3913
|
+
const currentState = state;
|
|
3720
3914
|
const existingTab = findTabByUri(currentState, uri);
|
|
3721
3915
|
const shouldRetryExistingTab = !!existingTab && existingTab.tab.loadingState === 'error';
|
|
3722
3916
|
if (existingTab && !shouldRetryExistingTab) {
|
|
3723
3917
|
const focusedState = focusEditorGroup(currentState, existingTab.groupId);
|
|
3724
|
-
|
|
3918
|
+
const switchedState = switchTab(focusedState, existingTab.groupId, existingTab.tab.id);
|
|
3919
|
+
await context.updateState(() => switchedState);
|
|
3920
|
+
return;
|
|
3725
3921
|
}
|
|
3726
3922
|
const previousTabId = getActiveTabId(currentState);
|
|
3727
3923
|
const {
|
|
3728
3924
|
stateWithTab,
|
|
3729
3925
|
tabId
|
|
3730
3926
|
} = getStateWithTab(currentState, editorInput, existingTab, shouldRetryExistingTab, uri, preview, title, editorType);
|
|
3731
|
-
|
|
3927
|
+
await context.updateState(() => stateWithTab);
|
|
3732
3928
|
if (await isDirectoryEditorInput(editorInput)) {
|
|
3733
|
-
const
|
|
3734
|
-
newState: latestState
|
|
3735
|
-
} = get(uid);
|
|
3929
|
+
const latestState = context.getState();
|
|
3736
3930
|
const errorState = updateTab(latestState, tabId, {
|
|
3737
3931
|
errorMessage: 'Expected a file but received a folder',
|
|
3738
3932
|
loadingState: 'error'
|
|
3739
3933
|
});
|
|
3740
|
-
|
|
3741
|
-
return
|
|
3934
|
+
await context.updateState(() => errorState);
|
|
3935
|
+
return;
|
|
3742
3936
|
}
|
|
3743
3937
|
try {
|
|
3744
3938
|
const viewletModuleId = await getViewletModuleIdForEditorInput(editorInput);
|
|
3745
|
-
const
|
|
3746
|
-
newState: stateAfterModuleId
|
|
3747
|
-
} = get(uid);
|
|
3939
|
+
const stateAfterModuleId = context.getState();
|
|
3748
3940
|
if (!viewletModuleId) {
|
|
3749
|
-
|
|
3941
|
+
const unsupportedState = updateTab(stateAfterModuleId, tabId, {
|
|
3750
3942
|
errorMessage: 'Could not determine editor type for this URI',
|
|
3751
3943
|
loadingState: 'error'
|
|
3752
3944
|
});
|
|
3945
|
+
await context.updateState(() => unsupportedState);
|
|
3946
|
+
return;
|
|
3753
3947
|
}
|
|
3754
3948
|
const bounds = {
|
|
3755
3949
|
height: stateAfterModuleId.height - stateAfterModuleId.tabHeight,
|
|
@@ -3763,10 +3957,10 @@ const openInput = async (state, options) => {
|
|
|
3763
3957
|
newState: switchedState
|
|
3764
3958
|
} = switchViewlet(intermediateState, previousTabId, tabId);
|
|
3765
3959
|
intermediateState = switchedState;
|
|
3766
|
-
|
|
3960
|
+
await context.updateState(() => intermediateState);
|
|
3767
3961
|
const tabWithViewlet = findTabById(intermediateState, tabId);
|
|
3768
3962
|
if (!tabWithViewlet) {
|
|
3769
|
-
return
|
|
3963
|
+
return;
|
|
3770
3964
|
}
|
|
3771
3965
|
const {
|
|
3772
3966
|
editorUid
|
|
@@ -3774,33 +3968,42 @@ const openInput = async (state, options) => {
|
|
|
3774
3968
|
if (editorUid === -1) {
|
|
3775
3969
|
throw new Error('invalid editorUid');
|
|
3776
3970
|
}
|
|
3777
|
-
await createViewlet(viewletModuleId, editorUid, tabId, bounds, uri);
|
|
3778
|
-
const
|
|
3779
|
-
|
|
3780
|
-
|
|
3781
|
-
const
|
|
3782
|
-
set(uid, state, readyState);
|
|
3783
|
-
const stateWithIcon = await updateTabIcon(uid, state, readyState, tabId);
|
|
3971
|
+
const renderedTitle = await createViewlet(viewletModuleId, editorUid, tabId, bounds, uri);
|
|
3972
|
+
const latestState = context.getState();
|
|
3973
|
+
const readyState = handleViewletReady(latestState, editorUid, renderedTitle);
|
|
3974
|
+
await context.updateState(() => readyState);
|
|
3975
|
+
const stateWithIcon = await updateTabIcon(context, readyState, tabId);
|
|
3784
3976
|
if (stateWithIcon) {
|
|
3785
|
-
return
|
|
3977
|
+
return;
|
|
3786
3978
|
}
|
|
3787
|
-
const {
|
|
3788
|
-
newState: finalState
|
|
3789
|
-
} = get(uid);
|
|
3790
|
-
return finalState;
|
|
3791
3979
|
} catch (error) {
|
|
3792
|
-
const
|
|
3793
|
-
newState: latestState
|
|
3794
|
-
} = get(uid);
|
|
3980
|
+
const latestState = context.getState();
|
|
3795
3981
|
const errorMessage = error instanceof Error ? error.message : 'Failed to open URI';
|
|
3796
3982
|
const errorState = updateTab(latestState, tabId, {
|
|
3797
3983
|
errorMessage,
|
|
3798
3984
|
loadingState: 'error'
|
|
3799
3985
|
});
|
|
3800
|
-
|
|
3801
|
-
return errorState;
|
|
3986
|
+
await context.updateState(() => errorState);
|
|
3802
3987
|
}
|
|
3803
3988
|
};
|
|
3989
|
+
const openInput = async (state, options) => {
|
|
3990
|
+
const {
|
|
3991
|
+
uid
|
|
3992
|
+
} = state;
|
|
3993
|
+
let currentState = getCurrentState(state);
|
|
3994
|
+
const context = {
|
|
3995
|
+
getState: () => get(uid)?.newState ?? currentState,
|
|
3996
|
+
updateState: updater => {
|
|
3997
|
+
const storedState = get(uid);
|
|
3998
|
+
const latestState = storedState?.newState ?? currentState;
|
|
3999
|
+
currentState = updater(latestState);
|
|
4000
|
+
set(uid, storedState?.oldState ?? state, currentState);
|
|
4001
|
+
return Promise.resolve(currentState);
|
|
4002
|
+
}
|
|
4003
|
+
};
|
|
4004
|
+
await openInputWithContext(context, options);
|
|
4005
|
+
return context.getState();
|
|
4006
|
+
};
|
|
3804
4007
|
|
|
3805
4008
|
const getOptionUriOptions = options => {
|
|
3806
4009
|
if (typeof options === 'string') {
|
|
@@ -3809,14 +4012,20 @@ const getOptionUriOptions = options => {
|
|
|
3809
4012
|
return options.uri;
|
|
3810
4013
|
};
|
|
3811
4014
|
|
|
3812
|
-
const
|
|
4015
|
+
const getOpenInputOptions = options => {
|
|
3813
4016
|
const uri = getOptionUriOptions(options);
|
|
3814
4017
|
const preview = typeof options === 'string' ? false : options.preview ?? false;
|
|
3815
|
-
return
|
|
4018
|
+
return {
|
|
3816
4019
|
editorInput: getNormalizedOpenEditorInput(uri),
|
|
3817
4020
|
focus: typeof options === 'string' ? false : options.focus,
|
|
3818
4021
|
preview
|
|
3819
|
-
}
|
|
4022
|
+
};
|
|
4023
|
+
};
|
|
4024
|
+
const openUri = async (state, options) => {
|
|
4025
|
+
return openInput(state, getOpenInputOptions(options));
|
|
4026
|
+
};
|
|
4027
|
+
const openUriWithContext = async (context, options) => {
|
|
4028
|
+
await openInputWithContext(context, getOpenInputOptions(options));
|
|
3820
4029
|
};
|
|
3821
4030
|
|
|
3822
4031
|
const retryOpen = async state => {
|
|
@@ -4002,7 +4211,7 @@ const splitEditorGroup$1 = (state, groupId, direction) => {
|
|
|
4002
4211
|
if (!sourceGroup) {
|
|
4003
4212
|
return state;
|
|
4004
4213
|
}
|
|
4005
|
-
const newGroupId = create$
|
|
4214
|
+
const newGroupId = create$2();
|
|
4006
4215
|
const splitLayoutDirection = getSplitLayoutDirection(direction);
|
|
4007
4216
|
const baseNewGroup = {
|
|
4008
4217
|
activeTabId: undefined,
|
|
@@ -4219,8 +4428,8 @@ const newFile = async state => {
|
|
|
4219
4428
|
getActiveTabId(newState);
|
|
4220
4429
|
|
|
4221
4430
|
// Create a new empty tab
|
|
4222
|
-
const tabId = create$
|
|
4223
|
-
const editorUid = create$
|
|
4431
|
+
const tabId = create$2();
|
|
4432
|
+
const editorUid = create$2();
|
|
4224
4433
|
const newTab = {
|
|
4225
4434
|
editorType: 'text',
|
|
4226
4435
|
editorUid,
|
|
@@ -4265,13 +4474,13 @@ const newFile = async state => {
|
|
|
4265
4474
|
if (actualEditorUid === -1) {
|
|
4266
4475
|
throw new Error(`invalid editorUid`);
|
|
4267
4476
|
}
|
|
4268
|
-
await createViewlet(viewletModuleId, actualEditorUid, tabId, bounds, newTab.uri || '');
|
|
4477
|
+
const title = await createViewlet(viewletModuleId, actualEditorUid, tabId, bounds, newTab.uri || '');
|
|
4269
4478
|
|
|
4270
4479
|
// After viewlet is created, get the latest state and mark it as ready
|
|
4271
4480
|
const {
|
|
4272
4481
|
newState: latestState
|
|
4273
4482
|
} = get(uid);
|
|
4274
|
-
const readyState = handleViewletReady(latestState, actualEditorUid);
|
|
4483
|
+
const readyState = handleViewletReady(latestState, actualEditorUid, title);
|
|
4275
4484
|
return readyState;
|
|
4276
4485
|
};
|
|
4277
4486
|
|
|
@@ -4366,6 +4575,9 @@ const handleModifiedStatusChange = (state, uri, newStatus) => {
|
|
|
4366
4575
|
}
|
|
4367
4576
|
};
|
|
4368
4577
|
};
|
|
4578
|
+
const handleModifiedStatusChangeWithContext = async (context, uri, newStatus) => {
|
|
4579
|
+
await context.updateState(state => handleModifiedStatusChange(state, uri, newStatus));
|
|
4580
|
+
};
|
|
4369
4581
|
|
|
4370
4582
|
const handleResize = async (state, dimensions) => {
|
|
4371
4583
|
const {
|
|
@@ -4598,47 +4810,6 @@ const handleUriChange = async (state, oldUri, newUri) => {
|
|
|
4598
4810
|
};
|
|
4599
4811
|
};
|
|
4600
4812
|
|
|
4601
|
-
const handleWorkspaceChange = state => {
|
|
4602
|
-
const {
|
|
4603
|
-
layout
|
|
4604
|
-
} = state;
|
|
4605
|
-
return {
|
|
4606
|
-
...state,
|
|
4607
|
-
layout: {
|
|
4608
|
-
...layout,
|
|
4609
|
-
activeGroupId: undefined,
|
|
4610
|
-
groups: []
|
|
4611
|
-
}
|
|
4612
|
-
};
|
|
4613
|
-
};
|
|
4614
|
-
|
|
4615
|
-
const hasActiveTextEditor = state => {
|
|
4616
|
-
const activeTab = getActiveTab(state);
|
|
4617
|
-
return activeTab?.tab.editorInput?.type === 'editor';
|
|
4618
|
-
};
|
|
4619
|
-
|
|
4620
|
-
const id = 7201;
|
|
4621
|
-
const sendMessagePortToExtensionHostWorker = async port => {
|
|
4622
|
-
await sendMessagePortToExtensionHostWorker$1(port, id);
|
|
4623
|
-
};
|
|
4624
|
-
|
|
4625
|
-
const createExtensionHostRpc = async () => {
|
|
4626
|
-
try {
|
|
4627
|
-
const rpc = await create$8({
|
|
4628
|
-
commandMap: {},
|
|
4629
|
-
send: sendMessagePortToExtensionHostWorker
|
|
4630
|
-
});
|
|
4631
|
-
return rpc;
|
|
4632
|
-
} catch (error) {
|
|
4633
|
-
throw new VError(error, `Failed to create extension host rpc`);
|
|
4634
|
-
}
|
|
4635
|
-
};
|
|
4636
|
-
|
|
4637
|
-
const initialize = async () => {
|
|
4638
|
-
const rpc = await createExtensionHostRpc();
|
|
4639
|
-
set$3(rpc);
|
|
4640
|
-
};
|
|
4641
|
-
|
|
4642
4813
|
const toFileUri = path => {
|
|
4643
4814
|
if (!path) {
|
|
4644
4815
|
return '';
|
|
@@ -4748,15 +4919,22 @@ const tryRestoreLayout = savedState => {
|
|
|
4748
4919
|
|
|
4749
4920
|
const createViewlets = async (layout, viewletModuleIds, bounds) => {
|
|
4750
4921
|
const editorUids = {};
|
|
4922
|
+
const titles = {};
|
|
4751
4923
|
for (const group of layout.groups) {
|
|
4752
4924
|
const activeTab = group.tabs.find(tab => tab.id === group.activeTabId);
|
|
4753
4925
|
if (activeTab && viewletModuleIds[activeTab.id]) {
|
|
4754
|
-
const editorUid = activeTab.editorUid === -1 ? create$
|
|
4926
|
+
const editorUid = activeTab.editorUid === -1 ? create$2() : activeTab.editorUid;
|
|
4755
4927
|
editorUids[activeTab.id] = editorUid;
|
|
4756
|
-
await createViewlet(viewletModuleIds[activeTab.id], editorUid, activeTab.id, bounds, activeTab.uri);
|
|
4928
|
+
const title = await createViewlet(viewletModuleIds[activeTab.id], editorUid, activeTab.id, bounds, activeTab.uri);
|
|
4929
|
+
if (title) {
|
|
4930
|
+
titles[activeTab.id] = title;
|
|
4931
|
+
}
|
|
4757
4932
|
}
|
|
4758
4933
|
}
|
|
4759
|
-
return
|
|
4934
|
+
return {
|
|
4935
|
+
editorUids,
|
|
4936
|
+
titles
|
|
4937
|
+
};
|
|
4760
4938
|
};
|
|
4761
4939
|
|
|
4762
4940
|
const getViewletModuleIds = async layout => {
|
|
@@ -4833,7 +5011,10 @@ const restoreAndCreateEditors = async (state, restoredLayout) => {
|
|
|
4833
5011
|
const viewletModuleIds = await getViewletModuleIds(newState.layout);
|
|
4834
5012
|
|
|
4835
5013
|
// Create viewlets and get editor UIDs
|
|
4836
|
-
const
|
|
5014
|
+
const {
|
|
5015
|
+
editorUids,
|
|
5016
|
+
titles
|
|
5017
|
+
} = await createViewlets(newState.layout, viewletModuleIds, bounds);
|
|
4837
5018
|
|
|
4838
5019
|
// Update tabs with editor UIDs
|
|
4839
5020
|
newState = updateTabs(newState, editorUids);
|
|
@@ -4844,7 +5025,7 @@ const restoreAndCreateEditors = async (state, restoredLayout) => {
|
|
|
4844
5025
|
if (activeTab && viewletModuleIds[activeTab.id]) {
|
|
4845
5026
|
const editorUid = editorUids[activeTab.id];
|
|
4846
5027
|
newState = createViewletForTab(newState, activeTab.id);
|
|
4847
|
-
newState = handleViewletReady(newState, editorUid);
|
|
5028
|
+
newState = handleViewletReady(newState, editorUid, titles[activeTab.id]);
|
|
4848
5029
|
}
|
|
4849
5030
|
}
|
|
4850
5031
|
return newState;
|
|
@@ -4887,6 +5068,37 @@ const loadContent = async (state, savedState) => {
|
|
|
4887
5068
|
};
|
|
4888
5069
|
};
|
|
4889
5070
|
|
|
5071
|
+
const handleWorkspaceChange = async (state, _workspacePath, savedState) => {
|
|
5072
|
+
return loadContent(state, savedState);
|
|
5073
|
+
};
|
|
5074
|
+
|
|
5075
|
+
const hasActiveTextEditor = state => {
|
|
5076
|
+
const activeTab = getActiveTab(state);
|
|
5077
|
+
return activeTab?.tab.editorInput?.type === 'editor';
|
|
5078
|
+
};
|
|
5079
|
+
|
|
5080
|
+
const id = 7201;
|
|
5081
|
+
const sendMessagePortToExtensionHostWorker = async port => {
|
|
5082
|
+
await sendMessagePortToExtensionHostWorker$1(port, id);
|
|
5083
|
+
};
|
|
5084
|
+
|
|
5085
|
+
const createExtensionHostRpc = async () => {
|
|
5086
|
+
try {
|
|
5087
|
+
const rpc = await create$8({
|
|
5088
|
+
commandMap: {},
|
|
5089
|
+
send: sendMessagePortToExtensionHostWorker
|
|
5090
|
+
});
|
|
5091
|
+
return rpc;
|
|
5092
|
+
} catch (error) {
|
|
5093
|
+
throw new VError(error, `Failed to create extension host rpc`);
|
|
5094
|
+
}
|
|
5095
|
+
};
|
|
5096
|
+
|
|
5097
|
+
const initialize = async () => {
|
|
5098
|
+
const rpc = await createExtensionHostRpc();
|
|
5099
|
+
set$3(rpc);
|
|
5100
|
+
};
|
|
5101
|
+
|
|
4890
5102
|
const hasTargetGroup = groupId => {
|
|
4891
5103
|
return groupId !== undefined && groupId >= 0;
|
|
4892
5104
|
};
|
|
@@ -4899,15 +5111,15 @@ const getMenuEntryArgs = groupId => {
|
|
|
4899
5111
|
};
|
|
4900
5112
|
|
|
4901
5113
|
const emptyObject = {};
|
|
4902
|
-
const RE_PLACEHOLDER = /\{(PH\d+)\}/g;
|
|
4903
5114
|
const i18nString = (key, placeholders = emptyObject) => {
|
|
4904
5115
|
if (placeholders === emptyObject) {
|
|
4905
5116
|
return key;
|
|
4906
5117
|
}
|
|
4907
|
-
|
|
4908
|
-
|
|
4909
|
-
|
|
4910
|
-
|
|
5118
|
+
let result = key;
|
|
5119
|
+
for (const [placeholder, replacement] of Object.entries(placeholders)) {
|
|
5120
|
+
result = result.split(`{${placeholder}}`).join(String(replacement));
|
|
5121
|
+
}
|
|
5122
|
+
return result;
|
|
4911
5123
|
};
|
|
4912
5124
|
|
|
4913
5125
|
const Close = 'Close';
|
|
@@ -5260,26 +5472,26 @@ const newWindow = async state => {
|
|
|
5260
5472
|
return state;
|
|
5261
5473
|
};
|
|
5262
5474
|
|
|
5263
|
-
const
|
|
5475
|
+
const openUrisWithContext = async (context, uris) => {
|
|
5264
5476
|
if (uris.length === 0) {
|
|
5265
|
-
return
|
|
5477
|
+
return;
|
|
5266
5478
|
}
|
|
5479
|
+
await openUriWithContext(context, uris[0]);
|
|
5267
5480
|
if (uris.length === 1) {
|
|
5268
|
-
return
|
|
5481
|
+
return;
|
|
5269
5482
|
}
|
|
5270
|
-
let currentState =
|
|
5483
|
+
let currentState = context.getState();
|
|
5271
5484
|
const firstTab = findTabByUri(currentState, uris[0]);
|
|
5272
5485
|
for (const uri of uris.slice(1)) {
|
|
5273
5486
|
const existingTab = findTabByUri(currentState, uri);
|
|
5274
|
-
if (existingTab) {
|
|
5275
|
-
|
|
5487
|
+
if (!existingTab) {
|
|
5488
|
+
currentState = ensureActiveGroup(currentState, uri);
|
|
5276
5489
|
}
|
|
5277
|
-
currentState = ensureActiveGroup(currentState, uri);
|
|
5278
5490
|
}
|
|
5279
|
-
if (
|
|
5280
|
-
|
|
5491
|
+
if (firstTab) {
|
|
5492
|
+
currentState = switchTab(currentState, firstTab.groupId, firstTab.tab.id);
|
|
5281
5493
|
}
|
|
5282
|
-
|
|
5494
|
+
await context.updateState(() => currentState);
|
|
5283
5495
|
};
|
|
5284
5496
|
|
|
5285
5497
|
const refresh = state => {
|
|
@@ -6350,7 +6562,7 @@ const createEmptyGroup = () => {
|
|
|
6350
6562
|
return {
|
|
6351
6563
|
activeTabId: undefined,
|
|
6352
6564
|
focused: false,
|
|
6353
|
-
id: create$
|
|
6565
|
+
id: create$2(),
|
|
6354
6566
|
isEmpty: true,
|
|
6355
6567
|
size: 100,
|
|
6356
6568
|
tabs: []
|
|
@@ -6525,7 +6737,7 @@ const splitDown = (state, groupId) => {
|
|
|
6525
6737
|
|
|
6526
6738
|
// If there are no groups, create an initial empty group first
|
|
6527
6739
|
if (groups.length === 0) {
|
|
6528
|
-
const initialGroupId = create$
|
|
6740
|
+
const initialGroupId = create$2();
|
|
6529
6741
|
const initialGroup = {
|
|
6530
6742
|
activeTabId: undefined,
|
|
6531
6743
|
focused: true,
|
|
@@ -6560,7 +6772,7 @@ const splitLeft = (state, groupId) => {
|
|
|
6560
6772
|
groups
|
|
6561
6773
|
} = layout;
|
|
6562
6774
|
if (groups.length === 0) {
|
|
6563
|
-
const initialGroupId = create$
|
|
6775
|
+
const initialGroupId = create$2();
|
|
6564
6776
|
const initialGroup = {
|
|
6565
6777
|
activeTabId: undefined,
|
|
6566
6778
|
focused: true,
|
|
@@ -6594,7 +6806,7 @@ const splitRight = (state, groupId) => {
|
|
|
6594
6806
|
|
|
6595
6807
|
// If there are no groups, create an initial empty group first
|
|
6596
6808
|
if (groups.length === 0) {
|
|
6597
|
-
const initialGroupId = create$
|
|
6809
|
+
const initialGroupId = create$2();
|
|
6598
6810
|
const initialGroup = {
|
|
6599
6811
|
activeTabId: undefined,
|
|
6600
6812
|
focused: true,
|
|
@@ -6625,7 +6837,7 @@ const splitUp = (state, groupId) => {
|
|
|
6625
6837
|
groups
|
|
6626
6838
|
} = layout;
|
|
6627
6839
|
if (groups.length === 0) {
|
|
6628
|
-
const initialGroupId = create$
|
|
6840
|
+
const initialGroupId = create$2();
|
|
6629
6841
|
const initialGroup = {
|
|
6630
6842
|
activeTabId: undefined,
|
|
6631
6843
|
focused: true,
|
|
@@ -6652,99 +6864,99 @@ const splitUp = (state, groupId) => {
|
|
|
6652
6864
|
};
|
|
6653
6865
|
|
|
6654
6866
|
const commandMap = {
|
|
6655
|
-
'Main.closeActiveEditor':
|
|
6656
|
-
'Main.closeAll':
|
|
6657
|
-
'Main.closeAllEditors':
|
|
6658
|
-
'Main.closeFocusedTab':
|
|
6659
|
-
'Main.closeOthers':
|
|
6660
|
-
'Main.closeSaved':
|
|
6661
|
-
'Main.closeTabsByUris':
|
|
6662
|
-
'Main.closeTabsRight':
|
|
6663
|
-
'Main.copyPath':
|
|
6664
|
-
'Main.copyRelativePath':
|
|
6665
|
-
'Main.focusNext':
|
|
6666
|
-
'Main.focusNextTab':
|
|
6667
|
-
'Main.focusPrevious':
|
|
6668
|
-
'Main.focusPreviousTab':
|
|
6669
|
-
'Main.handleModifiedStatusChange':
|
|
6670
|
-
'Main.handleTabContextMenu':
|
|
6867
|
+
'Main.closeActiveEditor': wrapSerialCommand(closeActiveEditor),
|
|
6868
|
+
'Main.closeAll': wrapSerialCommand(closeAll$1),
|
|
6869
|
+
'Main.closeAllEditors': wrapSerialCommand(closeAll$1),
|
|
6870
|
+
'Main.closeFocusedTab': wrapSerialCommand(closeFocusedTab),
|
|
6871
|
+
'Main.closeOthers': wrapSerialCommand(closeOtherTabs),
|
|
6872
|
+
'Main.closeSaved': wrapSerialCommand(closeSaved$1),
|
|
6873
|
+
'Main.closeTabsByUris': wrapSerialCommand(closeTabsByUris),
|
|
6874
|
+
'Main.closeTabsRight': wrapSerialCommand(closeTabsRight),
|
|
6875
|
+
'Main.copyPath': wrapSerialCommand(copyPath$1),
|
|
6876
|
+
'Main.copyRelativePath': wrapSerialCommand(copyRelativePath$1),
|
|
6877
|
+
'Main.focusNext': wrapSerialCommand(focusNextTab),
|
|
6878
|
+
'Main.focusNextTab': wrapSerialCommand(focusNextTab),
|
|
6879
|
+
'Main.focusPrevious': wrapSerialCommand(focusPreviousTab),
|
|
6880
|
+
'Main.focusPreviousTab': wrapSerialCommand(focusPreviousTab),
|
|
6881
|
+
'Main.handleModifiedStatusChange': wrapAsyncCommand(handleModifiedStatusChangeWithContext),
|
|
6882
|
+
'Main.handleTabContextMenu': wrapSerialCommand(handleTabContextMenu),
|
|
6671
6883
|
'Main.hasActiveTextEditor': wrapGetter(hasActiveTextEditor),
|
|
6672
|
-
'Main.openInput':
|
|
6673
|
-
'Main.openUri':
|
|
6674
|
-
'Main.openUris':
|
|
6675
|
-
'Main.restoreClosedTab':
|
|
6676
|
-
'Main.save':
|
|
6884
|
+
'Main.openInput': wrapSerialAsyncCommand(openInputWithContext),
|
|
6885
|
+
'Main.openUri': wrapSerialAsyncCommand(openUriWithContext),
|
|
6886
|
+
'Main.openUris': wrapSerialAsyncCommand(openUrisWithContext),
|
|
6887
|
+
'Main.restoreClosedTab': wrapSerialCommand(restoreClosedTab),
|
|
6888
|
+
'Main.save': wrapSerialCommand(save),
|
|
6677
6889
|
'Main.saveState': wrapGetter(saveState),
|
|
6678
|
-
'Main.splitRight':
|
|
6679
|
-
'MainArea.closeActiveEditor':
|
|
6680
|
-
'MainArea.closeAll':
|
|
6681
|
-
'MainArea.closeAllEditors':
|
|
6682
|
-
'MainArea.closeEditorGroup':
|
|
6683
|
-
'MainArea.closeFocusedTab':
|
|
6684
|
-
'MainArea.closeOthers':
|
|
6685
|
-
'MainArea.closeSaved':
|
|
6686
|
-
'MainArea.closeTabsByUris':
|
|
6687
|
-
'MainArea.closeTabsRight':
|
|
6688
|
-
'MainArea.copyIntoNewWindow':
|
|
6689
|
-
'MainArea.copyPath':
|
|
6690
|
-
'MainArea.copyRelativePath':
|
|
6691
|
-
'MainArea.create': create$
|
|
6890
|
+
'Main.splitRight': wrapSerialCommand(splitRight),
|
|
6891
|
+
'MainArea.closeActiveEditor': wrapSerialCommand(closeActiveEditor),
|
|
6892
|
+
'MainArea.closeAll': wrapSerialCommand(closeAll$1),
|
|
6893
|
+
'MainArea.closeAllEditors': wrapSerialCommand(closeAll$1),
|
|
6894
|
+
'MainArea.closeEditorGroup': wrapSerialCommand(closeEditorGroup$1),
|
|
6895
|
+
'MainArea.closeFocusedTab': wrapSerialCommand(closeFocusedTab),
|
|
6896
|
+
'MainArea.closeOthers': wrapSerialCommand(closeOtherTabs),
|
|
6897
|
+
'MainArea.closeSaved': wrapSerialCommand(closeSaved$1),
|
|
6898
|
+
'MainArea.closeTabsByUris': wrapSerialCommand(closeTabsByUris),
|
|
6899
|
+
'MainArea.closeTabsRight': wrapSerialCommand(closeTabsRight),
|
|
6900
|
+
'MainArea.copyIntoNewWindow': wrapSerialCommand(copyIntoNewWindow$1),
|
|
6901
|
+
'MainArea.copyPath': wrapSerialCommand(copyPath$1),
|
|
6902
|
+
'MainArea.copyRelativePath': wrapSerialCommand(copyRelativePath$1),
|
|
6903
|
+
'MainArea.create': create$1,
|
|
6692
6904
|
'MainArea.diff2': diff2,
|
|
6693
|
-
'MainArea.flipEditorLayout':
|
|
6694
|
-
'MainArea.focusNext':
|
|
6695
|
-
'MainArea.focusNextTab':
|
|
6696
|
-
'MainArea.focusPrevious':
|
|
6697
|
-
'MainArea.focusPreviousTab':
|
|
6905
|
+
'MainArea.flipEditorLayout': wrapSerialCommand(flipLayout),
|
|
6906
|
+
'MainArea.focusNext': wrapSerialCommand(focusNextTab),
|
|
6907
|
+
'MainArea.focusNextTab': wrapSerialCommand(focusNextTab),
|
|
6908
|
+
'MainArea.focusPrevious': wrapSerialCommand(focusPreviousTab),
|
|
6909
|
+
'MainArea.focusPreviousTab': wrapSerialCommand(focusPreviousTab),
|
|
6698
6910
|
'MainArea.getCommandIds': getCommandIds,
|
|
6699
6911
|
'MainArea.getMenuEntries': wrapGetter(getMenuEntries),
|
|
6700
6912
|
'MainArea.getMenuIds': getMenuIds,
|
|
6701
|
-
'MainArea.handleClick':
|
|
6702
|
-
'MainArea.handleClickAction':
|
|
6703
|
-
'MainArea.handleClickCloseTab':
|
|
6704
|
-
'MainArea.handleClickTab':
|
|
6705
|
-
'MainArea.handleClickTogglePreview':
|
|
6706
|
-
'MainArea.handleContextMenu':
|
|
6707
|
-
'MainArea.handleDoubleClick':
|
|
6708
|
-
'MainArea.handleHeaderDoubleClick':
|
|
6709
|
-
'MainArea.handleIconThemeChange':
|
|
6710
|
-
'MainArea.handleModifiedStatusChange':
|
|
6913
|
+
'MainArea.handleClick': wrapSerialCommand(handleClick),
|
|
6914
|
+
'MainArea.handleClickAction': wrapSerialCommand(handleClickAction),
|
|
6915
|
+
'MainArea.handleClickCloseTab': wrapSerialCommand(handleClickCloseTab),
|
|
6916
|
+
'MainArea.handleClickTab': wrapSerialCommand(handleClickTab),
|
|
6917
|
+
'MainArea.handleClickTogglePreview': wrapSerialCommand(handleClickTogglePreview),
|
|
6918
|
+
'MainArea.handleContextMenu': wrapSerialCommand(handleContextMenu),
|
|
6919
|
+
'MainArea.handleDoubleClick': wrapSerialCommand(handleDoubleClick),
|
|
6920
|
+
'MainArea.handleHeaderDoubleClick': wrapSerialCommand(handleHeaderDoubleClick),
|
|
6921
|
+
'MainArea.handleIconThemeChange': wrapSerialCommand(handleIconThemeChange),
|
|
6922
|
+
'MainArea.handleModifiedStatusChange': wrapAsyncCommand(handleModifiedStatusChangeWithContext),
|
|
6711
6923
|
'MainArea.handleResize': wrapGetter(handleResize),
|
|
6712
6924
|
// TODO would need to have a function that returns newstate as well as commands
|
|
6713
|
-
'MainArea.handleSashPointerDown':
|
|
6714
|
-
'MainArea.handleSashPointerMove':
|
|
6715
|
-
'MainArea.handleSashPointerUp':
|
|
6716
|
-
'MainArea.handleTabContextMenu':
|
|
6717
|
-
'MainArea.handleUriChange':
|
|
6718
|
-
'MainArea.handleWorkspaceChange':
|
|
6925
|
+
'MainArea.handleSashPointerDown': wrapSerialCommand(handleSashPointerDown),
|
|
6926
|
+
'MainArea.handleSashPointerMove': wrapSerialCommand(handleSashPointerMove),
|
|
6927
|
+
'MainArea.handleSashPointerUp': wrapSerialCommand(handleSashPointerUp),
|
|
6928
|
+
'MainArea.handleTabContextMenu': wrapSerialCommand(handleTabContextMenu),
|
|
6929
|
+
'MainArea.handleUriChange': wrapSerialCommand(handleUriChange),
|
|
6930
|
+
'MainArea.handleWorkspaceChange': wrapSerialCommand(handleWorkspaceChange),
|
|
6719
6931
|
'MainArea.hasActiveTextEditor': wrapGetter(hasActiveTextEditor),
|
|
6720
6932
|
'MainArea.initialize': initialize,
|
|
6721
|
-
'MainArea.loadContent':
|
|
6722
|
-
'MainArea.moveIntoNewWindow':
|
|
6723
|
-
'MainArea.newFile':
|
|
6724
|
-
'MainArea.newWindow':
|
|
6725
|
-
'MainArea.openInput':
|
|
6726
|
-
'MainArea.openUri':
|
|
6727
|
-
'MainArea.openUris':
|
|
6728
|
-
'MainArea.refresh':
|
|
6933
|
+
'MainArea.loadContent': wrapSerialCommand(loadContent),
|
|
6934
|
+
'MainArea.moveIntoNewWindow': wrapSerialCommand(moveIntoNewWindow),
|
|
6935
|
+
'MainArea.newFile': wrapSerialCommand(newFile),
|
|
6936
|
+
'MainArea.newWindow': wrapSerialCommand(newWindow),
|
|
6937
|
+
'MainArea.openInput': wrapSerialAsyncCommand(openInputWithContext),
|
|
6938
|
+
'MainArea.openUri': wrapSerialAsyncCommand(openUriWithContext),
|
|
6939
|
+
'MainArea.openUris': wrapSerialAsyncCommand(openUrisWithContext),
|
|
6940
|
+
'MainArea.refresh': wrapSerialCommand(refresh),
|
|
6729
6941
|
'MainArea.render2': render2,
|
|
6730
6942
|
'MainArea.renderEventListeners': renderEventListeners,
|
|
6731
6943
|
'MainArea.resize': wrapGetter(handleResize),
|
|
6732
|
-
'MainArea.restoreClosedTab':
|
|
6733
|
-
'MainArea.save':
|
|
6944
|
+
'MainArea.restoreClosedTab': wrapSerialCommand(restoreClosedTab),
|
|
6945
|
+
'MainArea.save': wrapSerialCommand(save),
|
|
6734
6946
|
'MainArea.saveState': wrapGetter(saveState),
|
|
6735
|
-
'MainArea.selectTab':
|
|
6736
|
-
'MainArea.setEditorLayoutGrid':
|
|
6737
|
-
'MainArea.setEditorLayoutSingle':
|
|
6738
|
-
'MainArea.setEditorLayoutThreeColumns':
|
|
6739
|
-
'MainArea.setEditorLayoutThreeRows':
|
|
6740
|
-
'MainArea.setEditorLayoutTwoColumns':
|
|
6741
|
-
'MainArea.setEditorLayoutTwoColumnsBottom':
|
|
6742
|
-
'MainArea.setEditorLayoutTwoRows':
|
|
6743
|
-
'MainArea.setEditorLayoutTwoRowsRight':
|
|
6744
|
-
'MainArea.splitDown':
|
|
6745
|
-
'MainArea.splitLeft':
|
|
6746
|
-
'MainArea.splitRight':
|
|
6747
|
-
'MainArea.splitUp':
|
|
6947
|
+
'MainArea.selectTab': wrapSerialCommand(selectTab),
|
|
6948
|
+
'MainArea.setEditorLayoutGrid': wrapSerialCommand(setEditorLayoutGrid),
|
|
6949
|
+
'MainArea.setEditorLayoutSingle': wrapSerialCommand(setEditorLayoutSingle),
|
|
6950
|
+
'MainArea.setEditorLayoutThreeColumns': wrapSerialCommand(setEditorLayoutThreeColumns),
|
|
6951
|
+
'MainArea.setEditorLayoutThreeRows': wrapSerialCommand(setEditorLayoutThreeRows),
|
|
6952
|
+
'MainArea.setEditorLayoutTwoColumns': wrapSerialCommand(setEditorLayoutTwoColumns),
|
|
6953
|
+
'MainArea.setEditorLayoutTwoColumnsBottom': wrapSerialCommand(setEditorLayoutTwoColumnsBottom),
|
|
6954
|
+
'MainArea.setEditorLayoutTwoRows': wrapSerialCommand(setEditorLayoutTwoRows),
|
|
6955
|
+
'MainArea.setEditorLayoutTwoRowsRight': wrapSerialCommand(setEditorLayoutTwoRowsRight),
|
|
6956
|
+
'MainArea.splitDown': wrapSerialCommand(splitDown),
|
|
6957
|
+
'MainArea.splitLeft': wrapSerialCommand(splitLeft),
|
|
6958
|
+
'MainArea.splitRight': wrapSerialCommand(splitRight),
|
|
6959
|
+
'MainArea.splitUp': wrapSerialCommand(splitUp),
|
|
6748
6960
|
'MainArea.terminate': terminate
|
|
6749
6961
|
};
|
|
6750
6962
|
|