feat: added copy/paste files
Signed-off-by: mellobacon <mellodev@outlook.com>
mellobacon committed
Apr 15, 2024 at 10:27 UTC
8daf27b4ec6648cc9ec91f496ddbea1a65fa4a6f
4 files changed
+45
-14
src/lib/File.ts
+35
-1
@@ -1,4 +1,4 @@
1
-import { dialog, fs, path, invoke, window } from "@tauri-apps/api";
1
+import { dialog, fs, path, invoke, window, clipboard } from "@tauri-apps/api";
2
import { get, writable } from 'svelte/store';
3
import { tabs, addEditorTab, renameTab, closeTab, refreshTabs } from "./EditorTabList.svelte";
4
import { filetree } from "./FileTree.svelte";
@@ -6,6 +6,7 @@ import { watchImmediate } from "tauri-plugin-fs-watch-api";
6
import { openFileTree } from "./Sidebar.svelte";
7
import { info, trace, warn, error } from "tauri-plugin-log-api";
8
import { homeDir } from "@tauri-apps/api/path";
9
+import { appSettings } from "../config/config";
10
11
export async function openFile() {
12
let newPath = await dialog.open() as string;
@@ -262,6 +263,39 @@ export async function renameFile(filename: string, oldpath: string) {
263
return true;
264
}
265
266
+export async function readFile(path) {
267
+ let fileData = {text: "", encoding: "UTF-8", extension: "", bom: false, spaces: await appSettings.get("editor.tabSize")};
268
+ try {
269
+ fileData = await invoke("read_file", {path: path});
270
+ if (fileData.spaces === 0) {
271
+ fileData.spaces = await appSettings.get("editor.tabSize")
272
+ }
273
+ } catch (error) {
274
+ warn(`Can't read file content in ${path}. Setting to empty string. Error: ${error}`, {file: "Tab.ts", line: 79});
275
+ }
276
+ return fileData;
277
+}
278
+
279
+export async function pasteFile(dest) {
280
+ const copied = await clipboard.readText();
281
+ const filename = copied.split(path.sep).pop();
282
+ if (!await fs.exists(copied) || await fs.exists(`${dest}${path.sep}${filename}`))
283
+ return
284
+ const fileData = await readFile(copied);
285
+
286
+ if (dest === copied) return;
287
+
288
+ if (!await dialog.confirm(`Are you sure you want to copy "${filename}" from "./${copied.split(path.sep).pop()}" into "./${dest.split(path.sep).pop()}?"`, {title: "Nucleus: Move File"})) {
289
+ return;
290
+ }
291
+ try {
292
+ await invoke("write_file", {path: dest, content: fileData.text, enc: fileData.encoding, hasBom: fileData.bom, spaces: fileData.spaces});
293
+ } catch (e) {
294
+ error(`Cannot create file in path ${dest}. Error: ${e}`, {file: "File.ts", line: 287});
295
+ }
296
+ addEditorTab(dest, filename);
297
+}
298
+
299
export function checkValidFileName(input: string) {
300
// refer to https://learn.microsoft.com/en-us/windows/win32/fileio/naming-a-file for invalid characters
301
// also https://gist.github.com/doctaphred/d01d05291546186941e1b7ddc02034d3
src/lib/FileTree.svelte
+4
-5
@@ -2,7 +2,7 @@
2
import FileTreeView from "./FileTree/FileTreeView.svelte";
3
import ContextMenu from "./utility/ContextMenu.svelte";
4
import { addEditorTab } from "./EditorTabList.svelte";
5
- import { openFolder } from "./File";
5
+ import { openFolder, pasteFile } from "./File";
6
import { clipboard } from "@tauri-apps/api";
7
import Button from "./utility/Button.svelte";
8
import { commands } from "../config/commands";
@@ -30,11 +30,10 @@
30
{name: "Open in File Explorer", shortcut: "", action: async () => commands.openInExplorer.command(path)},
31
{name: "New Folder...", shortcut: "", action: () => commands.createFolder.command(path)},
32
{name: "New File...", shortcut: "", action: () => {commands.createFile.command(path)}},
33
- {name: "Copy", shortcut: "Ctrl + C", action: () => {console.warn("Feature not implemented yet.")}},
33
+ {name: "Copy", shortcut: "Ctrl + C", action: async () => {await clipboard.writeText(path)}},
34
{name: "Cut", disabled: true, shortcut: "Ctrl + X", action: () => {console.warn("Feature not implemented yet.")}},
35
- {name: "Paste", shortcut: "Ctrl + X", disabled: true, action: () => {console.warn("Feature not implemented yet.")}},
35
+ {name: "Paste", shortcut: "Ctrl + V", action: async () => {await pasteFile(path)}},
36
{name: "Copy Filename", shortcut: "", action: async () => {await clipboard.writeText(name)}},
37
- {name: "Copy Absolute Path", shortcut: "", action: async () => {await clipboard.writeText(path)}},
37
{name: "Rename...", shortcut: "F2", disabled: true, action: () => {console.warn("Feature not implemented yet.")}},
38
{name: "Delete", disabled: true, shortcut: "Delete", action: () => {console.warn("Feature not implemented yet.")}}
39
]
@@ -92,4 +91,4 @@
91
font-size: 0.875rem;
92
}
93
}
95
-</style>
\ No newline at end of file
94
+</style>
src/lib/FileTree/FileTreeList.svelte
+4
-5
@@ -10,7 +10,7 @@
10
import Directory from "../../util/icons/Directory.svelte";
11
import {filetree} from "../FileTree.svelte";
12
import ContextMenu from "../utility/ContextMenu.svelte";
13
- import { moveFile, moveToTrash } from "../File";
13
+ import { moveFile, moveToTrash, pasteFile } from "../File";
14
import { clipboard } from "@tauri-apps/api";
15
import { onMount } from "svelte";
16
import { commands } from "../../config/commands";
@@ -40,11 +40,10 @@
40
{name: "Open in File Explorer", shortcut: commands.openInExplorer.keybind, action: async () => commands.openInExplorer.command(path)},
41
{name: "New Folder...", shortcut: "", action: () => commands.createFolder.command(path)},
42
{name: "New File...", shortcut: "", action: () => commands.createFile.command(path)},
43
- {name: "Copy", shortcut: "Ctrl + C", action: () => {console.warn("Feature not implemented yet.")}},
43
+ {name: "Copy", shortcut: "Ctrl + C", action: async () => {await clipboard.writeText(path)}},
44
{name: "Cut", disabled: isroot, shortcut: "Ctrl + X", action: () => {console.warn("Feature not implemented yet.")}},
45
- {name: "Paste", shortcut: "Ctrl + X", disabled: true, action: () => {console.warn("Feature not implemented yet.")}},
45
+ {name: "Paste", shortcut: "Ctrl + V", action: async () => {await pasteFile(path)}},
46
{name: "Copy Filename", shortcut: "", action: async () => {await clipboard.writeText(name)}},
47
- {name: "Copy Absolute Path", shortcut: "", action: async () => {await clipboard.writeText(path)}},
47
{name: "Rename...", disabled: isroot, shortcut: commands.renameFile.keybind, action: () => {commands.renameFile.command(name, path)}},
48
{name: "Delete", disabled: isroot, shortcut: "Delete", action: async () => {await moveToTrash(path)}}
49
]
@@ -234,4 +233,4 @@
233
.root > .tree-label {
234
font-weight: bold;
235
}
237
-</style>
\ No newline at end of file
236
+</style>
src/lib/FileTree/FileTreeNode.svelte
+2
-3
@@ -39,10 +39,9 @@
39
let contextmenu = false;
40
let contextmenuitems = [
41
{name: "Open in File Explorer", shortcut: commands.openInExplorer.keybind, action: async () => {commands.openInExplorer.command(path)}},
42
- {name: "Copy", shortcut: "Ctrl + C", action: () => {console.warn("Feature not implemented yet.")}},
42
+ {name: "Copy", shortcut: "Ctrl + C", action: async () => {await clipboard.writeText(path)}},
43
{name: "Cut", shortcut: "Ctrl + X", action: () => {console.warn("Feature not implemented yet.")}},
44
{name: "Copy Filename", shortcut: "", action: async () => {await clipboard.writeText(name)}},
45
- {name: "Copy Absolute Path", shortcut: "", action: async () => {await clipboard.writeText(path)}},
45
{name: "Edit", shortcut: "", action: () => {addEditorTab(path, name)}},
46
{name: "Rename...", shortcut: commands.renameFile.keybind, action: () => {commands.renameFile.command(name, path)}},
47
{name: "Delete", shortcut: "Delete", action: async () => {await moveToTrash(path)}}
@@ -142,4 +141,4 @@
141
display: flex;
142
margin-right: 15px;
143
}
145
-</style>
\ No newline at end of file
144
+</style>