Skip to content

Commit

Permalink
Proper Fix for Ideal New/Untitled Flow (#1351)
Browse files Browse the repository at this point in the history
# [rfc] Proper (?) Fix for Ideal New/Untitled Flow

This implements a proper(?) fix for creating new/untitled aiconfig
files:
- treats the file as regular Untitled (but with proper
`.aiconfig.json/yaml` extension), prompting for filename only on first
save, no longer needing to prompt immediately on create (undoing #1337)
- now, only one tab is opened and it opens the custom editor

The main change/fix is using a `WorkspaceEdit` to hold the initial
content changes instead of opening/showing a new text editor with the
content. I found that solution from
microsoft/vscode#93441

However, now the webview seems to reload the file after saving it for
the first time, which makes it go back to readonly and start up the
server :( --> it seems to dispose the untitled webview (killing the
server) and refresh with a new server...



https://github.com/lastmile-ai/aiconfig/assets/5060851/8a471b5e-f6d3-4860-a780-949ca928394a


Not sure if this is overall better because of the server thing. Need to
investigate some more. Fwiw, current scenario on main with 2 tabs is
probably a worse UX because:
- obviously, 2 tabs is confusing
- closing text editor tab seems to break custom editor (can't make edits
in custom editor after)? Also, closing text editor tab has the same
notification about unable to update server
- on top of ^, need to name the file beforehand, as opposed to on save
  • Loading branch information
rholinshead authored Feb 26, 2024
2 parents ba3b306 + 59b8cce commit 20a144c
Show file tree
Hide file tree
Showing 2 changed files with 7 additions and 56 deletions.
41 changes: 7 additions & 34 deletions vscode-extension/src/extension.ts
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@ import {
PythonExtension,
} from "@vscode/python-extension";
import { ufetch } from "ufetch";
import fs from "fs";
import path from "path";
import { AIConfigEditorProvider } from "./aiConfigEditor";
import {
Expand All @@ -26,7 +25,6 @@ import {
isSupportedConfigExtension,
SUPPORTED_FILE_EXTENSIONS,
setupEnvironmentVariables,
validateNewConfigName,
getConfigurationTarget,
} from "./util";
import {
Expand Down Expand Up @@ -214,54 +212,29 @@ async function createNewAIConfig(
);

const fileContentPath = mode === "json" ? newAIConfigJSON : newAIConfigYAML;

const fileContentBuffer = await vscode.workspace.fs.readFile(fileContentPath);
const initialContent = fileContentBuffer.toString();

const workspacePath = vscode.workspace.workspaceFolders
? vscode.workspace.workspaceFolders[0].uri.path
: null;

// Find the first available untitled file name to suggest as default
let firstAvailableUntitledName: string | null = null;
let i = 0;
while (firstAvailableUntitledName === null) {
const fileName = `untitled${i === 0 ? "" : "-" + i}.aiconfig.${mode}`;
const filePath = workspacePath
? path.join(workspacePath, fileName)
: fileName;

if (fs.existsSync(filePath)) {
i++;
} else {
firstAvailableUntitledName = fileName;
}
}

const newConfigName = await vscode.window.showInputBox({
prompt: "Enter a name for the new AIConfig file",
value: firstAvailableUntitledName,
validateInput: (input) => validateNewConfigName(input, mode),
});

const untitledFileName = `untitled.aiconfig.${mode}`;
const newConfigFilePath = workspacePath
? path.join(workspacePath, newConfigName)
: newConfigName;
? path.join(workspacePath, untitledFileName)
: untitledFileName;
const newConfigUri = vscode.Uri.file(newConfigFilePath).with({
scheme: "untitled",
});

const doc = await vscode.workspace.openTextDocument(newConfigUri);
const editor = await vscode.window.showTextDocument(doc, { preview: false });
const edit = new vscode.WorkspaceEdit();
edit.insert(newConfigUri, new vscode.Position(0, 0), initialContent);
await vscode.workspace.applyEdit(edit);

try {
await editor.edit((editBuilder) => {
editBuilder.insert(new vscode.Position(0, 0), initialContent);
});

await vscode.commands.executeCommand(
"vscode.openWith",
doc.uri,
newConfigUri,
AIConfigEditorProvider.viewType
);
} catch (e) {
Expand Down
22 changes: 0 additions & 22 deletions vscode-extension/src/util.ts
Original file line number Diff line number Diff line change
Expand Up @@ -381,28 +381,6 @@ export async function setupEnvironmentVariables(
}
}

export function validateNewConfigName(name: string, mode: "json" | "yaml") {
if (name === "") {
return "Filename is required";
}
if (mode === "json" && !name.endsWith(".aiconfig.json")) {
return "Filename must end with .aiconfig.json";
}
if (
mode === "yaml" &&
!name.endsWith(".aiconfig.yaml") &&
!name.endsWith(".aiconfig.yml")
) {
return "Filename must end with .aiconfig.yaml or .aiconfig.yml";
}

if (fs.existsSync(name)) {
return "File already exists";
}

return null;
}

/**
* Some VS Code setups can have multiple workspaces, in which
* case we should take the lowest common ancestor path that is shared
Expand Down

0 comments on commit 20a144c

Please sign in to comment.