Skip to content

Commit 35bb0a2

Browse files
committedOct 11, 2017
Initial commit
0 parents  commit 35bb0a2

24 files changed

+1132
-0
lines changed
 

‎.editorconfig

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
root = true
2+
3+
[*]
4+
indent_style = space
5+
indent_size = 4
6+
trim_trailing_whitespace = true
7+
8+
[{npm-shrinkwrap.json,package.json}]
9+
indent_style = space
10+
indent_size = 2

‎.gitignore

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
node_modules/
2+
*.log
3+
*.swp
4+
*.swo
5+
.DS_Store
6+
*.log
7+
log.txt
8+
9+
test-workspace
10+
lib

‎.travis.yml

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
language: node_js
2+
3+
node_js:
4+
- 'stable'
5+
6+
sudo: false
7+
8+
branches:
9+
only:
10+
- master
11+
12+
install:
13+
- npm install
14+
- (cd e2e ; npm install)
15+
16+
script:
17+
- npm run compile
18+
- npm run e2e
19+
20+
after_failure:
21+
- cat e2e/server-fixture/log.txt

‎.vscode/settings.json

+11
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
{
2+
"files.exclude": {
3+
"**/.git": true,
4+
"**/.svn": true,
5+
"**/.hg": true,
6+
"**/CVS": true,
7+
"**/.DS_Store": true,
8+
"lib": true,
9+
"**/*.log": true
10+
}
11+
}

‎CHANGELOG.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Changelog

‎CODE_OF_CONDUCT.md

+1
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
This project has adopted the [Microsoft Open Source Code of Conduct](https://opensource.microsoft.com/codeofconduct/). For more information see the [Code of Conduct FAQ](https://opensource.microsoft.com/codeofconduct/faq/) or contact [opencode@microsoft.com](mailto:opencode@microsoft.com) with any additional questions or comments.

‎LICENSE.txt

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
The MIT License (MIT)
2+
3+
Copyright (c) base project [2017] [Quramy], Modifications copyright Microsoft 2017
4+
5+
Permission is hereby granted, free of charge, to any person obtaining a copy
6+
of this software and associated documentation files (the "Software"), to deal
7+
in the Software without restriction, including without limitation the rights
8+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9+
copies of the Software, and to permit persons to whom the Software is
10+
furnished to do so, subject to the following conditions:
11+
12+
The above copyright notice and this permission notice shall be included in all
13+
copies or substantial portions of the Software.
14+
15+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21+
SOFTWARE.

‎README.md

+176
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,176 @@
1+
# TypeScript lit-html Plugin
2+
3+
TypeScript server plugin that adds intellisense for [lit-html](https://github.com/PolymerLabs/lit-html) template strings
4+
5+
![](documentation/preview.gif)
6+
7+
[![Build Status](https://travis-ci.org/Microsoft/typescript-lit-html-plugin.svg?branch=master)](https://travis-ci.org/Microsoft/typescript-lit-html-plugin)
8+
9+
## Usage
10+
This plugin requires TypeScript 2.4 or later. It can provide intellisense in both JavaScript and TypeScript files within any editor that uses TypeScript to power their language features. This includes [VS Code](https://code.visualstudio.com), [Sublime with the TypeScript plugin](https://github.com/Microsoft/TypeScript-Sublime-Plugin), [Atom with the TypeScript plugin](https://atom.io/packages/atom-typescript), and others.
11+
12+
### With VS Code
13+
To use this plugin with VS Code, first install the plugin and a copy of TypeScript in your workspace:
14+
15+
```bash
16+
npm install --save-dev typescript-lit-html-plugin typescript
17+
```
18+
19+
Then add a `plugins` section to your [`tsconfig.json`](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html) or [`jsconfig.json`](https://code.visualstudio.com/Docs/languages/javascript#_javascript-project-jsconfigjson)
20+
21+
```json
22+
{
23+
"compilerOptions": {
24+
"plugins": [
25+
{
26+
"name": "typescript-lit-html-plugin"
27+
}
28+
]
29+
}
30+
}
31+
```
32+
33+
Finally, run the `Select TypeScript version` command in VS Code to switch to use the workspace version of TypeScript for VS Code's JavaScript and TypeScript language support. You can find more information about managing typescript versions [in the VS Code documentation](https://code.visualstudio.com/Docs/languages/typescript#_using-newer-typescript-versions).
34+
35+
Also consider installing the [lit-html](https://marketplace.visualstudio.com/items?itemName=bierner.lit-html) extension to get stytax highlighting for lit-html template strings.
36+
37+
38+
### With Sublime
39+
This plugin works with the [Sublime TypeScript plugin](https://github.com/Microsoft/TypeScript-Sublime-Plugin).
40+
41+
First install the plugin and a copy of TypeScript in your workspace:
42+
43+
```bash
44+
npm install --save-dev typescript-lit-html-plugin typescript
45+
```
46+
47+
And configure Sublime to use the workspace version of TypeScript by [setting the `typescript_tsdk`](https://github.com/Microsoft/TypeScript-Sublime-Plugin#note-using-different-versions-of-typescript) setting in Sublime:
48+
49+
```json
50+
{
51+
"typescript_tsdk": "/Users/matb/my-amazing-project/node_modules/typescript/lib"
52+
}
53+
```
54+
55+
Finally add a `plugins` section to your [`tsconfig.json`](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html) or [`jsconfig.json`](https://code.visualstudio.com/Docs/languages/javascript#_javascript-project-jsconfigjson) and restart Sublime.
56+
57+
```json
58+
{
59+
"compilerOptions": {
60+
"plugins": [
61+
{
62+
"name": "typescript-lit-html-plugin"
63+
}
64+
]
65+
}
66+
}
67+
```
68+
69+
### With Atom
70+
This plugin works with the [Atom TypeScript plugin](https://atom.io/packages/atom-typescript).
71+
72+
First install the plugin and a copy of TypeScript in your workspace:
73+
74+
```bash
75+
npm install --save-dev typescript-lit-html-plugin typescript
76+
```
77+
78+
Then add a `plugins` section to your [`tsconfig.json`](http://www.typescriptlang.org/docs/handbook/tsconfig-json.html) or [`jsconfig.json`](https://code.visualstudio.com/Docs/languages/javascript#_javascript-project-jsconfigjson) and restart Atom.
79+
80+
```json
81+
{
82+
"compilerOptions": {
83+
"plugins": [
84+
{
85+
"name": "typescript-lit-html-plugin"
86+
}
87+
]
88+
}
89+
}
90+
```
91+
92+
To get sytnax highlighting for lit-html strings in Atom, consider installing the [language-babel](https://atom.io/packages/language-babel) extension.
93+
94+
95+
## Configuration
96+
97+
### Tags
98+
This plugin adds html IntelliSense to any template literal [tagged](https://developer.mozilla.org/en-US/docs/Web/JavaScript/Reference/Template_literals) with `html`:
99+
100+
```js
101+
import {html} from 'lit-html'
102+
103+
html`
104+
<div></div>
105+
`
106+
```
107+
108+
You can enable IntelliSense for other tag names by configuring `"tags"`:
109+
110+
```json
111+
{
112+
"compilerOptions": {
113+
"plugins": [
114+
{
115+
"name": "typescript-lit-html-plugin",
116+
"tags": [
117+
"html",
118+
"template"
119+
]
120+
}
121+
]
122+
}
123+
}
124+
```
125+
126+
## Contributing
127+
128+
To build the typescript-lit-html-plugin, you'll need [Git](https://git-scm.com/downloads) and [Node.js](https://nodejs.org/).
129+
130+
First, [fork](https://help.github.com/articles/fork-a-repo/) the typescript-lit-html-plugin repo and clone your fork:
131+
132+
```bash
133+
git clone https://github.com/YOUR_GITHUB_ACCOUNT_NAME/typescript-lit-html-plugin.git
134+
cd typescript-lit-html-plugin
135+
```
136+
137+
Then install dev dependencies:
138+
139+
```bash
140+
npm install
141+
```
142+
143+
The plugin is written in [TypeScript](http://www.typescriptlang.org). The source code is in the `src/` directory with the compiled JavaScript output to the `lib/` directory. Kick off a build using the `compile` script:
144+
145+
```bash
146+
npm run compile
147+
```
148+
149+
And then run the end to end tests with the `e2e` script:
150+
151+
```bash
152+
(cd e2e && npm install)
153+
npm run e2e
154+
```
155+
156+
You can submit bug fixes and features through [pull requests](https://help.github.com/articles/about-pull-requests/). To get started, first checkout a new feature branch on your local repo:
157+
158+
```bash
159+
git checkout -b my-awesome-new-feature-branch
160+
```
161+
162+
Make the desired code changes, commit them, and then push the changes up to your forked repository:
163+
164+
```bash
165+
git push origin my-awesome-new-feature-branch
166+
```
167+
168+
Then [submit a pull request](https://help.github.com/articles/creating-a-pull-request/
169+
) against the Microsoft typescript-lit-html-plugin repository.
170+
171+
Please also see our [Code of Conduct](CODE_OF_CONDUCT.md).
172+
173+
174+
## Credits
175+
176+
Code originally forked from: https://github.com/Quramy/ts-graphql-plugin

‎documentation/preview.gif

1.33 MB
Loading

‎e2e/package-lock.json

+12
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎e2e/package.json

+19
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
{
2+
"name": "e2e",
3+
"private": true,
4+
"version": "1.0.0",
5+
"description": "",
6+
"main": "index.js",
7+
"directories": {
8+
"test": "tests"
9+
},
10+
"scripts": {
11+
"test": "echo \"Error: no test specified\" && exit 1"
12+
},
13+
"keywords": [],
14+
"author": "",
15+
"license": "ISC",
16+
"dependencies": {
17+
"typescript": "2.4.2"
18+
}
19+
}

‎e2e/project-fixture/main.ts

Whitespace-only changes.

‎e2e/project-fixture/tsconfig.json

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
{
2+
"compilerOptions": {
3+
"target": "es2015",
4+
"module": "commonjs",
5+
"lib": [ ],
6+
"plugins": [
7+
{ "name": "../../../lib", "tags": ["html"] }
8+
]
9+
}
10+
}

‎e2e/server-fixture/index.js

+55
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
const { fork } = require('child_process');
2+
const path = require('path');
3+
const fs = require('fs');
4+
const readline = require('readline');
5+
6+
class TSServer {
7+
constructor() {
8+
const logfile = path.join(__dirname, 'log.txt');
9+
const tsserverPath = path.join(__dirname, '..', 'node_modules', 'typescript', 'lib', 'tsserver');
10+
const server = fork(tsserverPath, [
11+
'--logVerbosity', 'verbose',
12+
'--logFile', logfile
13+
], {
14+
cwd: path.join(__dirname, '..', 'project-fixture'),
15+
stdio: ['pipe', 'pipe', 'pipe', 'ipc'],
16+
});
17+
this._exitPromise = new Promise((resolve, reject) => {
18+
server.on('exit', code => resolve(code));
19+
server.on('error', reason => reject(reason));
20+
});
21+
server.stdout.setEncoding('utf-8');
22+
readline.createInterface({
23+
input: server.stdout
24+
}).on('line', line => {
25+
if (line[0] === '{') {
26+
this.responses.push(JSON.parse(line));
27+
}
28+
})
29+
30+
this._isClosed = false;
31+
this._server = server;
32+
this._seq = 0;
33+
this.responses = [];
34+
}
35+
36+
send(command) {
37+
const seq = ++this._seq;
38+
const req = JSON.stringify(Object.assign({ seq: seq, type: 'request' }, command)) + '\n';
39+
this._server.stdin.write(req);
40+
}
41+
42+
close() {
43+
if (!this._isClosed) {
44+
this._isClosed = true;
45+
this._server.stdin.end();
46+
}
47+
return this._exitPromise;
48+
}
49+
}
50+
51+
function createServer() {
52+
return new TSServer();
53+
}
54+
55+
module.exports = createServer;

‎e2e/tests/_helpers.js

+20
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
const assert = require('chai').assert;
2+
3+
exports.openMockFile = (server, mockFileName, fileContent) => {
4+
server.send({
5+
command: 'open',
6+
arguments: {
7+
file: mockFileName,
8+
fileContent,
9+
scriptKindName: 'TS'
10+
}
11+
});
12+
return server;
13+
};
14+
15+
16+
exports.getFirstResponseOfType = (command, server) => {
17+
const response = server.responses.find(response => response.command === command);
18+
assert.isTrue(response !== undefined);
19+
return response;
20+
};

‎e2e/tests/completions.js

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
const assert = require('chai').assert;
2+
const createServer = require('../server-fixture');
3+
const { openMockFile, getFirstResponseOfType } = require('./_helpers');
4+
5+
const mockFileName = 'main.ts';
6+
7+
describe('Completions', () => {
8+
it('should return tag completions', () => {
9+
const server = createServer();
10+
openMockFile(server, mockFileName, 'const q = html`<`');
11+
server.send({ command: 'completions', arguments: { file: mockFileName, offset: 17, line: 1, prefix: '' } });
12+
13+
return server.close().then(() => {
14+
const completionsResponse = getFirstResponseOfType('completions', server);
15+
assert.isTrue(completionsResponse.success);
16+
assert.isTrue(completionsResponse.body.some(item => item.name === 'main'));
17+
assert.isTrue(completionsResponse.body.some(item => item.name === 'button'));
18+
});
19+
});
20+
21+
it('should return property completions', () => {
22+
const server = createServer();
23+
openMockFile(server, mockFileName, 'const q = html`<button `');
24+
server.send({ command: 'completions', arguments: { file: mockFileName, offset: 24, line: 1, prefix: '' } });
25+
26+
return server.close().then(() => {
27+
const completionsResponse = getFirstResponseOfType('completions', server);
28+
assert.isTrue(completionsResponse.success);
29+
assert.isTrue(completionsResponse.body.some(item => item.name === 'onclick'));
30+
assert.isTrue(completionsResponse.body.some(item => item.name === 'title'));
31+
});
32+
});
33+
})

‎package-lock.json

+402
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

‎package.json

+45
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
{
2+
"name": "typescript-lit-html-plugin",
3+
"version": "0.0.1",
4+
"description": "TypeScript language service plugin that adds IntelliSense for html tagged templates",
5+
"keywords": [
6+
"TypeScript",
7+
"html",
8+
"literal html",
9+
"templates"
10+
],
11+
"main": "lib/index.js",
12+
"author": "Microsoft",
13+
"license": "MIT",
14+
"repository": {
15+
"type": "git",
16+
"url": "https://github.com/Microsoft/typescript-lit-html-plugin.git"
17+
},
18+
"bugs": {
19+
"url": "https://github.com/Microsoft/typescript-lit-html-plugin/issues"
20+
},
21+
"dependencies": {
22+
"typescript-template-language-service-decorator": "0.0.2",
23+
"vscode-html-languageservice": "^2.0.10",
24+
"vscode-languageserver-types": "^3.4.0"
25+
},
26+
"files": [
27+
"lib"
28+
],
29+
"devDependencies": {
30+
"@types/node": "^7.0.22",
31+
"chai": "^4.1.2",
32+
"glob": "^7.1.2",
33+
"mocha": "^3.5.3",
34+
"tslint": "^5.3.2",
35+
"typescript": "^2.5.3"
36+
},
37+
"peerDependencies": {
38+
"typescript": "^2.3.0"
39+
},
40+
"scripts": {
41+
"compile": "./node_modules/.bin/tsc -p .",
42+
"watch:compile": "./node_modules/.bin/tsc --watch -p .",
43+
"e2e": "./node_modules/.bin/mocha e2e/tests --slow 2000 --timeout 10000"
44+
}
45+
}

‎src/config.ts

+4
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
export const pluginName = 'ts-lit-html-plugin';

‎src/configuration.ts

+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
4+
export interface TsHtmlPluginConfiguration {
5+
tags: string[];
6+
}
7+
8+
export const defaultConfiguration: TsHtmlPluginConfiguration = {
9+
tags: ['html'],
10+
};
11+
12+
export const loadConfiguration = (config: any): TsHtmlPluginConfiguration => {
13+
return {
14+
tags: config.tags || defaultConfiguration.tags,
15+
};
16+
};

‎src/html-template-language-service.ts

+171
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,171 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
//
4+
// Original code forked from https://github.com/Quramy/ts-graphql-plugin
5+
6+
import * as ts from 'typescript/lib/tsserverlibrary';
7+
import { getLanguageService, LanguageService } from 'vscode-html-languageservice';
8+
import * as vscode from 'vscode-languageserver-types';
9+
import * as config from './config';
10+
import { TsHtmlPluginConfiguration } from './configuration';
11+
import { TemplateLanguageService, TemplateContext } from 'typescript-template-language-service-decorator';
12+
13+
export default class HtmlTemplateLanguageService implements TemplateLanguageService {
14+
15+
private _htmlLanguageService?: LanguageService;
16+
17+
constructor(
18+
private readonly configuration: TsHtmlPluginConfiguration
19+
) { }
20+
21+
private get htmlLanguageService(): LanguageService {
22+
if (!this._htmlLanguageService) {
23+
this._htmlLanguageService = getLanguageService();
24+
}
25+
return this._htmlLanguageService;
26+
}
27+
28+
public getCompletionsAtPosition(
29+
context: TemplateContext,
30+
position: ts.LineAndCharacter
31+
): ts.CompletionInfo {
32+
const doc = this.createVirtualDocument(context);
33+
const htmlDoc = this.htmlLanguageService.parseHTMLDocument(doc);
34+
const items = this.htmlLanguageService.doComplete(doc, position, htmlDoc);
35+
return translateCompletionItems(items);
36+
}
37+
38+
public getQuickInfoAtPosition(
39+
context: TemplateContext,
40+
position: ts.LineAndCharacter
41+
): ts.QuickInfo | undefined {
42+
const doc = this.createVirtualDocument(context);
43+
const htmlDoc = this.htmlLanguageService.parseHTMLDocument(doc);
44+
const hover = this.htmlLanguageService.doHover(doc, position, htmlDoc);
45+
if (hover) {
46+
return this.translateHover(hover, position, context);
47+
}
48+
return undefined;
49+
}
50+
51+
private createVirtualDocument(
52+
context: TemplateContext
53+
): vscode.TextDocument {
54+
const contents = context.text;
55+
return {
56+
uri: 'untitled://embedded.html',
57+
languageId: 'html',
58+
version: 1,
59+
getText: () => contents,
60+
positionAt: (offset: number) => {
61+
return context.toPosition(offset);
62+
},
63+
offsetAt: (p: vscode.Position) => {
64+
return context.toOffset(p);
65+
},
66+
lineCount: contents.split(/n/g).length + 1,
67+
};
68+
}
69+
70+
private translateHover(
71+
hover: vscode.Hover,
72+
position: ts.LineAndCharacter,
73+
context: TemplateContext
74+
): ts.QuickInfo {
75+
const contents: ts.SymbolDisplayPart[] = [];
76+
const convertPart = (hoverContents: typeof hover.contents) => {
77+
if (typeof hoverContents === 'string') {
78+
contents.push({ kind: 'unknown', text: hoverContents });
79+
} else if (Array.isArray(hoverContents)) {
80+
hoverContents.forEach(convertPart);
81+
} else {
82+
contents.push({ kind: 'unknown', text: hoverContents.value });
83+
}
84+
};
85+
convertPart(hover.contents);
86+
const start = context.toOffset(hover.range ? hover.range.start : position);
87+
return {
88+
kind: ts.ScriptElementKind.unknown,
89+
kindModifiers: '',
90+
textSpan: {
91+
start,
92+
length: hover.range ? context.toOffset(hover.range.end) - start : 1,
93+
},
94+
displayParts: [],
95+
documentation: contents,
96+
tags: [],
97+
};
98+
}
99+
}
100+
101+
function translateCompletionItems(items: vscode.CompletionList): ts.CompletionInfo {
102+
return {
103+
isGlobalCompletion: false,
104+
isMemberCompletion: false,
105+
isNewIdentifierLocation: false,
106+
entries: items.items.map(translateCompetionEntry),
107+
};
108+
}
109+
110+
function translateCompetionEntry(item: vscode.CompletionItem): ts.CompletionEntry {
111+
return {
112+
name: item.label,
113+
kindModifiers: '',
114+
kind: item.kind ? translateionCompletionItemKind(item.kind) : ts.ScriptElementKind.unknown,
115+
sortText: '0',
116+
};
117+
}
118+
119+
function translateionCompletionItemKind(kind: vscode.CompletionItemKind): ts.ScriptElementKind {
120+
switch (kind) {
121+
case vscode.CompletionItemKind.Method:
122+
return ts.ScriptElementKind.memberFunctionElement;
123+
case vscode.CompletionItemKind.Function:
124+
return ts.ScriptElementKind.functionElement;
125+
case vscode.CompletionItemKind.Constructor:
126+
return ts.ScriptElementKind.constructorImplementationElement;
127+
case vscode.CompletionItemKind.Field:
128+
case vscode.CompletionItemKind.Variable:
129+
return ts.ScriptElementKind.variableElement;
130+
case vscode.CompletionItemKind.Class:
131+
return ts.ScriptElementKind.classElement;
132+
case vscode.CompletionItemKind.Interface:
133+
return ts.ScriptElementKind.interfaceElement;
134+
case vscode.CompletionItemKind.Module:
135+
return ts.ScriptElementKind.moduleElement;
136+
case vscode.CompletionItemKind.Property:
137+
return ts.ScriptElementKind.memberVariableElement;
138+
case vscode.CompletionItemKind.Unit:
139+
case vscode.CompletionItemKind.Value:
140+
return ts.ScriptElementKind.constElement;
141+
case vscode.CompletionItemKind.Enum:
142+
return ts.ScriptElementKind.enumElement;
143+
case vscode.CompletionItemKind.Keyword:
144+
return ts.ScriptElementKind.keyword;
145+
case vscode.CompletionItemKind.Color:
146+
return ts.ScriptElementKind.constElement;
147+
case vscode.CompletionItemKind.Reference:
148+
return ts.ScriptElementKind.alias;
149+
case vscode.CompletionItemKind.File:
150+
return ts.ScriptElementKind.moduleElement;
151+
case vscode.CompletionItemKind.Snippet:
152+
case vscode.CompletionItemKind.Text:
153+
default:
154+
return ts.ScriptElementKind.unknown;
155+
}
156+
}
157+
158+
function translateSeverity(severity: vscode.DiagnosticSeverity | undefined): ts.DiagnosticCategory {
159+
switch (severity) {
160+
case vscode.DiagnosticSeverity.Information:
161+
case vscode.DiagnosticSeverity.Hint:
162+
return ts.DiagnosticCategory.Message;
163+
164+
case vscode.DiagnosticSeverity.Warning:
165+
return ts.DiagnosticCategory.Warning;
166+
167+
case vscode.DiagnosticSeverity.Error:
168+
default:
169+
return ts.DiagnosticCategory.Error;
170+
}
171+
}

‎src/index.ts

+46
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,46 @@
1+
// Copyright (c) Microsoft Corporation. All rights reserved.
2+
// Licensed under the MIT License.
3+
//
4+
// Original code forked from https://github.com/Quramy/ts-graphql-plugin
5+
6+
import * as ts from 'typescript/lib/tsserverlibrary';
7+
import HtmlTemplateLanguageService from './html-template-language-service';
8+
import { decorateWithTemplateLanguageService, Logger } from 'typescript-template-language-service-decorator';
9+
import { pluginName } from './config';
10+
import { loadConfiguration } from './configuration';
11+
12+
class LanguageServiceLogger implements Logger {
13+
constructor(
14+
private readonly info: ts.server.PluginCreateInfo
15+
) { }
16+
17+
public log(msg: string) {
18+
this.info.project.projectService.logger.info(`[${pluginName}] ${msg}`);
19+
}
20+
}
21+
22+
function create(info: ts.server.PluginCreateInfo): ts.LanguageService {
23+
const logger = new LanguageServiceLogger(info);
24+
const config = loadConfiguration(info.config);
25+
26+
logger.log('config: ' + JSON.stringify(config));
27+
28+
return decorateWithTemplateLanguageService(info.languageService, new HtmlTemplateLanguageService(config), {
29+
tags: config.tags,
30+
enableForStringWithSubstitutions: true,
31+
getSubstitution(
32+
templateString: string,
33+
start: number,
34+
end: number
35+
): string {
36+
const placeholder = templateString.slice(start, end);
37+
const pre = templateString.slice(0, start);
38+
const replacementChar = pre.match(/(^|\n)\s*$/g) ? ' ' : 'x';
39+
return placeholder.replace(/./gm, c => c === '\n' ? '\n' : replacementChar);
40+
},
41+
}, { logger });
42+
}
43+
44+
export = (mod: { typescript: typeof ts }) => {
45+
return { create };
46+
};

‎tsconfig.json

+15
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,15 @@
1+
{
2+
"compilerOptions": {
3+
"module": "commonjs",
4+
"target": "es6",
5+
"sourceMap": true,
6+
"outDir": "lib",
7+
"rootDir": "src"
8+
},
9+
"exclude": [
10+
"lib",
11+
"e2e",
12+
"node_modules",
13+
"test-workspace"
14+
]
15+
}

‎tslint.json

+33
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
{
2+
"defaultSeverity": "error",
3+
"extends": ["tslint:recommended"],
4+
"jsRules": {},
5+
"rules": {
6+
"indent": [true, "spaces"],
7+
"interface-name": [true, "never-prefix"],
8+
"variable-name": [true, "check-format", "allow-leading-underscore"],
9+
"curly": [true, "ignore-same-line"],
10+
"member-access": [true],
11+
"max-classes-per-file": [false],
12+
"no-empty": false,
13+
"object-literal-sort-keys": false,
14+
"no-unused-expression": true,
15+
"no-unused-variable": [true],
16+
"arrow-parens": [true, "ban-single-arg-parens"],
17+
"quotemark": [true, "single"],
18+
"eofline": false,
19+
"semicolon": [true, "always"],
20+
"class-name": true,
21+
"prefer-const": true,
22+
"import-spacing": true,
23+
"ordered-imports": false,
24+
"trailing-comma": [true, { "multiline": {
25+
"objects": "always",
26+
"arrays": "always",
27+
"functions": "never",
28+
"typeLiterals": "ignore"
29+
}}],
30+
"max-line-length": false
31+
},
32+
"rulesDirectory": []
33+
}

0 commit comments

Comments
 (0)
Please sign in to comment.