diff options
author | Nate Sesti <sestinj@gmail.com> | 2023-08-25 13:38:41 -0700 |
---|---|---|
committer | Nate Sesti <sestinj@gmail.com> | 2023-08-25 13:38:41 -0700 |
commit | e5f56308c5fd87695278682b2a36ca60df0db863 (patch) | |
tree | c7d66f5a3b56ce762bfd26033890597a07099007 /extension/src | |
parent | a55d64127a1e972d03f54a175b54eb0ad78e2b0e (diff) | |
download | sncontinue-e5f56308c5fd87695278682b2a36ca60df0db863.tar.gz sncontinue-e5f56308c5fd87695278682b2a36ca60df0db863.tar.bz2 sncontinue-e5f56308c5fd87695278682b2a36ca60df0db863.zip |
fix: :bug: ssh compatibility by reading from vscode.workspace.fs
Diffstat (limited to 'extension/src')
-rw-r--r-- | extension/src/continueIdeClient.ts | 65 | ||||
-rw-r--r-- | extension/src/diffs.ts | 84 | ||||
-rw-r--r-- | extension/src/util/util.ts | 45 | ||||
-rw-r--r-- | extension/src/util/vscode.ts | 65 |
4 files changed, 96 insertions, 163 deletions
diff --git a/extension/src/continueIdeClient.ts b/extension/src/continueIdeClient.ts index 430bb9dd..19575b13 100644 --- a/extension/src/continueIdeClient.ts +++ b/extension/src/continueIdeClient.ts @@ -12,10 +12,10 @@ import { rejectSuggestionCommand, } from "./suggestions"; import { FileEditWithFullContents } from "../schema/FileEditWithFullContents"; -import * as fs from "fs"; import { WebsocketMessenger } from "./util/messenger"; import { diffManager } from "./diffs"; const os = require("os"); +const path = require("path"); const continueVirtualDocumentScheme = "continue"; @@ -253,7 +253,7 @@ class IdeProtocolClient { break; case "readFile": messenger.send("readFile", { - contents: this.readFile(data.filepath), + contents: await this.readFile(data.filepath), }); break; case "getTerminalContents": @@ -261,6 +261,44 @@ class IdeProtocolClient { contents: await this.getTerminalContents(), }); break; + case "listDirectoryContents": + messenger.send("listDirectoryContents", { + contents: ( + await vscode.workspace.fs.readDirectory( + vscode.Uri.file(data.directory) + ) + ) + .map(([name, type]) => name) + .filter((name) => { + const DEFAULT_IGNORE_DIRS = [ + ".git", + ".vscode", + ".idea", + ".vs", + ".venv", + "env", + ".env", + "node_modules", + "dist", + "build", + "target", + "out", + "bin", + ".pytest_cache", + ".vscode-test", + ".continue", + "__pycache__", + ]; + if ( + !DEFAULT_IGNORE_DIRS.some((dir) => + name.split(path.sep).includes(dir) + ) + ) { + return name; + } + }), + }); + break; case "editFile": const fileEdit = await this.editFile(data.edit); messenger.send("editFile", { @@ -306,7 +344,7 @@ class IdeProtocolClient { this.showSuggestion(data.edit); break; case "showDiff": - this.showDiff(data.filepath, data.replacement, data.step_index); + await this.showDiff(data.filepath, data.replacement, data.step_index); break; case "getSessionId": case "connected": @@ -385,8 +423,8 @@ class IdeProtocolClient { ); } - showDiff(filepath: string, replacement: string, step_index: number) { - diffManager.writeDiff(filepath, replacement, step_index); + async showDiff(filepath: string, replacement: string, step_index: number) { + await diffManager.writeDiff(filepath, replacement, step_index); } openFile(filepath: string) { @@ -506,19 +544,14 @@ class IdeProtocolClient { }); } - readFile(filepath: string): string { + async readFile(filepath: string): Promise<string> { let contents: string | undefined; - vscode.window.visibleTextEditors - .filter((editor) => this.editorIsCode(editor)) - .forEach((editor) => { - if (editor.document.uri.fsPath === filepath) { - contents = editor.document.getText(); - } - }); if (typeof contents === "undefined") { - if (fs.existsSync(filepath)) { - contents = fs.readFileSync(filepath, "utf-8"); - } else { + try { + contents = await vscode.workspace.fs + .readFile(vscode.Uri.file(filepath)) + .then((bytes) => new TextDecoder().decode(bytes)); + } catch { contents = ""; } } diff --git a/extension/src/diffs.ts b/extension/src/diffs.ts index efaf7626..d2d1dae3 100644 --- a/extension/src/diffs.ts +++ b/extension/src/diffs.ts @@ -14,6 +14,19 @@ interface DiffInfo { range: vscode.Range; } +async function readFile(path: string): Promise<string> { + return await vscode.workspace.fs + .readFile(vscode.Uri.file(path)) + .then((bytes) => new TextDecoder().decode(bytes)); +} + +async function writeFile(path: string, contents: string) { + await vscode.workspace.fs.writeFile( + vscode.Uri.file(path), + new TextEncoder().encode(contents) + ); +} + export const DIFF_DIRECTORY = path .join(os.homedir(), ".continue", "diffs") .replace(/^C:/, "c:"); @@ -27,13 +40,9 @@ class DiffManager { return this.diffs.get(newFilepath); } - private setupDirectory() { + private async setupDirectory() { // Make sure the diff directory exists - if (!fs.existsSync(DIFF_DIRECTORY)) { - fs.mkdirSync(DIFF_DIRECTORY, { - recursive: true, - }); - } + await vscode.workspace.fs.createDirectory(vscode.Uri.file(DIFF_DIRECTORY)); } constructor() { @@ -57,15 +66,17 @@ class DiffManager { return path.join(DIFF_DIRECTORY, this.escapeFilepath(originalFilepath)); } - private openDiffEditor( + private async openDiffEditor( originalFilepath: string, newFilepath: string - ): vscode.TextEditor | undefined { - // If the file doesn't yet exist or the basename is a single digit number (git hash object or something), don't open the diff editor - if ( - !fs.existsSync(newFilepath) || - path.basename(originalFilepath).match(/^\d$/) - ) { + ): Promise<vscode.TextEditor | undefined> { + // If the file doesn't yet exist or the basename is a single digit number (vscode terminal), don't open the diff editor + try { + await vscode.workspace.fs.stat(vscode.Uri.file(newFilepath)); + } catch { + return undefined; + } + if (path.basename(originalFilepath).match(/^\d$/)) { return undefined; } @@ -128,21 +139,21 @@ class DiffManager { return 0; } - writeDiff( + async writeDiff( originalFilepath: string, newContent: string, step_index: number - ): string { - this.setupDirectory(); + ): Promise<string> { + await this.setupDirectory(); // Create or update existing diff const newFilepath = this.getNewFilepath(originalFilepath); - fs.writeFileSync(newFilepath, newContent); + await writeFile(newFilepath, newContent); // Open the diff editor if this is a new diff if (!this.diffs.has(newFilepath)) { // Figure out the first line that is different - const oldContent = ideProtocolClient.readFile(originalFilepath); + const oldContent = await ideProtocolClient.readFile(originalFilepath); const line = this._findFirstDifferentLine(oldContent, newContent); const diffInfo: DiffInfo = { @@ -157,7 +168,10 @@ class DiffManager { // Open the editor if it hasn't been opened yet const diffInfo = this.diffs.get(newFilepath); if (diffInfo && !diffInfo?.editor) { - diffInfo.editor = this.openDiffEditor(originalFilepath, newFilepath); + diffInfo.editor = await this.openDiffEditor( + originalFilepath, + newFilepath + ); this.diffs.set(newFilepath, diffInfo); } @@ -207,7 +221,7 @@ class DiffManager { return undefined; } - acceptDiff(newFilepath?: string) { + async acceptDiff(newFilepath?: string) { // When coming from a keyboard shortcut, we have to infer the newFilepath from visible text editors if (!newFilepath) { newFilepath = this.inferNewFilepath(); @@ -227,18 +241,18 @@ class DiffManager { vscode.workspace.textDocuments .find((doc) => doc.uri.fsPath === newFilepath) ?.save() - .then(() => { - fs.writeFileSync( + .then(async () => { + await writeFile( diffInfo.originalFilepath, - fs.readFileSync(diffInfo.newFilepath) + await readFile(diffInfo.newFilepath) ); this.cleanUpDiff(diffInfo); }); - recordAcceptReject(true, diffInfo); + await recordAcceptReject(true, diffInfo); } - rejectDiff(newFilepath?: string) { + async rejectDiff(newFilepath?: string) { // If no newFilepath is provided and there is only one in the dictionary, use that if (!newFilepath) { newFilepath = this.inferNewFilepath(); @@ -266,13 +280,13 @@ class DiffManager { this.cleanUpDiff(diffInfo); }); - recordAcceptReject(false, diffInfo); + await recordAcceptReject(false, diffInfo); } } export const diffManager = new DiffManager(); -function recordAcceptReject(accepted: boolean, diffInfo: DiffInfo) { +async function recordAcceptReject(accepted: boolean, diffInfo: DiffInfo) { const devDataDir = devDataPath(); const suggestionsPath = path.join(devDataDir, "suggestions.json"); @@ -280,10 +294,10 @@ function recordAcceptReject(accepted: boolean, diffInfo: DiffInfo) { let suggestions = []; // Check if suggestions.json exists - if (fs.existsSync(suggestionsPath)) { - const rawData = fs.readFileSync(suggestionsPath, "utf-8"); + try { + const rawData = await readFile(suggestionsPath); suggestions = JSON.parse(rawData); - } + } catch {} // Add the new suggestion to the list suggestions.push({ @@ -296,19 +310,15 @@ function recordAcceptReject(accepted: boolean, diffInfo: DiffInfo) { // ideProtocolClient.sendAcceptRejectSuggestion(accepted); // Write the updated suggestions back to the file - fs.writeFileSync( - suggestionsPath, - JSON.stringify(suggestions, null, 4), - "utf-8" - ); + await writeFile(suggestionsPath, JSON.stringify(suggestions, null, 4)); } export async function acceptDiffCommand(newFilepath?: string) { - diffManager.acceptDiff(newFilepath); + await diffManager.acceptDiff(newFilepath); ideProtocolClient.sendAcceptRejectDiff(true); } export async function rejectDiffCommand(newFilepath?: string) { - diffManager.rejectDiff(newFilepath); + await diffManager.rejectDiff(newFilepath); ideProtocolClient.sendAcceptRejectDiff(false); } diff --git a/extension/src/util/util.ts b/extension/src/util/util.ts index 15b34267..38c955e7 100644 --- a/extension/src/util/util.ts +++ b/extension/src/util/util.ts @@ -1,5 +1,3 @@ -import { RangeInFile } from "../../schema/RangeInFile"; -import * as fs from "fs"; const os = require("os"); function charIsEscapedAtIndex(index: number, str: string): boolean { @@ -52,49 +50,6 @@ export function convertSingleToDoubleQuoteJSON(json: string): string { return newJson; } -export async function readRangeInFile( - rangeInFile: RangeInFile -): Promise<string> { - const range = rangeInFile.range; - return new Promise((resolve, reject) => { - fs.readFile(rangeInFile.filepath, (err, data) => { - if (err) { - reject(err); - } else { - let lines = data.toString().split("\n"); - if (range.start.line === range.end.line) { - resolve( - lines[rangeInFile.range.start.line].slice( - rangeInFile.range.start.character, - rangeInFile.range.end.character - ) - ); - } else { - let firstLine = lines[range.start.line].slice(range.start.character); - let lastLine = lines[range.end.line].slice(0, range.end.character); - let middleLines = lines.slice(range.start.line + 1, range.end.line); - resolve([firstLine, ...middleLines, lastLine].join("\n")); - } - } - }); - }); -} - -export function codeSelectionsToVirtualFileSystem( - codeSelections: RangeInFile[] -): { - [filepath: string]: string; -} { - let virtualFileSystem: { [filepath: string]: string } = {}; - for (let cs of codeSelections) { - if (!cs.filepath) continue; - if (cs.filepath in virtualFileSystem) continue; - let content = fs.readFileSync(cs.filepath, "utf8"); - virtualFileSystem[cs.filepath] = content; - } - return virtualFileSystem; -} - export function debounced(delay: number, fn: Function) { let timerId: NodeJS.Timeout | null; return function (...args: any[]) { diff --git a/extension/src/util/vscode.ts b/extension/src/util/vscode.ts index 3110d589..bf0fa1e5 100644 --- a/extension/src/util/vscode.ts +++ b/extension/src/util/vscode.ts @@ -1,6 +1,4 @@ import * as vscode from "vscode"; -import * as path from "path"; -import * as fs from "fs"; export function translate(range: vscode.Range, lines: number): vscode.Range { return new vscode.Range( @@ -21,39 +19,6 @@ export function getNonce() { return text; } -export function getTestFile( - filename: string, - createFile: boolean = false -): string { - let basename = path.basename(filename).split(".")[0]; - switch (path.extname(filename)) { - case ".py": - basename += "_test"; - break; - case ".js": - case ".jsx": - case ".ts": - case ".tsx": - basename += ".test"; - break; - default: - basename += "_test"; - } - - const directory = path.join(path.dirname(filename), "tests"); - const testFilename = path.join(directory, basename + path.extname(filename)); - - // Optionally, create the file if it doesn't exist - if (createFile && !fs.existsSync(testFilename)) { - if (!fs.existsSync(directory)) { - fs.mkdirSync(directory); - } - fs.writeFileSync(testFilename, ""); - } - - return testFilename; -} - export function getExtensionUri(): vscode.Uri { return vscode.extensions.getExtension("Continue.continue")!.extensionUri; } @@ -100,36 +65,6 @@ export function getRightViewColumn(): vscode.ViewColumn { return column; } -export async function readFileAtRange( - range: vscode.Range, - filepath: string -): Promise<string> { - return new Promise((resolve, reject) => { - fs.readFile(filepath, (err, data) => { - if (err) { - reject(err); - } else { - let lines = data.toString().split("\n"); - if (range.isSingleLine) { - resolve( - lines[range.start.line].slice( - range.start.character, - range.end.character - ) - ); - } else { - const firstLine = lines[range.start.line].slice( - range.start.character - ); - const lastLine = lines[range.end.line].slice(0, range.end.character); - const middleLines = lines.slice(range.start.line + 1, range.end.line); - resolve([firstLine, ...middleLines, lastLine].join("\n")); - } - } - }); - }); -} - let showTextDocumentInProcess = false; export function openEditorAndRevealRange( |