├── images
├── header.png
├── logo.png
└── logo.svg
├── .gitignore
├── .vscodeignore
├── tsconfig.json
├── .vscode
├── tasks.json
└── launch.json
├── .eslintrc.js
├── src
├── utils
│ ├── errors.ts
│ ├── email.ts
│ └── comments.ts
└── extension.ts
├── README.md
└── package.json
/images/header.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VaibhavAcharya/code-gpt/HEAD/images/header.png
--------------------------------------------------------------------------------
/images/logo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/VaibhavAcharya/code-gpt/HEAD/images/logo.png
--------------------------------------------------------------------------------
/.gitignore:
--------------------------------------------------------------------------------
1 | out
2 | node_modules
3 | .vscode-test/
4 | *.vsix
5 | vscode.d.ts
6 | pnpm-lock.yaml
7 |
--------------------------------------------------------------------------------
/.vscodeignore:
--------------------------------------------------------------------------------
1 | .vscode/**
2 | .vscode-test/**
3 | out/test/**
4 | out/**/*.map
5 | src/**
6 | .gitignore
7 | tsconfig.json
8 | vsc-extension-quickstart.md
9 | tslint.json
--------------------------------------------------------------------------------
/tsconfig.json:
--------------------------------------------------------------------------------
1 | {
2 | "compilerOptions": {
3 | "module": "commonjs",
4 | "target": "es2020",
5 | "outDir": "out",
6 | "sourceMap": true,
7 | "rootDir": "src",
8 | "strict": true
9 | },
10 | "exclude": ["node_modules", ".vscode-test"]
11 | }
12 |
--------------------------------------------------------------------------------
/.vscode/tasks.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "2.0.0",
3 | "tasks": [
4 | {
5 | "type": "npm",
6 | "script": "watch",
7 | "problemMatcher": "$tsc-watch",
8 | "isBackground": true,
9 | "presentation": {
10 | "reveal": "never"
11 | },
12 | "group": {
13 | "kind": "build",
14 | "isDefault": true
15 | }
16 | }
17 | ]
18 | }
--------------------------------------------------------------------------------
/.eslintrc.js:
--------------------------------------------------------------------------------
1 | /**@type {import('eslint').Linter.Config} */
2 | // eslint-disable-next-line no-undef
3 | module.exports = {
4 | root: true,
5 | parser: '@typescript-eslint/parser',
6 | plugins: [
7 | '@typescript-eslint',
8 | ],
9 | extends: [
10 | 'eslint:recommended',
11 | 'plugin:@typescript-eslint/recommended',
12 | ],
13 | rules: {
14 | 'semi': [2, "always"],
15 | '@typescript-eslint/no-unused-vars': 0,
16 | '@typescript-eslint/no-explicit-any': 0,
17 | '@typescript-eslint/explicit-module-boundary-types': 0,
18 | '@typescript-eslint/no-non-null-assertion': 0,
19 | }
20 | };
--------------------------------------------------------------------------------
/src/utils/errors.ts:
--------------------------------------------------------------------------------
1 | import { window } from "vscode";
2 |
3 | const errorMessages = {
4 | noEditor: "Error: Editor not found! 😵",
5 | noEmail: "Error: Email is required! It is to protect us from unlimited use. We won't spam your email, promise. 🤝",
6 | noSelection: "Nothing selected. 😅",
7 | languageNotSupported: "Error: Language not supported yet! 😵",
8 | unableToConnect: "Error: Unable to connect to server! 💀",
9 | serverSentNothing: "Server sent nothing! 🙃",
10 | };
11 |
12 | export const displayError = (error: keyof typeof errorMessages) => {
13 | return window.showErrorMessage(errorMessages[error]);
14 | };
15 |
--------------------------------------------------------------------------------
/.vscode/launch.json:
--------------------------------------------------------------------------------
1 | {
2 | "version": "0.2.0",
3 | "configurations": [{
4 | "name": "Run Extension",
5 | "type": "extensionHost",
6 | "request": "launch",
7 | "runtimeExecutable": "${execPath}",
8 | "args": [
9 | "--extensionDevelopmentPath=${workspaceFolder}"
10 | ],
11 | "outFiles": [
12 | "${workspaceFolder}/out/**/*.js"
13 | ],
14 | "preLaunchTask": "npm: watch"
15 | },
16 | {
17 | "name": "Run Extension Tests",
18 | "type": "extensionHost",
19 | "request": "launch",
20 | "runtimeExecutable": "${execPath}",
21 | "args": [
22 | "--extensionDevelopmentPath=${workspaceFolder}",
23 | "--extensionTestsPath=${workspaceFolder}/out/test"
24 | ],
25 | "outFiles": [
26 | "${workspaceFolder}/out/test/**/*.js"
27 | ],
28 | "preLaunchTask": "npm: watch"
29 | }
30 | ]
31 | }
32 |
--------------------------------------------------------------------------------
/src/utils/email.ts:
--------------------------------------------------------------------------------
1 | import { type ExtensionContext, window } from "vscode";
2 |
3 | export const checkEmail = async (context: ExtensionContext) => {
4 | const email = await context.globalState.get("email");
5 |
6 | // If the email has not been saved, ask the user for their email
7 | if (!email) {
8 | const newEmail = await window.showInputBox({
9 | title: "Code-GPT",
10 | placeHolder: "📧 Enter your email",
11 | prompt: "To protect us from unlimited use. We won't spam your email, promise. 🤝",
12 | validateInput: (value) => {
13 | const emailRegex =
14 | /^(([^<>()[\]\\.,;:\s@"]+(\.[^<>()[\]\\.,;:\s@"]+)*)|(".+"))@((\[[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\.[0-9]{1,3}\])|(([a-zA-Z\-0-9]+\.)+[a-zA-Z]{2,}))$/;
15 |
16 | if (!emailRegex.test(value)) {
17 | return "Error: Invalid email. ☹";
18 | }
19 |
20 | return null;
21 | },
22 | });
23 |
24 | await context.globalState.update("email", newEmail);
25 | }
26 | };
27 |
--------------------------------------------------------------------------------
/images/logo.svg:
--------------------------------------------------------------------------------
1 |
16 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | 
2 |
3 | # [Code-GPT](https://marketplace.visualstudio.com/items?itemName=vaibhavacharya.code-gpt-va) — Make sense of any code, anytime. 🚀
4 |
5 | ## Introduction 👋
6 |
7 | Code-GPT is an extension for VS Code that provides you **instant explanations for your code** within the code editor using AI.
8 |
9 | With Code-GPT, you can:
10 | - 🧠 Get instant explanations for selected code in real-time
11 | - 💡 Increase your coding understanding and efficiency
12 | - ⏳ Save time and minimize frustration with clear code explanations
13 | - 🔍 Improve your coding skills with in-depth code analysis
14 |
15 | ## Demo 📽
16 | [](https://www.aiproducttools.com/images/codegpt/demo.mp4)
17 |
18 | ## Installation 📦
19 |
20 | 1. Open VS Code and click on the Extensions icon in the left sidebar
21 | 2. Search for "Code-GPT" in the Extensions Marketplace
22 | 3. Click on the Install button for "Code-GPT"
23 |
24 | ## How to Use Code-GPT 🛠
25 |
26 | 1. Select the code you want to understand in your VSCode editor
27 | 2. Open the Command Palette (press `Ctrl + Shift + P` or `Cmd + Shift + P` on Mac)
28 | 3. Type "Explain Selected Code" and select the command from the list
29 | 4. Enter your email address if prompted
30 | 5. Wait for the response and the explanation will be prepended to the selected code in your VSCode editor
31 |
32 | Enjoy the instant and comprehensive code explanations with Code-GPT! 🎉
33 |
34 | ## Author ✏
35 |
36 | - Twitter → [@VaibhavAcharya_](https://twitter.com/VaibhavAcharya_)
37 | - Website → [vaibhavacharya.github.io](https://vaibhavacharya.github.io)
38 | - GitHub → [VaibhavAcharya](https://github.com/VaibhavAcharya)
39 |
--------------------------------------------------------------------------------
/src/utils/comments.ts:
--------------------------------------------------------------------------------
1 | const singleLineCommentMap: Record = {
2 | abap: "--",
3 | bat: "::",
4 | bibtex: "%",
5 | clojure: ";",
6 | coffeescript: "#",
7 | c: "//",
8 | cpp: "//",
9 | csharp: "//",
10 | "cuda-cpp": "//",
11 | diff: "//",
12 | dockerfile: "#",
13 | fsharp: "//",
14 | "git-commit": "#",
15 | "git-rebase": "#",
16 | go: "//",
17 | groovy: "//",
18 | ini: ";",
19 | java: "//",
20 | javascript: "//",
21 | javascriptreact: "//",
22 | json: "//",
23 | jsonc: "//",
24 | latex: "%",
25 | less: "/*",
26 | lua: "--",
27 | makefile: "#",
28 | objectivec: "//",
29 | objectivecpp: "//",
30 | perl: "#",
31 | perl6: "#",
32 | php: "//",
33 | plaintext: "//",
34 | powershell: "#",
35 | jade: "//",
36 | pug: "//",
37 | python: "#",
38 | r: "#",
39 | razor: "@*",
40 | ruby: "#",
41 | rust: "//",
42 | sass: "//",
43 | shaderlab: "//",
44 | shellscript: "#",
45 | sql: "--",
46 | slim: "//",
47 | stylus: "//",
48 | swift: "//",
49 | typescript: "//",
50 | typescriptreact: "//",
51 | tex: "%",
52 | vb: "'",
53 | yaml: "#",
54 | };
55 |
56 | const multiLineCommentMap: Record = {
57 | css: ["/*", "*/"],
58 | handlebars: ["{{!--", "--}}"],
59 | html: [""],
60 | markdown: [""],
61 | scss: ["/*", "*/"],
62 | xml: [""],
63 | xsl: [""],
64 | };
65 |
66 | export const styleAsComment = (text: string, lang: string) => {
67 | const singleLineComment = singleLineCommentMap[lang];
68 | const multiLineComment = multiLineCommentMap[lang];
69 |
70 | if (!singleLineComment && !multiLineComment) return text;
71 |
72 | if (singleLineComment) return `${singleLineComment} ${text}`;
73 | if (multiLineComment) return `${multiLineComment[0]} ${text} ${multiLineComment[1]}`;
74 | };
75 |
76 | export const languageSupportsComments = (lang: string) => {
77 | return !!singleLineCommentMap[lang] || !!multiLineCommentMap[lang];
78 | };
79 |
--------------------------------------------------------------------------------
/package.json:
--------------------------------------------------------------------------------
1 | {
2 | "name": "code-gpt-va",
3 | "displayName": "Code-GPT — Make sense of any code, anytime. 🚀",
4 | "description": "Provides you instant explanations for your code within the code editor using AI.",
5 | "icon": "images/logo.png",
6 | "galleryBanner": {
7 | "color": "#000000",
8 | "theme": "dark"
9 | },
10 | "version": "0.0.6",
11 | "publisher": "vaibhavacharya",
12 | "author": {
13 | "name": "Vaibhav Acharya",
14 | "email": "vaibhavacharya111@gmail.com",
15 | "url": "https://www.twitter.com/VaibhavAcharya_"
16 | },
17 | "engines": {
18 | "vscode": "^1.74.0"
19 | },
20 | "private": true,
21 | "license": "MIT",
22 | "repository": {
23 | "type": "git",
24 | "url": "https://github.com/VaibhavAcharya/code-gpt"
25 | },
26 | "bugs": {
27 | "url": "https://github.com/VaibhavAcharya/code-gpt/issues"
28 | },
29 | "categories": [
30 | "Machine Learning",
31 | "Other"
32 | ],
33 | "keywords": [
34 | "ai",
35 | "code",
36 | "explanation",
37 | "comments"
38 | ],
39 | "activationEvents": [
40 | "*"
41 | ],
42 | "main": "./out/extension.js",
43 | "contributes": {
44 | "commands": [
45 | {
46 | "command": "extension.commentSelectedCode",
47 | "title": "Code-GPT → Comment Selected Code"
48 | },
49 | {
50 | "command": "extension.explainSelectedCode",
51 | "title": "Code-GPT → Explain Selected Code"
52 | }
53 | ],
54 | "menus": {
55 | "editor/context": [
56 | {
57 | "command": "extension.commentSelectedCode",
58 | "when": "editorHasSelection"
59 | },
60 | {
61 | "command": "extension.explainSelectedCode",
62 | "when": "editorHasSelection"
63 | }
64 | ]
65 | }
66 | },
67 | "scripts": {
68 | "vscode:prepublish": "npm run compile",
69 | "compile": "tsc -p ./",
70 | "lint": "eslint \"src/**/*.ts\"",
71 | "watch": "tsc -watch -p ./"
72 | },
73 | "devDependencies": {
74 | "@types/node": "^16.11.7",
75 | "@types/vscode": "1.74.0",
76 | "@typescript-eslint/eslint-plugin": "^5.42.0",
77 | "@typescript-eslint/parser": "^5.42.0",
78 | "eslint": "^8.26.0",
79 | "typescript": "^4.8.4"
80 | },
81 | "dependencies": {
82 | "@octokit/rest": "^18.0.0",
83 | "axios": "^1.3.2"
84 | }
85 | }
86 |
--------------------------------------------------------------------------------
/src/extension.ts:
--------------------------------------------------------------------------------
1 | import { type ExtensionContext, window, commands } from "vscode";
2 | import axios from "axios";
3 |
4 | import { checkEmail } from "./utils/email";
5 | import { displayError } from "./utils/errors";
6 | import { languageSupportsComments, styleAsComment } from "./utils/comments";
7 |
8 | // Function to handle the selected code
9 | const commentSelectedCode = async (context: ExtensionContext) => {
10 | // Check if the email has been saved or not
11 | await checkEmail(context);
12 | const email = await context.globalState.get("email");
13 | if (!email) return displayError("noEmail");
14 |
15 | // Grab the editor window
16 | const editor = window.activeTextEditor;
17 | if (!editor) return displayError("noEditor");
18 |
19 | // Aquire the selected text
20 | const selection = editor.selection;
21 | const selectedText = editor.document.getText(selection);
22 | if (!selectedText.length) return displayError("noSelection");
23 |
24 | const lang = editor.document.languageId;
25 | const isLanguageSupported = languageSupportsComments(lang);
26 | if (!isLanguageSupported) return displayError("languageNotSupported");
27 |
28 | // Send the selected code and email to the API
29 | try {
30 | const { data } = await axios.post("https://www.aiproducttools.com/api/codegpt", {
31 | email,
32 | input: selectedText,
33 | lang,
34 | });
35 |
36 | if (!data.output) return displayError("serverSentNothing");
37 |
38 | // Get the output from the API response
39 | const output = data.output.trim();
40 |
41 | // Wrap the output in a comment
42 | const comment = styleAsComment(output, lang);
43 |
44 | // Replace the selected text with the output
45 | editor.edit((editBuilder) => {
46 | editBuilder.insert(selection.start, `${comment}\n`);
47 | });
48 | } catch (error) {
49 | console.error(error);
50 | return displayError("unableToConnect");
51 | }
52 | };
53 |
54 | // Function to handle the selected code
55 | const explainSelectedCode = async (context: ExtensionContext) => {
56 | // Check if the email has been saved or not
57 | await checkEmail(context);
58 | const email = await context.globalState.get("email");
59 | if (!email) return displayError("noEmail");
60 |
61 | // Grab the editor window
62 | const editor = window.activeTextEditor;
63 | if (!editor) return displayError("noEditor");
64 |
65 | // Aquire the selected text
66 | const selection = editor.selection;
67 | const selectedText = editor.document.getText(selection);
68 | if (!selectedText.length) return displayError("noSelection");
69 |
70 | const lang = editor.document.languageId;
71 | const isLanguageSupported = languageSupportsComments(lang);
72 | if (!isLanguageSupported) return displayError("languageNotSupported");
73 |
74 | // Send the selected code and email to the API
75 | try {
76 | const { data } = await axios.post("https://www.aiproducttools.com/api/codegpt", {
77 | email,
78 | input: selectedText,
79 | lang,
80 | });
81 |
82 | if (!data.output) return displayError("serverSentNothing");
83 |
84 | // Get the output from the API response
85 | const output = data.output.trim();
86 |
87 | // Show the output in a message
88 | window.showInformationMessage(output)
89 |
90 | } catch (error) {
91 | console.error(error);
92 | return displayError("unableToConnect");
93 | }
94 | };
95 |
96 | // Register the "Explain Selected Code" command
97 | export function activate(context: ExtensionContext) {
98 | const registerComment = commands.registerCommand("extension.commentSelectedCode", () => commentSelectedCode(context));
99 | const registerExplain = commands.registerCommand("extension.explainSelectedCode", () => explainSelectedCode(context));
100 | context.subscriptions.push(registerComment);
101 | context.subscriptions.push(registerExplain);
102 | }
103 |
104 | // Deactivate the extension
105 | export function deactivate() {
106 | return null;
107 | }
108 |
--------------------------------------------------------------------------------