Merge branch 'master' into patch-1

This commit is contained in:
Christof Marti 2018-01-04 09:48:46 +01:00 committed by GitHub
commit 603e8f6eb4
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
944 changed files with 21596 additions and 15781 deletions

View file

@ -6,7 +6,7 @@
api: [],
color-picker: [],
css-less-sass: [],
debug: [ weinand ],
debug: [ isidorn ],
diff-editor: [],
editor: [],
editor-1000-limit: [],

View file

@ -1,6 +1,6 @@
<!-- Do you have a question? Please ask it on http://stackoverflow.com/questions/tagged/vscode. -->
<!-- Do you have a question? Please ask it on https://stackoverflow.com/questions/tagged/vscode. -->
<!-- Use Help > Report Issues to prefill these. -->
<!-- Use Help > Report Issue to prefill these. -->
- VSCode Version:
- OS Version:
@ -10,4 +10,4 @@ Steps to Reproduce:
2.
<!-- Launch with `code --disable-extensions` to check. -->
Does the issue happen when all extensions are disabled?: Yes/No
Does this issue occur when all extensions are disabled?: Yes/No

View file

@ -31,6 +31,7 @@ addons:
- libsecret-1-dev
before_install:
- export GITHUB_TOKEN=$PUBLIC_GITHUB_TOKEN
- git submodule update --init --recursive
- git clone --depth 1 https://github.com/creationix/nvm.git ./.nvm
- source ./.nvm/nvm.sh
@ -53,6 +54,7 @@ install:
script:
- node_modules/.bin/gulp hygiene
- node_modules/.bin/gulp electron --silent
- node_modules/.bin/tsc -p ./src/tsconfig.monaco.json --noEmit
- node_modules/.bin/gulp compile --silent --max_old_space_size=4096
- node_modules/.bin/gulp optimize-vscode --silent --max_old_space_size=4096
- if [[ "$TRAVIS_OS_NAME" == "linux" ]]; then ./scripts/test.sh --coverage --reporter dot; else ./scripts/test.sh --reporter dot; fi

View file

@ -10,6 +10,9 @@
"when": "$(basename).ts"
}
},
"files.associations": {
"OSSREADME.json": "jsonc"
},
"search.exclude": {
"**/node_modules": true,
"**/bower_components": true,
@ -36,4 +39,4 @@
}
],
"typescript.tsdk": "node_modules/typescript/lib"
}
}

View file

@ -1,65 +1,5 @@
// Listing in here platform dependencies that come in at build time
[{
"isLicense": true,
"name": "async-each",
"repositoryURL": "https://github.com/paulmillr/async-each",
"license": "MIT",
"licenseDetail": [
"The MIT License (MIT)",
"",
"Copyright (c) 2016 Paul Miller [(paulmillr.com)](http://paulmillr.com)",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and associated documentation files (the “Software”), to deal",
"in the Software without restriction, including without limitation the rights",
"to use, copy, modify, merge, publish, distribute, sublicense, and/or sell",
"copies of the Software, and to permit persons to whom the Software is",
"furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in",
"all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN",
"THE SOFTWARE."
],
"isProd": true
},
{
"isLicense": true,
"name": "chokidar",
"repositoryURL": "https://github.com/paulmillr/chokidar",
"license": "MIT",
"licenseDetail": [
"The MIT license.",
"",
"Copyright (c) 2012 - 2016 Paul Miller [paulmillr.com](http://paulmillr.com) & Elan Shanker",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of",
"this software and associated documentation files (the \"Software\"), to deal in",
"the Software without restriction, including without limitation the rights to",
"use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies",
"of the Software, and to permit persons to whom the Software is furnished to do",
"so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all",
"copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE",
"SOFTWARE."
],
"isProd": true
},
[
{
"name": "chromium",
"version": "58.0.3029.110",
@ -123,40 +63,56 @@
"isProd": true
},
{
"isLicense": true,
"name": "ripgrep",
"repositoryURL": "https://github.com/BurntSushi/ripgrep",
"name": "spdlog original",
"version": "0.14.0",
"repositoryURL": "https://github.com/gabime/spdlog",
"license": "MIT",
"isProd": true
},
// --------------------------------------------------------------------------------------
// --------------------------------------------------------------------------------------
// ONLY LICENSE TEXT AFTER THIS MARKER
// Each license entry should contain precisely the following fields:
// "isLicense": true
// "name": string
// "licenseDetail": string[]
// Furthermore, each license entry should contain a clear reason for existance.
{
// Reason: Added here because the repo at https://github.com/paulmillr/async-each
// does not include a LICENSE file that can be machine processed.
"isLicense": true,
"name": "async-each",
"licenseDetail": [
"The MIT License (MIT)",
"",
"Copyright (c) 2015 Andrew Gallant",
"Copyright (c) 2016 Paul Miller [(paulmillr.com)](http://paulmillr.com)",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of",
"this software and associated documentation files (the \"Software\"), to deal in",
"the Software without restriction, including without limitation the rights to",
"use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies",
"of the Software, and to permit persons to whom the Software is furnished to do",
"so, subject to the following conditions:",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and associated documentation files (the “Software”), to deal",
"in the Software without restriction, including without limitation the rights",
"to use, copy, modify, merge, publish, distribute, sublicense, and/or sell",
"copies of the Software, and to permit persons to whom the Software is",
"furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all",
"copies or substantial portions of the Software.",
"The above copyright notice and this permission notice shall be included in",
"all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"THE SOFTWARE IS PROVIDED “AS IS”, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE",
"SOFTWARE."
],
"isProd": true
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN",
"THE SOFTWARE."
]
},
{
// Reason: The license at https://github.com/aadsm/jschardet/blob/master/LICENSE
// does not include a clear Copyright statement and does not credit authors.
"isLicense": true,
"name": "jschardet",
"repositoryURL": "https://github.com/aadsm/jschardet",
"license": "LGPL",
"licenseDetail": [
"Chardet was originally ported from C++ by Mark Pilgrim. It is now maintained",
" by Dan Blanchard and Ian Cordasco, and was formerly maintained by Erik Rose.",
@ -670,12 +626,117 @@
" Ty Coon, President of Vice",
"",
"That's all there is to it!"
],
"isProd": true
]
},
{
// Added here because the module `parse5` has a dependency to it.
// The module `parse5` is shipped via the `extension-editing` built-in extension.
// The module `parse5` does not want to remove it https://github.com/inikulin/parse5/issues/225
"isLicense": true,
"name": "@types/node",
"licenseDetail": [
"This project is licensed under the MIT license.",
"Copyrights are respective of each contributor listed at the beginning of each definition file.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
},
{
// We override the license that gets discovered at
// https://github.com/Microsoft/TypeScript/blob/master/LICENSE.txt
// because it does not contain a Copyright statement
"isLicense": true,
"name": "typescript",
"licenseDetail": [
"Copyright (c) Microsoft Corporation. All rights reserved.",
"",
"Apache License",
"",
"Version 2.0, January 2004",
"",
"http://www.apache.org/licenses/",
"",
"TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION",
"",
"1. Definitions.",
"",
"\"License\" shall mean the terms and conditions for use, reproduction, and distribution as defined by Sections 1 through 9 of this document.",
"",
"\"Licensor\" shall mean the copyright owner or entity authorized by the copyright owner that is granting the License.",
"",
"\"Legal Entity\" shall mean the union of the acting entity and all other entities that control, are controlled by, or are under common control with that entity. For the purposes of this definition, \"control\" means (i) the power, direct or indirect, to cause the direction or management of such entity, whether by contract or otherwise, or (ii) ownership of fifty percent (50%) or more of the outstanding shares, or (iii) beneficial ownership of such entity.",
"",
"\"You\" (or \"Your\") shall mean an individual or Legal Entity exercising permissions granted by this License.",
"",
"\"Source\" form shall mean the preferred form for making modifications, including but not limited to software source code, documentation source, and configuration files.",
"",
"\"Object\" form shall mean any form resulting from mechanical transformation or translation of a Source form, including but not limited to compiled object code, generated documentation, and conversions to other media types.",
"",
"\"Work\" shall mean the work of authorship, whether in Source or Object form, made available under the License, as indicated by a copyright notice that is included in or attached to the work (an example is provided in the Appendix below).",
"",
"\"Derivative Works\" shall mean any work, whether in Source or Object form, that is based on (or derived from) the Work and for which the editorial revisions, annotations, elaborations, or other modifications represent, as a whole, an original work of authorship. For the purposes of this License, Derivative Works shall not include works that remain separable from, or merely link (or bind by name) to the interfaces of, the Work and Derivative Works thereof.",
"",
"\"Contribution\" shall mean any work of authorship, including the original version of the Work and any modifications or additions to that Work or Derivative Works thereof, that is intentionally submitted to Licensor for inclusion in the Work by the copyright owner or by an individual or Legal Entity authorized to submit on behalf of the copyright owner. For the purposes of this definition, \"submitted\" means any form of electronic, verbal, or written communication sent to the Licensor or its representatives, including but not limited to communication on electronic mailing lists, source code control systems, and issue tracking systems that are managed by, or on behalf of, the Licensor for the purpose of discussing and improving the Work, but excluding communication that is conspicuously marked or otherwise designated in writing by the copyright owner as \"Not a Contribution.\"",
"",
"\"Contributor\" shall mean Licensor and any individual or Legal Entity on behalf of whom a Contribution has been received by Licensor and subsequently incorporated within the Work.",
"",
"2. Grant of Copyright License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable copyright license to reproduce, prepare Derivative Works of, publicly display, publicly perform, sublicense, and distribute the Work and such Derivative Works in Source or Object form.",
"",
"3. Grant of Patent License. Subject to the terms and conditions of this License, each Contributor hereby grants to You a perpetual, worldwide, non-exclusive, no-charge, royalty-free, irrevocable (except as stated in this section) patent license to make, have made, use, offer to sell, sell, import, and otherwise transfer the Work, where such license applies only to those patent claims licensable by such Contributor that are necessarily infringed by their Contribution(s) alone or by combination of their Contribution(s) with the Work to which such Contribution(s) was submitted. If You institute patent litigation against any entity (including a cross-claim or counterclaim in a lawsuit) alleging that the Work or a Contribution incorporated within the Work constitutes direct or contributory patent infringement, then any patent licenses granted to You under this License for that Work shall terminate as of the date such litigation is filed.",
"",
"4. Redistribution. You may reproduce and distribute copies of the Work or Derivative Works thereof in any medium, with or without modifications, and in Source or Object form, provided that You meet the following conditions:",
"",
"You must give any other recipients of the Work or Derivative Works a copy of this License; and",
"",
"You must cause any modified files to carry prominent notices stating that You changed the files; and",
"",
"You must retain, in the Source form of any Derivative Works that You distribute, all copyright, patent, trademark, and attribution notices from the Source form of the Work, excluding those notices that do not pertain to any part of the Derivative Works; and",
"",
"If the Work includes a \"NOTICE\" text file as part of its distribution, then any Derivative Works that You distribute must include a readable copy of the attribution notices contained within such NOTICE file, excluding those notices that do not pertain to any part of the Derivative Works, in at least one of the following places: within a NOTICE text file distributed as part of the Derivative Works; within the Source form or documentation, if provided along with the Derivative Works; or, within a display generated by the Derivative Works, if and wherever such third-party notices normally appear. The contents of the NOTICE file are for informational purposes only and do not modify the License. You may add Your own attribution notices within Derivative Works that You distribute, alongside or as an addendum to the NOTICE text from the Work, provided that such additional attribution notices cannot be construed as modifying the License. You may add Your own copyright statement to Your modifications and may provide additional or different license terms and conditions for use, reproduction, or distribution of Your modifications, or for any such Derivative Works as a whole, provided Your use, reproduction, and distribution of the Work otherwise complies with the conditions stated in this License.",
"",
"5. Submission of Contributions. Unless You explicitly state otherwise, any Contribution intentionally submitted for inclusion in the Work by You to the Licensor shall be under the terms and conditions of this License, without any additional terms or conditions. Notwithstanding the above, nothing herein shall supersede or modify the terms of any separate license agreement you may have executed with Licensor regarding such Contributions.",
"",
"6. Trademarks. This License does not grant permission to use the trade names, trademarks, service marks, or product names of the Licensor, except as required for reasonable and customary use in describing the origin of the Work and reproducing the content of the NOTICE file.",
"",
"7. Disclaimer of Warranty. Unless required by applicable law or agreed to in writing, Licensor provides the Work (and each Contributor provides its Contributions) on an \"AS IS\" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied, including, without limitation, any warranties or conditions of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A PARTICULAR PURPOSE. You are solely responsible for determining the appropriateness of using or redistributing the Work and assume any risks associated with Your exercise of permissions under this License.",
"",
"8. Limitation of Liability. In no event and under no legal theory, whether in tort (including negligence), contract, or otherwise, unless required by applicable law (such as deliberate and grossly negligent acts) or agreed to in writing, shall any Contributor be liable to You for damages, including any direct, indirect, special, incidental, or consequential damages of any character arising as a result of this License or out of the use or inability to use the Work (including but not limited to damages for loss of goodwill, work stoppage, computer failure or malfunction, or any and all other commercial damages or losses), even if such Contributor has been advised of the possibility of such damages.",
"",
"9. Accepting Warranty or Additional Liability. While redistributing the Work or Derivative Works thereof, You may choose to offer, and charge a fee for, acceptance of support, warranty, indemnity, or other liability obligations and/or rights consistent with this License. However, in accepting such obligations, You may act only on Your own behalf and on Your sole responsibility, not on behalf of any other Contributor, and only if You agree to indemnify, defend, and hold each Contributor harmless for any liability incurred by, or claims asserted against, such Contributor by reason of your accepting any such warranty or additional liability.",
"",
"END OF TERMS AND CONDITIONS"
]
},
{
"isLicense": true,
"name": "@types/node",
"name": "noice-json-rpc",
"repositoryURL": "https://github.com/nojvek/noice-json-rpc",
"license": "MIT",
"licenseDetail": [
"Copyright (c) Manoj Patel",
"",
"MIT License",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation",
"files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy,",
"modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software",
"is furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES",
"OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS",
"BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT",
"OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
},
{
"isLicense": true,
"name": "@types/source-map",
"repositoryURL": "https://www.github.com/DefinitelyTyped/DefinitelyTyped",
"license": "MIT",
"licenseDetail": [
@ -687,126 +748,57 @@
"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
],
"isProd": true
]
},
{
"isLicense": true,
"name": "jsonfile",
"repositoryURL": "https+ssh://git@github.com/jprichardson/node-jsonfile",
"license": "MIT",
"name": "markdown-it-named-headers",
"licenseDetail": [
"(The MIT License)",
"Copyright (c) markdown-it-named-headers authors",
"",
"Copyright (c) 2012-2015, JP Richardson <jprichardson@gmail.com>",
"This is free and unencumbered software released into the public domain.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files",
"(the 'Software'), to deal in the Software without restriction, including without limitation the rights to use, copy, modify,",
" merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is",
" furnished to do so, subject to the following conditions:",
"Anyone is free to copy, modify, publish, use, compile, sell, or",
"distribute this software, either in source code form or as a compiled",
"binary, for any purpose, commercial or non-commercial, and by any",
"means.",
"",
"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
"In jurisdictions that recognize copyright laws, the author or authors",
"of this software dedicate any and all copyright interest in the",
"software to the public domain. We make this dedication for the benefit",
"of the public at large and to the detriment of our heirs and",
"successors. We intend this dedication to be an overt act of",
"relinquishment in perpetuity of all present and future rights to this",
"software under copyright law.",
"",
"THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE",
"WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS",
"OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,",
" ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
],
"isProd": true
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,",
"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF",
"MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.",
"IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR",
"OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,",
"ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR",
"OTHER DEALINGS IN THE SOFTWARE.",
"",
"For more information, please refer to <http://unlicense.org/>"
]
},
{
"isLicense": true,
"name": "string_decoder",
"repositoryURL": "https://github.com/rvagg/string_decoder",
"license": "MIT",
"name": "uc.micro",
"licenseDetail": [
"The MIT License (MIT)",
" DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE",
" Version 2, December 2004",
"",
"Node.js is licensed for use as follows:",
" Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>",
"",
"\"\"\"",
"Copyright Node.js contributors. All rights reserved.",
" Everyone is permitted to copy and distribute verbatim or modified",
" copies of this license document, and changing it is allowed as long",
" as the name is changed.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and associated documentation files (the \"Software\"), to",
"deal in the Software without restriction, including without limitation the",
"rights to use, copy, modify, merge, publish, distribute, sublicense, and/or",
"sell copies of the Software, and to permit persons to whom the Software is",
"furnished to do so, subject to the following conditions:",
" DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE",
" TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION",
"",
"The above copyright notice and this permission notice shall be included in",
"all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING",
"FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS",
"IN THE SOFTWARE.",
"\"\"\"",
"",
"This license applies to parts of Node.js originating from the",
"https://github.com/joyent/node repository:",
"",
"\"\"\"",
"Copyright Joyent, Inc. and other Node contributors. All rights reserved.",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and associated documentation files (the \"Software\"), to",
"deal in the Software without restriction, including without limitation the",
"rights to use, copy, modify, merge, publish, distribute, sublicense, and/or",
"sell copies of the Software, and to permit persons to whom the Software is",
"furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in",
"all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING",
"FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS",
"IN THE SOFTWARE.",
"\"\"\""
],
"isProd": true
},
{
"name": "spdlog original",
"version": "0.14.0",
"repositoryURL": "https://github.com/gabime/spdlog",
"license": "MIT",
"isProd": true
},
{
"isLicense": true,
"name": "spdlog",
"version": "0.14.0",
"repositoryURL": "https://github.com/gabime/spdlog",
"license": "MIT",
"licenseDetail": [
"MIT License",
"",
"Copyright (c) Microsoft Corporation. All rights reserved.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy",
"of this software and associated documentation files (the \"Software\"), to deal",
"in the Software without restriction, including without limitation the rights",
"to use, copy, modify, merge, publish, distribute, sublicense, and/or sell",
"copies of the Software, and to permit persons to whom the Software is",
"furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all",
"copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR",
"IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,",
"FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE",
"AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER",
"LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,",
"OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE",
"SOFTWARE"
" 0. You just DO WHAT THE FUCK YOU WANT TO."
]
}
]

View file

@ -1846,4 +1846,4 @@ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
=========================================
END OF vscode-swift NOTICES AND INFORMATION
END OF vscode-swift NOTICES AND INFORMATION

View file

@ -11,6 +11,7 @@ install:
build_script:
- yarn
- .\node_modules\.bin\gulp electron
- .\node_modules\.bin\tsc -p .\src\tsconfig.monaco.json --noEmit
- npm run compile
test_script:

View file

@ -45,8 +45,8 @@ const nodeModules = ['electron', 'original-fs']
// Build
const builtInExtensions = [
{ name: 'ms-vscode.node-debug', version: '1.19.7' },
{ name: 'ms-vscode.node-debug2', version: '1.19.3' }
{ name: 'ms-vscode.node-debug', version: '1.20.2' },
{ name: 'ms-vscode.node-debug2', version: '1.20.0' }
];
const excludedExtensions = [
@ -82,7 +82,7 @@ const vscodeResources = [
'out-build/vs/workbench/parts/welcome/walkThrough/**/*.md',
'out-build/vs/workbench/services/files/**/*.exe',
'out-build/vs/workbench/services/files/**/*.md',
'out-build/vs/code/electron-browser/sharedProcess.js',
'out-build/vs/code/electron-browser/sharedProcess/sharedProcess.js',
'!**/test/**'
];
@ -296,6 +296,7 @@ function packageTask(platform, arch, opts) {
.pipe(util.cleanNodeModule('oniguruma', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node', 'src/*.js']))
.pipe(util.cleanNodeModule('windows-mutex', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('native-keymap', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('native-is-elevated', ['binding.gyp', 'build/**', 'src/**', 'deps/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('native-watchdog', ['binding.gyp', 'build/**', 'src/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('spdlog', ['binding.gyp', 'build/**', 'deps/**', 'src/**', 'test/**'], ['**/*.node']))
.pipe(util.cleanNodeModule('jschardet', ['dist/**']))

View file

@ -22,6 +22,9 @@ var rootDir = path.join(__dirname, '../../src');
var options = require('../../src/tsconfig.json').compilerOptions;
options.verbose = false;
options.sourceMap = true;
if (process.env['VSCODE_NO_SOURCEMAP']) {
options.sourceMap = false;
}
options.rootDir = rootDir;
options.sourceRoot = util.toFileUri(rootDir);
function createCompile(build, emitError) {
@ -58,9 +61,13 @@ function compileTask(out, build) {
return function () {
var compile = createCompile(build, true);
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts'));
// Do not write .d.ts files to disk, as they are not needed there.
var dtsFilter = util.filter(function (data) { return !/\.d\.ts$/.test(data.path); });
return src
.pipe(compile())
.pipe(dtsFilter)
.pipe(gulp.dest(out))
.pipe(dtsFilter.restore)
.pipe(monacodtsTask(out, false));
};
}
@ -70,54 +77,19 @@ function watchTask(out, build) {
var compile = createCompile(build);
var src = es.merge(gulp.src('src/**', { base: 'src' }), gulp.src('node_modules/typescript/lib/lib.d.ts'));
var watchSrc = watch('src/**', { base: 'src' });
// Do not write .d.ts files to disk, as they are not needed there.
var dtsFilter = util.filter(function (data) { return !/\.d\.ts$/.test(data.path); });
return watchSrc
.pipe(util.incremental(compile, src, true))
.pipe(dtsFilter)
.pipe(gulp.dest(out))
.pipe(dtsFilter.restore)
.pipe(monacodtsTask(out, true));
};
}
exports.watchTask = watchTask;
function reloadTypeScriptNodeModule() {
var util = require('gulp-util');
function log(message) {
var rest = [];
for (var _i = 1; _i < arguments.length; _i++) {
rest[_i - 1] = arguments[_i];
}
util.log.apply(util, [util.colors.cyan('[memory watch dog]'), message].concat(rest));
}
function heapUsed() {
return (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2) + ' MB';
}
return es.through(function (data) {
this.emit('data', data);
}, function () {
log('memory usage after compilation finished: ' + heapUsed());
// It appears we are running into some variant of
// https://bugs.chromium.org/p/v8/issues/detail?id=2073
//
// Even though all references are dropped, some
// optimized methods in the TS compiler end up holding references
// to the entire TypeScript language host (>600MB)
//
// The idea is to force v8 to drop references to these
// optimized methods, by "reloading" the typescript node module
log('Reloading typescript node module...');
var resolvedName = require.resolve('typescript');
var originalModule = require.cache[resolvedName];
delete require.cache[resolvedName];
var newExports = require('typescript');
require.cache[resolvedName] = originalModule;
for (var prop in newExports) {
if (newExports.hasOwnProperty(prop)) {
originalModule.exports[prop] = newExports[prop];
}
}
log('typescript node module reloaded.');
this.emit('end');
});
}
function monacodtsTask(out, isWatch) {
var basePath = path.resolve(process.cwd(), out);
var neededFiles = {};
monacodts.getFilesToWatch(out).forEach(function (filePath) {
filePath = path.normalize(filePath);
@ -160,7 +132,7 @@ function monacodtsTask(out, isWatch) {
}));
}
resultStream = es.through(function (data) {
var filePath = path.normalize(data.path);
var filePath = path.normalize(path.resolve(basePath, data.relative));
if (neededFiles[filePath]) {
setInputFile(filePath, data.contents.toString());
}

View file

@ -25,6 +25,9 @@ const rootDir = path.join(__dirname, '../../src');
const options = require('../../src/tsconfig.json').compilerOptions;
options.verbose = false;
options.sourceMap = true;
if (process.env['VSCODE_NO_SOURCEMAP']) { // To be used by developers in a hurry
options.sourceMap = false;
}
options.rootDir = rootDir;
options.sourceRoot = util.toFileUri(rootDir);
@ -49,7 +52,6 @@ function createCompile(build: boolean, emitError?: boolean): (token?: util.ICanc
.pipe(tsFilter)
.pipe(util.loadSourcemaps())
.pipe(ts(token))
// .pipe(build ? reloadTypeScriptNodeModule() : es.through())
.pipe(noDeclarationsFilter)
.pipe(build ? nls() : es.through())
.pipe(noDeclarationsFilter.restore)
@ -75,9 +77,14 @@ export function compileTask(out: string, build: boolean): () => NodeJS.ReadWrite
gulp.src('node_modules/typescript/lib/lib.d.ts'),
);
// Do not write .d.ts files to disk, as they are not needed there.
const dtsFilter = util.filter(data => !/\.d\.ts$/.test(data.path));
return src
.pipe(compile())
.pipe(dtsFilter)
.pipe(gulp.dest(out))
.pipe(dtsFilter.restore)
.pipe(monacodtsTask(out, false));
};
}
@ -93,62 +100,22 @@ export function watchTask(out: string, build: boolean): () => NodeJS.ReadWriteSt
);
const watchSrc = watch('src/**', { base: 'src' });
// Do not write .d.ts files to disk, as they are not needed there.
const dtsFilter = util.filter(data => !/\.d\.ts$/.test(data.path));
return watchSrc
.pipe(util.incremental(compile, src, true))
.pipe(dtsFilter)
.pipe(gulp.dest(out))
.pipe(dtsFilter.restore)
.pipe(monacodtsTask(out, true));
};
}
function reloadTypeScriptNodeModule(): NodeJS.ReadWriteStream {
var util = require('gulp-util');
function log(message: any, ...rest: any[]): void {
util.log(util.colors.cyan('[memory watch dog]'), message, ...rest);
}
function heapUsed(): string {
return (process.memoryUsage().heapUsed / 1024 / 1024).toFixed(2) + ' MB';
}
return es.through(function (data) {
this.emit('data', data);
}, function () {
log('memory usage after compilation finished: ' + heapUsed());
// It appears we are running into some variant of
// https://bugs.chromium.org/p/v8/issues/detail?id=2073
//
// Even though all references are dropped, some
// optimized methods in the TS compiler end up holding references
// to the entire TypeScript language host (>600MB)
//
// The idea is to force v8 to drop references to these
// optimized methods, by "reloading" the typescript node module
log('Reloading typescript node module...');
var resolvedName = require.resolve('typescript');
var originalModule = require.cache[resolvedName];
delete require.cache[resolvedName];
var newExports = require('typescript');
require.cache[resolvedName] = originalModule;
for (var prop in newExports) {
if (newExports.hasOwnProperty(prop)) {
originalModule.exports[prop] = newExports[prop];
}
}
log('typescript node module reloaded.');
this.emit('end');
});
}
function monacodtsTask(out: string, isWatch: boolean): NodeJS.ReadWriteStream {
const basePath = path.resolve(process.cwd(), out);
const neededFiles: { [file: string]: boolean; } = {};
monacodts.getFilesToWatch(out).forEach(function (filePath) {
filePath = path.normalize(filePath);
@ -196,7 +163,7 @@ function monacodtsTask(out: string, isWatch: boolean): NodeJS.ReadWriteStream {
}
resultStream = es.through(function (data) {
const filePath = path.normalize(data.path);
const filePath = path.normalize(path.resolve(basePath, data.relative));
if (neededFiles[filePath]) {
setInputFile(filePath, data.contents.toString());
}

View file

@ -70,6 +70,10 @@
"name": "vs/workbench/parts/markers",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/logs",
"project": "vscode-workbench"
},
{
"name": "vs/workbench/parts/nps",
"project": "vscode-workbench"
@ -199,4 +203,4 @@
"project": "vscode-workbench"
}
]
}
}

View file

@ -14,14 +14,19 @@ var url = require('url');
function getOptions(urlString) {
var _url = url.parse(urlString);
var headers = {
'User-Agent': 'VSCode'
};
var token = process.env['GITHUB_TOKEN'];
if (token) {
headers['Authorization'] = 'token ' + token
}
return {
protocol: _url.protocol,
host: _url.host,
port: _url.port,
path: _url.path,
headers: {
'User-Agent': 'NodeJS'
}
headers: headers
};
}
@ -68,8 +73,8 @@ function getCommitSha(repoId, repoPath) {
});
}
exports.update = function (repoId, repoPath, dest, modifyGrammar) {
var contentPath = 'https://raw.githubusercontent.com/' + repoId + '/master/' + repoPath;
exports.update = function (repoId, repoPath, dest, modifyGrammar, version = 'master') {
var contentPath = 'https://raw.githubusercontent.com/' + repoId + `/${version}/` + repoPath;
console.log('Reading from ' + contentPath);
return download(contentPath).then(function (content) {
var ext = path.extname(repoPath);

View file

@ -19,6 +19,9 @@ step "Install dependencies" \
step "Hygiene" \
npm run gulp -- hygiene
step "Monaco Editor Check" \
./node_modules/.bin/tsc -p ./src/tsconfig.monaco.json --noEmit
step "Mix in repository from vscode-distro" \
npm run gulp -- mixin

View file

@ -22,6 +22,9 @@ step "Install dependencies" \
step "Hygiene" \
npm run gulp -- hygiene
step "Monaco Editor Check" \
./node_modules/.bin/tsc -p ./src/tsconfig.monaco.json --noEmit
step "Mix in repository from vscode-distro" \
npm run gulp -- mixin

View file

@ -24,6 +24,10 @@ step "Hygiene" {
exec { & npm run gulp -- hygiene }
}
step "Monaco Editor Check" {
exec { & .\node_modules\.bin\tsc -p .\src\tsconfig.monaco.json --noEmit }
}
$env:VSCODE_MIXIN_PASSWORD = $mixinPassword
step "Mix in repository from vscode-distro" {
exec { & npm run gulp -- mixin }

View file

@ -1,7 +1,7 @@
# install node
$env:Path = $env:NVM_HOME + ";" + $env:NVM_SYMLINK + ";" + $env:Path
$NodeVersion = "8.9.1"
nvm install $NodeVersion
nvm use $NodeVersion
npm install -g yarn
# nvm install $NodeVersion
# nvm use $NodeVersion
# npm install -g yarn
$env:Path = $env:NVM_HOME + "\v" + $NodeVersion + ";" + $env:Path

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/mmims/language-batchfile/commit/40b605c75db3967a24b7015f6d3a885360b84e28",
"version": "https://github.com/mmims/language-batchfile/commit/3dd105c31484e5975144478dac1aa91d8f51e528",
"scopeName": "source.batchfile",
"name": "Batch File",
"fileTypes": [
@ -454,11 +454,15 @@
{
"begin": "\\(",
"beginCaptures": {
"0": "punctuation.section.group.begin.batchfile"
"0": {
"name": "punctuation.section.group.begin.batchfile"
}
},
"end": "\\)",
"endCaptures": {
"0": "punctuation.section.group.end.batchfile"
"0": {
"name": "punctuation.section.group.end.batchfile"
}
},
"name": "meta.group.batchfile",
"patterns": [

View file

@ -10,7 +10,8 @@
"Other"
],
"activationEvents": [
"onLanguage:json", "onLanguage:jsonc"
"onLanguage:json",
"onLanguage:jsonc"
],
"main": "./out/extension",
"scripts": {
@ -18,7 +19,7 @@
"watch": "gulp watch-extension:configuration-editing"
},
"dependencies": {
"jsonc-parser": "^0.3.1",
"jsonc-parser": "^1.0.0",
"vscode-nls": "^2.0.1"
},
"contributes": {
@ -76,4 +77,4 @@
"devDependencies": {
"@types/node": "7.0.4"
}
}
}

View file

@ -6,12 +6,10 @@
version "7.0.4"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.4.tgz#9aabc135979ded383325749f508894c662948c8b"
jsonc-parser@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-0.3.1.tgz#6ebf5c75224368d4b07ef4c26f9434e657472e95"
dependencies:
vscode-nls "^2.0.2"
jsonc-parser@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-1.0.0.tgz#ddcc864ae708e60a7a6dd36daea00172fa8d9272"
vscode-nls@^2.0.1, vscode-nls@^2.0.2:
vscode-nls@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/dotnet/csharp-tmLanguage/commit/436456ee5ce44e29cb1752c3b29f493b1de08c42",
"version": "https://github.com/dotnet/csharp-tmLanguage/commit/a334939a6493290f874264712447107bc9545835",
"name": "C#",
"scopeName": "source.cs",
"fileTypes": [
@ -935,7 +935,7 @@
"name": "punctuation.separator.colon.cs"
}
},
"end": "(?=\\{|where|;)",
"end": "(?=\\{|where|;|=>)",
"patterns": [
{
"name": "keyword.other.class.cs",
@ -2438,18 +2438,12 @@
]
},
"throw-expression": {
"begin": "(?<!\\.)\\b(throw)\\b",
"beginCaptures": {
"match": "(?<!\\.)\\b(throw)\\b",
"captures": {
"1": {
"name": "keyword.control.flow.throw.cs"
}
},
"end": "(?=;)",
"patterns": [
{
"include": "#expression"
}
]
}
},
"interpolated-string": {
"name": "string.quoted.double.cs",
@ -3055,7 +3049,7 @@
"name": "keyword.other.new.cs"
}
},
"end": "(?=\\)|;|})",
"end": "(?<=\\})",
"patterns": [
{
"include": "#initializer-expression"
@ -3087,25 +3081,13 @@
"include": "#attribute-section"
},
{
"name": "storage.modifier.cs",
"match": "\\b(ref|params|out)\\b"
},
{
"match": "\\s+([_[:alpha:]][_[:alnum:]]*)\\s*(?=[=,\\]])",
"captures": {
"1": {
"name": "entity.name.variable.parameter.cs"
}
}
},
{
"include": "#variable-initializer"
},
{
"include": "#type"
"include": "#parameter"
},
{
"include": "#punctuation-comma"
},
{
"include": "#variable-initializer"
}
]
}
@ -3132,28 +3114,34 @@
"include": "#attribute-section"
},
{
"name": "storage.modifier.cs",
"match": "\\b(ref|params|out|this)\\b"
},
{
"match": "\\b([_[:alpha:]][_[:alnum:]]*)\\s*(?=[=,)])",
"captures": {
"1": {
"name": "entity.name.variable.parameter.cs"
}
}
},
{
"include": "#variable-initializer"
},
{
"include": "#type"
"include": "#parameter"
},
{
"include": "#punctuation-comma"
},
{
"include": "#variable-initializer"
}
]
},
"parameter": {
"match": "(?x)\n(?:(?:\\b(ref|params|out|this)\\b)\\s+)?\n(?<type-name>\n (?:\n (?:ref\\s+)? # ref return\n (?:\n (?:(?<identifier>[_[:alpha:]][_[:alnum:]]*)\\s*\\:\\:\\s*)? # alias-qualification\n (?<name-and-type-args> # identifier + type arguments (if any)\n \\g<identifier>\\s*\n (?<type-args>\\s*<(?:[^<>]|\\g<type-args>)+>\\s*)?\n )\n (?:\\s*\\.\\s*\\g<name-and-type-args>)* | # Are there any more names being dotted into?\n (?<tuple>\\s*\\((?:[^\\(\\)]|\\g<tuple>)+\\))\n )\n (?:\\s*\\*\\s*)* # pointer suffix?\n (?:\\s*\\?\\s*)? # nullable suffix?\n (?:\\s*\\[(?:\\s*,\\s*)*\\]\\s*)* # array suffix?\n )\n)\\s+\n(\\g<identifier>)",
"captures": {
"1": {
"name": "storage.modifier.cs"
},
"2": {
"patterns": [
{
"include": "#type"
}
]
},
"7": {
"name": "entity.name.variable.parameter.cs"
}
}
},
"argument-list": {
"begin": "\\(",
"beginCaptures": {

View file

@ -21,7 +21,7 @@ export function activate(context: ExtensionContext) {
// The server is implemented in node
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'cssServerMain.js'));
// The debug options for the server
let debugOptions = { execArgv: ['--nolazy', '--inspect=6004'] };
let debugOptions = { execArgv: ['--nolazy', '--inspect=6044'] };
// If the extension is launch in debug mode the debug server options are use
// Otherwise the run options are used

View file

@ -8,7 +8,7 @@
"node": "*"
},
"dependencies": {
"vscode-css-languageservice": "^3.0.2",
"vscode-css-languageservice": "^3.0.3",
"vscode-languageserver": "^3.5.0"
},
"devDependencies": {

View file

@ -15,6 +15,7 @@ import { DocumentColorRequest, ServerCapabilities as CPServerCapabilities, Color
import { getCSSLanguageService, getSCSSLanguageService, getLESSLanguageService, LanguageSettings, LanguageService, Stylesheet } from 'vscode-css-languageservice';
import { getLanguageModelCache } from './languageModelCache';
import { formatError, runSafe } from './utils/errors';
export interface Settings {
css: LanguageSettings;
@ -28,6 +29,10 @@ let connection: IConnection = createConnection();
console.log = connection.console.log.bind(connection.console);
console.error = connection.console.error.bind(connection.console);
process.on('unhandledRejection', (e: any) => {
connection.console.error(formatError(`Unhandled exception`, e));
});
// Create a simple text document manager. The text document manager
// supports full document sync only
let documents: TextDocuments = new TextDocuments();
@ -122,7 +127,7 @@ function updateConfiguration(settings: Settings) {
}
let pendingValidationRequests: { [uri: string]: NodeJS.Timer } = {};
const validationDelayMs = 200;
const validationDelayMs = 500;
// The content of a text document has changed. This event is emitted
// when the text document first opened or when its content has changed.
@ -159,73 +164,95 @@ function validateTextDocument(textDocument: TextDocument): void {
let diagnostics = getLanguageService(textDocument).doValidation(textDocument, stylesheet, settings);
// Send the computed diagnostics to VSCode.
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
}, e => {
connection.console.error(formatError(`Error while validating ${textDocument.uri}`, e));
});
}
connection.onCompletion(textDocumentPosition => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).doComplete(document, textDocumentPosition.position, stylesheet)!; /* TODO: remove ! once LS has null annotations */
return runSafe(() => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).doComplete(document, textDocumentPosition.position, stylesheet)!; /* TODO: remove ! once LS has null annotations */
}, null, `Error while computing completions for ${textDocumentPosition.textDocument.uri}`);
});
connection.onHover(textDocumentPosition => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let styleSheet = stylesheets.get(document);
return getLanguageService(document).doHover(document, textDocumentPosition.position, styleSheet)!; /* TODO: remove ! once LS has null annotations */
return runSafe(() => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let styleSheet = stylesheets.get(document);
return getLanguageService(document).doHover(document, textDocumentPosition.position, styleSheet)!; /* TODO: remove ! once LS has null annotations */
}, null, `Error while computing hover for ${textDocumentPosition.textDocument.uri}`);
});
connection.onDocumentSymbol(documentSymbolParams => {
let document = documents.get(documentSymbolParams.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).findDocumentSymbols(document, stylesheet);
return runSafe(() => {
let document = documents.get(documentSymbolParams.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).findDocumentSymbols(document, stylesheet);
}, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`);
});
connection.onDefinition(documentSymbolParams => {
let document = documents.get(documentSymbolParams.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).findDefinition(document, documentSymbolParams.position, stylesheet);
return runSafe(() => {
let document = documents.get(documentSymbolParams.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).findDefinition(document, documentSymbolParams.position, stylesheet);
}, null, `Error while computing definitions for ${documentSymbolParams.textDocument.uri}`);
});
connection.onDocumentHighlight(documentSymbolParams => {
let document = documents.get(documentSymbolParams.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).findDocumentHighlights(document, documentSymbolParams.position, stylesheet);
return runSafe(() => {
let document = documents.get(documentSymbolParams.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).findDocumentHighlights(document, documentSymbolParams.position, stylesheet);
}, [], `Error while computing document highlights for ${documentSymbolParams.textDocument.uri}`);
});
connection.onReferences(referenceParams => {
let document = documents.get(referenceParams.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).findReferences(document, referenceParams.position, stylesheet);
return runSafe(() => {
let document = documents.get(referenceParams.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).findReferences(document, referenceParams.position, stylesheet);
}, [], `Error while computing references for ${referenceParams.textDocument.uri}`);
});
connection.onCodeAction(codeActionParams => {
let document = documents.get(codeActionParams.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).doCodeActions(document, codeActionParams.range, codeActionParams.context, stylesheet);
return runSafe(() => {
let document = documents.get(codeActionParams.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).doCodeActions(document, codeActionParams.range, codeActionParams.context, stylesheet);
}, [], `Error while computing code actions for ${codeActionParams.textDocument.uri}`);
});
connection.onRequest(DocumentColorRequest.type, params => {
let document = documents.get(params.textDocument.uri);
if (document) {
let stylesheet = stylesheets.get(document);
return getLanguageService(document).findDocumentColors(document, stylesheet);
}
return [];
return runSafe(() => {
let document = documents.get(params.textDocument.uri);
if (document) {
let stylesheet = stylesheets.get(document);
return getLanguageService(document).findDocumentColors(document, stylesheet);
}
return [];
}, [], `Error while computing document colors for ${params.textDocument.uri}`);
});
connection.onRequest(ColorPresentationRequest.type, params => {
let document = documents.get(params.textDocument.uri);
if (document) {
let stylesheet = stylesheets.get(document);
return getLanguageService(document).getColorPresentations(document, stylesheet, params.color, params.range);
}
return [];
return runSafe(() => {
let document = documents.get(params.textDocument.uri);
if (document) {
let stylesheet = stylesheets.get(document);
return getLanguageService(document).getColorPresentations(document, stylesheet, params.color, params.range);
}
return [];
}, [], `Error while computing color presentations for ${params.textDocument.uri}`);
});
connection.onRenameRequest(renameParameters => {
let document = documents.get(renameParameters.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).doRename(document, renameParameters.position, renameParameters.newName, stylesheet);
return runSafe(() => {
let document = documents.get(renameParameters.textDocument.uri);
let stylesheet = stylesheets.get(document);
return getLanguageService(document).doRename(document, renameParameters.position, renameParameters.newName, stylesheet);
}, null, `Error while computing renames for ${renameParameters.textDocument.uri}`);
});
// Listen on the connection

View file

@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
export function formatError(message: string, err: any): string {
if (err instanceof Error) {
let error = <Error>err;
return `${message}: ${error.message}\n${error.stack}`;
} else if (typeof err === 'string') {
return `${message}: ${err}`;
} else if (err) {
return `${message}: ${err.toString()}`;
}
return message;
}
export function runSafe<T>(func: () => Thenable<T> | T, errorVal: T, errorMessage: string): Thenable<T> | T {
try {
let t = func();
if (t instanceof Promise) {
return t.then(void 0, e => {
console.error(formatError(errorMessage, e));
return errorVal;
});
}
return t;
} catch (e) {
console.error(formatError(errorMessage, e));
return errorVal;
}
}

View file

@ -6,8 +6,7 @@
"noUnusedLocals": true,
"lib": [
"es5", "es2015.promise"
],
"strict": true
]
},
"include": [
"src/**/*"

View file

@ -6,9 +6,9 @@
version "7.0.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c"
vscode-css-languageservice@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.2.tgz#ae0c43836318455aa290c777556394d6127b8f6c"
vscode-css-languageservice@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.3.tgz#02cc4efa5335f5104e0a2f3b6920faaf59db4f7a"
dependencies:
vscode-languageserver-types "3.5.0"
vscode-nls "^2.0.1"

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/atom/language-css/commit/ec289867164a34fce48a69776b7f8dc380e3dc37",
"version": "https://github.com/atom/language-css/commit/b781e2152b677d4a38c4501de477948cb6a04f65",
"scopeName": "source.css",
"name": "CSS",
"fileTypes": [
@ -1058,7 +1058,7 @@
"name": "support.constant.text-direction.css"
},
{
"include": "#property-value"
"include": "#property-values"
}
]
},

View file

@ -314,12 +314,12 @@
"vscode": "1.0.1"
},
"dependencies": {
"@emmetio/html-matcher": "^0.3.1",
"@emmetio/html-matcher": "^0.3.3",
"@emmetio/css-parser": "ramya-rao-a/css-parser#vscode",
"@emmetio/math-expression": "^0.1.1",
"vscode-emmet-helper": "^1.1.19",
"vscode-languageserver-types": "^3.0.3",
"vscode-emmet-helper": "^1.1.20",
"vscode-languageserver-types": "^3.5.0",
"image-size": "^0.5.2",
"vscode-nls": "2.0.2"
}
}
}

View file

@ -4,7 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { Node, HtmlNode, Rule } from 'EmmetNode';
import { Node, HtmlNode, Rule, Property } from 'EmmetNode';
import { getEmmetHelper, getNode, getInnerRange, getMappingForIncludedLanguages, parseDocument, validate, getEmmetConfiguration, isStyleSheet, getEmmetMode } from './util';
const trimRegex = /[\u00a0]*[\d|#|\-|\*|\u2022]+\.?/;
@ -32,8 +32,14 @@ export function wrapWithAbbreviation(args: any) {
const abbreviationPromise = (args && args['abbreviation']) ? Promise.resolve(args['abbreviation']) : vscode.window.showInputBox({ prompt: 'Enter Abbreviation' });
const helper = getEmmetHelper();
return abbreviationPromise.then(abbreviation => {
if (!abbreviation || !abbreviation.trim() || !helper.isAbbreviationValid(syntax, abbreviation)) { return false; }
return abbreviationPromise.then(inputAbbreviation => {
if (!inputAbbreviation || !inputAbbreviation.trim() || !helper.isAbbreviationValid(syntax, inputAbbreviation)) { return false; }
let extractedResults = helper.extractAbbreviationFromText(inputAbbreviation);
if (!extractedResults) {
return false;
}
let { abbreviation, filter } = extractedResults;
let expandAbbrList: ExpandAbbreviationInput[] = [];
@ -48,7 +54,7 @@ export function wrapWithAbbreviation(args: any) {
const preceedingWhiteSpace = matches ? matches[1].length : 0;
rangeToReplace = new vscode.Range(rangeToReplace.start.line, rangeToReplace.start.character + preceedingWhiteSpace, rangeToReplace.end.line, rangeToReplace.end.character);
expandAbbrList.push({ syntax, abbreviation, rangeToReplace, textToWrap: ['\n\t$TM_SELECTED_TEXT\n'] });
expandAbbrList.push({ syntax, abbreviation, rangeToReplace, textToWrap: ['\n\t$TM_SELECTED_TEXT\n'], filter });
});
return expandAbbreviationInRange(editor, expandAbbrList, true);
@ -223,6 +229,23 @@ export function isValidLocationForEmmetAbbreviation(document: vscode.TextDocumen
return true;
}
// Fix for https://github.com/Microsoft/vscode/issues/34162
// Other than sass, stylus, we can make use of the terminator tokens to validate position
if (syntax !== 'sass' && syntax !== 'stylus' && currentNode.type === 'property') {
const propertyNode = <Property>currentNode;
if (propertyNode.terminatorToken
&& propertyNode.separator
&& position.isAfterOrEqual(propertyNode.separatorToken.end)
&& position.isBeforeOrEqual(propertyNode.terminatorToken.start)) {
return false;
}
if (!propertyNode.terminatorToken
&& propertyNode.separator
&& position.isAfterOrEqual(propertyNode.separatorToken.end)) {
return false;
}
}
// If current node is a rule or at-rule, then perform additional checks to ensure
// emmet suggestions are not provided in the rule selector
if (currentNode.type !== 'rule' && currentNode.type !== 'at-rule') {
@ -242,7 +265,10 @@ export function isValidLocationForEmmetAbbreviation(document: vscode.TextDocumen
if (currentCssNode.parent
&& (currentCssNode.parent.type === 'rule' || currentCssNode.parent.type === 'at-rule')
&& currentCssNode.selectorToken
&& position.line !== currentCssNode.selectorToken.end.line) {
&& position.line !== currentCssNode.selectorToken.end.line
&& currentCssNode.selectorToken.start.character === abbreviationRange.start.character
&& currentCssNode.selectorToken.start.line === abbreviationRange.start.line
) {
return true;
}

View file

@ -23,6 +23,12 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi
const isSyntaxMapped = mappedLanguages[document.languageId] ? true : false;
let syntax = getEmmetMode((isSyntaxMapped ? mappedLanguages[document.languageId] : document.languageId), excludedLanguages);
if (!syntax
|| emmetConfig['showExpandedAbbreviation'] === 'never'
|| ((isSyntaxMapped || syntax === 'jsx') && emmetConfig['showExpandedAbbreviation'] !== 'always')) {
return;
}
const helper = getEmmetHelper();
const extractAbbreviationResults = helper.extractAbbreviation(document, position);
if (!extractAbbreviationResults) {
@ -46,12 +52,6 @@ export class DefaultCompletionItemProvider implements vscode.CompletionItemProvi
}
}
if (!syntax
|| ((isSyntaxMapped || syntax === 'jsx')
&& emmetConfig['showExpandedAbbreviation'] !== 'always')) {
return;
}
let noiseCheckPromise: Thenable<any> = Promise.resolve();
// Fix for https://github.com/Microsoft/vscode/issues/32647

View file

@ -5,44 +5,12 @@
import 'mocha';
import * as assert from 'assert';
import { Selection, workspace, CompletionList, CancellationTokenSource, Position } from 'vscode';
import { Selection, workspace, CompletionList, CancellationTokenSource } from 'vscode';
import { withRandomFileEditor, closeAllEditors } from './testUtils';
import { expandEmmetAbbreviation, wrapWithAbbreviation, wrapIndividualLinesWithAbbreviation } from '../abbreviationActions';
import { expandEmmetAbbreviation } from '../abbreviationActions';
import { DefaultCompletionItemProvider } from '../defaultCompletionProvider';
const completionProvider = new DefaultCompletionItemProvider();
const cssContents = `
.boo {
margin: 20px 10px;
m10
background-image: url('tryme.png');
m10
}
.boo .hoo {
margin: 10px;
ind
}
`;
const scssContents = `
.boo {
margin: 10px;
p10
.hoo {
p20
}
}
@include b(alert) {
margin: 10px;
p30
@include b(alert) {
p40
}
}
`;
const htmlContents = `
<body class="header">
@ -67,53 +35,6 @@ const htmlContents = `
</body>
`;
const htmlContentsForWrapTests = `
<ul class="nav main">
<li class="item1">img</li>
<li class="item2">$hithere</li>
</ul>
`;
const wrapBlockElementExpected = `
<ul class="nav main">
<div>
<li class="item1">img</li>
</div>
<div>
<li class="item2">$hithere</li>
</div>
</ul>
`;
const wrapInlineElementExpected = `
<ul class="nav main">
<span><li class="item1">img</li></span>
<span><li class="item2">$hithere</li></span>
</ul>
`;
const wrapSnippetExpected = `
<ul class="nav main">
<a href=""><li class="item1">img</li></a>
<a href=""><li class="item2">$hithere</li></a>
</ul>
`;
const wrapMultiLineAbbrExpected = `
<ul class="nav main">
<ul>
<li>
<li class="item1">img</li>
</li>
</ul>
<ul>
<li>
<li class="item2">$hithere</li>
</li>
</ul>
</ul>
`;
suite('Tests for Expand Abbreviations (HTML)', () => {
teardown(() => {
// Reset config and close all editors
@ -360,277 +281,6 @@ suite('Tests for Expand Abbreviations (HTML)', () => {
});
suite('Tests for Expand Abbreviations (CSS)', () => {
teardown(closeAllEditors);
test('Expand abbreviation (CSS)', () => {
return withRandomFileEditor(cssContents, 'css', (editor, doc) => {
editor.selections = [new Selection(3, 1, 3, 4), new Selection(5, 1, 5, 4)];
return expandEmmetAbbreviation(null).then(() => {
assert.equal(editor.document.getText(), cssContents.replace(/m10/g, 'margin: 10px;'));
return Promise.resolve();
});
});
});
test('Expand abbreviation in completion list (CSS)', () => {
const abbreviation = 'm10';
const expandedText = 'margin: 10px;';
return withRandomFileEditor(cssContents, 'css', (editor, doc) => {
editor.selection = new Selection(3, 1, 3, 4);
const cancelSrc = new CancellationTokenSource();
const completionPromise1 = completionProvider.provideCompletionItems(editor.document, new Position(3, 4), cancelSrc.token);
const completionPromise2 = completionProvider.provideCompletionItems(editor.document, new Position(5, 4), cancelSrc.token);
if (!completionPromise1 || !completionPromise2) {
assert.equal(1, 2, `Problem with expanding m10`);
return Promise.resolve();
}
const callBack = (completionList: CompletionList) => {
if (!completionList.items || !completionList.items.length) {
assert.equal(1, 2, `Problem with expanding m10`);
return;
}
const emmetCompletionItem = completionList.items[0];
assert.equal(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`);
assert.equal((<string>emmetCompletionItem.documentation || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);
assert.equal(emmetCompletionItem.filterText, abbreviation, `FilterText of completion item doesnt match.`);
};
return Promise.all<CompletionList>([completionPromise1, completionPromise2]).then(([result1, result2]) => {
callBack(result1);
callBack(result2);
return Promise.resolve();
});
});
});
test('Expand abbreviation (SCSS)', () => {
return withRandomFileEditor(scssContents, 'scss', (editor, doc) => {
editor.selections = [
new Selection(3, 4, 3, 4),
new Selection(5, 5, 5, 5),
new Selection(11, 4, 11, 4),
new Selection(14, 5, 14, 5)
];
return expandEmmetAbbreviation(null).then(() => {
assert.equal(editor.document.getText(), scssContents.replace(/p(\d\d)/g, 'padding: $1px;'));
return Promise.resolve();
});
});
});
test('Expand abbreviation in completion list (SCSS)', () => {
return withRandomFileEditor(scssContents, 'scss', (editor, doc) => {
editor.selection = new Selection(3, 4, 3, 4);
const cancelSrc = new CancellationTokenSource();
const completionPromise1 = completionProvider.provideCompletionItems(editor.document, new Position(3, 4), cancelSrc.token);
const completionPromise2 = completionProvider.provideCompletionItems(editor.document, new Position(5, 5), cancelSrc.token);
const completionPromise3 = completionProvider.provideCompletionItems(editor.document, new Position(11, 4), cancelSrc.token);
const completionPromise4 = completionProvider.provideCompletionItems(editor.document, new Position(14, 5), cancelSrc.token);
if (!completionPromise1 || !completionPromise2 || !completionPromise3 || !completionPromise4) {
assert.equal(1, 2, `Problem with expanding padding abbreviations`);
return Promise.resolve();
}
const callBack = (completionList: CompletionList, abbreviation, expandedText) => {
if (!completionList.items || !completionList.items.length) {
assert.equal(1, 2, `Problem with expanding m10`);
return;
}
const emmetCompletionItem = completionList.items[0];
assert.equal(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`);
assert.equal((<string>emmetCompletionItem.documentation || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);
assert.equal(emmetCompletionItem.filterText, abbreviation, `FilterText of completion item doesnt match.`);
};
return Promise.all<CompletionList>([completionPromise1, completionPromise2, completionPromise3, completionPromise4]).then(([result1, result2, result3, result4]) => {
callBack(result1, 'p10', 'padding: 10px;');
callBack(result2, 'p20', 'padding: 20px;');
callBack(result3, 'p30', 'padding: 30px;');
callBack(result4, 'p40', 'padding: 40px;');
return Promise.resolve();
});
});
});
test('Invalid locations for abbreviations in scss', () => {
const scssContentsNoExpand = `
m10
.boo {
margin: 10px;
.hoo {
background:
}
}
`;
return withRandomFileEditor(scssContentsNoExpand, 'scss', (editor, doc) => {
editor.selections = [
new Selection(1, 3, 1, 3), // outside rule
new Selection(5, 15, 5, 15) // in the value part of property value
];
return expandEmmetAbbreviation(null).then(() => {
assert.equal(editor.document.getText(), scssContentsNoExpand);
return Promise.resolve();
});
});
});
test('Invalid locations for abbreviations in scss in completion list', () => {
const scssContentsNoExpand = `
m10
.boo {
margin: 10px;
.hoo {
background:
}
}
`;
return withRandomFileEditor(scssContentsNoExpand, 'scss', (editor, doc) => {
editor.selection = new Selection(1, 3, 1, 3); // outside rule
const cancelSrc = new CancellationTokenSource();
let completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token);
if (completionPromise) {
assert.equal(1, 2, `m10 gets expanded in invalid location (outside rule)`);
}
editor.selection = new Selection(5, 15, 5, 15); // in the value part of property value
completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token);
if (completionPromise) {
return completionPromise.then((completionList: CompletionList) => {
if (completionList && completionList.items && completionList.items.length > 0) {
assert.equal(1, 2, `m10 gets expanded in invalid location (n the value part of property value)`);
}
return Promise.resolve();
});
}
return Promise.resolve();
});
});
});
suite('Tests for Wrap with Abbreviations', () => {
teardown(closeAllEditors);
const multiCursors = [new Selection(2, 6, 2, 6), new Selection(3, 6, 3, 6)];
const multiCursorsWithSelection = [new Selection(2, 2, 2, 28), new Selection(3, 2, 3, 33)];
const multiCursorsWithFullLineSelection = [new Selection(2, 0, 2, 28), new Selection(3, 0, 3, 33)];
test('Wrap with block element using multi cursor', () => {
return testWrapWithAbbreviation(multiCursors, 'div', wrapBlockElementExpected);
});
test('Wrap with inline element using multi cursor', () => {
return testWrapWithAbbreviation(multiCursors, 'span', wrapInlineElementExpected);
});
test('Wrap with snippet using multi cursor', () => {
return testWrapWithAbbreviation(multiCursors, 'a', wrapSnippetExpected);
});
test('Wrap with multi line abbreviation using multi cursor', () => {
return testWrapWithAbbreviation(multiCursors, 'ul>li', wrapMultiLineAbbrExpected);
});
test('Wrap with block element using multi cursor selection', () => {
return testWrapWithAbbreviation(multiCursorsWithSelection, 'div', wrapBlockElementExpected);
});
test('Wrap with inline element using multi cursor selection', () => {
return testWrapWithAbbreviation(multiCursorsWithSelection, 'span', wrapInlineElementExpected);
});
test('Wrap with snippet using multi cursor selection', () => {
return testWrapWithAbbreviation(multiCursorsWithSelection, 'a', wrapSnippetExpected);
});
test('Wrap with multi line abbreviation using multi cursor selection', () => {
return testWrapWithAbbreviation(multiCursorsWithSelection, 'ul>li', wrapMultiLineAbbrExpected);
});
test('Wrap with block element using multi cursor full line selection', () => {
return testWrapWithAbbreviation(multiCursorsWithFullLineSelection, 'div', wrapBlockElementExpected);
});
test('Wrap with inline element using multi cursor full line selection', () => {
return testWrapWithAbbreviation(multiCursorsWithFullLineSelection, 'span', wrapInlineElementExpected);
});
test('Wrap with snippet using multi cursor full line selection', () => {
return testWrapWithAbbreviation(multiCursorsWithFullLineSelection, 'a', wrapSnippetExpected);
});
test('Wrap with multi line abbreviation using multi cursor full line selection', () => {
return testWrapWithAbbreviation(multiCursorsWithFullLineSelection, 'ul>li', wrapMultiLineAbbrExpected);
});
test('Wrap individual lines with abbreviation', () => {
const contents = `
<ul class="nav main">
<li class="item1">img</li>
<li class="item2">hi.there</li>
</ul>
`;
const wrapIndividualLinesExpected = `
<ul class="nav main">
<ul>
<li class="hello1"><li class="item1">img</li></li>
<li class="hello2"><li class="item2">hi.there</li></li>
</ul>
</ul>
`;
return withRandomFileEditor(contents, 'html', (editor, doc) => {
editor.selections = [new Selection(2, 2, 3, 33)];
const promise = wrapIndividualLinesWithAbbreviation({ abbreviation: 'ul>li.hello$*' });
if (!promise) {
assert.equal(1, 2, 'Wrap Individual Lines with Abbreviation returned udnefined.');
return Promise.resolve();
}
return promise.then(() => {
assert.equal(editor.document.getText(), wrapIndividualLinesExpected);
return Promise.resolve();
});
});
});
test('Wrap individual lines with abbreviation and trim', () => {
const contents = `
<ul class="nav main">
lorem ipsum
lorem ipsum
</ul>
`;
const wrapIndividualLinesExpected = `
<ul class="nav main">
<ul>
<li class="hello1">lorem ipsum</li>
<li class="hello2">lorem ipsum</li>
</ul>
</ul>
`;
return withRandomFileEditor(contents, 'html', (editor, doc) => {
editor.selections = [new Selection(2, 3, 3, 16)];
const promise = wrapIndividualLinesWithAbbreviation({ abbreviation: 'ul>li.hello$*|t' });
if (!promise) {
assert.equal(1, 2, 'Wrap Individual Lines with Abbreviation returned udnefined.');
return Promise.resolve();
}
return promise.then(() => {
assert.equal(editor.document.getText(), wrapIndividualLinesExpected);
return Promise.resolve();
});
});
});
});
suite('Tests for jsx, xml and xsl', () => {
teardown(closeAllEditors);
@ -720,18 +370,3 @@ function testHtmlCompletionProvider(selection: Selection, abbreviation: string,
});
}
function testWrapWithAbbreviation(selections: Selection[], abbreviation: string, expectedContents: string): Thenable<any> {
return withRandomFileEditor(htmlContentsForWrapTests, 'html', (editor, doc) => {
editor.selections = selections;
const promise = wrapWithAbbreviation({ abbreviation });
if (!promise) {
assert.equal(1, 2, 'Wrap with Abbreviation returned udnefined.');
return Promise.resolve();
}
return promise.then(() => {
assert.equal(editor.document.getText(), expectedContents);
return Promise.resolve();
});
});
}

View file

@ -0,0 +1,301 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'mocha';
import * as assert from 'assert';
import { Selection, CompletionList, CancellationTokenSource, Position } from 'vscode';
import { withRandomFileEditor, closeAllEditors } from './testUtils';
import { expandEmmetAbbreviation } from '../abbreviationActions';
import { DefaultCompletionItemProvider } from '../defaultCompletionProvider';
const completionProvider = new DefaultCompletionItemProvider();
const cssContents = `
.boo {
margin: 20px 10px;
m10
background-image: url('tryme.png');
m10
}
.boo .hoo {
margin: 10px;
ind
}
`;
const scssContents = `
.boo {
margin: 10px;
p10
.hoo {
p20
}
}
@include b(alert) {
margin: 10px;
p30
@include b(alert) {
p40
}
}
.foo {
margin: 10px;
margin: a
.hoo {
color: #000;
}
}
`;
suite('Tests for Expand Abbreviations (CSS)', () => {
teardown(closeAllEditors);
test('Expand abbreviation (CSS)', () => {
return withRandomFileEditor(cssContents, 'css', (editor, doc) => {
editor.selections = [new Selection(3, 1, 3, 4), new Selection(5, 1, 5, 4)];
return expandEmmetAbbreviation(null).then(() => {
assert.equal(editor.document.getText(), cssContents.replace(/m10/g, 'margin: 10px;'));
return Promise.resolve();
});
});
});
test('Skip when typing property values when there is a property in the next line (CSS)', () => {
const testContent = `
.foo {
margin: a
margin: 10px;
}
`;
return withRandomFileEditor(testContent, 'css', (editor, doc) => {
editor.selection = new Selection(2, 10, 2, 10);
return expandEmmetAbbreviation(null).then(() => {
assert.equal(editor.document.getText(), testContent);
const cancelSrc = new CancellationTokenSource();
const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(2, 10), cancelSrc.token);
if (completionPromise) {
assert.equal(1, 2, `Invalid completion at property value`);
}
return Promise.resolve();
});
});
});
test('Skip when typing property values when there is a property in the previous line (CSS)', () => {
const testContent = `
.foo {
margin: 10px;
margin: a
}
`;
return withRandomFileEditor(testContent, 'css', (editor, doc) => {
editor.selection = new Selection(3, 10, 3, 10);
return expandEmmetAbbreviation(null).then(() => {
assert.equal(editor.document.getText(), testContent);
const cancelSrc = new CancellationTokenSource();
const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(3, 10), cancelSrc.token);
if (completionPromise) {
assert.equal(1, 2, `Invalid completion at property value`);
}
return Promise.resolve();
});
});
});
test('Skip when typing property values when it is the only property in the rule (CSS)', () => {
const testContent = `
.foo {
margin: a
}
`;
return withRandomFileEditor(testContent, 'css', (editor, doc) => {
editor.selection = new Selection(2, 10, 2, 10);
return expandEmmetAbbreviation(null).then(() => {
assert.equal(editor.document.getText(), testContent);
const cancelSrc = new CancellationTokenSource();
const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(2, 10), cancelSrc.token);
if (completionPromise) {
assert.equal(1, 2, `Invalid completion at property value`);
}
return Promise.resolve();
});
});
});
test('Expand abbreviation in completion list (CSS)', () => {
const abbreviation = 'm10';
const expandedText = 'margin: 10px;';
return withRandomFileEditor(cssContents, 'css', (editor, doc) => {
editor.selection = new Selection(3, 1, 3, 4);
const cancelSrc = new CancellationTokenSource();
const completionPromise1 = completionProvider.provideCompletionItems(editor.document, new Position(3, 4), cancelSrc.token);
const completionPromise2 = completionProvider.provideCompletionItems(editor.document, new Position(5, 4), cancelSrc.token);
if (!completionPromise1 || !completionPromise2) {
assert.equal(1, 2, `Problem with expanding m10`);
return Promise.resolve();
}
const callBack = (completionList: CompletionList) => {
if (!completionList.items || !completionList.items.length) {
assert.equal(1, 2, `Problem with expanding m10`);
return;
}
const emmetCompletionItem = completionList.items[0];
assert.equal(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`);
assert.equal((<string>emmetCompletionItem.documentation || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);
assert.equal(emmetCompletionItem.filterText, abbreviation, `FilterText of completion item doesnt match.`);
};
return Promise.all<CompletionList>([completionPromise1, completionPromise2]).then(([result1, result2]) => {
callBack(result1);
callBack(result2);
return Promise.resolve();
});
});
});
test('Expand abbreviation (SCSS)', () => {
return withRandomFileEditor(scssContents, 'scss', (editor, doc) => {
editor.selections = [
new Selection(3, 4, 3, 4),
new Selection(5, 5, 5, 5),
new Selection(11, 4, 11, 4),
new Selection(14, 5, 14, 5)
];
return expandEmmetAbbreviation(null).then(() => {
assert.equal(editor.document.getText(), scssContents.replace(/p(\d\d)/g, 'padding: $1px;'));
return Promise.resolve();
});
});
});
test('Expand abbreviation in completion list (SCSS)', () => {
return withRandomFileEditor(scssContents, 'scss', (editor, doc) => {
editor.selection = new Selection(3, 4, 3, 4);
const cancelSrc = new CancellationTokenSource();
const completionPromise1 = completionProvider.provideCompletionItems(editor.document, new Position(3, 4), cancelSrc.token);
const completionPromise2 = completionProvider.provideCompletionItems(editor.document, new Position(5, 5), cancelSrc.token);
const completionPromise3 = completionProvider.provideCompletionItems(editor.document, new Position(11, 4), cancelSrc.token);
const completionPromise4 = completionProvider.provideCompletionItems(editor.document, new Position(14, 5), cancelSrc.token);
if (!completionPromise1) {
assert.equal(1, 2, `Problem with expanding padding abbreviations at line 3 col 4`);
}
if (!completionPromise2) {
assert.equal(1, 2, `Problem with expanding padding abbreviations at line 5 col 5`);
}
if (!completionPromise3) {
assert.equal(1, 2, `Problem with expanding padding abbreviations at line 11 col 4`);
}
if (!completionPromise4) {
assert.equal(1, 2, `Problem with expanding padding abbreviations at line 14 col 5`);
}
if (!completionPromise1 || !completionPromise2 || !completionPromise3 || !completionPromise4) {
return Promise.resolve();
}
const callBack = (completionList: CompletionList, abbreviation, expandedText) => {
if (!completionList.items || !completionList.items.length) {
assert.equal(1, 2, `Problem with expanding m10`);
return;
}
const emmetCompletionItem = completionList.items[0];
assert.equal(emmetCompletionItem.label, expandedText, `Label of completion item doesnt match.`);
assert.equal((<string>emmetCompletionItem.documentation || '').replace(/\|/g, ''), expandedText, `Docs of completion item doesnt match.`);
assert.equal(emmetCompletionItem.filterText, abbreviation, `FilterText of completion item doesnt match.`);
};
return Promise.all<CompletionList>([completionPromise1, completionPromise2, completionPromise3, completionPromise4]).then(([result1, result2, result3, result4]) => {
callBack(result1, 'p10', 'padding: 10px;');
callBack(result2, 'p20', 'padding: 20px;');
callBack(result3, 'p30', 'padding: 30px;');
callBack(result4, 'p40', 'padding: 40px;');
return Promise.resolve();
});
});
});
test('Invalid locations for abbreviations in scss', () => {
const scssContentsNoExpand = `
m10
.boo {
margin: 10px;
.hoo {
background:
}
}
`;
return withRandomFileEditor(scssContentsNoExpand, 'scss', (editor, doc) => {
editor.selections = [
new Selection(1, 3, 1, 3), // outside rule
new Selection(5, 15, 5, 15) // in the value part of property value
];
return expandEmmetAbbreviation(null).then(() => {
assert.equal(editor.document.getText(), scssContentsNoExpand);
return Promise.resolve();
});
});
});
test('Invalid locations for abbreviations in scss in completion list', () => {
const scssContentsNoExpand = `
m10
.boo {
margin: 10px;
.hoo {
background:
}
}
`;
return withRandomFileEditor(scssContentsNoExpand, 'scss', (editor, doc) => {
editor.selection = new Selection(1, 3, 1, 3); // outside rule
const cancelSrc = new CancellationTokenSource();
let completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token);
if (completionPromise) {
assert.equal(1, 2, `m10 gets expanded in invalid location (outside rule)`);
}
editor.selection = new Selection(5, 15, 5, 15); // in the value part of property value
completionPromise = completionProvider.provideCompletionItems(editor.document, editor.selection.active, cancelSrc.token);
if (completionPromise) {
return completionPromise.then((completionList: CompletionList) => {
if (completionList && completionList.items && completionList.items.length > 0) {
assert.equal(1, 2, `m10 gets expanded in invalid location (n the value part of property value)`);
}
return Promise.resolve();
});
}
return Promise.resolve();
});
});
});
test('Skip when typing property values when there is a nested rule in the next line (SCSS)', () => {
return withRandomFileEditor(scssContents, 'scss', (editor, doc) => {
editor.selection = new Selection(19, 10, 19, 10);
return expandEmmetAbbreviation(null).then(() => {
assert.equal(editor.document.getText(), scssContents);
const cancelSrc = new CancellationTokenSource();
const completionPromise = completionProvider.provideCompletionItems(editor.document, new Position(19, 10), cancelSrc.token);
if (completionPromise) {
assert.equal(1, 2, `Invalid completion at property value`);
}
return Promise.resolve();
});
});
});

View file

@ -0,0 +1,250 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import 'mocha';
import * as assert from 'assert';
import { Selection } from 'vscode';
import { withRandomFileEditor, closeAllEditors } from './testUtils';
import { wrapWithAbbreviation, wrapIndividualLinesWithAbbreviation } from '../abbreviationActions';
const htmlContentsForWrapTests = `
<ul class="nav main">
<li class="item1">img</li>
<li class="item2">$hithere</li>
</ul>
`;
const wrapBlockElementExpected = `
<ul class="nav main">
<div>
<li class="item1">img</li>
</div>
<div>
<li class="item2">$hithere</li>
</div>
</ul>
`;
const wrapInlineElementExpected = `
<ul class="nav main">
<span><li class="item1">img</li></span>
<span><li class="item2">$hithere</li></span>
</ul>
`;
const wrapSnippetExpected = `
<ul class="nav main">
<a href=""><li class="item1">img</li></a>
<a href=""><li class="item2">$hithere</li></a>
</ul>
`;
const wrapMultiLineAbbrExpected = `
<ul class="nav main">
<ul>
<li>
<li class="item1">img</li>
</li>
</ul>
<ul>
<li>
<li class="item2">$hithere</li>
</li>
</ul>
</ul>
`;
suite('Tests for Wrap with Abbreviations', () => {
teardown(closeAllEditors);
const multiCursors = [new Selection(2, 6, 2, 6), new Selection(3, 6, 3, 6)];
const multiCursorsWithSelection = [new Selection(2, 2, 2, 28), new Selection(3, 2, 3, 33)];
const multiCursorsWithFullLineSelection = [new Selection(2, 0, 2, 28), new Selection(3, 0, 3, 33)];
test('Wrap with block element using multi cursor', () => {
return testWrapWithAbbreviation(multiCursors, 'div', wrapBlockElementExpected);
});
test('Wrap with inline element using multi cursor', () => {
return testWrapWithAbbreviation(multiCursors, 'span', wrapInlineElementExpected);
});
test('Wrap with snippet using multi cursor', () => {
return testWrapWithAbbreviation(multiCursors, 'a', wrapSnippetExpected);
});
test('Wrap with multi line abbreviation using multi cursor', () => {
return testWrapWithAbbreviation(multiCursors, 'ul>li', wrapMultiLineAbbrExpected);
});
test('Wrap with block element using multi cursor selection', () => {
return testWrapWithAbbreviation(multiCursorsWithSelection, 'div', wrapBlockElementExpected);
});
test('Wrap with inline element using multi cursor selection', () => {
return testWrapWithAbbreviation(multiCursorsWithSelection, 'span', wrapInlineElementExpected);
});
test('Wrap with snippet using multi cursor selection', () => {
return testWrapWithAbbreviation(multiCursorsWithSelection, 'a', wrapSnippetExpected);
});
test('Wrap with multi line abbreviation using multi cursor selection', () => {
return testWrapWithAbbreviation(multiCursorsWithSelection, 'ul>li', wrapMultiLineAbbrExpected);
});
test('Wrap with block element using multi cursor full line selection', () => {
return testWrapWithAbbreviation(multiCursorsWithFullLineSelection, 'div', wrapBlockElementExpected);
});
test('Wrap with inline element using multi cursor full line selection', () => {
return testWrapWithAbbreviation(multiCursorsWithFullLineSelection, 'span', wrapInlineElementExpected);
});
test('Wrap with snippet using multi cursor full line selection', () => {
return testWrapWithAbbreviation(multiCursorsWithFullLineSelection, 'a', wrapSnippetExpected);
});
test('Wrap with multi line abbreviation using multi cursor full line selection', () => {
return testWrapWithAbbreviation(multiCursorsWithFullLineSelection, 'ul>li', wrapMultiLineAbbrExpected);
});
test('Wrap with abbreviation and comment filter', () => {
const contents = `
<ul class="nav main">
line
</ul>
`;
const expectedContents = `
<ul class="nav main">
<li class="hello">
line
</li>
<!-- /.hello -->
</ul>
`;
return withRandomFileEditor(contents, 'html', (editor, doc) => {
editor.selections = [new Selection(2, 0, 2, 0)];
const promise = wrapWithAbbreviation({ abbreviation: 'li.hello|c' });
if (!promise) {
assert.equal(1, 2, 'Wrap returned udnefined instead of promise.');
return Promise.resolve();
}
return promise.then(() => {
assert.equal(editor.document.getText(), expectedContents);
return Promise.resolve();
});
});
});
test('Wrap individual lines with abbreviation', () => {
const contents = `
<ul class="nav main">
<li class="item1">img</li>
<li class="item2">hi.there</li>
</ul>
`;
const wrapIndividualLinesExpected = `
<ul class="nav main">
<ul>
<li class="hello1"><li class="item1">img</li></li>
<li class="hello2"><li class="item2">hi.there</li></li>
</ul>
</ul>
`;
return withRandomFileEditor(contents, 'html', (editor, doc) => {
editor.selections = [new Selection(2, 2, 3, 33)];
const promise = wrapIndividualLinesWithAbbreviation({ abbreviation: 'ul>li.hello$*' });
if (!promise) {
assert.equal(1, 2, 'Wrap Individual Lines with Abbreviation returned udnefined.');
return Promise.resolve();
}
return promise.then(() => {
assert.equal(editor.document.getText(), wrapIndividualLinesExpected);
return Promise.resolve();
});
});
});
test('Wrap individual lines with abbreviation with comment filter', () => {
const contents = `
<ul class="nav main">
<li class="item1">img</li>
<li class="item2">hi.there</li>
</ul>
`;
const wrapIndividualLinesExpected = `
<ul class="nav main">
<ul>
<li class="hello"><li class="item1">img</li></li>
<!-- /.hello -->
<li class="hello"><li class="item2">hi.there</li></li>
<!-- /.hello -->
</ul>
</ul>
`;
return withRandomFileEditor(contents, 'html', (editor, doc) => {
editor.selections = [new Selection(2, 2, 3, 33)];
const promise = wrapIndividualLinesWithAbbreviation({ abbreviation: 'ul>li.hello*|c' });
if (!promise) {
assert.equal(1, 2, 'Wrap Individual Lines with Abbreviation returned udnefined.');
return Promise.resolve();
}
return promise.then(() => {
assert.equal(editor.document.getText(), wrapIndividualLinesExpected);
return Promise.resolve();
});
});
});
test('Wrap individual lines with abbreviation and trim', () => {
const contents = `
<ul class="nav main">
lorem ipsum
lorem ipsum
</ul>
`;
const wrapIndividualLinesExpected = `
<ul class="nav main">
<ul>
<li class="hello1">lorem ipsum</li>
<li class="hello2">lorem ipsum</li>
</ul>
</ul>
`;
return withRandomFileEditor(contents, 'html', (editor, doc) => {
editor.selections = [new Selection(2, 3, 3, 16)];
const promise = wrapIndividualLinesWithAbbreviation({ abbreviation: 'ul>li.hello$*|t' });
if (!promise) {
assert.equal(1, 2, 'Wrap Individual Lines with Abbreviation returned udnefined.');
return Promise.resolve();
}
return promise.then(() => {
assert.equal(editor.document.getText(), wrapIndividualLinesExpected);
return Promise.resolve();
});
});
});
});
function testWrapWithAbbreviation(selections: Selection[], abbreviation: string, expectedContents: string): Thenable<any> {
return withRandomFileEditor(htmlContentsForWrapTests, 'html', (editor, doc) => {
editor.selections = selections;
const promise = wrapWithAbbreviation({ abbreviation });
if (!promise) {
assert.equal(1, 2, 'Wrap with Abbreviation returned udnefined.');
return Promise.resolve();
}
return promise.then(() => {
assert.equal(editor.document.getText(), expectedContents);
return Promise.resolve();
});
});
}

View file

@ -68,9 +68,10 @@ declare module 'EmmetNode' {
export interface Property extends CssNode {
valueToken: Token
separator: Token
separator: string
parent: Rule
terminatorToken: Token
separatorToken: Token
value: string
}

View file

@ -13,9 +13,9 @@
version "0.1.3"
resolved "https://registry.yarnpkg.com/@emmetio/extract-abbreviation/-/extract-abbreviation-0.1.3.tgz#dc00bf488ddf86a2a82ca95fb2ccb575bd832f68"
"@emmetio/html-matcher@^0.3.1":
version "0.3.2"
resolved "https://registry.yarnpkg.com/@emmetio/html-matcher/-/html-matcher-0.3.2.tgz#efe0023e97191de1639f01fdcf0a198b588d3624"
"@emmetio/html-matcher@^0.3.3":
version "0.3.3"
resolved "https://registry.yarnpkg.com/@emmetio/html-matcher/-/html-matcher-0.3.3.tgz#0bbdadc0882e185950f03737dc6dbf8f7bd90728"
dependencies:
"@emmetio/stream-reader" "^2.0.0"
"@emmetio/stream-reader-utils" "^0.1.0"
@ -2048,9 +2048,9 @@ vinyl@~2.0.1:
remove-trailing-separator "^1.0.1"
replace-ext "^1.0.0"
vscode-emmet-helper@^1.1.19:
version "1.1.19"
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.1.19.tgz#e5b607076171555c6be3655a8eb11c17f980b2dd"
vscode-emmet-helper@^1.1.20:
version "1.1.20"
resolved "https://registry.yarnpkg.com/vscode-emmet-helper/-/vscode-emmet-helper-1.1.20.tgz#7523dc7f635f74e4becc44d4e519a9db5055a023"
dependencies:
"@emmetio/extract-abbreviation" "^0.1.1"
vscode-languageserver-types "^3.0.3"
@ -2059,6 +2059,10 @@ vscode-languageserver-types@^3.0.3:
version "3.3.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.3.0.tgz#8964dc7c2247536fbefd2d6836bf3febac80dd00"
vscode-languageserver-types@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-types/-/vscode-languageserver-types-3.5.0.tgz#e48d79962f0b8e02de955e3f524908e2b19c0374"
vscode-nls@2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"

View file

@ -20,7 +20,7 @@
"watch": "gulp watch-extension:extension-editing"
},
"dependencies": {
"jsonc-parser": "^0.3.1",
"jsonc-parser": "^1.0.0",
"markdown-it": "^8.3.1",
"parse5": "^3.0.2",
"vscode-nls": "^2.0.1"

View file

@ -20,11 +20,9 @@ entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
jsonc-parser@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-0.3.1.tgz#6ebf5c75224368d4b07ef4c26f9434e657472e95"
dependencies:
vscode-nls "^2.0.2"
jsonc-parser@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-1.0.0.tgz#ddcc864ae708e60a7a6dd36daea00172fa8d9272"
linkify-it@^2.0.0:
version "2.0.3"
@ -60,6 +58,6 @@ uc.micro@^1.0.1, uc.micro@^1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/uc.micro/-/uc.micro-1.0.3.tgz#7ed50d5e0f9a9fb0a573379259f2a77458d50192"
vscode-nls@^2.0.1, vscode-nls@^2.0.2:
vscode-nls@^2.0.1:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"

View file

@ -68,6 +68,15 @@
"dark": "resources/icons/dark/open-file.svg"
}
},
{
"command": "git.openFile2",
"title": "%command.openFile%",
"category": "Git",
"icon": {
"light": "resources/icons/light/open-file-mono.svg",
"dark": "resources/icons/dark/open-file-mono.svg"
}
},
{
"command": "git.openHEADFile",
"title": "%command.openHEADFile%",
@ -369,6 +378,10 @@
"command": "git.revertChange",
"when": "false"
},
{
"command": "git.openFile2",
"when": "false"
},
{
"command": "git.unstage",
"when": "gitOpenRepositoryCount != 0"
@ -701,11 +714,21 @@
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "1_modification"
},
{
"command": "git.openFile",
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "navigation"
},
{
"command": "git.stage",
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "inline"
},
{
"command": "git.openFile2",
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "inline0"
},
{
"command": "git.openChange",
"when": "scmProvider == git && scmResourceGroup == index",
@ -731,6 +754,11 @@
"when": "scmProvider == git && scmResourceGroup == index",
"group": "inline"
},
{
"command": "git.openFile2",
"when": "scmProvider == git && scmResourceGroup == index",
"group": "inline0"
},
{
"command": "git.openChange",
"when": "scmProvider == git && scmResourceGroup == workingTree",
@ -766,6 +794,11 @@
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "inline"
},
{
"command": "git.openFile2",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "inline0"
},
{
"command": "git.ignore",
"when": "scmProvider == git && scmResourceGroup == workingTree",
@ -828,6 +861,11 @@
"default": null,
"isExecutable": true
},
"git.autoRepositoryDetection": {
"type": "boolean",
"description": "%config.autoRepositoryDetection%",
"default": true
},
"git.autorefresh": {
"type": "boolean",
"description": "%config.autorefresh%",
@ -946,6 +984,15 @@
"dark": "#6c6cc4",
"highContrast": "#6c6cc4"
}
},
{
"id": "gitDecoration.submoduleResourceForeground",
"description": "%colors.submodule%",
"defaults": {
"light": "#1258a7",
"dark": "#8db9e2",
"highContrast": "#8db9e2"
}
}
]
},
@ -954,13 +1001,15 @@
"file-type": "^7.2.0",
"iconv-lite": "0.4.19",
"vscode-extension-telemetry": "0.0.8",
"vscode-nls": "2.0.2"
"vscode-nls": "2.0.2",
"which": "^1.3.0"
},
"devDependencies": {
"@types/byline": "4.2.31",
"@types/file-type": "^5.2.1",
"@types/mocha": "2.2.43",
"@types/node": "7.0.43",
"@types/which": "^1.0.28",
"mocha": "^3.2.0"
}
}

View file

@ -49,6 +49,7 @@
"command.stashPopLatest": "Pop Latest Stash",
"config.enabled": "Whether git is enabled",
"config.path": "Path to the git executable",
"config.autoRepositoryDetection": "Whether repositories should be automatically detected",
"config.autorefresh": "Whether auto refreshing is enabled",
"config.autofetch": "Whether auto fetching is enabled",
"config.enableLongCommitWarning": "Whether long commit messages should be warned about",
@ -67,5 +68,6 @@
"colors.deleted": "Color for deleted resources.",
"colors.untracked": "Color for untracked resources.",
"colors.ignored": "Color for ignored resources.",
"colors.conflict": "Color for resources with conflicts."
"colors.conflict": "Color for resources with conflicts.",
"colors.submodule": "Color for submodule resources."
}

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon fill="#C5C5C5" points="10,2 7.414,2 8.414,3 9,3 9,3.586 9,4 9,4.414 9,6 12,6 12,13 4,13 4,8 3,8 3,14 13,14 13,5"/><polygon fill="#C5C5C5" points="5,1 3,1 5,3 1,3 1,5 5,5 3,7 5,7 8,4"/></svg>

After

Width:  |  Height:  |  Size: 262 B

View file

@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon fill="#424242" points="10,2 7.414,2 8.414,3 9,3 9,3.586 9,4 9,4.414 9,6 12,6 12,13 4,13 4,8 3,8 3,14 13,14 13,5"/><polygon fill="#424242" points="5,1 3,1 5,3 1,3 1,5 5,5 3,7 5,7 8,4"/></svg>

After

Width:  |  Height:  |  Size: 262 B

View file

@ -1,3 +1 @@
<!DOCTYPE svg PUBLIC "-//W3C//DTD SVG 1.1//EN" "http://www.w3.org/Graphics/SVG/1.1/DTD/svg11.dtd" [
<!ENTITY ns_flows "http://ns.adobe.com/Flows/1.0/">
]><svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon fill="#656565" points="10,2 7.414,2 8.414,3 9,3 9,3.586 9,4 9,4.414 9,6 12,6 12,13 4,13 4,8 3,8 3,14 13,14 13,5"/><polygon fill="#00539C" points="5,1 3,1 5,3 1,3 1,5 5,5 3,7 5,7 8,4"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><polygon fill="#656565" points="10,2 7.414,2 8.414,3 9,3 9,3.586 9,4 9,4.414 9,6 12,6 12,13 4,13 4,8 3,8 3,14 13,14 13,5"/><polygon fill="#00539C" points="5,1 3,1 5,3 1,3 1,5 5,5 3,7 5,7 8,4"/></svg>

Before

Width:  |  Height:  |  Size: 419 B

After

Width:  |  Height:  |  Size: 262 B

View file

@ -5,7 +5,7 @@
'use strict';
import { workspace, Disposable, EventEmitter, Memento, window, MessageItem, ConfigurationTarget } from 'vscode';
import { workspace, Disposable, EventEmitter, Memento, window, MessageItem, ConfigurationTarget, commands, Uri } from 'vscode';
import { GitErrorCodes } from './git';
import { Repository, Operation } from './repository';
import { eventToPromise, filterEvent, onceEvent } from './util';
@ -54,14 +54,20 @@ export class AutoFetcher {
}
const yes: MessageItem = { title: localize('yes', "Yes") };
const readMore: MessageItem = { title: localize('read more', "Read More") };
const no: MessageItem = { isCloseAffordance: true, title: localize('no', "No") };
const askLater: MessageItem = { title: localize('not now', "Not Now") };
const result = await window.showInformationMessage(localize('suggest auto fetch', "Would you like to enable auto fetching of Git repositories?"), yes, no, askLater);
const askLater: MessageItem = { title: localize('not now', "Ask Me Later") };
const result = await window.showInformationMessage(localize('suggest auto fetch', "Would you like Code to periodically run `git fetch`?"), yes, readMore, no, askLater);
if (result === askLater) {
return;
}
if (result === readMore) {
commands.executeCommand('vscode.open', Uri.parse('https://go.microsoft.com/fwlink/?linkid=865294'));
return this.onFirstGoodRemoteOperation();
}
if (result === yes) {
const gitConfig = workspace.getConfiguration('git');
gitConfig.update('autofetch', true, ConfigurationTarget.Global);

View file

@ -7,12 +7,13 @@
import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor, CancellationTokenSource, StatusBarAlignment } from 'vscode';
import { Ref, RefType, Git, GitErrorCodes, Branch } from './git';
import { Repository, Resource, Status, CommitOptions, ResourceGroupType } from './repository';
import { Repository, Resource, Status, CommitOptions, ResourceGroupType, RepositoryState } from './repository';
import { Model } from './model';
import { toGitUri, fromGitUri } from './uri';
import { grep } from './util';
import { applyLineChanges, intersectDiffWithRange, toLineRanges, invertLineChange } from './staging';
import { grep, eventToPromise, isDescendant } from './util';
import { applyLineChanges, intersectDiffWithRange, toLineRanges, invertLineChange, getModifiedRange } from './staging';
import * as path from 'path';
import { lstat, Stats } from 'fs';
import * as os from 'os';
import TelemetryReporter from 'vscode-extension-telemetry';
import * as nls from 'vscode-nls';
@ -168,8 +169,28 @@ export class CommandCenter {
}
private async _openResource(resource: Resource, preview?: boolean, preserveFocus?: boolean, preserveSelection?: boolean): Promise<void> {
const left = await this.getLeftResource(resource);
const right = await this.getRightResource(resource);
let stat: Stats | undefined;
try {
stat = await new Promise<Stats>((c, e) => lstat(resource.resourceUri.fsPath, (err, stat) => err ? e(err) : c(stat)));
} catch (err) {
// noop
}
let left: Uri | undefined;
let right: Uri | undefined;
if (stat && stat.isDirectory()) {
const repository = this.model.getRepositoryForSubmodule(resource.resourceUri);
if (repository) {
right = toGitUri(resource.resourceUri, resource.resourceGroupType === ResourceGroupType.Index ? 'index' : 'wt', { submoduleOf: repository.root });
}
} else {
left = await this.getLeftResource(resource);
right = await this.getRightResource(resource);
}
const title = this.getTitle(resource);
if (!right) {
@ -330,7 +351,6 @@ export class CommandCenter {
const config = workspace.getConfiguration('git');
let value = config.get<string>('defaultCloneDirectory') || os.homedir();
value = value.replace(/^~/, os.homedir());
const parentPath = await window.showInputBox({
prompt: localize('parent', "Parent Directory"),
@ -358,11 +378,10 @@ export class CommandCenter {
statusBarItem.command = cancelCommandId;
statusBarItem.show();
const clonePromise = this.git.clone(url, parentPath, tokenSource.token);
const clonePromise = this.git.clone(url, parentPath.replace(/^~/, os.homedir()), tokenSource.token);
try {
window.withProgress({ location: ProgressLocation.SourceControl, title: localize('cloning', "Cloning git repository...") }, () => clonePromise);
// window.withProgress({ location: ProgressLocation.Window, title: localize('cloning', "Cloning git repository...") }, () => clonePromise);
const repositoryPath = await clonePromise;
@ -484,7 +503,10 @@ export class CommandCenter {
}
if (resource) {
uris = [...resourceStates.map(r => r.resourceUri), resource.resourceUri];
const resources = ([resource, ...resourceStates] as Resource[])
.filter(r => r.type !== Status.DELETED && r.type !== Status.INDEX_DELETED);
uris = resources.map(r => r.resourceUri);
}
}
@ -511,6 +533,11 @@ export class CommandCenter {
}
}
@command('git.openFile2')
async openFile2(arg?: Resource | Uri, ...resourceStates: SourceControlResourceState[]): Promise<void> {
this.openFile(arg, ...resourceStates);
}
@command('git.openHEADFile')
async openHEADFile(arg?: Resource | Uri): Promise<void> {
let resource: Resource | undefined = undefined;
@ -709,10 +736,7 @@ export class CommandCenter {
const modifiedDocument = textEditor.document;
const selections = textEditor.selections;
const selectedChanges = changes.filter(change => {
const modifiedRange = change.modifiedEndLineNumber === 0
? new Range(modifiedDocument.lineAt(change.modifiedStartLineNumber - 1).range.end, modifiedDocument.lineAt(change.modifiedStartLineNumber).range.start)
: new Range(modifiedDocument.lineAt(change.modifiedStartLineNumber - 1).range.start, modifiedDocument.lineAt(change.modifiedEndLineNumber - 1).range.end);
const modifiedRange = getModifiedRange(modifiedDocument, change);
return selections.every(selection => !selection.intersection(modifiedRange));
});
@ -939,6 +963,25 @@ export class CommandCenter {
getCommitMessage: () => Promise<string | undefined>,
opts?: CommitOptions
): Promise<boolean> {
const unsavedTextDocuments = workspace.textDocuments
.filter(d => !d.isUntitled && d.isDirty && isDescendant(repository.root, d.uri.fsPath));
if (unsavedTextDocuments.length > 0) {
const message = unsavedTextDocuments.length === 1
? localize('unsaved files single', "The following file is unsaved: {0}.\n\nWould you like to save it before comitting?", path.basename(unsavedTextDocuments[0].uri.fsPath))
: localize('unsaved files', "There are {0} unsaved files.\n\nWould you like to save them before comitting?", unsavedTextDocuments.length);
const saveAndCommit = localize('save and commit', "Save All & Commit");
const commit = localize('commit', "Commit Anyway");
const pick = await window.showWarningMessage(message, { modal: true }, saveAndCommit, commit);
if (pick === saveAndCommit) {
await Promise.all(unsavedTextDocuments.map(d => d.save()));
await repository.status();
} else if (pick !== commit) {
return false; // do not commit on cancel
}
}
const config = workspace.getConfiguration('git');
const enableSmartCommit = config.get<boolean>('enableSmartCommit') === true;
const enableCommitSigning = config.get<boolean>('enableCommitSigning') === true;
@ -963,6 +1006,8 @@ export class CommandCenter {
if (!opts) {
opts = { all: noStagedChanges };
} else if (!opts.all && noStagedChanges) {
opts = { ...opts, all: true };
}
// enable signing of commits if configurated
@ -996,8 +1041,21 @@ export class CommandCenter {
return message;
}
let value: string | undefined = undefined;
if (opts && opts.amend && repository.HEAD && repository.HEAD.commit) {
value = (await repository.getCommit(repository.HEAD.commit)).message;
}
const getPreviousCommitMessage = async () => {
//Only return the previous commit message if it's an amend commit and the repo already has a commit
if (opts && opts.amend && repository.HEAD && repository.HEAD.commit) {
return (await repository.getCommit('HEAD')).message;
}
};
return await window.showInputBox({
value: opts && opts.defaultMsg,
value,
placeHolder: localize('commit message', "Commit message"),
prompt: localize('provide commit message', "Please provide a commit message"),
ignoreFocusOut: true
@ -1041,15 +1099,7 @@ export class CommandCenter {
@command('git.commitStagedAmend', { repository: true })
async commitStagedAmend(repository: Repository): Promise<void> {
let msg;
if (repository.HEAD) {
if (repository.HEAD.commit) {
let id = repository.HEAD.commit;
let commit = await repository.getCommit(id);
msg = commit.message;
}
}
await this.commitWithAnyInput(repository, { all: false, amend: true, defaultMsg: msg });
await this.commitWithAnyInput(repository, { all: false, amend: true });
}
@command('git.commitAll', { repository: true })
@ -1267,25 +1317,26 @@ export class CommandCenter {
return;
}
const picks = remotes.map(r => ({ label: r.name, description: r.url }));
const remotePicks = remotes.map(r => ({ label: r.name, description: r.url }));
const placeHolder = localize('pick remote pull repo', "Pick a remote to pull the branch from");
const pick = await window.showQuickPick(picks, { placeHolder });
const remotePick = await window.showQuickPick(remotePicks, { placeHolder });
if (!pick) {
if (!remotePick) {
return;
}
const branchName = await window.showInputBox({
placeHolder: localize('branch name', "Branch name"),
prompt: localize('provide branch name', "Please provide a branch name"),
ignoreFocusOut: true
});
const remoteRefs = repository.refs;
const remoteRefsFiltered = remoteRefs.filter(r => (r.remote === remotePick.label));
const branchPicks = remoteRefsFiltered.map(r => ({ label: r.name })) as { label: string; description: string }[];
const branchPick = await window.showQuickPick(branchPicks, { placeHolder });
if (!branchName) {
if (!branchPick) {
return;
}
repository.pull(false, pick.label, branchName);
const remoteCharCnt = remotePick.label.length;
repository.pull(false, remotePick.label, branchPick.label.slice(remoteCharCnt + 1));
}
@command('git.pull', { repository: true })
@ -1321,7 +1372,27 @@ export class CommandCenter {
return;
}
await repository.push();
if (!repository.HEAD || !repository.HEAD.name) {
window.showWarningMessage(localize('nobranch', "Please check out a branch to push to a remote."));
return;
}
try {
await repository.push();
} catch (err) {
if (err.gitErrorCode !== GitErrorCodes.NoUpstreamBranch) {
throw err;
}
const branchName = repository.HEAD.name;
const message = localize('confirm publish branch', "The branch '{0}' has no upstream branch. Would you like to publish this branch?", branchName);
const yes = localize('ok', "OK");
const pick = await window.showWarningMessage(message, { modal: true }, yes);
if (pick === yes) {
await this.publish(repository);
}
}
}
@command('git.pushWithTags', { repository: true })
@ -1465,7 +1536,10 @@ export class CommandCenter {
}
private async _stash(repository: Repository, includeUntracked = false): Promise<void> {
if (repository.workingTreeGroup.resourceStates.length === 0) {
const noUnstagedChanges = repository.workingTreeGroup.resourceStates.length === 0;
const noStagedChanges = repository.indexGroup.resourceStates.length === 0;
if (noUnstagedChanges && noStagedChanges) {
window.showInformationMessage(localize('no changes stash', "There are no changes to stash."));
return;
}
@ -1641,13 +1715,18 @@ export class CommandCenter {
const isSingleResource = arg instanceof Uri;
const groups = resources.reduce((result, resource) => {
const repository = this.model.getRepository(resource);
let repository = this.model.getRepository(resource);
if (!repository) {
console.warn('Could not find git repository for ', resource);
return result;
}
// Could it be a submodule?
if (resource.fsPath === repository.root) {
repository = this.model.getRepositoryForSubmodule(resource) || repository;
}
const tuple = result.filter(p => p.repository === repository)[0];
if (tuple) {

View file

@ -52,7 +52,7 @@ export class GitContentProvider {
return;
}
this._onDidChange.fire(toGitUri(uri, '', true));
this._onDidChange.fire(toGitUri(uri, '', { replaceFileExtension: true }));
}
@debounce(1100)
@ -83,6 +83,18 @@ export class GitContentProvider {
}
async provideTextDocumentContent(uri: Uri): Promise<string> {
let { path, ref, submoduleOf } = fromGitUri(uri);
if (submoduleOf) {
const repository = this.model.getRepository(submoduleOf);
if (!repository) {
return '';
}
return await repository.diff(path, { cached: ref === 'index' });
}
const repository = this.model.getRepository(uri);
if (!repository) {
@ -95,8 +107,6 @@ export class GitContentProvider {
this.cache[cacheKey] = cacheValue;
let { path, ref } = fromGitUri(uri);
if (ref === '~') {
const fileUri = Uri.file(path);
const uriString = fileUri.toString();

View file

@ -6,35 +6,48 @@
'use strict';
import { window, workspace, Uri, Disposable, Event, EventEmitter, DecorationData, DecorationProvider, ThemeColor } from 'vscode';
import * as path from 'path';
import { Repository, GitResourceGroup, Status } from './repository';
import { Model } from './model';
import { debounce } from './decorators';
import { filterEvent } from './util';
import { filterEvent, dispose, anyEvent, mapEvent, fireEvent } from './util';
import { Submodule, GitErrorCodes } from './git';
type Callback = { resolve: (status: boolean) => void, reject: (err: any) => void };
class GitIgnoreDecorationProvider implements DecorationProvider {
private readonly _onDidChangeDecorations = new EventEmitter<Uri[]>();
readonly onDidChangeDecorations: Event<Uri[]> = this._onDidChangeDecorations.event;
private checkIgnoreQueue = new Map<string, { resolve: (status: boolean) => void, reject: (err: any) => void }>();
readonly onDidChangeDecorations: Event<Uri[]>;
private queue = new Map<string, { repository: Repository; queue: Map<string, Callback>; }>();
private disposables: Disposable[] = [];
constructor(private repository: Repository) {
this.disposables.push(
window.registerDecorationProvider(this),
filterEvent(workspace.onDidSaveTextDocument, e => e.fileName.endsWith('.gitignore'))(_ => this._onDidChangeDecorations.fire())
//todo@joh -> events when the ignore status actually changes, not only when the file changes
);
}
constructor(private model: Model) {
//todo@joh -> events when the ignore status actually changes, not only when the file changes
this.onDidChangeDecorations = fireEvent(anyEvent<any>(
filterEvent(workspace.onDidSaveTextDocument, e => e.fileName.endsWith('.gitignore')),
model.onDidOpenRepository,
model.onDidCloseRepository
));
dispose(): void {
this.disposables.forEach(d => d.dispose());
this.checkIgnoreQueue.clear();
this.disposables.push(window.registerDecorationProvider(this));
}
provideDecoration(uri: Uri): Promise<DecorationData | undefined> {
const repository = this.model.getRepository(uri);
if (!repository) {
return Promise.resolve(undefined);
}
let queueItem = this.queue.get(repository.root);
if (!queueItem) {
queueItem = { repository, queue: new Map<string, Callback>() };
this.queue.set(repository.root, queueItem);
}
return new Promise<boolean>((resolve, reject) => {
this.checkIgnoreQueue.set(uri.fsPath, { resolve, reject });
queueItem!.queue.set(uri.fsPath, { resolve, reject });
this.checkIgnoreSoon();
}).then(ignored => {
if (ignored) {
@ -48,23 +61,42 @@ class GitIgnoreDecorationProvider implements DecorationProvider {
@debounce(500)
private checkIgnoreSoon(): void {
const queue = new Map(this.checkIgnoreQueue.entries());
this.checkIgnoreQueue.clear();
this.repository.checkIgnore([...queue.keys()]).then(ignoreSet => {
for (const [key, value] of queue.entries()) {
value.resolve(ignoreSet.has(key));
}
}, err => {
console.error(err);
for (const [, value] of queue.entries()) {
value.reject(err);
}
});
const queue = new Map(this.queue.entries());
this.queue.clear();
for (const [, item] of queue) {
const paths = [...item.queue.keys()];
item.repository.checkIgnore(paths).then(ignoreSet => {
for (const [key, value] of item.queue.entries()) {
value.resolve(ignoreSet.has(key));
}
}, err => {
if (err.gitErrorCode !== GitErrorCodes.IsInSubmodule) {
console.error(err);
}
for (const [, value] of item.queue.entries()) {
value.reject(err);
}
});
}
}
dispose(): void {
this.disposables.forEach(d => d.dispose());
this.queue.clear();
}
}
class GitDecorationProvider implements DecorationProvider {
private static SubmoduleDecorationData: DecorationData = {
title: 'Submodule',
abbreviation: 'S',
color: new ThemeColor('gitDecoration.submoduleResourceForeground')
};
private readonly _onDidChangeDecorations = new EventEmitter<Uri[]>();
readonly onDidChangeDecorations: Event<Uri[]> = this._onDidChangeDecorations.event;
@ -80,6 +112,8 @@ class GitDecorationProvider implements DecorationProvider {
private onDidRunGitStatus(): void {
let newDecorations = new Map<string, DecorationData>();
this.collectSubmoduleDecorationData(newDecorations);
this.collectDecorationData(this.repository.indexGroup, newDecorations);
this.collectDecorationData(this.repository.workingTreeGroup, newDecorations);
this.collectDecorationData(this.repository.mergeGroup, newDecorations);
@ -101,6 +135,12 @@ class GitDecorationProvider implements DecorationProvider {
});
}
private collectSubmoduleDecorationData(bucket: Map<string, DecorationData>): void {
for (const submodule of this.repository.submodules) {
bucket.set(Uri.file(path.join(this.repository.root, submodule.path)).toString(), GitDecorationProvider.SubmoduleDecorationData);
}
}
provideDecoration(uri: Uri): DecorationData | undefined {
return this.decorations.get(uri.toString());
}
@ -113,17 +153,21 @@ class GitDecorationProvider implements DecorationProvider {
export class GitDecorations {
private configListener: Disposable;
private modelListener: Disposable[] = [];
private disposables: Disposable[] = [];
private modelDisposables: Disposable[] = [];
private providers = new Map<Repository, Disposable>();
constructor(private model: Model) {
this.configListener = workspace.onDidChangeConfiguration(e => e.affectsConfiguration('git.decorations.enabled') && this.update());
this.disposables.push(new GitIgnoreDecorationProvider(model));
const onEnablementChange = filterEvent(workspace.onDidChangeConfiguration, e => e.affectsConfiguration('git.decorations.enabled'));
onEnablementChange(this.update, this, this.disposables);
this.update();
}
private update(): void {
const enabled = workspace.getConfiguration('git').get('decorations.enabled');
if (enabled) {
this.enable();
} else {
@ -132,26 +176,25 @@ export class GitDecorations {
}
private enable(): void {
this.modelListener = [];
this.model.onDidOpenRepository(this.onDidOpenRepository, this, this.modelListener);
this.model.onDidCloseRepository(this.onDidCloseRepository, this, this.modelListener);
this.model.onDidOpenRepository(this.onDidOpenRepository, this, this.modelDisposables);
this.model.onDidCloseRepository(this.onDidCloseRepository, this, this.modelDisposables);
this.model.repositories.forEach(this.onDidOpenRepository, this);
}
private disable(): void {
this.modelListener.forEach(d => d.dispose());
this.modelDisposables = dispose(this.modelDisposables);
this.providers.forEach(value => value.dispose());
this.providers.clear();
}
private onDidOpenRepository(repository: Repository): void {
const provider = new GitDecorationProvider(repository);
const ignoreProvider = new GitIgnoreDecorationProvider(repository);
this.providers.set(repository, Disposable.from(provider, ignoreProvider));
this.providers.set(repository, provider);
}
private onDidCloseRepository(repository: Repository): void {
const provider = this.providers.get(repository);
if (provider) {
provider.dispose();
this.providers.delete(repository);
@ -159,9 +202,7 @@ export class GitDecorations {
}
dispose(): void {
this.configListener.dispose();
this.modelListener.forEach(d => d.dispose());
this.providers.forEach(value => value.dispose);
this.providers.clear();
this.disable();
this.disposables = dispose(this.disposables);
}
}

View file

@ -9,13 +9,14 @@ import * as fs from 'fs';
import * as path from 'path';
import * as os from 'os';
import * as cp from 'child_process';
import * as which from 'which';
import { EventEmitter } from 'events';
import iconv = require('iconv-lite');
import * as filetype from 'file-type';
import { assign, uniqBy, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp, readBytes, detectUnicodeEncoding, Encoding, onceEvent } from './util';
import { CancellationToken } from 'vscode';
const readfile = denodeify<string>(fs.readFile);
const readfile = denodeify<string, string | null, string>(fs.readFile);
export interface IGit {
path: string;
@ -124,10 +125,17 @@ function findSystemGitWin32(base: string, onLookup: (path: string) => void): Pro
return findSpecificGit(path.join(base, 'Git', 'cmd', 'git.exe'), onLookup);
}
function findGitWin32InPath(onLookup: (path: string) => void): Promise<IGit> {
const whichPromise = new Promise<string>((c, e) => which('git.exe', (err, path) => err ? e(err) : c(path)));
return whichPromise.then(path => findSpecificGit(path, onLookup));
}
function findGitWin32(onLookup: (path: string) => void): Promise<IGit> {
return findSystemGitWin32(process.env['ProgramW6432'] as string, onLookup)
.then(void 0, () => findSystemGitWin32(process.env['ProgramFiles(x86)'] as string, onLookup))
.then(void 0, () => findSystemGitWin32(process.env['ProgramFiles'] as string, onLookup));
.then(void 0, () => findSystemGitWin32(process.env['ProgramFiles'] as string, onLookup))
.then(void 0, () => findSystemGitWin32(path.join(process.env['LocalAppData'] as string, 'Programs'), onLookup))
.then(void 0, () => findGitWin32InPath(onLookup));
}
export function findGit(hint: string | undefined, onLookup: (path: string) => void): Promise<IGit> {
@ -317,7 +325,9 @@ export const GitErrorCodes = {
BranchAlreadyExists: 'BranchAlreadyExists',
NoLocalChanges: 'NoLocalChanges',
NoStashFound: 'NoStashFound',
LocalChangesOverwritten: 'LocalChangesOverwritten'
LocalChangesOverwritten: 'LocalChangesOverwritten',
NoUpstreamBranch: 'NoUpstreamBranch',
IsInSubmodule: 'IsInSubmodule'
};
function getGitErrorCode(stderr: string): string | undefined {
@ -534,6 +544,72 @@ export class GitStatusParser {
}
}
export interface Submodule {
name: string;
path: string;
url: string;
}
export function parseGitmodules(raw: string): Submodule[] {
const regex = /\r?\n/g;
let position = 0;
let match: RegExpExecArray | null = null;
const result: Submodule[] = [];
let submodule: Partial<Submodule> = {};
function parseLine(line: string): void {
const sectionMatch = /^\s*\[submodule "([^"]+)"\]\s*$/.exec(line);
if (sectionMatch) {
if (submodule.name && submodule.path && submodule.url) {
result.push(submodule as Submodule);
}
const name = sectionMatch[1];
if (name) {
submodule = { name };
return;
}
}
if (!submodule) {
return;
}
const propertyMatch = /^\s*(\w+) = (.*)$/.exec(line);
if (!propertyMatch) {
return;
}
const [, key, value] = propertyMatch;
switch (key) {
case 'path': submodule.path = value; break;
case 'url': submodule.url = value; break;
}
}
while (match = regex.exec(raw)) {
parseLine(raw.substring(position, match.index));
position = match.index + match[0].length;
}
parseLine(raw.substring(position));
if (submodule.name && submodule.path && submodule.url) {
result.push(submodule as Submodule);
}
return result;
}
export interface DiffOptions {
cached?: boolean;
}
export class Repository {
constructor(
@ -672,6 +748,19 @@ export class Repository {
}
}
async diff(path: string, options: DiffOptions = {}): Promise<string> {
const args = ['diff'];
if (options.cached) {
args.push('--cached');
}
args.push('--', path);
const result = await this.run(args);
return result.stdout;
}
async add(paths: string[]): Promise<void> {
const args = ['add', '-A', '--'];
@ -945,6 +1034,8 @@ export class Repository {
err.gitErrorCode = GitErrorCodes.PushRejected;
} else if (/Could not read from remote repository/.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.RemoteConnectionError;
} else if (/^fatal: The current branch .* has no upstream branch/.test(err.stderr || '')) {
err.gitErrorCode = GitErrorCodes.NoUpstreamBranch;
}
throw err;
@ -1059,7 +1150,7 @@ export class Repository {
}
async getRefs(): Promise<Ref[]> {
const result = await this.run(['for-each-ref', '--format', '%(refname) %(objectname)']);
const result = await this.run(['for-each-ref', '--format', '%(refname) %(objectname)', '--sort', '-committerdate']);
const fn = (line: string): Ref | null => {
let match: RegExpExecArray | null;
@ -1178,4 +1269,24 @@ export class Repository {
return { hash: match[1], message: match[2] };
}
async updateSubmodules(paths: string[]): Promise<void> {
const args = ['submodule', 'update', '--', ...paths];
await this.run(args);
}
async getSubmodules(): Promise<Submodule[]> {
const gitmodulesPath = path.join(this.root, '.gitmodules');
try {
const gitmodulesRaw = await readfile(gitmodulesPath, 'utf8');
return parseGitmodules(gitmodulesRaw);
} catch (err) {
if (/ENOENT/.test(err.message)) {
return [];
}
throw err;
}
}
}

View file

@ -8,11 +8,12 @@
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor, Memento, ConfigurationChangeEvent } from 'vscode';
import { Repository, RepositoryState } from './repository';
import { memoize, sequentialize, debounce } from './decorators';
import { dispose, anyEvent, filterEvent, IDisposable, isDescendant } from './util';
import { dispose, anyEvent, filterEvent, IDisposable, isDescendant, find, firstIndex } from './util';
import { Git, GitErrorCodes } from './git';
import * as path from 'path';
import * as fs from 'fs';
import * as nls from 'vscode-nls';
import { fromGitUri } from './uri';
const localize = nls.loadMessageBundle();
@ -27,7 +28,7 @@ class RepositoryPick implements QuickPickItem {
.join(' ');
}
constructor(public readonly repository: Repository) { }
constructor(public readonly repository: Repository, public readonly index: number) { }
}
export interface ModelChangeEvent {
@ -101,8 +102,11 @@ export class Model {
}
private onPossibleGitRepositoryChange(uri: Uri): void {
const possibleGitRepositoryPath = uri.fsPath.replace(/\.git.*$/, '');
this.possibleGitRepositoryPaths.add(possibleGitRepositoryPath);
this.eventuallyScanPossibleGitRepository(uri.fsPath.replace(/\.git.*$/, ''));
}
private eventuallyScanPossibleGitRepository(path: string) {
this.possibleGitRepositoryPaths.add(path);
this.eventuallyScanPossibleGitRepositories();
}
@ -149,6 +153,13 @@ export class Model {
}
private onDidChangeVisibleTextEditors(editors: TextEditor[]): void {
const config = workspace.getConfiguration('git');
const enabled = config.get<boolean>('autoRepositoryDetection') === true;
if (!enabled) {
return;
}
editors.forEach(editor => {
const uri = editor.document.uri;
@ -206,11 +217,20 @@ export class Model {
const disappearListener = onDidDisappearRepository(() => dispose());
const changeListener = repository.onDidChangeRepository(uri => this._onDidChangeRepository.fire({ repository, uri }));
const originalResourceChangeListener = repository.onDidChangeOriginalResource(uri => this._onDidChangeOriginalResource.fire({ repository, uri }));
const scanSubmodules = () => {
repository.submodules
.map(r => path.join(repository.root, r.path))
.forEach(p => this.eventuallyScanPossibleGitRepository(p));
};
const statusListener = repository.onDidRunGitStatus(scanSubmodules);
scanSubmodules();
const dispose = () => {
disappearListener.dispose();
changeListener.dispose();
originalResourceChangeListener.dispose();
statusListener.dispose();
repository.dispose();
this.openRepositories = this.openRepositories.filter(e => e !== openRepository);
@ -237,7 +257,16 @@ export class Model {
throw new Error(localize('no repositories', "There are no available repositories"));
}
const picks = this.openRepositories.map(e => new RepositoryPick(e.repository));
const picks = this.openRepositories.map((e, index) => new RepositoryPick(e.repository, index));
const active = window.activeTextEditor;
const repository = active && this.getRepository(active.document.fileName);
const index = firstIndex(picks, pick => pick.repository === repository);
// Move repository pick containing the active text editor to appear first
if (index > -1) {
picks.unshift(...picks.splice(index, 1));
}
const placeHolder = localize('pick repo', "Choose a repository");
const pick = await window.showQuickPick(picks, { placeHolder });
@ -272,14 +301,29 @@ export class Model {
}
if (hint instanceof Uri) {
const resourcePath = hint.fsPath;
let resourcePath: string;
for (const liveRepository of this.openRepositories) {
const relativePath = path.relative(liveRepository.repository.root, resourcePath);
if (hint.scheme === 'git') {
resourcePath = fromGitUri(hint).path;
} else {
resourcePath = hint.fsPath;
}
if (isDescendant(liveRepository.repository.root, resourcePath)) {
return liveRepository;
outer:
for (const liveRepository of this.openRepositories.sort((a, b) => b.repository.root.length - a.repository.root.length)) {
if (!isDescendant(liveRepository.repository.root, resourcePath)) {
continue;
}
for (const submodule of liveRepository.repository.submodules) {
const submoduleRoot = path.join(liveRepository.repository.root, submodule.path);
if (isDescendant(submoduleRoot, resourcePath)) {
continue outer;
}
}
return liveRepository;
}
return undefined;
@ -300,6 +344,20 @@ export class Model {
return undefined;
}
getRepositoryForSubmodule(submoduleUri: Uri): Repository | undefined {
for (const repository of this.repositories) {
for (const submodule of repository.submodules) {
const submodulePath = path.join(repository.root, submodule.path);
if (submodulePath === submoduleUri.fsPath) {
return repository;
}
}
}
return undefined;
}
dispose(): void {
const openRepositories = [...this.openRepositories];
openRepositories.forEach(r => r.dispose());

View file

@ -6,8 +6,8 @@
'use strict';
import { Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData, Memento } from 'vscode';
import { Repository as BaseRepository, Ref, Branch, Remote, Commit, GitErrorCodes, Stash, RefType, GitError } from './git';
import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant } from './util';
import { Repository as BaseRepository, Ref, Branch, Remote, Commit, GitErrorCodes, Stash, RefType, GitError, Submodule, DiffOptions } from './git';
import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant, IDisposable, onceEvent, EmptyDisposable, debounceEvent } from './util';
import { memoize, throttle, debounce } from './decorators';
import { toGitUri } from './uri';
import { AutoFetcher } from './autofetch';
@ -105,7 +105,7 @@ export class Resource implements SourceControlResourceState {
}
};
private getIconPath(theme: string): Uri | undefined {
private getIconPath(theme: string): Uri {
switch (this.type) {
case Status.INDEX_MODIFIED: return Resource.Icons[theme].Modified;
case Status.MODIFIED: return Resource.Icons[theme].Modified;
@ -123,7 +123,6 @@ export class Resource implements SourceControlResourceState {
case Status.DELETED_BY_US: return Resource.Icons[theme].Conflict;
case Status.BOTH_ADDED: return Resource.Icons[theme].Conflict;
case Status.BOTH_MODIFIED: return Resource.Icons[theme].Conflict;
default: return void 0;
}
}
@ -182,7 +181,7 @@ export class Resource implements SourceControlResourceState {
return { strikeThrough, faded, tooltip, light, dark, letter, color, source: 'git.resource' /*todo@joh*/ };
}
get letter(): string | undefined {
get letter(): string {
switch (this.type) {
case Status.INDEX_MODIFIED:
case Status.MODIFIED:
@ -207,12 +206,10 @@ export class Resource implements SourceControlResourceState {
case Status.BOTH_ADDED:
case Status.BOTH_MODIFIED:
return 'C';
default:
return undefined;
}
}
get color(): ThemeColor | undefined {
get color(): ThemeColor {
switch (this.type) {
case Status.INDEX_MODIFIED:
case Status.MODIFIED:
@ -235,8 +232,6 @@ export class Resource implements SourceControlResourceState {
case Status.BOTH_ADDED:
case Status.BOTH_MODIFIED:
return new ThemeColor('gitDecoration.conflictingResourceForeground');
default:
return undefined;
}
}
@ -261,7 +256,7 @@ export class Resource implements SourceControlResourceState {
}
}
get resourceDecoration(): DecorationData | undefined {
get resourceDecoration(): DecorationData {
const title = this.tooltip;
const abbreviation = this.letter;
const color = this.color;
@ -280,6 +275,7 @@ export class Resource implements SourceControlResourceState {
export enum Operation {
Status = 'Status',
Diff = 'Diff',
Add = 'Add',
RevertFiles = 'RevertFiles',
Commit = 'Commit',
@ -301,7 +297,8 @@ export enum Operation {
Tag = 'Tag',
Stash = 'Stash',
CheckIgnore = 'CheckIgnore',
LSTree = 'LSTree'
LSTree = 'LSTree',
SubmoduleUpdate = 'SubmoduleUpdate'
}
function isReadOnly(operation: Operation): boolean {
@ -330,6 +327,7 @@ function shouldShowProgress(operation: Operation): boolean {
export interface Operations {
isIdle(): boolean;
shouldShowProgress(): boolean;
isRunning(operation: Operation): boolean;
}
@ -366,6 +364,18 @@ class OperationsImpl implements Operations {
return true;
}
shouldShowProgress(): boolean {
const operations = this.operations.keys();
for (const operation of operations) {
if (shouldShowProgress(operation)) {
return true;
}
}
return false;
}
}
export interface CommitOptions {
@ -373,7 +383,6 @@ export interface CommitOptions {
amend?: boolean;
signoff?: boolean;
signCommit?: boolean;
defaultMsg?: string;
}
export interface GitResourceGroup extends SourceControlResourceGroup {
@ -385,6 +394,29 @@ export interface OperationResult {
error: any;
}
class ProgressManager {
private disposable: IDisposable = EmptyDisposable;
constructor(private repository: Repository) {
const start = onceEvent(filterEvent(repository.onDidChangeOperations, () => repository.operations.shouldShowProgress()));
const end = onceEvent(filterEvent(debounceEvent(repository.onDidChangeOperations, 300), () => !repository.operations.shouldShowProgress()));
const setup = () => {
this.disposable = start(() => {
const promise = eventToPromise(end).then(() => setup());
window.withProgress({ location: ProgressLocation.SourceControl }, () => promise);
});
};
setup();
}
dispose(): void {
this.disposable.dispose();
}
}
export class Repository implements Disposable {
private _onDidChangeRepository = new EventEmitter<Uri>();
@ -439,6 +471,11 @@ export class Repository implements Disposable {
return this._remotes;
}
private _submodules: Submodule[] = [];
get submodules(): Submodule[] {
return this._submodules;
}
private _operations = new OperationsImpl();
get operations(): Operations { return this._operations; }
@ -484,6 +521,7 @@ export class Repository implements Disposable {
this._sourceControl.inputBox.placeholder = localize('commitMessage', "Message (press {0} to commit)");
this._sourceControl.acceptInputCommand = { command: 'git.commitWithInput', title: localize('commit', "Commit"), arguments: [this._sourceControl] };
this._sourceControl.quickDiffProvider = this;
this._sourceControl.inputBox.lineWarningLength = 72;
this.disposables.push(this._sourceControl);
this._mergeGroup = this._sourceControl.createResourceGroup('merge', localize('merge changes', "Merge Changes"));
@ -504,6 +542,9 @@ export class Repository implements Disposable {
statusBar.onDidChange(() => this._sourceControl.statusBarCommands = statusBar.commands, null, this.disposables);
this._sourceControl.statusBarCommands = statusBar.commands;
const progressManager = new ProgressManager(this);
this.disposables.push(progressManager);
this.updateCommitTemplate();
this.status();
}
@ -513,7 +554,7 @@ export class Repository implements Disposable {
return;
}
return toGitUri(uri, '', true);
return toGitUri(uri, '', { replaceFileExtension: true });
}
private async updateCommitTemplate(): Promise<void> {
@ -524,21 +565,15 @@ export class Repository implements Disposable {
}
}
// @throttle
// async init(): Promise<void> {
// if (this.state !== State.NotAGitRepository) {
// return;
// }
// await this.git.init(this.workspaceRoot.fsPath);
// await this.status();
// }
@throttle
async status(): Promise<void> {
await this.run(Operation.Status);
}
diff(path: string, options: DiffOptions = {}): Promise<string> {
return this.run(Operation.Diff, () => this.repository.diff(path, options));
}
async add(resources: Uri[]): Promise<void> {
await this.run(Operation.Add, () => this.repository.add(resources.map(r => r.fsPath)));
}
@ -567,8 +602,18 @@ export class Repository implements Disposable {
await this.run(Operation.Clean, async () => {
const toClean: string[] = [];
const toCheckout: string[] = [];
const submodulesToUpdate: string[] = [];
resources.forEach(r => {
const fsPath = r.fsPath;
for (const submodule of this.submodules) {
if (path.join(this.root, submodule.path) === fsPath) {
submodulesToUpdate.push(fsPath);
return;
}
}
const raw = r.toString();
const scmResource = find(this.workingTreeGroup.resourceStates, sr => sr.resourceUri.toString() === raw);
@ -579,11 +624,11 @@ export class Repository implements Disposable {
switch (scmResource.type) {
case Status.UNTRACKED:
case Status.IGNORED:
toClean.push(r.fsPath);
toClean.push(fsPath);
break;
default:
toCheckout.push(r.fsPath);
toCheckout.push(fsPath);
break;
}
});
@ -598,6 +643,10 @@ export class Repository implements Disposable {
promises.push(this.repository.checkout('', toCheckout));
}
if (submodulesToUpdate.length > 0) {
promises.push(this.repository.updateSubmodules(submodulesToUpdate));
}
await Promise.all(promises);
});
}
@ -780,7 +829,11 @@ export class Repository implements Disposable {
// paths are separated by the null-character
resolve(new Set<string>(data.split('\0')));
} else {
reject(new GitError({ stdout: data, stderr, exitCode }));
if (/ is in submodule /.test(stderr)) {
reject(new GitError({ stdout: data, stderr, exitCode, gitErrorCode: GitErrorCodes.IsInSubmodule }));
} else {
reject(new GitError({ stdout: data, stderr, exitCode }));
}
}
};
@ -807,37 +860,31 @@ export class Repository implements Disposable {
throw new Error('Repository not initialized');
}
const run = async () => {
let error: any = null;
let error: any = null;
this._operations.start(operation);
this._onRunOperation.fire(operation);
this._operations.start(operation);
this._onRunOperation.fire(operation);
try {
const result = await this.retryRun(runOperation);
try {
const result = await this.retryRun(runOperation);
if (!isReadOnly(operation)) {
await this.updateModelState();
}
return result;
} catch (err) {
error = err;
if (err.gitErrorCode === GitErrorCodes.NotAGitRepository) {
this.state = RepositoryState.Disposed;
}
throw err;
} finally {
this._operations.end(operation);
this._onDidRunOperation.fire({ operation, error });
if (!isReadOnly(operation)) {
await this.updateModelState();
}
};
return shouldShowProgress(operation)
? window.withProgress({ location: ProgressLocation.SourceControl }, run)
: run();
return result;
} catch (err) {
error = err;
if (err.gitErrorCode === GitErrorCodes.NotAGitRepository) {
this.state = RepositoryState.Disposed;
}
throw err;
} finally {
this._operations.end(operation);
this._onDidRunOperation.fire({ operation, error });
}
}
private async retryRun<T>(runOperation: () => Promise<T> = () => Promise.resolve<any>(null)): Promise<T> {
@ -863,7 +910,7 @@ export class Repository implements Disposable {
const { status, didHitLimit } = await this.repository.getStatus();
const config = workspace.getConfiguration('git');
const shouldIgnore = config.get<boolean>('ignoreLimitWarning') === true;
const useIcons = config.get<boolean>('decorations.enabled', true);
const useIcons = !config.get<boolean>('decorations.enabled', true);
this.isRepositoryHuge = didHitLimit;
@ -896,11 +943,12 @@ export class Repository implements Disposable {
// noop
}
const [refs, remotes] = await Promise.all([this.repository.getRefs(), this.repository.getRemotes()]);
const [refs, remotes, submodules] = await Promise.all([this.repository.getRefs(), this.repository.getRemotes(), this.repository.getSubmodules()]);
this._HEAD = HEAD;
this._refs = refs;
this._remotes = remotes;
this._submodules = submodules;
const index: Resource[] = [];
const workingTree: Resource[] = [];

View file

@ -72,10 +72,16 @@ export function toLineRanges(selections: Selection[], textDocument: TextDocument
return result;
}
function getModifiedRange(textDocument: TextDocument, diff: LineChange): Range {
return diff.modifiedEndLineNumber === 0
? new Range(textDocument.lineAt(diff.modifiedStartLineNumber - 1).range.end, textDocument.lineAt(diff.modifiedStartLineNumber).range.start)
: new Range(textDocument.lineAt(diff.modifiedStartLineNumber - 1).range.start, textDocument.lineAt(diff.modifiedEndLineNumber - 1).range.end);
export function getModifiedRange(textDocument: TextDocument, diff: LineChange): Range {
if (diff.modifiedEndLineNumber === 0) {
if (diff.modifiedStartLineNumber === 0) {
return new Range(textDocument.lineAt(diff.modifiedStartLineNumber).range.end, textDocument.lineAt(diff.modifiedStartLineNumber).range.start);
} else {
return new Range(textDocument.lineAt(diff.modifiedStartLineNumber - 1).range.end, textDocument.lineAt(diff.modifiedStartLineNumber).range.start);
}
} else {
return new Range(textDocument.lineAt(diff.modifiedStartLineNumber - 1).range.start, textDocument.lineAt(diff.modifiedEndLineNumber - 1).range.end);
}
}
export function intersectDiffWithRange(textDocument: TextDocument, diff: LineChange, range: Range): LineChange | null {

View file

@ -6,7 +6,7 @@
'use strict';
import 'mocha';
import { GitStatusParser } from '../git';
import { GitStatusParser, parseGitmodules } from '../git';
import * as assert from 'assert';
suite('git', () => {
@ -135,4 +135,44 @@ suite('git', () => {
]);
});
});
suite('parseGitmodules', () => {
test('empty', () => {
assert.deepEqual(parseGitmodules(''), []);
});
test('sample', () => {
const sample = `[submodule "deps/spdlog"]
path = deps/spdlog
url = https://github.com/gabime/spdlog.git
`;
assert.deepEqual(parseGitmodules(sample), [
{ name: 'deps/spdlog', path: 'deps/spdlog', url: 'https://github.com/gabime/spdlog.git' }
]);
});
test('big', () => {
const sample = `[submodule "deps/spdlog"]
path = deps/spdlog
url = https://github.com/gabime/spdlog.git
[submodule "deps/spdlog2"]
path = deps/spdlog2
url = https://github.com/gabime/spdlog.git
[submodule "deps/spdlog3"]
path = deps/spdlog3
url = https://github.com/gabime/spdlog.git
[submodule "deps/spdlog4"]
path = deps/spdlog4
url = https://github.com/gabime/spdlog4.git
`;
assert.deepEqual(parseGitmodules(sample), [
{ name: 'deps/spdlog', path: 'deps/spdlog', url: 'https://github.com/gabime/spdlog.git' },
{ name: 'deps/spdlog2', path: 'deps/spdlog2', url: 'https://github.com/gabime/spdlog.git' },
{ name: 'deps/spdlog3', path: 'deps/spdlog3', url: 'https://github.com/gabime/spdlog.git' },
{ name: 'deps/spdlog4', path: 'deps/spdlog4', url: 'https://github.com/gabime/spdlog4.git' }
]);
});
});
});

View file

@ -7,20 +7,45 @@
import { Uri } from 'vscode';
export function fromGitUri(uri: Uri): { path: string; ref: string; } {
export interface GitUriParams {
path: string;
ref: string;
submoduleOf?: string;
}
export function fromGitUri(uri: Uri): GitUriParams {
return JSON.parse(uri.query);
}
export interface GitUriOptions {
replaceFileExtension?: boolean;
submoduleOf?: string;
}
// As a mitigation for extensions like ESLint showing warnings and errors
// for git URIs, let's change the file extension of these uris to .git,
// when `replaceFileExtension` is true.
export function toGitUri(uri: Uri, ref: string, replaceFileExtension = false): Uri {
export function toGitUri(uri: Uri, ref: string, options: GitUriOptions = {}): Uri {
const params: GitUriParams = {
path: uri.fsPath,
ref
};
if (options.submoduleOf) {
params.submoduleOf = options.submoduleOf;
}
let path = uri.path;
if (options.replaceFileExtension) {
path = `${path}.git`;
} else if (options.submoduleOf) {
path = `${path}.diff`;
}
return uri.with({
scheme: 'git',
path: replaceFileExtension ? `${uri.path}.git` : uri.path,
query: JSON.stringify({
path: uri.fsPath,
ref
})
path,
query: JSON.stringify(params)
});
}

View file

@ -34,6 +34,10 @@ export function combinedDisposable(disposables: IDisposable[]): IDisposable {
export const EmptyDisposable = toDisposable(() => null);
export function fireEvent<T>(event: Event<T>): Event<T> {
return (listener, thisArgs = null, disposables?) => event(_ => listener.call(thisArgs), null, disposables);
}
export function mapEvent<I, O>(event: Event<I>, map: (i: I) => O): Event<O> {
return (listener, thisArgs = null, disposables?) => event(i => listener.call(thisArgs, map(i)), null, disposables);
}
@ -69,6 +73,16 @@ export function onceEvent<T>(event: Event<T>): Event<T> {
};
}
export function debounceEvent<T>(event: Event<T>, delay: number): Event<T> {
return (listener, thisArgs = null, disposables?) => {
let timer: NodeJS.Timer;
return event(e => {
clearTimeout(timer);
timer = setTimeout(() => listener.call(thisArgs, e), delay);
}, null, disposables);
};
}
export function eventToPromise<T>(event: Event<T>): Promise<T> {
return new Promise<T>(c => onceEvent(event)(c));
}
@ -116,6 +130,10 @@ export function groupBy<T>(arr: T[], fn: (el: T) => string): { [key: string]: T[
}, Object.create(null));
}
export function denodeify<A, B, C, R>(fn: Function): (a: A, b: B, c: C) => Promise<R>;
export function denodeify<A, B, R>(fn: Function): (a: A, b: B) => Promise<R>;
export function denodeify<A, R>(fn: Function): (a: A) => Promise<R>;
export function denodeify<R>(fn: Function): (...args: any[]) => Promise<R>;
export function denodeify<R>(fn: Function): (...args: any[]) => Promise<R> {
return (...args) => new Promise<R>((c, e) => fn(...args, (err: any, r: any) => err ? e(err) : c(r)));
}
@ -177,6 +195,16 @@ export function uniqueFilter<T>(keyFn: (t: T) => string): (t: T) => boolean {
};
}
export function firstIndex<T>(array: T[], fn: (t: T) => boolean): number {
for (let i = 0; i < array.length; i++) {
if (fn(array[i])) {
return i;
}
}
return -1;
}
export function find<T>(array: T[], fn: (t: T) => boolean): T | undefined {
let result: T | undefined = undefined;

View file

@ -26,6 +26,10 @@
version "7.0.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c"
"@types/which@^1.0.28":
version "1.0.28"
resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6"
applicationinsights@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-0.18.0.tgz#162ebb48a383408bc4de44db32b417307f45bbc1"
@ -123,6 +127,10 @@ inherits@2:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
json3@3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
@ -238,6 +246,12 @@ vscode-nls@2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"
which@^1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/which/-/which-1.3.0.tgz#ff04bdfc010ee547d780bec38e1ac1c2777d253a"
dependencies:
isexe "^2.0.0"
winreg@1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.3.tgz#93ad116b2696da87d58f7265a8fcea5254a965d5"

View file

@ -1 +1,2 @@
test/**
test/**
build/**

View file

@ -1,29 +1,42 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "textmate/git.tmbundle",
"version": "0.0.0",
"license": "MIT",
"repositoryURL": "https://github.com/textmate/git.tmbundle",
"licenseDetail": [
"Copyright (c) 2008 Tim Harper",
"",
"Permission is hereby granted, free of charge, to any person obtaining",
"a copy of this software and associated documentation files (the\"",
"Software\"), to deal in the Software without restriction, including",
"without limitation the rights to use, copy, modify, merge, publish,",
"distribute, sublicense, and/or sell copies of the Software, and to",
"permit persons to whom the Software is furnished to do so, subject to",
"the following conditions:",
"",
"The above copyright notice and this permission notice shall be",
"included in all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,",
"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF",
"MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND",
"NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE",
"LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION",
"OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION",
"WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
}]
[
{
"name": "textmate/git.tmbundle",
"version": "0.0.0",
"license": "MIT",
"repositoryURL": "https://github.com/textmate/git.tmbundle",
"licenseDetail": [
"Copyright (c) 2008 Tim Harper",
"",
"Permission is hereby granted, free of charge, to any person obtaining",
"a copy of this software and associated documentation files (the\"",
"Software\"), to deal in the Software without restriction, including",
"without limitation the rights to use, copy, modify, merge, publish,",
"distribute, sublicense, and/or sell copies of the Software, and to",
"permit persons to whom the Software is furnished to do so, subject to",
"the following conditions:",
"",
"The above copyright notice and this permission notice shall be",
"included in all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,",
"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF",
"MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND",
"NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE",
"LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION",
"OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION",
"WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
},
{
"name": "textmate/diff.tmbundle",
"version": "0.0.0",
"repositoryURL": "https://github.com/textmate/diff.tmbundle",
"licenseDetail": [
"Permission to copy, use, modify, sell and distribute this",
"software is granted. This software is provided \"as is\" without",
"express or implied warranty, and with no claim as to its",
"suitability for any purpose."
]
}
]

View file

@ -0,0 +1,16 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
var updateGrammar = require('../../../build/npm/update-grammar');
updateGrammar.update('textmate/git.tmbundle', 'Syntaxes/Git%20Commit%20Message.tmLanguage', './syntaxes/git-commit.tmLanguage.json');
updateGrammar.update('textmate/git.tmbundle', 'Syntaxes/Git%20Rebase%20Message.tmLanguage', './syntaxes/git-rebase.tmLanguage.json');
updateGrammar.update('textmate/diff.tmbundle', 'Syntaxes/Diff.plist', './syntaxes/diff.tmLanguage.json');

View file

@ -0,0 +1,11 @@
{
"comments": {
"lineComment": "#",
"blockComment": [ "#", " " ]
},
"brackets": [
["{", "}"],
["[", "]"],
["(", ")"]
]
}

View file

@ -11,7 +11,7 @@
"Other"
],
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js textmate/git.tmbundle Syntaxes/Git%20Commit%20Message.tmLanguage ./syntaxes/git-commit.tmLanguage.json Syntaxes/Git%20Rebase%20Message.tmLanguage ./syntaxes/git-rebase.tmLanguage.json"
"update-grammar": "node ./build/update-grammars.js"
},
"contributes": {
"languages": [
@ -37,6 +37,19 @@
"git-rebase-todo"
],
"configuration": "./git-rebase.language-configuration.json"
},
{
"id": "diff",
"aliases": [
"Diff",
"diff"
],
"extensions": [
".patch",
".diff",
".rej"
],
"configuration": "./diff.language-configuration.json"
}
],
"grammars": [
@ -49,12 +62,19 @@
"language": "git-rebase",
"scopeName": "text.git-rebase",
"path": "./syntaxes/git-rebase.tmLanguage.json"
},
{
"language": "diff",
"scopeName": "source.diff",
"path": "./syntaxes/diff.tmLanguage.json"
}
],
"configurationDefaults": {
"[git-commit]": {
"editor.rulers": [72]
}
}
"[git-commit]": {
"editor.rulers": [
72
]
}
}
}
}

View file

@ -0,0 +1,168 @@
{
"information_for_contributors": [
"This file has been converted from https://github.com/textmate/diff.tmbundle/blob/master/Syntaxes/Diff.plist",
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/textmate/diff.tmbundle/commit/0593bb775eab1824af97ef2172fd38822abd97d7",
"fileTypes": [
"patch",
"diff",
"rej"
],
"firstLineMatch": "(?x)^\n\t\t(===\\ modified\\ file\n\t\t|==== \\s* // .+ \\s - \\s .+ \\s+ ====\n\t\t|Index:\\ \n\t\t|---\\ [^%\\n]\n\t\t|\\*\\*\\*.*\\d{4}\\s*$\n\t\t|\\d+(,\\d+)* (a|d|c) \\d+(,\\d+)* $\n\t\t|diff\\ --git\\ \n\t\t|commit\\ [0-9a-f]{40}$\n\t\t)",
"keyEquivalent": "^~D",
"name": "Diff",
"patterns": [
{
"captures": {
"1": {
"name": "punctuation.definition.separator.diff"
}
},
"match": "^((\\*{15})|(={67})|(-{3}))$\\n?",
"name": "meta.separator.diff"
},
{
"match": "^\\d+(,\\d+)*(a|d|c)\\d+(,\\d+)*$\\n?",
"name": "meta.diff.range.normal"
},
{
"captures": {
"1": {
"name": "punctuation.definition.range.diff"
},
"2": {
"name": "meta.toc-list.line-number.diff"
},
"3": {
"name": "punctuation.definition.range.diff"
}
},
"match": "^(@@)\\s*(.+?)\\s*(@@)($\\n?)?",
"name": "meta.diff.range.unified"
},
{
"captures": {
"3": {
"name": "punctuation.definition.range.diff"
},
"4": {
"name": "punctuation.definition.range.diff"
},
"6": {
"name": "punctuation.definition.range.diff"
},
"7": {
"name": "punctuation.definition.range.diff"
}
},
"match": "^(((\\-{3}) .+ (\\-{4}))|((\\*{3}) .+ (\\*{4})))$\\n?",
"name": "meta.diff.range.context"
},
{
"match": "^diff --git a/.*$\\n?",
"name": "meta.diff.header.git"
},
{
"match": "^diff (-|\\S+\\s+\\S+).*$\\n?",
"name": "meta.diff.header.command"
},
{
"captures": {
"4": {
"name": "punctuation.definition.from-file.diff"
},
"6": {
"name": "punctuation.definition.from-file.diff"
},
"7": {
"name": "punctuation.definition.from-file.diff"
}
},
"match": "(^(((-{3}) .+)|((\\*{3}) .+))$\\n?|^(={4}) .+(?= - ))",
"name": "meta.diff.header.from-file"
},
{
"captures": {
"2": {
"name": "punctuation.definition.to-file.diff"
},
"3": {
"name": "punctuation.definition.to-file.diff"
},
"4": {
"name": "punctuation.definition.to-file.diff"
}
},
"match": "(^(\\+{3}) .+$\\n?| (-) .* (={4})$\\n?)",
"name": "meta.diff.header.to-file"
},
{
"captures": {
"3": {
"name": "punctuation.definition.inserted.diff"
},
"6": {
"name": "punctuation.definition.inserted.diff"
}
},
"match": "^(((>)( .*)?)|((\\+).*))$\\n?",
"name": "markup.inserted.diff"
},
{
"captures": {
"1": {
"name": "punctuation.definition.changed.diff"
}
},
"match": "^(!).*$\\n?",
"name": "markup.changed.diff"
},
{
"captures": {
"3": {
"name": "punctuation.definition.deleted.diff"
},
"6": {
"name": "punctuation.definition.deleted.diff"
}
},
"match": "^(((<)( .*)?)|((-).*))$\\n?",
"name": "markup.deleted.diff"
},
{
"begin": "^(#)",
"captures": {
"1": {
"name": "punctuation.definition.comment.diff"
}
},
"comment": "Git produces unified diffs with embedded comments\"",
"end": "\\n",
"name": "comment.line.number-sign.diff"
},
{
"match": "^index [0-9a-f]{7,40}\\.\\.[0-9a-f]{7,40}.*$\\n?",
"name": "meta.diff.index.git"
},
{
"captures": {
"1": {
"name": "punctuation.separator.key-value.diff"
},
"2": {
"name": "meta.toc-list.file-name.diff"
}
},
"match": "^Index(:) (.+)$\\n?",
"name": "meta.diff.index"
},
{
"match": "^Only in .*: .*$\\n?",
"name": "meta.diff.only-in"
}
],
"scopeName": "source.diff",
"uuid": "7E848FF4-708E-11D9-97B4-0011242E4184"
}

View file

@ -0,0 +1,7 @@
diff --git a/helloworld.txt b/helloworld.txt
index e4f37c4..557db03 100644
--- a/helloworld.txt
+++ b/helloworld.txt
@@ -1 +1 @@
-Hello world
+Hello World

View file

@ -0,0 +1,167 @@
[
{
"c": "diff --git a/helloworld.txt b/helloworld.txt",
"t": "source.diff meta.diff.header.git",
"r": {
"dark_plus": "meta.diff.header: #569CD6",
"light_plus": "meta.diff.header: #000080",
"dark_vs": "meta.diff.header: #569CD6",
"light_vs": "meta.diff.header: #000080",
"hc_black": "meta.diff.header: #000080"
}
},
{
"c": "index e4f37c4..557db03 100644",
"t": "source.diff meta.diff.index.git",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "---",
"t": "source.diff meta.diff.header.from-file punctuation.definition.from-file.diff",
"r": {
"dark_plus": "meta.diff.header: #569CD6",
"light_plus": "meta.diff.header: #000080",
"dark_vs": "meta.diff.header: #569CD6",
"light_vs": "meta.diff.header: #000080",
"hc_black": "meta.diff.header: #000080"
}
},
{
"c": " a/helloworld.txt",
"t": "source.diff meta.diff.header.from-file",
"r": {
"dark_plus": "meta.diff.header: #569CD6",
"light_plus": "meta.diff.header: #000080",
"dark_vs": "meta.diff.header: #569CD6",
"light_vs": "meta.diff.header: #000080",
"hc_black": "meta.diff.header: #000080"
}
},
{
"c": "+++",
"t": "source.diff meta.diff.header.to-file punctuation.definition.to-file.diff",
"r": {
"dark_plus": "meta.diff.header: #569CD6",
"light_plus": "meta.diff.header: #000080",
"dark_vs": "meta.diff.header: #569CD6",
"light_vs": "meta.diff.header: #000080",
"hc_black": "meta.diff.header: #000080"
}
},
{
"c": " b/helloworld.txt",
"t": "source.diff meta.diff.header.to-file",
"r": {
"dark_plus": "meta.diff.header: #569CD6",
"light_plus": "meta.diff.header: #000080",
"dark_vs": "meta.diff.header: #569CD6",
"light_vs": "meta.diff.header: #000080",
"hc_black": "meta.diff.header: #000080"
}
},
{
"c": "@@",
"t": "source.diff meta.diff.range.unified punctuation.definition.range.diff",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": " ",
"t": "source.diff meta.diff.range.unified",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "-1 +1",
"t": "source.diff meta.diff.range.unified meta.toc-list.line-number.diff",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": " ",
"t": "source.diff meta.diff.range.unified",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "@@",
"t": "source.diff meta.diff.range.unified punctuation.definition.range.diff",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "-",
"t": "source.diff markup.deleted.diff punctuation.definition.deleted.diff",
"r": {
"dark_plus": "markup.deleted: #CE9178",
"light_plus": "markup.deleted: #A31515",
"dark_vs": "markup.deleted: #CE9178",
"light_vs": "markup.deleted: #A31515",
"hc_black": "markup.deleted: #CE9178"
}
},
{
"c": "Hello world",
"t": "source.diff markup.deleted.diff",
"r": {
"dark_plus": "markup.deleted: #CE9178",
"light_plus": "markup.deleted: #A31515",
"dark_vs": "markup.deleted: #CE9178",
"light_vs": "markup.deleted: #A31515",
"hc_black": "markup.deleted: #CE9178"
}
},
{
"c": "+",
"t": "source.diff markup.inserted.diff punctuation.definition.inserted.diff",
"r": {
"dark_plus": "markup.inserted: #B5CEA8",
"light_plus": "markup.inserted: #09885A",
"dark_vs": "markup.inserted: #B5CEA8",
"light_vs": "markup.inserted: #09885A",
"hc_black": "markup.inserted: #B5CEA8"
}
},
{
"c": "Hello World",
"t": "source.diff markup.inserted.diff",
"r": {
"dark_plus": "markup.inserted: #B5CEA8",
"light_plus": "markup.inserted: #09885A",
"dark_vs": "markup.inserted: #B5CEA8",
"light_vs": "markup.inserted: #09885A",
"hc_black": "markup.inserted: #B5CEA8"
}
}
]

View file

@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/atom/language-go/commit/f7c6ca60bfd9d11252560b21e9378e5f82438ce3",
"version": "https://github.com/atom/language-go/commit/b6fd68f74efa109679e31fe6f4a41ac105262d0e",
"scopeName": "source.go",
"name": "Go",
"comment": "Go language",
@ -491,7 +491,7 @@
"name": "keyword.operator.increment.go"
},
{
"match": "(==|!=|<=|>=|<[^<]|>[^>])",
"match": "(==|!=|<=|>=|<(?!<)|>(?!>))",
"name": "keyword.operator.comparison.go"
},
{

View file

@ -39,7 +39,7 @@ export function activate(context: ExtensionContext) {
// The server is implemented in node
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'htmlServerMain.js'));
// The debug options for the server
let debugOptions = { execArgv: ['--nolazy', '--inspect=6004'] };
let debugOptions = { execArgv: ['--nolazy', '--inspect=6045'] };
// If the extension is launch in debug mode the debug server options are use
// Otherwise the run options are used

View file

@ -8,8 +8,8 @@
"node": "*"
},
"dependencies": {
"vscode-css-languageservice": "^3.0.2",
"vscode-html-languageservice": "^2.0.13",
"vscode-css-languageservice": "^3.0.3",
"vscode-html-languageservice": "^2.0.14",
"vscode-languageserver": "^3.5.0",
"vscode-nls": "^2.0.2",
"vscode-uri": "^1.0.1"

View file

@ -5,7 +5,6 @@
'use strict';
import { createConnection, IConnection, TextDocuments, InitializeParams, InitializeResult, RequestType, DocumentRangeFormattingRequest, Disposable, DocumentSelector, TextDocumentPositionParams, ServerCapabilities, Position } from 'vscode-languageserver';
import { DocumentContext } from 'vscode-html-languageservice';
import { TextDocument, Diagnostic, DocumentLink, SymbolInformation } from 'vscode-languageserver-types';
import { getLanguageModes, LanguageModes, Settings } from './modes/languageModes';
@ -15,13 +14,12 @@ import { DidChangeWorkspaceFoldersNotification, WorkspaceFolder } from 'vscode-l
import { format } from './modes/formatting';
import { pushAll } from './utils/arrays';
import { endsWith, startsWith } from './utils/strings';
import * as url from 'url';
import * as path from 'path';
import { getDocumentContext } from './utils/documentContext';
import uri from 'vscode-uri';
import { formatError, runSafe } from './utils/errors';
import * as nls from 'vscode-nls';
nls.config(process.env['VSCODE_NLS_CONFIG']);
namespace TagCloseRequest {
@ -34,6 +32,10 @@ let connection: IConnection = createConnection();
console.log = connection.console.log.bind(connection.console);
console.error = connection.console.error.bind(connection.console);
process.on('unhandledRejection', (e: any) => {
connection.console.error(formatError(`Unhandled exception`, e));
});
// Create a simple text document manager. The text document manager
// supports full document sync only
let documents: TextDocuments = new TextDocuments();
@ -41,7 +43,6 @@ let documents: TextDocuments = new TextDocuments();
// for open, change and close text document events
documents.listen(connection);
let workspacePath: string | undefined | null;
let workspaceFolders: WorkspaceFolder[] | undefined;
var languageModes: LanguageModes;
@ -77,8 +78,13 @@ function getDocumentSettings(textDocument: TextDocument, needsDocumentSettings:
connection.onInitialize((params: InitializeParams): InitializeResult => {
let initializationOptions = params.initializationOptions;
workspacePath = params.rootPath;
workspaceFolders = (<any>params).workspaceFolders;
if (!Array.isArray(workspaceFolders)) {
workspaceFolders = [];
if (params.rootPath) {
workspaceFolders.push({ name: '', uri: uri.file(params.rootPath).toString() });
}
}
languageModes = getLanguageModes(initializationOptions ? initializationOptions.embeddedLanguages : { css: true, javascript: true });
documents.onDidClose(e => {
@ -168,7 +174,7 @@ connection.onDidChangeConfiguration((change) => {
});
let pendingValidationRequests: { [uri: string]: NodeJS.Timer } = {};
const validationDelayMs = 200;
const validationDelayMs = 500;
// The content of a text document has changed. This event is emitted
// when the text document first opened or when its content has changed.
@ -207,191 +213,195 @@ function isValidationEnabled(languageId: string, settings: Settings = globalSett
}
async function validateTextDocument(textDocument: TextDocument) {
let diagnostics: Diagnostic[] = [];
if (textDocument.languageId === 'html') {
let modes = languageModes.getAllModesInDocument(textDocument);
let settings = await getDocumentSettings(textDocument, () => modes.some(m => !!m.doValidation));
modes.forEach(mode => {
if (mode.doValidation && isValidationEnabled(mode.getId(), settings)) {
pushAll(diagnostics, mode.doValidation(textDocument, settings));
}
});
try {
let diagnostics: Diagnostic[] = [];
if (textDocument.languageId === 'html') {
let modes = languageModes.getAllModesInDocument(textDocument);
let settings = await getDocumentSettings(textDocument, () => modes.some(m => !!m.doValidation));
modes.forEach(mode => {
if (mode.doValidation && isValidationEnabled(mode.getId(), settings)) {
pushAll(diagnostics, mode.doValidation(textDocument, settings));
}
});
}
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
} catch (e) {
connection.console.error(formatError(`Error while validating ${textDocument.uri}`, e));
}
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
}
connection.onCompletion(async textDocumentPosition => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, textDocumentPosition.position);
if (mode && mode.doComplete) {
let doComplete = mode.doComplete;
if (mode.getId() !== 'html') {
connection.telemetry.logEvent({ key: 'html.embbedded.complete', value: { languageId: mode.getId() } });
return runSafe(async () => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, textDocumentPosition.position);
if (mode && mode.doComplete) {
let doComplete = mode.doComplete;
if (mode.getId() !== 'html') {
connection.telemetry.logEvent({ key: 'html.embbedded.complete', value: { languageId: mode.getId() } });
}
let settings = await getDocumentSettings(document, () => doComplete.length > 2);
return doComplete(document, textDocumentPosition.position, settings);
}
let settings = await getDocumentSettings(document, () => doComplete.length > 2);
return doComplete(document, textDocumentPosition.position, settings);
}
return { isIncomplete: true, items: [] };
return { isIncomplete: true, items: [] };
}, null, `Error while computing completions for ${textDocumentPosition.textDocument.uri}`);
});
connection.onCompletionResolve(item => {
let data = item.data;
if (data && data.languageId && data.uri) {
let mode = languageModes.getMode(data.languageId);
let document = documents.get(data.uri);
if (mode && mode.doResolve && document) {
return mode.doResolve(document, item);
return runSafe(() => {
let data = item.data;
if (data && data.languageId && data.uri) {
let mode = languageModes.getMode(data.languageId);
let document = documents.get(data.uri);
if (mode && mode.doResolve && document) {
return mode.doResolve(document, item);
}
}
}
return item;
return item;
}, null, `Error while resolving completion proposal`);
});
connection.onHover(textDocumentPosition => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, textDocumentPosition.position);
if (mode && mode.doHover) {
return mode.doHover(document, textDocumentPosition.position);
}
return null;
return runSafe(() => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, textDocumentPosition.position);
if (mode && mode.doHover) {
return mode.doHover(document, textDocumentPosition.position);
}
return null;
}, null, `Error while computing hover for ${textDocumentPosition.textDocument.uri}`);
});
connection.onDocumentHighlight(documentHighlightParams => {
let document = documents.get(documentHighlightParams.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, documentHighlightParams.position);
if (mode && mode.findDocumentHighlight) {
return mode.findDocumentHighlight(document, documentHighlightParams.position);
}
return [];
return runSafe(() => {
let document = documents.get(documentHighlightParams.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, documentHighlightParams.position);
if (mode && mode.findDocumentHighlight) {
return mode.findDocumentHighlight(document, documentHighlightParams.position);
}
return [];
}, [], `Error while computing document highlights for ${documentHighlightParams.textDocument.uri}`);
});
connection.onDefinition(definitionParams => {
let document = documents.get(definitionParams.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, definitionParams.position);
if (mode && mode.findDefinition) {
return mode.findDefinition(document, definitionParams.position);
}
return [];
return runSafe(() => {
let document = documents.get(definitionParams.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, definitionParams.position);
if (mode && mode.findDefinition) {
return mode.findDefinition(document, definitionParams.position);
}
return [];
}, null, `Error while computing definitions for ${definitionParams.textDocument.uri}`);
});
connection.onReferences(referenceParams => {
let document = documents.get(referenceParams.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, referenceParams.position);
if (mode && mode.findReferences) {
return mode.findReferences(document, referenceParams.position);
}
return [];
return runSafe(() => {
let document = documents.get(referenceParams.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, referenceParams.position);
if (mode && mode.findReferences) {
return mode.findReferences(document, referenceParams.position);
}
return [];
}, [], `Error while computing references for ${referenceParams.textDocument.uri}`);
});
connection.onSignatureHelp(signatureHelpParms => {
let document = documents.get(signatureHelpParms.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, signatureHelpParms.position);
if (mode && mode.doSignatureHelp) {
return mode.doSignatureHelp(document, signatureHelpParms.position);
}
return null;
return runSafe(() => {
let document = documents.get(signatureHelpParms.textDocument.uri);
let mode = languageModes.getModeAtPosition(document, signatureHelpParms.position);
if (mode && mode.doSignatureHelp) {
return mode.doSignatureHelp(document, signatureHelpParms.position);
}
return null;
}, null, `Error while computing signature help for ${signatureHelpParms.textDocument.uri}`);
});
connection.onDocumentRangeFormatting(async formatParams => {
let document = documents.get(formatParams.textDocument.uri);
let settings = await getDocumentSettings(document, () => true);
if (!settings) {
settings = globalSettings;
}
let unformattedTags: string = settings && settings.html && settings.html.format && settings.html.format.unformatted || '';
let enabledModes = { css: !unformattedTags.match(/\bstyle\b/), javascript: !unformattedTags.match(/\bscript\b/) };
return runSafe(async () => {
let document = documents.get(formatParams.textDocument.uri);
let settings = await getDocumentSettings(document, () => true);
if (!settings) {
settings = globalSettings;
}
let unformattedTags: string = settings && settings.html && settings.html.format && settings.html.format.unformatted || '';
let enabledModes = { css: !unformattedTags.match(/\bstyle\b/), javascript: !unformattedTags.match(/\bscript\b/) };
return format(languageModes, document, formatParams.range, formatParams.options, settings, enabledModes);
return format(languageModes, document, formatParams.range, formatParams.options, settings, enabledModes);
}, [], `Error while formatting range for ${formatParams.textDocument.uri}`);
});
connection.onDocumentLinks(documentLinkParam => {
let document = documents.get(documentLinkParam.textDocument.uri);
let documentContext: DocumentContext = {
resolveReference: (ref, base) => {
if (base) {
ref = url.resolve(base, ref);
}
if (ref[0] === '/') {
let root = getRootFolder(document.uri);
if (root) {
return uri.file(path.join(root, ref)).toString();
return runSafe(() => {
let document = documents.get(documentLinkParam.textDocument.uri);
let links: DocumentLink[] = [];
if (document) {
let documentContext = getDocumentContext(document.uri, workspaceFolders);
languageModes.getAllModesInDocument(document).forEach(m => {
if (m.findDocumentLinks) {
pushAll(links, m.findDocumentLinks(document, documentContext));
}
}
return url.resolve(document.uri, ref);
},
};
let links: DocumentLink[] = [];
languageModes.getAllModesInDocument(document).forEach(m => {
if (m.findDocumentLinks) {
pushAll(links, m.findDocumentLinks(document, documentContext));
});
}
});
return links;
return links;
}, [], `Error while document links for ${documentLinkParam.textDocument.uri}`);
});
function getRootFolder(docUri: string): string | undefined | null {
if (workspaceFolders) {
for (let folder of workspaceFolders) {
let folderURI = folder.uri;
if (!endsWith(folderURI, '/')) {
folderURI = folderURI + '/';
}
if (startsWith(docUri, folderURI)) {
return folderURI;
}
}
return void 0;
}
return workspacePath;
}
connection.onDocumentSymbol(documentSymbolParms => {
let document = documents.get(documentSymbolParms.textDocument.uri);
let symbols: SymbolInformation[] = [];
languageModes.getAllModesInDocument(document).forEach(m => {
if (m.findDocumentSymbols) {
pushAll(symbols, m.findDocumentSymbols(document));
}
});
return symbols;
return runSafe(() => {
let document = documents.get(documentSymbolParms.textDocument.uri);
let symbols: SymbolInformation[] = [];
languageModes.getAllModesInDocument(document).forEach(m => {
if (m.findDocumentSymbols) {
pushAll(symbols, m.findDocumentSymbols(document));
}
});
return symbols;
}, [], `Error while computing document symbols for ${documentSymbolParms.textDocument.uri}`);
});
connection.onRequest(DocumentColorRequest.type, params => {
let infos: ColorInformation[] = [];
let document = documents.get(params.textDocument.uri);
if (document) {
languageModes.getAllModesInDocument(document).forEach(m => {
if (m.findDocumentColors) {
pushAll(infos, m.findDocumentColors(document));
}
});
}
return infos;
return runSafe(() => {
let infos: ColorInformation[] = [];
let document = documents.get(params.textDocument.uri);
if (document) {
languageModes.getAllModesInDocument(document).forEach(m => {
if (m.findDocumentColors) {
pushAll(infos, m.findDocumentColors(document));
}
});
}
return infos;
}, [], `Error while computing document colors for ${params.textDocument.uri}`);
});
connection.onRequest(ColorPresentationRequest.type, params => {
let document = documents.get(params.textDocument.uri);
if (document) {
let mode = languageModes.getModeAtPosition(document, params.range.start);
if (mode && mode.getColorPresentations) {
return mode.getColorPresentations(document, params.color, params.range);
return runSafe(() => {
let document = documents.get(params.textDocument.uri);
if (document) {
let mode = languageModes.getModeAtPosition(document, params.range.start);
if (mode && mode.getColorPresentations) {
return mode.getColorPresentations(document, params.color, params.range);
}
}
}
return [];
return [];
}, [], `Error while computing color presentations for ${params.textDocument.uri}`);
});
connection.onRequest(TagCloseRequest.type, params => {
let document = documents.get(params.textDocument.uri);
if (document) {
let pos = params.position;
if (pos.character > 0) {
let mode = languageModes.getModeAtPosition(document, Position.create(pos.line, pos.character - 1));
if (mode && mode.doAutoClose) {
return mode.doAutoClose(document, pos);
return runSafe(() => {
let document = documents.get(params.textDocument.uri);
if (document) {
let pos = params.position;
if (pos.character > 0) {
let mode = languageModes.getModeAtPosition(document, Position.create(pos.line, pos.character - 1));
if (mode && mode.doAutoClose) {
return mode.doAutoClose(document, pos);
}
}
}
}
return null;
return null;
}, null, `Error while computing tag close actions for ${params.textDocument.uri}`);
});

View file

@ -0,0 +1,22 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as assert from 'assert';
import { getDocumentContext } from '../utils/documentContext';
suite('Document Context', () => {
test('Context', function (): any {
const docURI = 'file:///users/test/folder/test.html';
const rootFolders = [{ name: '', uri: 'file:///users/test/' }];
let context = getDocumentContext(docURI, rootFolders);
assert.equal(context.resolveReference('/', docURI), 'file:///users/test/');
assert.equal(context.resolveReference('/message.html', docURI), 'file:///users/test/message.html');
assert.equal(context.resolveReference('message.html', docURI), 'file:///users/test/folder/message.html');
assert.equal(context.resolveReference('message.html', 'file:///users/test/'), 'file:///users/test/message.html');
});
});

View file

@ -0,0 +1,40 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { DocumentContext } from 'vscode-html-languageservice';
import { endsWith, startsWith } from '../utils/strings';
import * as url from 'url';
import { WorkspaceFolder } from 'vscode-languageserver-protocol/lib/protocol.workspaceFolders.proposed';
export function getDocumentContext(documentUri: string, workspaceFolders: WorkspaceFolder[]): DocumentContext {
function getRootFolder(): string | undefined {
for (let folder of workspaceFolders) {
let folderURI = folder.uri;
if (!endsWith(folderURI, '/')) {
folderURI = folderURI + '/';
}
if (startsWith(documentUri, folderURI)) {
return folderURI;
}
}
return void 0;
}
return {
resolveReference: (ref, base = documentUri) => {
if (ref[0] === '/') { // resolve absolute path against the current workspace folder
if (startsWith(base, 'file://')) {
let folderUri = getRootFolder();
if (folderUri) {
return folderUri + ref.substr(1);
}
}
}
return url.resolve(base, ref);
},
};
}

View file

@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
export function formatError(message: string, err: any): string {
if (err instanceof Error) {
let error = <Error>err;
return `${message}: ${error.message}\n${error.stack}`;
} else if (typeof err === 'string') {
return `${message}: ${err}`;
} else if (err) {
return `${message}: ${err.toString()}`;
}
return message;
}
export function runSafe<T>(func: () => Thenable<T> | T, errorVal: T, errorMessage: string): Thenable<T> | T {
try {
let t = func();
if (t instanceof Promise) {
return t.then(void 0, e => {
console.error(formatError(errorMessage, e));
return errorVal;
});
}
return t;
} catch (e) {
console.error(formatError(errorMessage, e));
return errorVal;
}
}

View file

@ -10,16 +10,16 @@
version "7.0.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c"
vscode-css-languageservice@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.2.tgz#ae0c43836318455aa290c777556394d6127b8f6c"
vscode-css-languageservice@^3.0.3:
version "3.0.3"
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-3.0.3.tgz#02cc4efa5335f5104e0a2f3b6920faaf59db4f7a"
dependencies:
vscode-languageserver-types "3.5.0"
vscode-nls "^2.0.1"
vscode-html-languageservice@^2.0.13:
version "2.0.13"
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-2.0.13.tgz#09c4437cffb0800b865d71552f4dfd8240c796d8"
vscode-html-languageservice@^2.0.14:
version "2.0.14"
resolved "https://registry.yarnpkg.com/vscode-html-languageservice/-/vscode-html-languageservice-2.0.14.tgz#15491c11bb7e196f6fd03b6c6c768901935862eb"
dependencies:
vscode-languageserver-types "3.5.0"
vscode-nls "^2.0.2"

View file

@ -11,8 +11,8 @@
],
"main": "./out/javascriptMain",
"dependencies": {
"jsonc-parser": "^0.3.1",
"request-light": "^0.2.0",
"jsonc-parser": "^1.0.0",
"request-light": "^0.2.2",
"vscode-nls": "^2.0.2"
},
"scripts": {
@ -101,27 +101,27 @@
"jsonValidation": [
{
"fileMatch": "package.json",
"url": "http://json.schemastore.org/package"
"url": "https://schemastore.azurewebsites.net/schemas/json/package.json"
},
{
"fileMatch": "bower.json",
"url": "http://json.schemastore.org/bower"
"url": "https://schemastore.azurewebsites.net/schemas/json/bower.json"
},
{
"fileMatch": ".bowerrc",
"url": "http://json.schemastore.org/bowerrc"
"url": "https://schemastore.azurewebsites.net/schemas/json/bowerrc.json"
},
{
"fileMatch": ".babelrc",
"url": "http://json.schemastore.org/babelrc"
"url": "https://schemastore.azurewebsites.net/schemas/json/babelrc.json"
},
{
"fileMatch": ".babelrc.json",
"url": "http://json.schemastore.org/babelrc"
"url": "https://schemastore.azurewebsites.net/schemas/json/babelrc.json"
},
{
"fileMatch": "jsconfig.json",
"url": "http://json.schemastore.org/jsconfig"
"url": "https://schemastore.azurewebsites.net/schemas/json/jsconfig.json"
},
{
"fileMatch": "jsconfig.json",
@ -129,7 +129,7 @@
},
{
"fileMatch": "jsconfig.*.json",
"url": "http://json.schemastore.org/jsconfig"
"url": "https://schemastore.azurewebsites.net/schemas/json/jsconfig.json"
},
{
"fileMatch": "jsconfig.*.json",

File diff suppressed because one or more lines are too long

File diff suppressed because one or more lines are too long

View file

@ -6,9 +6,11 @@
version "8.0.33"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.33.tgz#1126e94374014e54478092830704f6ea89df04cd"
agent-base@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-1.0.2.tgz#6890d3fb217004b62b70f8928e0fae5f8952a706"
agent-base@4, agent-base@^4.1.0:
version "4.1.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.1.2.tgz#80fa6cde440f4dcf9af2617cf246099b5d99f0c8"
dependencies:
es6-promisify "^5.0.0"
debug@2:
version "2.2.0"
@ -16,42 +18,54 @@ debug@2:
dependencies:
ms "0.7.1"
extend@3:
version "3.0.0"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.0.tgz#5a474353b9f3353ddd8176dfd37b91c83a46f1d4"
http-proxy-agent@^0.2.6:
version "0.2.7"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-0.2.7.tgz#e17fda65f0902d952ce7921e62c7ff8862655a5e"
debug@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
dependencies:
agent-base "~1.0.1"
ms "2.0.0"
es6-promise@^4.0.3:
version "4.1.1"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a"
es6-promisify@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
dependencies:
es6-promise "^4.0.3"
http-proxy-agent@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.0.0.tgz#46482a2f0523a4d6082551709f469cb3e4a85ff4"
dependencies:
agent-base "4"
debug "2"
extend "3"
https-proxy-agent@^0.3.5:
version "0.3.6"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-0.3.6.tgz#713fa38e5d353f50eb14a342febe29033ed1619b"
https-proxy-agent@2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.1.1.tgz#a7ce4382a1ba8266ee848578778122d491260fd9"
dependencies:
agent-base "~1.0.1"
debug "2"
extend "3"
agent-base "^4.1.0"
debug "^3.1.0"
jsonc-parser@^0.3.1:
version "0.3.1"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-0.3.1.tgz#6ebf5c75224368d4b07ef4c26f9434e657472e95"
dependencies:
vscode-nls "^2.0.2"
jsonc-parser@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-1.0.0.tgz#ddcc864ae708e60a7a6dd36daea00172fa8d9272"
ms@0.7.1:
version "0.7.1"
resolved "https://registry.yarnpkg.com/ms/-/ms-0.7.1.tgz#9cd13c03adbff25b65effde7ce864ee952017098"
request-light@^0.2.0:
version "0.2.0"
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.0.tgz#922497791c2e68528124dfb82354cf37e4bb2cfc"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
request-light@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.2.tgz#53e48af32ad1514e45221ea5ece5ce782720f712"
dependencies:
http-proxy-agent "^0.2.6"
https-proxy-agent "^0.3.5"
http-proxy-agent "2.0.0"
https-proxy-agent "2.1.1"
vscode-nls "^2.0.2"
vscode-nls@^2.0.2:

View file

@ -67,7 +67,7 @@ export function activate(context: ExtensionContext) {
// The server is implemented in node
let serverModule = context.asAbsolutePath(path.join('server', 'out', 'jsonServerMain.js'));
// The debug options for the server
let debugOptions = { execArgv: ['--nolazy', '--inspect'] };
let debugOptions = { execArgv: ['--nolazy', '--inspect=6046'] };
// If the extension is launch in debug mode the debug server options are use
// Otherwise the run options are used

View file

@ -9,7 +9,7 @@
},
"dependencies": {
"jsonc-parser": "^1.0.0",
"request-light": "^0.2.1",
"request-light": "^0.2.2",
"vscode-json-languageservice": "^3.0.4",
"vscode-languageserver": "^3.5.0",
"vscode-nls": "^2.0.2",

View file

@ -105,7 +105,7 @@ let schemaRequestService = (uri: string): Thenable<string> => {
return connection.sendRequest(VSCodeContentRequest.type, uri).then(responseText => {
return responseText;
}, error => {
return error.message;
return Promise.reject(error.message);
});
}
if (uri.indexOf('//schema.management.azure.com/') !== -1) {
@ -232,7 +232,7 @@ documents.onDidClose(event => {
});
let pendingValidationRequests: { [uri: string]: NodeJS.Timer; } = {};
const validationDelayMs = 200;
const validationDelayMs = 500;
function cleanPendingValidation(textDocument: TextDocument): void {
let request = pendingValidationRequests[textDocument.uri];

View file

@ -6,9 +6,11 @@
version "7.0.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c"
agent-base@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-1.0.2.tgz#6890d3fb217004b62b70f8928e0fae5f8952a706"
agent-base@4, agent-base@^4.1.0:
version "4.1.2"
resolved "https://registry.yarnpkg.com/agent-base/-/agent-base-4.1.2.tgz#80fa6cde440f4dcf9af2617cf246099b5d99f0c8"
dependencies:
es6-promisify "^5.0.0"
debug@2:
version "2.6.9"
@ -16,25 +18,35 @@ debug@2:
dependencies:
ms "2.0.0"
extend@3:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
http-proxy-agent@^0.2.6:
version "0.2.7"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-0.2.7.tgz#e17fda65f0902d952ce7921e62c7ff8862655a5e"
debug@^3.1.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.1.0.tgz#5bb5a0672628b64149566ba16819e61518c67261"
dependencies:
agent-base "~1.0.1"
debug "2"
extend "3"
ms "2.0.0"
https-proxy-agent@^0.3.5:
version "0.3.6"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-0.3.6.tgz#713fa38e5d353f50eb14a342febe29033ed1619b"
es6-promise@^4.0.3:
version "4.1.1"
resolved "https://registry.yarnpkg.com/es6-promise/-/es6-promise-4.1.1.tgz#8811e90915d9a0dba36274f0b242dbda78f9c92a"
es6-promisify@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/es6-promisify/-/es6-promisify-5.0.0.tgz#5109d62f3e56ea967c4b63505aef08291c8a5203"
dependencies:
agent-base "~1.0.1"
es6-promise "^4.0.3"
http-proxy-agent@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/http-proxy-agent/-/http-proxy-agent-2.0.0.tgz#46482a2f0523a4d6082551709f469cb3e4a85ff4"
dependencies:
agent-base "4"
debug "2"
extend "3"
https-proxy-agent@2.1.1:
version "2.1.1"
resolved "https://registry.yarnpkg.com/https-proxy-agent/-/https-proxy-agent-2.1.1.tgz#a7ce4382a1ba8266ee848578778122d491260fd9"
dependencies:
agent-base "^4.1.0"
debug "^3.1.0"
jsonc-parser@^1.0.0:
version "1.0.0"
@ -44,12 +56,12 @@ ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
request-light@^0.2.1:
version "0.2.1"
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.1.tgz#986f5a82893e9d1ca6a896ebe6f46c51c6b4557f"
request-light@^0.2.2:
version "0.2.2"
resolved "https://registry.yarnpkg.com/request-light/-/request-light-0.2.2.tgz#53e48af32ad1514e45221ea5ece5ce782720f712"
dependencies:
http-proxy-agent "^0.2.6"
https-proxy-agent "^0.3.5"
http-proxy-agent "2.0.0"
https-proxy-agent "2.1.1"
vscode-nls "^2.0.2"
vscode-json-languageservice@^3.0.4:

View file

@ -0,0 +1,9 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[
{
"name": "vscode-logfile-highlighter",
"version": "1.2.0",
"license": "MIT",
"repositoryURL": "https://github.com/emilast/vscode-logfile-highlighter"
}
]

View file

@ -0,0 +1,37 @@
{
"name": "log",
"version": "0.1.0",
"publisher": "vscode",
"engines": {
"vscode": "*"
},
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js emilast/vscode-logfile-highlighter syntaxes/log.tmLanguage ./syntaxes/log.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "log",
"extensions": [
".log",
"*.log.?"
],
"aliases": [
"log"
]
}
],
"grammars": [
{
"language": "Log",
"scopeName": "text.log",
"path": "./syntaxes/log.tmLanguage.json"
},
{
"language": "log",
"scopeName": "text.log",
"path": "./syntaxes/log.tmLanguage.json"
}
]
}
}

View file

@ -0,0 +1,93 @@
{
"information_for_contributors": [
"This file has been converted from https://github.com/emilast/vscode-logfile-highlighter/blob/master/syntaxes/log.tmLanguage",
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/emilast/vscode-logfile-highlighter/commit/3f3ea0a69165bc95f62bb487fda73e925ae229a6",
"scopeName": "text.log",
"fileTypes": [
"log"
],
"name": "Log file",
"patterns": [
{
"match": "\\b(DEBUG)\\b|(?i)\\b(debug)\\:",
"name": "markup.changed log.debug"
},
{
"match": "(?i)\\[(debug|dbug|dbg|de|d)\\]",
"name": "markup.changed log.debug"
},
{
"match": "\\b(HINT|INFO|INFORMATION)\\b|(?i)\\b(info|information)\\:",
"name": "markup.inserted log.info"
},
{
"match": "(?i)\\[(information|info|inf|in|i)\\]",
"name": "markup.inserted log.info"
},
{
"match": "\\b(WARNING|WARN)\\b|(?i)\\b(warning)\\:",
"name": "markup.deleted log.warning"
},
{
"match": "(?i)\\[(warning|warn|wrn|wn|w)\\]",
"name": "markup.deleted log.warning"
},
{
"match": "\\b(ERROR|FAILURE|FAIL)\\b|(?i)\\b(error)\\:",
"name": "string.regexp, strong log.error"
},
{
"match": "(?i)\\[(error|eror|err|er|e|fatal|fatl|ftl|fa|f)\\]",
"name": "string.regexp, strong log.error"
},
{
"match": "\\b\\d{4}-\\d{2}-\\d{2}(T|\\b)",
"name": "comment log.date"
},
{
"match": "\\b\\d{2}[^\\w\\s]\\d{2}[^\\w\\s]\\d{4}\\b",
"name": "comment log.date"
},
{
"match": "\\d{2}:\\d{2}(:\\d{2}([.,]\\d{3,6})?)?(Z| ?[+-]\\d{2}:\\d{2})?\\b",
"name": "comment log.date"
},
{
"match": "[0-9a-fA-F]{8}[-]?([0-9a-fA-F]{4}[-]?){3}[0-9a-fA-F]{12}",
"name": "constant.language log.constant"
},
{
"match": "\\b([0-9]+|true|false|null)\\b",
"name": "constant.language log.constant"
},
{
"match": "\"[^\"]*\"",
"name": "string log.string"
},
{
"match": "'[^']*'",
"name": "string log.string"
},
{
"match": "\\b([a-zA-Z.]*Exception)\\b",
"name": "string.regexp, emphasis log.type"
},
{
"begin": "^[\\t ]*at",
"end": "$",
"name": "string.key, emphasis log.exception"
},
{
"match": "\\b(http|https|ftp|file)://\\S+\\b/?",
"name": "constant.language log.constant"
},
{
"match": "\\b([\\w]+\\.)+(\\w)+\\b",
"name": "constant.language log.constant"
}
],
"uuid": "E81BB6AB-CAC7-4C27-9A79-4137A4693EBD"
}

View file

@ -0,0 +1,9 @@
[2017-12-21 12:47:29.584] [renderer1] [trace] CommandService#executeCommand workbench.view.explorer
[2017-12-21 12:47:29.614] [renderer1] [trace] CommandService#executeCommand setContext
[2017-12-21 12:47:29.632] [renderer1] [trace] SCMService#registerSCMProvider
[2017-12-21 12:47:29.636] [renderer1] [trace] CommandService#executeCommand setContext
[2017-12-21 12:47:32.164] [renderer1] [trace] CommandService#executeCommand workbench.action.showCommands
[2017-12-21 12:47:33.122] [renderer1] [trace] CommandService#executeCommand workbench.action.openLogFile
[2017-12-21 12:47:34.249] [renderer1] [trace] CommandService#executeCommand workbench.action.openLogViewer
[2017-12-21 12:47:48.078] [renderer1] [trace] CommandService#executeCommand workbench.action.showCommands
[2017-12-21 12:47:49.294] [renderer1] [trace] CommandService#executeCommand workbench.action.reloadWindow

View file

@ -0,0 +1,563 @@
[
{
"c": "[",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "2017-12-21",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": " ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "12:47:29.584",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": "] [renderer1] [trace] CommandService#executeCommand ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "workbench.view.explorer",
"t": "text.log constant.language log.constant",
"r": {
"dark_plus": "constant.language: #569CD6",
"light_plus": "constant.language: #0000FF",
"dark_vs": "constant.language: #569CD6",
"light_vs": "constant.language: #0000FF",
"hc_black": "constant.language: #569CD6"
}
},
{
"c": "[",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "2017-12-21",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": " ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "12:47:29.614",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": "] [renderer1] [trace] CommandService#executeCommand setContext",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "[",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "2017-12-21",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": " ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "12:47:29.632",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": "] [renderer1] [trace] SCMService#registerSCMProvider",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "[",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "2017-12-21",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": " ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "12:47:29.636",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": "] [renderer1] [trace] CommandService#executeCommand setContext",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "[",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "2017-12-21",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": " ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "12:47:32.164",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": "] [renderer1] [trace] CommandService#executeCommand ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "workbench.action.showCommands",
"t": "text.log constant.language log.constant",
"r": {
"dark_plus": "constant.language: #569CD6",
"light_plus": "constant.language: #0000FF",
"dark_vs": "constant.language: #569CD6",
"light_vs": "constant.language: #0000FF",
"hc_black": "constant.language: #569CD6"
}
},
{
"c": "[",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "2017-12-21",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": " ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "12:47:33.122",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": "] [renderer1] [trace] CommandService#executeCommand ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "workbench.action.openLogFile",
"t": "text.log constant.language log.constant",
"r": {
"dark_plus": "constant.language: #569CD6",
"light_plus": "constant.language: #0000FF",
"dark_vs": "constant.language: #569CD6",
"light_vs": "constant.language: #0000FF",
"hc_black": "constant.language: #569CD6"
}
},
{
"c": "[",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "2017-12-21",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": " ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "12:47:34.249",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": "] [renderer1] [trace] CommandService#executeCommand ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "workbench.action.openLogViewer",
"t": "text.log constant.language log.constant",
"r": {
"dark_plus": "constant.language: #569CD6",
"light_plus": "constant.language: #0000FF",
"dark_vs": "constant.language: #569CD6",
"light_vs": "constant.language: #0000FF",
"hc_black": "constant.language: #569CD6"
}
},
{
"c": "[",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "2017-12-21",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": " ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "12:47:48.078",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": "] [renderer1] [trace] CommandService#executeCommand ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "workbench.action.showCommands",
"t": "text.log constant.language log.constant",
"r": {
"dark_plus": "constant.language: #569CD6",
"light_plus": "constant.language: #0000FF",
"dark_vs": "constant.language: #569CD6",
"light_vs": "constant.language: #0000FF",
"hc_black": "constant.language: #569CD6"
}
},
{
"c": "[",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "2017-12-21",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": " ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "12:47:49.294",
"t": "text.log comment log.date",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": "] [renderer1] [trace] CommandService#executeCommand ",
"t": "text.log",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "workbench.action.reloadWindow",
"t": "text.log constant.language log.constant",
"r": {
"dark_plus": "constant.language: #569CD6",
"light_plus": "constant.language: #0000FF",
"dark_vs": "constant.language: #569CD6",
"light_vs": "constant.language: #0000FF",
"hc_black": "constant.language: #569CD6"
}
}
]

View file

@ -15,38 +15,6 @@
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER", "LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
},
{
"isLicense": true,
"name": "markdown-it-named-headers",
"licenseDetail": [
"Copyright (c) markdown-it-named-headers authors",
"",
"This is free and unencumbered software released into the public domain.",
"",
"Anyone is free to copy, modify, publish, use, compile, sell, or",
"distribute this software, either in source code form or as a compiled",
"binary, for any purpose, commercial or non-commercial, and by any",
"means.",
"",
"In jurisdictions that recognize copyright laws, the author or authors",
"of this software dedicate any and all copyright interest in the",
"software to the public domain. We make this dedication for the benefit",
"of the public at large and to the detriment of our heirs and",
"successors. We intend this dedication to be an overt act of",
"relinquishment in perpetuity of all present and future rights to this",
"software under copyright law.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND,",
"EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF",
"MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT.",
"IN NO EVENT SHALL THE AUTHORS BE LIABLE FOR ANY CLAIM, DAMAGES OR",
"OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,",
"ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR",
"OTHER DEALINGS IN THE SOFTWARE.",
"",
"For more information, please refer to <http://unlicense.org/>"
]
},
{
"name": "textmate/markdown.tmbundle",
"version": "0.0.0",
@ -67,23 +35,4 @@
"to the base-name name of the original file, and an extension of txt, html, or similar. For example",
"\"tidy\" is accompanied by \"tidy-license.txt\"."
]
},
{
"isLicense": true,
"name": "uc.micro",
"licenseDetail": [
" DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE",
" Version 2, December 2004",
"",
" Copyright (C) 2004 Sam Hocevar <sam@hocevar.net>",
"",
" Everyone is permitted to copy and distribute verbatim or modified",
" copies of this license document, and changing it is allowed as long",
" as the name is changed.",
"",
" DO WHAT THE FUCK YOU WANT TO PUBLIC LICENSE",
" TERMS AND CONDITIONS FOR COPYING, DISTRIBUTION AND MODIFICATION",
"",
" 0. You just DO WHAT THE FUCK YOU WANT TO."
]
}]

View file

@ -39,6 +39,10 @@
["`", "`"]
],
"folding": {
"offSide": true
"offSide": true,
"markers": {
"start": "^\\s*<!--\\s*#?region\\b.*-->",
"end": "^\\s*<!--\\s*#?endregion\\b.*-->"
}
}
}
}

View file

@ -2,7 +2,7 @@
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
// @ts-check
'use strict';
(function () {
@ -29,24 +29,58 @@
};
}
/**
* @param {string} command
* @param {any[]} args
*/
function postMessage(command, args) {
window.parent.postMessage({
command: 'did-click-link',
data: `command:${command}?${encodeURIComponent(JSON.stringify(args))}`
}, 'file://');
}
/**
* @typedef {{ element: Element, line: number }} CodeLineElement
*/
/**
* @return {CodeLineElement[]}
*/
const getCodeLineElements = (() => {
/** @type {CodeLineElement[]} */
let elements;
return () => {
if (!elements) {
elements = Array.prototype.map.call(
document.getElementsByClassName('code-line'),
element => {
const line = +element.getAttribute('data-line');
return { element, line }
})
.filter(x => !isNaN(x.line));
}
return elements;
};
})()
/**
* Find the html elements that map to a specific target line in the editor.
*
* If an exact match, returns a single element. If the line is between elements,
* returns the element prior to and the element after the given line.
*
* @param {number} targetLine
*
* @returns {{ previous: CodeLineElement, next?: CodeLineElement }}
*/
function getElementsForSourceLine(targetLine) {
const lines = document.getElementsByClassName('code-line');
let previous = lines[0] && +lines[0].getAttribute('data-line') ? { line: +lines[0].getAttribute('data-line'), element: lines[0] } : null;
for (const element of lines) {
const lineNumber = +element.getAttribute('data-line');
if (isNaN(lineNumber)) {
continue;
}
const entry = { line: lineNumber, element: element };
if (lineNumber === targetLine) {
const lines = getCodeLineElements();
let previous = lines[0] || null;
for (const entry of lines) {
if (entry.line === targetLine) {
return { previous: entry, next: null };
} else if (lineNumber > targetLine) {
} else if (entry.line > targetLine) {
return { previous, next: entry };
}
previous = entry;
@ -56,28 +90,37 @@
/**
* Find the html elements that are at a specific pixel offset on the page.
*
* @returns {{ previous: CodeLineElement, next?: CodeLineElement }}
*/
function getLineElementsAtPageOffset(offset) {
const lines = document.getElementsByClassName('code-line');
const lines = getCodeLineElements()
const position = offset - window.scrollY;
let previous = null;
for (const element of lines) {
const line = +element.getAttribute('data-line');
if (isNaN(line)) {
continue;
let lo = -1;
let hi = lines.length - 1;
while (lo + 1 < hi) {
const mid = Math.floor((lo + hi) / 2);
const bounds = lines[mid].element.getBoundingClientRect();
if (bounds.top + bounds.height >= position) {
hi = mid;
} else {
lo = mid;
}
const bounds = element.getBoundingClientRect();
const entry = { element, line };
if (position < bounds.top) {
if (previous && previous.fractional < 1) {
previous.line += previous.fractional;
return { previous };
}
return { previous, next: entry };
}
entry.fractional = (position - bounds.top) / (bounds.height);
previous = entry;
}
const hiElement = lines[hi];
if (hi >= 1 && hiElement.element.getBoundingClientRect().top > position) {
const loElement = lines[lo];
const bounds = loElement.element.getBoundingClientRect();
const previous = { element: loElement.element, line: loElement.line + (position - bounds.top) / (bounds.height) };
const next = { element: hiElement.element, line: hiElement.line, fractional: 0 };
return { previous, next };
}
const bounds = hiElement.element.getBoundingClientRect();
const previous = { element: hiElement.element, line: hiElement.line + (position - bounds.top) / (bounds.height) };
return { previous };
}
@ -87,6 +130,8 @@
/**
* Attempt to reveal the element for a source line in the editor.
*
* @param {number} line
*/
function scrollToRevealSourceLine(line) {
const { previous, next } = getElementsForSourceLine(line);
@ -196,14 +241,37 @@
const offset = event.pageY;
const line = getEditorLineNumberForPageOffset(offset);
if (!isNaN(line)) {
const args = [settings.source, line];
window.parent.postMessage({
command: "did-click-link",
data: `command:_markdown.didClick?${encodeURIComponent(JSON.stringify(args))}`
}, "file://");
postMessage('_markdown.didClick', [settings.source, line]);
}
});
document.addEventListener('click', event => {
if (!event) {
return;
}
const baseElement = document.getElementsByTagName('base')[0];
/** @type {*} */
let node = event.target;
while (node) {
if (node.tagName && node.tagName.toLowerCase() === 'a' && node.href) {
if (node.getAttribute('href').startsWith('#')) {
break;
}
if (node.href.startsWith('file://')) {
const [path, fragment] = node.href.replace(/^file:\/\//i, '').split('#');
postMessage('_markdown.openDocumentLink', { path, fragment });
event.preventDefault();
event.stopPropagation();
break;
}
break;
}
node = node.parentNode;
}
}, true);
if (settings.scrollEditorWithPreview) {
window.addEventListener('scroll', throttle(() => {
if (scrollDisabled) {
@ -211,11 +279,7 @@
} else {
const line = getEditorLineNumberForPageOffset(window.scrollY);
if (!isNaN(line)) {
const args = [settings.source, line];
window.parent.postMessage({
command: 'did-click-link',
data: `command:_markdown.revealLine?${encodeURIComponent(JSON.stringify(args))}`
}, 'file://');
postMessage('_markdown.revealLine', [settings.source, line]);
}
}
}, 50));

View file

@ -311,8 +311,8 @@
"highlight.js": "9.5.0",
"markdown-it": "^8.4.0",
"markdown-it-named-headers": "0.0.4",
"vscode-extension-telemetry": "0.0.8",
"vscode-nls": "2.0.2"
"vscode-extension-telemetry": "^0.0.8",
"vscode-nls": "^2.0.2"
},
"devDependencies": {
"@types/highlight.js": "9.1.10",
@ -321,4 +321,4 @@
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.5.4"
}
}
}

View file

@ -140,7 +140,7 @@ export class RefreshPreviewCommand implements Command {
} else {
// update all generated md documents
for (const document of vscode.workspace.textDocuments) {
if (document.uri.scheme === 'markdown') {
if (document.uri.scheme === MDDocumentContentProvider.scheme) {
this.contentProvider.update(document.uri);
}
}
@ -264,6 +264,16 @@ export class OpenDocumentLinkCommand implements Command {
new vscode.Range(line, 0, line, 0),
vscode.TextEditorRevealType.AtTop);
}
const lineNumberFragment = args.fragment.match(/^L(\d+)$/);
if (lineNumberFragment) {
const line = +lineNumberFragment[1] - 1;
if (!isNaN(line)) {
return editor.revealRange(
new vscode.Range(line, 0, line, 0),
vscode.TextEditorRevealType.AtTop);
}
}
}
};

View file

@ -28,7 +28,7 @@ export function activate(context: vscode.ExtensionContext) {
const selector = 'markdown';
const contentProvider = new MDDocumentContentProvider(engine, context, cspArbiter, logger);
context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider(selector, contentProvider));
context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider(MDDocumentContentProvider.scheme, contentProvider));
loadMarkdownExtensions(contentProvider, engine);

View file

@ -22,16 +22,16 @@ const previewStrings = {
export function isMarkdownFile(document: vscode.TextDocument) {
return document.languageId === 'markdown'
&& document.uri.scheme !== 'markdown'; // prevent processing of own documents
&& document.uri.scheme !== MDDocumentContentProvider.scheme; // prevent processing of own documents
}
export function getMarkdownUri(uri: vscode.Uri) {
if (uri.scheme === 'markdown') {
if (uri.scheme === MDDocumentContentProvider.scheme) {
return uri;
}
return uri.with({
scheme: 'markdown',
scheme: MDDocumentContentProvider.scheme,
path: uri.path + '.rendered',
query: uri.toString()
});
@ -139,6 +139,8 @@ class PreviewConfigManager {
}
export class MDDocumentContentProvider implements vscode.TextDocumentContentProvider {
public static readonly scheme = 'markdown';
private _onDidChange = new vscode.EventEmitter<vscode.Uri>();
private _waiting: boolean = false;
private previewConfigurations = new PreviewConfigManager();
@ -279,7 +281,7 @@ export class MDDocumentContentProvider implements vscode.TextDocumentContentProv
public updateConfiguration() {
// update all generated md documents
for (const document of vscode.workspace.textDocuments) {
if (document.uri.scheme === 'markdown') {
if (document.uri.scheme === MDDocumentContentProvider.scheme) {
const sourceUri = vscode.Uri.parse(document.uri.query);
if (this.previewConfigurations.shouldUpdateConfiguration(sourceUri)) {
this.update(document.uri);

View file

@ -137,8 +137,9 @@ export class MarkdownEngine {
md.normalizeLink = (link: string) => {
try {
let uri = vscode.Uri.parse(link);
if (!uri.scheme && uri.path && !uri.fragment) {
if (!uri.scheme && uri.path) {
// Assume it must be a file
const fragment = uri.fragment;
if (uri.path[0] === '/') {
const root = vscode.workspace.getWorkspaceFolder(this.currentDocument);
if (root) {
@ -147,6 +148,10 @@ export class MarkdownEngine {
} else {
uri = vscode.Uri.file(path.join(path.dirname(this.currentDocument.path), uri.path));
}
if (fragment) {
uri = uri.with({ fragment });
}
return normalizeLink(uri.toString(true));
}
} catch (e) {

View file

@ -522,11 +522,11 @@
<array>
<dict>
<key>include</key>
<string>#list_paragraph</string>
<string>#block</string>
</dict>
<dict>
<key>include</key>
<string>#block</string>
<string>#list_paragraph</string>
</dict>
</array>
<key>while</key>
@ -549,11 +549,11 @@
<array>
<dict>
<key>include</key>
<string>#list_paragraph</string>
<string>#block</string>
</dict>
<dict>
<key>include</key>
<string>#block</string>
<string>#list_paragraph</string>
</dict>
</array>
<key>while</key>

View file

@ -347,11 +347,11 @@
<array>
<dict>
<key>include</key>
<string>#list_paragraph</string>
<string>#block</string>
</dict>
<dict>
<key>include</key>
<string>#block</string>
<string>#list_paragraph</string>
</dict>
</array>
<key>while</key>
@ -374,11 +374,11 @@
<array>
<dict>
<key>include</key>
<string>#list_paragraph</string>
<string>#block</string>
</dict>
<dict>
<key>include</key>
<string>#block</string>
<string>#list_paragraph</string>
</dict>
</array>
<key>while</key>

View file

@ -155,14 +155,14 @@ util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
vscode-extension-telemetry@0.0.8:
vscode-extension-telemetry@^0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.0.8.tgz#2261bff986b6690a6f1f746a45ac5bd1f85d29e0"
dependencies:
applicationinsights "0.18.0"
winreg "1.2.3"
vscode-nls@2.0.2:
vscode-nls@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"

View file

@ -1,16 +0,0 @@
[{
"isLicense": true,
"name": "@types/source-map",
"repositoryURL": "https://www.github.com/DefinitelyTyped/DefinitelyTyped",
"license": "MIT",
"licenseDetail": [
"This project is licensed under the MIT license.",
"Copyrights are respective of each contributor listed at the beginning of each definition file.",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED \"AS IS\", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
}]

View file

@ -1,6 +1,6 @@
{
"name": "node-debug",
"version": "1.19.2",
"version": "1.19.7",
"lockfileVersion": 1,
"requires": true,
"dependencies": {
@ -42,21 +42,21 @@
}
},
"@types/mocha": {
"version": "2.2.42",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.42.tgz",
"integrity": "sha512-b6gVDoxEbAQGwbV7gSzeFw/hy3/eEAokztktdzl4bHvGgb9K5zW4mVQDlVYch2w31m8t/J7L2iqhQvz3r5edCQ==",
"version": "2.2.44",
"resolved": "https://registry.npmjs.org/@types/mocha/-/mocha-2.2.44.tgz",
"integrity": "sha512-k2tWTQU8G4+iSMvqKi0Q9IIsWAp/n8xzdZS4Q4YVIltApoMA00wFBFdlJnmoaK1/z7B0Cy0yPe6GgXteSmdUNw==",
"dev": true
},
"@types/node": {
"version": "6.0.52",
"resolved": "https://registry.npmjs.org/@types/node/-/node-6.0.52.tgz",
"integrity": "sha1-GsOpm0IyD55GNILyWvTCNZRzqqY=",
"version": "7.0.43",
"resolved": "https://registry.npmjs.org/@types/node/-/node-7.0.43.tgz",
"integrity": "sha512-7scYwwfHNppXvH/9JzakbVxk0o0QUILVk1Lv64GRaxwPuGpnF1QBiwdvhDpLcymb8BpomQL3KYoWKq3wUdDMhQ==",
"dev": true
},
"@types/source-map": {
"version": "0.5.1",
"resolved": "https://registry.npmjs.org/@types/source-map/-/source-map-0.5.1.tgz",
"integrity": "sha512-/GVAjL1Y8puvZab63n8tsuBiYwZt1bApMdx58/msQ9ID5T05ov+wm/ZV1DvYC/DKKEygpTJViqQvkh5Rhrl4CA==",
"version": "0.5.2",
"resolved": "https://registry.npmjs.org/@types/source-map/-/source-map-0.5.2.tgz",
"integrity": "sha512-++w4WmMbk3dS3UeHGzAG+xJOSz5Xqtjys/TBkqG3qp3SeWE7Wwezqe5eB7B51cxUyh4PW7bwVotpsLdBK0D8cw==",
"dev": true
},
"abbrev": {
@ -4755,9 +4755,9 @@
}
},
"mime": {
"version": "1.4.1",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.4.1.tgz",
"integrity": "sha512-KI1+qOZu5DcW6wayYHSzR/tXKCDC5Om4s1z2QJjDULzLcmf3DvzS7oluY4HCTrc+9FiKmWUgeNLg7W3uIQvxtQ==",
"version": "1.5.0",
"resolved": "https://registry.npmjs.org/mime/-/mime-1.5.0.tgz",
"integrity": "sha512-v/jMDoK/qKptnTuC3YUNbIj8uUYvTCIHzVu9BHldKSWja48wusAtfjlcBlqnFrqClu3yf69ScDxBPrIyFnF51g==",
"dev": true
},
"mime-db": {
@ -5149,13 +5149,30 @@
"integrity": "sha1-bVuTSkVpk7I9N/QKOC1vFmao5cY=",
"dev": true
},
"parse-semver": {
"version": "1.1.1",
"resolved": "https://registry.npmjs.org/parse-semver/-/parse-semver-1.1.1.tgz",
"integrity": "sha1-mkr9bfBj3Egm+T+6SpnPIj9mbLg=",
"dev": true,
"requires": {
"semver": "5.4.1"
},
"dependencies": {
"semver": {
"version": "5.4.1",
"resolved": "https://registry.npmjs.org/semver/-/semver-5.4.1.tgz",
"integrity": "sha512-WfG/X9+oATh81XtllIo/I8gOiY9EXRdv1cQdyykeXK17YcUW3EXUAi2To4pcH6nZtJPr7ZOpM5OMyWJZm+8Rsg==",
"dev": true
}
}
},
"parse5": {
"version": "3.0.3",
"resolved": "https://registry.npmjs.org/parse5/-/parse5-3.0.3.tgz",
"integrity": "sha512-rgO9Zg5LLLkfJF9E6CCmXlSE4UVceloys8JrFqCcHloC3usd/kJCyPDwH2SOlzix2j3xaP9sUX3e8+kvkuleAA==",
"dev": true,
"requires": {
"@types/node": "6.0.52"
"@types/node": "7.0.43"
}
},
"path-dirname": {
@ -6671,9 +6688,9 @@
}
},
"vsce": {
"version": "1.32.0",
"resolved": "https://registry.npmjs.org/vsce/-/vsce-1.32.0.tgz",
"integrity": "sha1-EN+pIyGCwg6r5r8xJdMzpLIG/j0=",
"version": "1.33.2",
"resolved": "https://registry.npmjs.org/vsce/-/vsce-1.33.2.tgz",
"integrity": "sha1-NkX2mq+YTiL3TqSdNfON0Y1m/18=",
"dev": true,
"requires": {
"cheerio": "1.0.0-rc.2",
@ -6682,9 +6699,10 @@
"glob": "7.1.2",
"lodash": "4.17.4",
"markdown-it": "8.4.0",
"mime": "1.4.1",
"mime": "1.5.0",
"minimatch": "3.0.4",
"osenv": "0.1.4",
"parse-semver": "1.1.1",
"read": "1.0.7",
"semver": "5.4.1",
"tmp": "0.0.29",
@ -6709,9 +6727,9 @@
}
},
"vscode": {
"version": "1.1.6",
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.6.tgz",
"integrity": "sha1-Ru0a+iwbnWifY5TI8WvR1xkPdfs=",
"version": "1.1.8",
"resolved": "https://registry.npmjs.org/vscode/-/vscode-1.1.8.tgz",
"integrity": "sha512-kT6sIA1AEKR5M+us2fXk5dxwV9SR/IEdLHNmVW4/dl1wNBHoEvgIo1qMQwHNxPVTQmw70KTGZ9UVeVb8FbpNFA==",
"dev": true,
"requires": {
"glob": "7.1.2",
@ -6739,34 +6757,26 @@
}
},
"vscode-debugadapter": {
"version": "1.25.0-pre.0",
"resolved": "https://registry.npmjs.org/vscode-debugadapter/-/vscode-debugadapter-1.25.0-pre.0.tgz",
"integrity": "sha1-0pDsVH5h5Pvss2P/9ojSAyMZQmQ=",
"version": "1.25.0",
"resolved": "https://registry.npmjs.org/vscode-debugadapter/-/vscode-debugadapter-1.25.0.tgz",
"integrity": "sha512-tsOtNNKKTbnQanARdkFfUxI8qKVKba+QHOKWC1reDDeeyvzoNKkLMGkL/xsiKn5vQDeaP3zFBcLY8Ysak9GrvQ==",
"requires": {
"vscode-debugprotocol": "1.25.0-pre.0"
},
"dependencies": {
"vscode-debugprotocol": {
"version": "1.25.0-pre.0",
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.25.0-pre.0.tgz",
"integrity": "sha1-rYPnvZWxmseV31D6Di/pA0YqcrY="
}
"vscode-debugprotocol": "1.25.0"
}
},
"vscode-debugadapter-testsupport": {
"version": "1.24.0",
"resolved": "https://registry.npmjs.org/vscode-debugadapter-testsupport/-/vscode-debugadapter-testsupport-1.24.0.tgz",
"integrity": "sha1-rDZ1scU/wW+1JMvSt+znEhtiXng=",
"version": "1.25.0",
"resolved": "https://registry.npmjs.org/vscode-debugadapter-testsupport/-/vscode-debugadapter-testsupport-1.25.0.tgz",
"integrity": "sha512-6E2N7CoH7B0KEDvI9mFVFt4H+dRFDhtj3PmLVjNojfZ1VZZS2yfhE0XO0E5Axdhef3zTpUU6WZoeOOMVFGZGIg==",
"dev": true,
"requires": {
"vscode-debugprotocol": "1.24.0"
"vscode-debugprotocol": "1.25.0"
}
},
"vscode-debugprotocol": {
"version": "1.24.0",
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.24.0.tgz",
"integrity": "sha1-28EOjX2VsQJyehmvPw/O9+JSsI4=",
"dev": true
"version": "1.25.0",
"resolved": "https://registry.npmjs.org/vscode-debugprotocol/-/vscode-debugprotocol-1.25.0.tgz",
"integrity": "sha512-e1EUy/5npqa0NlAwRCUu8A9LnVRf6tkwiPQcCLyUFCC9o2GxcAqH5Va4mqXDoxQ58ar3zODivKQeRb3z1KH7WA=="
},
"vscode-nls": {
"version": "2.0.2",
@ -6774,9 +6784,9 @@
"integrity": "sha1-gIUiOAhEuK0VNJmvXDsDkhrqAto="
},
"vscode-nls-dev": {
"version": "2.1.5",
"resolved": "https://registry.npmjs.org/vscode-nls-dev/-/vscode-nls-dev-2.1.5.tgz",
"integrity": "sha1-GfqjsYp/MCIBA5pMlnu9IvoShE0=",
"version": "2.1.6",
"resolved": "https://registry.npmjs.org/vscode-nls-dev/-/vscode-nls-dev-2.1.6.tgz",
"integrity": "sha512-1IylC/ekENYqz1vEItfrzrMXS8LW9aZQnNTU6BfdwT0Jddzed+l+nvU8amgVKFFmC1/GoiMFk5wtC20zWBbEbw==",
"dev": true,
"requires": {
"clone": "1.0.3",

View file

@ -1,23 +0,0 @@
[{
"isLicense": true,
"name": "noice-json-rpc",
"repositoryURL": "https://github.com/nojvek/noice-json-rpc",
"license": "MIT",
"licenseDetail": [
"Copyright (c) Manoj Patel",
"",
"MIT License",
"",
"Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation",
"files (the \"Software\"), to deal in the Software without restriction, including without limitation the rights to use, copy,",
"modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software",
"is furnished to do so, subject to the following conditions:",
"",
"The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.",
"",
"THE SOFTWARE IS PROVIDED *AS IS*, WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES",
"OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS",
"BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT",
"OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE."
]
}]

View file

@ -3,7 +3,7 @@
"version": "0.0.1",
"description": "Dependencies shared by all extensions",
"dependencies": {
"typescript": "2.6.2"
"typescript": "2.7.0-insiders.20171214"
},
"scripts": {
"postinstall": "node ./postinstall"

View file

@ -20,5 +20,6 @@ function adaptInjectionScope(grammar) {
injections[newInjectionKey] = injection;
}
updateGrammar.update('atom/language-php', 'grammars/php.cson', './syntaxes/php.tmLanguage.json', adaptInjectionScope);
updateGrammar.update('atom/language-php', 'grammars/php.cson', './syntaxes/php.tmLanguage.json', undefined);
updateGrammar.update('atom/language-php', 'grammars/html.cson', './syntaxes/html.tmLanguage.json', adaptInjectionScope);

View file

@ -35,10 +35,15 @@
}
],
"grammars": [
{
"language": "php",
"scopeName": "source.php",
"path": "./syntaxes/php.tmLanguage.json"
},
{
"language": "php",
"scopeName": "text.html.php",
"path": "./syntaxes/php.tmLanguage.json",
"path": "./syntaxes/html.tmLanguage.json",
"embeddedLanguages": {
"text.html": "html",
"source.php": "php",

Some files were not shown because too many files have changed in this diff Show more