在文件树上支持右键添加文件和添加目录操作
This commit is contained in:
@@ -2555,6 +2555,69 @@ pub async fn delete_file_tree_entry(
|
|||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#[tauri::command]
|
||||||
|
pub async fn create_file_tree_entry(
|
||||||
|
root_path: String,
|
||||||
|
path: String,
|
||||||
|
name: String,
|
||||||
|
kind: String,
|
||||||
|
) -> Result<String, AppCommandError> {
|
||||||
|
let root = PathBuf::from(&root_path);
|
||||||
|
if !root.exists() || !root.is_dir() {
|
||||||
|
return Err(AppCommandError::not_found("Folder does not exist"));
|
||||||
|
}
|
||||||
|
|
||||||
|
let validated_name = validate_new_name(&name)?;
|
||||||
|
|
||||||
|
let parent_dir = if path.is_empty() {
|
||||||
|
root.clone()
|
||||||
|
} else {
|
||||||
|
let resolved = resolve_tree_path(&root, &path)?;
|
||||||
|
if !resolved.exists() {
|
||||||
|
return Err(AppCommandError::not_found("Parent path does not exist"));
|
||||||
|
}
|
||||||
|
if resolved.is_file() {
|
||||||
|
resolved
|
||||||
|
.parent()
|
||||||
|
.map(|p| p.to_path_buf())
|
||||||
|
.ok_or_else(|| AppCommandError::invalid_input("Cannot determine parent directory"))?
|
||||||
|
} else {
|
||||||
|
resolved
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
let target = parent_dir.join(validated_name);
|
||||||
|
if target.exists() {
|
||||||
|
return Err(AppCommandError::already_exists(
|
||||||
|
"A file or directory with this name already exists",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
|
||||||
|
match kind.as_str() {
|
||||||
|
"file" => {
|
||||||
|
std::fs::File::create(&target).map_err(AppCommandError::io)?;
|
||||||
|
}
|
||||||
|
"dir" => {
|
||||||
|
std::fs::create_dir(&target).map_err(AppCommandError::io)?;
|
||||||
|
}
|
||||||
|
_ => {
|
||||||
|
return Err(AppCommandError::invalid_input(
|
||||||
|
"Kind must be 'file' or 'dir'",
|
||||||
|
));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
let rel = target
|
||||||
|
.strip_prefix(&root)
|
||||||
|
.map_err(|e| {
|
||||||
|
AppCommandError::invalid_input("Failed to compute relative path")
|
||||||
|
.with_detail(e.to_string())
|
||||||
|
})?
|
||||||
|
.to_string_lossy()
|
||||||
|
.to_string();
|
||||||
|
Ok(rel)
|
||||||
|
}
|
||||||
|
|
||||||
#[tauri::command]
|
#[tauri::command]
|
||||||
pub async fn git_log(
|
pub async fn git_log(
|
||||||
path: String,
|
path: String,
|
||||||
|
|||||||
@@ -218,6 +218,7 @@ pub fn run() {
|
|||||||
folders::save_file_copy,
|
folders::save_file_copy,
|
||||||
folders::rename_file_tree_entry,
|
folders::rename_file_tree_entry,
|
||||||
folders::delete_file_tree_entry,
|
folders::delete_file_tree_entry,
|
||||||
|
folders::create_file_tree_entry,
|
||||||
folders::git_log,
|
folders::git_log,
|
||||||
folders::git_commit_branches,
|
folders::git_commit_branches,
|
||||||
windows::open_folder_window,
|
windows::open_folder_window,
|
||||||
|
|||||||
@@ -21,6 +21,7 @@ import { useTabContext } from "@/contexts/tab-context"
|
|||||||
import { useTerminalContext } from "@/contexts/terminal-context"
|
import { useTerminalContext } from "@/contexts/terminal-context"
|
||||||
import { useWorkspaceContext } from "@/contexts/workspace-context"
|
import { useWorkspaceContext } from "@/contexts/workspace-context"
|
||||||
import {
|
import {
|
||||||
|
createFileTreeEntry,
|
||||||
deleteFileTreeEntry,
|
deleteFileTreeEntry,
|
||||||
gitAddFiles,
|
gitAddFiles,
|
||||||
getGitBranch,
|
getGitBranch,
|
||||||
@@ -419,6 +420,7 @@ interface RenderNodeProps {
|
|||||||
onOpenDirInTerminal: (dirPath: string, fileName: string) => Promise<void>
|
onOpenDirInTerminal: (dirPath: string, fileName: string) => Promise<void>
|
||||||
onRequestAddToVcs: (target: FileActionTarget) => void
|
onRequestAddToVcs: (target: FileActionTarget) => void
|
||||||
onRequestRename: (target: FileActionTarget) => void
|
onRequestRename: (target: FileActionTarget) => void
|
||||||
|
onRequestCreate: (parentPath: string, kind: "file" | "dir") => void
|
||||||
onRequestDelete: (target: FileActionTarget) => void
|
onRequestDelete: (target: FileActionTarget) => void
|
||||||
onRefresh: () => void
|
onRefresh: () => void
|
||||||
}
|
}
|
||||||
@@ -441,6 +443,7 @@ function RenderNode({
|
|||||||
onRequestRollback,
|
onRequestRollback,
|
||||||
onOpenDirInTerminal,
|
onOpenDirInTerminal,
|
||||||
onRequestAddToVcs,
|
onRequestAddToVcs,
|
||||||
|
onRequestCreate,
|
||||||
onRequestRename,
|
onRequestRename,
|
||||||
onRequestDelete,
|
onRequestDelete,
|
||||||
onRefresh,
|
onRefresh,
|
||||||
@@ -507,6 +510,21 @@ function RenderNode({
|
|||||||
>
|
>
|
||||||
{t("attachToCurrentSession")}
|
{t("attachToCurrentSession")}
|
||||||
</ContextMenuItem>
|
</ContextMenuItem>
|
||||||
|
<ContextMenuSub>
|
||||||
|
<ContextMenuSubTrigger>{t("new")}</ContextMenuSubTrigger>
|
||||||
|
<ContextMenuSubContent>
|
||||||
|
<ContextMenuItem
|
||||||
|
onSelect={() => onRequestCreate(node.path, "file")}
|
||||||
|
>
|
||||||
|
{t("newFile")}
|
||||||
|
</ContextMenuItem>
|
||||||
|
<ContextMenuItem
|
||||||
|
onSelect={() => onRequestCreate(node.path, "dir")}
|
||||||
|
>
|
||||||
|
{t("newDirectory")}
|
||||||
|
</ContextMenuItem>
|
||||||
|
</ContextMenuSubContent>
|
||||||
|
</ContextMenuSub>
|
||||||
<ContextMenuSub>
|
<ContextMenuSub>
|
||||||
<ContextMenuSubTrigger disabled={isGitMenuDisabled}>
|
<ContextMenuSubTrigger disabled={isGitMenuDisabled}>
|
||||||
{t("git")}
|
{t("git")}
|
||||||
@@ -629,6 +647,7 @@ function RenderNode({
|
|||||||
onRequestCompareWithBranch={onRequestCompareWithBranch}
|
onRequestCompareWithBranch={onRequestCompareWithBranch}
|
||||||
onRequestRollback={onRequestRollback}
|
onRequestRollback={onRequestRollback}
|
||||||
onOpenDirInTerminal={onOpenDirInTerminal}
|
onOpenDirInTerminal={onOpenDirInTerminal}
|
||||||
|
onRequestCreate={onRequestCreate}
|
||||||
onRequestAddToVcs={onRequestAddToVcs}
|
onRequestAddToVcs={onRequestAddToVcs}
|
||||||
onRequestRename={onRequestRename}
|
onRequestRename={onRequestRename}
|
||||||
onRequestDelete={onRequestDelete}
|
onRequestDelete={onRequestDelete}
|
||||||
@@ -639,6 +658,19 @@ function RenderNode({
|
|||||||
</FileTreeFolder>
|
</FileTreeFolder>
|
||||||
</ContextMenuTrigger>
|
</ContextMenuTrigger>
|
||||||
<ContextMenuContent>
|
<ContextMenuContent>
|
||||||
|
<ContextMenuSub>
|
||||||
|
<ContextMenuSubTrigger>{t("new")}</ContextMenuSubTrigger>
|
||||||
|
<ContextMenuSubContent>
|
||||||
|
<ContextMenuItem
|
||||||
|
onSelect={() => onRequestCreate(node.path, "file")}
|
||||||
|
>
|
||||||
|
{t("newFile")}
|
||||||
|
</ContextMenuItem>
|
||||||
|
<ContextMenuItem onSelect={() => onRequestCreate(node.path, "dir")}>
|
||||||
|
{t("newDirectory")}
|
||||||
|
</ContextMenuItem>
|
||||||
|
</ContextMenuSubContent>
|
||||||
|
</ContextMenuSub>
|
||||||
<ContextMenuSub>
|
<ContextMenuSub>
|
||||||
<ContextMenuSubTrigger disabled={isGitMenuDisabled}>
|
<ContextMenuSubTrigger disabled={isGitMenuDisabled}>
|
||||||
{t("git")}
|
{t("git")}
|
||||||
@@ -736,6 +768,10 @@ export function FileTreeTab() {
|
|||||||
)
|
)
|
||||||
const [renameValue, setRenameValue] = useState("")
|
const [renameValue, setRenameValue] = useState("")
|
||||||
const [renaming, setRenaming] = useState(false)
|
const [renaming, setRenaming] = useState(false)
|
||||||
|
const [createParentPath, setCreateParentPath] = useState<string | null>(null)
|
||||||
|
const [createKind, setCreateKind] = useState<"file" | "dir">("file")
|
||||||
|
const [createName, setCreateName] = useState("")
|
||||||
|
const [creating, setCreating] = useState(false)
|
||||||
const [deleteTarget, setDeleteTarget] = useState<FileActionTarget | null>(
|
const [deleteTarget, setDeleteTarget] = useState<FileActionTarget | null>(
|
||||||
null
|
null
|
||||||
)
|
)
|
||||||
@@ -1139,6 +1175,15 @@ export function FileTreeTab() {
|
|||||||
})
|
})
|
||||||
}, [folder, t])
|
}, [folder, t])
|
||||||
|
|
||||||
|
const handleRequestCreate = useCallback(
|
||||||
|
(parentPath: string, kind: "file" | "dir") => {
|
||||||
|
setCreateParentPath(parentPath)
|
||||||
|
setCreateKind(kind)
|
||||||
|
setCreateName("")
|
||||||
|
},
|
||||||
|
[]
|
||||||
|
)
|
||||||
|
|
||||||
const handleRequestRename = useCallback((target: FileActionTarget) => {
|
const handleRequestRename = useCallback((target: FileActionTarget) => {
|
||||||
setRenameTarget(target)
|
setRenameTarget(target)
|
||||||
setRenameValue(target.name)
|
setRenameValue(target.name)
|
||||||
@@ -1516,6 +1561,33 @@ export function FileTreeTab() {
|
|||||||
]
|
]
|
||||||
)
|
)
|
||||||
|
|
||||||
|
const handleCreateConfirm = useCallback(async () => {
|
||||||
|
if (!folder?.path || createParentPath === null) return
|
||||||
|
const trimmedName = createName.trim()
|
||||||
|
if (!trimmedName) {
|
||||||
|
setCreateParentPath(null)
|
||||||
|
return
|
||||||
|
}
|
||||||
|
|
||||||
|
setCreating(true)
|
||||||
|
try {
|
||||||
|
await createFileTreeEntry(
|
||||||
|
folder.path,
|
||||||
|
createParentPath,
|
||||||
|
trimmedName,
|
||||||
|
createKind
|
||||||
|
)
|
||||||
|
setCreateParentPath(null)
|
||||||
|
setCreateName("")
|
||||||
|
await fetchTree()
|
||||||
|
} catch (error) {
|
||||||
|
const message = error instanceof Error ? error.message : String(error)
|
||||||
|
toast.error(t("toasts.createFailed"), { description: message })
|
||||||
|
} finally {
|
||||||
|
setCreating(false)
|
||||||
|
}
|
||||||
|
}, [createKind, createName, createParentPath, fetchTree, folder?.path, t])
|
||||||
|
|
||||||
const handleRenameConfirm = useCallback(async () => {
|
const handleRenameConfirm = useCallback(async () => {
|
||||||
if (!folder?.path || !renameTarget) return
|
if (!folder?.path || !renameTarget) return
|
||||||
const nextName = renameValue.trim()
|
const nextName = renameValue.trim()
|
||||||
@@ -2074,6 +2146,7 @@ export function FileTreeTab() {
|
|||||||
}
|
}
|
||||||
onRequestRollback={handleRequestRollback}
|
onRequestRollback={handleRequestRollback}
|
||||||
onOpenDirInTerminal={handleOpenDirInTerminal}
|
onOpenDirInTerminal={handleOpenDirInTerminal}
|
||||||
|
onRequestCreate={handleRequestCreate}
|
||||||
onRequestAddToVcs={handleAddToVcs}
|
onRequestAddToVcs={handleAddToVcs}
|
||||||
onRequestRename={handleRequestRename}
|
onRequestRename={handleRequestRename}
|
||||||
onRequestDelete={handleRequestDelete}
|
onRequestDelete={handleRequestDelete}
|
||||||
@@ -2083,6 +2156,21 @@ export function FileTreeTab() {
|
|||||||
</FileTreeFolder>
|
</FileTreeFolder>
|
||||||
</ContextMenuTrigger>
|
</ContextMenuTrigger>
|
||||||
<ContextMenuContent>
|
<ContextMenuContent>
|
||||||
|
<ContextMenuSub>
|
||||||
|
<ContextMenuSubTrigger>{t("new")}</ContextMenuSubTrigger>
|
||||||
|
<ContextMenuSubContent>
|
||||||
|
<ContextMenuItem
|
||||||
|
onSelect={() => handleRequestCreate("", "file")}
|
||||||
|
>
|
||||||
|
{t("newFile")}
|
||||||
|
</ContextMenuItem>
|
||||||
|
<ContextMenuItem
|
||||||
|
onSelect={() => handleRequestCreate("", "dir")}
|
||||||
|
>
|
||||||
|
{t("newDirectory")}
|
||||||
|
</ContextMenuItem>
|
||||||
|
</ContextMenuSubContent>
|
||||||
|
</ContextMenuSub>
|
||||||
<ContextMenuSub>
|
<ContextMenuSub>
|
||||||
<ContextMenuSubTrigger disabled={!gitEnabled}>
|
<ContextMenuSubTrigger disabled={!gitEnabled}>
|
||||||
{t("git")}
|
{t("git")}
|
||||||
@@ -2165,6 +2253,17 @@ export function FileTreeTab() {
|
|||||||
</div>
|
</div>
|
||||||
</ContextMenuTrigger>
|
</ContextMenuTrigger>
|
||||||
<ContextMenuContent>
|
<ContextMenuContent>
|
||||||
|
<ContextMenuSub>
|
||||||
|
<ContextMenuSubTrigger>{t("new")}</ContextMenuSubTrigger>
|
||||||
|
<ContextMenuSubContent>
|
||||||
|
<ContextMenuItem onSelect={() => handleRequestCreate("", "file")}>
|
||||||
|
{t("newFile")}
|
||||||
|
</ContextMenuItem>
|
||||||
|
<ContextMenuItem onSelect={() => handleRequestCreate("", "dir")}>
|
||||||
|
{t("newDirectory")}
|
||||||
|
</ContextMenuItem>
|
||||||
|
</ContextMenuSubContent>
|
||||||
|
</ContextMenuSub>
|
||||||
<ContextMenuItem
|
<ContextMenuItem
|
||||||
onSelect={() => {
|
onSelect={() => {
|
||||||
void fetchTree()
|
void fetchTree()
|
||||||
@@ -2175,6 +2274,68 @@ export function FileTreeTab() {
|
|||||||
</ContextMenuContent>
|
</ContextMenuContent>
|
||||||
</ContextMenu>
|
</ContextMenu>
|
||||||
|
|
||||||
|
<Dialog
|
||||||
|
open={createParentPath !== null}
|
||||||
|
onOpenChange={(open) => {
|
||||||
|
if (open) return
|
||||||
|
setCreateParentPath(null)
|
||||||
|
setCreateName("")
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
<DialogContent>
|
||||||
|
<DialogHeader>
|
||||||
|
<DialogTitle>
|
||||||
|
{createKind === "dir"
|
||||||
|
? t("createDialog.newDirectory")
|
||||||
|
: t("createDialog.newFile")}
|
||||||
|
</DialogTitle>
|
||||||
|
<DialogDescription>
|
||||||
|
{t("createDialog.description", {
|
||||||
|
kind:
|
||||||
|
createKind === "dir"
|
||||||
|
? t("newDirectory").toLowerCase()
|
||||||
|
: t("newFile").toLowerCase(),
|
||||||
|
})}
|
||||||
|
</DialogDescription>
|
||||||
|
</DialogHeader>
|
||||||
|
<form
|
||||||
|
onSubmit={(event) => {
|
||||||
|
event.preventDefault()
|
||||||
|
void handleCreateConfirm()
|
||||||
|
}}
|
||||||
|
className="space-y-4"
|
||||||
|
>
|
||||||
|
<Input
|
||||||
|
value={createName}
|
||||||
|
onChange={(event) => setCreateName(event.target.value)}
|
||||||
|
autoFocus
|
||||||
|
disabled={creating}
|
||||||
|
placeholder={
|
||||||
|
createKind === "dir"
|
||||||
|
? t("createDialog.placeholderDirectory")
|
||||||
|
: t("createDialog.placeholderFile")
|
||||||
|
}
|
||||||
|
/>
|
||||||
|
<DialogFooter>
|
||||||
|
<Button
|
||||||
|
type="button"
|
||||||
|
variant="outline"
|
||||||
|
disabled={creating}
|
||||||
|
onClick={() => {
|
||||||
|
setCreateParentPath(null)
|
||||||
|
setCreateName("")
|
||||||
|
}}
|
||||||
|
>
|
||||||
|
{tCommon("cancel")}
|
||||||
|
</Button>
|
||||||
|
<Button type="submit" disabled={creating || !createName.trim()}>
|
||||||
|
{tCommon("create")}
|
||||||
|
</Button>
|
||||||
|
</DialogFooter>
|
||||||
|
</form>
|
||||||
|
</DialogContent>
|
||||||
|
</Dialog>
|
||||||
|
|
||||||
<Dialog
|
<Dialog
|
||||||
open={Boolean(renameTarget)}
|
open={Boolean(renameTarget)}
|
||||||
onOpenChange={(open) => {
|
onOpenChange={(open) => {
|
||||||
@@ -2473,7 +2634,12 @@ export function FileTreeTab() {
|
|||||||
<Collapsible key={remoteName}>
|
<Collapsible key={remoteName}>
|
||||||
<CollapsibleTrigger className="flex w-full items-center gap-2.5 rounded-xl px-2 py-1.5 pl-5 text-sm hover:bg-accent hover:text-accent-foreground select-none outline-hidden">
|
<CollapsibleTrigger className="flex w-full items-center gap-2.5 rounded-xl px-2 py-1.5 pl-5 text-sm hover:bg-accent hover:text-accent-foreground select-none outline-hidden">
|
||||||
<ChevronRight className="h-3 w-3 shrink-0 transition-transform [[data-state=open]>&]:rotate-90" />
|
<ChevronRight className="h-3 w-3 shrink-0 transition-transform [[data-state=open]>&]:rotate-90" />
|
||||||
{remoteName} ({groupedCompareRemoteBranches[remoteName].length})
|
{remoteName} (
|
||||||
|
{
|
||||||
|
groupedCompareRemoteBranches[remoteName]
|
||||||
|
.length
|
||||||
|
}
|
||||||
|
)
|
||||||
</CollapsibleTrigger>
|
</CollapsibleTrigger>
|
||||||
<CollapsibleContent className="space-y-1 pt-1 pl-3">
|
<CollapsibleContent className="space-y-1 pt-1 pl-3">
|
||||||
{groupedCompareRemoteBranches[remoteName].map(
|
{groupedCompareRemoteBranches[remoteName].map(
|
||||||
@@ -2489,7 +2655,9 @@ export function FileTreeTab() {
|
|||||||
}}
|
}}
|
||||||
disabled={comparing}
|
disabled={comparing}
|
||||||
>
|
>
|
||||||
{branch.substring(remoteName.length + 1)}
|
{branch.substring(
|
||||||
|
remoteName.length + 1
|
||||||
|
)}
|
||||||
</Button>
|
</Button>
|
||||||
)
|
)
|
||||||
)}
|
)}
|
||||||
|
|||||||
@@ -967,6 +967,9 @@
|
|||||||
"attachToCurrentSession": "إرفاق بالجلسة الحالية",
|
"attachToCurrentSession": "إرفاق بالجلسة الحالية",
|
||||||
"compareWithBranch": "المقارنة مع الفرع...",
|
"compareWithBranch": "المقارنة مع الفرع...",
|
||||||
"reloadFromDisk": "إعادة التحميل من القرص",
|
"reloadFromDisk": "إعادة التحميل من القرص",
|
||||||
|
"new": "جديد",
|
||||||
|
"newFile": "ملف",
|
||||||
|
"newDirectory": "مجلد",
|
||||||
"openIn": "فتح في",
|
"openIn": "فتح في",
|
||||||
"openInTerminal": "فتح في الطرفية",
|
"openInTerminal": "فتح في الطرفية",
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -996,7 +999,15 @@
|
|||||||
"rolledBackFiles": "{count, plural, one {تم التراجع عن ملف واحد} other {تم التراجع عن # ملفات}}",
|
"rolledBackFiles": "{count, plural, one {تم التراجع عن ملف واحد} other {تم التراجع عن # ملفات}}",
|
||||||
"savedAsCopy": "تم الحفظ كنسخة",
|
"savedAsCopy": "تم الحفظ كنسخة",
|
||||||
"saveCopyFailed": "فشل الحفظ كنسخة",
|
"saveCopyFailed": "فشل الحفظ كنسخة",
|
||||||
"watchStartFailed": "فشل بدء مراقبة الملفات"
|
"watchStartFailed": "فشل بدء مراقبة الملفات",
|
||||||
|
"createFailed": "فشل في الإنشاء"
|
||||||
|
},
|
||||||
|
"createDialog": {
|
||||||
|
"newFile": "ملف جديد",
|
||||||
|
"newDirectory": "مجلد جديد",
|
||||||
|
"description": "أدخل اسمًا لـ{kind} الجديد.",
|
||||||
|
"placeholderFile": "file-name.ext",
|
||||||
|
"placeholderDirectory": "folder-name"
|
||||||
},
|
},
|
||||||
"renameDialog": {
|
"renameDialog": {
|
||||||
"renameDirectory": "إعادة تسمية المجلد",
|
"renameDirectory": "إعادة تسمية المجلد",
|
||||||
|
|||||||
@@ -967,6 +967,9 @@
|
|||||||
"attachToCurrentSession": "An aktuelle Sitzung anhängen",
|
"attachToCurrentSession": "An aktuelle Sitzung anhängen",
|
||||||
"compareWithBranch": "Mit Branch vergleichen...",
|
"compareWithBranch": "Mit Branch vergleichen...",
|
||||||
"reloadFromDisk": "Von Datenträger neu laden",
|
"reloadFromDisk": "Von Datenträger neu laden",
|
||||||
|
"new": "Neu",
|
||||||
|
"newFile": "Datei",
|
||||||
|
"newDirectory": "Verzeichnis",
|
||||||
"openIn": "Öffnen in",
|
"openIn": "Öffnen in",
|
||||||
"openInTerminal": "Im Terminal öffnen",
|
"openInTerminal": "Im Terminal öffnen",
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -996,7 +999,15 @@
|
|||||||
"rolledBackFiles": "{count, plural, one {# Datei zurückgesetzt} other {# Dateien zurückgesetzt}}",
|
"rolledBackFiles": "{count, plural, one {# Datei zurückgesetzt} other {# Dateien zurückgesetzt}}",
|
||||||
"savedAsCopy": "Als Kopie gespeichert",
|
"savedAsCopy": "Als Kopie gespeichert",
|
||||||
"saveCopyFailed": "Speichern als Kopie fehlgeschlagen",
|
"saveCopyFailed": "Speichern als Kopie fehlgeschlagen",
|
||||||
"watchStartFailed": "Dateiwatch konnte nicht gestartet werden"
|
"watchStartFailed": "Dateiwatch konnte nicht gestartet werden",
|
||||||
|
"createFailed": "Erstellen fehlgeschlagen"
|
||||||
|
},
|
||||||
|
"createDialog": {
|
||||||
|
"newFile": "Neue Datei",
|
||||||
|
"newDirectory": "Neues Verzeichnis",
|
||||||
|
"description": "Geben Sie einen Namen für das neue {kind} ein.",
|
||||||
|
"placeholderFile": "file-name.ext",
|
||||||
|
"placeholderDirectory": "folder-name"
|
||||||
},
|
},
|
||||||
"renameDialog": {
|
"renameDialog": {
|
||||||
"renameDirectory": "Verzeichnis umbenennen",
|
"renameDirectory": "Verzeichnis umbenennen",
|
||||||
|
|||||||
@@ -967,6 +967,9 @@
|
|||||||
"attachToCurrentSession": "Attach to current session",
|
"attachToCurrentSession": "Attach to current session",
|
||||||
"compareWithBranch": "Compare with branch...",
|
"compareWithBranch": "Compare with branch...",
|
||||||
"reloadFromDisk": "Reload from disk",
|
"reloadFromDisk": "Reload from disk",
|
||||||
|
"new": "New",
|
||||||
|
"newFile": "File",
|
||||||
|
"newDirectory": "Directory",
|
||||||
"openIn": "Open in",
|
"openIn": "Open in",
|
||||||
"openInTerminal": "Open in terminal",
|
"openInTerminal": "Open in terminal",
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -996,7 +999,15 @@
|
|||||||
"rolledBackFiles": "Rolled back {count, plural, one {# file} other {# files}}",
|
"rolledBackFiles": "Rolled back {count, plural, one {# file} other {# files}}",
|
||||||
"savedAsCopy": "Saved as a copy",
|
"savedAsCopy": "Saved as a copy",
|
||||||
"saveCopyFailed": "Failed to save as copy",
|
"saveCopyFailed": "Failed to save as copy",
|
||||||
"watchStartFailed": "Failed to start file watch"
|
"watchStartFailed": "Failed to start file watch",
|
||||||
|
"createFailed": "Failed to create"
|
||||||
|
},
|
||||||
|
"createDialog": {
|
||||||
|
"newFile": "New file",
|
||||||
|
"newDirectory": "New directory",
|
||||||
|
"description": "Enter a name for the new {kind}.",
|
||||||
|
"placeholderFile": "file-name.ext",
|
||||||
|
"placeholderDirectory": "folder-name"
|
||||||
},
|
},
|
||||||
"renameDialog": {
|
"renameDialog": {
|
||||||
"renameDirectory": "Rename directory",
|
"renameDirectory": "Rename directory",
|
||||||
|
|||||||
@@ -967,6 +967,9 @@
|
|||||||
"attachToCurrentSession": "Adjuntar a la sesión actual",
|
"attachToCurrentSession": "Adjuntar a la sesión actual",
|
||||||
"compareWithBranch": "Comparar con rama...",
|
"compareWithBranch": "Comparar con rama...",
|
||||||
"reloadFromDisk": "Recargar desde disco",
|
"reloadFromDisk": "Recargar desde disco",
|
||||||
|
"new": "Nuevo",
|
||||||
|
"newFile": "Archivo",
|
||||||
|
"newDirectory": "Directorio",
|
||||||
"openIn": "Abrir en",
|
"openIn": "Abrir en",
|
||||||
"openInTerminal": "Abrir en terminal",
|
"openInTerminal": "Abrir en terminal",
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -996,7 +999,15 @@
|
|||||||
"rolledBackFiles": "{count, plural, one {Se revirtió # archivo} other {Se revirtieron # archivos}}",
|
"rolledBackFiles": "{count, plural, one {Se revirtió # archivo} other {Se revirtieron # archivos}}",
|
||||||
"savedAsCopy": "Guardado como copia",
|
"savedAsCopy": "Guardado como copia",
|
||||||
"saveCopyFailed": "No se pudo guardar como copia",
|
"saveCopyFailed": "No se pudo guardar como copia",
|
||||||
"watchStartFailed": "No se pudo iniciar la vigilancia de archivos"
|
"watchStartFailed": "No se pudo iniciar la vigilancia de archivos",
|
||||||
|
"createFailed": "Error al crear"
|
||||||
|
},
|
||||||
|
"createDialog": {
|
||||||
|
"newFile": "Nuevo archivo",
|
||||||
|
"newDirectory": "Nuevo directorio",
|
||||||
|
"description": "Ingrese un nombre para el nuevo {kind}.",
|
||||||
|
"placeholderFile": "file-name.ext",
|
||||||
|
"placeholderDirectory": "folder-name"
|
||||||
},
|
},
|
||||||
"renameDialog": {
|
"renameDialog": {
|
||||||
"renameDirectory": "Renombrar directorio",
|
"renameDirectory": "Renombrar directorio",
|
||||||
|
|||||||
@@ -967,6 +967,9 @@
|
|||||||
"attachToCurrentSession": "Attacher à la session actuelle",
|
"attachToCurrentSession": "Attacher à la session actuelle",
|
||||||
"compareWithBranch": "Comparer avec la branche...",
|
"compareWithBranch": "Comparer avec la branche...",
|
||||||
"reloadFromDisk": "Recharger depuis le disque",
|
"reloadFromDisk": "Recharger depuis le disque",
|
||||||
|
"new": "Nouveau",
|
||||||
|
"newFile": "Fichier",
|
||||||
|
"newDirectory": "Répertoire",
|
||||||
"openIn": "Ouvrir dans",
|
"openIn": "Ouvrir dans",
|
||||||
"openInTerminal": "Ouvrir dans le terminal",
|
"openInTerminal": "Ouvrir dans le terminal",
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -996,7 +999,15 @@
|
|||||||
"rolledBackFiles": "{count, plural, one {# fichier annulé} other {# fichiers annulés}}",
|
"rolledBackFiles": "{count, plural, one {# fichier annulé} other {# fichiers annulés}}",
|
||||||
"savedAsCopy": "Enregistré en copie",
|
"savedAsCopy": "Enregistré en copie",
|
||||||
"saveCopyFailed": "Échec de l'enregistrement en copie",
|
"saveCopyFailed": "Échec de l'enregistrement en copie",
|
||||||
"watchStartFailed": "Échec du démarrage de la surveillance de fichiers"
|
"watchStartFailed": "Échec du démarrage de la surveillance de fichiers",
|
||||||
|
"createFailed": "Échec de la création"
|
||||||
|
},
|
||||||
|
"createDialog": {
|
||||||
|
"newFile": "Nouveau fichier",
|
||||||
|
"newDirectory": "Nouveau répertoire",
|
||||||
|
"description": "Entrez un nom pour le nouveau {kind}.",
|
||||||
|
"placeholderFile": "file-name.ext",
|
||||||
|
"placeholderDirectory": "folder-name"
|
||||||
},
|
},
|
||||||
"renameDialog": {
|
"renameDialog": {
|
||||||
"renameDirectory": "Renommer le dossier",
|
"renameDirectory": "Renommer le dossier",
|
||||||
|
|||||||
@@ -967,6 +967,9 @@
|
|||||||
"attachToCurrentSession": "現在のセッションに添付",
|
"attachToCurrentSession": "現在のセッションに添付",
|
||||||
"compareWithBranch": "ブランチと比較...",
|
"compareWithBranch": "ブランチと比較...",
|
||||||
"reloadFromDisk": "ディスクから再読み込み",
|
"reloadFromDisk": "ディスクから再読み込み",
|
||||||
|
"new": "新規作成",
|
||||||
|
"newFile": "ファイル",
|
||||||
|
"newDirectory": "ディレクトリ",
|
||||||
"openIn": "で開く",
|
"openIn": "で開く",
|
||||||
"openInTerminal": "ターミナルで開く",
|
"openInTerminal": "ターミナルで開く",
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -996,7 +999,15 @@
|
|||||||
"rolledBackFiles": "{count, plural, one {# 件のファイルをロールバックしました} other {# 件のファイルをロールバックしました}}",
|
"rolledBackFiles": "{count, plural, one {# 件のファイルをロールバックしました} other {# 件のファイルをロールバックしました}}",
|
||||||
"savedAsCopy": "コピーとして保存しました",
|
"savedAsCopy": "コピーとして保存しました",
|
||||||
"saveCopyFailed": "コピーとして保存できませんでした",
|
"saveCopyFailed": "コピーとして保存できませんでした",
|
||||||
"watchStartFailed": "ファイル監視の開始に失敗しました"
|
"watchStartFailed": "ファイル監視の開始に失敗しました",
|
||||||
|
"createFailed": "作成に失敗しました"
|
||||||
|
},
|
||||||
|
"createDialog": {
|
||||||
|
"newFile": "新規ファイル",
|
||||||
|
"newDirectory": "新規ディレクトリ",
|
||||||
|
"description": "新しい{kind}の名前を入力してください。",
|
||||||
|
"placeholderFile": "file-name.ext",
|
||||||
|
"placeholderDirectory": "folder-name"
|
||||||
},
|
},
|
||||||
"renameDialog": {
|
"renameDialog": {
|
||||||
"renameDirectory": "ディレクトリ名を変更",
|
"renameDirectory": "ディレクトリ名を変更",
|
||||||
|
|||||||
@@ -967,6 +967,9 @@
|
|||||||
"attachToCurrentSession": "현재 세션에 연결",
|
"attachToCurrentSession": "현재 세션에 연결",
|
||||||
"compareWithBranch": "브랜치와 비교...",
|
"compareWithBranch": "브랜치와 비교...",
|
||||||
"reloadFromDisk": "디스크에서 다시 불러오기",
|
"reloadFromDisk": "디스크에서 다시 불러오기",
|
||||||
|
"new": "새로 만들기",
|
||||||
|
"newFile": "파일",
|
||||||
|
"newDirectory": "디렉터리",
|
||||||
"openIn": "열기",
|
"openIn": "열기",
|
||||||
"openInTerminal": "터미널에서 열기",
|
"openInTerminal": "터미널에서 열기",
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -996,7 +999,15 @@
|
|||||||
"rolledBackFiles": "{count, plural, one {#개 파일을 롤백했습니다} other {#개 파일을 롤백했습니다}}",
|
"rolledBackFiles": "{count, plural, one {#개 파일을 롤백했습니다} other {#개 파일을 롤백했습니다}}",
|
||||||
"savedAsCopy": "사본으로 저장했습니다",
|
"savedAsCopy": "사본으로 저장했습니다",
|
||||||
"saveCopyFailed": "사본으로 저장하지 못했습니다",
|
"saveCopyFailed": "사본으로 저장하지 못했습니다",
|
||||||
"watchStartFailed": "파일 감시 시작에 실패했습니다"
|
"watchStartFailed": "파일 감시 시작에 실패했습니다",
|
||||||
|
"createFailed": "생성 실패"
|
||||||
|
},
|
||||||
|
"createDialog": {
|
||||||
|
"newFile": "새 파일",
|
||||||
|
"newDirectory": "새 디렉터리",
|
||||||
|
"description": "새 {kind}의 이름을 입력하세요.",
|
||||||
|
"placeholderFile": "file-name.ext",
|
||||||
|
"placeholderDirectory": "folder-name"
|
||||||
},
|
},
|
||||||
"renameDialog": {
|
"renameDialog": {
|
||||||
"renameDirectory": "디렉터리 이름 변경",
|
"renameDirectory": "디렉터리 이름 변경",
|
||||||
|
|||||||
@@ -967,6 +967,9 @@
|
|||||||
"attachToCurrentSession": "Anexar à sessão atual",
|
"attachToCurrentSession": "Anexar à sessão atual",
|
||||||
"compareWithBranch": "Comparar com branch...",
|
"compareWithBranch": "Comparar com branch...",
|
||||||
"reloadFromDisk": "Recarregar do disco",
|
"reloadFromDisk": "Recarregar do disco",
|
||||||
|
"new": "Novo",
|
||||||
|
"newFile": "Arquivo",
|
||||||
|
"newDirectory": "Diretório",
|
||||||
"openIn": "Abrir em",
|
"openIn": "Abrir em",
|
||||||
"openInTerminal": "Abrir no terminal",
|
"openInTerminal": "Abrir no terminal",
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -996,7 +999,15 @@
|
|||||||
"rolledBackFiles": "{count, plural, one {# arquivo revertido} other {# arquivos revertidos}}",
|
"rolledBackFiles": "{count, plural, one {# arquivo revertido} other {# arquivos revertidos}}",
|
||||||
"savedAsCopy": "Salvo como cópia",
|
"savedAsCopy": "Salvo como cópia",
|
||||||
"saveCopyFailed": "Falha ao salvar como cópia",
|
"saveCopyFailed": "Falha ao salvar como cópia",
|
||||||
"watchStartFailed": "Falha ao iniciar monitoramento de arquivos"
|
"watchStartFailed": "Falha ao iniciar monitoramento de arquivos",
|
||||||
|
"createFailed": "Falha ao criar"
|
||||||
|
},
|
||||||
|
"createDialog": {
|
||||||
|
"newFile": "Novo arquivo",
|
||||||
|
"newDirectory": "Novo diretório",
|
||||||
|
"description": "Digite um nome para o novo {kind}.",
|
||||||
|
"placeholderFile": "file-name.ext",
|
||||||
|
"placeholderDirectory": "folder-name"
|
||||||
},
|
},
|
||||||
"renameDialog": {
|
"renameDialog": {
|
||||||
"renameDirectory": "Renomear diretório",
|
"renameDirectory": "Renomear diretório",
|
||||||
|
|||||||
@@ -967,6 +967,9 @@
|
|||||||
"attachToCurrentSession": "附加到当前会话",
|
"attachToCurrentSession": "附加到当前会话",
|
||||||
"compareWithBranch": "与分支比较...",
|
"compareWithBranch": "与分支比较...",
|
||||||
"reloadFromDisk": "从磁盘重新加载",
|
"reloadFromDisk": "从磁盘重新加载",
|
||||||
|
"new": "新建",
|
||||||
|
"newFile": "文件",
|
||||||
|
"newDirectory": "目录",
|
||||||
"openIn": "打开于",
|
"openIn": "打开于",
|
||||||
"openInTerminal": "在终端打开",
|
"openInTerminal": "在终端打开",
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -996,7 +999,15 @@
|
|||||||
"rolledBackFiles": "已回滚 {count} 个文件",
|
"rolledBackFiles": "已回滚 {count} 个文件",
|
||||||
"savedAsCopy": "已另存为副本",
|
"savedAsCopy": "已另存为副本",
|
||||||
"saveCopyFailed": "另存为副本失败",
|
"saveCopyFailed": "另存为副本失败",
|
||||||
"watchStartFailed": "文件监听启动失败"
|
"watchStartFailed": "文件监听启动失败",
|
||||||
|
"createFailed": "创建失败"
|
||||||
|
},
|
||||||
|
"createDialog": {
|
||||||
|
"newFile": "新建文件",
|
||||||
|
"newDirectory": "新建目录",
|
||||||
|
"description": "输入新{kind}的名称。",
|
||||||
|
"placeholderFile": "文件名.ext",
|
||||||
|
"placeholderDirectory": "文件夹名"
|
||||||
},
|
},
|
||||||
"renameDialog": {
|
"renameDialog": {
|
||||||
"renameDirectory": "重命名目录",
|
"renameDirectory": "重命名目录",
|
||||||
|
|||||||
@@ -967,6 +967,9 @@
|
|||||||
"attachToCurrentSession": "附加到目前會話",
|
"attachToCurrentSession": "附加到目前會話",
|
||||||
"compareWithBranch": "與分支比較...",
|
"compareWithBranch": "與分支比較...",
|
||||||
"reloadFromDisk": "從磁碟重新載入",
|
"reloadFromDisk": "從磁碟重新載入",
|
||||||
|
"new": "新建",
|
||||||
|
"newFile": "檔案",
|
||||||
|
"newDirectory": "目錄",
|
||||||
"openIn": "開啟於",
|
"openIn": "開啟於",
|
||||||
"openInTerminal": "在終端開啟",
|
"openInTerminal": "在終端開啟",
|
||||||
"actions": {
|
"actions": {
|
||||||
@@ -996,7 +999,15 @@
|
|||||||
"rolledBackFiles": "已回滾 {count} 個檔案",
|
"rolledBackFiles": "已回滾 {count} 個檔案",
|
||||||
"savedAsCopy": "已另存為副本",
|
"savedAsCopy": "已另存為副本",
|
||||||
"saveCopyFailed": "另存為副本失敗",
|
"saveCopyFailed": "另存為副本失敗",
|
||||||
"watchStartFailed": "檔案監聽啟動失敗"
|
"watchStartFailed": "檔案監聽啟動失敗",
|
||||||
|
"createFailed": "建立失敗"
|
||||||
|
},
|
||||||
|
"createDialog": {
|
||||||
|
"newFile": "新建檔案",
|
||||||
|
"newDirectory": "新建目錄",
|
||||||
|
"description": "輸入新{kind}的名稱。",
|
||||||
|
"placeholderFile": "file-name.ext",
|
||||||
|
"placeholderDirectory": "folder-name"
|
||||||
},
|
},
|
||||||
"renameDialog": {
|
"renameDialog": {
|
||||||
"renameDirectory": "重新命名目錄",
|
"renameDirectory": "重新命名目錄",
|
||||||
|
|||||||
@@ -850,6 +850,15 @@ export async function deleteFileTreeEntry(
|
|||||||
return invoke("delete_file_tree_entry", { rootPath, path })
|
return invoke("delete_file_tree_entry", { rootPath, path })
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export async function createFileTreeEntry(
|
||||||
|
rootPath: string,
|
||||||
|
path: string,
|
||||||
|
name: string,
|
||||||
|
kind: "file" | "dir"
|
||||||
|
): Promise<string> {
|
||||||
|
return invoke("create_file_tree_entry", { rootPath, path, name, kind })
|
||||||
|
}
|
||||||
|
|
||||||
export async function gitLog(
|
export async function gitLog(
|
||||||
path: string,
|
path: string,
|
||||||
limit?: number,
|
limit?: number,
|
||||||
|
|||||||
Reference in New Issue
Block a user