mirror of
https://github.com/microsoft/vscode-extension-samples.git
synced 2026-04-27 16:55:44 +08:00
Merge pull request #264 from microsoft/embedded-lsp
Samples for embedded lsp
This commit is contained in:
4
lsp-embedded-language-service/.gitignore
vendored
Normal file
4
lsp-embedded-language-service/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
out
|
||||
node_modules
|
||||
client/server
|
||||
.vscode-test
|
||||
44
lsp-embedded-language-service/.vscode/launch.json
vendored
Normal file
44
lsp-embedded-language-service/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
// A launch configuration that compiles the extension and then opens it inside a new window
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"name": "Launch Client",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": ["--extensionDevelopmentPath=${workspaceRoot}"],
|
||||
"outFiles": ["${workspaceRoot}/client/out/**/*.js"],
|
||||
"preLaunchTask": {
|
||||
"type": "npm",
|
||||
"script": "watch"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"name": "Attach to Server",
|
||||
"port": 6009,
|
||||
"restart": true,
|
||||
"outFiles": ["${workspaceRoot}/server/out/**/*.js"]
|
||||
},
|
||||
{
|
||||
"name": "Language Server E2E Test",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceRoot}",
|
||||
"--extensionTestsPath=${workspaceRoot}/client/out/test",
|
||||
"${workspaceRoot}/client/testFixture"
|
||||
],
|
||||
"outFiles": ["${workspaceRoot}/client/out/test/**/*.js"]
|
||||
}
|
||||
],
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Client + Server",
|
||||
"configurations": ["Launch Client", "Attach to Server"]
|
||||
}
|
||||
]
|
||||
}
|
||||
6
lsp-embedded-language-service/.vscode/settings.json
vendored
Normal file
6
lsp-embedded-language-service/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"editor.insertSpaces": false,
|
||||
"tslint.enable": true,
|
||||
"typescript.tsc.autoDetect": "off",
|
||||
"typescript.preferences.quoteStyle": "single"
|
||||
}
|
||||
33
lsp-embedded-language-service/.vscode/tasks.json
vendored
Normal file
33
lsp-embedded-language-service/.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "compile",
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"panel": "dedicated",
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"isBackground": true,
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"panel": "dedicated",
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc-watch"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
14
lsp-embedded-language-service/.vscodeignore
Normal file
14
lsp-embedded-language-service/.vscodeignore
Normal file
@ -0,0 +1,14 @@
|
||||
.vscode/**
|
||||
**/*.ts
|
||||
**/*.map
|
||||
.gitignore
|
||||
**/tsconfig.json
|
||||
**/tsconfig.base.json
|
||||
contributing.md
|
||||
.travis.yml
|
||||
client/node_modules/**
|
||||
!client/node_modules/vscode-jsonrpc/**
|
||||
!client/node_modules/vscode-languageclient/**
|
||||
!client/node_modules/vscode-languageserver-protocol/**
|
||||
!client/node_modules/vscode-languageserver-types/**
|
||||
!client/node_modules/semver/**
|
||||
38
lsp-embedded-language-service/README.md
Normal file
38
lsp-embedded-language-service/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# LSP Example for Embedded Language using Language Service
|
||||
|
||||
Heavily documented sample code for https://code.visualstudio.com/api/language-extensions/embedded-language-server-guide
|
||||
|
||||
## Functionality
|
||||
|
||||
This Language Server works for plain text file. It has the following language features:
|
||||
- Completions
|
||||
- Diagnostics regenerated on each file change or configuration change
|
||||
|
||||
It also includes an End-to-End test.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
.
|
||||
├── client // Language Client
|
||||
│ ├── src
|
||||
│ │ ├── test // End to End tests for Language Client / Server
|
||||
│ │ └── extension.ts // Language Client entry point
|
||||
├── package.json // The extension manifest.
|
||||
└── server // Language Server
|
||||
└── src
|
||||
└── server.ts // Language Server entry point
|
||||
```
|
||||
|
||||
## Running the Sample
|
||||
|
||||
- Run `npm install` in this folder. This installs all necessary npm modules in both the client and server folder
|
||||
- Open VS Code on this folder.
|
||||
- Press Ctrl+Shift+B to compile the client and server.
|
||||
- Switch to the Debug viewlet.
|
||||
- Select `Launch Client` from the drop down.
|
||||
- Run the launch config.
|
||||
- If you want to debug the server as well use the launch configuration `Attach to Server`
|
||||
- In the [Extension Development Host] instance of VSCode, open a document in 'plain text' language mode.
|
||||
- Type `j` or `t` to see `Javascript` and `TypeScript` completion.
|
||||
- Enter text content such as `AAA aaa BBB`. The extension will emit diagnostics for all words in all-uppercase.
|
||||
744
lsp-embedded-language-service/client/package-lock.json
generated
Normal file
744
lsp-embedded-language-service/client/package-lock.json
generated
Normal file
@ -0,0 +1,744 @@
|
||||
{
|
||||
"name": "lsp-sample-client",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"agent-base": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
|
||||
"integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es6-promisify": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
|
||||
"integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^2.0.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||
"dev": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
|
||||
"dev": true
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
|
||||
"dev": true
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"browser-stdout": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
|
||||
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
|
||||
"dev": true
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
|
||||
"dev": true
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
|
||||
"dev": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.15.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
|
||||
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
|
||||
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
|
||||
"dev": true
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
||||
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
|
||||
"dev": true
|
||||
},
|
||||
"es6-promisify": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
|
||||
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es6-promise": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||
"dev": true
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"dev": true
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
|
||||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
|
||||
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
|
||||
"dev": true
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
|
||||
"dev": true
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"growl": {
|
||||
"version": "1.10.5",
|
||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
|
||||
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
|
||||
"dev": true
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
|
||||
"dev": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
|
||||
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.5.5",
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
},
|
||||
"he": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
|
||||
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
|
||||
"dev": true
|
||||
},
|
||||
"http-proxy-agent": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
|
||||
"integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"agent-base": "4",
|
||||
"debug": "3.1.0"
|
||||
}
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
"sshpk": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
|
||||
"integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"agent-base": "^4.1.0",
|
||||
"debug": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
||||
"dev": true
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
|
||||
"dev": true
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
|
||||
"dev": true
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.2.3",
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.40.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
|
||||
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.24",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
|
||||
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.40.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"mocha": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
|
||||
"integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browser-stdout": "1.3.1",
|
||||
"commander": "2.15.1",
|
||||
"debug": "3.1.0",
|
||||
"diff": "3.5.0",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"glob": "7.1.2",
|
||||
"growl": "1.10.5",
|
||||
"he": "1.1.1",
|
||||
"minimatch": "3.0.4",
|
||||
"mkdirp": "0.5.1",
|
||||
"supports-color": "5.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
|
||||
"dev": true
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz",
|
||||
"integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==",
|
||||
"dev": true
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"querystringify": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
|
||||
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
|
||||
"dev": true
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
||||
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.0",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.4.3",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
|
||||
"dev": true
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
|
||||
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA=="
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.12",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz",
|
||||
"integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
|
||||
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
"bcrypt-pbkdf": "^1.0.0",
|
||||
"dashdash": "^1.12.0",
|
||||
"ecc-jsbn": "~0.1.1",
|
||||
"getpass": "^0.1.1",
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.0.2",
|
||||
"tweetnacl": "~0.14.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
|
||||
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
|
||||
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"psl": "^1.1.24",
|
||||
"punycode": "^1.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
|
||||
"dev": true
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
|
||||
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"url-parse": {
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
|
||||
"integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"querystringify": "^2.1.1",
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
|
||||
"dev": true
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"vscode": {
|
||||
"version": "1.1.35",
|
||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.35.tgz",
|
||||
"integrity": "sha512-xPnxzQU40LOS2yPyzWW+WKpTV6qA3z16TcgpZ9O38UWLA157Zz4GxUx5H7Gd07pxzw0GqvusbF4D+5GBgNxvEQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.2",
|
||||
"mocha": "^5.2.0",
|
||||
"request": "^2.88.0",
|
||||
"semver": "^5.4.1",
|
||||
"source-map-support": "^0.5.0",
|
||||
"url-parse": "^1.4.4",
|
||||
"vscode-test": "^0.4.1"
|
||||
}
|
||||
},
|
||||
"vscode-jsonrpc": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz",
|
||||
"integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg=="
|
||||
},
|
||||
"vscode-languageclient": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz",
|
||||
"integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==",
|
||||
"requires": {
|
||||
"semver": "^5.5.0",
|
||||
"vscode-languageserver-protocol": "3.14.1"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-protocol": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz",
|
||||
"integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==",
|
||||
"requires": {
|
||||
"vscode-jsonrpc": "^4.0.0",
|
||||
"vscode-languageserver-types": "3.14.0"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz",
|
||||
"integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A=="
|
||||
},
|
||||
"vscode-test": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.4.3.tgz",
|
||||
"integrity": "sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"http-proxy-agent": "^2.1.0",
|
||||
"https-proxy-agent": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
25
lsp-embedded-language-service/client/package.json
Normal file
25
lsp-embedded-language-service/client/package.json
Normal file
@ -0,0 +1,25 @@
|
||||
{
|
||||
"name": "lsp-sample-client",
|
||||
"description": "VSCode part of a language server",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"version": "0.0.1",
|
||||
"publisher": "vscode",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-extension-samples"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.33.0"
|
||||
},
|
||||
"scripts": {
|
||||
"update-vscode": "vscode-install",
|
||||
"postinstall": "vscode-install"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageclient": "^5.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vscode": "^1.1.35"
|
||||
}
|
||||
}
|
||||
61
lsp-embedded-language-service/client/src/extension.ts
Normal file
61
lsp-embedded-language-service/client/src/extension.ts
Normal file
@ -0,0 +1,61 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import * as path from 'path';
|
||||
import { ExtensionContext } from 'vscode';
|
||||
|
||||
import {
|
||||
LanguageClient,
|
||||
LanguageClientOptions,
|
||||
ServerOptions,
|
||||
TransportKind
|
||||
} from 'vscode-languageclient';
|
||||
|
||||
let client: LanguageClient;
|
||||
|
||||
export function activate(context: ExtensionContext) {
|
||||
// The server is implemented in node
|
||||
let serverModule = context.asAbsolutePath(
|
||||
path.join('server', 'out', 'server.js')
|
||||
);
|
||||
// The debug options for the server
|
||||
// --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
|
||||
let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };
|
||||
|
||||
// If the extension is launched in debug mode then the debug server options are used
|
||||
// Otherwise the run options are used
|
||||
let serverOptions: ServerOptions = {
|
||||
run: { module: serverModule, transport: TransportKind.ipc },
|
||||
debug: {
|
||||
module: serverModule,
|
||||
transport: TransportKind.ipc,
|
||||
options: debugOptions
|
||||
}
|
||||
};
|
||||
|
||||
// Options to control the language client
|
||||
let clientOptions: LanguageClientOptions = {
|
||||
// Register the server for plain text documents
|
||||
documentSelector: [{ scheme: 'file', language: 'html' }]
|
||||
};
|
||||
|
||||
// Create the language client and start the client.
|
||||
client = new LanguageClient(
|
||||
'languageServerExample',
|
||||
'Language Server Example',
|
||||
serverOptions,
|
||||
clientOptions
|
||||
);
|
||||
|
||||
// Start the client. This will also launch the server
|
||||
client.start();
|
||||
}
|
||||
|
||||
export function deactivate(): Thenable<void> | undefined {
|
||||
if (!client) {
|
||||
return undefined;
|
||||
}
|
||||
return client.stop();
|
||||
}
|
||||
11
lsp-embedded-language-service/client/tsconfig.json
Normal file
11
lsp-embedded-language-service/client/tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"outDir": "out",
|
||||
"rootDir": "src",
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", ".vscode-test"]
|
||||
}
|
||||
323
lsp-embedded-language-service/package-lock.json
generated
Normal file
323
lsp-embedded-language-service/package-lock.json
generated
Normal file
@ -0,0 +1,323 @@
|
||||
{
|
||||
"name": "lsp-embedded-language-service-sample",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
|
||||
"integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/highlight": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"@babel/highlight": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
|
||||
"integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^2.0.0",
|
||||
"esutils": "^2.0.2",
|
||||
"js-tokens": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@types/mocha": {
|
||||
"version": "5.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz",
|
||||
"integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "12.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.7.tgz",
|
||||
"integrity": "sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"builtin-modules": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
|
||||
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.20.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
|
||||
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
|
||||
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
|
||||
"dev": true
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||
"dev": true
|
||||
},
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
|
||||
"dev": true
|
||||
},
|
||||
"esutils": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
|
||||
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
|
||||
"dev": true
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"dev": true
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.13.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
|
||||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz",
|
||||
"integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
|
||||
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
|
||||
"dev": true
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
|
||||
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
|
||||
"dev": true
|
||||
},
|
||||
"tslint": {
|
||||
"version": "5.16.0",
|
||||
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.16.0.tgz",
|
||||
"integrity": "sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"builtin-modules": "^1.1.1",
|
||||
"chalk": "^2.3.0",
|
||||
"commander": "^2.12.1",
|
||||
"diff": "^3.2.0",
|
||||
"glob": "^7.1.1",
|
||||
"js-yaml": "^3.13.0",
|
||||
"minimatch": "^3.0.4",
|
||||
"mkdirp": "^0.5.1",
|
||||
"resolve": "^1.3.2",
|
||||
"semver": "^5.3.0",
|
||||
"tslib": "^1.8.0",
|
||||
"tsutils": "^2.29.0"
|
||||
}
|
||||
},
|
||||
"tsutils": {
|
||||
"version": "2.29.0",
|
||||
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
|
||||
"integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "^1.8.1"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.6.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz",
|
||||
"integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==",
|
||||
"dev": true
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
35
lsp-embedded-language-service/package.json
Normal file
35
lsp-embedded-language-service/package.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "lsp-embedded-language-service-sample",
|
||||
"description": "A language server example using language services to support embedded languages",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"version": "1.0.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-extension-samples"
|
||||
},
|
||||
"publisher": "vscode-samples",
|
||||
"categories": [],
|
||||
"keywords": [],
|
||||
"engines": {
|
||||
"vscode": "^1.33.0"
|
||||
},
|
||||
"activationEvents": [
|
||||
"onLanguage:html"
|
||||
],
|
||||
"main": "./client/out/extension",
|
||||
"contributes": {},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "cd client && npm run update-vscode && cd .. && npm run compile",
|
||||
"compile": "tsc -b",
|
||||
"watch": "tsc -b -w",
|
||||
"postinstall": "cd client && npm install && cd ../server && npm install && cd ..",
|
||||
"test": "sh ./scripts/e2e.sh"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^12.11.7",
|
||||
"tslint": "^5.16.0",
|
||||
"typescript": "^3.6.4"
|
||||
}
|
||||
}
|
||||
96
lsp-embedded-language-service/server/package-lock.json
generated
Normal file
96
lsp-embedded-language-service/server/package-lock.json
generated
Normal file
@ -0,0 +1,96 @@
|
||||
{
|
||||
"name": "lsp-sample-server",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"vscode-css-languageservice": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-css-languageservice/-/vscode-css-languageservice-4.1.1.tgz",
|
||||
"integrity": "sha512-2r2bYbhscivRu1zqh5kNe8aYpFnfksMYC7wTpKX2HqFsSzSJYXk0sCqPaWsP5ptqz0OFBTXnzx2JlE+Nb5Edgw==",
|
||||
"requires": {
|
||||
"vscode-languageserver-textdocument": "^1.0.1",
|
||||
"vscode-languageserver-types": "^3.15.1",
|
||||
"vscode-nls": "^4.1.1",
|
||||
"vscode-uri": "^2.1.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.15.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
|
||||
"integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
|
||||
},
|
||||
"vscode-uri": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.1.tgz",
|
||||
"integrity": "sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"vscode-html-languageservice": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-3.0.3.tgz",
|
||||
"integrity": "sha512-U+upM3gHp3HaF3wXAnUduA6IDKcz6frWS/dTAju3cZVIyZwOLBBFElQVlLH0ycHyMzqUFrjvdv+kEyPAEWfQ/g==",
|
||||
"requires": {
|
||||
"vscode-languageserver-types": "^3.15.0-next.2",
|
||||
"vscode-nls": "^4.1.1",
|
||||
"vscode-uri": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.15.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
|
||||
"integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
|
||||
},
|
||||
"vscode-uri": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.1.tgz",
|
||||
"integrity": "sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"vscode-jsonrpc": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz",
|
||||
"integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg=="
|
||||
},
|
||||
"vscode-languageserver": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz",
|
||||
"integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==",
|
||||
"requires": {
|
||||
"vscode-languageserver-protocol": "3.14.1",
|
||||
"vscode-uri": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-protocol": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz",
|
||||
"integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==",
|
||||
"requires": {
|
||||
"vscode-jsonrpc": "^4.0.0",
|
||||
"vscode-languageserver-types": "3.14.0"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-textdocument": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-textdocument/-/vscode-languageserver-textdocument-1.0.1.tgz",
|
||||
"integrity": "sha512-UIcJDjX7IFkck7cSkNNyzIz5FyvpQfY7sdzVy+wkKN/BLaD4DQ0ppXQrKePomCxTS7RrolK1I0pey0bG9eh8dA=="
|
||||
},
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz",
|
||||
"integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A=="
|
||||
},
|
||||
"vscode-nls": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz",
|
||||
"integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw=="
|
||||
},
|
||||
"vscode-uri": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz",
|
||||
"integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
20
lsp-embedded-language-service/server/package.json
Normal file
20
lsp-embedded-language-service/server/package.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"name": "lsp-sample-server",
|
||||
"description": "Example implementation of a language server in node.",
|
||||
"version": "1.0.0",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-extension-samples"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-css-languageservice": "^4.1.1",
|
||||
"vscode-html-languageservice": "^3.0.3",
|
||||
"vscode-languageserver": "^5.2.1"
|
||||
},
|
||||
"scripts": {}
|
||||
}
|
||||
233
lsp-embedded-language-service/server/src/embeddedSupport.ts
Normal file
233
lsp-embedded-language-service/server/src/embeddedSupport.ts
Normal file
@ -0,0 +1,233 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TextDocument, Position, LanguageService, TokenType, Range } from './languageModes';
|
||||
|
||||
export interface LanguageRange extends Range {
|
||||
languageId: string | undefined;
|
||||
attributeValue?: boolean;
|
||||
}
|
||||
|
||||
export interface HTMLDocumentRegions {
|
||||
getEmbeddedDocument(languageId: string, ignoreAttributeValues?: boolean): TextDocument;
|
||||
getLanguageRanges(range: Range): LanguageRange[];
|
||||
getLanguageAtPosition(position: Position): string | undefined;
|
||||
getLanguagesInDocument(): string[];
|
||||
getImportedScripts(): string[];
|
||||
}
|
||||
|
||||
export const CSS_STYLE_RULE = '__';
|
||||
|
||||
interface EmbeddedRegion { languageId: string | undefined; start: number; end: number; attributeValue?: boolean; }
|
||||
|
||||
|
||||
export function getDocumentRegions(languageService: LanguageService, document: TextDocument): HTMLDocumentRegions {
|
||||
let regions: EmbeddedRegion[] = [];
|
||||
let scanner = languageService.createScanner(document.getText());
|
||||
let lastTagName: string = '';
|
||||
let lastAttributeName: string | null = null;
|
||||
let languageIdFromType: string | undefined = undefined;
|
||||
let importedScripts: string[] = [];
|
||||
|
||||
let token = scanner.scan();
|
||||
while (token !== TokenType.EOS) {
|
||||
switch (token) {
|
||||
case TokenType.StartTag:
|
||||
lastTagName = scanner.getTokenText();
|
||||
lastAttributeName = null;
|
||||
languageIdFromType = 'javascript';
|
||||
break;
|
||||
case TokenType.Styles:
|
||||
regions.push({ languageId: 'css', start: scanner.getTokenOffset(), end: scanner.getTokenEnd() });
|
||||
break;
|
||||
case TokenType.Script:
|
||||
regions.push({ languageId: languageIdFromType, start: scanner.getTokenOffset(), end: scanner.getTokenEnd() });
|
||||
break;
|
||||
case TokenType.AttributeName:
|
||||
lastAttributeName = scanner.getTokenText();
|
||||
break;
|
||||
case TokenType.AttributeValue:
|
||||
if (lastAttributeName === 'src' && lastTagName.toLowerCase() === 'script') {
|
||||
let value = scanner.getTokenText();
|
||||
if (value[0] === '\'' || value[0] === '"') {
|
||||
value = value.substr(1, value.length - 1);
|
||||
}
|
||||
importedScripts.push(value);
|
||||
} else if (lastAttributeName === 'type' && lastTagName.toLowerCase() === 'script') {
|
||||
if (/["'](module|(text|application)\/(java|ecma)script|text\/babel)["']/.test(scanner.getTokenText())) {
|
||||
languageIdFromType = 'javascript';
|
||||
} else if (/["']text\/typescript["']/.test(scanner.getTokenText())) {
|
||||
languageIdFromType = 'typescript';
|
||||
} else {
|
||||
languageIdFromType = undefined;
|
||||
}
|
||||
} else {
|
||||
let attributeLanguageId = getAttributeLanguage(lastAttributeName!);
|
||||
if (attributeLanguageId) {
|
||||
let start = scanner.getTokenOffset();
|
||||
let end = scanner.getTokenEnd();
|
||||
let firstChar = document.getText()[start];
|
||||
if (firstChar === '\'' || firstChar === '"') {
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
regions.push({ languageId: attributeLanguageId, start, end, attributeValue: true });
|
||||
}
|
||||
}
|
||||
lastAttributeName = null;
|
||||
break;
|
||||
}
|
||||
token = scanner.scan();
|
||||
}
|
||||
return {
|
||||
getLanguageRanges: (range: Range) => getLanguageRanges(document, regions, range),
|
||||
getEmbeddedDocument: (languageId: string, ignoreAttributeValues: boolean) => getEmbeddedDocument(document, regions, languageId, ignoreAttributeValues),
|
||||
getLanguageAtPosition: (position: Position) => getLanguageAtPosition(document, regions, position),
|
||||
getLanguagesInDocument: () => getLanguagesInDocument(document, regions),
|
||||
getImportedScripts: () => importedScripts
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function getLanguageRanges(document: TextDocument, regions: EmbeddedRegion[], range: Range): LanguageRange[] {
|
||||
let result: LanguageRange[] = [];
|
||||
let currentPos = range ? range.start : Position.create(0, 0);
|
||||
let currentOffset = range ? document.offsetAt(range.start) : 0;
|
||||
let endOffset = range ? document.offsetAt(range.end) : document.getText().length;
|
||||
for (let region of regions) {
|
||||
if (region.end > currentOffset && region.start < endOffset) {
|
||||
let start = Math.max(region.start, currentOffset);
|
||||
let startPos = document.positionAt(start);
|
||||
if (currentOffset < region.start) {
|
||||
result.push({
|
||||
start: currentPos,
|
||||
end: startPos,
|
||||
languageId: 'html'
|
||||
});
|
||||
}
|
||||
let end = Math.min(region.end, endOffset);
|
||||
let endPos = document.positionAt(end);
|
||||
if (end > region.start) {
|
||||
result.push({
|
||||
start: startPos,
|
||||
end: endPos,
|
||||
languageId: region.languageId,
|
||||
attributeValue: region.attributeValue
|
||||
});
|
||||
}
|
||||
currentOffset = end;
|
||||
currentPos = endPos;
|
||||
}
|
||||
}
|
||||
if (currentOffset < endOffset) {
|
||||
let endPos = range ? range.end : document.positionAt(endOffset);
|
||||
result.push({
|
||||
start: currentPos,
|
||||
end: endPos,
|
||||
languageId: 'html'
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getLanguagesInDocument(_document: TextDocument, regions: EmbeddedRegion[]): string[] {
|
||||
let result = [];
|
||||
for (let region of regions) {
|
||||
if (region.languageId && result.indexOf(region.languageId) === -1) {
|
||||
result.push(region.languageId);
|
||||
if (result.length === 3) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.push('html');
|
||||
return result;
|
||||
}
|
||||
|
||||
function getLanguageAtPosition(document: TextDocument, regions: EmbeddedRegion[], position: Position): string | undefined {
|
||||
let offset = document.offsetAt(position);
|
||||
for (let region of regions) {
|
||||
if (region.start <= offset) {
|
||||
if (offset <= region.end) {
|
||||
return region.languageId;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 'html';
|
||||
}
|
||||
|
||||
function getEmbeddedDocument(document: TextDocument, contents: EmbeddedRegion[], languageId: string, ignoreAttributeValues: boolean): TextDocument {
|
||||
let currentPos = 0;
|
||||
let oldContent = document.getText();
|
||||
let result = '';
|
||||
let lastSuffix = '';
|
||||
for (let c of contents) {
|
||||
if (c.languageId === languageId && (!ignoreAttributeValues || !c.attributeValue)) {
|
||||
result = substituteWithWhitespace(result, currentPos, c.start, oldContent, lastSuffix, getPrefix(c));
|
||||
result += oldContent.substring(c.start, c.end);
|
||||
currentPos = c.end;
|
||||
lastSuffix = getSuffix(c);
|
||||
}
|
||||
}
|
||||
result = substituteWithWhitespace(result, currentPos, oldContent.length, oldContent, lastSuffix, '');
|
||||
return TextDocument.create(document.uri, languageId, document.version, result);
|
||||
}
|
||||
|
||||
function getPrefix(c: EmbeddedRegion) {
|
||||
if (c.attributeValue) {
|
||||
switch (c.languageId) {
|
||||
case 'css': return CSS_STYLE_RULE + '{';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
function getSuffix(c: EmbeddedRegion) {
|
||||
if (c.attributeValue) {
|
||||
switch (c.languageId) {
|
||||
case 'css': return '}';
|
||||
case 'javascript': return ';';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function substituteWithWhitespace(result: string, start: number, end: number, oldContent: string, before: string, after: string) {
|
||||
let accumulatedWS = 0;
|
||||
result += before;
|
||||
for (let i = start + before.length; i < end; i++) {
|
||||
let ch = oldContent[i];
|
||||
if (ch === '\n' || ch === '\r') {
|
||||
// only write new lines, skip the whitespace
|
||||
accumulatedWS = 0;
|
||||
result += ch;
|
||||
} else {
|
||||
accumulatedWS++;
|
||||
}
|
||||
}
|
||||
result = append(result, ' ', accumulatedWS - after.length);
|
||||
result += after;
|
||||
return result;
|
||||
}
|
||||
|
||||
function append(result: string, str: string, n: number): string {
|
||||
while (n > 0) {
|
||||
if (n & 1) {
|
||||
result += str;
|
||||
}
|
||||
n >>= 1;
|
||||
str += str;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getAttributeLanguage(attributeName: string): string | null {
|
||||
let match = attributeName.match(/^(style)$|^(on\w+)$/i);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
return match[1] ? 'css' : 'javascript';
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TextDocument } from 'vscode-html-languageservice';
|
||||
|
||||
export interface LanguageModelCache<T> {
|
||||
get(document: TextDocument): T;
|
||||
onDocumentRemoved(document: TextDocument): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTimeInSec: number, parse: (document: TextDocument) => T): LanguageModelCache<T> {
|
||||
let languageModels: { [uri: string]: { version: number, languageId: string, cTime: number, languageModel: T } } = {};
|
||||
let nModels = 0;
|
||||
|
||||
let cleanupInterval: NodeJS.Timer | undefined = undefined;
|
||||
if (cleanupIntervalTimeInSec > 0) {
|
||||
cleanupInterval = setInterval(() => {
|
||||
const cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000;
|
||||
const uris = Object.keys(languageModels);
|
||||
for (const uri of uris) {
|
||||
const languageModelInfo = languageModels[uri];
|
||||
if (languageModelInfo.cTime < cutoffTime) {
|
||||
delete languageModels[uri];
|
||||
nModels--;
|
||||
}
|
||||
}
|
||||
}, cleanupIntervalTimeInSec * 1000);
|
||||
}
|
||||
|
||||
return {
|
||||
get(document: TextDocument): T {
|
||||
const version = document.version;
|
||||
const languageId = document.languageId;
|
||||
const languageModelInfo = languageModels[document.uri];
|
||||
if (languageModelInfo && languageModelInfo.version === version && languageModelInfo.languageId === languageId) {
|
||||
languageModelInfo.cTime = Date.now();
|
||||
return languageModelInfo.languageModel;
|
||||
}
|
||||
const languageModel = parse(document);
|
||||
languageModels[document.uri] = { languageModel, version, languageId, cTime: Date.now() };
|
||||
if (!languageModelInfo) {
|
||||
nModels++;
|
||||
}
|
||||
|
||||
if (nModels === maxEntries) {
|
||||
let oldestTime = Number.MAX_VALUE;
|
||||
let oldestUri = null;
|
||||
for (const uri in languageModels) {
|
||||
const languageModelInfo = languageModels[uri];
|
||||
if (languageModelInfo.cTime < oldestTime) {
|
||||
oldestUri = uri;
|
||||
oldestTime = languageModelInfo.cTime;
|
||||
}
|
||||
}
|
||||
if (oldestUri) {
|
||||
delete languageModels[oldestUri];
|
||||
nModels--;
|
||||
}
|
||||
}
|
||||
return languageModel;
|
||||
|
||||
},
|
||||
onDocumentRemoved(document: TextDocument) {
|
||||
const uri = document.uri;
|
||||
if (languageModels[uri]) {
|
||||
delete languageModels[uri];
|
||||
nModels--;
|
||||
}
|
||||
},
|
||||
dispose() {
|
||||
if (typeof cleanupInterval !== 'undefined') {
|
||||
clearInterval(cleanupInterval);
|
||||
cleanupInterval = undefined;
|
||||
languageModels = {};
|
||||
nModels = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
122
lsp-embedded-language-service/server/src/languageModes.ts
Normal file
122
lsp-embedded-language-service/server/src/languageModes.ts
Normal file
@ -0,0 +1,122 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { getCSSLanguageService } from 'vscode-css-languageservice';
|
||||
import {
|
||||
CompletionList,
|
||||
Diagnostic,
|
||||
getLanguageService as getHTMLLanguageService,
|
||||
Position,
|
||||
Range,
|
||||
TextDocument
|
||||
} from 'vscode-html-languageservice';
|
||||
import { getCSSMode } from './modes/cssMode';
|
||||
import { getDocumentRegions, HTMLDocumentRegions } from './embeddedSupport';
|
||||
import { getHTMLMode } from './modes/htmlMode';
|
||||
import { getLanguageModelCache, LanguageModelCache } from './languageModelCache';
|
||||
|
||||
export * from 'vscode-html-languageservice';
|
||||
|
||||
export interface LanguageMode {
|
||||
getId(): string;
|
||||
doValidation?: (document: TextDocument) => Diagnostic[];
|
||||
doComplete?: (document: TextDocument, position: Position) => CompletionList;
|
||||
onDocumentRemoved(document: TextDocument): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export interface LanguageModes {
|
||||
getModeAtPosition(document: TextDocument, position: Position): LanguageMode | undefined;
|
||||
getModesInRange(document: TextDocument, range: Range): LanguageModeRange[];
|
||||
getAllModes(): LanguageMode[];
|
||||
getAllModesInDocument(document: TextDocument): LanguageMode[];
|
||||
getMode(languageId: string): LanguageMode | undefined;
|
||||
onDocumentRemoved(document: TextDocument): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export interface LanguageModeRange extends Range {
|
||||
mode: LanguageMode | undefined;
|
||||
attributeValue?: boolean;
|
||||
}
|
||||
|
||||
export function getLanguageModes(): LanguageModes {
|
||||
const htmlLanguageService = getHTMLLanguageService();
|
||||
const cssLanguageService = getCSSLanguageService();
|
||||
|
||||
let documentRegions = getLanguageModelCache<HTMLDocumentRegions>(10, 60, document =>
|
||||
getDocumentRegions(htmlLanguageService, document)
|
||||
);
|
||||
|
||||
let modelCaches: LanguageModelCache<any>[] = [];
|
||||
modelCaches.push(documentRegions);
|
||||
|
||||
let modes = Object.create(null);
|
||||
modes['html'] = getHTMLMode(htmlLanguageService);
|
||||
modes['css'] = getCSSMode(cssLanguageService, documentRegions);
|
||||
|
||||
return {
|
||||
getModeAtPosition(
|
||||
document: TextDocument,
|
||||
position: Position
|
||||
): LanguageMode | undefined {
|
||||
let languageId = documentRegions.get(document).getLanguageAtPosition(position);
|
||||
if (languageId) {
|
||||
return modes[languageId];
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
getModesInRange(document: TextDocument, range: Range): LanguageModeRange[] {
|
||||
return documentRegions
|
||||
.get(document)
|
||||
.getLanguageRanges(range)
|
||||
.map(r => {
|
||||
return <LanguageModeRange>{
|
||||
start: r.start,
|
||||
end: r.end,
|
||||
mode: r.languageId && modes[r.languageId],
|
||||
attributeValue: r.attributeValue
|
||||
};
|
||||
});
|
||||
},
|
||||
getAllModesInDocument(document: TextDocument): LanguageMode[] {
|
||||
let result = [];
|
||||
for (let languageId of documentRegions.get(document).getLanguagesInDocument()) {
|
||||
let mode = modes[languageId];
|
||||
if (mode) {
|
||||
result.push(mode);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
getAllModes(): LanguageMode[] {
|
||||
let result = [];
|
||||
for (let languageId in modes) {
|
||||
let mode = modes[languageId];
|
||||
if (mode) {
|
||||
result.push(mode);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
getMode(languageId: string): LanguageMode {
|
||||
return modes[languageId];
|
||||
},
|
||||
onDocumentRemoved(document: TextDocument) {
|
||||
modelCaches.forEach(mc => mc.onDocumentRemoved(document));
|
||||
for (let mode in modes) {
|
||||
modes[mode].onDocumentRemoved(document);
|
||||
}
|
||||
},
|
||||
dispose(): void {
|
||||
modelCaches.forEach(mc => mc.dispose());
|
||||
modelCaches = [];
|
||||
for (let mode in modes) {
|
||||
modes[mode].dispose();
|
||||
}
|
||||
modes = {};
|
||||
}
|
||||
};
|
||||
}
|
||||
34
lsp-embedded-language-service/server/src/modes/cssMode.ts
Normal file
34
lsp-embedded-language-service/server/src/modes/cssMode.ts
Normal file
@ -0,0 +1,34 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { LanguageService as CSSLanguageService } from 'vscode-css-languageservice';
|
||||
import { HTMLDocumentRegions } from '../embeddedSupport';
|
||||
import { LanguageModelCache } from '../languageModelCache';
|
||||
import { LanguageMode, Position, TextDocument } from '../languageModes';
|
||||
|
||||
export function getCSSMode(
|
||||
cssLanguageService: CSSLanguageService,
|
||||
documentRegions: LanguageModelCache<HTMLDocumentRegions>
|
||||
): LanguageMode {
|
||||
return {
|
||||
getId() {
|
||||
return 'css';
|
||||
},
|
||||
doValidation(document: TextDocument) {
|
||||
// Get virtual CSS document, with all non-CSS code replaced with whitespace
|
||||
const embedded = documentRegions.get(document).getEmbeddedDocument('css');
|
||||
const stylesheet = cssLanguageService.parseStylesheet(embedded);
|
||||
return cssLanguageService.doValidation(embedded, stylesheet);
|
||||
},
|
||||
doComplete(document: TextDocument, position: Position) {
|
||||
// Get virtual CSS document, with all non-CSS code replaced with whitespace
|
||||
const embedded = documentRegions.get(document).getEmbeddedDocument('css');
|
||||
const stylesheet = cssLanguageService.parseStylesheet(embedded);
|
||||
return cssLanguageService.doComplete(embedded, position, stylesheet);
|
||||
},
|
||||
onDocumentRemoved(_document: TextDocument) {},
|
||||
dispose() {}
|
||||
};
|
||||
}
|
||||
28
lsp-embedded-language-service/server/src/modes/htmlMode.ts
Normal file
28
lsp-embedded-language-service/server/src/modes/htmlMode.ts
Normal file
@ -0,0 +1,28 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import {
|
||||
LanguageMode,
|
||||
LanguageService as HTMLLanguageService,
|
||||
Position,
|
||||
TextDocument
|
||||
} from '../languageModes';
|
||||
|
||||
export function getHTMLMode(htmlLanguageService: HTMLLanguageService): LanguageMode {
|
||||
return {
|
||||
getId() {
|
||||
return 'html';
|
||||
},
|
||||
doComplete(document: TextDocument, position: Position) {
|
||||
return htmlLanguageService.doComplete(
|
||||
document,
|
||||
position,
|
||||
htmlLanguageService.parseHTMLDocument(document)
|
||||
);
|
||||
},
|
||||
onDocumentRemoved(_document: TextDocument) {},
|
||||
dispose() {}
|
||||
};
|
||||
}
|
||||
106
lsp-embedded-language-service/server/src/server.ts
Normal file
106
lsp-embedded-language-service/server/src/server.ts
Normal file
@ -0,0 +1,106 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import {
|
||||
CompletionList,
|
||||
createConnection,
|
||||
Diagnostic,
|
||||
InitializeParams,
|
||||
ProposedFeatures,
|
||||
TextDocument,
|
||||
TextDocuments
|
||||
} from 'vscode-languageserver';
|
||||
import { getLanguageModes, LanguageModes } from './languageModes';
|
||||
|
||||
// Create a connection for the server. The connection uses Node's IPC as a transport.
|
||||
// Also include all preview / proposed LSP features.
|
||||
let connection = createConnection(ProposedFeatures.all);
|
||||
|
||||
// Create a simple text document manager. The text document manager
|
||||
// supports full document sync only
|
||||
let documents: TextDocuments = new TextDocuments();
|
||||
|
||||
let languageModes: LanguageModes;
|
||||
|
||||
connection.onInitialize((_params: InitializeParams) => {
|
||||
languageModes = getLanguageModes();
|
||||
|
||||
documents.onDidClose(e => {
|
||||
languageModes.onDocumentRemoved(e.document);
|
||||
});
|
||||
connection.onShutdown(() => {
|
||||
languageModes.dispose();
|
||||
});
|
||||
|
||||
return {
|
||||
capabilities: {
|
||||
textDocumentSync: documents.syncKind,
|
||||
// Tell the client that the server supports code completion
|
||||
completionProvider: {
|
||||
resolveProvider: false
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
connection.onInitialized(() => {});
|
||||
|
||||
connection.onDidChangeConfiguration(_change => {
|
||||
// Revalidate all open text documents
|
||||
documents.all().forEach(validateTextDocument);
|
||||
});
|
||||
|
||||
// The content of a text document has changed. This event is emitted
|
||||
// when the text document first opened or when its content has changed.
|
||||
documents.onDidChangeContent(change => {
|
||||
validateTextDocument(change.document);
|
||||
});
|
||||
|
||||
async function validateTextDocument(textDocument: TextDocument) {
|
||||
try {
|
||||
const version = textDocument.version;
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
if (textDocument.languageId === 'html') {
|
||||
const modes = languageModes.getAllModesInDocument(textDocument);
|
||||
const latestTextDocument = documents.get(textDocument.uri);
|
||||
if (latestTextDocument && latestTextDocument.version === version) {
|
||||
// check no new version has come in after in after the async op
|
||||
modes.forEach(mode => {
|
||||
if (mode.doValidation) {
|
||||
mode.doValidation(latestTextDocument).forEach(d => {
|
||||
diagnostics.push(d);
|
||||
});
|
||||
}
|
||||
});
|
||||
connection.sendDiagnostics({ uri: latestTextDocument.uri, diagnostics });
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
connection.console.error(`Error while validating ${textDocument.uri}`);
|
||||
connection.console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
connection.onCompletion(async (textDocumentPosition, token) => {
|
||||
const document = documents.get(textDocumentPosition.textDocument.uri);
|
||||
if (!document) {
|
||||
return null;
|
||||
}
|
||||
|
||||
const mode = languageModes.getModeAtPosition(document, textDocumentPosition.position);
|
||||
if (!mode || !mode.doComplete) {
|
||||
return CompletionList.create();
|
||||
}
|
||||
const doComplete = mode.doComplete!;
|
||||
|
||||
return doComplete(document, textDocumentPosition.position);
|
||||
});
|
||||
|
||||
// Make the text document manager listen on the connection
|
||||
// for open, change and close text document events
|
||||
documents.listen(connection);
|
||||
|
||||
// Listen on the connection
|
||||
connection.listen();
|
||||
13
lsp-embedded-language-service/server/tsconfig.json
Normal file
13
lsp-embedded-language-service/server/tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"outDir": "out",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", ".vscode-test"]
|
||||
}
|
||||
20
lsp-embedded-language-service/tsconfig.json
Normal file
20
lsp-embedded-language-service/tsconfig.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"outDir": "out",
|
||||
"rootDir": "src",
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
".vscode-test"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "./client" },
|
||||
{ "path": "./server" }
|
||||
]
|
||||
}
|
||||
6
lsp-embedded-language-service/tslint.json
Normal file
6
lsp-embedded-language-service/tslint.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"rules": {
|
||||
"indent": [true, "tabs"],
|
||||
"semicolon": [true, "always"]
|
||||
}
|
||||
}
|
||||
4
lsp-embedded-request-forwarding/.gitignore
vendored
Normal file
4
lsp-embedded-request-forwarding/.gitignore
vendored
Normal file
@ -0,0 +1,4 @@
|
||||
out
|
||||
node_modules
|
||||
client/server
|
||||
.vscode-test
|
||||
44
lsp-embedded-request-forwarding/.vscode/launch.json
vendored
Normal file
44
lsp-embedded-request-forwarding/.vscode/launch.json
vendored
Normal file
@ -0,0 +1,44 @@
|
||||
// A launch configuration that compiles the extension and then opens it inside a new window
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"name": "Launch Client",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": ["--extensionDevelopmentPath=${workspaceRoot}"],
|
||||
"outFiles": ["${workspaceRoot}/client/out/**/*.js"],
|
||||
"preLaunchTask": {
|
||||
"type": "npm",
|
||||
"script": "watch"
|
||||
}
|
||||
},
|
||||
{
|
||||
"type": "node",
|
||||
"request": "attach",
|
||||
"name": "Attach to Server",
|
||||
"port": 6009,
|
||||
"restart": true,
|
||||
"outFiles": ["${workspaceRoot}/server/out/**/*.js"]
|
||||
},
|
||||
{
|
||||
"name": "Language Server E2E Test",
|
||||
"type": "extensionHost",
|
||||
"request": "launch",
|
||||
"runtimeExecutable": "${execPath}",
|
||||
"args": [
|
||||
"--extensionDevelopmentPath=${workspaceRoot}",
|
||||
"--extensionTestsPath=${workspaceRoot}/client/out/test",
|
||||
"${workspaceRoot}/client/testFixture"
|
||||
],
|
||||
"outFiles": ["${workspaceRoot}/client/out/test/**/*.js"]
|
||||
}
|
||||
],
|
||||
"compounds": [
|
||||
{
|
||||
"name": "Client + Server",
|
||||
"configurations": ["Launch Client", "Attach to Server"]
|
||||
}
|
||||
]
|
||||
}
|
||||
6
lsp-embedded-request-forwarding/.vscode/settings.json
vendored
Normal file
6
lsp-embedded-request-forwarding/.vscode/settings.json
vendored
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"editor.insertSpaces": false,
|
||||
"tslint.enable": true,
|
||||
"typescript.tsc.autoDetect": "off",
|
||||
"typescript.preferences.quoteStyle": "single"
|
||||
}
|
||||
33
lsp-embedded-request-forwarding/.vscode/tasks.json
vendored
Normal file
33
lsp-embedded-request-forwarding/.vscode/tasks.json
vendored
Normal file
@ -0,0 +1,33 @@
|
||||
{
|
||||
"version": "2.0.0",
|
||||
"tasks": [
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "compile",
|
||||
"group": "build",
|
||||
"presentation": {
|
||||
"panel": "dedicated",
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc"
|
||||
]
|
||||
},
|
||||
{
|
||||
"type": "npm",
|
||||
"script": "watch",
|
||||
"isBackground": true,
|
||||
"group": {
|
||||
"kind": "build",
|
||||
"isDefault": true
|
||||
},
|
||||
"presentation": {
|
||||
"panel": "dedicated",
|
||||
"reveal": "never"
|
||||
},
|
||||
"problemMatcher": [
|
||||
"$tsc-watch"
|
||||
]
|
||||
}
|
||||
]
|
||||
}
|
||||
14
lsp-embedded-request-forwarding/.vscodeignore
Normal file
14
lsp-embedded-request-forwarding/.vscodeignore
Normal file
@ -0,0 +1,14 @@
|
||||
.vscode/**
|
||||
**/*.ts
|
||||
**/*.map
|
||||
.gitignore
|
||||
**/tsconfig.json
|
||||
**/tsconfig.base.json
|
||||
contributing.md
|
||||
.travis.yml
|
||||
client/node_modules/**
|
||||
!client/node_modules/vscode-jsonrpc/**
|
||||
!client/node_modules/vscode-languageclient/**
|
||||
!client/node_modules/vscode-languageserver-protocol/**
|
||||
!client/node_modules/vscode-languageserver-types/**
|
||||
!client/node_modules/semver/**
|
||||
38
lsp-embedded-request-forwarding/README.md
Normal file
38
lsp-embedded-request-forwarding/README.md
Normal file
@ -0,0 +1,38 @@
|
||||
# LSP Example for Embedded Language using Language Service
|
||||
|
||||
Heavily documented sample code for https://code.visualstudio.com/api/language-extensions/embedded-language-server-guide
|
||||
|
||||
## Functionality
|
||||
|
||||
This Language Server works for plain text file. It has the following language features:
|
||||
- Completions
|
||||
- Diagnostics regenerated on each file change or configuration change
|
||||
|
||||
It also includes an End-to-End test.
|
||||
|
||||
## Structure
|
||||
|
||||
```
|
||||
.
|
||||
├── client // Language Client
|
||||
│ ├── src
|
||||
│ │ ├── test // End to End tests for Language Client / Server
|
||||
│ │ └── extension.ts // Language Client entry point
|
||||
├── package.json // The extension manifest.
|
||||
└── server // Language Server
|
||||
└── src
|
||||
└── server.ts // Language Server entry point
|
||||
```
|
||||
|
||||
## Running the Sample
|
||||
|
||||
- Run `npm install` in this folder. This installs all necessary npm modules in both the client and server folder
|
||||
- Open VS Code on this folder.
|
||||
- Press Ctrl+Shift+B to compile the client and server.
|
||||
- Switch to the Debug viewlet.
|
||||
- Select `Launch Client` from the drop down.
|
||||
- Run the launch config.
|
||||
- If you want to debug the server as well use the launch configuration `Attach to Server`
|
||||
- In the [Extension Development Host] instance of VSCode, open a document in 'plain text' language mode.
|
||||
- Type `j` or `t` to see `Javascript` and `TypeScript` completion.
|
||||
- Enter text content such as `AAA aaa BBB`. The extension will emit diagnostics for all words in all-uppercase.
|
||||
771
lsp-embedded-request-forwarding/client/package-lock.json
generated
Normal file
771
lsp-embedded-request-forwarding/client/package-lock.json
generated
Normal file
@ -0,0 +1,771 @@
|
||||
{
|
||||
"name": "lsp-sample-client",
|
||||
"version": "0.0.1",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"agent-base": {
|
||||
"version": "4.3.0",
|
||||
"resolved": "https://registry.npmjs.org/agent-base/-/agent-base-4.3.0.tgz",
|
||||
"integrity": "sha512-salcGninV0nPrwpGNn4VTXBb1SOuXQBiqbrNXoeizJsHrsL6ERFM2Ne3JUSBWRE6aeNJI2ROP/WEEIDUiDe3cg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es6-promisify": "^5.0.0"
|
||||
}
|
||||
},
|
||||
"ajv": {
|
||||
"version": "6.10.0",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-6.10.0.tgz",
|
||||
"integrity": "sha512-nffhOpkymDECQyR0mnsUtoCE8RlX38G0rYP+wgLWFyZuUyuuojSSvi/+euOiQBIn63whYwYVIIH1TvE3tu4OEg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fast-deep-equal": "^2.0.1",
|
||||
"fast-json-stable-stringify": "^2.0.0",
|
||||
"json-schema-traverse": "^0.4.1",
|
||||
"uri-js": "^4.2.2"
|
||||
}
|
||||
},
|
||||
"asn1": {
|
||||
"version": "0.2.4",
|
||||
"resolved": "https://registry.npmjs.org/asn1/-/asn1-0.2.4.tgz",
|
||||
"integrity": "sha512-jxwzQpLQjSmWXgwaCZE9Nz+glAG01yF1QnWgbhGwHI5A6FRIEY6IVqtHhIepHqI7/kyEyQEagBC5mBEFlIYvdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safer-buffer": "~2.1.0"
|
||||
}
|
||||
},
|
||||
"assert-plus": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/assert-plus/-/assert-plus-1.0.0.tgz",
|
||||
"integrity": "sha1-8S4PPF13sLHN2RRpQuTpbB5N1SU=",
|
||||
"dev": true
|
||||
},
|
||||
"asynckit": {
|
||||
"version": "0.4.0",
|
||||
"resolved": "https://registry.npmjs.org/asynckit/-/asynckit-0.4.0.tgz",
|
||||
"integrity": "sha1-x57Zf380y48robyXkLzDZkdLS3k=",
|
||||
"dev": true
|
||||
},
|
||||
"aws-sign2": {
|
||||
"version": "0.7.0",
|
||||
"resolved": "https://registry.npmjs.org/aws-sign2/-/aws-sign2-0.7.0.tgz",
|
||||
"integrity": "sha1-tG6JCTSpWR8tL2+G1+ap8bP+dqg=",
|
||||
"dev": true
|
||||
},
|
||||
"aws4": {
|
||||
"version": "1.8.0",
|
||||
"resolved": "https://registry.npmjs.org/aws4/-/aws4-1.8.0.tgz",
|
||||
"integrity": "sha512-ReZxvNHIOv88FlT7rxcXIIC0fPt4KZqZbOlivyWtXLt8ESx84zd3kMC6iK5jVeS2qt+g7ftS7ye4fi06X5rtRQ==",
|
||||
"dev": true
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"bcrypt-pbkdf": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.2.tgz",
|
||||
"integrity": "sha1-pDAdOJtqQ/m2f/PKEaP2Y342Dp4=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tweetnacl": "^0.14.3"
|
||||
}
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"browser-stdout": {
|
||||
"version": "1.3.1",
|
||||
"resolved": "https://registry.npmjs.org/browser-stdout/-/browser-stdout-1.3.1.tgz",
|
||||
"integrity": "sha512-qhAVI1+Av2X7qelOfAIYwXONood6XlZE/fXaBSmW/T5SzLAmCgzi+eiWE7fUvbHaeNBQH13UftjpXxsfLkMpgw==",
|
||||
"dev": true
|
||||
},
|
||||
"buffer-from": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/buffer-from/-/buffer-from-1.1.1.tgz",
|
||||
"integrity": "sha512-MQcXEUbCKtEo7bhqEs6560Hyd4XaovZlO/k9V3hjVUF/zwW7KBVdSK4gIt/bzwS9MbR5qob+F5jusZsb0YQK2A==",
|
||||
"dev": true
|
||||
},
|
||||
"caseless": {
|
||||
"version": "0.12.0",
|
||||
"resolved": "https://registry.npmjs.org/caseless/-/caseless-0.12.0.tgz",
|
||||
"integrity": "sha1-G2gcIf+EAzyCZUMJBolCDRhxUdw=",
|
||||
"dev": true
|
||||
},
|
||||
"combined-stream": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/combined-stream/-/combined-stream-1.0.8.tgz",
|
||||
"integrity": "sha512-FQN4MRfuJeHf7cBbBMJFXhKSDq+2kAArBlmRBvcvFE5BB1HZKXtSFASDhdlz9zOYwxh8lDdnvmMOe/+5cdoEdg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"delayed-stream": "~1.0.0"
|
||||
}
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.15.1",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.15.1.tgz",
|
||||
"integrity": "sha512-VlfT9F3V0v+jr4yxPc5gg9s62/fIVWsd2Bk2iD435um1NlGMYdVCq+MjcXnhYq2icNOizHr1kK+5TI6H0Hy0ag==",
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"core-util-is": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/core-util-is/-/core-util-is-1.0.2.tgz",
|
||||
"integrity": "sha1-tf1UIgqivFq1eqtxQMlAdUUDwac=",
|
||||
"dev": true
|
||||
},
|
||||
"dashdash": {
|
||||
"version": "1.14.1",
|
||||
"resolved": "https://registry.npmjs.org/dashdash/-/dashdash-1.14.1.tgz",
|
||||
"integrity": "sha1-hTz6D3y+L+1d4gMmuN1YEDX24vA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"debug": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/debug/-/debug-3.1.0.tgz",
|
||||
"integrity": "sha512-OX8XqP7/1a9cqkxYw2yXss15f26NKWBpDXQd0/uK/KPqdQhxbPa994hnzjcE2VqQpDslf55723cKPUOGSmMY3g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ms": "2.0.0"
|
||||
}
|
||||
},
|
||||
"delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
"integrity": "sha1-3zrhmayt+31ECqrgsp4icrJOxhk=",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
|
||||
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
|
||||
"dev": true
|
||||
},
|
||||
"ecc-jsbn": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/ecc-jsbn/-/ecc-jsbn-0.1.2.tgz",
|
||||
"integrity": "sha1-OoOpBOVDUyh4dMVkt1SThoSamMk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"es6-promise": {
|
||||
"version": "4.2.8",
|
||||
"resolved": "https://registry.npmjs.org/es6-promise/-/es6-promise-4.2.8.tgz",
|
||||
"integrity": "sha512-HJDGx5daxeIvxdBxvG2cb9g4tEvwIk3i8+nhX0yGrYmZUzbkdg8QbDevheDB8gd0//uPj4c1EQua8Q+MViT0/w==",
|
||||
"dev": true
|
||||
},
|
||||
"es6-promisify": {
|
||||
"version": "5.0.0",
|
||||
"resolved": "https://registry.npmjs.org/es6-promisify/-/es6-promisify-5.0.0.tgz",
|
||||
"integrity": "sha1-UQnWLz5W6pZ8S2NQWu8IKRyKUgM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"es6-promise": "^4.0.3"
|
||||
}
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||
"dev": true
|
||||
},
|
||||
"extend": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/extend/-/extend-3.0.2.tgz",
|
||||
"integrity": "sha512-fjquC59cD7CyW6urNXK0FBufkZcoiGG80wTuPujX590cB5Ttln20E2UB4S/WARVqhXffZl2LNgS+gQdPIIim/g==",
|
||||
"dev": true
|
||||
},
|
||||
"extsprintf": {
|
||||
"version": "1.3.0",
|
||||
"resolved": "https://registry.npmjs.org/extsprintf/-/extsprintf-1.3.0.tgz",
|
||||
"integrity": "sha1-lpGEQOMEGnpBT4xS48V06zw+HgU=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-deep-equal": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-2.0.1.tgz",
|
||||
"integrity": "sha1-ewUhjd+WZ79/Nwv3/bLLFf3Qqkk=",
|
||||
"dev": true
|
||||
},
|
||||
"fast-json-stable-stringify": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz",
|
||||
"integrity": "sha1-1RQsDK7msRifh9OnYREGT4bIu/I=",
|
||||
"dev": true
|
||||
},
|
||||
"forever-agent": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/forever-agent/-/forever-agent-0.6.1.tgz",
|
||||
"integrity": "sha1-+8cfDEGt6zf5bFd60e1C2P2sypE=",
|
||||
"dev": true
|
||||
},
|
||||
"form-data": {
|
||||
"version": "2.3.3",
|
||||
"resolved": "https://registry.npmjs.org/form-data/-/form-data-2.3.3.tgz",
|
||||
"integrity": "sha512-1lLKB2Mu3aGP1Q/2eCOx0fNbRMe7XdwktwOruhfqqd0rIJWwN4Dh+E3hrPSlDCXnSR7UtZ1N38rVXm+6+MEhJQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asynckit": "^0.4.0",
|
||||
"combined-stream": "^1.0.6",
|
||||
"mime-types": "^2.1.12"
|
||||
}
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"getpass": {
|
||||
"version": "0.1.7",
|
||||
"resolved": "https://registry.npmjs.org/getpass/-/getpass-0.1.7.tgz",
|
||||
"integrity": "sha1-Xv+OPmhNVprkyysSgmBOi6YhSfo=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"growl": {
|
||||
"version": "1.10.5",
|
||||
"resolved": "https://registry.npmjs.org/growl/-/growl-1.10.5.tgz",
|
||||
"integrity": "sha512-qBr4OuELkhPenW6goKVXiv47US3clb3/IbuWF9KNKEijAy9oeHxU9IgzjvJhHkUzhaj7rOUD7+YGWqUjLp5oSA==",
|
||||
"dev": true
|
||||
},
|
||||
"har-schema": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/har-schema/-/har-schema-2.0.0.tgz",
|
||||
"integrity": "sha1-qUwiJOvKwEeCoNkDVSHyRzW37JI=",
|
||||
"dev": true
|
||||
},
|
||||
"har-validator": {
|
||||
"version": "5.1.3",
|
||||
"resolved": "https://registry.npmjs.org/har-validator/-/har-validator-5.1.3.tgz",
|
||||
"integrity": "sha512-sNvOCzEQNr/qrvJgc3UG/kD4QtlHycrzwS+6mfTrrSq97BvaYcPZZI1ZSqGSPR73Cxn4LKTD4PttRwfU7jWq5g==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ajv": "^6.5.5",
|
||||
"har-schema": "^2.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
},
|
||||
"he": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/he/-/he-1.1.1.tgz",
|
||||
"integrity": "sha1-k0EP0hsAlzUVH4howvJx80J+I/0=",
|
||||
"dev": true
|
||||
},
|
||||
"http-proxy-agent": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/http-proxy-agent/-/http-proxy-agent-2.1.0.tgz",
|
||||
"integrity": "sha512-qwHbBLV7WviBl0rQsOzH6o5lwyOIvwp/BdFnvVxXORldu5TmjFfjzBcWUWS5kWAZhmv+JtiDhSuQCp4sBfbIgg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"agent-base": "4",
|
||||
"debug": "3.1.0"
|
||||
}
|
||||
},
|
||||
"http-signature": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/http-signature/-/http-signature-1.2.0.tgz",
|
||||
"integrity": "sha1-muzZJRFHcvPZW2WmCruPfBj7rOE=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"jsprim": "^1.2.2",
|
||||
"sshpk": "^1.7.0"
|
||||
}
|
||||
},
|
||||
"https-proxy-agent": {
|
||||
"version": "2.2.1",
|
||||
"resolved": "https://registry.npmjs.org/https-proxy-agent/-/https-proxy-agent-2.2.1.tgz",
|
||||
"integrity": "sha512-HPCTS1LW51bcyMYbxUIOO4HEOlQ1/1qRaFWcyxvwaqUS9TY88aoEuHUY33kuAh1YhVVaDQhLZsnPd+XNARWZlQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"agent-base": "^4.1.0",
|
||||
"debug": "^3.1.0"
|
||||
}
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.4",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.4.tgz",
|
||||
"integrity": "sha512-k/vGaX4/Yla3WzyMCvTQOXYeIHvqOKtnqBduzTHpzpQZzAskKMhZ2K+EnBiSM9zGSoIFeMpXKxa4dYeZIQqewQ==",
|
||||
"dev": true
|
||||
},
|
||||
"is-typedarray": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/is-typedarray/-/is-typedarray-1.0.0.tgz",
|
||||
"integrity": "sha1-5HnICFjfDBsR3dppQPlgEfzaSpo=",
|
||||
"dev": true
|
||||
},
|
||||
"isstream": {
|
||||
"version": "0.1.2",
|
||||
"resolved": "https://registry.npmjs.org/isstream/-/isstream-0.1.2.tgz",
|
||||
"integrity": "sha1-R+Y/evVa+m+S4VAOaQ64uFKcCZo=",
|
||||
"dev": true
|
||||
},
|
||||
"jsbn": {
|
||||
"version": "0.1.1",
|
||||
"resolved": "https://registry.npmjs.org/jsbn/-/jsbn-0.1.1.tgz",
|
||||
"integrity": "sha1-peZUwuWi3rXyAdls77yoDA7y9RM=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema": {
|
||||
"version": "0.2.3",
|
||||
"resolved": "https://registry.npmjs.org/json-schema/-/json-schema-0.2.3.tgz",
|
||||
"integrity": "sha1-tIDIkuWaLwWVTOcnvT8qTogvnhM=",
|
||||
"dev": true
|
||||
},
|
||||
"json-schema-traverse": {
|
||||
"version": "0.4.1",
|
||||
"resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz",
|
||||
"integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==",
|
||||
"dev": true
|
||||
},
|
||||
"json-stringify-safe": {
|
||||
"version": "5.0.1",
|
||||
"resolved": "https://registry.npmjs.org/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz",
|
||||
"integrity": "sha1-Epai1Y/UXxmg9s4B1lcB4sc1tus=",
|
||||
"dev": true
|
||||
},
|
||||
"jsprim": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/jsprim/-/jsprim-1.4.1.tgz",
|
||||
"integrity": "sha1-MT5mvB5cwG5Di8G3SZwuXFastqI=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "1.0.0",
|
||||
"extsprintf": "1.3.0",
|
||||
"json-schema": "0.2.3",
|
||||
"verror": "1.10.0"
|
||||
}
|
||||
},
|
||||
"mime-db": {
|
||||
"version": "1.40.0",
|
||||
"resolved": "https://registry.npmjs.org/mime-db/-/mime-db-1.40.0.tgz",
|
||||
"integrity": "sha512-jYdeOMPy9vnxEqFRRo6ZvTZ8d9oPb+k18PKoYNYUe2stVEBPPwsln/qWzdbmaIvnhZ9v2P+CuecK+fpUfsV2mA==",
|
||||
"dev": true
|
||||
},
|
||||
"mime-types": {
|
||||
"version": "2.1.24",
|
||||
"resolved": "https://registry.npmjs.org/mime-types/-/mime-types-2.1.24.tgz",
|
||||
"integrity": "sha512-WaFHS3MCl5fapm3oLxU4eYDw77IQM2ACcxQ9RIxfaC3ooc6PFuBMGZZsYpvoXS5D5QTWPieo1jjLdAm3TBP3cQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"mime-db": "1.40.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"mocha": {
|
||||
"version": "5.2.0",
|
||||
"resolved": "https://registry.npmjs.org/mocha/-/mocha-5.2.0.tgz",
|
||||
"integrity": "sha512-2IUgKDhc3J7Uug+FxMXuqIyYzH7gJjXECKe/w43IGgQHTSj3InJi+yAA7T24L9bQMRKiUEHxEX37G5JpVUGLcQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"browser-stdout": "1.3.1",
|
||||
"commander": "2.15.1",
|
||||
"debug": "3.1.0",
|
||||
"diff": "3.5.0",
|
||||
"escape-string-regexp": "1.0.5",
|
||||
"glob": "7.1.2",
|
||||
"growl": "1.10.5",
|
||||
"he": "1.1.1",
|
||||
"minimatch": "3.0.4",
|
||||
"mkdirp": "0.5.1",
|
||||
"supports-color": "5.4.0"
|
||||
},
|
||||
"dependencies": {
|
||||
"glob": {
|
||||
"version": "7.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.2.tgz",
|
||||
"integrity": "sha512-MJTUg1kjuLeQCJ+ccE4Vpa6kKVXkPYJ2mOCQyUuKLcLQsdrMCpBPUi8qVE6+YuaJkozeA9NusTAw3hLr8Xe5EQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"ms": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/ms/-/ms-2.0.0.tgz",
|
||||
"integrity": "sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=",
|
||||
"dev": true
|
||||
},
|
||||
"oauth-sign": {
|
||||
"version": "0.9.0",
|
||||
"resolved": "https://registry.npmjs.org/oauth-sign/-/oauth-sign-0.9.0.tgz",
|
||||
"integrity": "sha512-fexhUFFPTGV8ybAtSIGbV6gOkSv8UtRbDBnAyLQw4QPKkgNlsH2ByPGtMUqdWkos6YCRmAqViwgZrJc/mRDzZQ==",
|
||||
"dev": true
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"performance-now": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/performance-now/-/performance-now-2.1.0.tgz",
|
||||
"integrity": "sha1-Ywn04OX6kT7BxpMHrjZLSzd8nns=",
|
||||
"dev": true
|
||||
},
|
||||
"psl": {
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/psl/-/psl-1.2.0.tgz",
|
||||
"integrity": "sha512-GEn74ZffufCmkDDLNcl3uuyF/aSD6exEyh1v/ZSdAomB82t6G9hzJVRx0jBmLDW+VfZqks3aScmMw9DszwUalA==",
|
||||
"dev": true
|
||||
},
|
||||
"punycode": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-2.1.1.tgz",
|
||||
"integrity": "sha512-XRsRjdf+j5ml+y/6GKHPZbrF/8p2Yga0JPtdqTIY2Xe5ohJPD9saDJJLPvp9+NSBprVvevdXZybnj2cv8OEd0A==",
|
||||
"dev": true
|
||||
},
|
||||
"qs": {
|
||||
"version": "6.5.2",
|
||||
"resolved": "https://registry.npmjs.org/qs/-/qs-6.5.2.tgz",
|
||||
"integrity": "sha512-N5ZAX4/LxJmF+7wN74pUD6qAh9/wnvdQcjq9TZjevvXzSUo7bfmw91saqMjzGS2xq91/odN2dW/WOl7qQHNDGA==",
|
||||
"dev": true
|
||||
},
|
||||
"querystringify": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/querystringify/-/querystringify-2.1.1.tgz",
|
||||
"integrity": "sha512-w7fLxIRCRT7U8Qu53jQnJyPkYZIaR4n5151KMfcJlO/A9397Wxb1amJvROTK6TOnp7PfoAmg/qXiNHI+08jRfA==",
|
||||
"dev": true
|
||||
},
|
||||
"request": {
|
||||
"version": "2.88.0",
|
||||
"resolved": "https://registry.npmjs.org/request/-/request-2.88.0.tgz",
|
||||
"integrity": "sha512-NAqBSrijGLZdM0WZNsInLJpkJokL72XYjUpnB0iwsRgxh7dB6COrHnTBNwN0E+lHDAJzu7kLAkDeY08z2/A0hg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"aws-sign2": "~0.7.0",
|
||||
"aws4": "^1.8.0",
|
||||
"caseless": "~0.12.0",
|
||||
"combined-stream": "~1.0.6",
|
||||
"extend": "~3.0.2",
|
||||
"forever-agent": "~0.6.1",
|
||||
"form-data": "~2.3.2",
|
||||
"har-validator": "~5.1.0",
|
||||
"http-signature": "~1.2.0",
|
||||
"is-typedarray": "~1.0.0",
|
||||
"isstream": "~0.1.2",
|
||||
"json-stringify-safe": "~5.0.1",
|
||||
"mime-types": "~2.1.19",
|
||||
"oauth-sign": "~0.9.0",
|
||||
"performance-now": "^2.1.0",
|
||||
"qs": "~6.5.2",
|
||||
"safe-buffer": "^5.1.2",
|
||||
"tough-cookie": "~2.4.3",
|
||||
"tunnel-agent": "^0.6.0",
|
||||
"uuid": "^3.3.2"
|
||||
}
|
||||
},
|
||||
"requires-port": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/requires-port/-/requires-port-1.0.0.tgz",
|
||||
"integrity": "sha1-kl0mAdOaxIXgkc8NpcbmlNw9yv8=",
|
||||
"dev": true
|
||||
},
|
||||
"safe-buffer": {
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safe-buffer/-/safe-buffer-5.1.2.tgz",
|
||||
"integrity": "sha512-Gd2UZBJDkXlY7GbJxfsE8/nvKkUEU1G38c1siN6QP6a9PT9MmHB8GnpscSmMJSoF8LOIrt8ud/wPtojys4G6+g==",
|
||||
"dev": true
|
||||
},
|
||||
"safer-buffer": {
|
||||
"version": "2.1.2",
|
||||
"resolved": "https://registry.npmjs.org/safer-buffer/-/safer-buffer-2.1.2.tgz",
|
||||
"integrity": "sha512-YZo3K82SD7Riyi0E1EQPojLz7kpepnSQI9IyPbHHg1XXXevb5dJI7tpyN2ADxGcQbHG7vcyRHk0cbwqcQriUtg==",
|
||||
"dev": true
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
|
||||
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA=="
|
||||
},
|
||||
"source-map": {
|
||||
"version": "0.6.1",
|
||||
"resolved": "https://registry.npmjs.org/source-map/-/source-map-0.6.1.tgz",
|
||||
"integrity": "sha512-UjgapumWlbMhkBgzT7Ykc5YXUT46F0iKu8SGXq0bcwP5dz/h0Plj6enJqjz1Zbq2l5WaqYnrVbwWOWMyF3F47g==",
|
||||
"dev": true
|
||||
},
|
||||
"source-map-support": {
|
||||
"version": "0.5.12",
|
||||
"resolved": "https://registry.npmjs.org/source-map-support/-/source-map-support-0.5.12.tgz",
|
||||
"integrity": "sha512-4h2Pbvyy15EE02G+JOZpUCmqWJuqrs+sEkzewTm++BPi7Hvn/HwcqLAcNxYAyI0x13CpPPn+kMjl+hplXMHITQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"buffer-from": "^1.0.0",
|
||||
"source-map": "^0.6.0"
|
||||
}
|
||||
},
|
||||
"sshpk": {
|
||||
"version": "1.16.1",
|
||||
"resolved": "https://registry.npmjs.org/sshpk/-/sshpk-1.16.1.tgz",
|
||||
"integrity": "sha512-HXXqVUq7+pcKeLqqZj6mHFUMvXtOJt1uoUx09pFW6011inTMxqI8BA8PM95myrIyyKwdnzjdFjLiE6KBPVtJIg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"asn1": "~0.2.3",
|
||||
"assert-plus": "^1.0.0",
|
||||
"bcrypt-pbkdf": "^1.0.0",
|
||||
"dashdash": "^1.12.0",
|
||||
"ecc-jsbn": "~0.1.1",
|
||||
"getpass": "^0.1.1",
|
||||
"jsbn": "~0.1.0",
|
||||
"safer-buffer": "^2.0.2",
|
||||
"tweetnacl": "~0.14.0"
|
||||
}
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.4.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.4.0.tgz",
|
||||
"integrity": "sha512-zjaXglF5nnWpsq470jSv6P9DwPvgLkuapYmfDm3JWOm0vkNTVF2tI4UrN2r6jH1qM/uc/WtxYY1hYoA2dOKj5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"tough-cookie": {
|
||||
"version": "2.4.3",
|
||||
"resolved": "https://registry.npmjs.org/tough-cookie/-/tough-cookie-2.4.3.tgz",
|
||||
"integrity": "sha512-Q5srk/4vDM54WJsJio3XNn6K2sCG+CQ8G5Wz6bZhRZoAe/+TxjWB/GlFAnYEbkYVlON9FMk/fE3h2RLpPXo4lQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"psl": "^1.1.24",
|
||||
"punycode": "^1.4.1"
|
||||
},
|
||||
"dependencies": {
|
||||
"punycode": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/punycode/-/punycode-1.4.1.tgz",
|
||||
"integrity": "sha1-wNWmOycYgArY4esPpSachN1BhF4=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"tunnel-agent": {
|
||||
"version": "0.6.0",
|
||||
"resolved": "https://registry.npmjs.org/tunnel-agent/-/tunnel-agent-0.6.0.tgz",
|
||||
"integrity": "sha1-J6XeoGs2sEoKmWZ3SykIaPD8QP0=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"safe-buffer": "^5.0.1"
|
||||
}
|
||||
},
|
||||
"tweetnacl": {
|
||||
"version": "0.14.5",
|
||||
"resolved": "https://registry.npmjs.org/tweetnacl/-/tweetnacl-0.14.5.tgz",
|
||||
"integrity": "sha1-WuaBd/GS1EViadEIr6k/+HQ/T2Q=",
|
||||
"dev": true
|
||||
},
|
||||
"uri-js": {
|
||||
"version": "4.2.2",
|
||||
"resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.2.2.tgz",
|
||||
"integrity": "sha512-KY9Frmirql91X2Qgjry0Wd4Y+YTdrdZheS8TFwvkbLWf/G5KNJDCh6pKL5OZctEW4+0Baa5idK2ZQuELRwPznQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"punycode": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"url-parse": {
|
||||
"version": "1.4.7",
|
||||
"resolved": "https://registry.npmjs.org/url-parse/-/url-parse-1.4.7.tgz",
|
||||
"integrity": "sha512-d3uaVyzDB9tQoSXFvuSUNFibTd9zxd2bkVrDRvF5TmvWWQwqE4lgYJ5m+x1DbecWkw+LK4RNl2CU1hHuOKPVlg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"querystringify": "^2.1.1",
|
||||
"requires-port": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"uuid": {
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/uuid/-/uuid-3.3.2.tgz",
|
||||
"integrity": "sha512-yXJmeNaw3DnnKAOKJE51sL/ZaYfWJRl1pK9dr19YFCu0ObS231AB1/LbqTKRAQ5kw8A90rA6fr4riOUpTZvQZA==",
|
||||
"dev": true
|
||||
},
|
||||
"verror": {
|
||||
"version": "1.10.0",
|
||||
"resolved": "https://registry.npmjs.org/verror/-/verror-1.10.0.tgz",
|
||||
"integrity": "sha1-OhBcoXBTr1XW4nDB+CiGguGNpAA=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"assert-plus": "^1.0.0",
|
||||
"core-util-is": "1.0.2",
|
||||
"extsprintf": "^1.2.0"
|
||||
}
|
||||
},
|
||||
"vscode": {
|
||||
"version": "1.1.35",
|
||||
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.35.tgz",
|
||||
"integrity": "sha512-xPnxzQU40LOS2yPyzWW+WKpTV6qA3z16TcgpZ9O38UWLA157Zz4GxUx5H7Gd07pxzw0GqvusbF4D+5GBgNxvEQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"glob": "^7.1.2",
|
||||
"mocha": "^5.2.0",
|
||||
"request": "^2.88.0",
|
||||
"semver": "^5.4.1",
|
||||
"source-map-support": "^0.5.0",
|
||||
"url-parse": "^1.4.4",
|
||||
"vscode-test": "^0.4.1"
|
||||
}
|
||||
},
|
||||
"vscode-html-languageservice": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-3.0.3.tgz",
|
||||
"integrity": "sha512-U+upM3gHp3HaF3wXAnUduA6IDKcz6frWS/dTAju3cZVIyZwOLBBFElQVlLH0ycHyMzqUFrjvdv+kEyPAEWfQ/g==",
|
||||
"requires": {
|
||||
"vscode-languageserver-types": "^3.15.0-next.2",
|
||||
"vscode-nls": "^4.1.1",
|
||||
"vscode-uri": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.15.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
|
||||
"integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"vscode-jsonrpc": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz",
|
||||
"integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg=="
|
||||
},
|
||||
"vscode-languageclient": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageclient/-/vscode-languageclient-5.2.1.tgz",
|
||||
"integrity": "sha512-7jrS/9WnV0ruqPamN1nE7qCxn0phkH5LjSgSp9h6qoJGoeAKzwKz/PF6M+iGA/aklx4GLZg1prddhEPQtuXI1Q==",
|
||||
"requires": {
|
||||
"semver": "^5.5.0",
|
||||
"vscode-languageserver-protocol": "3.14.1"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-protocol": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz",
|
||||
"integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==",
|
||||
"requires": {
|
||||
"vscode-jsonrpc": "^4.0.0",
|
||||
"vscode-languageserver-types": "3.14.0"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz",
|
||||
"integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A=="
|
||||
},
|
||||
"vscode-nls": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz",
|
||||
"integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw=="
|
||||
},
|
||||
"vscode-test": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/vscode-test/-/vscode-test-0.4.3.tgz",
|
||||
"integrity": "sha512-EkMGqBSefZH2MgW65nY05rdRSko15uvzq4VAPM5jVmwYuFQKE7eikKXNJDRxL+OITXHB6pI+a3XqqD32Y3KC5w==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"http-proxy-agent": "^2.1.0",
|
||||
"https-proxy-agent": "^2.2.1"
|
||||
}
|
||||
},
|
||||
"vscode-uri": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.1.tgz",
|
||||
"integrity": "sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A=="
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
26
lsp-embedded-request-forwarding/client/package.json
Normal file
26
lsp-embedded-request-forwarding/client/package.json
Normal file
@ -0,0 +1,26 @@
|
||||
{
|
||||
"name": "lsp-sample-client",
|
||||
"description": "VSCode part of a language server",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"version": "0.0.1",
|
||||
"publisher": "vscode",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-extension-samples"
|
||||
},
|
||||
"engines": {
|
||||
"vscode": "^1.33.0"
|
||||
},
|
||||
"scripts": {
|
||||
"update-vscode": "vscode-install",
|
||||
"postinstall": "vscode-install"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-html-languageservice": "^3.0.3",
|
||||
"vscode-languageclient": "^5.2.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"vscode": "^1.1.35"
|
||||
}
|
||||
}
|
||||
394
lsp-embedded-request-forwarding/client/src/embeddedSupport.ts
Normal file
394
lsp-embedded-request-forwarding/client/src/embeddedSupport.ts
Normal file
@ -0,0 +1,394 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TextDocument, Position, Range } from 'vscode-languageclient';
|
||||
import { LanguageService, TokenType } from 'vscode-html-languageservice';
|
||||
|
||||
export interface LanguageRange extends Range {
|
||||
languageId: string | undefined;
|
||||
attributeValue?: boolean;
|
||||
}
|
||||
|
||||
export interface HTMLDocumentRegions {
|
||||
getEmbeddedDocument(languageId: string, ignoreAttributeValues?: boolean): TextDocument;
|
||||
getLanguageRanges(range: Range): LanguageRange[];
|
||||
getLanguageAtPosition(position: Position): string | undefined;
|
||||
getLanguagesInDocument(): string[];
|
||||
getImportedScripts(): string[];
|
||||
}
|
||||
|
||||
export const CSS_STYLE_RULE = '__';
|
||||
|
||||
interface EmbeddedRegion {
|
||||
languageId: string | undefined;
|
||||
start: number;
|
||||
end: number;
|
||||
attributeValue?: boolean;
|
||||
}
|
||||
|
||||
export function getCSSVirtualContent(
|
||||
languageService: LanguageService,
|
||||
documentText: string
|
||||
): string {
|
||||
let regions: EmbeddedRegion[] = [];
|
||||
let scanner = languageService.createScanner(documentText);
|
||||
let lastTagName: string = '';
|
||||
let lastAttributeName: string | null = null;
|
||||
let languageIdFromType: string | undefined = undefined;
|
||||
let importedScripts: string[] = [];
|
||||
|
||||
let token = scanner.scan();
|
||||
while (token !== TokenType.EOS) {
|
||||
switch (token) {
|
||||
case TokenType.StartTag:
|
||||
lastTagName = scanner.getTokenText();
|
||||
lastAttributeName = null;
|
||||
languageIdFromType = 'javascript';
|
||||
break;
|
||||
case TokenType.Styles:
|
||||
regions.push({
|
||||
languageId: 'css',
|
||||
start: scanner.getTokenOffset(),
|
||||
end: scanner.getTokenEnd()
|
||||
});
|
||||
break;
|
||||
case TokenType.Script:
|
||||
regions.push({
|
||||
languageId: languageIdFromType,
|
||||
start: scanner.getTokenOffset(),
|
||||
end: scanner.getTokenEnd()
|
||||
});
|
||||
break;
|
||||
case TokenType.AttributeName:
|
||||
lastAttributeName = scanner.getTokenText();
|
||||
break;
|
||||
case TokenType.AttributeValue:
|
||||
if (lastAttributeName === 'src' && lastTagName.toLowerCase() === 'script') {
|
||||
let value = scanner.getTokenText();
|
||||
if (value[0] === "'" || value[0] === '"') {
|
||||
value = value.substr(1, value.length - 1);
|
||||
}
|
||||
importedScripts.push(value);
|
||||
} else if (lastAttributeName === 'type' && lastTagName.toLowerCase() === 'script') {
|
||||
if (
|
||||
/["'](module|(text|application)\/(java|ecma)script|text\/babel)["']/.test(
|
||||
scanner.getTokenText()
|
||||
)
|
||||
) {
|
||||
languageIdFromType = 'javascript';
|
||||
} else if (/["']text\/typescript["']/.test(scanner.getTokenText())) {
|
||||
languageIdFromType = 'typescript';
|
||||
} else {
|
||||
languageIdFromType = undefined;
|
||||
}
|
||||
} else {
|
||||
let attributeLanguageId = getAttributeLanguage(lastAttributeName!);
|
||||
if (attributeLanguageId) {
|
||||
let start = scanner.getTokenOffset();
|
||||
let end = scanner.getTokenEnd();
|
||||
let firstChar = documentText[start];
|
||||
if (firstChar === "'" || firstChar === '"') {
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
regions.push({
|
||||
languageId: attributeLanguageId,
|
||||
start,
|
||||
end,
|
||||
attributeValue: true
|
||||
});
|
||||
}
|
||||
}
|
||||
lastAttributeName = null;
|
||||
break;
|
||||
}
|
||||
token = scanner.scan();
|
||||
}
|
||||
|
||||
let content = documentText
|
||||
.split('\n')
|
||||
.map(line => {
|
||||
return ' '.repeat(line.length);
|
||||
}).join('\n');
|
||||
|
||||
regions.forEach(r => {
|
||||
if (r.languageId === 'css') {
|
||||
content = content.slice(0, r.start) + documentText.slice(r.start, r.end) + content.slice(r.end);
|
||||
}
|
||||
});
|
||||
|
||||
return content;
|
||||
}
|
||||
|
||||
|
||||
export function getDocumentRegions(
|
||||
languageService: LanguageService,
|
||||
document: TextDocument
|
||||
): HTMLDocumentRegions {
|
||||
let regions: EmbeddedRegion[] = [];
|
||||
let scanner = languageService.createScanner(document.getText());
|
||||
let lastTagName: string = '';
|
||||
let lastAttributeName: string | null = null;
|
||||
let languageIdFromType: string | undefined = undefined;
|
||||
let importedScripts: string[] = [];
|
||||
|
||||
let token = scanner.scan();
|
||||
while (token !== TokenType.EOS) {
|
||||
switch (token) {
|
||||
case TokenType.StartTag:
|
||||
lastTagName = scanner.getTokenText();
|
||||
lastAttributeName = null;
|
||||
languageIdFromType = 'javascript';
|
||||
break;
|
||||
case TokenType.Styles:
|
||||
regions.push({
|
||||
languageId: 'css',
|
||||
start: scanner.getTokenOffset(),
|
||||
end: scanner.getTokenEnd()
|
||||
});
|
||||
break;
|
||||
case TokenType.Script:
|
||||
regions.push({
|
||||
languageId: languageIdFromType,
|
||||
start: scanner.getTokenOffset(),
|
||||
end: scanner.getTokenEnd()
|
||||
});
|
||||
break;
|
||||
case TokenType.AttributeName:
|
||||
lastAttributeName = scanner.getTokenText();
|
||||
break;
|
||||
case TokenType.AttributeValue:
|
||||
if (lastAttributeName === 'src' && lastTagName.toLowerCase() === 'script') {
|
||||
let value = scanner.getTokenText();
|
||||
if (value[0] === "'" || value[0] === '"') {
|
||||
value = value.substr(1, value.length - 1);
|
||||
}
|
||||
importedScripts.push(value);
|
||||
} else if (lastAttributeName === 'type' && lastTagName.toLowerCase() === 'script') {
|
||||
if (
|
||||
/["'](module|(text|application)\/(java|ecma)script|text\/babel)["']/.test(
|
||||
scanner.getTokenText()
|
||||
)
|
||||
) {
|
||||
languageIdFromType = 'javascript';
|
||||
} else if (/["']text\/typescript["']/.test(scanner.getTokenText())) {
|
||||
languageIdFromType = 'typescript';
|
||||
} else {
|
||||
languageIdFromType = undefined;
|
||||
}
|
||||
} else {
|
||||
let attributeLanguageId = getAttributeLanguage(lastAttributeName!);
|
||||
if (attributeLanguageId) {
|
||||
let start = scanner.getTokenOffset();
|
||||
let end = scanner.getTokenEnd();
|
||||
let firstChar = document.getText()[start];
|
||||
if (firstChar === "'" || firstChar === '"') {
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
regions.push({
|
||||
languageId: attributeLanguageId,
|
||||
start,
|
||||
end,
|
||||
attributeValue: true
|
||||
});
|
||||
}
|
||||
}
|
||||
lastAttributeName = null;
|
||||
break;
|
||||
}
|
||||
token = scanner.scan();
|
||||
}
|
||||
return {
|
||||
getLanguageRanges: (range: Range) => getLanguageRanges(document, regions, range),
|
||||
getEmbeddedDocument: (languageId: string, ignoreAttributeValues: boolean) =>
|
||||
getEmbeddedDocument(document, regions, languageId, ignoreAttributeValues),
|
||||
getLanguageAtPosition: (position: Position) =>
|
||||
getLanguageAtPosition(document, regions, position),
|
||||
getLanguagesInDocument: () => getLanguagesInDocument(document, regions),
|
||||
getImportedScripts: () => importedScripts
|
||||
};
|
||||
}
|
||||
|
||||
function getLanguageRanges(
|
||||
document: TextDocument,
|
||||
regions: EmbeddedRegion[],
|
||||
range: Range
|
||||
): LanguageRange[] {
|
||||
let result: LanguageRange[] = [];
|
||||
let currentPos = range ? range.start : Position.create(0, 0);
|
||||
let currentOffset = range ? document.offsetAt(range.start) : 0;
|
||||
let endOffset = range ? document.offsetAt(range.end) : document.getText().length;
|
||||
for (let region of regions) {
|
||||
if (region.end > currentOffset && region.start < endOffset) {
|
||||
let start = Math.max(region.start, currentOffset);
|
||||
let startPos = document.positionAt(start);
|
||||
if (currentOffset < region.start) {
|
||||
result.push({
|
||||
start: currentPos,
|
||||
end: startPos,
|
||||
languageId: 'html'
|
||||
});
|
||||
}
|
||||
let end = Math.min(region.end, endOffset);
|
||||
let endPos = document.positionAt(end);
|
||||
if (end > region.start) {
|
||||
result.push({
|
||||
start: startPos,
|
||||
end: endPos,
|
||||
languageId: region.languageId,
|
||||
attributeValue: region.attributeValue
|
||||
});
|
||||
}
|
||||
currentOffset = end;
|
||||
currentPos = endPos;
|
||||
}
|
||||
}
|
||||
if (currentOffset < endOffset) {
|
||||
let endPos = range ? range.end : document.positionAt(endOffset);
|
||||
result.push({
|
||||
start: currentPos,
|
||||
end: endPos,
|
||||
languageId: 'html'
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getLanguagesInDocument(
|
||||
_document: TextDocument,
|
||||
regions: EmbeddedRegion[]
|
||||
): string[] {
|
||||
let result = [];
|
||||
for (let region of regions) {
|
||||
if (region.languageId && result.indexOf(region.languageId) === -1) {
|
||||
result.push(region.languageId);
|
||||
if (result.length === 3) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.push('html');
|
||||
return result;
|
||||
}
|
||||
|
||||
function getLanguageAtPosition(
|
||||
document: TextDocument,
|
||||
regions: EmbeddedRegion[],
|
||||
position: Position
|
||||
): string | undefined {
|
||||
let offset = document.offsetAt(position);
|
||||
for (let region of regions) {
|
||||
if (region.start <= offset) {
|
||||
if (offset <= region.end) {
|
||||
return region.languageId;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 'html';
|
||||
}
|
||||
|
||||
function getEmbeddedDocument(
|
||||
document: TextDocument,
|
||||
contents: EmbeddedRegion[],
|
||||
languageId: string,
|
||||
ignoreAttributeValues: boolean
|
||||
): TextDocument {
|
||||
let currentPos = 0;
|
||||
let oldContent = document.getText();
|
||||
let result = '';
|
||||
let lastSuffix = '';
|
||||
for (let c of contents) {
|
||||
if (c.languageId === languageId && (!ignoreAttributeValues || !c.attributeValue)) {
|
||||
result = substituteWithWhitespace(
|
||||
result,
|
||||
currentPos,
|
||||
c.start,
|
||||
oldContent,
|
||||
lastSuffix,
|
||||
getPrefix(c)
|
||||
);
|
||||
result += oldContent.substring(c.start, c.end);
|
||||
currentPos = c.end;
|
||||
lastSuffix = getSuffix(c);
|
||||
}
|
||||
}
|
||||
result = substituteWithWhitespace(
|
||||
result,
|
||||
currentPos,
|
||||
oldContent.length,
|
||||
oldContent,
|
||||
lastSuffix,
|
||||
''
|
||||
);
|
||||
return TextDocument.create(document.uri, languageId, document.version, result);
|
||||
}
|
||||
|
||||
function getPrefix(c: EmbeddedRegion) {
|
||||
if (c.attributeValue) {
|
||||
switch (c.languageId) {
|
||||
case 'css':
|
||||
return CSS_STYLE_RULE + '{';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
function getSuffix(c: EmbeddedRegion) {
|
||||
if (c.attributeValue) {
|
||||
switch (c.languageId) {
|
||||
case 'css':
|
||||
return '}';
|
||||
case 'javascript':
|
||||
return ';';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function substituteWithWhitespace(
|
||||
result: string,
|
||||
start: number,
|
||||
end: number,
|
||||
oldContent: string,
|
||||
before: string,
|
||||
after: string
|
||||
) {
|
||||
let accumulatedWS = 0;
|
||||
result += before;
|
||||
for (let i = start + before.length; i < end; i++) {
|
||||
let ch = oldContent[i];
|
||||
if (ch === '\n' || ch === '\r') {
|
||||
// only write new lines, skip the whitespace
|
||||
accumulatedWS = 0;
|
||||
result += ch;
|
||||
} else {
|
||||
accumulatedWS++;
|
||||
}
|
||||
}
|
||||
result = append(result, ' ', accumulatedWS - after.length);
|
||||
result += after;
|
||||
return result;
|
||||
}
|
||||
|
||||
function append(result: string, str: string, n: number): string {
|
||||
while (n > 0) {
|
||||
if (n & 1) {
|
||||
result += str;
|
||||
}
|
||||
n >>= 1;
|
||||
str += str;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getAttributeLanguage(attributeName: string): string | null {
|
||||
let match = attributeName.match(/^(style)$|^(on\w+)$/i);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
return match[1] ? 'css' : 'javascript';
|
||||
}
|
||||
81
lsp-embedded-request-forwarding/client/src/extension.ts
Normal file
81
lsp-embedded-request-forwarding/client/src/extension.ts
Normal file
@ -0,0 +1,81 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import * as path from 'path';
|
||||
import { commands, CompletionList, ExtensionContext, Uri, workspace } from 'vscode';
|
||||
import { getLanguageService } from 'vscode-html-languageservice';
|
||||
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient';
|
||||
import { getCSSVirtualContent } from './embeddedSupport';
|
||||
|
||||
let client: LanguageClient;
|
||||
|
||||
const htmlLanguageService = getLanguageService();
|
||||
|
||||
export function activate(context: ExtensionContext) {
|
||||
// The server is implemented in node
|
||||
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'server.js'));
|
||||
// The debug options for the server
|
||||
// --inspect=6009: runs the server in Node's Inspector mode so VS Code can attach to the server for debugging
|
||||
let debugOptions = { execArgv: ['--nolazy', '--inspect=6009'] };
|
||||
|
||||
// If the extension is launched in debug mode then the debug server options are used
|
||||
// Otherwise the run options are used
|
||||
let serverOptions: ServerOptions = {
|
||||
run: { module: serverModule, transport: TransportKind.ipc },
|
||||
debug: {
|
||||
module: serverModule,
|
||||
transport: TransportKind.ipc,
|
||||
options: debugOptions
|
||||
}
|
||||
};
|
||||
|
||||
const virtualDocumentContents = new Map<string, string>();
|
||||
|
||||
workspace.registerTextDocumentContentProvider('embedded-content', {
|
||||
provideTextDocumentContent: uri => {
|
||||
const originalUri = uri.fsPath.slice(1).slice(0, -4);
|
||||
return virtualDocumentContents.get(originalUri);
|
||||
}
|
||||
});
|
||||
|
||||
let clientOptions: LanguageClientOptions = {
|
||||
documentSelector: [{ scheme: 'file', language: 'html' }],
|
||||
middleware: {
|
||||
provideCompletionItem: async (document, position, context, token, next) => {
|
||||
const originalUri = document.uri.toString();
|
||||
virtualDocumentContents.set(originalUri, getCSSVirtualContent(htmlLanguageService, document.getText()));
|
||||
|
||||
const vdocUriString = `embedded-content://css/${encodeURIComponent(
|
||||
originalUri
|
||||
)}.css`;
|
||||
const vdocUri = Uri.parse(vdocUriString);
|
||||
return await commands.executeCommand<CompletionList>(
|
||||
'vscode.executeCompletionItemProvider',
|
||||
vdocUri,
|
||||
position,
|
||||
context.triggerCharacter
|
||||
);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Create the language client and start the client.
|
||||
client = new LanguageClient(
|
||||
'languageServerExample',
|
||||
'Language Server Example',
|
||||
serverOptions,
|
||||
clientOptions
|
||||
);
|
||||
|
||||
// Start the client. This will also launch the server
|
||||
client.start();
|
||||
}
|
||||
|
||||
export function deactivate(): Thenable<void> | undefined {
|
||||
if (!client) {
|
||||
return undefined;
|
||||
}
|
||||
return client.stop();
|
||||
}
|
||||
11
lsp-embedded-request-forwarding/client/tsconfig.json
Normal file
11
lsp-embedded-request-forwarding/client/tsconfig.json
Normal file
@ -0,0 +1,11 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"outDir": "out",
|
||||
"rootDir": "src",
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", ".vscode-test"]
|
||||
}
|
||||
323
lsp-embedded-request-forwarding/package-lock.json
generated
Normal file
323
lsp-embedded-request-forwarding/package-lock.json
generated
Normal file
@ -0,0 +1,323 @@
|
||||
{
|
||||
"name": "lsp-embedded-language-service-sample",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"@babel/code-frame": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/code-frame/-/code-frame-7.0.0.tgz",
|
||||
"integrity": "sha512-OfC2uemaknXr87bdLUkWog7nYuliM9Ij5HUcajsVcMCpQrcLmtxRbVFTIqmcSkSeYRBFBRxs2FiUqFJDLdiebA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/highlight": "^7.0.0"
|
||||
}
|
||||
},
|
||||
"@babel/highlight": {
|
||||
"version": "7.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@babel/highlight/-/highlight-7.0.0.tgz",
|
||||
"integrity": "sha512-UFMC4ZeFC48Tpvj7C8UgLvtkaUuovQX+5xNWrsIoMG8o2z+XFKjKaN9iVmS84dPwVN00W4wPmqvYoZF3EGAsfw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"chalk": "^2.0.0",
|
||||
"esutils": "^2.0.2",
|
||||
"js-tokens": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"@types/mocha": {
|
||||
"version": "5.2.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-5.2.7.tgz",
|
||||
"integrity": "sha512-NYrtPht0wGzhwe9+/idPaBB+TqkY9AhTvOLMkThm0IoEfLaiVQZwBwyJ5puCkO3AUCWrmcoePjp2mbFocKy4SQ==",
|
||||
"dev": true
|
||||
},
|
||||
"@types/node": {
|
||||
"version": "12.11.7",
|
||||
"resolved": "https://registry.npmjs.org/@types/node/-/node-12.11.7.tgz",
|
||||
"integrity": "sha512-JNbGaHFCLwgHn/iCckiGSOZ1XYHsKFwREtzPwSGCVld1SGhOlmZw2D4ZI94HQCrBHbADzW9m4LER/8olJTRGHA==",
|
||||
"dev": true
|
||||
},
|
||||
"ansi-styles": {
|
||||
"version": "3.2.1",
|
||||
"resolved": "https://registry.npmjs.org/ansi-styles/-/ansi-styles-3.2.1.tgz",
|
||||
"integrity": "sha512-VT0ZI6kZRdTh8YyJw3SMbYm/u+NqfsAxEpWO0Pf9sq8/e94WxxOpPKx9FR1FlyCtOVDNOQ+8ntlqFxiRc+r5qA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-convert": "^1.9.0"
|
||||
}
|
||||
},
|
||||
"argparse": {
|
||||
"version": "1.0.10",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-1.0.10.tgz",
|
||||
"integrity": "sha512-o5Roy6tNG4SL/FOkCAN6RzjiakZS25RLYFrcMttJqbdd8BWrnA+fGz57iN5Pb06pvBGvl5gQ0B48dJlslXvoTg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"sprintf-js": "~1.0.2"
|
||||
}
|
||||
},
|
||||
"balanced-match": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.0.tgz",
|
||||
"integrity": "sha1-ibTRmasr7kneFk6gK4nORi1xt2c=",
|
||||
"dev": true
|
||||
},
|
||||
"brace-expansion": {
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
}
|
||||
},
|
||||
"builtin-modules": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-1.1.1.tgz",
|
||||
"integrity": "sha1-Jw8HbFpywC9bZaR9+Uxf46J4iS8=",
|
||||
"dev": true
|
||||
},
|
||||
"chalk": {
|
||||
"version": "2.4.2",
|
||||
"resolved": "https://registry.npmjs.org/chalk/-/chalk-2.4.2.tgz",
|
||||
"integrity": "sha512-Mti+f9lpJNcwF4tWV8/OrTTtF1gZi+f8FqlyAdouralcFWFQWF2+NgCHShjkCb+IFBLq9buZwE1xckQU4peSuQ==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"ansi-styles": "^3.2.1",
|
||||
"escape-string-regexp": "^1.0.5",
|
||||
"supports-color": "^5.3.0"
|
||||
}
|
||||
},
|
||||
"color-convert": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/color-convert/-/color-convert-1.9.3.tgz",
|
||||
"integrity": "sha512-QfAUtd+vFdAtFQcC8CCyYt1fYWxSqAiK2cSD6zDB8N3cpsEBAvRxp9zOGg6G/SHHJYAT88/az/IuDGALsNVbGg==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"color-name": "1.1.3"
|
||||
}
|
||||
},
|
||||
"color-name": {
|
||||
"version": "1.1.3",
|
||||
"resolved": "https://registry.npmjs.org/color-name/-/color-name-1.1.3.tgz",
|
||||
"integrity": "sha1-p9BVi9icQveV3UIyj3QIMcpTvCU=",
|
||||
"dev": true
|
||||
},
|
||||
"commander": {
|
||||
"version": "2.20.0",
|
||||
"resolved": "https://registry.npmjs.org/commander/-/commander-2.20.0.tgz",
|
||||
"integrity": "sha512-7j2y+40w61zy6YC2iRNpUe/NwhNyoXrYpHMrSunaMG64nRnaf96zO/KMQR4OyN/UnE5KLyEBnKHd4aG3rskjpQ==",
|
||||
"dev": true
|
||||
},
|
||||
"concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=",
|
||||
"dev": true
|
||||
},
|
||||
"diff": {
|
||||
"version": "3.5.0",
|
||||
"resolved": "https://registry.npmjs.org/diff/-/diff-3.5.0.tgz",
|
||||
"integrity": "sha512-A46qtFgd+g7pDZinpnwiRJtxbC1hpgf0uzP3iG89scHk0AUC7A1TGxf5OiiOUv/JMZR8GOt8hL900hV0bOy5xA==",
|
||||
"dev": true
|
||||
},
|
||||
"escape-string-regexp": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz",
|
||||
"integrity": "sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=",
|
||||
"dev": true
|
||||
},
|
||||
"esprima": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/esprima/-/esprima-4.0.1.tgz",
|
||||
"integrity": "sha512-eGuFFw7Upda+g4p+QHvnW0RyTX/SVeJBDM/gCtMARO0cLuT2HcEKnTPvhjV6aGeqrCB/sbNop0Kszm0jsaWU4A==",
|
||||
"dev": true
|
||||
},
|
||||
"esutils": {
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/esutils/-/esutils-2.0.2.tgz",
|
||||
"integrity": "sha1-Cr9PHKpbyx96nYrMbepPqqBLrJs=",
|
||||
"dev": true
|
||||
},
|
||||
"fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha1-FQStJSMVjKpA20onh8sBQRmU6k8=",
|
||||
"dev": true
|
||||
},
|
||||
"glob": {
|
||||
"version": "7.1.4",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.1.4.tgz",
|
||||
"integrity": "sha512-hkLPepehmnKk41pUGm3sYxoFs/umurYfYJCerbXEyFIWcAzvpipAgVkBqqT9RBKMGjnq6kMuyYwha6csxbiM1A==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.0.4",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
}
|
||||
},
|
||||
"has-flag": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/has-flag/-/has-flag-3.0.0.tgz",
|
||||
"integrity": "sha1-tdRU3CGZriJWmfNGfloH87lVuv0=",
|
||||
"dev": true
|
||||
},
|
||||
"inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"inherits": {
|
||||
"version": "2.0.3",
|
||||
"resolved": "https://registry.npmjs.org/inherits/-/inherits-2.0.3.tgz",
|
||||
"integrity": "sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=",
|
||||
"dev": true
|
||||
},
|
||||
"js-tokens": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/js-tokens/-/js-tokens-4.0.0.tgz",
|
||||
"integrity": "sha512-RdJUflcE3cUzKiMqQgsCu06FPu9UdIJO0beYbPhHN4k6apgJtifcoCtT9bcxOpYBtpD2kCM6Sbzg4CausW/PKQ==",
|
||||
"dev": true
|
||||
},
|
||||
"js-yaml": {
|
||||
"version": "3.13.1",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-3.13.1.tgz",
|
||||
"integrity": "sha512-YfbcO7jXDdyj0DGxYVSlSeQNHbD7XPWvrVWeVUujrQEoZzWJIRrCPoyk6kL6IAjAG2IolMK4T0hNUe0HOUs5Jw==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"argparse": "^1.0.7",
|
||||
"esprima": "^4.0.0"
|
||||
}
|
||||
},
|
||||
"minimatch": {
|
||||
"version": "3.0.4",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.0.4.tgz",
|
||||
"integrity": "sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
}
|
||||
},
|
||||
"minimist": {
|
||||
"version": "0.0.8",
|
||||
"resolved": "https://registry.npmjs.org/minimist/-/minimist-0.0.8.tgz",
|
||||
"integrity": "sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=",
|
||||
"dev": true
|
||||
},
|
||||
"mkdirp": {
|
||||
"version": "0.5.1",
|
||||
"resolved": "https://registry.npmjs.org/mkdirp/-/mkdirp-0.5.1.tgz",
|
||||
"integrity": "sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"minimist": "0.0.8"
|
||||
}
|
||||
},
|
||||
"once": {
|
||||
"version": "1.4.0",
|
||||
"resolved": "https://registry.npmjs.org/once/-/once-1.4.0.tgz",
|
||||
"integrity": "sha1-WDsap3WWHUsROsF9nFC6753Xa9E=",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"wrappy": "1"
|
||||
}
|
||||
},
|
||||
"path-is-absolute": {
|
||||
"version": "1.0.1",
|
||||
"resolved": "http://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha1-F0uSaHNVNP+8es5r9TpanhtcX18=",
|
||||
"dev": true
|
||||
},
|
||||
"path-parse": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/path-parse/-/path-parse-1.0.6.tgz",
|
||||
"integrity": "sha512-GSmOT2EbHrINBf9SR7CDELwlJ8AENk3Qn7OikK4nFYAu3Ote2+JYNVvkpAEQm3/TLNEJFD/xZJjzyxg3KBWOzw==",
|
||||
"dev": true
|
||||
},
|
||||
"resolve": {
|
||||
"version": "1.10.1",
|
||||
"resolved": "https://registry.npmjs.org/resolve/-/resolve-1.10.1.tgz",
|
||||
"integrity": "sha512-KuIe4mf++td/eFb6wkaPbMDnP6kObCaEtIDuHOUED6MNUo4K670KZUHuuvYPZDxNF0WVLw49n06M2m2dXphEzA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"path-parse": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"semver": {
|
||||
"version": "5.7.0",
|
||||
"resolved": "https://registry.npmjs.org/semver/-/semver-5.7.0.tgz",
|
||||
"integrity": "sha512-Ya52jSX2u7QKghxeoFGpLwCtGlt7j0oY9DYb5apt9nPlJ42ID+ulTXESnt/qAQcoSERyZ5sl3LDIOw0nAn/5DA==",
|
||||
"dev": true
|
||||
},
|
||||
"sprintf-js": {
|
||||
"version": "1.0.3",
|
||||
"resolved": "https://registry.npmjs.org/sprintf-js/-/sprintf-js-1.0.3.tgz",
|
||||
"integrity": "sha1-BOaSb2YolTVPPdAVIDYzuFcpfiw=",
|
||||
"dev": true
|
||||
},
|
||||
"supports-color": {
|
||||
"version": "5.5.0",
|
||||
"resolved": "https://registry.npmjs.org/supports-color/-/supports-color-5.5.0.tgz",
|
||||
"integrity": "sha512-QjVjwdXIt408MIiAqCX4oUKsgU2EqAGzs2Ppkm4aQYbjm+ZEWEcW4SfFNTr4uMNZma0ey4f5lgLrkB0aX0QMow==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"has-flag": "^3.0.0"
|
||||
}
|
||||
},
|
||||
"tslib": {
|
||||
"version": "1.9.3",
|
||||
"resolved": "https://registry.npmjs.org/tslib/-/tslib-1.9.3.tgz",
|
||||
"integrity": "sha512-4krF8scpejhaOgqzBEcGM7yDIEfi0/8+8zDRZhNZZ2kjmHJ4hv3zCbQWxoJGz1iw5U0Jl0nma13xzHXcncMavQ==",
|
||||
"dev": true
|
||||
},
|
||||
"tslint": {
|
||||
"version": "5.16.0",
|
||||
"resolved": "https://registry.npmjs.org/tslint/-/tslint-5.16.0.tgz",
|
||||
"integrity": "sha512-UxG2yNxJ5pgGwmMzPMYh/CCnCnh0HfPgtlVRDs1ykZklufFBL1ZoTlWFRz2NQjcoEiDoRp+JyT0lhBbbH/obyA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"@babel/code-frame": "^7.0.0",
|
||||
"builtin-modules": "^1.1.1",
|
||||
"chalk": "^2.3.0",
|
||||
"commander": "^2.12.1",
|
||||
"diff": "^3.2.0",
|
||||
"glob": "^7.1.1",
|
||||
"js-yaml": "^3.13.0",
|
||||
"minimatch": "^3.0.4",
|
||||
"mkdirp": "^0.5.1",
|
||||
"resolve": "^1.3.2",
|
||||
"semver": "^5.3.0",
|
||||
"tslib": "^1.8.0",
|
||||
"tsutils": "^2.29.0"
|
||||
}
|
||||
},
|
||||
"tsutils": {
|
||||
"version": "2.29.0",
|
||||
"resolved": "https://registry.npmjs.org/tsutils/-/tsutils-2.29.0.tgz",
|
||||
"integrity": "sha512-g5JVHCIJwzfISaXpXE1qvNalca5Jwob6FjI4AoPlqMusJ6ftFE7IkkFoMhVLRgK+4Kx3gkzb8UZK5t5yTTvEmA==",
|
||||
"dev": true,
|
||||
"requires": {
|
||||
"tslib": "^1.8.1"
|
||||
}
|
||||
},
|
||||
"typescript": {
|
||||
"version": "3.6.4",
|
||||
"resolved": "https://registry.npmjs.org/typescript/-/typescript-3.6.4.tgz",
|
||||
"integrity": "sha512-unoCll1+l+YK4i4F8f22TaNVPRHcD9PA3yCuZ8g5e0qGqlVlJ/8FSateOLLSagn+Yg5+ZwuPkL8LFUc0Jcvksg==",
|
||||
"dev": true
|
||||
},
|
||||
"wrappy": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/wrappy/-/wrappy-1.0.2.tgz",
|
||||
"integrity": "sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=",
|
||||
"dev": true
|
||||
}
|
||||
}
|
||||
}
|
||||
35
lsp-embedded-request-forwarding/package.json
Normal file
35
lsp-embedded-request-forwarding/package.json
Normal file
@ -0,0 +1,35 @@
|
||||
{
|
||||
"name": "lsp-embedded-language-service-sample",
|
||||
"description": "A language server example using language services to support embedded languages",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"version": "1.0.0",
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-extension-samples"
|
||||
},
|
||||
"publisher": "vscode-samples",
|
||||
"categories": [],
|
||||
"keywords": [],
|
||||
"engines": {
|
||||
"vscode": "^1.33.0"
|
||||
},
|
||||
"activationEvents": [
|
||||
"onLanguage:html"
|
||||
],
|
||||
"main": "./client/out/extension",
|
||||
"contributes": {},
|
||||
"scripts": {
|
||||
"vscode:prepublish": "cd client && npm run update-vscode && cd .. && npm run compile",
|
||||
"compile": "tsc -b",
|
||||
"watch": "tsc -b -w",
|
||||
"postinstall": "cd client && npm install && cd ../server && npm install && cd ..",
|
||||
"test": "sh ./scripts/e2e.sh"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/mocha": "^5.2.7",
|
||||
"@types/node": "^12.11.7",
|
||||
"tslint": "^5.16.0",
|
||||
"typescript": "^3.6.4"
|
||||
}
|
||||
}
|
||||
68
lsp-embedded-request-forwarding/server/package-lock.json
generated
Normal file
68
lsp-embedded-request-forwarding/server/package-lock.json
generated
Normal file
@ -0,0 +1,68 @@
|
||||
{
|
||||
"name": "lsp-sample-server",
|
||||
"version": "1.0.0",
|
||||
"lockfileVersion": 1,
|
||||
"requires": true,
|
||||
"dependencies": {
|
||||
"vscode-html-languageservice": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/vscode-html-languageservice/-/vscode-html-languageservice-3.0.3.tgz",
|
||||
"integrity": "sha512-U+upM3gHp3HaF3wXAnUduA6IDKcz6frWS/dTAju3cZVIyZwOLBBFElQVlLH0ycHyMzqUFrjvdv+kEyPAEWfQ/g==",
|
||||
"requires": {
|
||||
"vscode-languageserver-types": "^3.15.0-next.2",
|
||||
"vscode-nls": "^4.1.1",
|
||||
"vscode-uri": "^2.0.3"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.15.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.15.1.tgz",
|
||||
"integrity": "sha512-+a9MPUQrNGRrGU630OGbYVQ+11iOIovjCkqxajPa9w57Sd5ruK8WQNsslzpa0x/QJqC8kRc2DUxWjIFwoNm4ZQ=="
|
||||
},
|
||||
"vscode-uri": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-2.1.1.tgz",
|
||||
"integrity": "sha512-eY9jmGoEnVf8VE8xr5znSah7Qt1P/xsCdErz+g8HYZtJ7bZqKH5E3d+6oVNm1AC/c6IHUDokbmVXKOi4qPAC9A=="
|
||||
}
|
||||
}
|
||||
},
|
||||
"vscode-jsonrpc": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-jsonrpc/-/vscode-jsonrpc-4.0.0.tgz",
|
||||
"integrity": "sha512-perEnXQdQOJMTDFNv+UF3h1Y0z4iSiaN9jIlb0OqIYgosPCZGYh/MCUlkFtV2668PL69lRDO32hmvL2yiidUYg=="
|
||||
},
|
||||
"vscode-languageserver": {
|
||||
"version": "5.2.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver/-/vscode-languageserver-5.2.1.tgz",
|
||||
"integrity": "sha512-GuayqdKZqAwwaCUjDvMTAVRPJOp/SLON3mJ07eGsx/Iq9HjRymhKWztX41rISqDKhHVVyFM+IywICyZDla6U3A==",
|
||||
"requires": {
|
||||
"vscode-languageserver-protocol": "3.14.1",
|
||||
"vscode-uri": "^1.0.6"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-protocol": {
|
||||
"version": "3.14.1",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.14.1.tgz",
|
||||
"integrity": "sha512-IL66BLb2g20uIKog5Y2dQ0IiigW0XKrvmWiOvc0yXw80z3tMEzEnHjaGAb3ENuU7MnQqgnYJ1Cl2l9RvNgDi4g==",
|
||||
"requires": {
|
||||
"vscode-jsonrpc": "^4.0.0",
|
||||
"vscode-languageserver-types": "3.14.0"
|
||||
}
|
||||
},
|
||||
"vscode-languageserver-types": {
|
||||
"version": "3.14.0",
|
||||
"resolved": "https://registry.npmjs.org/vscode-languageserver-types/-/vscode-languageserver-types-3.14.0.tgz",
|
||||
"integrity": "sha512-lTmS6AlAlMHOvPQemVwo3CezxBp0sNB95KNPkqp3Nxd5VFEnuG1ByM0zlRWos0zjO3ZWtkvhal0COgiV1xIA4A=="
|
||||
},
|
||||
"vscode-nls": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/vscode-nls/-/vscode-nls-4.1.2.tgz",
|
||||
"integrity": "sha512-7bOHxPsfyuCqmP+hZXscLhiHwe7CSuFE4hyhbs22xPIhQ4jv99FcR4eBzfYYVLP356HNFpdvz63FFb/xw6T4Iw=="
|
||||
},
|
||||
"vscode-uri": {
|
||||
"version": "1.0.8",
|
||||
"resolved": "https://registry.npmjs.org/vscode-uri/-/vscode-uri-1.0.8.tgz",
|
||||
"integrity": "sha512-obtSWTlbJ+a+TFRYGaUumtVwb+InIUVI0Lu0VBUAPmj2cU5JutEXg3xUE0c2J5Tcy7h2DEKVJBFi+Y9ZSFzzPQ=="
|
||||
}
|
||||
}
|
||||
}
|
||||
19
lsp-embedded-request-forwarding/server/package.json
Normal file
19
lsp-embedded-request-forwarding/server/package.json
Normal file
@ -0,0 +1,19 @@
|
||||
{
|
||||
"name": "lsp-sample-server",
|
||||
"description": "Example implementation of a language server in node.",
|
||||
"version": "1.0.0",
|
||||
"author": "Microsoft Corporation",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"repository": {
|
||||
"type": "git",
|
||||
"url": "https://github.com/Microsoft/vscode-extension-samples"
|
||||
},
|
||||
"dependencies": {
|
||||
"vscode-html-languageservice": "^3.0.3",
|
||||
"vscode-languageserver": "^5.2.1"
|
||||
},
|
||||
"scripts": {}
|
||||
}
|
||||
233
lsp-embedded-request-forwarding/server/src/embeddedSupport.ts
Normal file
233
lsp-embedded-request-forwarding/server/src/embeddedSupport.ts
Normal file
@ -0,0 +1,233 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TextDocument, Position, LanguageService, TokenType, Range } from './languageModes';
|
||||
|
||||
export interface LanguageRange extends Range {
|
||||
languageId: string | undefined;
|
||||
attributeValue?: boolean;
|
||||
}
|
||||
|
||||
export interface HTMLDocumentRegions {
|
||||
getEmbeddedDocument(languageId: string, ignoreAttributeValues?: boolean): TextDocument;
|
||||
getLanguageRanges(range: Range): LanguageRange[];
|
||||
getLanguageAtPosition(position: Position): string | undefined;
|
||||
getLanguagesInDocument(): string[];
|
||||
getImportedScripts(): string[];
|
||||
}
|
||||
|
||||
export const CSS_STYLE_RULE = '__';
|
||||
|
||||
interface EmbeddedRegion { languageId: string | undefined; start: number; end: number; attributeValue?: boolean; }
|
||||
|
||||
|
||||
export function getDocumentRegions(languageService: LanguageService, document: TextDocument): HTMLDocumentRegions {
|
||||
let regions: EmbeddedRegion[] = [];
|
||||
let scanner = languageService.createScanner(document.getText());
|
||||
let lastTagName: string = '';
|
||||
let lastAttributeName: string | null = null;
|
||||
let languageIdFromType: string | undefined = undefined;
|
||||
let importedScripts: string[] = [];
|
||||
|
||||
let token = scanner.scan();
|
||||
while (token !== TokenType.EOS) {
|
||||
switch (token) {
|
||||
case TokenType.StartTag:
|
||||
lastTagName = scanner.getTokenText();
|
||||
lastAttributeName = null;
|
||||
languageIdFromType = 'javascript';
|
||||
break;
|
||||
case TokenType.Styles:
|
||||
regions.push({ languageId: 'css', start: scanner.getTokenOffset(), end: scanner.getTokenEnd() });
|
||||
break;
|
||||
case TokenType.Script:
|
||||
regions.push({ languageId: languageIdFromType, start: scanner.getTokenOffset(), end: scanner.getTokenEnd() });
|
||||
break;
|
||||
case TokenType.AttributeName:
|
||||
lastAttributeName = scanner.getTokenText();
|
||||
break;
|
||||
case TokenType.AttributeValue:
|
||||
if (lastAttributeName === 'src' && lastTagName.toLowerCase() === 'script') {
|
||||
let value = scanner.getTokenText();
|
||||
if (value[0] === '\'' || value[0] === '"') {
|
||||
value = value.substr(1, value.length - 1);
|
||||
}
|
||||
importedScripts.push(value);
|
||||
} else if (lastAttributeName === 'type' && lastTagName.toLowerCase() === 'script') {
|
||||
if (/["'](module|(text|application)\/(java|ecma)script|text\/babel)["']/.test(scanner.getTokenText())) {
|
||||
languageIdFromType = 'javascript';
|
||||
} else if (/["']text\/typescript["']/.test(scanner.getTokenText())) {
|
||||
languageIdFromType = 'typescript';
|
||||
} else {
|
||||
languageIdFromType = undefined;
|
||||
}
|
||||
} else {
|
||||
let attributeLanguageId = getAttributeLanguage(lastAttributeName!);
|
||||
if (attributeLanguageId) {
|
||||
let start = scanner.getTokenOffset();
|
||||
let end = scanner.getTokenEnd();
|
||||
let firstChar = document.getText()[start];
|
||||
if (firstChar === '\'' || firstChar === '"') {
|
||||
start++;
|
||||
end--;
|
||||
}
|
||||
regions.push({ languageId: attributeLanguageId, start, end, attributeValue: true });
|
||||
}
|
||||
}
|
||||
lastAttributeName = null;
|
||||
break;
|
||||
}
|
||||
token = scanner.scan();
|
||||
}
|
||||
return {
|
||||
getLanguageRanges: (range: Range) => getLanguageRanges(document, regions, range),
|
||||
getEmbeddedDocument: (languageId: string, ignoreAttributeValues: boolean) => getEmbeddedDocument(document, regions, languageId, ignoreAttributeValues),
|
||||
getLanguageAtPosition: (position: Position) => getLanguageAtPosition(document, regions, position),
|
||||
getLanguagesInDocument: () => getLanguagesInDocument(document, regions),
|
||||
getImportedScripts: () => importedScripts
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
function getLanguageRanges(document: TextDocument, regions: EmbeddedRegion[], range: Range): LanguageRange[] {
|
||||
let result: LanguageRange[] = [];
|
||||
let currentPos = range ? range.start : Position.create(0, 0);
|
||||
let currentOffset = range ? document.offsetAt(range.start) : 0;
|
||||
let endOffset = range ? document.offsetAt(range.end) : document.getText().length;
|
||||
for (let region of regions) {
|
||||
if (region.end > currentOffset && region.start < endOffset) {
|
||||
let start = Math.max(region.start, currentOffset);
|
||||
let startPos = document.positionAt(start);
|
||||
if (currentOffset < region.start) {
|
||||
result.push({
|
||||
start: currentPos,
|
||||
end: startPos,
|
||||
languageId: 'html'
|
||||
});
|
||||
}
|
||||
let end = Math.min(region.end, endOffset);
|
||||
let endPos = document.positionAt(end);
|
||||
if (end > region.start) {
|
||||
result.push({
|
||||
start: startPos,
|
||||
end: endPos,
|
||||
languageId: region.languageId,
|
||||
attributeValue: region.attributeValue
|
||||
});
|
||||
}
|
||||
currentOffset = end;
|
||||
currentPos = endPos;
|
||||
}
|
||||
}
|
||||
if (currentOffset < endOffset) {
|
||||
let endPos = range ? range.end : document.positionAt(endOffset);
|
||||
result.push({
|
||||
start: currentPos,
|
||||
end: endPos,
|
||||
languageId: 'html'
|
||||
});
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getLanguagesInDocument(_document: TextDocument, regions: EmbeddedRegion[]): string[] {
|
||||
let result = [];
|
||||
for (let region of regions) {
|
||||
if (region.languageId && result.indexOf(region.languageId) === -1) {
|
||||
result.push(region.languageId);
|
||||
if (result.length === 3) {
|
||||
return result;
|
||||
}
|
||||
}
|
||||
}
|
||||
result.push('html');
|
||||
return result;
|
||||
}
|
||||
|
||||
function getLanguageAtPosition(document: TextDocument, regions: EmbeddedRegion[], position: Position): string | undefined {
|
||||
let offset = document.offsetAt(position);
|
||||
for (let region of regions) {
|
||||
if (region.start <= offset) {
|
||||
if (offset <= region.end) {
|
||||
return region.languageId;
|
||||
}
|
||||
} else {
|
||||
break;
|
||||
}
|
||||
}
|
||||
return 'html';
|
||||
}
|
||||
|
||||
function getEmbeddedDocument(document: TextDocument, contents: EmbeddedRegion[], languageId: string, ignoreAttributeValues: boolean): TextDocument {
|
||||
let currentPos = 0;
|
||||
let oldContent = document.getText();
|
||||
let result = '';
|
||||
let lastSuffix = '';
|
||||
for (let c of contents) {
|
||||
if (c.languageId === languageId && (!ignoreAttributeValues || !c.attributeValue)) {
|
||||
result = substituteWithWhitespace(result, currentPos, c.start, oldContent, lastSuffix, getPrefix(c));
|
||||
result += oldContent.substring(c.start, c.end);
|
||||
currentPos = c.end;
|
||||
lastSuffix = getSuffix(c);
|
||||
}
|
||||
}
|
||||
result = substituteWithWhitespace(result, currentPos, oldContent.length, oldContent, lastSuffix, '');
|
||||
return TextDocument.create(document.uri, languageId, document.version, result);
|
||||
}
|
||||
|
||||
function getPrefix(c: EmbeddedRegion) {
|
||||
if (c.attributeValue) {
|
||||
switch (c.languageId) {
|
||||
case 'css': return CSS_STYLE_RULE + '{';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
function getSuffix(c: EmbeddedRegion) {
|
||||
if (c.attributeValue) {
|
||||
switch (c.languageId) {
|
||||
case 'css': return '}';
|
||||
case 'javascript': return ';';
|
||||
}
|
||||
}
|
||||
return '';
|
||||
}
|
||||
|
||||
function substituteWithWhitespace(result: string, start: number, end: number, oldContent: string, before: string, after: string) {
|
||||
let accumulatedWS = 0;
|
||||
result += before;
|
||||
for (let i = start + before.length; i < end; i++) {
|
||||
let ch = oldContent[i];
|
||||
if (ch === '\n' || ch === '\r') {
|
||||
// only write new lines, skip the whitespace
|
||||
accumulatedWS = 0;
|
||||
result += ch;
|
||||
} else {
|
||||
accumulatedWS++;
|
||||
}
|
||||
}
|
||||
result = append(result, ' ', accumulatedWS - after.length);
|
||||
result += after;
|
||||
return result;
|
||||
}
|
||||
|
||||
function append(result: string, str: string, n: number): string {
|
||||
while (n > 0) {
|
||||
if (n & 1) {
|
||||
result += str;
|
||||
}
|
||||
n >>= 1;
|
||||
str += str;
|
||||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
function getAttributeLanguage(attributeName: string): string | null {
|
||||
let match = attributeName.match(/^(style)$|^(on\w+)$/i);
|
||||
if (!match) {
|
||||
return null;
|
||||
}
|
||||
return match[1] ? 'css' : 'javascript';
|
||||
}
|
||||
@ -0,0 +1,82 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { TextDocument } from 'vscode-html-languageservice';
|
||||
|
||||
export interface LanguageModelCache<T> {
|
||||
get(document: TextDocument): T;
|
||||
onDocumentRemoved(document: TextDocument): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTimeInSec: number, parse: (document: TextDocument) => T): LanguageModelCache<T> {
|
||||
let languageModels: { [uri: string]: { version: number, languageId: string, cTime: number, languageModel: T } } = {};
|
||||
let nModels = 0;
|
||||
|
||||
let cleanupInterval: NodeJS.Timer | undefined = undefined;
|
||||
if (cleanupIntervalTimeInSec > 0) {
|
||||
cleanupInterval = setInterval(() => {
|
||||
const cutoffTime = Date.now() - cleanupIntervalTimeInSec * 1000;
|
||||
const uris = Object.keys(languageModels);
|
||||
for (const uri of uris) {
|
||||
const languageModelInfo = languageModels[uri];
|
||||
if (languageModelInfo.cTime < cutoffTime) {
|
||||
delete languageModels[uri];
|
||||
nModels--;
|
||||
}
|
||||
}
|
||||
}, cleanupIntervalTimeInSec * 1000);
|
||||
}
|
||||
|
||||
return {
|
||||
get(document: TextDocument): T {
|
||||
const version = document.version;
|
||||
const languageId = document.languageId;
|
||||
const languageModelInfo = languageModels[document.uri];
|
||||
if (languageModelInfo && languageModelInfo.version === version && languageModelInfo.languageId === languageId) {
|
||||
languageModelInfo.cTime = Date.now();
|
||||
return languageModelInfo.languageModel;
|
||||
}
|
||||
const languageModel = parse(document);
|
||||
languageModels[document.uri] = { languageModel, version, languageId, cTime: Date.now() };
|
||||
if (!languageModelInfo) {
|
||||
nModels++;
|
||||
}
|
||||
|
||||
if (nModels === maxEntries) {
|
||||
let oldestTime = Number.MAX_VALUE;
|
||||
let oldestUri = null;
|
||||
for (const uri in languageModels) {
|
||||
const languageModelInfo = languageModels[uri];
|
||||
if (languageModelInfo.cTime < oldestTime) {
|
||||
oldestUri = uri;
|
||||
oldestTime = languageModelInfo.cTime;
|
||||
}
|
||||
}
|
||||
if (oldestUri) {
|
||||
delete languageModels[oldestUri];
|
||||
nModels--;
|
||||
}
|
||||
}
|
||||
return languageModel;
|
||||
|
||||
},
|
||||
onDocumentRemoved(document: TextDocument) {
|
||||
const uri = document.uri;
|
||||
if (languageModels[uri]) {
|
||||
delete languageModels[uri];
|
||||
nModels--;
|
||||
}
|
||||
},
|
||||
dispose() {
|
||||
if (typeof cleanupInterval !== 'undefined') {
|
||||
clearInterval(cleanupInterval);
|
||||
cleanupInterval = undefined;
|
||||
languageModels = {};
|
||||
nModels = 0;
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
118
lsp-embedded-request-forwarding/server/src/languageModes.ts
Normal file
118
lsp-embedded-request-forwarding/server/src/languageModes.ts
Normal file
@ -0,0 +1,118 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import {
|
||||
CompletionList,
|
||||
Diagnostic,
|
||||
getLanguageService as getHTMLLanguageService,
|
||||
Position,
|
||||
Range,
|
||||
TextDocument
|
||||
} from 'vscode-html-languageservice';
|
||||
import { getDocumentRegions, HTMLDocumentRegions } from './embeddedSupport';
|
||||
import { getHTMLMode } from './modes/htmlMode';
|
||||
import { getLanguageModelCache, LanguageModelCache } from './languageModelCache';
|
||||
|
||||
export * from 'vscode-html-languageservice';
|
||||
|
||||
export interface LanguageMode {
|
||||
getId(): string;
|
||||
doValidation?: (document: TextDocument) => Diagnostic[];
|
||||
doComplete?: (document: TextDocument, position: Position) => CompletionList;
|
||||
onDocumentRemoved(document: TextDocument): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export interface LanguageModes {
|
||||
getModeAtPosition(document: TextDocument, position: Position): LanguageMode | undefined;
|
||||
getModesInRange(document: TextDocument, range: Range): LanguageModeRange[];
|
||||
getAllModes(): LanguageMode[];
|
||||
getAllModesInDocument(document: TextDocument): LanguageMode[];
|
||||
getMode(languageId: string): LanguageMode | undefined;
|
||||
onDocumentRemoved(document: TextDocument): void;
|
||||
dispose(): void;
|
||||
}
|
||||
|
||||
export interface LanguageModeRange extends Range {
|
||||
mode: LanguageMode | undefined;
|
||||
attributeValue?: boolean;
|
||||
}
|
||||
|
||||
export function getLanguageModes(): LanguageModes {
|
||||
const htmlLanguageService = getHTMLLanguageService();
|
||||
|
||||
let documentRegions = getLanguageModelCache<HTMLDocumentRegions>(10, 60, document =>
|
||||
getDocumentRegions(htmlLanguageService, document)
|
||||
);
|
||||
|
||||
let modelCaches: LanguageModelCache<any>[] = [];
|
||||
modelCaches.push(documentRegions);
|
||||
|
||||
let modes = Object.create(null);
|
||||
modes['html'] = getHTMLMode(htmlLanguageService);
|
||||
|
||||
return {
|
||||
getModeAtPosition(
|
||||
document: TextDocument,
|
||||
position: Position
|
||||
): LanguageMode | undefined {
|
||||
let languageId = documentRegions.get(document).getLanguageAtPosition(position);
|
||||
if (languageId) {
|
||||
return modes[languageId];
|
||||
}
|
||||
return undefined;
|
||||
},
|
||||
getModesInRange(document: TextDocument, range: Range): LanguageModeRange[] {
|
||||
return documentRegions
|
||||
.get(document)
|
||||
.getLanguageRanges(range)
|
||||
.map(r => {
|
||||
return <LanguageModeRange>{
|
||||
start: r.start,
|
||||
end: r.end,
|
||||
mode: r.languageId && modes[r.languageId],
|
||||
attributeValue: r.attributeValue
|
||||
};
|
||||
});
|
||||
},
|
||||
getAllModesInDocument(document: TextDocument): LanguageMode[] {
|
||||
let result = [];
|
||||
for (let languageId of documentRegions.get(document).getLanguagesInDocument()) {
|
||||
let mode = modes[languageId];
|
||||
if (mode) {
|
||||
result.push(mode);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
getAllModes(): LanguageMode[] {
|
||||
let result = [];
|
||||
for (let languageId in modes) {
|
||||
let mode = modes[languageId];
|
||||
if (mode) {
|
||||
result.push(mode);
|
||||
}
|
||||
}
|
||||
return result;
|
||||
},
|
||||
getMode(languageId: string): LanguageMode {
|
||||
return modes[languageId];
|
||||
},
|
||||
onDocumentRemoved(document: TextDocument) {
|
||||
modelCaches.forEach(mc => mc.onDocumentRemoved(document));
|
||||
for (let mode in modes) {
|
||||
modes[mode].onDocumentRemoved(document);
|
||||
}
|
||||
},
|
||||
dispose(): void {
|
||||
modelCaches.forEach(mc => mc.dispose());
|
||||
modelCaches = [];
|
||||
for (let mode in modes) {
|
||||
modes[mode].dispose();
|
||||
}
|
||||
modes = {};
|
||||
}
|
||||
};
|
||||
}
|
||||
28
lsp-embedded-request-forwarding/server/src/modes/htmlMode.ts
Normal file
28
lsp-embedded-request-forwarding/server/src/modes/htmlMode.ts
Normal file
@ -0,0 +1,28 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import {
|
||||
LanguageMode,
|
||||
LanguageService as HTMLLanguageService,
|
||||
Position,
|
||||
TextDocument
|
||||
} from '../languageModes';
|
||||
|
||||
export function getHTMLMode(htmlLanguageService: HTMLLanguageService): LanguageMode {
|
||||
return {
|
||||
getId() {
|
||||
return 'html';
|
||||
},
|
||||
doComplete(document: TextDocument, position: Position) {
|
||||
return htmlLanguageService.doComplete(
|
||||
document,
|
||||
position,
|
||||
htmlLanguageService.parseHTMLDocument(document)
|
||||
);
|
||||
},
|
||||
onDocumentRemoved(_document: TextDocument) {},
|
||||
dispose() {}
|
||||
};
|
||||
}
|
||||
111
lsp-embedded-request-forwarding/server/src/server.ts
Normal file
111
lsp-embedded-request-forwarding/server/src/server.ts
Normal file
@ -0,0 +1,111 @@
|
||||
/* --------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
* ------------------------------------------------------------------------------------------ */
|
||||
|
||||
import {
|
||||
CompletionList,
|
||||
createConnection,
|
||||
Diagnostic,
|
||||
InitializeParams,
|
||||
ProposedFeatures,
|
||||
TextDocument,
|
||||
TextDocuments
|
||||
} from 'vscode-languageserver';
|
||||
import { getLanguageModes, LanguageModes } from './languageModes';
|
||||
|
||||
// Create a connection for the server. The connection uses Node's IPC as a transport.
|
||||
// Also include all preview / proposed LSP features.
|
||||
let connection = createConnection(ProposedFeatures.all);
|
||||
|
||||
// Create a simple text document manager. The text document manager
|
||||
// supports full document sync only
|
||||
let documents: TextDocuments = new TextDocuments();
|
||||
|
||||
let languageModes: LanguageModes;
|
||||
|
||||
connection.onInitialize((_params: InitializeParams) => {
|
||||
languageModes = getLanguageModes();
|
||||
|
||||
documents.onDidClose(e => {
|
||||
languageModes.onDocumentRemoved(e.document);
|
||||
});
|
||||
connection.onShutdown(() => {
|
||||
languageModes.dispose();
|
||||
});
|
||||
|
||||
return {
|
||||
capabilities: {
|
||||
textDocumentSync: documents.syncKind,
|
||||
// Tell the client that the server supports code completion
|
||||
completionProvider: {
|
||||
resolveProvider: false
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
connection.onInitialized(() => {});
|
||||
|
||||
connection.onDidChangeConfiguration(_change => {
|
||||
// Revalidate all open text documents
|
||||
documents.all().forEach(validateTextDocument);
|
||||
});
|
||||
|
||||
// The content of a text document has changed. This event is emitted
|
||||
// when the text document first opened or when its content has changed.
|
||||
documents.onDidChangeContent(change => {
|
||||
validateTextDocument(change.document);
|
||||
});
|
||||
|
||||
async function validateTextDocument(textDocument: TextDocument) {
|
||||
try {
|
||||
const version = textDocument.version;
|
||||
const diagnostics: Diagnostic[] = [];
|
||||
if (textDocument.languageId === 'html') {
|
||||
const modes = languageModes.getAllModesInDocument(textDocument);
|
||||
const latestTextDocument = documents.get(textDocument.uri);
|
||||
if (latestTextDocument && latestTextDocument.version === version) {
|
||||
// check no new version has come in after in after the async op
|
||||
modes.forEach(mode => {
|
||||
if (mode.doValidation) {
|
||||
mode.doValidation(latestTextDocument).forEach(d => {
|
||||
diagnostics.push(d);
|
||||
});
|
||||
}
|
||||
});
|
||||
connection.sendDiagnostics({ uri: latestTextDocument.uri, diagnostics });
|
||||
}
|
||||
}
|
||||
} catch (e) {
|
||||
connection.console.error(`Error while validating ${textDocument.uri}`);
|
||||
connection.console.error(e);
|
||||
}
|
||||
}
|
||||
|
||||
connection.onDidChangeWatchedFiles(_change => {
|
||||
// Monitored files have change in VSCode
|
||||
connection.console.log('We received an file change event');
|
||||
});
|
||||
|
||||
// This handler provides the initial list of the completion items.
|
||||
connection.onCompletion(async (textDocumentPosition, token) => {
|
||||
const document = documents.get(textDocumentPosition.textDocument.uri);
|
||||
if (!document) {
|
||||
return null;
|
||||
}
|
||||
const mode = languageModes.getModeAtPosition(document, textDocumentPosition.position);
|
||||
if (!mode || !mode.doComplete) {
|
||||
return CompletionList.create();
|
||||
}
|
||||
const doComplete = mode.doComplete!;
|
||||
|
||||
return doComplete(document, textDocumentPosition.position);
|
||||
});
|
||||
|
||||
// Make the text document manager listen on the connection
|
||||
// for open, change and close text document events
|
||||
documents.listen(connection);
|
||||
|
||||
// Listen on the connection
|
||||
connection.listen();
|
||||
13
lsp-embedded-request-forwarding/server/tsconfig.json
Normal file
13
lsp-embedded-request-forwarding/server/tsconfig.json
Normal file
@ -0,0 +1,13 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"target": "es6",
|
||||
"module": "commonjs",
|
||||
"moduleResolution": "node",
|
||||
"sourceMap": true,
|
||||
"strict": true,
|
||||
"outDir": "out",
|
||||
"rootDir": "src"
|
||||
},
|
||||
"include": ["src"],
|
||||
"exclude": ["node_modules", ".vscode-test"]
|
||||
}
|
||||
20
lsp-embedded-request-forwarding/tsconfig.json
Normal file
20
lsp-embedded-request-forwarding/tsconfig.json
Normal file
@ -0,0 +1,20 @@
|
||||
{
|
||||
"compilerOptions": {
|
||||
"module": "commonjs",
|
||||
"target": "es6",
|
||||
"outDir": "out",
|
||||
"rootDir": "src",
|
||||
"sourceMap": true
|
||||
},
|
||||
"include": [
|
||||
"src"
|
||||
],
|
||||
"exclude": [
|
||||
"node_modules",
|
||||
".vscode-test"
|
||||
],
|
||||
"references": [
|
||||
{ "path": "./client" },
|
||||
{ "path": "./server" }
|
||||
]
|
||||
}
|
||||
6
lsp-embedded-request-forwarding/tslint.json
Normal file
6
lsp-embedded-request-forwarding/tslint.json
Normal file
@ -0,0 +1,6 @@
|
||||
{
|
||||
"rules": {
|
||||
"indent": [true, "tabs"],
|
||||
"semicolon": [true, "always"]
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user