├── 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 | 2 | 3 | 4 | 5 | 6 | 7 | 8 | 9 | 10 | 11 | 12 | 13 | 14 | 15 | 16 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | ![header](https://www.aiproducttools.com/images/codegpt/header.png) 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 | [![demo video](https://www.aiproducttools.com/images/codegpt/demo.gif)](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 | --------------------------------------------------------------------------------