diff --git a/src-tauri/src/commands.rs b/src-tauri/src/commands.rs index f832d6d..62c0a91 100644 --- a/src-tauri/src/commands.rs +++ b/src-tauri/src/commands.rs @@ -463,6 +463,78 @@ pub async fn write_file_content(path: String, content: String) -> Result<(), Str .map_err(|e| format!("Failed to write file: {}", e)) } +#[tauri::command] +pub async fn create_file(path: String) -> Result<(), String> { + use std::fs::File; + use std::path::Path; + + let file_path = Path::new(&path); + + if file_path.exists() { + return Err("File already exists".to_string()); + } + + File::create(file_path).map_err(|e| format!("Failed to create file: {}", e))?; + + Ok(()) +} + +#[tauri::command] +pub async fn create_directory(path: String) -> Result<(), String> { + use std::fs; + use std::path::Path; + + let dir_path = Path::new(&path); + + if dir_path.exists() { + return Err("Directory already exists".to_string()); + } + + fs::create_dir_all(dir_path).map_err(|e| format!("Failed to create directory: {}", e))?; + + Ok(()) +} + +#[tauri::command] +pub async fn delete_file(path: String) -> Result<(), String> { + use std::fs; + use std::path::Path; + + let file_path = Path::new(&path); + + if !file_path.exists() { + return Err("File does not exist".to_string()); + } + + if file_path.is_dir() { + return Err("Path is a directory, use delete_directory instead".to_string()); + } + + fs::remove_file(file_path).map_err(|e| format!("Failed to delete file: {}", e))?; + + Ok(()) +} + +#[tauri::command] +pub async fn delete_directory(path: String) -> Result<(), String> { + use std::fs; + use std::path::Path; + + let dir_path = Path::new(&path); + + if !dir_path.exists() { + return Err("Directory does not exist".to_string()); + } + + if !dir_path.is_dir() { + return Err("Path is not a directory".to_string()); + } + + fs::remove_dir_all(dir_path).map_err(|e| format!("Failed to delete directory: {}", e))?; + + Ok(()) +} + #[cfg(test)] mod tests { use super::*; diff --git a/src-tauri/src/lib.rs b/src-tauri/src/lib.rs index 2c8b9de..0d0901e 100644 --- a/src-tauri/src/lib.rs +++ b/src-tauri/src/lib.rs @@ -154,6 +154,10 @@ pub fn run() { list_directory, read_file_content, write_file_content, + create_file, + create_directory, + delete_file, + delete_directory, ]) .run(tauri::generate_context!()) .expect("error while running tauri application"); diff --git a/src/lib/components/KeyboardShortcutsModal.svelte b/src/lib/components/KeyboardShortcutsModal.svelte index e87e04b..fb17d78 100644 --- a/src/lib/components/KeyboardShortcutsModal.svelte +++ b/src/lib/components/KeyboardShortcutsModal.svelte @@ -34,6 +34,8 @@ { keys: ["Ctrl", "B"], description: "Toggle file browser" }, { keys: ["Ctrl", "S"], description: "Save current file" }, { keys: ["Ctrl", "W"], description: "Close current tab" }, + { keys: ["Ctrl", "N"], description: "New file" }, + { keys: ["Right-click"], description: "Context menu (New/Delete)" }, ], }, { diff --git a/src/lib/components/editor/ConfirmDialog.svelte b/src/lib/components/editor/ConfirmDialog.svelte new file mode 100644 index 0000000..f436a5e --- /dev/null +++ b/src/lib/components/editor/ConfirmDialog.svelte @@ -0,0 +1,60 @@ + + + + + +
+ +
e.stopPropagation()} + > +

{title}

+

{message}

+ +
+ + +
+
+
diff --git a/src/lib/components/editor/FileBrowser.svelte b/src/lib/components/editor/FileBrowser.svelte index 3e0b0ac..5c72801 100644 --- a/src/lib/components/editor/FileBrowser.svelte +++ b/src/lib/components/editor/FileBrowser.svelte @@ -1,36 +1,169 @@ -
+ +
handleContextMenu(e, null)}>
Files - +
+ + + +
@@ -63,13 +196,60 @@ {:else}
{#each $fileTree as entry (entry.path)} - + {/each}
{/if}
+{#if contextMenu.show} + +{/if} + +{#if dialog.type === "newFile"} + +{/if} + +{#if dialog.type === "newFolder"} + +{/if} + +{#if dialog.type === "delete" && dialog.targetEntry} + +{/if} +