summaryrefslogtreecommitdiff
path: root/extension
diff options
context:
space:
mode:
authorNate Sesti <sestinj@gmail.com>2023-06-25 12:24:45 -0700
committerNate Sesti <sestinj@gmail.com>2023-06-25 12:24:45 -0700
commit54048d3e7bda9c39cc08888b37e0c7dc0716a713 (patch)
tree3ff7254f755e4b3b28a523d652b78dd1f61f868d /extension
parent82ead52472d4e2a2e291aa5f17ea8522fc11f236 (diff)
parentad462728afc4e6a9e1402aff295010ced9cf2f7a (diff)
downloadsncontinue-54048d3e7bda9c39cc08888b37e0c7dc0716a713.tar.gz
sncontinue-54048d3e7bda9c39cc08888b37e0c7dc0716a713.tar.bz2
sncontinue-54048d3e7bda9c39cc08888b37e0c7dc0716a713.zip
Merge branch 'main' into function-calling
Diffstat (limited to 'extension')
-rw-r--r--extension/package-lock.json4
-rw-r--r--extension/package.json2
-rw-r--r--extension/react-app/src/components/ContinueButton.tsx13
-rw-r--r--extension/react-app/src/components/DebugPanel.tsx2
-rw-r--r--extension/react-app/src/hooks/ContinueGUIClientProtocol.ts2
-rw-r--r--extension/react-app/src/hooks/useContinueGUIProtocol.ts4
-rw-r--r--extension/react-app/src/redux/slices/configSlice.ts16
-rw-r--r--extension/react-app/src/redux/store.ts1
-rw-r--r--extension/react-app/src/tabs/gui.tsx30
-rw-r--r--extension/scripts/continuedev-0.1.1-py3-none-any.whlbin86409 -> 86716 bytes
-rw-r--r--extension/src/activation/activate.ts40
-rw-r--r--extension/src/commands.ts94
-rw-r--r--extension/src/continueIdeClient.ts16
-rw-r--r--extension/src/debugPanel.ts174
-rw-r--r--extension/src/decorations.ts97
-rw-r--r--extension/src/lang-server/codeLens.ts34
-rw-r--r--extension/src/languages/index.d.ts13
-rw-r--r--extension/src/languages/index.ts19
-rw-r--r--extension/src/languages/javascript/index.ts16
-rw-r--r--extension/src/languages/notImplemented.ts10
-rw-r--r--extension/src/languages/python/index.ts74
21 files changed, 73 insertions, 588 deletions
diff --git a/extension/package-lock.json b/extension/package-lock.json
index 79b010cc..12b2fe13 100644
--- a/extension/package-lock.json
+++ b/extension/package-lock.json
@@ -1,12 +1,12 @@
{
"name": "continue",
- "version": "0.0.60",
+ "version": "0.0.61",
"lockfileVersion": 2,
"requires": true,
"packages": {
"": {
"name": "continue",
- "version": "0.0.60",
+ "version": "0.0.61",
"license": "Apache-2.0",
"dependencies": {
"@electron/rebuild": "^3.2.10",
diff --git a/extension/package.json b/extension/package.json
index 94a58ebd..9fd1d7a6 100644
--- a/extension/package.json
+++ b/extension/package.json
@@ -14,7 +14,7 @@
"displayName": "Continue",
"pricing": "Free",
"description": "Accelerating software development with language models",
- "version": "0.0.60",
+ "version": "0.0.61",
"publisher": "Continue",
"engines": {
"vscode": "^1.74.0"
diff --git a/extension/react-app/src/components/ContinueButton.tsx b/extension/react-app/src/components/ContinueButton.tsx
index c6117bf9..ef6719b7 100644
--- a/extension/react-app/src/components/ContinueButton.tsx
+++ b/extension/react-app/src/components/ContinueButton.tsx
@@ -1,6 +1,8 @@
import styled, { keyframes } from "styled-components";
import { Button } from ".";
import { Play } from "@styled-icons/heroicons-outline";
+import { useSelector } from "react-redux";
+import { RootStore } from "../redux/store";
let StyledButton = styled(Button)`
margin: auto;
@@ -25,14 +27,21 @@ let StyledButton = styled(Button)`
`;
function ContinueButton(props: { onClick?: () => void; hidden?: boolean }) {
+ const vscMediaUrl = useSelector(
+ (state: RootStore) => state.config.vscMediaUrl
+ );
+
return (
<StyledButton
hidden={props.hidden}
className="m-auto"
onClick={props.onClick}
>
- <Play />
- {/* <img src={"/continue_arrow.png"} width="16px"></img> */}
+ {vscMediaUrl ? (
+ <img src={`${vscMediaUrl}/play_button.png`} width="22px" />
+ ) : (
+ <Play />
+ )}
Continue
</StyledButton>
);
diff --git a/extension/react-app/src/components/DebugPanel.tsx b/extension/react-app/src/components/DebugPanel.tsx
index 30f38779..94dbac9e 100644
--- a/extension/react-app/src/components/DebugPanel.tsx
+++ b/extension/react-app/src/components/DebugPanel.tsx
@@ -6,6 +6,7 @@ import {
setApiUrl,
setVscMachineId,
setSessionId,
+ setVscMediaUrl,
} from "../redux/slices/configSlice";
import { setHighlightedCode } from "../redux/slices/miscSlice";
import { updateFileSystem } from "../redux/slices/debugContexSlice";
@@ -37,6 +38,7 @@ function DebugPanel(props: DebugPanelProps) {
dispatch(setApiUrl(event.data.apiUrl));
dispatch(setVscMachineId(event.data.vscMachineId));
dispatch(setSessionId(event.data.sessionId));
+ dispatch(setVscMediaUrl(event.data.vscMediaUrl));
break;
case "highlightedCode":
dispatch(setHighlightedCode(event.data.rangeInFile));
diff --git a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts
index 824bb086..3d8e0a38 100644
--- a/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts
+++ b/extension/react-app/src/hooks/ContinueGUIClientProtocol.ts
@@ -13,6 +13,8 @@ abstract class AbstractContinueGUIClientProtocol {
callback: (commands: { name: string; description: string }[]) => void
): void;
+ abstract changeDefaultModel(model: string): void;
+
abstract sendClear(): void;
abstract retryAtIndex(index: number): void;
diff --git a/extension/react-app/src/hooks/useContinueGUIProtocol.ts b/extension/react-app/src/hooks/useContinueGUIProtocol.ts
index 59397742..f43a66ff 100644
--- a/extension/react-app/src/hooks/useContinueGUIProtocol.ts
+++ b/extension/react-app/src/hooks/useContinueGUIProtocol.ts
@@ -55,6 +55,10 @@ class ContinueGUIClientProtocol extends AbstractContinueGUIClientProtocol {
});
}
+ changeDefaultModel(model: string) {
+ this.messenger.send("change_default_model", { model });
+ }
+
sendClear() {
this.messenger.send("clear_history", {});
}
diff --git a/extension/react-app/src/redux/slices/configSlice.ts b/extension/react-app/src/redux/slices/configSlice.ts
index a6a641e6..1b107bed 100644
--- a/extension/react-app/src/redux/slices/configSlice.ts
+++ b/extension/react-app/src/redux/slices/configSlice.ts
@@ -37,9 +37,21 @@ export const configSlice = createSlice({
...state,
sessionId: action.payload,
}),
+ setVscMediaUrl: (
+ state: RootStore["config"],
+ action: { type: string; payload: string }
+ ) => ({
+ ...state,
+ vscMediaUrl: action.payload,
+ }),
},
});
-export const { setVscMachineId, setApiUrl, setWorkspacePath, setSessionId } =
- configSlice.actions;
+export const {
+ setVscMachineId,
+ setApiUrl,
+ setWorkspacePath,
+ setSessionId,
+ setVscMediaUrl,
+} = configSlice.actions;
export default configSlice.reducer;
diff --git a/extension/react-app/src/redux/store.ts b/extension/react-app/src/redux/store.ts
index f9eb0517..a5eef4ba 100644
--- a/extension/react-app/src/redux/store.ts
+++ b/extension/react-app/src/redux/store.ts
@@ -21,6 +21,7 @@ export interface RootStore {
vscMachineId: string | undefined;
sessionId: string | undefined;
sessionStarted: number | undefined;
+ vscMediaUrl: string | undefined;
};
chat: {
messages: ChatMessage[];
diff --git a/extension/react-app/src/tabs/gui.tsx b/extension/react-app/src/tabs/gui.tsx
index d6131174..5001fe4b 100644
--- a/extension/react-app/src/tabs/gui.tsx
+++ b/extension/react-app/src/tabs/gui.tsx
@@ -215,7 +215,7 @@ function GUI(props: GUIProps) {
useEffect(() => {
const listener = (e: any) => {
// Cmd + J to toggle fast model
- if (e.key === "j" && e.metaKey) {
+ if (e.key === "i" && e.metaKey && e.shiftKey) {
setUsingFastModel((prev) => !prev);
}
};
@@ -230,21 +230,24 @@ function GUI(props: GUIProps) {
console.log("CLIENT ON STATE UPDATE: ", client, client?.onStateUpdate);
client?.onStateUpdate((state) => {
// Scroll only if user is at very bottom of the window.
+ setUsingFastModel(state.default_model === "gpt-3.5-turbo");
const shouldScrollToBottom =
topGuiDivRef.current &&
topGuiDivRef.current?.offsetHeight - window.scrollY < 100;
setWaitingForSteps(state.active);
setHistory(state.history);
setUserInputQueue(state.user_input_queue);
- const nextStepsOpen = [...stepsOpen];
- for (
- let i = nextStepsOpen.length;
- i < state.history.timeline.length;
- i++
- ) {
- nextStepsOpen.push(true);
- }
- setStepsOpen(nextStepsOpen);
+ setStepsOpen((prev) => {
+ const nextStepsOpen = [...prev];
+ for (
+ let i = nextStepsOpen.length;
+ i < state.history.timeline.length;
+ i++
+ ) {
+ nextStepsOpen.push(true);
+ }
+ return nextStepsOpen;
+ });
if (shouldScrollToBottom) {
scrollToBottom();
@@ -470,8 +473,11 @@ function GUI(props: GUIProps) {
Contribute Data
</span>
</div>
- {/* <HeaderButtonWithText
+ <HeaderButtonWithText
onClick={() => {
+ client?.changeDefaultModel(
+ usingFastModel ? "gpt-4" : "gpt-3.5-turbo"
+ );
setUsingFastModel((prev) => !prev);
}}
text={usingFastModel ? "gpt-3.5-turbo" : "gpt-4"}
@@ -481,7 +487,7 @@ function GUI(props: GUIProps) {
>
{usingFastModel ? "⚡" : "🧠"}
</div>
- </HeaderButtonWithText> */}
+ </HeaderButtonWithText>
<HeaderButtonWithText
onClick={() => {
client?.sendClear();
diff --git a/extension/scripts/continuedev-0.1.1-py3-none-any.whl b/extension/scripts/continuedev-0.1.1-py3-none-any.whl
index 99f96d80..29e41d3c 100644
--- a/extension/scripts/continuedev-0.1.1-py3-none-any.whl
+++ b/extension/scripts/continuedev-0.1.1-py3-none-any.whl
Binary files differ
diff --git a/extension/src/activation/activate.ts b/extension/src/activation/activate.ts
index 32726c86..c4bdbaa9 100644
--- a/extension/src/activation/activate.ts
+++ b/extension/src/activation/activate.ts
@@ -2,13 +2,12 @@ import * as vscode from "vscode";
import { registerAllCommands } from "../commands";
import { registerAllCodeLensProviders } from "../lang-server/codeLens";
import { sendTelemetryEvent, TelemetryEvent } from "../telemetry";
-import { getExtensionUri } from "../util/vscode";
-import * as path from "path";
// import { openCapturedTerminal } from "../terminal/terminalEmulator";
import IdeProtocolClient from "../continueIdeClient";
import { getContinueServerUrl } from "../bridge";
-import { setupDebugPanel, ContinueGUIWebviewViewProvider } from "../debugPanel";
import { CapturedTerminal } from "../terminal/terminalEmulator";
+import { setupDebugPanel, ContinueGUIWebviewViewProvider } from "../debugPanel";
+// import { CapturedTerminal } from "../terminal/terminalEmulator";
export let extensionContext: vscode.ExtensionContext | undefined = undefined;
@@ -49,41 +48,10 @@ export function activateExtension(
})();
// All opened terminals should be replaced by our own terminal
- vscode.window.onDidOpenTerminal((terminal) => {
- if (terminal.name === "Continue") {
- return;
- }
- const options = terminal.creationOptions;
- const capturedTerminal = new CapturedTerminal({
- ...options,
- name: "Continue",
- });
- terminal.dispose();
- if (!ideProtocolClient.continueTerminal) {
- ideProtocolClient.continueTerminal = capturedTerminal;
- }
- });
+ // vscode.window.onDidOpenTerminal((terminal) => {});
// If any terminals are open to start, replace them
- vscode.window.terminals.forEach((terminal) => {
- if (terminal.name === "Continue") {
- return;
- }
- const options = terminal.creationOptions;
- const capturedTerminal = new CapturedTerminal(
- {
- ...options,
- name: "Continue",
- },
- (commandOutput: string) => {
- ideProtocolClient.sendCommandOutput(commandOutput);
- }
- );
- terminal.dispose();
- if (!ideProtocolClient.continueTerminal) {
- ideProtocolClient.continueTerminal = capturedTerminal;
- }
- });
+ // vscode.window.terminals.forEach((terminal) => {}
extensionContext = context;
}
diff --git a/extension/src/commands.ts b/extension/src/commands.ts
index 22e15c43..77273343 100644
--- a/extension/src/commands.ts
+++ b/extension/src/commands.ts
@@ -3,7 +3,6 @@ import {
decorationManager,
showAnswerInTextEditor,
showGutterSpinner,
- writeAndShowUnitTest,
} from "./decorations";
import {
acceptSuggestionCommand,
@@ -12,19 +11,8 @@ import {
suggestionUpCommand,
} from "./suggestions";
import * as bridge from "./bridge";
-import { debugPanelWebview, setupDebugPanel } from "./debugPanel";
-// import { openCapturedTerminal } from "./terminal/terminalEmulator";
-import { getRightViewColumn } from "./util/vscode";
-import {
- findSuspiciousCode,
- runPythonScript,
- writeUnitTestForFunction,
-} from "./bridge";
+import { debugPanelWebview } from "./debugPanel";
import { sendTelemetryEvent, TelemetryEvent } from "./telemetry";
-import { getLanguageLibrary } from "./languages";
-import { SerializedDebugContext } from "./client";
-import { addFileSystemToDebugContext } from "./util/util";
-import { ideProtocolClient } from "./activation/activate";
// Copy everything over from extension.ts
const commandsMap: { [command: string]: (...args: any) => any } = {
@@ -67,72 +55,9 @@ const commandsMap: { [command: string]: (...args: any) => any } = {
type: "focusContinueInput",
});
},
- "continue.openCapturedTerminal": () => {
- // Happens in webview resolution function
- // openCapturedTerminal();
- },
- "continue.findSuspiciousCode": async (
- debugContext: SerializedDebugContext
- ) => {
- vscode.window.withProgress(
- {
- location: vscode.ProgressLocation.Notification,
- title: "Finding suspicious code",
- cancellable: false,
- },
- async (progress, token) => {
- let suspiciousCode = await findSuspiciousCode(debugContext);
- debugContext.rangesInFiles = suspiciousCode;
- let { filesystem } = addFileSystemToDebugContext(debugContext);
- debugPanelWebview?.postMessage({
- type: "findSuspiciousCode",
- codeLocations: suspiciousCode,
- filesystem,
- });
- }
- );
- },
- "continue.debugTest": async (fileAndFunctionSpecifier: string) => {
- sendTelemetryEvent(TelemetryEvent.AutoDebugThisTest);
- let editor = vscode.window.activeTextEditor;
- if (editor) editor.document.save();
- let { stdout } = await runPythonScript("run_unit_test.py", [
- fileAndFunctionSpecifier,
- ]);
- let traceback = getLanguageLibrary(
- fileAndFunctionSpecifier.split("::")[0]
- ).parseFirstStacktrace(stdout);
- if (!traceback) {
- vscode.window.showInformationMessage("The test passes!");
- return;
- }
- vscode.commands.executeCommand("continue.openContinueGUI").then(() => {
- setTimeout(() => {
- debugPanelWebview?.postMessage({
- type: "traceback",
- value: traceback,
- });
- }, 500);
- });
- },
};
const textEditorCommandsMap: { [command: string]: (...args: any) => {} } = {
- "continue.writeUnitTest": async (editor: vscode.TextEditor) => {
- let position = editor.selection.active;
-
- let gutterSpinnerKey = showGutterSpinner(editor, position.line);
- try {
- let test = await writeUnitTestForFunction(
- editor.document.fileName,
- position
- );
- writeAndShowUnitTest(editor.document.fileName, test);
- } catch {
- } finally {
- decorationManager.deleteDecoration(gutterSpinnerKey);
- }
- },
"continue.writeDocstring": async (editor: vscode.TextEditor, _) => {
sendTelemetryEvent(TelemetryEvent.GenerateDocstring);
let gutterSpinnerKey = showGutterSpinner(
@@ -199,20 +124,3 @@ async function answerQuestion(
}
);
}
-
-// async function suggestFixForAllWorkspaceProblems() {
-// Something like this, just figure out the loops for diagnostics vs problems
-// let problems = vscode.languages.getDiagnostics();
-// let codeSuggestions = await Promise.all(problems.map((problem) => {
-// return bridge.suggestFixForProblem(problem[0].fsPath, problem[1]);
-// }));
-// for (const [uri, diagnostics] of problems) {
-// for (let i = 0; i < diagnostics.length; i++) {
-// let diagnostic = diagnostics[i];
-// let suggestedCode = codeSuggestions[i];
-// // If you're going to do this for a bunch of files at once, it will show the unsaved icon in the tab
-// // BUT it would be better to have a single window to review all edits
-// showSuggestion(uri.fsPath, diagnostic.range, suggestedCode)
-// }
-// }
-// }
diff --git a/extension/src/continueIdeClient.ts b/extension/src/continueIdeClient.ts
index fbad5f5d..3a77e348 100644
--- a/extension/src/continueIdeClient.ts
+++ b/extension/src/continueIdeClient.ts
@@ -12,7 +12,6 @@ import { debugPanelWebview, setupDebugPanel } from "./debugPanel";
import { FileEditWithFullContents } from "../schema/FileEditWithFullContents";
import fs = require("fs");
import { WebsocketMessenger } from "./util/messenger";
-import { CapturedTerminal } from "./terminal/terminalEmulator";
import { decorationManager } from "./decorations";
class IdeProtocolClient {
@@ -326,17 +325,14 @@ class IdeProtocolClient {
return rangeInFiles;
}
- public continueTerminal: CapturedTerminal | undefined;
-
async runCommand(command: string) {
- if (!this.continueTerminal || this.continueTerminal.isClosed()) {
- this.continueTerminal = new CapturedTerminal({
- name: "Continue",
- });
+ if (vscode.window.terminals.length) {
+ vscode.window.terminals[0].sendText(command);
+ } else {
+ const terminal = vscode.window.createTerminal();
+ terminal.show();
+ terminal.sendText(command);
}
-
- this.continueTerminal.show();
- return await this.continueTerminal.runCommand(command);
}
sendCommandOutput(output: string) {
diff --git a/extension/src/debugPanel.ts b/extension/src/debugPanel.ts
index bb98eb46..b0db590a 100644
--- a/extension/src/debugPanel.ts
+++ b/extension/src/debugPanel.ts
@@ -1,21 +1,11 @@
import * as vscode from "vscode";
-import {
- debugApi,
- getContinueServerUrl,
- runPythonScript,
- unittestApi,
-} from "./bridge";
-import { writeAndShowUnitTest } from "./decorations";
-import { showSuggestion } from "./suggestions";
-import { getLanguageLibrary } from "./languages";
+import { getContinueServerUrl } from "./bridge";
import {
getExtensionUri,
getNonce,
openEditorAndRevealRange,
} from "./util/vscode";
-import { sendTelemetryEvent, TelemetryEvent } from "./telemetry";
-import { RangeInFile, SerializedDebugContext } from "./client";
-import { addFileSystemToDebugContext } from "./util/util";
+import { RangeInFile } from "./client";
const WebSocket = require("ws");
class StreamManager {
@@ -146,6 +136,9 @@ export function setupDebugPanel(
let extensionUri = getExtensionUri();
let scriptUri: string;
let styleMainUri: string;
+ let vscMediaUrl: string = debugPanelWebview
+ .asWebviewUri(vscode.Uri.joinPath(extensionUri, "react-app/dist"))
+ .toString();
const isProduction = true; // context?.extensionMode === vscode.ExtensionMode.Development;
if (!isProduction) {
@@ -236,6 +229,7 @@ export function setupDebugPanel(
vscMachineId: vscode.env.machineId,
apiUrl: getContinueServerUrl(),
sessionId,
+ vscMediaUrl,
});
// // Listen for changes to server URL in settings
@@ -273,71 +267,6 @@ export function setupDebugPanel(
connection.send(data.message);
break;
}
- case "listTenThings": {
- sendTelemetryEvent(TelemetryEvent.GenerateIdeas);
- let resp = await debugApi.listtenDebugListPost({
- serializedDebugContext: data.debugContext,
- });
- panel.webview.postMessage({
- type: "listTenThings",
- value: resp.completion,
- });
- break;
- }
- case "suggestFix": {
- let completion: string;
- let codeSelection = data.debugContext.rangesInFiles?.at(0);
- if (codeSelection) {
- completion = (
- await debugApi.inlineDebugInlinePost({
- inlineBody: {
- filecontents: await vscode.workspace.fs
- .readFile(vscode.Uri.file(codeSelection.filepath))
- .toString(),
- startline: codeSelection.range.start.line,
- endline: codeSelection.range.end.line,
- traceback: data.debugContext.traceback,
- },
- })
- ).completion;
- } else if (data.debugContext.traceback) {
- completion = (
- await debugApi.suggestionDebugSuggestionGet({
- traceback: data.debugContext.traceback,
- })
- ).completion;
- } else {
- break;
- }
- panel.webview.postMessage({
- type: "suggestFix",
- value: completion,
- });
- break;
- }
- case "findSuspiciousCode": {
- let traceback = getLanguageLibrary(".py").parseFirstStacktrace(
- data.debugContext.traceback
- );
- if (traceback === undefined) return;
- vscode.commands.executeCommand(
- "continue.findSuspiciousCode",
- data.debugContext
- );
- break;
- }
- case "queryEmbeddings": {
- let { results } = await runPythonScript("index.py query", [
- data.query,
- 2,
- vscode.workspace.workspaceFolders?.[0].uri.fsPath,
- ]);
- panel.webview.postMessage({
- type: "queryEmbeddings",
- results,
- });
- break;
- }
case "openFile": {
openEditorAndRevealRange(data.path, undefined, vscode.ViewColumn.One);
break;
@@ -351,20 +280,6 @@ export function setupDebugPanel(
streamManager.closeStream();
break;
}
- case "explainCode": {
- sendTelemetryEvent(TelemetryEvent.ExplainCode);
- let debugContext: SerializedDebugContext = addFileSystemToDebugContext(
- data.debugContext
- );
- let resp = await debugApi.explainDebugExplainPost({
- serializedDebugContext: debugContext,
- });
- panel.webview.postMessage({
- type: "explainCode",
- value: resp.completion,
- });
- break;
- }
case "withProgress": {
// This message allows withProgress to be used in the webview
if (data.done) {
@@ -395,83 +310,6 @@ export function setupDebugPanel(
);
break;
}
- case "makeEdit": {
- sendTelemetryEvent(TelemetryEvent.SuggestFix);
- let suggestedEdits = data.edits;
-
- if (
- typeof suggestedEdits === "undefined" ||
- suggestedEdits.length === 0
- ) {
- vscode.window.showInformationMessage(
- "Continue couldn't find a fix for this error."
- );
- return;
- }
-
- for (let i = 0; i < suggestedEdits.length; i++) {
- let edit = suggestedEdits[i];
- await showSuggestion(
- edit.filepath,
- new vscode.Range(
- edit.range.start.line,
- edit.range.start.character,
- edit.range.end.line,
- edit.range.end.character
- ),
- edit.replacement
- );
- }
- break;
- }
- case "generateUnitTest": {
- sendTelemetryEvent(TelemetryEvent.CreateTest);
- vscode.window.withProgress(
- {
- location: vscode.ProgressLocation.Notification,
- title: "Generating Unit Test...",
- cancellable: false,
- },
- async () => {
- for (let i = 0; i < data.debugContext.rangesInFiles?.length; i++) {
- let codeSelection = data.debugContext.rangesInFiles?.at(i);
- if (
- codeSelection &&
- codeSelection.filepath &&
- codeSelection.range
- ) {
- try {
- let filecontents = (
- await vscode.workspace.fs.readFile(
- vscode.Uri.file(codeSelection.filepath)
- )
- ).toString();
- let resp =
- await unittestApi.failingtestUnittestFailingtestPost({
- failingTestBody: {
- fp: {
- filecontents,
- lineno: codeSelection.range.end.line,
- },
- description: data.debugContext.description || "",
- },
- });
-
- if (resp.completion) {
- let decorationKey = await writeAndShowUnitTest(
- codeSelection.filepath,
- resp.completion
- );
- break;
- }
- } catch {}
- }
- }
- }
- );
-
- break;
- }
}
});
diff --git a/extension/src/decorations.ts b/extension/src/decorations.ts
index d2c94135..0587110c 100644
--- a/extension/src/decorations.ts
+++ b/extension/src/decorations.ts
@@ -1,7 +1,5 @@
import * as vscode from "vscode";
-import { getRightViewColumn, getTestFile } from "./util/vscode";
import * as path from "path";
-import { getLanguageLibrary } from "./languages";
export function showAnswerInTextEditor(
filename: string,
@@ -223,98 +221,3 @@ export function highlightCode(
return key;
}
-
-// Show unit test
-const pythonImportDistinguisher = (line: string): boolean => {
- if (line.startsWith("from") || line.startsWith("import")) {
- return true;
- }
- return false;
-};
-const javascriptImportDistinguisher = (line: string): boolean => {
- if (line.startsWith("import")) {
- return true;
- }
- return false;
-};
-const importDistinguishersMap: {
- [fileExtension: string]: (line: string) => boolean;
-} = {
- js: javascriptImportDistinguisher,
- ts: javascriptImportDistinguisher,
- py: pythonImportDistinguisher,
-};
-function getImportsFromFileString(
- fileString: string,
- importDistinguisher: (line: string) => boolean
-): Set<string> {
- let importLines = new Set<string>();
- for (let line of fileString.split("\n")) {
- if (importDistinguisher(line)) {
- importLines.add(line);
- }
- }
- return importLines;
-}
-function removeRedundantLinesFrom(
- fileContents: string,
- linesToRemove: Set<string>
-): string {
- let fileLines = fileContents.split("\n");
- fileLines = fileLines.filter((line: string) => {
- return !linesToRemove.has(line);
- });
- return fileLines.join("\n");
-}
-
-export async function writeAndShowUnitTest(
- filename: string,
- test: string
-): Promise<DecorationKey> {
- return new Promise((resolve, reject) => {
- let testFilename = getTestFile(filename, true);
- vscode.workspace.openTextDocument(testFilename).then((doc) => {
- let fileContent = doc.getText();
- let fileEmpty = fileContent.trim() === "";
- let existingImportLines = getImportsFromFileString(
- fileContent,
- importDistinguishersMap[doc.fileName.split(".").at(-1) || ".py"]
- );
-
- // Remove redundant imports, make sure pytest is there
- test = removeRedundantLinesFrom(test, existingImportLines);
- test =
- (fileEmpty
- ? `${getLanguageLibrary(".py").writeImport(
- testFilename,
- filename
- )}\nimport pytest\n\n`
- : "\n\n") +
- test.trim() +
- "\n";
-
- vscode.window
- .showTextDocument(doc, getRightViewColumn())
- .then((editor) => {
- let lastLine = editor.document.lineAt(editor.document.lineCount - 1);
- let testRange = new vscode.Range(
- lastLine.range.end,
- new vscode.Position(
- test.split("\n").length + lastLine.range.end.line,
- 0
- )
- );
- editor
- .edit((edit) => {
- edit.insert(lastLine.range.end, test);
- return true;
- })
- .then((success) => {
- if (!success) reject("Failed to insert test");
- let key = highlightCode(editor, testRange);
- resolve(key);
- });
- });
- });
- });
-}
diff --git a/extension/src/lang-server/codeLens.ts b/extension/src/lang-server/codeLens.ts
index 2a362b62..26528d96 100644
--- a/extension/src/lang-server/codeLens.ts
+++ b/extension/src/lang-server/codeLens.ts
@@ -1,5 +1,4 @@
import * as vscode from "vscode";
-import { getLanguageLibrary } from "../languages";
import { editorToSuggestions } from "../suggestions";
class SuggestionsCodeLensProvider implements vscode.CodeLensProvider {
@@ -52,40 +51,9 @@ class SuggestionsCodeLensProvider implements vscode.CodeLensProvider {
}
}
-class PytestCodeLensProvider implements vscode.CodeLensProvider {
- public provideCodeLenses(
- document: vscode.TextDocument,
- token: vscode.CancellationToken
- ): vscode.CodeLens[] | Thenable<vscode.CodeLens[]> {
- let codeLenses: vscode.CodeLens[] = [];
- let lineno = 1;
- let languageLibrary = getLanguageLibrary(document.fileName);
- for (let line of document.getText().split("\n")) {
- if (
- languageLibrary.lineIsFunctionDef(line) &&
- languageLibrary.parseFunctionDefForName(line).startsWith("test_")
- ) {
- let functionToTest = languageLibrary.parseFunctionDefForName(line);
- let fileAndFunctionNameSpecifier =
- document.fileName + "::" + functionToTest;
- codeLenses.push(
- new vscode.CodeLens(new vscode.Range(lineno, 0, lineno, 1), {
- title: "Debug This Test",
- command: "continue.debugTest",
- arguments: [fileAndFunctionNameSpecifier],
- })
- );
- }
- lineno++;
- }
-
- return codeLenses;
- }
-}
-
const allCodeLensProviders: { [langauge: string]: vscode.CodeLensProvider[] } =
{
- python: [new SuggestionsCodeLensProvider(), new PytestCodeLensProvider()],
+ python: [new SuggestionsCodeLensProvider()],
};
export function registerAllCodeLensProviders(context: vscode.ExtensionContext) {
diff --git a/extension/src/languages/index.d.ts b/extension/src/languages/index.d.ts
deleted file mode 100644
index be7ddfbc..00000000
--- a/extension/src/languages/index.d.ts
+++ /dev/null
@@ -1,13 +0,0 @@
-export interface LanguageLibrary {
- language: string;
- fileExtensions: string[];
- parseFirstStacktrace: (stdout: string) => string | undefined;
- lineIsFunctionDef: (line: string) => boolean;
- parseFunctionDefForName: (line: string) => string;
- lineIsComment: (line: string) => boolean;
- writeImport: (
- sourcePath: string,
- pathToImport: string,
- namesToImport?: string[] | undefined
- ) => string;
-}
diff --git a/extension/src/languages/index.ts b/extension/src/languages/index.ts
deleted file mode 100644
index 31d73a0b..00000000
--- a/extension/src/languages/index.ts
+++ /dev/null
@@ -1,19 +0,0 @@
-import pythonLanguageLibrary from "./python";
-import javascriptLanguageLibrary from "./javascript";
-import { LanguageLibrary } from "./index.d";
-
-export const languageLibraries: LanguageLibrary[] = [
- pythonLanguageLibrary,
- javascriptLanguageLibrary,
-];
-
-export function getLanguageLibrary(filepath: string): LanguageLibrary {
- for (let languageLibrary of languageLibraries) {
- for (let fileExtension of languageLibrary.fileExtensions) {
- if (filepath.endsWith(fileExtension)) {
- return languageLibrary;
- }
- }
- }
- throw new Error(`No language library found for file ${filepath}`);
-}
diff --git a/extension/src/languages/javascript/index.ts b/extension/src/languages/javascript/index.ts
deleted file mode 100644
index 1c21a2fc..00000000
--- a/extension/src/languages/javascript/index.ts
+++ /dev/null
@@ -1,16 +0,0 @@
-import { LanguageLibrary } from "../index.d";
-import { notImplemented } from "../notImplemented";
-
-const NI = (propertyName: string) => notImplemented(propertyName, "javascript");
-
-const javascriptLangaugeLibrary: LanguageLibrary = {
- language: "javascript",
- fileExtensions: [".js", ".jsx", ".ts", ".tsx"],
- parseFirstStacktrace: NI("parseFirstStacktrace"),
- lineIsFunctionDef: NI("lineIsFunctionDef"),
- parseFunctionDefForName: NI("parseFunctionDefForName"),
- lineIsComment: NI("lineIsComment"),
- writeImport: NI("writeImport"),
-};
-
-export default javascriptLangaugeLibrary;
diff --git a/extension/src/languages/notImplemented.ts b/extension/src/languages/notImplemented.ts
deleted file mode 100644
index bbba2382..00000000
--- a/extension/src/languages/notImplemented.ts
+++ /dev/null
@@ -1,10 +0,0 @@
-export function notImplemented(
- propertyName: string,
- langauge: string
-): (...args: any[]) => never {
- return (...args: any[]) => {
- throw new Error(
- `Property ${propertyName} not implemented for language ${langauge}.`
- );
- };
-}
diff --git a/extension/src/languages/python/index.ts b/extension/src/languages/python/index.ts
deleted file mode 100644
index 50282b45..00000000
--- a/extension/src/languages/python/index.ts
+++ /dev/null
@@ -1,74 +0,0 @@
-import path = require("path");
-import { LanguageLibrary } from "../index.d";
-
-const tracebackStart = "Traceback (most recent call last):";
-const tracebackEnd = (buf: string): string | undefined => {
- let lines = buf
- .split("\n")
- .filter((line: string) => line.trim() !== "~~^~~")
- .filter((line: string) => line.trim() !== "");
- for (let i = 0; i < lines.length; i++) {
- if (
- lines[i].startsWith(" File") &&
- i + 2 < lines.length &&
- lines[i + 2][0] !== " "
- ) {
- return lines.slice(0, i + 3).join("\n");
- }
- }
- return undefined;
-};
-
-function parseFirstStacktrace(stdout: string): string | undefined {
- let startIdx = stdout.indexOf(tracebackStart);
- if (startIdx < 0) return undefined;
- stdout = stdout.substring(startIdx);
- return tracebackEnd(stdout);
-}
-
-function lineIsFunctionDef(line: string): boolean {
- return line.startsWith("def ");
-}
-
-function parseFunctionDefForName(line: string): string {
- return line.split("def ")[1].split("(")[0];
-}
-
-function lineIsComment(line: string): boolean {
- return line.trim().startsWith("#");
-}
-
-function writeImport(
- sourcePath: string,
- pathToImport: string,
- namesToImport: string[] | undefined = undefined
-): string {
- let segs = path.relative(sourcePath, pathToImport).split(path.sep);
- let importFrom = "";
- for (let seg of segs) {
- if (seg === "..") {
- importFrom = "." + importFrom;
- } else {
- if (!importFrom.endsWith(".")) {
- importFrom += ".";
- }
- importFrom += seg.split(".").slice(0, -1).join(".");
- }
- }
-
- return `from ${importFrom} import ${
- namesToImport ? namesToImport.join(", ") : "*"
- }`;
-}
-
-const pythonLangaugeLibrary: LanguageLibrary = {
- language: "python",
- fileExtensions: [".py"],
- parseFirstStacktrace,
- lineIsFunctionDef,
- parseFunctionDefForName,
- lineIsComment,
- writeImport,
-};
-
-export default pythonLangaugeLibrary;