Skip to content

fix: show save dialog when creating new files (issue 6309) #6745

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from
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
1 change: 1 addition & 0 deletions core/index.d.ts
Original file line number Diff line number Diff line change
Expand Up @@ -1395,6 +1395,7 @@ export interface ApplyToFilePayload {
text: string;
toolCallId?: string;
isSearchAndReplace?: boolean;
showSaveDialog?: boolean;
}

export interface RangeInFileWithContents {
Expand Down
41 changes: 41 additions & 0 deletions extensions/vscode/src/extension/VsCodeMessenger.ts
Original file line number Diff line number Diff line change
Expand Up @@ -15,6 +15,7 @@ import {
WEBVIEW_TO_CORE_PASS_THROUGH,
} from "core/protocol/passThrough";
import { stripImages } from "core/util/messageContent";
import * as path from "path";
import * as vscode from "vscode";

import { ApplyManager } from "../apply";
Expand Down Expand Up @@ -132,6 +133,46 @@ export class VsCodeMessenger {
});

this.onWebview("applyToFile", async ({ data }) => {
// Check if we should show save dialog for new file creation
if (data.showSaveDialog) {
// Extract filename from the suggested filepath if available
let defaultUri: vscode.Uri | undefined;
if (data.filepath) {
const filename = path.basename(data.filepath);
const workspaceFolder = vscode.workspace.workspaceFolders?.[0];
if (workspaceFolder) {
// Try to use the suggested directory structure if it exists
const suggestedDir = path.dirname(data.filepath);
if (suggestedDir && suggestedDir !== '.') {
defaultUri = vscode.Uri.joinPath(workspaceFolder.uri, suggestedDir, filename);
} else {
defaultUri = vscode.Uri.joinPath(workspaceFolder.uri, filename);
}
}
} else {
defaultUri = vscode.workspace.workspaceFolders?.[0]?.uri;
}

const uri = await vscode.window.showSaveDialog({
defaultUri,
saveLabel: "Create File",
title: "Choose location for new file",
});

if (!uri) {
// User cancelled
await webviewProtocol.request("updateApplyState", {
streamId: data.streamId,
status: "closed",
toolCallId: data.toolCallId,
});
return;
}

// Update the filepath with the user's choice
data.filepath = uri.fsPath;
}

const [verticalDiffManager, configHandler] = await Promise.all([
verticalDiffManagerPromise,
configHandlerPromise,
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -150,7 +150,11 @@ export function StepContainerPreToolbar({

async function onClickApply() {
const fileUri = await getFileUriToApplyTo();
if (!fileUri) {

// Check if we're creating a new file (when fileExists is false or when we don't have a specific file)
const isCreatingNewFile = !fileExists && relativeFilepath;

if (!fileUri && !isCreatingNewFile) {
void ideMessenger.ide.showToast(
"error",
"Could not resolve filepath to apply changes",
Expand All @@ -163,12 +167,15 @@ export function StepContainerPreToolbar({
streamId: codeBlockStreamId,
filepath: fileUri,
text: codeBlockContent,
showSaveDialog: !!isCreatingNewFile,
toolCallId: forceToolCallId,
});

setAppliedFileUri(fileUri);
void refreshFileExists();
if (fileUri) {
setAppliedFileUri(fileUri);
void refreshFileExists();
}
}

function onClickInsertAtCursor() {
ideMessenger.post("insertAtCursor", { text: codeBlockContent });
}
Expand Down
Loading