Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
39 changes: 39 additions & 0 deletions src-tauri/src/commands/folders.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3689,3 +3689,42 @@ async fn get_unpushed_hashes(

Ok((Some(hashes), has_upstream))
}

#[cfg(feature = "tauri-runtime")]
#[cfg_attr(feature = "tauri-runtime", tauri::command)]
pub async fn open_in_vscode(path: String) -> Result<(), AppCommandError> {
#[cfg(target_os = "macos")]
{
let status = crate::process::tokio_command("open")
.args(["-a", "Visual Studio Code", &path])
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.await;

if let Ok(s) = status {
if s.success() {
return Ok(());
}
}
}

let status = crate::process::tokio_command("code")
.arg(&path)
.stdin(Stdio::null())
.stdout(Stdio::null())
.stderr(Stdio::null())
.status()
.await;

match status {
Ok(s) if s.success() => Ok(()),
Err(e) if e.kind() == std::io::ErrorKind::NotFound => Err(
AppCommandError::dependency_missing("VS Code is not installed or available in PATH."),
),
_ => Err(AppCommandError::dependency_missing(
"Failed to open VS Code.",
)),
}
}
1 change: 1 addition & 0 deletions src-tauri/src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -531,6 +531,7 @@ mod tauri_app {
folders::add_folder_to_history,
folders::remove_folder_from_history,
folders::create_folder_directory,
folders::open_in_vscode,
folders::clone_repository,
folders::get_git_branch,
folders::git_init,
Expand Down
25 changes: 25 additions & 0 deletions src/components/conversations/sidebar-conversation-list.tsx
Original file line number Diff line number Diff line change
Expand Up @@ -36,6 +36,7 @@ import { useTerminalContext } from "@/contexts/terminal-context"
import { useZoomLevel } from "@/hooks/use-appearance"
import {
importLocalConversations,
openInVsCode,
openProjectBootWindow,
updateConversationTitle,
updateConversationStatus,
Expand Down Expand Up @@ -172,6 +173,7 @@ const FolderHeader = memo(function FolderHeader({
onChangeColor,
onOpenInSystemExplorer,
onOpenInTerminal,
onOpenInVsCode,
isDragging,
dragControls,
t,
Expand All @@ -191,6 +193,7 @@ const FolderHeader = memo(function FolderHeader({
onChangeColor: (folderId: number, color: string) => void
onOpenInSystemExplorer: (folderId: number) => void
onOpenInTerminal: (folderId: number) => void
onOpenInVsCode: (folderId: number) => void
isDragging?: boolean
dragControls: DragControls
t: ReturnType<typeof useTranslations>
Expand Down Expand Up @@ -329,6 +332,12 @@ const FolderHeader = memo(function FolderHeader({
<ContextMenuItem onSelect={() => onOpenInTerminal(folderId)}>
{tFileTree("openInTerminal")}
</ContextMenuItem>
<ContextMenuItem
disabled={!isDesktopMode}
onSelect={() => onOpenInVsCode(folderId)}
>
{tFileTree("openInVsCode")}
</ContextMenuItem>
</ContextMenuSubContent>
</ContextMenuSub>
<ContextMenuSeparator />
Expand Down Expand Up @@ -400,6 +409,7 @@ interface FolderGroupItemProps {
onChangeColor: (folderId: number, color: string) => void
onOpenInSystemExplorer: (folderId: number) => void
onOpenInTerminal: (folderId: number) => void
onOpenInVsCode: (folderId: number) => void
onSelect: (id: number, agentType: string) => void
onDoubleClick: (id: number, agentType: string) => void
onRename: (id: number, newTitle: string) => Promise<void>
Expand Down Expand Up @@ -436,6 +446,7 @@ function FolderGroupItem({
onChangeColor,
onOpenInSystemExplorer,
onOpenInTerminal,
onOpenInVsCode,
onSelect,
onDoubleClick,
onRename,
Expand Down Expand Up @@ -512,6 +523,7 @@ function FolderGroupItem({
onChangeColor={onChangeColor}
onOpenInSystemExplorer={onOpenInSystemExplorer}
onOpenInTerminal={onOpenInTerminal}
onOpenInVsCode={onOpenInVsCode}
isDragging={dragging}
dragControls={dragControls}
t={t}
Expand Down Expand Up @@ -694,6 +706,18 @@ export function SidebarConversationList({
[folderIndex, createTerminalInDirectory, tFileTree]
)

const handleOpenFolderInVsCode = useCallback(
(folderId: number) => {
const folder = folderIndex.get(folderId)
if (!folder) return
void openInVsCode(folder.path).catch((err) => {
console.error("[openInVsCode] failed:", err)
toast.error(tFileTree("toasts.openDirectoryFailed"))
})
},
[folderIndex, tFileTree]
)

const scrollRootRef = useRef<OverlayScrollbarsComponentRef>(null)
const scrollToActiveRef = useRef<() => void>(() => {})
const pendingScrollRef = useRef(false)
Expand Down Expand Up @@ -1166,6 +1190,7 @@ export function SidebarConversationList({
handleOpenFolderInSystemExplorer
}
onOpenInTerminal={handleOpenFolderInTerminal}
onOpenInVsCode={handleOpenFolderInVsCode}
onSelect={handleSelect}
onDoubleClick={handleDoubleClick}
onRename={handleRename}
Expand Down
1 change: 1 addition & 0 deletions src/i18n/messages/ar.json
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@
"newDirectory": "مجلد",
"openIn": "فتح في",
"openInTerminal": "فتح في الطرفية",
"openInVsCode": "فتح في VS Code",
"actions": {
"select": "تحديد",
"unselect": "إلغاء التحديد",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/messages/de.json
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@
"newDirectory": "Verzeichnis",
"openIn": "Öffnen in",
"openInTerminal": "Im Terminal öffnen",
"openInVsCode": "In VS Code öffnen",
"actions": {
"select": "Auswählen",
"unselect": "Auswahl aufheben",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/messages/en.json
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@
"newDirectory": "Directory",
"openIn": "Open in",
"openInTerminal": "Open in terminal",
"openInVsCode": "Open in VS Code",
"actions": {
"select": "Select",
"unselect": "Unselect",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/messages/es.json
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@
"newDirectory": "Directorio",
"openIn": "Abrir en",
"openInTerminal": "Abrir en terminal",
"openInVsCode": "Abrir en VS Code",
"actions": {
"select": "Seleccionar",
"unselect": "Deseleccionar",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/messages/fr.json
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@
"newDirectory": "Répertoire",
"openIn": "Ouvrir dans",
"openInTerminal": "Ouvrir dans le terminal",
"openInVsCode": "Ouvrir dans VS Code",
"actions": {
"select": "Sélectionner",
"unselect": "Désélectionner",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/messages/ja.json
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@
"newDirectory": "ディレクトリ",
"openIn": "で開く",
"openInTerminal": "ターミナルで開く",
"openInVsCode": "VS Code で開く",
"actions": {
"select": "選択",
"unselect": "選択解除",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/messages/ko.json
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@
"newDirectory": "디렉터리",
"openIn": "열기",
"openInTerminal": "터미널에서 열기",
"openInVsCode": "VS Code 에서 열기",
"actions": {
"select": "선택",
"unselect": "선택 해제",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/messages/pt.json
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@
"newDirectory": "Diretório",
"openIn": "Abrir em",
"openInTerminal": "Abrir no terminal",
"openInVsCode": "Abrir no VS Code",
"actions": {
"select": "Selecionar",
"unselect": "Desmarcar",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/messages/zh-CN.json
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@
"newDirectory": "目录",
"openIn": "打开于",
"openInTerminal": "在终端打开",
"openInVsCode": "在VS Code中打开",
"actions": {
"select": "选择",
"unselect": "取消选择",
Expand Down
1 change: 1 addition & 0 deletions src/i18n/messages/zh-TW.json
Original file line number Diff line number Diff line change
Expand Up @@ -1427,6 +1427,7 @@
"newDirectory": "目錄",
"openIn": "開啟於",
"openInTerminal": "在終端開啟",
"openInVsCode": "在VS Code中開啟",
"actions": {
"select": "選擇",
"unselect": "取消選擇",
Expand Down
4 changes: 4 additions & 0 deletions src/lib/api.ts
Original file line number Diff line number Diff line change
Expand Up @@ -735,6 +735,10 @@ export async function createFolderDirectory(path: string): Promise<void> {
return getTransport().call("create_folder_directory", { path })
}

export async function openInVsCode(path: string): Promise<void> {
return getTransport().call("open_in_vscode", { path })
}

export async function cloneRepository(
url: string,
targetDir: string,
Expand Down