@lvce-editor/explorer-view 2.55.0 → 2.57.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/explorerViewWorkerMain.js +151 -73
- package/package.json +1 -1
|
@@ -885,7 +885,7 @@ const WebWorkerRpcClient = {
|
|
|
885
885
|
|
|
886
886
|
const CreateFolder$1 = 1;
|
|
887
887
|
const CreateFile$1 = 2;
|
|
888
|
-
const Copy$
|
|
888
|
+
const Copy$1 = 3;
|
|
889
889
|
const Rename$2 = 4;
|
|
890
890
|
|
|
891
891
|
const rpcs = Object.create(null);
|
|
@@ -973,7 +973,7 @@ const applyOperation = operation => {
|
|
|
973
973
|
if (operation.type === CreateFolder$1) {
|
|
974
974
|
return mkdir(operation.path);
|
|
975
975
|
}
|
|
976
|
-
if (operation.type === Copy$
|
|
976
|
+
if (operation.type === Copy$1) {
|
|
977
977
|
return copy$1(operation.from || '', operation.path);
|
|
978
978
|
}
|
|
979
979
|
if (operation.type === Rename$2) {
|
|
@@ -995,6 +995,23 @@ const applyFileOperations = async operations => {
|
|
|
995
995
|
}
|
|
996
996
|
};
|
|
997
997
|
|
|
998
|
+
const DELTA_EDITING = 100;
|
|
999
|
+
|
|
1000
|
+
const BlockDevice = 1;
|
|
1001
|
+
const CharacterDevice = 2;
|
|
1002
|
+
const Directory = 3;
|
|
1003
|
+
const DirectoryExpanded = 4;
|
|
1004
|
+
const DirectoryExpanding = 5;
|
|
1005
|
+
const File = 7;
|
|
1006
|
+
const Socket = 8;
|
|
1007
|
+
const Symlink = 9;
|
|
1008
|
+
const SymLinkFile = 10;
|
|
1009
|
+
const SymLinkFolder = 11;
|
|
1010
|
+
const Unknown = 12;
|
|
1011
|
+
const EditingFile = File + DELTA_EDITING;
|
|
1012
|
+
const EditingFolder = Directory + DELTA_EDITING;
|
|
1013
|
+
const EditingDirectoryExpanded = DirectoryExpanded + DELTA_EDITING;
|
|
1014
|
+
|
|
998
1015
|
const dirname = (pathSeparator, path) => {
|
|
999
1016
|
const index = path.lastIndexOf(pathSeparator);
|
|
1000
1017
|
if (index === -1) {
|
|
@@ -1015,16 +1032,32 @@ const join2 = (path, childPath) => {
|
|
|
1015
1032
|
return `${path}/${childPath}`;
|
|
1016
1033
|
};
|
|
1017
1034
|
|
|
1035
|
+
const getActualType = (type, expanded) => {
|
|
1036
|
+
const actualType = type === Directory && expanded ? DirectoryExpanded : type;
|
|
1037
|
+
return actualType;
|
|
1038
|
+
};
|
|
1018
1039
|
const createTree = (items, root) => {
|
|
1019
1040
|
const tree = Object.create(null);
|
|
1020
1041
|
const rootLength = root.length;
|
|
1021
|
-
|
|
1042
|
+
const paths = items.map(item => {
|
|
1022
1043
|
const relativePath = item.path.slice(rootLength);
|
|
1023
1044
|
const dirname = dirname2(relativePath);
|
|
1045
|
+
return dirname;
|
|
1046
|
+
});
|
|
1047
|
+
for (const item of items) {
|
|
1048
|
+
const {
|
|
1049
|
+
type,
|
|
1050
|
+
name,
|
|
1051
|
+
path
|
|
1052
|
+
} = item;
|
|
1053
|
+
const relativePath = path.slice(rootLength);
|
|
1054
|
+
const dirname = dirname2(relativePath);
|
|
1055
|
+
const isExpanded = paths.includes(relativePath);
|
|
1056
|
+
const actualType = getActualType(type, isExpanded);
|
|
1024
1057
|
tree[dirname] ||= [];
|
|
1025
1058
|
tree[dirname].push({
|
|
1026
|
-
name
|
|
1027
|
-
type:
|
|
1059
|
+
name,
|
|
1060
|
+
type: actualType
|
|
1028
1061
|
});
|
|
1029
1062
|
}
|
|
1030
1063
|
return tree;
|
|
@@ -1076,23 +1109,6 @@ const getPaths = items => {
|
|
|
1076
1109
|
return items.map(getPath);
|
|
1077
1110
|
};
|
|
1078
1111
|
|
|
1079
|
-
const DELTA_EDITING = 100;
|
|
1080
|
-
|
|
1081
|
-
const BlockDevice = 1;
|
|
1082
|
-
const CharacterDevice = 2;
|
|
1083
|
-
const Directory = 3;
|
|
1084
|
-
const DirectoryExpanded = 4;
|
|
1085
|
-
const DirectoryExpanding = 5;
|
|
1086
|
-
const File = 7;
|
|
1087
|
-
const Socket = 8;
|
|
1088
|
-
const Symlink = 9;
|
|
1089
|
-
const SymLinkFile = 10;
|
|
1090
|
-
const SymLinkFolder = 11;
|
|
1091
|
-
const Unknown = 12;
|
|
1092
|
-
const EditingFile = File + DELTA_EDITING;
|
|
1093
|
-
const EditingFolder = Directory + DELTA_EDITING;
|
|
1094
|
-
const EditingDirectoryExpanded = DirectoryExpanded + DELTA_EDITING;
|
|
1095
|
-
|
|
1096
1112
|
const getSimpleIconRequestType = direntType => {
|
|
1097
1113
|
if (direntType === Directory || direntType === DirectoryExpanded || direntType === EditingDirectoryExpanded || direntType === EditingFolder) {
|
|
1098
1114
|
return 2;
|
|
@@ -1197,13 +1213,14 @@ const getPathParts = (root, uri, pathSeparator) => {
|
|
|
1197
1213
|
const parts = [];
|
|
1198
1214
|
let index = root.length - 1;
|
|
1199
1215
|
let depth = 0;
|
|
1200
|
-
while ((index = uri.indexOf(
|
|
1216
|
+
while ((index = uri.indexOf(pathSeparator, index + 1)) !== -1) {
|
|
1201
1217
|
const partUri = uri.slice(0, index);
|
|
1202
1218
|
parts.push({
|
|
1203
1219
|
path: partUri,
|
|
1204
1220
|
depth: depth++,
|
|
1205
1221
|
root,
|
|
1206
|
-
pathSeparator
|
|
1222
|
+
pathSeparator,
|
|
1223
|
+
expanded: true
|
|
1207
1224
|
});
|
|
1208
1225
|
}
|
|
1209
1226
|
return parts;
|
|
@@ -1310,14 +1327,14 @@ const sortExplorerItems = rawDirents => {
|
|
|
1310
1327
|
};
|
|
1311
1328
|
|
|
1312
1329
|
// TODO figure out whether this uses too much memory (name,path -> redundant, depth could be computed on demand)
|
|
1313
|
-
const toDisplayDirent = (parentPath, parentDepth,
|
|
1314
|
-
const path = join2(parentPath,
|
|
1330
|
+
const toDisplayDirent = (parentPath, parentDepth, rawDirentType, rawDirentName, index, length) => {
|
|
1331
|
+
const path = join2(parentPath, rawDirentName);
|
|
1315
1332
|
return {
|
|
1316
|
-
name:
|
|
1333
|
+
name: rawDirentName,
|
|
1317
1334
|
posInSet: index + 1,
|
|
1318
1335
|
setSize: length,
|
|
1319
1336
|
depth: parentDepth + 1,
|
|
1320
|
-
type:
|
|
1337
|
+
type: rawDirentType,
|
|
1321
1338
|
path,
|
|
1322
1339
|
// TODO storing absolute path might be too costly, could also store relative path here
|
|
1323
1340
|
icon: '',
|
|
@@ -1325,7 +1342,7 @@ const toDisplayDirent = (parentPath, parentDepth, rawDirent, index, length) => {
|
|
|
1325
1342
|
};
|
|
1326
1343
|
};
|
|
1327
1344
|
|
|
1328
|
-
const toDisplayDirents = (pathSeparator, rawDirents, parentDirentPath, parentDirentDepth, excluded) => {
|
|
1345
|
+
const toDisplayDirents = (pathSeparator, rawDirents, parentDirentPath, parentDirentDepth, excluded, expanded = false) => {
|
|
1329
1346
|
rawDirents = sortExplorerItems(rawDirents);
|
|
1330
1347
|
const result = [];
|
|
1331
1348
|
const visibleItems = rawDirents.filter(item => {
|
|
@@ -1337,7 +1354,7 @@ const toDisplayDirents = (pathSeparator, rawDirents, parentDirentPath, parentDir
|
|
|
1337
1354
|
const count = visibleItems.length;
|
|
1338
1355
|
for (let i = 0; i < visibleItems.length; i++) {
|
|
1339
1356
|
const rawDirent = visibleItems[i];
|
|
1340
|
-
result.push(toDisplayDirent(parentDirentPath, parentDirentDepth, rawDirent, i, count));
|
|
1357
|
+
result.push(toDisplayDirent(parentDirentPath, parentDirentDepth, rawDirent.type, rawDirent.name, i, count));
|
|
1341
1358
|
}
|
|
1342
1359
|
return result;
|
|
1343
1360
|
};
|
|
@@ -1443,11 +1460,12 @@ const i18nString = (key, placeholders = emptyObject) => {
|
|
|
1443
1460
|
};
|
|
1444
1461
|
|
|
1445
1462
|
const CollapseAllFoldersInExplorer = 'Collapse All Folders in Explorer';
|
|
1446
|
-
const Copy
|
|
1463
|
+
const Copy = 'Copy';
|
|
1447
1464
|
const CopyPath = 'Copy Path';
|
|
1448
1465
|
const CopyRelativePath = 'Copy Relative Path';
|
|
1449
|
-
const Cut
|
|
1466
|
+
const Cut = 'Cut';
|
|
1450
1467
|
const Delete$1 = 'Delete';
|
|
1468
|
+
const FileNameCannotStartWithSlash = 'A file or folder name cannot start with a slash.';
|
|
1451
1469
|
const FileOrFolderNameMustBeProvider = 'A file or folder name must be provided.';
|
|
1452
1470
|
const FilesExplorer = 'Files Explorer';
|
|
1453
1471
|
const NewFile$1 = 'New File...';
|
|
@@ -1474,10 +1492,10 @@ const openInIntegratedTerminal = () => {
|
|
|
1474
1492
|
return i18nString(OpenInIntegratedTerminal);
|
|
1475
1493
|
};
|
|
1476
1494
|
const cut = () => {
|
|
1477
|
-
return i18nString(Cut
|
|
1495
|
+
return i18nString(Cut);
|
|
1478
1496
|
};
|
|
1479
1497
|
const copy = () => {
|
|
1480
|
-
return i18nString(Copy
|
|
1498
|
+
return i18nString(Copy);
|
|
1481
1499
|
};
|
|
1482
1500
|
const paste = () => {
|
|
1483
1501
|
return i18nString(Paste);
|
|
@@ -1512,6 +1530,9 @@ const openFolder$1 = () => {
|
|
|
1512
1530
|
const fileOrFolderNameMustBeProvided = () => {
|
|
1513
1531
|
return i18nString(FileOrFolderNameMustBeProvider);
|
|
1514
1532
|
};
|
|
1533
|
+
const fileCannotStartWithSlash = () => {
|
|
1534
|
+
return i18nString(FileNameCannotStartWithSlash);
|
|
1535
|
+
};
|
|
1515
1536
|
const typeAFileName = () => {
|
|
1516
1537
|
return i18nString(TypeAFileName);
|
|
1517
1538
|
};
|
|
@@ -1521,6 +1542,9 @@ const validateFileName2 = name => {
|
|
|
1521
1542
|
const editingErrorMessage = fileOrFolderNameMustBeProvided();
|
|
1522
1543
|
return editingErrorMessage;
|
|
1523
1544
|
}
|
|
1545
|
+
if (name.startsWith('/')) {
|
|
1546
|
+
return fileCannotStartWithSlash();
|
|
1547
|
+
}
|
|
1524
1548
|
return '';
|
|
1525
1549
|
};
|
|
1526
1550
|
|
|
@@ -1970,7 +1994,8 @@ const create2 = (uid, uri, x, y, width, height, args, parentUid, platform = 0) =
|
|
|
1970
1994
|
handleOffset: 0,
|
|
1971
1995
|
scrollBarActive: false,
|
|
1972
1996
|
scrollBarHeight: 0,
|
|
1973
|
-
confirmPaste: false
|
|
1997
|
+
confirmPaste: false,
|
|
1998
|
+
pasteShouldMove: false
|
|
1974
1999
|
};
|
|
1975
2000
|
set(uid, state, state);
|
|
1976
2001
|
};
|
|
@@ -2017,7 +2042,8 @@ const create = (id, uri, x, y, width, height, args, parentUid, platform = 0) =>
|
|
|
2017
2042
|
handleOffset: 0,
|
|
2018
2043
|
scrollBarActive: false,
|
|
2019
2044
|
scrollBarHeight: 0,
|
|
2020
|
-
confirmPaste: false
|
|
2045
|
+
confirmPaste: false,
|
|
2046
|
+
pasteShouldMove: false
|
|
2021
2047
|
};
|
|
2022
2048
|
set(state.uid, state, state);
|
|
2023
2049
|
return state;
|
|
@@ -2355,7 +2381,7 @@ const focusPrevious = state => {
|
|
|
2355
2381
|
}
|
|
2356
2382
|
};
|
|
2357
2383
|
|
|
2358
|
-
const commandIds = ['acceptEdit', 'cancelEdit', 'cancelTypeAhead', 'collapseAll', 'copyPath', 'copyRelativePath', 'dispose', 'expandAll', 'expandRecursively', 'focus', 'focusFirst', 'focusIndex', 'focusLast', 'focusNext', 'focusNone', 'focusPrevious', 'getFocusedDirent', 'getMenuEntries2', 'getMouseActions', 'handleArrowLeft', 'handleArrowLeft', 'handleArrowRight', 'handleArrowRight', 'handleBlur', 'handleClick', 'handleClickAt', 'handleClickCurrent', 'handleClickCurrentButKeepFocus', 'handleClickOpenFolder', 'handleContextMenu', 'handleContextMenuKeyboard', 'handleCopy', 'handleDragLeave', 'handleDragOver', 'handleDrop', 'handleFocus', 'handleIconThemeChange', 'handleInputBlur', 'handleInputClick', 'handleInputKeyDown', 'handleKeyDown', 'handleLanguagesChanged', 'handleMouseEnter', 'handleMouseLeave', 'handlePaste', 'handlePointerDown', 'handleUpload', 'handleWheel', 'handleWorkspaceChange', 'hotReload', 'newFile', 'newFolder', 'openContainingFolder', 'refresh', 'removeDirent', 'rename', 'renameDirent', 'renderEventListeners', 'revealItem', 'revealItem', 'scrollDown', 'scrollUp', 'selectAll', 'selectDown', 'selectUp', 'setDeltaY', 'setSelectedIndices', 'updateEditingValue', 'updateIcons'];
|
|
2384
|
+
const commandIds = ['acceptEdit', 'cancelEdit', 'cancelTypeAhead', 'collapseAll', 'copyPath', 'copyRelativePath', 'dispose', 'expandAll', 'expandRecursively', 'focus', 'focusFirst', 'focusIndex', 'focusLast', 'handleCut', 'focusNext', 'focusNone', 'focusPrevious', 'getFocusedDirent', 'getMenuEntries2', 'getMouseActions', 'handleArrowLeft', 'handleArrowLeft', 'handleArrowRight', 'handleArrowRight', 'handleBlur', 'handleClick', 'handleClickAt', 'handleClickCurrent', 'handleClickCurrentButKeepFocus', 'handleClickOpenFolder', 'handleContextMenu', 'handleContextMenuKeyboard', 'handleCopy', 'handleDragLeave', 'handleDragOver', 'handleDrop', 'handleFocus', 'handleIconThemeChange', 'handleInputBlur', 'handleInputClick', 'handleInputKeyDown', 'handleKeyDown', 'handleLanguagesChanged', 'handleMouseEnter', 'handleMouseLeave', 'handlePaste', 'handlePointerDown', 'handleUpload', 'handleWheel', 'handleWorkspaceChange', 'hotReload', 'newFile', 'newFolder', 'openContainingFolder', 'refresh', 'removeDirent', 'rename', 'renameDirent', 'renderEventListeners', 'revealItem', 'revealItem', 'scrollDown', 'scrollUp', 'selectAll', 'selectDown', 'selectUp', 'setDeltaY', 'setSelectedIndices', 'updateEditingValue', 'updateIcons'];
|
|
2359
2385
|
|
|
2360
2386
|
const getCommandIds = () => {
|
|
2361
2387
|
return commandIds;
|
|
@@ -2511,7 +2537,7 @@ const menuEntryCut = {
|
|
|
2511
2537
|
id: 'cut',
|
|
2512
2538
|
label: cut(),
|
|
2513
2539
|
flags: RestoreFocus,
|
|
2514
|
-
command:
|
|
2540
|
+
command: 'Explorer.handleCut'
|
|
2515
2541
|
};
|
|
2516
2542
|
const menuEntryCopy = {
|
|
2517
2543
|
id: 'copy',
|
|
@@ -3102,7 +3128,28 @@ const handleCopy = async state => {
|
|
|
3102
3128
|
// TODO handle copy error gracefully
|
|
3103
3129
|
const files = [absolutePath];
|
|
3104
3130
|
await writeNativeFiles('copy', files);
|
|
3105
|
-
return
|
|
3131
|
+
return {
|
|
3132
|
+
...state,
|
|
3133
|
+
pasteShouldMove: false
|
|
3134
|
+
};
|
|
3135
|
+
};
|
|
3136
|
+
|
|
3137
|
+
const handleCut = async state => {
|
|
3138
|
+
// TODO handle multiple files
|
|
3139
|
+
// TODO if not file is selected, what happens?
|
|
3140
|
+
const dirent = getFocusedDirent$1(state);
|
|
3141
|
+
if (!dirent) {
|
|
3142
|
+
console.error('[ViewletExplorer/handleCut] no dirent selected');
|
|
3143
|
+
return state;
|
|
3144
|
+
}
|
|
3145
|
+
const absolutePath = dirent.path;
|
|
3146
|
+
// TODO handle cut error gracefully
|
|
3147
|
+
const files = [absolutePath];
|
|
3148
|
+
await writeNativeFiles('cut', files);
|
|
3149
|
+
return {
|
|
3150
|
+
...state,
|
|
3151
|
+
pasteShouldMove: true
|
|
3152
|
+
};
|
|
3106
3153
|
};
|
|
3107
3154
|
|
|
3108
3155
|
const handleDragLeave = state => {
|
|
@@ -3398,7 +3445,7 @@ const getFileOperationsElectron = async (root, paths, fileHandles) => {
|
|
|
3398
3445
|
} = fileHandle;
|
|
3399
3446
|
const path = paths[i];
|
|
3400
3447
|
operations.push({
|
|
3401
|
-
type: Copy$
|
|
3448
|
+
type: Copy$1,
|
|
3402
3449
|
path: join2(root, name),
|
|
3403
3450
|
from: path
|
|
3404
3451
|
});
|
|
@@ -3769,7 +3816,7 @@ const getFileOperationsCopy = (root, existingUris, files) => {
|
|
|
3769
3816
|
const uniqueName = generateUniqueName(baseName, existingUris, root);
|
|
3770
3817
|
const newUri = join2(root, uniqueName);
|
|
3771
3818
|
operations.push({
|
|
3772
|
-
type: Copy$
|
|
3819
|
+
type: Copy$1,
|
|
3773
3820
|
from: file,
|
|
3774
3821
|
// TODO ensure file is uri
|
|
3775
3822
|
path: newUri
|
|
@@ -3805,24 +3852,57 @@ const handlePasteCopy = async (state, nativeFiles) => {
|
|
|
3805
3852
|
const firstNewFilePath = newFilePaths[0];
|
|
3806
3853
|
const newFileIndex = getIndex(latestState.items, firstNewFilePath);
|
|
3807
3854
|
if (newFileIndex !== -1) {
|
|
3808
|
-
|
|
3855
|
+
const adjustedState = adjustScrollAfterPaste(latestState, newFileIndex);
|
|
3856
|
+
return {
|
|
3857
|
+
...adjustedState,
|
|
3858
|
+
pasteShouldMove: false
|
|
3859
|
+
};
|
|
3809
3860
|
}
|
|
3810
3861
|
}
|
|
3811
3862
|
// If there are no items, ensure focusedIndex is 0
|
|
3812
3863
|
if (latestState.items.length === 0) {
|
|
3813
3864
|
return {
|
|
3814
3865
|
...latestState,
|
|
3815
|
-
focusedIndex: 0
|
|
3866
|
+
focusedIndex: 0,
|
|
3867
|
+
pasteShouldMove: false
|
|
3816
3868
|
};
|
|
3817
3869
|
}
|
|
3818
|
-
return
|
|
3870
|
+
return {
|
|
3871
|
+
...latestState,
|
|
3872
|
+
pasteShouldMove: false
|
|
3873
|
+
};
|
|
3819
3874
|
};
|
|
3820
3875
|
|
|
3821
|
-
const
|
|
3822
|
-
|
|
3823
|
-
|
|
3824
|
-
|
|
3876
|
+
const getOperations = (toUri, files) => {
|
|
3877
|
+
const operations = [];
|
|
3878
|
+
for (const file of files) {
|
|
3879
|
+
const baseName = getBaseName('/', file);
|
|
3880
|
+
const newUri = join2(toUri, baseName);
|
|
3881
|
+
operations.push({
|
|
3882
|
+
type: Rename$2,
|
|
3883
|
+
from: file,
|
|
3884
|
+
path: newUri
|
|
3885
|
+
});
|
|
3886
|
+
}
|
|
3887
|
+
return operations;
|
|
3888
|
+
};
|
|
3889
|
+
const getTargetUri = (root, items, index) => {
|
|
3890
|
+
if (index === -1) {
|
|
3891
|
+
return root;
|
|
3825
3892
|
}
|
|
3893
|
+
return items[index].path;
|
|
3894
|
+
};
|
|
3895
|
+
const handlePasteCut = async (state, nativeFiles) => {
|
|
3896
|
+
const {
|
|
3897
|
+
root,
|
|
3898
|
+
pathSeparator,
|
|
3899
|
+
items,
|
|
3900
|
+
focusedIndex
|
|
3901
|
+
} = state;
|
|
3902
|
+
// TODO root is not necessrily target uri
|
|
3903
|
+
const targetUri = getTargetUri(root, items, focusedIndex);
|
|
3904
|
+
const operations = getOperations(targetUri, nativeFiles.files);
|
|
3905
|
+
await applyFileOperations(operations);
|
|
3826
3906
|
|
|
3827
3907
|
// Refresh the state after cut operations
|
|
3828
3908
|
const latestState = await refresh(state);
|
|
@@ -3830,36 +3910,23 @@ const handlePasteCut = async (state, nativeFiles) => {
|
|
|
3830
3910
|
// Focus on the first pasted file and adjust scroll position
|
|
3831
3911
|
if (nativeFiles.files.length > 0) {
|
|
3832
3912
|
const firstPastedFile = nativeFiles.files[0];
|
|
3833
|
-
const targetPath = `${
|
|
3913
|
+
const targetPath = `${root}${pathSeparator}${getBaseName(pathSeparator, firstPastedFile)}`;
|
|
3834
3914
|
const pastedFileIndex = getIndex(latestState.items, targetPath);
|
|
3835
3915
|
if (pastedFileIndex !== -1) {
|
|
3836
|
-
|
|
3916
|
+
const adjustedState = adjustScrollAfterPaste(latestState, pastedFileIndex);
|
|
3917
|
+
return {
|
|
3918
|
+
...adjustedState,
|
|
3919
|
+
pasteShouldMove: false
|
|
3920
|
+
};
|
|
3837
3921
|
}
|
|
3838
3922
|
}
|
|
3839
|
-
return
|
|
3840
|
-
|
|
3841
|
-
|
|
3842
|
-
|
|
3843
|
-
console.error('[ViewletExplorer/handlePaste] no paths detected');
|
|
3844
|
-
return state;
|
|
3923
|
+
return {
|
|
3924
|
+
...latestState,
|
|
3925
|
+
pasteShouldMove: false
|
|
3926
|
+
};
|
|
3845
3927
|
};
|
|
3846
3928
|
|
|
3847
3929
|
const None$3 = 'none';
|
|
3848
|
-
const Copy = 'copy';
|
|
3849
|
-
const Cut = 'cut';
|
|
3850
|
-
|
|
3851
|
-
const getPasteHandler = type => {
|
|
3852
|
-
switch (type) {
|
|
3853
|
-
case None$3:
|
|
3854
|
-
return handlePasteNone;
|
|
3855
|
-
case Copy:
|
|
3856
|
-
return handlePasteCopy;
|
|
3857
|
-
case Cut:
|
|
3858
|
-
return handlePasteCut;
|
|
3859
|
-
default:
|
|
3860
|
-
throw new Error(`unexpected native paste type: ${type}`);
|
|
3861
|
-
}
|
|
3862
|
-
};
|
|
3863
3930
|
|
|
3864
3931
|
const handlePaste = async state => {
|
|
3865
3932
|
const nativeFiles = await readNativeFiles();
|
|
@@ -3878,8 +3945,18 @@ const handlePaste = async state => {
|
|
|
3878
3945
|
// TODO but what if a file is currently selected? Then maybe the parent folder
|
|
3879
3946
|
// TODO but will it work if the folder is a symlink?
|
|
3880
3947
|
// TODO handle error gracefully when copy fails
|
|
3881
|
-
|
|
3882
|
-
return
|
|
3948
|
+
|
|
3949
|
+
// If no files to paste, return original state unchanged
|
|
3950
|
+
if (nativeFiles.type === None$3) {
|
|
3951
|
+
return state;
|
|
3952
|
+
}
|
|
3953
|
+
|
|
3954
|
+
// Use the pasteShouldMove flag to determine whether to cut or copy
|
|
3955
|
+
if (state.pasteShouldMove) {
|
|
3956
|
+
return handlePasteCut(state, nativeFiles);
|
|
3957
|
+
} else {
|
|
3958
|
+
return handlePasteCopy(state, nativeFiles);
|
|
3959
|
+
}
|
|
3883
3960
|
};
|
|
3884
3961
|
|
|
3885
3962
|
const handlePointerDown = (state, button, x, y) => {
|
|
@@ -5427,6 +5504,7 @@ const commandMap = {
|
|
|
5427
5504
|
'Explorer.handleContextMenu': wrapCommand(handleContextMenu),
|
|
5428
5505
|
'Explorer.handleContextMenuKeyboard': wrapCommand(handleContextMenuKeyboard),
|
|
5429
5506
|
'Explorer.handleCopy': wrapCommand(handleCopy),
|
|
5507
|
+
'Explorer.handleCut': wrapCommand(handleCut),
|
|
5430
5508
|
'Explorer.handleDragLeave': wrapCommand(handleDragLeave),
|
|
5431
5509
|
'Explorer.handleDragOver': wrapCommand(handleDragOver),
|
|
5432
5510
|
'Explorer.handleDrop': wrapCommand(handleDrop),
|