diff --git a/smart-template-strings-sample/.gitignore b/smart-template-strings-sample/.gitignore new file mode 100644 index 00000000..8e5962ee --- /dev/null +++ b/smart-template-strings-sample/.gitignore @@ -0,0 +1,2 @@ +out +node_modules \ No newline at end of file diff --git a/smart-template-strings-sample/.vscode/launch.json b/smart-template-strings-sample/.vscode/launch.json new file mode 100644 index 00000000..523895f3 --- /dev/null +++ b/smart-template-strings-sample/.vscode/launch.json @@ -0,0 +1,21 @@ +{ + // Use IntelliSense to learn about possible Node.js debug attributes. + // Hover to view descriptions of existing attributes. + // For more information, visit: https://go.microsoft.com/fwlink/?linkid=830387 + "version": "0.2.0", + "configurations": [ + { + "type": "extensionHost", + "request": "launch", + "name": "Launch Extension", + "runtimeExecutable": "${execPath}", + "args": [ + "--extensionDevelopmentPath=${workspaceRoot}" + ], + "sourceMaps": true, + "outFiles": [ + "${workspaceRoot}/out/**/*.js" + ] + } + ] +} diff --git a/smart-template-strings-sample/README.md b/smart-template-strings-sample/README.md new file mode 100644 index 00000000..c5304b01 --- /dev/null +++ b/smart-template-strings-sample/README.md @@ -0,0 +1,13 @@ +# smart-template-strings + +A sample extension that offers completions inside template strings. Template strings and tag function are becoming popular for embedding SQL-constructs or HTML inside JavaScript or TypeScript. For instance + +```js +html(...args) { + // populate dom from args +} + +html`div` +``` + +This sample shows how to indentify such template strings and how to provide completions inside of them. diff --git a/smart-template-strings-sample/package.json b/smart-template-strings-sample/package.json new file mode 100644 index 00000000..2dda7a94 --- /dev/null +++ b/smart-template-strings-sample/package.json @@ -0,0 +1,31 @@ +{ + "name": "smart-template-strings", + "displayName": "smart-template-strings", + "description": "", + "version": "0.0.1", + "publisher": "jrieken", + "engines": { + "vscode": "^1.5.0" + }, + "categories": [ + "Other" + ], + "activationEvents": [ + "onLanguage:javascript", + "onLanguage:typescript" + ], + "main": "./out/src/extension", + "contributes": {}, + "scripts": { + "vscode:prepublish": "tsc -p ./", + "compile": "tsc -p ./", + "postinstall": "node ./node_modules/vscode/bin/install && tsc -p ./" + }, + "dependencies": { + "typescript": "^2.2.1" + }, + "devDependencies": { + "vscode": "^1.0.0", + "@types/node": "^6.0.40" + } +} diff --git a/smart-template-strings-sample/src/extension.ts b/smart-template-strings-sample/src/extension.ts new file mode 100644 index 00000000..2fa0a314 --- /dev/null +++ b/smart-template-strings-sample/src/extension.ts @@ -0,0 +1,39 @@ +'use strict'; + +import * as vscode from 'vscode'; +import * as ts from 'typescript'; + +export function activate(context: vscode.ExtensionContext) { + + vscode.languages.registerCompletionItemProvider(['typescript', 'javascript'], { + provideCompletionItems(doc, pos) { + + const offset = doc.offsetAt(pos); + const source = ts.createSourceFile(doc.fileName, doc.getText(), ts.ScriptTarget.Latest, true); + + let token = (ts as any).getTokenAtPosition(source, offset) + let template: ts.TaggedTemplateExpression; + while (token) { + if (token.kind === ts.SyntaxKind.TaggedTemplateExpression) { + template = token; + break; + } + token = token.parent; + } + + if (!template + || template.tag.getText() !== 'foo' + || (offset < template.template.pos && offset > template.template.end) + ) { + return; + } + + return [ + new vscode.CompletionItem('bar', vscode.CompletionItemKind.Value), + new vscode.CompletionItem('baz', vscode.CompletionItemKind.Value), + new vscode.CompletionItem('far', vscode.CompletionItemKind.Value) + ]; + } + }); +} + diff --git a/smart-template-strings-sample/tsconfig.json b/smart-template-strings-sample/tsconfig.json new file mode 100644 index 00000000..da3318cd --- /dev/null +++ b/smart-template-strings-sample/tsconfig.json @@ -0,0 +1,16 @@ +{ + "compilerOptions": { + "module": "commonjs", + "target": "es6", + "sourceMap": true, + "outDir": "out", + "lib": [ + "es6" + ], + "rootDir": "." + }, + "exclude": [ + "node_modules", + ".vscode-test" + ] +}