summaryrefslogtreecommitdiff
path: root/extension/src
diff options
context:
space:
mode:
authorNate Sesti <sestinj@gmail.com>2023-08-25 13:38:41 -0700
committerNate Sesti <sestinj@gmail.com>2023-08-25 13:38:41 -0700
commite5f56308c5fd87695278682b2a36ca60df0db863 (patch)
treec7d66f5a3b56ce762bfd26033890597a07099007 /extension/src
parenta55d64127a1e972d03f54a175b54eb0ad78e2b0e (diff)
downloadsncontinue-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.ts65
-rw-r--r--extension/src/diffs.ts84
-rw-r--r--extension/src/util/util.ts45
-rw-r--r--extension/src/util/vscode.ts65
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(