From b37992215d4f8edfbbdf67c3b78c42cfe879a3d9 Mon Sep 17 00:00:00 2001 From: rohansh-tty Date: Sun, 5 Mar 2023 15:52:35 +0530 Subject: [PATCH 1/9] Fixed .git folder check bug - Handling this case in catch block --- src/getRemoteUrl.ts | 94 +++++++++++++++++++-------------------------- 1 file changed, 40 insertions(+), 54 deletions(-) diff --git a/src/getRemoteUrl.ts b/src/getRemoteUrl.ts index dcf7034..1c070e8 100644 --- a/src/getRemoteUrl.ts +++ b/src/getRemoteUrl.ts @@ -1,21 +1,9 @@ import { simpleGit, SimpleGit, CleanOptions } from 'simple-git'; import * as vscode from 'vscode'; import * as path from 'path'; -import { statSync } from 'fs'; +import fs from 'fs'; -function isGitDirectory() { - try { - statSync('.git'); - return true; - } - catch (err: any) { - if (err.code === 'ENOENT') { - return false; - } - } -} - class GetRemoteURL { context: vscode.ExtensionContext; @@ -24,50 +12,48 @@ class GetRemoteURL { } async findURL() { - if (!isGitDirectory()) { - vscode.window.showErrorMessage("Remote URL not found because it is not a Git repository"); - } - else { - try { - let currentFilePath: string = vscode.window.activeTextEditor!.document.fileName; - let parentDir: string = path.dirname(currentFilePath); - let localgit: SimpleGit = simpleGit(parentDir).clean(CleanOptions.FORCE); - - const gitRemotes = await localgit.getRemotes(true); - const branchSummary = await localgit.branch(); - const currentBranch = branchSummary.current; - const remoteURL = gitRemotes[0]['refs']['push']; - - const rootDir = await localgit.revparse(['--show-toplevel']); - const relativePath = path.relative(rootDir, currentFilePath); // find relative path b/w root and current working directory - - let gitRepoURL = remoteURL; - let gitURLPrefix; - if (!remoteURL.startsWith('git@') && (!remoteURL.startsWith('https'))) { - vscode.window.showErrorMessage("URL not found. Currently supports Github only (both HTTPS and SSH)"); + try { + let currentFilePath: string = vscode.window.activeTextEditor!.document.fileName; + let parentDir: string = path.dirname(currentFilePath); + let localgit: SimpleGit = simpleGit(parentDir).clean(CleanOptions.FORCE); + + const gitRemotes = await localgit.getRemotes(true); + const branchSummary = await localgit.branch(); + const currentBranch = branchSummary.current; + const remoteURL = gitRemotes[0]['refs']['push']; + + const rootDir = await localgit.revparse(['--show-toplevel']); + const relativePath = path.relative(rootDir, currentFilePath); // find relative path b/w root and current working directory + + let gitRepoURL = remoteURL; + let gitURLPrefix; + if (!remoteURL.startsWith('git@') && (!remoteURL.startsWith('https'))) { + vscode.window.showErrorMessage("URL not found. Currently supports Github only (both HTTPS and SSH)"); + } + else { + if (remoteURL.startsWith('git@')) { + gitRepoURL = remoteURL.split('@')[1]; // split with @ and get the repo url + gitURLPrefix = "https://"; } - else { - if (remoteURL.startsWith('git@')) { - gitRepoURL = remoteURL.split('@')[1]; // split with @ and get the repo url - gitURLPrefix = "https://"; - } - else if (remoteURL.startsWith('https')) { - const stripdotgit = remoteURL.substring(0, remoteURL.length - 4) + '/blob/'; // remove .git - gitURLPrefix = ""; - } - const stripdotgit = gitRepoURL.substring(0, gitRepoURL.length - 4) + '/blob/'; // remove .git - const replacecolon = stripdotgit.replace(':', '/'); // replace colon with forward slash - const result = gitURLPrefix + replacecolon + currentBranch + '/' + relativePath; - vscode.window.showInformationMessage("Remote URL successfully found and copied to clipboard"); - vscode.env.clipboard.writeText(result.toString()); + else if (remoteURL.startsWith('https')) { + const stripdotgit = remoteURL.substring(0, remoteURL.length - 4) + '/blob/'; // remove .git + gitURLPrefix = ""; } - return 'SUCCESS'; - } - catch (e) { - /* handle all errors here */ - console.log('ERROR:', e); - return 'FAILED'; + const stripdotgit = gitRepoURL.substring(0, gitRepoURL.length - 4) + '/blob/'; // remove .git + const replacecolon = stripdotgit.replace(':', '/'); // replace colon with forward slash + const result = gitURLPrefix + replacecolon + currentBranch + '/' + relativePath; + vscode.window.showInformationMessage("Remote URL successfully found and copied to clipboard"); + vscode.env.clipboard.writeText(result.toString()); } + return 'SUCCESS'; + } + catch (error: any) { + /* handle all errors here */ + const errorMessage = error.message; + // console.log('ERROR:', errMessage); + vscode.window.showErrorMessage("URL not found because " + errorMessage); + + return 'FAILED'; } } } From 2440e00ad94a5aa7c744306424ffff7ea04a56e2 Mon Sep 17 00:00:00 2001 From: Shrijith Venkatramana Date: Sun, 5 Mar 2023 16:11:16 +0530 Subject: [PATCH 2/9] Remove unused fs --- src/getRemoteUrl.ts | 1 - 1 file changed, 1 deletion(-) diff --git a/src/getRemoteUrl.ts b/src/getRemoteUrl.ts index 1c070e8..8a4ce42 100644 --- a/src/getRemoteUrl.ts +++ b/src/getRemoteUrl.ts @@ -1,7 +1,6 @@ import { simpleGit, SimpleGit, CleanOptions } from 'simple-git'; import * as vscode from 'vscode'; import * as path from 'path'; -import fs from 'fs'; class GetRemoteURL { From 806dbd377a606cb8b741726f05776958bb30c152 Mon Sep 17 00:00:00 2001 From: Shrijith Venkatramana Date: Sun, 5 Mar 2023 16:11:29 +0530 Subject: [PATCH 3/9] 2.4.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 18c5b1e..6321b6e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "Lama2", - "version": "2.3.0", + "version": "2.4.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "Lama2", - "version": "2.3.0", + "version": "2.4.0", "license": "SEE LICENSE IN LICENSE", "dependencies": { "ansi-to-html": "^0.7.2", diff --git a/package.json b/package.json index 2bba428..a96f8f0 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "Lama2", "displayName": "Lama2", "description": "Nifty VSCode UI for Lama2, the plain-text powered API client", - "version": "2.3.0", + "version": "2.4.0", "publisher": "Hexmos", "license": "SEE LICENSE IN LICENSE", "icon": "lama2.png", From 115f913e98c2b47023fb19bc58d8289652d0b79b Mon Sep 17 00:00:00 2001 From: Shrijith Venkatramana Date: Sun, 5 Mar 2023 16:11:40 +0530 Subject: [PATCH 4/9] 2.5.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 6321b6e..034f51e 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "Lama2", - "version": "2.4.0", + "version": "2.5.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "Lama2", - "version": "2.4.0", + "version": "2.5.0", "license": "SEE LICENSE IN LICENSE", "dependencies": { "ansi-to-html": "^0.7.2", diff --git a/package.json b/package.json index a96f8f0..09db1f5 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "Lama2", "displayName": "Lama2", "description": "Nifty VSCode UI for Lama2, the plain-text powered API client", - "version": "2.4.0", + "version": "2.5.0", "publisher": "Hexmos", "license": "SEE LICENSE IN LICENSE", "icon": "lama2.png", From 4e93b77ddddeaf9373075ad13cbd415ef45565b4 Mon Sep 17 00:00:00 2001 From: Shrijith Venkatramana Date: Mon, 6 Mar 2023 16:58:36 +0530 Subject: [PATCH 5/9] Autocomplete improvement --- src/extension.ts | 349 ++++++++++++++++++++++++++++++----------------- 1 file changed, 221 insertions(+), 128 deletions(-) diff --git a/src/extension.ts b/src/extension.ts index e50aff7..50ca237 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,19 +1,14 @@ import * as vscode from "vscode"; import * as fs from "fs"; import * as path from "path"; +import { exec } from "child_process"; + import ExecuteCurrentFile from "./executeCurrentFile"; import GenerateCodeSnippet from "./generateCodeSnippet"; import GetRemoteURL from "./getRemoteUrl"; import LanguagesData from "./languages"; -import { exec } from 'child_process'; import triggers from "./triggers"; -let examplesJSONStr = - '{"0006_cookies.l2":"POST \\nhttps://httpbin.org/post\\n\\n# HEADERS\\nCookie:\\"sessionid=foo;another-cookie=bar\\"\\n\\nHeader1:value1\\nHeader2: Value2\\n\\n# DATA\\nhello=world","0002_sample_post.l2":"POST\\nhttps://httpbin.org/post\\n\\n{\\n \\"a\\": \\"b\\",\\n \\"c\\": \\"d\\"\\n}","0005_headers_simple.l2":"POST \\nhttps://httpbin.org/post\\n\\n# HEADERS\\nX-Parse-Application-Id:\'helloworld\'\\nX-Parse-REST-API-Key:\\"byeworld\\"\\n\\n# DATA\\na=\\"b\\" # double-quoted string\\n\'c\'=d # single-quoted & unquoted strings","0008_base64_image":{"0008_base64_image.l2":"POST\\nhttp://httpbin.org/post\\n\\n{\\n\\t\\"imageb64_field\\": \\"\'${PHOTO}\'\\",\\n}","l2.env":"\\nexport PHOTO=`base64 image.jpeg`"},"0001_sample_post_varjson.l2":"POST\\nhttps://httpbin.org/post\\n\\na=b\\nc=d","0007_multipart_file":{"0007_multipart_file.l2":"POST\\nMULTIPART\\nhttp://httpbin.org/post\\n\\n\'X-Parse-Application-Id\':helloworld \\nX-Parse-REST-API-Key:\\"helloworld\\"\\n\\n# DATA\\nfirst=second\\n\\n# FILES\\nmyfile@./image.jpeg"},"0004_env_switch_root":{"0004_env_switch_root.l2":"POST\\n${REMOTE}/post\\n\\n{\\n \\"lorem\\": \\"ipsum\\"\\n}","l2.env":"export LOCAL=\\"http://localhost:8000\\"\\nexport REMOTE=\\"http://httpbin.org\\""},"0003_comment.l2":"# Pound symbol signifies a comment\\nPOST\\nhttps://httpbin.org/post\\n\\na=b # Comments may start at the end of lines as well\\nc=d\\n\\n# Comments work even after the payload","0000_sample_get.l2":"GET\\nhttps://httpbin.org/get","0009_processor_basic":{"0009_processor_basic.l2":"url = \\"http://google.com\\"\\n---\\n# stage 1\\n\\nPOST\\n${REMOTE_COORD}/anything\\n\\n{\\n \\"username\\": \\"admin\\",\\n \\"password\\": \\"Password@123\\",\\n \\"from\\": \\"${LOCAL_COORD}/anything\\",\\n \\"url\\": \\"${url}\\",\\n \\"Token\\": \\"MySuperSecretToken\\"\\n}\\n\\n---\\n\\n// filtering, store in var\\nconsole.log(\\"@@Result\\", result)\\nlet TOKEN = result[\\"json\\"][\\"Token\\"]\\nconsole.log(TOKEN)\\n\\n---\\n\\n# stage 2\\nGET\\n${REMOTE_COORD}/bearer\\n\\nAuthorization: \'Bearer ${TOKEN}\'\\n\\n{}","l2.env":"\\nexport LOCAL_COORD=\\"http://localhost:8080\\"\\nexport REMOTE_COORD=\\"http://httpbin.org\\""}}'; -let examplesJSON = JSON.parse(examplesJSONStr); -let specificExGlobal = ""; -let subSpecificExGlobal = ""; - interface LanguageData { info: { key: string; @@ -28,86 +23,92 @@ interface LanguagesData { [key: string]: LanguageData; } -export function activate(context: vscode.ExtensionContext) { - console.log('>>> Congratulations, your extension "Lama2" is now active!'); +let examplesJSONStr = + '{"0006_cookies.l2":"POST \\nhttps://httpbin.org/post\\n\\n# HEADERS\\nCookie:\\"sessionid=foo;another-cookie=bar\\"\\n\\nHeader1:value1\\nHeader2: Value2\\n\\n# DATA\\nhello=world","0002_sample_post.l2":"POST\\nhttps://httpbin.org/post\\n\\n{\\n \\"a\\": \\"b\\",\\n \\"c\\": \\"d\\"\\n}","0005_headers_simple.l2":"POST \\nhttps://httpbin.org/post\\n\\n# HEADERS\\nX-Parse-Application-Id:\'helloworld\'\\nX-Parse-REST-API-Key:\\"byeworld\\"\\n\\n# DATA\\na=\\"b\\" # double-quoted string\\n\'c\'=d # single-quoted & unquoted strings","0008_base64_image":{"0008_base64_image.l2":"POST\\nhttp://httpbin.org/post\\n\\n{\\n\\t\\"imageb64_field\\": \\"\'${PHOTO}\'\\",\\n}","l2.env":"\\nexport PHOTO=`base64 image.jpeg`"},"0001_sample_post_varjson.l2":"POST\\nhttps://httpbin.org/post\\n\\na=b\\nc=d","0007_multipart_file":{"0007_multipart_file.l2":"POST\\nMULTIPART\\nhttp://httpbin.org/post\\n\\n\'X-Parse-Application-Id\':helloworld \\nX-Parse-REST-API-Key:\\"helloworld\\"\\n\\n# DATA\\nfirst=second\\n\\n# FILES\\nmyfile@./image.jpeg"},"0004_env_switch_root":{"0004_env_switch_root.l2":"POST\\n${REMOTE}/post\\n\\n{\\n \\"lorem\\": \\"ipsum\\"\\n}","l2.env":"export LOCAL=\\"http://localhost:8000\\"\\nexport REMOTE=\\"http://httpbin.org\\""},"0003_comment.l2":"# Pound symbol signifies a comment\\nPOST\\nhttps://httpbin.org/post\\n\\na=b # Comments may start at the end of lines as well\\nc=d\\n\\n# Comments work even after the payload","0000_sample_get.l2":"GET\\nhttps://httpbin.org/get","0009_processor_basic":{"0009_processor_basic.l2":"url = \\"http://google.com\\"\\n---\\n# stage 1\\n\\nPOST\\n${REMOTE_COORD}/anything\\n\\n{\\n \\"username\\": \\"admin\\",\\n \\"password\\": \\"Password@123\\",\\n \\"from\\": \\"${LOCAL_COORD}/anything\\",\\n \\"url\\": \\"${url}\\",\\n \\"Token\\": \\"MySuperSecretToken\\"\\n}\\n\\n---\\n\\n// filtering, store in var\\nconsole.log(\\"@@Result\\", result)\\nlet TOKEN = result[\\"json\\"][\\"Token\\"]\\nconsole.log(TOKEN)\\n\\n---\\n\\n# stage 2\\nGET\\n${REMOTE_COORD}/bearer\\n\\nAuthorization: \'Bearer ${TOKEN}\'\\n\\n{}","l2.env":"\\nexport LOCAL_COORD=\\"http://localhost:8080\\"\\nexport REMOTE_COORD=\\"http://httpbin.org\\""}}'; +let examplesJSON = JSON.parse(examplesJSONStr); +let specificExGlobal = ""; +let subSpecificExGlobal = ""; +let envVars = [] as string[]; +let cursorPosition = 0; - // Level1 command pallette +function execCurL2File(context: vscode.ExtensionContext) { + let executeCurrentFile = new ExecuteCurrentFile(context); + return vscode.commands.registerCommand("lama2.ExecuteCurrentFile", () => + executeCurrentFile.execFile() + ); +} + +function getRemoteUrl(context: vscode.ExtensionContext) { let getremoteUrl = new GetRemoteURL(context); + console.log(getremoteUrl); let getremoteUrlFileDisposable = vscode.commands.registerCommand( "lama2.GetRemoteURL", () => getremoteUrl.findURL() ); - context.subscriptions.push(getremoteUrlFileDisposable); - - // Level1 command pallette - let executeCurrentFile = new ExecuteCurrentFile(context); - - let executeCurrentFileDisposable = vscode.commands.registerCommand( - "lama2.ExecuteCurrentFile", - () => executeCurrentFile.execFile() - ); + return getremoteUrlFileDisposable; +} - context.subscriptions.push(executeCurrentFileDisposable); +function prettifyL2File() { + return vscode.commands.registerCommand("lama2.PrettifyCurrentFile", () => { + console.log("Executing prettify command"); + exec(`l2 -b ${vscode.window.activeTextEditor?.document.fileName}`); + }); +} - // Level1 command pallette +function genLama2Examples() { + return vscode.commands.registerCommand("lama2.Lama2Examples", async () => { + let specificEx: string | undefined = await vscode.window.showQuickPick( + Object.keys(examplesJSON) + ); - let prettifyCurrentFileDisposable = vscode.commands.registerCommand( - "lama2.PrettifyCurrentFile", - () => { - console.log("Executing prettify command"); - exec(`l2 -b ${vscode.window.activeTextEditor?.document.fileName}`); - } - ); - context.subscriptions.push(prettifyCurrentFileDisposable); + if (specificEx) { + specificExGlobal = specificEx; + if (specificEx.endsWith(".env") || specificEx.endsWith(".l2")) { + vscode.window.activeTextEditor?.edit((builder) => { + const doc = vscode.window.activeTextEditor?.document; + builder.replace( + new vscode.Range( + doc!.lineAt(0).range.start, + doc!.lineAt(doc!.lineCount - 1).range.end + ), + examplesJSON[specificExGlobal] + ); + }); + return; + } - let generateCodeSnippet = new GenerateCodeSnippet(); - let lama2Examples = vscode.commands.registerCommand( - "lama2.Lama2Examples", - async () => { - let specificEx: string | undefined = await vscode.window.showQuickPick( - Object.keys(examplesJSON) + let subSpecificEx: string | undefined = await vscode.window.showQuickPick( + Object.keys(examplesJSON[specificEx]) ); - if (specificEx) { - specificExGlobal = specificEx; - if (specificEx.endsWith(".env") || specificEx.endsWith(".l2")) { - vscode.window.activeTextEditor?.edit((builder) => { - const doc = vscode.window.activeTextEditor?.document; - builder.replace( - new vscode.Range( - doc!.lineAt(0).range.start, - doc!.lineAt(doc!.lineCount - 1).range.end - ), - examplesJSON[specificExGlobal] - ); - }); - return; - } - - let subSpecificEx: string | undefined = - await vscode.window.showQuickPick( - Object.keys(examplesJSON[specificEx]) + if (subSpecificEx) { + subSpecificExGlobal = subSpecificEx; + vscode.window.activeTextEditor?.edit((builder) => { + const doc = vscode.window.activeTextEditor?.document; + builder.replace( + new vscode.Range( + doc!.lineAt(0).range.start, + doc!.lineAt(doc!.lineCount - 1).range.end + ), + examplesJSON[specificExGlobal][subSpecificExGlobal] ); - - if (subSpecificEx) { - subSpecificExGlobal = subSpecificEx; - vscode.window.activeTextEditor?.edit((builder) => { - const doc = vscode.window.activeTextEditor?.document; - builder.replace( - new vscode.Range( - doc!.lineAt(0).range.start, - doc!.lineAt(doc!.lineCount - 1).range.end - ), - examplesJSON[specificExGlobal][subSpecificExGlobal] - ); - }); - return; - } + }); + return; } } - ); + }); +} - // Level1 command pallette +function isDefault(defaultClient: string, client: string) { + if (defaultClient == client) { + return "(Default)"; + } else { + return ""; + } +} + +function genCodeSnip() { + let generateCodeSnippet = new GenerateCodeSnippet(); let generateCodeSnippetDisposable = vscode.commands.registerCommand( "lama2.GenerateCodeSnippet", async () => { @@ -175,44 +176,84 @@ export function activate(context: vscode.ExtensionContext) { } } ); - context.subscriptions.push(generateCodeSnippetDisposable); + return generateCodeSnippetDisposable; +} - let envVariables = [] as string[]; - const activeTextEditor = vscode.window.activeTextEditor; - if (activeTextEditor) { - const activeFilePath = activeTextEditor.document.uri.fsPath; - const envFilePath = path.join(path.dirname(activeFilePath), "l2.env"); - fs.readFile(envFilePath, "utf8", (err, data) => { - if (err) { - console.error(err); - return; - } +function getEnvFromL2DotEnv(): string[] { + const editor = vscode.window.activeTextEditor; + if (!editor) { + return []; + } + + const l2FilePath = editor.document.fileName; + if (!l2FilePath.endsWith(".l2")) { + return []; + } + + const l2FileDir = path.dirname(l2FilePath); + const envFilePath = path.join(l2FileDir, "l2.env"); - envVariables = data - .split("\n") - .filter((line) => line.startsWith("export")) - .map((line) => line.split("=")[0].replace("export ", "")); - console.log("envVariables -> ", envVariables); - }); + if (!fs.existsSync(envFilePath)) { + vscode.window.showInformationMessage( + "Could not find 'l2.env' file to suggest variables, sorry." + ); + return []; } - let cursorPosition: any; - let linePosition: any; + const envFileContent = fs.readFileSync(envFilePath, "utf-8"); + const envVarRegex = /^export\s+([^\s=]+)=/gm; + const envVars: string[] = []; + let match: RegExpExecArray | null; + while ((match = envVarRegex.exec(envFileContent))) { + envVars.push(match[1]); + } + + return envVars; +} + +function getENVS() { + return vscode.workspace.onDidChangeTextDocument((event) => { + let editor = vscode.window.activeTextEditor; + if ( + editor && + event.document === editor.document && + event.contentChanges.length > 0 + ) { + // Check if the file has an extension of .l2 + if (event.document.fileName.endsWith(".l2")) { + // Check if the cursor is in between these ${} by using regular expressions + let currentLine = editor.document.lineAt(editor.selection.active.line); + let cursorPosition = editor.selection.active.character; + let lineText = currentLine.text; + let regex = /\${.*/g; + let match = regex.exec(lineText); + while (match) { + let matchIndex = match.index + currentLine.range.start.character; + if ( + cursorPosition > matchIndex && + cursorPosition < matchIndex + match[0].length + ) { + let cursorPos = cursorPosition + 1; + cursorPosition = cursorPos; + envVars = getEnvFromL2DotEnv(); + console.log("Environment variables:", envVars); + // envVars looks like this ['zzz', 'KARMA_CORE_URL', 'third', 'fourth', 'fifth'] + break; + } + match = regex.exec(lineText); + } + } + } + }); +} - let suggestEnvVariables = vscode.languages.registerCompletionItemProvider( +function suggestENVS() { + return vscode.languages.registerCompletionItemProvider( { language: "lama2", scheme: "file" }, { // eslint-disable-next-line no-unused-vars provideCompletionItems(document, position, token, context) { - // get all text until the `position` and check if it reads `${` - - const linePrefix = document - .lineAt(position) - .text.substring(0, position.character); - if (!linePrefix.endsWith("${")) { - return undefined; - } let createSuggestion = (text: string) => { let item = new vscode.CompletionItem( text, @@ -221,17 +262,32 @@ export function activate(context: vscode.ExtensionContext) { item.range = new vscode.Range(position, position); item.command = { title: "", - command: "options", + command: "envoptions", }; return item; }; - const suggestionsArray = envVariables.map((item, index) => { + + const currentLine = document.lineAt(position.line).text; + const triggerPrefix = currentLine + .substring(0, position.character) + .includes("${"); + const triggerPostfix = currentLine + .substring(position.character) + .includes("}"); + + const suggestionsArray = envVars.map((item, index) => { return createSuggestion(item); }); - return suggestionsArray; + if (triggerPrefix == true && triggerPostfix == false) { + return suggestionsArray; + } else if (triggerPrefix == true) { + return suggestionsArray; + } else { + return []; + } }, - ...triggers, // trigger + ...triggers, //triggers for activating the suggestions resolveCompletionItem( item: vscode.CompletionItem, token: vscode.CancellationToken @@ -240,40 +296,77 @@ export function activate(context: vscode.ExtensionContext) { if (editor) { const position = editor.selection.active; cursorPosition = position.character; - linePosition = position.line; } return item; }, } ); +} + +function replaceTextAfterEnvSelected() { + const editor = vscode.window.activeTextEditor; + if (editor) { + let position = editor.selection.active; + let lineText = editor.document.lineAt(position.line).text; + let linePosition = editor.document.lineAt(position.line).range.start + .character; + let openingBraceIndex = lineText.indexOf("{", linePosition); + if (openingBraceIndex >= 0 && cursorPosition > openingBraceIndex) { + let newText = lineText.substring(0, openingBraceIndex + 1); + newText += lineText.substring(cursorPosition); + let edit = new vscode.WorkspaceEdit(); + let range = new vscode.Range( + position.line, + 0, + position.line, + lineText.length + ); + edit.replace(editor.document.uri, range, newText); + vscode.workspace.applyEdit(edit); + } + } +} + +export function activate(context: vscode.ExtensionContext) { + console.log('>>> Congratulations, your extension "Lama2" is now active!'); + + // Level1 command pallette + let executeCurrentFileDisposable = execCurL2File(context); + context.subscriptions.push(executeCurrentFileDisposable); + console.log(">>> executeCurrentFileDisposable is now active!"); + + // Level1 command pallette + let getremoteUrlFileDisposable = getRemoteUrl(context); + context.subscriptions.push(getremoteUrlFileDisposable); + console.log(">>> getremoteUrlFileDisposable is now active!"); + + // Level1 command pallette + let prettifyCurrentFileDisposable = prettifyL2File(); + context.subscriptions.push(prettifyCurrentFileDisposable); + console.log(">>> prettifyCurrentFileDisposable is now active!"); + + // Level1 command pallette + let lama2Examples = genLama2Examples(); + console.log(">>> lama2Examples is now active!"); + + // Level1 command pallette + let generateCodeSnippetDisposable = genCodeSnip(); + context.subscriptions.push(generateCodeSnippetDisposable); + console.log(">>> generateCodeSnippetDisposable is now active!"); + + let envsDisposable = getENVS(); + context.subscriptions.push(envsDisposable); + console.log(">>> envsDisposable is now active!"); + + let suggestEnvVariables = suggestENVS(); context.subscriptions.push( suggestEnvVariables, - vscode.commands.registerCommand("options", () => { - const editor = vscode.window.activeTextEditor; - if (editor) { - const position = editor.selection.active; - const bracketPosition = editor.document - .lineAt(position.line) - .text.indexOf("{"); - const start = new vscode.Position(linePosition, bracketPosition + 1); // start position - const end = new vscode.Position(linePosition, cursorPosition); // end position - const range = new vscode.Range(start, end); // create range object - const replaceText = ""; - const edit = new vscode.WorkspaceEdit(); - edit.replace(editor.document.uri, range, replaceText); - vscode.workspace.applyEdit(edit); - } + vscode.commands.registerCommand("envoptions", () => { + // This method is activated when the user selects a suggested env variable. + replaceTextAfterEnvSelected(); }) ); } // this method is called when your extension is deactivated -export function deactivate() {} - -function isDefault(defaultClient: string, client: string) { - if (defaultClient == client) { - return "(Default)"; - } else { - return ""; - } -} +export function deactivate() {} \ No newline at end of file From e1cd1bcdff78fab0eb52fba38aa19a9578a6d375 Mon Sep 17 00:00:00 2001 From: Shrijith Venkatramana Date: Mon, 6 Mar 2023 16:58:42 +0530 Subject: [PATCH 6/9] 2.6.0 --- package-lock.json | 4 ++-- package.json | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/package-lock.json b/package-lock.json index 034f51e..55ca196 100644 --- a/package-lock.json +++ b/package-lock.json @@ -1,12 +1,12 @@ { "name": "Lama2", - "version": "2.5.0", + "version": "2.6.0", "lockfileVersion": 2, "requires": true, "packages": { "": { "name": "Lama2", - "version": "2.5.0", + "version": "2.6.0", "license": "SEE LICENSE IN LICENSE", "dependencies": { "ansi-to-html": "^0.7.2", diff --git a/package.json b/package.json index 09db1f5..068011e 100644 --- a/package.json +++ b/package.json @@ -2,7 +2,7 @@ "name": "Lama2", "displayName": "Lama2", "description": "Nifty VSCode UI for Lama2, the plain-text powered API client", - "version": "2.5.0", + "version": "2.6.0", "publisher": "Hexmos", "license": "SEE LICENSE IN LICENSE", "icon": "lama2.png", From 704b559ac6fb5f4a389575b6e34b5e86266a6316 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Sun, 16 Jul 2023 11:47:36 +0530 Subject: [PATCH 7/9] Detailed env suggestions for l2 - Using `l2 --env ${l2FilePath}` go lang binary command to fetch env. - Removed old searching envs in the frontend as performance was low. - Moved all the suggestions and replacing part to new file. --- src/extension.ts | 196 ++++------------------------------ src/suggestEnvironmentVars.ts | 121 +++++++++++++++++++++ 2 files changed, 142 insertions(+), 175 deletions(-) create mode 100644 src/suggestEnvironmentVars.ts diff --git a/src/extension.ts b/src/extension.ts index 50ca237..550c4a1 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,13 +1,11 @@ import * as vscode from "vscode"; -import * as fs from "fs"; -import * as path from "path"; import { exec } from "child_process"; import ExecuteCurrentFile from "./executeCurrentFile"; import GenerateCodeSnippet from "./generateCodeSnippet"; import GetRemoteURL from "./getRemoteUrl"; import LanguagesData from "./languages"; -import triggers from "./triggers"; +import { replaceTextAfterEnvSelected, suggestENVS } from "./suggestEnvironmentVars"; interface LanguageData { info: { @@ -28,8 +26,7 @@ let examplesJSONStr = let examplesJSON = JSON.parse(examplesJSONStr); let specificExGlobal = ""; let subSpecificExGlobal = ""; -let envVars = [] as string[]; -let cursorPosition = 0; + function execCurL2File(context: vscode.ExtensionContext) { let executeCurrentFile = new ExecuteCurrentFile(context); @@ -149,25 +146,25 @@ function genCodeSnip() { // Level3 command pallette const selection: | { - label: string; - language: string; - client: string; - } + label: string; + language: string; + client: string; + } | undefined = await vscode.window.showQuickPick( - clientKeys - .sort((a, b) => - a === defaultClient ? -1 : b === defaultClient ? 1 : 0 - ) - .map((client) => ({ - label: `${language ?? ""}: ${client} ${isDefault( - defaultClient, - client - )}`, - language: language ?? "", - client: client, - })), - { placeHolder: "Select a client" } - ); + clientKeys + .sort((a, b) => + a === defaultClient ? -1 : b === defaultClient ? 1 : 0 + ) + .map((client) => ({ + label: `${language ?? ""}: ${client} ${isDefault( + defaultClient, + client + )}`, + language: language ?? "", + client: client, + })), + { placeHolder: "Select a client" } + ); if (selection) { generateCodeSnippet.execFile(selection.language, selection.client); @@ -179,153 +176,6 @@ function genCodeSnip() { return generateCodeSnippetDisposable; } -function getEnvFromL2DotEnv(): string[] { - const editor = vscode.window.activeTextEditor; - if (!editor) { - return []; - } - - const l2FilePath = editor.document.fileName; - if (!l2FilePath.endsWith(".l2")) { - return []; - } - - const l2FileDir = path.dirname(l2FilePath); - const envFilePath = path.join(l2FileDir, "l2.env"); - - if (!fs.existsSync(envFilePath)) { - vscode.window.showInformationMessage( - "Could not find 'l2.env' file to suggest variables, sorry." - ); - return []; - } - - const envFileContent = fs.readFileSync(envFilePath, "utf-8"); - const envVarRegex = /^export\s+([^\s=]+)=/gm; - - const envVars: string[] = []; - let match: RegExpExecArray | null; - while ((match = envVarRegex.exec(envFileContent))) { - envVars.push(match[1]); - } - - return envVars; -} - -function getENVS() { - return vscode.workspace.onDidChangeTextDocument((event) => { - let editor = vscode.window.activeTextEditor; - if ( - editor && - event.document === editor.document && - event.contentChanges.length > 0 - ) { - // Check if the file has an extension of .l2 - if (event.document.fileName.endsWith(".l2")) { - // Check if the cursor is in between these ${} by using regular expressions - let currentLine = editor.document.lineAt(editor.selection.active.line); - let cursorPosition = editor.selection.active.character; - let lineText = currentLine.text; - let regex = /\${.*/g; - let match = regex.exec(lineText); - while (match) { - let matchIndex = match.index + currentLine.range.start.character; - if ( - cursorPosition > matchIndex && - cursorPosition < matchIndex + match[0].length - ) { - let cursorPos = cursorPosition + 1; - cursorPosition = cursorPos; - envVars = getEnvFromL2DotEnv(); - console.log("Environment variables:", envVars); - // envVars looks like this ['zzz', 'KARMA_CORE_URL', 'third', 'fourth', 'fifth'] - break; - } - match = regex.exec(lineText); - } - } - } - }); -} - -function suggestENVS() { - return vscode.languages.registerCompletionItemProvider( - { language: "lama2", scheme: "file" }, - { - // eslint-disable-next-line no-unused-vars - provideCompletionItems(document, position, token, context) { - let createSuggestion = (text: string) => { - let item = new vscode.CompletionItem( - text, - vscode.CompletionItemKind.Text - ); - item.range = new vscode.Range(position, position); - item.command = { - title: "", - command: "envoptions", - }; - return item; - }; - - const currentLine = document.lineAt(position.line).text; - const triggerPrefix = currentLine - .substring(0, position.character) - .includes("${"); - const triggerPostfix = currentLine - .substring(position.character) - .includes("}"); - - const suggestionsArray = envVars.map((item, index) => { - return createSuggestion(item); - }); - - if (triggerPrefix == true && triggerPostfix == false) { - return suggestionsArray; - } else if (triggerPrefix == true) { - return suggestionsArray; - } else { - return []; - } - }, - ...triggers, //triggers for activating the suggestions - resolveCompletionItem( - item: vscode.CompletionItem, - token: vscode.CancellationToken - ) { - const editor = vscode.window.activeTextEditor; - if (editor) { - const position = editor.selection.active; - cursorPosition = position.character; - } - return item; - }, - } - ); -} - -function replaceTextAfterEnvSelected() { - const editor = vscode.window.activeTextEditor; - if (editor) { - let position = editor.selection.active; - let lineText = editor.document.lineAt(position.line).text; - let linePosition = editor.document.lineAt(position.line).range.start - .character; - let openingBraceIndex = lineText.indexOf("{", linePosition); - if (openingBraceIndex >= 0 && cursorPosition > openingBraceIndex) { - let newText = lineText.substring(0, openingBraceIndex + 1); - newText += lineText.substring(cursorPosition); - let edit = new vscode.WorkspaceEdit(); - let range = new vscode.Range( - position.line, - 0, - position.line, - lineText.length - ); - edit.replace(editor.document.uri, range, newText); - vscode.workspace.applyEdit(edit); - } - } -} export function activate(context: vscode.ExtensionContext) { console.log('>>> Congratulations, your extension "Lama2" is now active!'); @@ -354,10 +204,6 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(generateCodeSnippetDisposable); console.log(">>> generateCodeSnippetDisposable is now active!"); - let envsDisposable = getENVS(); - context.subscriptions.push(envsDisposable); - console.log(">>> envsDisposable is now active!"); - let suggestEnvVariables = suggestENVS(); context.subscriptions.push( suggestEnvVariables, @@ -369,4 +215,4 @@ export function activate(context: vscode.ExtensionContext) { } // this method is called when your extension is deactivated -export function deactivate() {} \ No newline at end of file +export function deactivate() { } diff --git a/src/suggestEnvironmentVars.ts b/src/suggestEnvironmentVars.ts new file mode 100644 index 0000000..b54e5e8 --- /dev/null +++ b/src/suggestEnvironmentVars.ts @@ -0,0 +1,121 @@ +import * as vscode from "vscode"; +import { execSync } from "child_process"; + +import triggers from "./triggers"; +let cursorPosition = 0; + +export function getEnvsFromEnvCommand(): {} { + const editor = vscode.window.activeTextEditor; + if (!editor) { + return {}; + } + + const l2FilePath = editor.document.fileName; + if (!l2FilePath.endsWith(".l2")) { + return {}; + } + + try { + // const commandOutput = execSync(`./build/l2 --env ${l2FilePath}`, { cwd: "/home/lovestaco/repos/Lama2", }).toString(); // For local debugging + const commandOutput = execSync(`l2 --env ${l2FilePath}`).toString(); + + const mapStartIndex = commandOutput.indexOf("{"); + const mapEndIndex = commandOutput.lastIndexOf("}"); + const envMapStr = commandOutput.substring(mapStartIndex, mapEndIndex + 1); + + const envMap = JSON.parse(envMapStr); + return envMap; + } catch (error) { + console.error("Error executing the command:", error); + return {}; + } +} + +function createSuggestion(env: string, envVal: string, envSrc: string, position: any) { + let item = new vscode.CompletionItem( + env, + vscode.CompletionItemKind.Text + ); + item.detail = envVal; + item.documentation = `src: ${envSrc}`; + item.range = new vscode.Range(position, position); + item.command = { + title: "", + command: "envoptions", + arguments: [env], + }; + return item; + +} + +export function suggestENVS() { + return vscode.languages.registerCompletionItemProvider( + { language: "lama2", scheme: "file" }, + { + // eslint-disable-next-line no-unused-vars + provideCompletionItems(document, position, token, context) { + const currentLine = document.lineAt(position.line).text; + const triggerPrefix = currentLine + .substring(0, position.character) + .includes("${"); + const triggerPostfix = currentLine + .substring(position.character) + .includes("}"); + + const envVarsObj = getEnvsFromEnvCommand() as Record< + string, + { src: string; val: string } + >; // Explicitly cast to the correct type + const envVars = new Map(Object.entries(envVarsObj)); + + const suggestionsArray = Array.from(envVars.entries()).map( + ([env, meta]) => createSuggestion(env, meta.val, meta.src, position) + ); + + if (triggerPrefix && !triggerPostfix) { + return suggestionsArray; + } else if (triggerPrefix) { + return suggestionsArray; + } else { + return []; + } + }, + ...triggers, // triggers for activating the suggestions + resolveCompletionItem( + item: vscode.CompletionItem, + token: vscode.CancellationToken + ) { + const editor = vscode.window.activeTextEditor; + if (editor) { + const position = editor.selection.active; + cursorPosition = position.character; + } + return item; + }, + } + ); +} + +export function replaceTextAfterEnvSelected() { + const editor = vscode.window.activeTextEditor; + if (editor) { + let position = editor.selection.active; + let lineText = editor.document.lineAt(position.line).text; + let linePosition = editor.document.lineAt(position.line).range.start + .character; + let openingBraceIndex = lineText.indexOf("{", linePosition); + if (openingBraceIndex >= 0 && cursorPosition > openingBraceIndex) { + let newText = lineText.substring(0, openingBraceIndex + 1); + newText += lineText.substring(cursorPosition); + let edit = new vscode.WorkspaceEdit(); + let range = new vscode.Range( + position.line, + 0, + position.line, + lineText.length + ); + edit.replace(editor.document.uri, range, newText); + vscode.workspace.applyEdit(edit); + } + } +} \ No newline at end of file From 7f97a104a83ee38bd23625d8633d192120f7a792 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Tue, 18 Jul 2023 09:40:08 +0530 Subject: [PATCH 8/9] Reading the JSON from stdout without searching for Braces --- src/suggestEnvironmentVars.ts | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/src/suggestEnvironmentVars.ts b/src/suggestEnvironmentVars.ts index b54e5e8..cf3d090 100644 --- a/src/suggestEnvironmentVars.ts +++ b/src/suggestEnvironmentVars.ts @@ -16,14 +16,11 @@ export function getEnvsFromEnvCommand(): {} { } try { + // Execute the command and read the stdout for JSON of all the env's + // const commandOutput = execSync(`./build/l2 --env ${l2FilePath}`, { cwd: "/home/lovestaco/repos/Lama2", }).toString(); // For local debugging const commandOutput = execSync(`l2 --env ${l2FilePath}`).toString(); - - const mapStartIndex = commandOutput.indexOf("{"); - const mapEndIndex = commandOutput.lastIndexOf("}"); - const envMapStr = commandOutput.substring(mapStartIndex, mapEndIndex + 1); - - const envMap = JSON.parse(envMapStr); + const envMap = JSON.parse(commandOutput); return envMap; } catch (error) { console.error("Error executing the command:", error); From cdc416c52521c9294344edf686754bddec6aa357 Mon Sep 17 00:00:00 2001 From: lovestaco Date: Tue, 18 Jul 2023 10:15:09 +0530 Subject: [PATCH 9/9] Modularity for the files and functions --- src/executeCurrentFile.ts | 16 ++- src/extension.ts | 184 ++-------------------------------- src/genLama2Examples.ts | 50 +++++++++ src/generateCodeSnippet.ts | 97 +++++++++++++++++- src/getRemoteUrl.ts | 10 +- src/prettifyL2File.ts | 9 ++ src/suggestEnvironmentVars.ts | 2 +- 7 files changed, 183 insertions(+), 185 deletions(-) create mode 100644 src/genLama2Examples.ts create mode 100644 src/prettifyL2File.ts diff --git a/src/executeCurrentFile.ts b/src/executeCurrentFile.ts index 8962b5f..8a4b045 100644 --- a/src/executeCurrentFile.ts +++ b/src/executeCurrentFile.ts @@ -64,7 +64,7 @@ class ExecuteCurrentFile { let windowsBasePath = "C:\\ProgramData\\.lama2" let randomNameBase = this.generateRandomName(8) let currentFilePath = vscode.window.activeTextEditor?.document.fileName - + if (process.platform === "win32") { if (!fs.existsSync(windowsBasePath)) { fs.mkdirSync(windowsBasePath) @@ -72,9 +72,9 @@ class ExecuteCurrentFile { randomNameFlag = `${windowsBasePath}\\${randomNameBase}.flag` randomNameFile = `${windowsBasePath}\\${randomNameBase}.json` cmd = `powershell l2 -o ${randomNameFile} ${currentFilePath}; New-Item -Path ${randomNameFlag}` - }else { - randomNameFlag = `/tmp/${randomNameBase}.flag` - randomNameFile = `/tmp/${randomNameBase}.json` + } else { + randomNameFlag = `/tmp/${randomNameBase}.flag` + randomNameFile = `/tmp/${randomNameBase}.json` cmd = `l2 -o ${randomNameFile} ${currentFilePath}; touch ${randomNameFlag}` } return { @@ -257,4 +257,10 @@ class ExecuteCurrentFile { } -export default ExecuteCurrentFile +export function execCurL2File(context: vscode.ExtensionContext) { + let executeCurrentFile = new ExecuteCurrentFile(context); + return vscode.commands.registerCommand("lama2.ExecuteCurrentFile", () => + executeCurrentFile.execFile() + ); +} + diff --git a/src/extension.ts b/src/extension.ts index 550c4a1..bec8921 100644 --- a/src/extension.ts +++ b/src/extension.ts @@ -1,181 +1,11 @@ import * as vscode from "vscode"; -import { exec } from "child_process"; - -import ExecuteCurrentFile from "./executeCurrentFile"; -import GenerateCodeSnippet from "./generateCodeSnippet"; -import GetRemoteURL from "./getRemoteUrl"; -import LanguagesData from "./languages"; -import { replaceTextAfterEnvSelected, suggestENVS } from "./suggestEnvironmentVars"; - -interface LanguageData { - info: { - key: string; - title: string; - extname: string; - default: string; - }; - clientsById: Record; -} - -interface LanguagesData { - [key: string]: LanguageData; -} - -let examplesJSONStr = - '{"0006_cookies.l2":"POST \\nhttps://httpbin.org/post\\n\\n# HEADERS\\nCookie:\\"sessionid=foo;another-cookie=bar\\"\\n\\nHeader1:value1\\nHeader2: Value2\\n\\n# DATA\\nhello=world","0002_sample_post.l2":"POST\\nhttps://httpbin.org/post\\n\\n{\\n \\"a\\": \\"b\\",\\n \\"c\\": \\"d\\"\\n}","0005_headers_simple.l2":"POST \\nhttps://httpbin.org/post\\n\\n# HEADERS\\nX-Parse-Application-Id:\'helloworld\'\\nX-Parse-REST-API-Key:\\"byeworld\\"\\n\\n# DATA\\na=\\"b\\" # double-quoted string\\n\'c\'=d # single-quoted & unquoted strings","0008_base64_image":{"0008_base64_image.l2":"POST\\nhttp://httpbin.org/post\\n\\n{\\n\\t\\"imageb64_field\\": \\"\'${PHOTO}\'\\",\\n}","l2.env":"\\nexport PHOTO=`base64 image.jpeg`"},"0001_sample_post_varjson.l2":"POST\\nhttps://httpbin.org/post\\n\\na=b\\nc=d","0007_multipart_file":{"0007_multipart_file.l2":"POST\\nMULTIPART\\nhttp://httpbin.org/post\\n\\n\'X-Parse-Application-Id\':helloworld \\nX-Parse-REST-API-Key:\\"helloworld\\"\\n\\n# DATA\\nfirst=second\\n\\n# FILES\\nmyfile@./image.jpeg"},"0004_env_switch_root":{"0004_env_switch_root.l2":"POST\\n${REMOTE}/post\\n\\n{\\n \\"lorem\\": \\"ipsum\\"\\n}","l2.env":"export LOCAL=\\"http://localhost:8000\\"\\nexport REMOTE=\\"http://httpbin.org\\""},"0003_comment.l2":"# Pound symbol signifies a comment\\nPOST\\nhttps://httpbin.org/post\\n\\na=b # Comments may start at the end of lines as well\\nc=d\\n\\n# Comments work even after the payload","0000_sample_get.l2":"GET\\nhttps://httpbin.org/get","0009_processor_basic":{"0009_processor_basic.l2":"url = \\"http://google.com\\"\\n---\\n# stage 1\\n\\nPOST\\n${REMOTE_COORD}/anything\\n\\n{\\n \\"username\\": \\"admin\\",\\n \\"password\\": \\"Password@123\\",\\n \\"from\\": \\"${LOCAL_COORD}/anything\\",\\n \\"url\\": \\"${url}\\",\\n \\"Token\\": \\"MySuperSecretToken\\"\\n}\\n\\n---\\n\\n// filtering, store in var\\nconsole.log(\\"@@Result\\", result)\\nlet TOKEN = result[\\"json\\"][\\"Token\\"]\\nconsole.log(TOKEN)\\n\\n---\\n\\n# stage 2\\nGET\\n${REMOTE_COORD}/bearer\\n\\nAuthorization: \'Bearer ${TOKEN}\'\\n\\n{}","l2.env":"\\nexport LOCAL_COORD=\\"http://localhost:8080\\"\\nexport REMOTE_COORD=\\"http://httpbin.org\\""}}'; -let examplesJSON = JSON.parse(examplesJSONStr); -let specificExGlobal = ""; -let subSpecificExGlobal = ""; - - -function execCurL2File(context: vscode.ExtensionContext) { - let executeCurrentFile = new ExecuteCurrentFile(context); - return vscode.commands.registerCommand("lama2.ExecuteCurrentFile", () => - executeCurrentFile.execFile() - ); -} - -function getRemoteUrl(context: vscode.ExtensionContext) { - let getremoteUrl = new GetRemoteURL(context); - console.log(getremoteUrl); - let getremoteUrlFileDisposable = vscode.commands.registerCommand( - "lama2.GetRemoteURL", - () => getremoteUrl.findURL() - ); - return getremoteUrlFileDisposable; -} - -function prettifyL2File() { - return vscode.commands.registerCommand("lama2.PrettifyCurrentFile", () => { - console.log("Executing prettify command"); - exec(`l2 -b ${vscode.window.activeTextEditor?.document.fileName}`); - }); -} - -function genLama2Examples() { - return vscode.commands.registerCommand("lama2.Lama2Examples", async () => { - let specificEx: string | undefined = await vscode.window.showQuickPick( - Object.keys(examplesJSON) - ); - - if (specificEx) { - specificExGlobal = specificEx; - if (specificEx.endsWith(".env") || specificEx.endsWith(".l2")) { - vscode.window.activeTextEditor?.edit((builder) => { - const doc = vscode.window.activeTextEditor?.document; - builder.replace( - new vscode.Range( - doc!.lineAt(0).range.start, - doc!.lineAt(doc!.lineCount - 1).range.end - ), - examplesJSON[specificExGlobal] - ); - }); - return; - } - - let subSpecificEx: string | undefined = await vscode.window.showQuickPick( - Object.keys(examplesJSON[specificEx]) - ); - - if (subSpecificEx) { - subSpecificExGlobal = subSpecificEx; - vscode.window.activeTextEditor?.edit((builder) => { - const doc = vscode.window.activeTextEditor?.document; - builder.replace( - new vscode.Range( - doc!.lineAt(0).range.start, - doc!.lineAt(doc!.lineCount - 1).range.end - ), - examplesJSON[specificExGlobal][subSpecificExGlobal] - ); - }); - return; - } - } - }); -} - -function isDefault(defaultClient: string, client: string) { - if (defaultClient == client) { - return "(Default)"; - } else { - return ""; - } -} - -function genCodeSnip() { - let generateCodeSnippet = new GenerateCodeSnippet(); - let generateCodeSnippetDisposable = vscode.commands.registerCommand( - "lama2.GenerateCodeSnippet", - async () => { - const langkwys = Object.keys(LanguagesData); - let languageOptions: { [key: string]: string } = {}; - for (let i = 0; i < langkwys.length; i++) { - const key = langkwys[i] as keyof typeof LanguagesData; - const languageData = LanguagesData[key]; - languageOptions[languageData.info.title] = languageData.info.key; - } - - const languageKeys = Object.keys(LanguagesData); - - // Level2 command pallette - let language: string | undefined = await vscode.window.showQuickPick( - Object.keys(languageOptions) - ); - - if (language) { - language = languageOptions[language]; - const languageKey = languageKeys.find( - (key) => - LanguagesData[key as keyof typeof LanguagesData].info.key === - language - )!; - - const clientsById = - LanguagesData[languageKey as keyof typeof LanguagesData].clientsById; - const defaultClient = - LanguagesData[languageKey as keyof typeof LanguagesData].info.default; - - const clientKeys = Object.keys(clientsById); - - if (clientKeys.length === 1) { - const client = clientKeys[0]; - generateCodeSnippet.execFile(language, client); - } else { - // Level3 command pallette - const selection: - | { - label: string; - language: string; - client: string; - } - | undefined = await vscode.window.showQuickPick( - clientKeys - .sort((a, b) => - a === defaultClient ? -1 : b === defaultClient ? 1 : 0 - ) - .map((client) => ({ - label: `${language ?? ""}: ${client} ${isDefault( - defaultClient, - client - )}`, - language: language ?? "", - client: client, - })), - { placeHolder: "Select a client" } - ); - - if (selection) { - generateCodeSnippet.execFile(selection.language, selection.client); - } - } - } - } - ); - return generateCodeSnippetDisposable; -} +import { genCodeSnip } from "./generateCodeSnippet"; +import { getRemoteUrl } from "./getRemoteUrl"; +import { replaceTextAfterEnvSelected, suggestENVs } from "./suggestEnvironmentVars"; +import { genLama2Examples } from "./genLama2Examples"; +import { execCurL2File } from "./executeCurrentFile"; +import { prettifyL2File } from "./prettifyL2File"; export function activate(context: vscode.ExtensionContext) { console.log('>>> Congratulations, your extension "Lama2" is now active!'); @@ -204,7 +34,7 @@ export function activate(context: vscode.ExtensionContext) { context.subscriptions.push(generateCodeSnippetDisposable); console.log(">>> generateCodeSnippetDisposable is now active!"); - let suggestEnvVariables = suggestENVS(); + let suggestEnvVariables = suggestENVs(); context.subscriptions.push( suggestEnvVariables, vscode.commands.registerCommand("envoptions", () => { diff --git a/src/genLama2Examples.ts b/src/genLama2Examples.ts new file mode 100644 index 0000000..c9aa914 --- /dev/null +++ b/src/genLama2Examples.ts @@ -0,0 +1,50 @@ +import * as vscode from "vscode"; +let examplesJSONStr = + '{"0006_cookies.l2":"POST \\nhttps://httpbin.org/post\\n\\n# HEADERS\\nCookie:\\"sessionid=foo;another-cookie=bar\\"\\n\\nHeader1:value1\\nHeader2: Value2\\n\\n# DATA\\nhello=world","0002_sample_post.l2":"POST\\nhttps://httpbin.org/post\\n\\n{\\n \\"a\\": \\"b\\",\\n \\"c\\": \\"d\\"\\n}","0005_headers_simple.l2":"POST \\nhttps://httpbin.org/post\\n\\n# HEADERS\\nX-Parse-Application-Id:\'helloworld\'\\nX-Parse-REST-API-Key:\\"byeworld\\"\\n\\n# DATA\\na=\\"b\\" # double-quoted string\\n\'c\'=d # single-quoted & unquoted strings","0008_base64_image":{"0008_base64_image.l2":"POST\\nhttp://httpbin.org/post\\n\\n{\\n\\t\\"imageb64_field\\": \\"\'${PHOTO}\'\\",\\n}","l2.env":"\\nexport PHOTO=`base64 image.jpeg`"},"0001_sample_post_varjson.l2":"POST\\nhttps://httpbin.org/post\\n\\na=b\\nc=d","0007_multipart_file":{"0007_multipart_file.l2":"POST\\nMULTIPART\\nhttp://httpbin.org/post\\n\\n\'X-Parse-Application-Id\':helloworld \\nX-Parse-REST-API-Key:\\"helloworld\\"\\n\\n# DATA\\nfirst=second\\n\\n# FILES\\nmyfile@./image.jpeg"},"0004_env_switch_root":{"0004_env_switch_root.l2":"POST\\n${REMOTE}/post\\n\\n{\\n \\"lorem\\": \\"ipsum\\"\\n}","l2.env":"export LOCAL=\\"http://localhost:8000\\"\\nexport REMOTE=\\"http://httpbin.org\\""},"0003_comment.l2":"# Pound symbol signifies a comment\\nPOST\\nhttps://httpbin.org/post\\n\\na=b # Comments may start at the end of lines as well\\nc=d\\n\\n# Comments work even after the payload","0000_sample_get.l2":"GET\\nhttps://httpbin.org/get","0009_processor_basic":{"0009_processor_basic.l2":"url = \\"http://google.com\\"\\n---\\n# stage 1\\n\\nPOST\\n${REMOTE_COORD}/anything\\n\\n{\\n \\"username\\": \\"admin\\",\\n \\"password\\": \\"Password@123\\",\\n \\"from\\": \\"${LOCAL_COORD}/anything\\",\\n \\"url\\": \\"${url}\\",\\n \\"Token\\": \\"MySuperSecretToken\\"\\n}\\n\\n---\\n\\n// filtering, store in var\\nconsole.log(\\"@@Result\\", result)\\nlet TOKEN = result[\\"json\\"][\\"Token\\"]\\nconsole.log(TOKEN)\\n\\n---\\n\\n# stage 2\\nGET\\n${REMOTE_COORD}/bearer\\n\\nAuthorization: \'Bearer ${TOKEN}\'\\n\\n{}","l2.env":"\\nexport LOCAL_COORD=\\"http://localhost:8080\\"\\nexport REMOTE_COORD=\\"http://httpbin.org\\""}}'; +let examplesJSON = JSON.parse(examplesJSONStr); +let specificExGlobal = ""; +let subSpecificExGlobal = ""; + +export function genLama2Examples() { + return vscode.commands.registerCommand("lama2.Lama2Examples", async () => { + let specificEx: string | undefined = await vscode.window.showQuickPick( + Object.keys(examplesJSON) + ); + + if (specificEx) { + specificExGlobal = specificEx; + if (specificEx.endsWith(".env") || specificEx.endsWith(".l2")) { + vscode.window.activeTextEditor?.edit((builder) => { + const doc = vscode.window.activeTextEditor?.document; + builder.replace( + new vscode.Range( + doc!.lineAt(0).range.start, + doc!.lineAt(doc!.lineCount - 1).range.end + ), + examplesJSON[specificExGlobal] + ); + }); + return; + } + + let subSpecificEx: string | undefined = await vscode.window.showQuickPick( + Object.keys(examplesJSON[specificEx]) + ); + + if (subSpecificEx) { + subSpecificExGlobal = subSpecificEx; + vscode.window.activeTextEditor?.edit((builder) => { + const doc = vscode.window.activeTextEditor?.document; + builder.replace( + new vscode.Range( + doc!.lineAt(0).range.start, + doc!.lineAt(doc!.lineCount - 1).range.end + ), + examplesJSON[specificExGlobal][subSpecificExGlobal] + ); + }); + return; + } + } + }); +} diff --git a/src/generateCodeSnippet.ts b/src/generateCodeSnippet.ts index ea10c5e..da1e0cb 100644 --- a/src/generateCodeSnippet.ts +++ b/src/generateCodeSnippet.ts @@ -2,6 +2,7 @@ import * as vscode from "vscode"; import ChokiExtension from "./watchFile"; let fs = require("fs"); import { window } from "vscode"; +import LanguagesData from "./languages"; class GenerateCodeSnippet { LAMA2_TERM_NAME = "AutoLama2"; @@ -110,4 +111,98 @@ class GenerateCodeSnippet { } } -export default GenerateCodeSnippet; + +function isDefault(defaultClient: string, client: string) { + if (defaultClient == client) { + return "(Default)"; + } else { + return ""; + } +} + +interface LanguageData { + info: { + key: string; + title: string; + extname: string; + default: string; + }; + clientsById: Record; +} + +interface LanguagesData { + [key: string]: LanguageData; +} + +export function genCodeSnip() { + let generateCodeSnippet = new GenerateCodeSnippet(); + let generateCodeSnippetDisposable = vscode.commands.registerCommand( + "lama2.GenerateCodeSnippet", + async () => { + const langkwys = Object.keys(LanguagesData); + let languageOptions: { [key: string]: string } = {}; + for (let i = 0; i < langkwys.length; i++) { + const key = langkwys[i] as keyof typeof LanguagesData; + const languageData = LanguagesData[key]; + languageOptions[languageData.info.title] = languageData.info.key; + } + + const languageKeys = Object.keys(LanguagesData); + + // Level2 command pallette + let language: string | undefined = await vscode.window.showQuickPick( + Object.keys(languageOptions) + ); + + if (language) { + language = languageOptions[language]; + const languageKey = languageKeys.find( + (key) => + LanguagesData[key as keyof typeof LanguagesData].info.key === + language + )!; + + const clientsById = + LanguagesData[languageKey as keyof typeof LanguagesData].clientsById; + const defaultClient = + LanguagesData[languageKey as keyof typeof LanguagesData].info.default; + + const clientKeys = Object.keys(clientsById); + + if (clientKeys.length === 1) { + const client = clientKeys[0]; + generateCodeSnippet.execFile(language, client); + } else { + // Level3 command pallette + const selection: + | { + label: string; + language: string; + client: string; + } + | undefined = await vscode.window.showQuickPick( + clientKeys + .sort((a, b) => + a === defaultClient ? -1 : b === defaultClient ? 1 : 0 + ) + .map((client) => ({ + label: `${language ?? ""}: ${client} ${isDefault( + defaultClient, + client + )}`, + language: language ?? "", + client: client, + })), + { placeHolder: "Select a client" } + ); + + if (selection) { + generateCodeSnippet.execFile(selection.language, selection.client); + } + } + } + } + ); + return generateCodeSnippetDisposable; +} + diff --git a/src/getRemoteUrl.ts b/src/getRemoteUrl.ts index 8a4ce42..3c4161b 100644 --- a/src/getRemoteUrl.ts +++ b/src/getRemoteUrl.ts @@ -57,4 +57,12 @@ class GetRemoteURL { } } -export default GetRemoteURL; \ No newline at end of file +export function getRemoteUrl(context: vscode.ExtensionContext) { + let getremoteUrl = new GetRemoteURL(context); + console.log(getremoteUrl); + let getremoteUrlFileDisposable = vscode.commands.registerCommand( + "lama2.GetRemoteURL", + () => getremoteUrl.findURL() + ); + return getremoteUrlFileDisposable; +} \ No newline at end of file diff --git a/src/prettifyL2File.ts b/src/prettifyL2File.ts new file mode 100644 index 0000000..6178a78 --- /dev/null +++ b/src/prettifyL2File.ts @@ -0,0 +1,9 @@ +import * as vscode from "vscode"; +import { exec } from "child_process"; + +export function prettifyL2File() { + return vscode.commands.registerCommand("lama2.PrettifyCurrentFile", () => { + console.log("Executing prettify command"); + exec(`l2 -b ${vscode.window.activeTextEditor?.document.fileName}`); + }); +} \ No newline at end of file diff --git a/src/suggestEnvironmentVars.ts b/src/suggestEnvironmentVars.ts index cf3d090..03c9a52 100644 --- a/src/suggestEnvironmentVars.ts +++ b/src/suggestEnvironmentVars.ts @@ -45,7 +45,7 @@ function createSuggestion(env: string, envVal: string, envSrc: string, position: } -export function suggestENVS() { +export function suggestENVs() { return vscode.languages.registerCompletionItemProvider( { language: "lama2", scheme: "file" }, {