Initial VS Code 1.19 source merge (#571)

* Initial 1.19 xcopy

* Fix yarn build

* Fix numerous build breaks

* Next batch of build break fixes

* More build break fixes

* Runtime breaks

* Additional post merge fixes

* Fix windows setup file

* Fix test failures.

* Update license header blocks to refer to source eula
This commit is contained in:
Karl Burtram
2018-01-28 23:37:17 -08:00
committed by GitHub
parent 9a1ac20710
commit 251ae01c3e
8009 changed files with 93378 additions and 35634 deletions
+7
View File
@@ -0,0 +1,7 @@
[{
"name": "typescript",
"version": "2.6.2",
"license": "Apache-2.0",
"repositoryURL": "https://github.com/Microsoft/TypeScript",
"isProd": true
}]
+608
View File
@@ -0,0 +1,608 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/node@^8.0.24", "@types/node@^8.0.47":
version "8.5.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.5.9.tgz#7155cfb4ae405bca4dd8df1a214c339e939109bf"
adal-node@0.1.25:
version "0.1.25"
resolved "https://registry.yarnpkg.com/adal-node/-/adal-node-0.1.25.tgz#6554350ab42914870004c45c0d64448f3dbfcd03"
dependencies:
"@types/node" "^8.0.47"
async ">=0.6.0"
date-utils "*"
jws "3.x.x"
request ">= 2.52.0"
underscore ">= 1.3.1"
uuid "^3.1.0"
xmldom ">= 0.1.x"
xpath.js "~1.0.5"
ajv@^5.1.0:
version "5.5.2"
resolved "https://registry.yarnpkg.com/ajv/-/ajv-5.5.2.tgz#73b5eeca3fab653e3d3f9422b341ad42205dc965"
dependencies:
co "^4.6.0"
fast-deep-equal "^1.0.0"
fast-json-stable-stringify "^2.0.0"
json-schema-traverse "^0.3.0"
ansi-regex@^2.0.0:
version "2.1.1"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-2.1.1.tgz#c3b33ab5ee360d86e0e628f0468ae7ef27d654df"
ansi-styles@^2.2.1:
version "2.2.1"
resolved "https://registry.yarnpkg.com/ansi-styles/-/ansi-styles-2.2.1.tgz#b432dd3358b634cf75e1e4664368240533c1ddbe"
asn1@0.1.11:
version "0.1.11"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.1.11.tgz#559be18376d08a4ec4dbe80877d27818639b2df7"
asn1@~0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/asn1/-/asn1-0.2.3.tgz#dac8787713c9966849fc8180777ebe9c1ddf3b86"
assert-plus@1.0.0, assert-plus@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-1.0.0.tgz#f12e0f3c5d77b0b1cdd9146942e4e96c1e4dd525"
assert-plus@^0.1.5:
version "0.1.5"
resolved "https://registry.yarnpkg.com/assert-plus/-/assert-plus-0.1.5.tgz#ee74009413002d84cec7219c6ac811812e723160"
async@>=0.6.0, async@^2.0.1:
version "2.6.0"
resolved "https://registry.yarnpkg.com/async/-/async-2.6.0.tgz#61a29abb6fcc026fea77e56d1c6ec53a795951f4"
dependencies:
lodash "^4.14.0"
asynckit@^0.4.0:
version "0.4.0"
resolved "https://registry.yarnpkg.com/asynckit/-/asynckit-0.4.0.tgz#c79ed97f7f34cb8f2ba1bc9790bcc366474b4b79"
aws-sign2@~0.5.0:
version "0.5.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.5.0.tgz#c57103f7a17fc037f02d7c2e64b602ea223f7d63"
aws-sign2@~0.7.0:
version "0.7.0"
resolved "https://registry.yarnpkg.com/aws-sign2/-/aws-sign2-0.7.0.tgz#b46e890934a9591f2d2f6f86d7e6a9f1b3fe76a8"
aws4@^1.6.0:
version "1.6.0"
resolved "https://registry.yarnpkg.com/aws4/-/aws4-1.6.0.tgz#83ef5ca860b2b32e4a0deedee8c771b9db57471e"
base64url@2.0.0, base64url@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/base64url/-/base64url-2.0.0.tgz#eac16e03ea1438eff9423d69baa36262ed1f70bb"
bcrypt-pbkdf@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/bcrypt-pbkdf/-/bcrypt-pbkdf-1.0.1.tgz#63bc5dcb61331b92bc05fd528953c33462a06f8d"
dependencies:
tweetnacl "^0.14.3"
bl@~1.0.0:
version "1.0.3"
resolved "https://registry.yarnpkg.com/bl/-/bl-1.0.3.tgz#fc5421a28fd4226036c3b3891a66a25bc64d226e"
dependencies:
readable-stream "~2.0.5"
bluebird@^2.9.30:
version "2.11.0"
resolved "https://registry.yarnpkg.com/bluebird/-/bluebird-2.11.0.tgz#534b9033c022c9579c56ba3b3e5a5caafbb650e1"
boom@2.x.x:
version "2.10.1"
resolved "https://registry.yarnpkg.com/boom/-/boom-2.10.1.tgz#39c8918ceff5799f83f9492a848f625add0c766f"
dependencies:
hoek "2.x.x"
boom@4.x.x:
version "4.3.1"
resolved "https://registry.yarnpkg.com/boom/-/boom-4.3.1.tgz#4f8a3005cb4a7e3889f749030fd25b96e01d2e31"
dependencies:
hoek "4.x.x"
boom@5.x.x:
version "5.2.0"
resolved "https://registry.yarnpkg.com/boom/-/boom-5.2.0.tgz#5dd9da6ee3a5f302077436290cb717d3f4a54e02"
dependencies:
hoek "4.x.x"
buffer-equal-constant-time@1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/buffer-equal-constant-time/-/buffer-equal-constant-time-1.0.1.tgz#f8e71132f7ffe6e01a5c9697a4c6f3e48d5cc819"
caseless@~0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.11.0.tgz#715b96ea9841593cc33067923f5ec60ebda4f7d7"
caseless@~0.12.0:
version "0.12.0"
resolved "https://registry.yarnpkg.com/caseless/-/caseless-0.12.0.tgz#1b681c21ff84033c826543090689420d187151dc"
chalk@^1.0.0:
version "1.1.3"
resolved "https://registry.yarnpkg.com/chalk/-/chalk-1.1.3.tgz#a8115c55e4a702fe4d150abd3872822a7e09fc98"
dependencies:
ansi-styles "^2.2.1"
escape-string-regexp "^1.0.2"
has-ansi "^2.0.0"
strip-ansi "^3.0.0"
supports-color "^2.0.0"
co@^4.6.0:
version "4.6.0"
resolved "https://registry.yarnpkg.com/co/-/co-4.6.0.tgz#6ea6bdf3d853ae54ccb8e47bfa0bf3f9031fb184"
combined-stream@^1.0.5, combined-stream@~1.0.1, combined-stream@~1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/combined-stream/-/combined-stream-1.0.5.tgz#938370a57b4a51dea2c77c15d5c5fdf895164009"
dependencies:
delayed-stream "~1.0.0"
commander@^2.8.1:
version "2.13.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.13.0.tgz#6964bca67685df7c1f1430c584f07d7597885b9c"
core-util-is@1.0.2, core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
cryptiles@2.x.x:
version "2.0.5"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-2.0.5.tgz#3bdfecdc608147c1c67202fa291e7dca59eaa3b8"
dependencies:
boom "2.x.x"
cryptiles@3.x.x:
version "3.1.2"
resolved "https://registry.yarnpkg.com/cryptiles/-/cryptiles-3.1.2.tgz#a89fbb220f5ce25ec56e8c4aa8a4fd7b5b0d29fe"
dependencies:
boom "5.x.x"
ctype@0.5.3:
version "0.5.3"
resolved "https://registry.yarnpkg.com/ctype/-/ctype-0.5.3.tgz#82c18c2461f74114ef16c135224ad0b9144ca12f"
dashdash@^1.12.0:
version "1.14.1"
resolved "https://registry.yarnpkg.com/dashdash/-/dashdash-1.14.1.tgz#853cfa0f7cbe2fed5de20326b8dd581035f6e2f0"
dependencies:
assert-plus "^1.0.0"
date-utils@*:
version "1.2.21"
resolved "https://registry.yarnpkg.com/date-utils/-/date-utils-1.2.21.tgz#61fb16cdc1274b3c9acaaffe9fc69df8720a2b64"
delayed-stream@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/delayed-stream/-/delayed-stream-1.0.0.tgz#df3ae199acadfb7d440aaae0b29e2272b24ec619"
ecc-jsbn@~0.1.1:
version "0.1.1"
resolved "https://registry.yarnpkg.com/ecc-jsbn/-/ecc-jsbn-0.1.1.tgz#0fc73a9ed5f0d53c38193398523ef7e543777505"
dependencies:
jsbn "~0.1.0"
ecdsa-sig-formatter@1.0.9:
version "1.0.9"
resolved "https://registry.yarnpkg.com/ecdsa-sig-formatter/-/ecdsa-sig-formatter-1.0.9.tgz#4bc926274ec3b5abb5016e7e1d60921ac262b2a1"
dependencies:
base64url "^2.0.0"
safe-buffer "^5.0.1"
escape-string-regexp@^1.0.2:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
extend@~3.0.0, extend@~3.0.1:
version "3.0.1"
resolved "https://registry.yarnpkg.com/extend/-/extend-3.0.1.tgz#a755ea7bc1adfcc5a31ce7e762dbaadc5e636444"
extsprintf@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.3.0.tgz#96918440e3041a7a414f8c52e3c574eb3c3e1e05"
extsprintf@^1.2.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/extsprintf/-/extsprintf-1.4.0.tgz#e2689f8f356fad62cca65a3a91c5df5f9551692f"
fast-deep-equal@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fast-deep-equal/-/fast-deep-equal-1.0.0.tgz#96256a3bc975595eb36d82e9929d060d893439ff"
fast-json-stable-stringify@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/fast-json-stable-stringify/-/fast-json-stable-stringify-2.0.0.tgz#d5142c0caee6b1189f87d3a76111064f86c8bbf2"
forever-agent@~0.6.0, forever-agent@~0.6.1:
version "0.6.1"
resolved "https://registry.yarnpkg.com/forever-agent/-/forever-agent-0.6.1.tgz#fbc71f0c41adeb37f96c577ad1ed42d8fdacca91"
form-data@~1.0.0-rc1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-1.0.1.tgz#ae315db9a4907fa065502304a66d7733475ee37c"
dependencies:
async "^2.0.1"
combined-stream "^1.0.5"
mime-types "^2.1.11"
form-data@~2.3.1:
version "2.3.1"
resolved "https://registry.yarnpkg.com/form-data/-/form-data-2.3.1.tgz#6fb94fbd71885306d73d15cc497fe4cc4ecd44bf"
dependencies:
asynckit "^0.4.0"
combined-stream "^1.0.5"
mime-types "^2.1.12"
generate-function@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/generate-function/-/generate-function-2.0.0.tgz#6858fe7c0969b7d4e9093337647ac79f60dfbe74"
generate-object-property@^1.1.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/generate-object-property/-/generate-object-property-1.2.0.tgz#9c0e1c40308ce804f4783618b937fa88f99d50d0"
dependencies:
is-property "^1.0.0"
getpass@^0.1.1:
version "0.1.7"
resolved "https://registry.yarnpkg.com/getpass/-/getpass-0.1.7.tgz#5eff8e3e684d569ae4cb2b1282604e8ba62149fa"
dependencies:
assert-plus "^1.0.0"
har-schema@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/har-schema/-/har-schema-2.0.0.tgz#a94c2224ebcac04782a0d9035521f24735b7ec92"
har-validator@^1.6.1:
version "1.8.0"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-1.8.0.tgz#d83842b0eb4c435960aeb108a067a3aa94c0eeb2"
dependencies:
bluebird "^2.9.30"
chalk "^1.0.0"
commander "^2.8.1"
is-my-json-valid "^2.12.0"
har-validator@~5.0.3:
version "5.0.3"
resolved "https://registry.yarnpkg.com/har-validator/-/har-validator-5.0.3.tgz#ba402c266194f15956ef15e0fcf242993f6a7dfd"
dependencies:
ajv "^5.1.0"
har-schema "^2.0.0"
has-ansi@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/has-ansi/-/has-ansi-2.0.0.tgz#34f5049ce1ecdf2b0649af3ef24e45ed35416d91"
dependencies:
ansi-regex "^2.0.0"
hawk@~3.1.0:
version "3.1.3"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-3.1.3.tgz#078444bd7c1640b0fe540d2c9b73d59678e8e1c4"
dependencies:
boom "2.x.x"
cryptiles "2.x.x"
hoek "2.x.x"
sntp "1.x.x"
hawk@~6.0.2:
version "6.0.2"
resolved "https://registry.yarnpkg.com/hawk/-/hawk-6.0.2.tgz#af4d914eb065f9b5ce4d9d11c1cb2126eecc3038"
dependencies:
boom "4.x.x"
cryptiles "3.x.x"
hoek "4.x.x"
sntp "2.x.x"
hoek@2.x.x:
version "2.16.3"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-2.16.3.tgz#20bb7403d3cea398e91dc4710a8ff1b8274a25ed"
hoek@4.x.x:
version "4.2.0"
resolved "https://registry.yarnpkg.com/hoek/-/hoek-4.2.0.tgz#72d9d0754f7fe25ca2d01ad8f8f9a9449a89526d"
http-signature@~0.11.0:
version "0.11.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-0.11.0.tgz#1796cf67a001ad5cd6849dca0991485f09089fe6"
dependencies:
asn1 "0.1.11"
assert-plus "^0.1.5"
ctype "0.5.3"
http-signature@~1.2.0:
version "1.2.0"
resolved "https://registry.yarnpkg.com/http-signature/-/http-signature-1.2.0.tgz#9aecd925114772f3d95b65a60abb8f7c18fbace1"
dependencies:
assert-plus "^1.0.0"
jsprim "^1.2.2"
sshpk "^1.7.0"
inherits@~2.0.1:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
is-my-json-valid@^2.12.0:
version "2.17.1"
resolved "https://registry.yarnpkg.com/is-my-json-valid/-/is-my-json-valid-2.17.1.tgz#3da98914a70a22f0a8563ef1511a246c6fc55471"
dependencies:
generate-function "^2.0.0"
generate-object-property "^1.1.0"
jsonpointer "^4.0.0"
xtend "^4.0.0"
is-property@^1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/is-property/-/is-property-1.0.2.tgz#57fe1c4e48474edd65b09911f26b1cd4095dda84"
is-typedarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/is-typedarray/-/is-typedarray-1.0.0.tgz#e479c80858df0c1b11ddda6940f96011fcda4a9a"
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
isstream@~0.1.1, isstream@~0.1.2:
version "0.1.2"
resolved "https://registry.yarnpkg.com/isstream/-/isstream-0.1.2.tgz#47e63f7af55afa6f92e1500e690eb8b8529c099a"
jsbn@~0.1.0:
version "0.1.1"
resolved "https://registry.yarnpkg.com/jsbn/-/jsbn-0.1.1.tgz#a5e654c2e5a2deb5f201d96cefbca80c0ef2f513"
json-schema-traverse@^0.3.0:
version "0.3.1"
resolved "https://registry.yarnpkg.com/json-schema-traverse/-/json-schema-traverse-0.3.1.tgz#349a6d44c53a51de89b40805c5d5e59b417d3340"
json-schema@0.2.3:
version "0.2.3"
resolved "https://registry.yarnpkg.com/json-schema/-/json-schema-0.2.3.tgz#b480c892e59a2f05954ce727bd3f2a4e882f9e13"
json-stringify-safe@~5.0.0, json-stringify-safe@~5.0.1:
version "5.0.1"
resolved "https://registry.yarnpkg.com/json-stringify-safe/-/json-stringify-safe-5.0.1.tgz#1296a2d58fd45f19a0f6ce01d65701e2c735b6eb"
jsonpointer@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/jsonpointer/-/jsonpointer-4.0.1.tgz#4fd92cb34e0e9db3c89c8622ecf51f9b978c6cb9"
jsprim@^1.2.2:
version "1.4.1"
resolved "https://registry.yarnpkg.com/jsprim/-/jsprim-1.4.1.tgz#313e66bc1e5cc06e438bc1b7499c2e5c56acb6a2"
dependencies:
assert-plus "1.0.0"
extsprintf "1.3.0"
json-schema "0.2.3"
verror "1.10.0"
jwa@^1.1.4:
version "1.1.5"
resolved "https://registry.yarnpkg.com/jwa/-/jwa-1.1.5.tgz#a0552ce0220742cd52e153774a32905c30e756e5"
dependencies:
base64url "2.0.0"
buffer-equal-constant-time "1.0.1"
ecdsa-sig-formatter "1.0.9"
safe-buffer "^5.0.1"
jws@3.x.x:
version "3.1.4"
resolved "https://registry.yarnpkg.com/jws/-/jws-3.1.4.tgz#f9e8b9338e8a847277d6444b1464f61880e050a2"
dependencies:
base64url "^2.0.0"
jwa "^1.1.4"
safe-buffer "^5.0.1"
lodash@^4.14.0:
version "4.17.4"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.4.tgz#78203a4d1c328ae1d86dca6460e369b57f4055ae"
mime-db@~1.30.0:
version "1.30.0"
resolved "https://registry.yarnpkg.com/mime-db/-/mime-db-1.30.0.tgz#74c643da2dd9d6a45399963465b26d5ca7d71f01"
mime-types@^2.1.11, mime-types@^2.1.12, mime-types@~2.1.17, mime-types@~2.1.2:
version "2.1.17"
resolved "https://registry.yarnpkg.com/mime-types/-/mime-types-2.1.17.tgz#09d7a393f03e995a79f8af857b70a9e0ab16557a"
dependencies:
mime-db "~1.30.0"
node-uuid@~1.4.0:
version "1.4.8"
resolved "https://registry.yarnpkg.com/node-uuid/-/node-uuid-1.4.8.tgz#b040eb0923968afabf8d32fb1f17f1167fdab907"
oauth-sign@~0.8.0, oauth-sign@~0.8.2:
version "0.8.2"
resolved "https://registry.yarnpkg.com/oauth-sign/-/oauth-sign-0.8.2.tgz#46a6ab7f0aead8deae9ec0565780b7d4efeb9d43"
performance-now@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/performance-now/-/performance-now-2.1.0.tgz#6309f4e0e5fa913ec1c69307ae364b4b377c9e7b"
process-nextick-args@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
punycode@^1.4.1:
version "1.4.1"
resolved "https://registry.yarnpkg.com/punycode/-/punycode-1.4.1.tgz#c0d5a63b2718800ad8e1eb0fa5269c84dd41845e"
qs@~5.1.0:
version "5.1.0"
resolved "https://registry.yarnpkg.com/qs/-/qs-5.1.0.tgz#4d932e5c7ea411cca76a312d39a606200fd50cd9"
qs@~6.5.1:
version "6.5.1"
resolved "https://registry.yarnpkg.com/qs/-/qs-6.5.1.tgz#349cdf6eef89ec45c12d7d5eb3fc0c870343a6d8"
readable-stream@~2.0.5:
version "2.0.6"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.0.6.tgz#8f90341e68a53ccc928788dacfcd11b36eb9b78e"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.1"
isarray "~1.0.0"
process-nextick-args "~1.0.6"
string_decoder "~0.10.x"
util-deprecate "~1.0.1"
request@2.63.0:
version "2.63.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.63.0.tgz#c83e7c3485e5d9bf9b146318429bc48f1253d8be"
dependencies:
aws-sign2 "~0.5.0"
bl "~1.0.0"
caseless "~0.11.0"
combined-stream "~1.0.1"
extend "~3.0.0"
forever-agent "~0.6.0"
form-data "~1.0.0-rc1"
har-validator "^1.6.1"
hawk "~3.1.0"
http-signature "~0.11.0"
isstream "~0.1.1"
json-stringify-safe "~5.0.0"
mime-types "~2.1.2"
node-uuid "~1.4.0"
oauth-sign "~0.8.0"
qs "~5.1.0"
stringstream "~0.0.4"
tough-cookie ">=0.12.0"
tunnel-agent "~0.4.0"
"request@>= 2.52.0":
version "2.83.0"
resolved "https://registry.yarnpkg.com/request/-/request-2.83.0.tgz#ca0b65da02ed62935887808e6f510381034e3356"
dependencies:
aws-sign2 "~0.7.0"
aws4 "^1.6.0"
caseless "~0.12.0"
combined-stream "~1.0.5"
extend "~3.0.1"
forever-agent "~0.6.1"
form-data "~2.3.1"
har-validator "~5.0.3"
hawk "~6.0.2"
http-signature "~1.2.0"
is-typedarray "~1.0.0"
isstream "~0.1.2"
json-stringify-safe "~5.0.1"
mime-types "~2.1.17"
oauth-sign "~0.8.2"
performance-now "^2.1.0"
qs "~6.5.1"
safe-buffer "^5.1.1"
stringstream "~0.0.5"
tough-cookie "~2.3.3"
tunnel-agent "^0.6.0"
uuid "^3.1.0"
safe-buffer@^5.0.1, safe-buffer@^5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
sntp@1.x.x:
version "1.0.9"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-1.0.9.tgz#6541184cc90aeea6c6e7b35e2659082443c66198"
dependencies:
hoek "2.x.x"
sntp@2.x.x:
version "2.1.0"
resolved "https://registry.yarnpkg.com/sntp/-/sntp-2.1.0.tgz#2c6cec14fedc2222739caf9b5c3d85d1cc5a2cc8"
dependencies:
hoek "4.x.x"
sshpk@^1.7.0:
version "1.13.1"
resolved "https://registry.yarnpkg.com/sshpk/-/sshpk-1.13.1.tgz#512df6da6287144316dc4c18fe1cf1d940739be3"
dependencies:
asn1 "~0.2.3"
assert-plus "^1.0.0"
dashdash "^1.12.0"
getpass "^0.1.1"
optionalDependencies:
bcrypt-pbkdf "^1.0.0"
ecc-jsbn "~0.1.1"
jsbn "~0.1.0"
tweetnacl "~0.14.0"
string_decoder@~0.10.x:
version "0.10.31"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-0.10.31.tgz#62e203bc41766c6c28c9fc84301dab1c5310fa94"
stringstream@~0.0.4, stringstream@~0.0.5:
version "0.0.5"
resolved "https://registry.yarnpkg.com/stringstream/-/stringstream-0.0.5.tgz#4e484cd4de5a0bbbee18e46307710a8a81621878"
strip-ansi@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-3.0.1.tgz#6a385fb8853d952d5ff05d0e8aaf94278dc63dcf"
dependencies:
ansi-regex "^2.0.0"
supports-color@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-2.0.0.tgz#535d045ce6b6363fa40117084629995e9df324c7"
tough-cookie@>=0.12.0, tough-cookie@~2.3.3:
version "2.3.3"
resolved "https://registry.yarnpkg.com/tough-cookie/-/tough-cookie-2.3.3.tgz#0b618a5565b6dea90bf3425d04d55edc475a7561"
dependencies:
punycode "^1.4.1"
tunnel-agent@^0.6.0:
version "0.6.0"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.6.0.tgz#27a5dea06b36b04a0a9966774b290868f0fc40fd"
dependencies:
safe-buffer "^5.0.1"
tunnel-agent@~0.4.0:
version "0.4.3"
resolved "https://registry.yarnpkg.com/tunnel-agent/-/tunnel-agent-0.4.3.tgz#6373db76909fe570e08d73583365ed828a74eeeb"
tweetnacl@^0.14.3, tweetnacl@~0.14.0:
version "0.14.5"
resolved "https://registry.yarnpkg.com/tweetnacl/-/tweetnacl-0.14.5.tgz#5ae68177f192d4456269d108afa93ff8743f4f64"
"underscore@>= 1.3.1":
version "1.8.3"
resolved "https://registry.yarnpkg.com/underscore/-/underscore-1.8.3.tgz#4f3fb53b106e6097fcf9cb4109f2a5e9bdfa5022"
util-deprecate@~1.0.1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/util-deprecate/-/util-deprecate-1.0.2.tgz#450d4dc9fa70de732762fbd2d4a28981419a0ccf"
uuid@^3.1.0:
version "3.2.1"
resolved "https://registry.yarnpkg.com/uuid/-/uuid-3.2.1.tgz#12c528bb9d58d0b9265d9a2f6f0fe8be17ff1f14"
verror@1.10.0:
version "1.10.0"
resolved "https://registry.yarnpkg.com/verror/-/verror-1.10.0.tgz#3a105ca17053af55d6e270c1f8288682e18da400"
dependencies:
assert-plus "^1.0.0"
core-util-is "1.0.2"
extsprintf "^1.2.0"
vscode-nls@2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"
"xmldom@>= 0.1.x":
version "0.1.27"
resolved "https://registry.yarnpkg.com/xmldom/-/xmldom-0.1.27.tgz#d501f97b3bdb403af8ef9ecc20573187aadac0e9"
xpath.js@~1.0.5:
version "1.0.7"
resolved "https://registry.yarnpkg.com/xpath.js/-/xpath.js-1.0.7.tgz#7e94627f541276cbc6a6b02b5d35e9418565b3e4"
xtend@^4.0.0:
version "4.0.1"
resolved "https://registry.yarnpkg.com/xtend/-/xtend-4.0.1.tgz#a5c6d532be656e23db820efb943a1f04998d63af"
+3 -18
View File
@@ -1,22 +1,7 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "sublimehq/Packages",
"name": "mmims/language-batchfile",
"version": "0.0.0",
"license": "TextMate Bundle License",
"repositoryURL": "https://github.com/sublimehq/Packages",
"licenseDetail": [
"Copyright (c) Sublime Packages project authors",
"",
"If not otherwise specified (see below), files in this folder fall under the following license: ",
"",
"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.",
"",
"An exception is made for files in readable text which contain their own license information, ",
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added ",
"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\"."
]
"license": "MIT",
"repositoryURL": "https://github.com/mmims/language-batchfile"
}]
+9 -2
View File
@@ -3,6 +3,9 @@
"version": "0.1.0",
"publisher": "vscode",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js mmims/language-batchfile grammars/batchfile.cson ./syntaxes/batchfile.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "bat",
@@ -12,8 +15,12 @@
}],
"grammars": [{
"language": "bat",
"scopeName": "source.dosbatch",
"path": "./syntaxes/Batch File.tmLanguage"
"scopeName": "source.batchfile",
"path": "./syntaxes/batchfile.tmLanguage.json"
}],
"snippets": [{
"language": "bat",
"path": "./snippets/batchfile.snippets.json"
}]
}
}
@@ -0,0 +1,16 @@
{
"Region Start": {
"prefix": "#region",
"body": [
"::#region"
],
"description": "Folding Region Start"
},
"Region End": {
"prefix": "#endregion",
"body": [
"::#endregion"
],
"description": "Folding Region End"
}
}
@@ -0,0 +1,693 @@
{
"information_for_contributors": [
"This file has been converted from https://github.com/mmims/language-batchfile/blob/master/grammars/batchfile.cson",
"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",
"scopeName": "source.batchfile",
"name": "Batch File",
"fileTypes": [
"bat",
"cmd"
],
"patterns": [
{
"include": "#commands"
},
{
"include": "#comments"
},
{
"include": "#constants"
},
{
"include": "#controls"
},
{
"include": "#escaped_characters"
},
{
"include": "#labels"
},
{
"include": "#numbers"
},
{
"include": "#operators"
},
{
"include": "#parens"
},
{
"include": "#strings"
},
{
"include": "#variables"
}
],
"repository": {
"commands": {
"patterns": [
{
"match": "(?<=^|[\\s@])(?i:adprep|append|arp|assoc|at|atmadm|attrib|auditpol|autochk|autoconv|autofmt|bcdboot|bcdedit|bdehdcfg|bitsadmin|bootcfg|brea|cacls|cd|certreq|certutil|change|chcp|chdir|chglogon|chgport|chgusr|chkdsk|chkntfs|choice|cipher|clip|clscluadmin|cluster|cmd|cmdkey|cmstp|color|comp|compact|convert|copy|cprofile|cscript|csvde|date|dcdiag|dcgpofix|dcpromo|defra|del|dfscmd|dfsdiag|dfsrmig|diantz|dir|dirquota|diskcomp|diskcopy|diskpart|diskperf|diskraid|diskshadow|dispdiag|doin|dnscmd|doskey|driverquery|dsacls|dsadd|dsamain|dsdbutil|dsget|dsmgmt|dsmod|dsmove|dsquery|dsrm|edit|endlocal|eraseesentutl|eventcreate|eventquery|eventtriggers|evntcmd|expand|extract|fc|filescrn|find|findstr|finger|flattemp|fonde|forfiles|format|freedisk|fsutil|ftp|ftype|fveupdate|getmac|gettype|gpfixup|gpresult|gpupdate|graftabl|hashgen|hep|helpctr|hostname|icacls|iisreset|inuse|ipconfig|ipxroute|irftp|ismserv|jetpack|klist|ksetup|ktmutil|ktpass|label|ldifd|ldp|lodctr|logman|logoff|lpq|lpr|macfile|makecab|manage-bde|mapadmin|md|mkdir|mklink|mmc|mode|more|mount|mountvol|move|mqbup|mqsvc|mqtgsvc|msdt|msg|msiexec|msinfo32|mstsc|nbtstat|net computer|net group|net localgroup|net print|net session|net share|net start|net stop|net use|net user|net view|net|netcfg|netdiag|netdom|netsh|netstat|nfsadmin|nfsshare|nfsstat|nlb|nlbmgr|nltest|nslookup|ntackup|ntcmdprompt|ntdsutil|ntfrsutl|openfiles|pagefileconfig|path|pathping|pause|pbadmin|pentnt|perfmon|ping|pnpunatten|pnputil|popd|powercfg|powershell|powershell_ise|print|prncnfg|prndrvr|prnjobs|prnmngr|prnport|prnqctl|prompt|pubprn|pushd|pushprinterconnections|pwlauncher|qappsrv|qprocess|query|quser|qwinsta|rasdial|rcp|rd|rdpsign|regentc|recover|redircmp|redirusr|reg|regini|regsvr32|relog|ren|rename|rendom|repadmin|repair-bde|replace|reset session|rxec|risetup|rmdir|robocopy|route|rpcinfo|rpcping|rsh|runas|rundll32|rwinsta|sc|schtasks|scwcmd|secedit|serverceipoptin|servrmanagercmd|serverweroptin|setlocal|setspn|setx|sfc|shadow|shift|showmount|shutdown|sort|start|storrept|subst|sxstrace|ysocmgr|systeminfo|takeown|tapicfg|taskkill|tasklist|tcmsetup|telnet|tftp|time|timeout|title|tlntadmn|tpmvscmgr|tpmvscmgr|tacerpt|tracert|tree|tscon|tsdiscon|tsecimp|tskill|tsprof|type|typeperf|tzutil|uddiconfig|umount|unlodctr|ver|verifier|verif|vol|vssadmin|w32tm|waitfor|wbadmin|wdsutil|wecutil|wevtutil|where|whoami|winnt|winnt32|winpop|winrm|winrs|winsat|wlbs|mic|wscript|xcopy)(?=$|\\s)",
"name": "keyword.command.batchfile"
},
{
"begin": "(?<=^|[\\s@])(?i:echo)(?=$|\\s|\\.)",
"beginCaptures": {
"0": {
"name": "keyword.command.batchfile"
}
},
"end": "(?=$\\n|[&|><)])",
"patterns": [
{
"include": "#escaped_characters"
},
{
"include": "#variables"
},
{
"include": "#numbers"
},
{
"include": "#strings"
}
]
},
{
"include": "#command_set"
}
]
},
"command_set": {
"patterns": [
{
"begin": "(?<=^|[\\s@])(?i:SET)(?=$|\\s)",
"beginCaptures": {
"0": {
"name": "keyword.command.batchfile"
}
},
"end": "(?=$\\n|[&|><)])",
"patterns": [
{
"include": "#command_set_inside"
}
]
}
]
},
"command_set_inside": {
"patterns": [
{
"include": "#escaped_characters"
},
{
"include": "#variables"
},
{
"include": "#numbers"
},
{
"include": "#parens"
},
{
"begin": "(\")\\s*([^ ][^=]*)(=)\"?",
"beginCaptures": {
"1": {
"name": "punctuation.definition.string.begin.batchfile"
},
"2": {
"name": "variable.other.readwrite.batchfile"
},
"3": {
"name": "keyword.operator.assignment.batchfile"
}
},
"end": "\"",
"endCaptures": {
"0": {
"name": "string.quoted.double.batchfile"
}
},
"patterns": [
{
"include": "#variables"
},
{
"include": "#numbers"
},
{
"include": "#parens"
}
]
},
{
"include": "#strings"
},
{
"begin": "([^ ][^=]*)(=)",
"beginCaptures": {
"1": {
"name": "variable.other.readwrite.batchfile"
},
"2": {
"name": "keyword.operator.assignment.batchfile"
}
},
"end": "(?=$\\n|[&|><)])",
"patterns": [
{
"include": "#escaped_characters"
},
{
"include": "#variables"
},
{
"include": "#numbers"
},
{
"include": "#parens"
},
{
"include": "#strings"
}
]
},
{
"begin": "\\s+/[aA]\\s+",
"end": "(?=$\\n|[&|><)])",
"name": "meta.expression.set.batchfile",
"patterns": [
{
"include": "#command_set_inside_arithmetic"
},
{
"include": "#command_set_group"
},
{
"begin": "\"",
"beginCaptures": {
"0": {
"name": "punctuation.definition.string.begin.batchfile"
}
},
"end": "\"",
"endCaptures": {
"0": {
"name": "punctuation.definition.string.end.batchfile"
}
},
"name": "string.quoted.double.batchfile",
"patterns": [
{
"include": "#command_set_inside_arithmetic"
},
{
"include": "#command_set_group"
},
{
"include": "#variables"
}
]
}
]
},
{
"begin": "\\s+/[pP]\\s+",
"end": "(?=$\\n|[&|><)])",
"patterns": [
{
"begin": "([^ ][^=]*)(=)",
"beginCaptures": {
"1": {
"name": "variable.other.readwrite.batchfile"
},
"2": {
"name": "keyword.operator.assignment.batchfile"
}
},
"end": "(?=$\\n|[&|><)])",
"name": "meta.prompt.set.batchfile",
"patterns": [
{
"include": "#strings"
}
]
}
]
}
]
},
"command_set_group": {
"patterns": [
{
"begin": "\\(",
"beginCaptures": {
"0": {
"name": "punctuation.section.group.begin.batchfile"
}
},
"end": "\\)",
"endCaptures": {
"0": {
"name": "punctuation.section.group.end.batchfile"
}
},
"patterns": [
{
"include": "#command_set_inside_arithmetic"
}
]
}
]
},
"command_set_inside_arithmetic": {
"patterns": [
{
"include": "#command_set_operators"
},
{
"include": "#numbers"
},
{
"match": ",",
"name": "punctuation.separator.batchfile"
}
]
},
"command_set_operators": {
"patterns": [
{
"match": "\\+\\=|\\-\\=|\\*\\=|/\\=|%%\\=|&\\=|\\|\\=|\\^\\=|<<\\=|>>\\=",
"name": "keyword.operator.assignment.augmented.batchfile"
},
{
"match": "\\+|\\-|/|\\*|%%|\\||&|\\^|<<|>>|~",
"name": "keyword.operator.arithmetic.batchfile"
},
{
"match": "!",
"name": "keyword.operator.logical.batchfile"
},
{
"match": "=",
"name": "keyword.operator.assignment.batchfile"
}
]
},
"comments": {
"patterns": [
{
"begin": "(?:^|(&))\\s*(?=((?::[+=,;: ])))",
"beginCaptures": {
"1": {
"name": "keyword.operator.conditional.batchfile"
}
},
"end": "\\n",
"patterns": [
{
"begin": "((?::[+=,;: ]))",
"beginCaptures": {
"1": {
"name": "punctuation.definition.comment.batchfile"
}
},
"end": "(?=\\n)",
"name": "comment.line.colon.batchfile"
}
]
},
{
"begin": "(?<=^|[\\s@])(?i)(REM)(\\.)",
"beginCaptures": {
"1": {
"name": "keyword.command.rem.batchfile"
},
"2": {
"name": "punctuation.separator.batchfile"
}
},
"end": "(?=$\\n|[&|><)])",
"name": "comment.line.rem.batchfile"
},
{
"begin": "(?<=^|[\\s@])(?i:rem)\\b",
"beginCaptures": {
"0": {
"name": "keyword.command.rem.batchfile"
}
},
"end": "\\n",
"name": "comment.line.rem.batchfile",
"patterns": [
{
"match": "[><|]",
"name": "invalid.illegal.unexpected-character.batchfile"
}
]
}
]
},
"constants": {
"patterns": [
{
"match": "\\b(?i:NUL)\\b",
"name": "constant.language.batchfile"
}
]
},
"controls": {
"patterns": [
{
"match": "(?<=^|\\s)(?i)(?:goto|call|exit)(?=$|\\s)",
"name": "keyword.control.statement.batchfile"
},
{
"match": "(?<=^|\\s)(?i)(if)\\s+(?:(not)\\s+)?(exist|defined|errorlevel|cmdextversion)(?=\\s)",
"captures": {
"1": {
"name": "keyword.control.conditional.batchfile"
},
"2": {
"name": "keyword.operator.logical.batchfile"
},
"3": {
"name": "keyword.other.special-method.batchfile"
}
}
},
{
"match": "(?<=^|\\s)(?i)(?:if|else)(?=$|\\s)",
"name": "keyword.control.conditional.batchfile"
},
{
"match": "(?<=^|\\s)(?i)for(?=\\s)",
"name": "keyword.control.repeat.batchfile"
}
]
},
"escaped_characters": {
"patterns": [
{
"match": "%%|\\^\\^!|\\^.|\\^\\n",
"name": "constant.character.escape.batchfile"
}
]
},
"labels": {
"patterns": [
{
"match": "^\\s*(:)([^+=,;:\\s].*)$",
"captures": {
"1": {
"name": "punctuation.separator.batchfile"
},
"2": {
"name": "keyword.other.special-method.batchfile"
}
}
}
]
},
"numbers": {
"patterns": [
{
"match": "(?<=^|\\s|=)(0[xX][0-9A-Fa-f]*|[+-]?\\d+)(?=$|\\s|<|>)",
"name": "constant.numeric.batchfile"
}
]
},
"operators": {
"patterns": [
{
"match": "@(?=\\S)",
"name": "keyword.operator.at.batchfile"
},
{
"match": "(?<=\\s)(?i:EQU|NEQ|LSS|LEQ|GTR|GEQ)(?=\\s)|==",
"name": "keyword.operator.comparison.batchfile"
},
{
"match": "(?<=\\s)(?i)(NOT)(?=\\s)",
"name": "keyword.operator.logical.batchfile"
},
{
"match": "&&?|\\|\\|",
"name": "keyword.operator.conditional.batchfile"
},
{
"match": "\\|",
"name": "keyword.operator.pipe.batchfile"
},
{
"match": "<&?|>[&>]?",
"name": "keyword.operator.redirection.batchfile"
}
]
},
"parens": {
"patterns": [
{
"begin": "\\(",
"beginCaptures": {
"0": "punctuation.section.group.begin.batchfile"
},
"end": "\\)",
"endCaptures": {
"0": "punctuation.section.group.end.batchfile"
},
"name": "meta.group.batchfile",
"patterns": [
{
"match": ",|;",
"name": "punctuation.separator.batchfile"
},
{
"include": "$self"
}
]
}
]
},
"strings": {
"patterns": [
{
"begin": "\"",
"beginCaptures": {
"0": {
"name": "punctuation.definition.string.begin.batchfile"
}
},
"end": "(\")|(\\n)",
"endCaptures": {
"1": {
"name": "punctuation.definition.string.end.batchfile"
},
"2": {
"name": "invalid.illegal.newline.batchfile"
}
},
"name": "string.quoted.double.batchfile",
"patterns": [
{
"include": "#variables"
}
]
}
]
},
"variables": {
"patterns": [
{
"match": "(%)((~([fdpnxsatz]|\\$PATH:)*)?\\d|\\*)",
"captures": {
"1": {
"name": "punctuation.definition.variable.batchfile"
}
},
"name": "variable.parameter.batchfile"
},
{
"include": "#variable"
},
{
"include": "#variable_delayed_expansion"
}
]
},
"variable": {
"patterns": [
{
"begin": "%(?=[^%]+%)",
"beginCaptures": {
"0": {
"name": "punctuation.definition.variable.begin.batchfile"
}
},
"end": "(%)|\\n",
"endCaptures": {
"1": {
"name": "punctuation.definition.variable.end.batchfile"
}
},
"name": "variable.other.readwrite.batchfile",
"patterns": [
{
"begin": ":~",
"beginCaptures": {
"0": {
"name": "punctuation.separator.batchfile"
}
},
"end": "(?=%|\\n)",
"name": "meta.variable.substring.batchfile",
"patterns": [
{
"include": "#variable_substring"
}
]
},
{
"begin": ":",
"beginCaptures": {
"0": {
"name": "punctuation.separator.batchfile"
}
},
"end": "(?=%|\\n)",
"name": "meta.variable.substitution.batchfile",
"patterns": [
{
"include": "#variable_replace"
},
{
"begin": "=",
"beginCaptures": {
"0": {
"name": "punctuation.separator.batchfile"
}
},
"end": "(?=%|\\n)",
"patterns": [
{
"include": "#variable_delayed_expansion"
},
{
"match": "[^%]+",
"name": "string.unquoted.batchfile"
}
]
}
]
}
]
}
]
},
"variable_delayed_expansion": {
"patterns": [
{
"begin": "!(?=[^!]+!)",
"beginCaptures": {
"0": {
"name": "punctuation.definition.variable.begin.batchfile"
}
},
"end": "(!)|\\n",
"endCaptures": {
"1": {
"name": "punctuation.definition.variable.end.batchfile"
}
},
"name": "variable.other.readwrite.batchfile",
"patterns": [
{
"begin": ":~",
"beginCaptures": {
"0": {
"name": "punctuation.separator.batchfile"
}
},
"end": "(?=!|\\n)",
"name": "meta.variable.substring.batchfile",
"patterns": [
{
"include": "#variable_substring"
}
]
},
{
"begin": ":",
"beginCaptures": {
"0": {
"name": "punctuation.separator.batchfile"
}
},
"end": "(?=!|\\n)",
"name": "meta.variable.substitution.batchfile",
"patterns": [
{
"include": "#escaped_characters"
},
{
"include": "#variable_replace"
},
{
"include": "#variable"
},
{
"begin": "=",
"beginCaptures": {
"0": {
"name": "punctuation.separator.batchfile"
}
},
"end": "(?=!|\\n)",
"patterns": [
{
"include": "#variable"
},
{
"match": "[^!]+",
"name": "string.unquoted.batchfile"
}
]
}
]
}
]
}
]
},
"variable_replace": {
"patterns": [
{
"match": "[^=%!\\n]+",
"name": "string.unquoted.batchfile"
}
]
},
"variable_substring": {
"patterns": [
{
"match": "([+-]?\\d+)(?:(,)([+-]?\\d+))?",
"captures": {
"1": {
"name": "constant.numeric.batchfile"
},
"2": {
"name": "punctuation.separator.batchfile"
},
"3": {
"name": "constant.numeric.batchfile"
}
}
}
]
}
}
}
@@ -1,18 +1,18 @@
[
{
"c": "@",
"t": "source.dosbatch",
"t": "source.batchfile keyword.operator.at.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"hc_black": "keyword.operator: #D4D4D4"
}
},
{
"c": "echo",
"t": "source.dosbatch keyword.command.dosbatch",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@@ -23,7 +23,7 @@
},
{
"c": " off",
"t": "source.dosbatch",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -34,7 +34,7 @@
},
{
"c": "setlocal",
"t": "source.dosbatch keyword.command.dosbatch",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@@ -45,7 +45,7 @@
},
{
"c": "title",
"t": "source.dosbatch keyword.command.dosbatch",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@@ -56,7 +56,7 @@
},
{
"c": " VSCode Dev",
"t": "source.dosbatch",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -67,7 +67,7 @@
},
{
"c": "pushd",
"t": "source.dosbatch keyword.command.dosbatch",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@@ -78,7 +78,7 @@
},
{
"c": " ",
"t": "source.dosbatch",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -89,7 +89,7 @@
},
{
"c": "%",
"t": "source.dosbatch variable.parameter.function.dosbatch variable.parameter.function.begin.shell",
"t": "source.batchfile variable.parameter.batchfile punctuation.definition.variable.batchfile",
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
@@ -100,7 +100,7 @@
},
{
"c": "~dp0",
"t": "source.dosbatch variable.parameter.function.dosbatch",
"t": "source.batchfile variable.parameter.batchfile",
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
@@ -111,7 +111,7 @@
},
{
"c": "\\..",
"t": "source.dosbatch",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -121,8 +121,8 @@
}
},
{
"c": ":: Node modules",
"t": "source.dosbatch comment.line.colons.dosbatch",
"c": "::",
"t": "source.batchfile comment.line.colon.batchfile punctuation.definition.comment.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
@@ -132,8 +132,19 @@
}
},
{
"c": "if not exist",
"t": "source.dosbatch keyword.control.conditional.if.dosbatch",
"c": " Node modules",
"t": "source.batchfile comment.line.colon.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": "if",
"t": "source.batchfile keyword.control.conditional.batchfile",
"r": {
"dark_plus": "keyword.control: #C586C0",
"light_plus": "keyword.control: #AF00DB",
@@ -142,9 +153,53 @@
"hc_black": "keyword.control: #C586C0"
}
},
{
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "not",
"t": "source.batchfile keyword.operator.logical.batchfile",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"hc_black": "keyword.operator: #D4D4D4"
}
},
{
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "exist",
"t": "source.batchfile keyword.other.special-method.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
"c": " node_modules ",
"t": "source.dosbatch",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -155,7 +210,7 @@
},
{
"c": "call",
"t": "source.dosbatch keyword.control.statement.dosbatch",
"t": "source.batchfile keyword.control.statement.batchfile",
"r": {
"dark_plus": "keyword.control: #C586C0",
"light_plus": "keyword.control: #AF00DB",
@@ -166,7 +221,7 @@
},
{
"c": " .\\scripts\\npm.bat install",
"t": "source.dosbatch",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -176,8 +231,19 @@
}
},
{
"c": ":: Get electron",
"t": "source.dosbatch comment.line.colons.dosbatch",
"c": "::",
"t": "source.batchfile comment.line.colon.batchfile punctuation.definition.comment.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": " Get electron",
"t": "source.batchfile comment.line.colon.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
@@ -188,7 +254,7 @@
},
{
"c": "node .\\node_modules\\gulp\\bin\\gulp.js electron",
"t": "source.dosbatch",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -198,8 +264,8 @@
}
},
{
"c": ":: Build",
"t": "source.dosbatch comment.line.colons.dosbatch",
"c": "::",
"t": "source.batchfile comment.line.colon.batchfile punctuation.definition.comment.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
@@ -209,8 +275,19 @@
}
},
{
"c": "if not exist",
"t": "source.dosbatch keyword.control.conditional.if.dosbatch",
"c": " Build",
"t": "source.batchfile comment.line.colon.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": "if",
"t": "source.batchfile keyword.control.conditional.batchfile",
"r": {
"dark_plus": "keyword.control: #C586C0",
"light_plus": "keyword.control: #AF00DB",
@@ -220,8 +297,8 @@
}
},
{
"c": " out node .\\node_modules\\gulp\\bin\\gulp.js compile",
"t": "source.dosbatch",
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -231,8 +308,63 @@
}
},
{
"c": ":: Configuration",
"t": "source.dosbatch comment.line.colons.dosbatch",
"c": "not",
"t": "source.batchfile keyword.operator.logical.batchfile",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"hc_black": "keyword.operator: #D4D4D4"
}
},
{
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "exist",
"t": "source.batchfile keyword.other.special-method.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
"dark_vs": "keyword: #569CD6",
"light_vs": "keyword: #0000FF",
"hc_black": "keyword: #569CD6"
}
},
{
"c": " out node .\\node_modules\\gulp\\bin\\gulp.js compile",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "::",
"t": "source.batchfile comment.line.colon.batchfile punctuation.definition.comment.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
"dark_vs": "comment: #608B4E",
"light_vs": "comment: #008000",
"hc_black": "comment: #7CA668"
}
},
{
"c": " Configuration",
"t": "source.batchfile comment.line.colon.batchfile",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
@@ -243,7 +375,7 @@
},
{
"c": "set",
"t": "source.dosbatch keyword.command.dosbatch",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@@ -253,8 +385,41 @@
}
},
{
"c": " NODE_ENV=development",
"t": "source.dosbatch",
"c": " ",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "NODE_ENV",
"t": "source.batchfile variable.other.readwrite.batchfile",
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "variable: #9CDCFE"
}
},
{
"c": "=",
"t": "source.batchfile keyword.operator.assignment.batchfile",
"r": {
"dark_plus": "keyword.operator: #D4D4D4",
"light_plus": "keyword.operator: #000000",
"dark_vs": "keyword.operator: #D4D4D4",
"light_vs": "keyword.operator: #000000",
"hc_black": "keyword.operator: #D4D4D4"
}
},
{
"c": "development",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -265,7 +430,7 @@
},
{
"c": "call",
"t": "source.dosbatch keyword.control.statement.dosbatch",
"t": "source.batchfile keyword.control.statement.batchfile",
"r": {
"dark_plus": "keyword.control: #C586C0",
"light_plus": "keyword.control: #AF00DB",
@@ -276,7 +441,7 @@
},
{
"c": " ",
"t": "source.dosbatch",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -287,7 +452,7 @@
},
{
"c": "echo",
"t": "source.dosbatch keyword.command.dosbatch",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@@ -298,7 +463,7 @@
},
{
"c": " ",
"t": "source.dosbatch",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -308,19 +473,41 @@
}
},
{
"c": "%%LINE:rem +=%%",
"t": "source.dosbatch variable.other.parsetime.dosbatch",
"c": "%%",
"t": "source.batchfile constant.character.escape.batchfile",
"r": {
"dark_plus": "variable: #9CDCFE",
"light_plus": "variable: #001080",
"dark_plus": "constant.character.escape: #D7BA7D",
"light_plus": "constant.character.escape: #A31515",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "variable: #9CDCFE"
"hc_black": "constant.character: #569CD6"
}
},
{
"c": "LINE:rem +=",
"t": "source.batchfile",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "%%",
"t": "source.batchfile constant.character.escape.batchfile",
"r": {
"dark_plus": "constant.character.escape: #D7BA7D",
"light_plus": "constant.character.escape: #A31515",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "constant.character: #569CD6"
}
},
{
"c": "popd",
"t": "source.dosbatch keyword.command.dosbatch",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@@ -331,7 +518,7 @@
},
{
"c": "endlocal",
"t": "source.dosbatch keyword.command.dosbatch",
"t": "source.batchfile keyword.command.batchfile",
"r": {
"dark_plus": "keyword: #569CD6",
"light_plus": "keyword: #0000FF",
@@ -1,4 +1,3 @@
test/**
src/**
tsconfig.json
npm-shrinkwrap.json
tsconfig.json
@@ -10,7 +10,7 @@
"Other"
],
"activationEvents": [
"onLanguage:json"
"onLanguage:json", "onLanguage:jsonc"
],
"main": "./out/extension",
"scripts": {
@@ -14,12 +14,12 @@ import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
const decoration = vscode.window.createTextEditorDecorationType({
color: '#b1b1b1'
color: '#9e9e9e'
});
let pendingLaunchJsonDecoration: NodeJS.Timer;
export function activate(context): void {
export function activate(context: vscode.ExtensionContext): void {
//keybindings.json command-suggestions
context.subscriptions.push(registerKeybindingsCompletions());
@@ -60,7 +60,7 @@ function registerKeybindingsCompletions(): vscode.Disposable {
}
function registerSettingsCompletions(): vscode.Disposable {
return vscode.languages.registerCompletionItemProvider({ language: 'json', pattern: '**/settings.json' }, {
return vscode.languages.registerCompletionItemProvider({ language: 'jsonc', pattern: '**/settings.json' }, {
provideCompletionItems(document, position, token) {
return new SettingsDocument(document).provideCompletionItems(position, token);
}
@@ -173,7 +173,7 @@ function updateLaunchJsonDecorations(editor: vscode.TextEditor | undefined): voi
editor.setDecorations(decoration, ranges);
}
vscode.languages.registerDocumentSymbolProvider({ pattern: '**/launch.json', language: 'json' }, {
vscode.languages.registerDocumentSymbolProvider({ pattern: '**/launch.json', language: 'jsonc' }, {
provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.ProviderResult<vscode.SymbolInformation[]> {
const result: vscode.SymbolInformation[] = [];
let name: string = '';
@@ -149,20 +149,36 @@ export class SettingsDocument {
return Promise.resolve(completions);
}
private provideLanguageCompletionItems(location: Location, range: vscode.Range, formatFunc: (string) => string = (l) => JSON.stringify(l)): vscode.ProviderResult<vscode.CompletionItem[]> {
private provideLanguageCompletionItems(location: Location, range: vscode.Range, formatFunc: (string: string) => string = (l) => JSON.stringify(l)): vscode.ProviderResult<vscode.CompletionItem[]> {
return vscode.languages.getLanguages().then(languages => {
return languages.map(l => {
return this.newSimpleCompletionItem(formatFunc(l), range);
});
const completionItems = [];
const configuration = vscode.workspace.getConfiguration();
for (const language of languages) {
const inspect = configuration.inspect(`[${language}]`);
if (!inspect || !inspect.defaultValue) {
const item = new vscode.CompletionItem(formatFunc(language));
item.kind = vscode.CompletionItemKind.Property;
item.range = range;
completionItems.push(item);
}
}
return completionItems;
});
}
private provideLanguageOverridesCompletionItems(location: Location, position: vscode.Position): vscode.ProviderResult<vscode.CompletionItem[]> {
let range = this.document.getWordRangeAtPosition(position) || new vscode.Range(position, position);
const text = this.document.getText(range);
if (location.path.length === 0) {
let range = this.document.getWordRangeAtPosition(position, /^\s*\[.*]?/) || new vscode.Range(position, position);
let text = this.document.getText(range);
if (text && text.trim().startsWith('[')) {
range = new vscode.Range(new vscode.Position(range.start.line, range.start.character + text.indexOf('[')), range.end);
return this.provideLanguageCompletionItems(location, range, language => `"[${language}]"`);
}
range = this.document.getWordRangeAtPosition(position) || new vscode.Range(position, position);
text = this.document.getText(range);
let snippet = '"[${1:language}]": {\n\t"$0"\n}';
// Suggestion model word matching includes quotes,
@@ -184,6 +200,7 @@ export class SettingsDocument {
if (location.path.length === 1 && location.previousNode && typeof location.previousNode.value === 'string' && location.previousNode.value.startsWith('[')) {
// Suggestion model word matching includes closed sqaure bracket and ending quote
// Hence include them in the proposal to replace
let range = this.document.getWordRangeAtPosition(position) || new vscode.Range(position, position);
return this.provideLanguageCompletionItems(location, range, language => `"[${language}]"`);
}
return Promise.resolve([]);
@@ -6,7 +6,7 @@
"lib": [
"es2015"
],
"strictNullChecks": true
"strict": true
},
"include": [
"src/**/*"
@@ -0,0 +1,17 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/node@7.0.4":
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"
vscode-nls@^2.0.1, vscode-nls@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"
+1 -2
View File
@@ -1,4 +1,3 @@
test/**
src/**
tsconfig.json
npm-shrinkwrap.json
tsconfig.json
+2 -2
View File
@@ -47,6 +47,6 @@
},
"devDependencies": {
"@types/markdown-it": "0.0.2",
"@types/node": "7.0.43"
"@types/node": "6.0.78"
}
}
}
@@ -17,7 +17,7 @@ export function activate(context: vscode.ExtensionContext) {
//package.json suggestions
context.subscriptions.push(registerPackageDocumentCompletions());
context.subscriptions.push(new ExtensionLinter(context));
context.subscriptions.push(new ExtensionLinter());
}
const _linkProvider = new class implements vscode.DocumentLinkProvider {
@@ -10,7 +10,7 @@ import { parseTree, findNodeAtLocation, Node as JsonNode } from 'jsonc-parser';
import * as nls from 'vscode-nls';
import * as MarkdownItType from 'markdown-it';
import { languages, workspace, Disposable, ExtensionContext, TextDocument, Uri, Diagnostic, Range, DiagnosticSeverity, Position } from 'vscode';
import { languages, workspace, Disposable, TextDocument, Uri, Diagnostic, Range, DiagnosticSeverity, Position } from 'vscode';
const product = require('../../../product.json');
const allowedBadgeProviders: string[] = (product.extensionAllowedBadgeProviders || []).map(s => s.toLowerCase());
@@ -54,7 +54,7 @@ export class ExtensionLinter {
private timer: NodeJS.Timer;
private markdownIt: MarkdownItType.MarkdownIt;
constructor(private context: ExtensionContext) {
constructor() {
this.disposables.push(
workspace.onDidOpenTextDocument(document => this.queue(document)),
workspace.onDidChangeTextDocument(event => this.queue(event.document)),
@@ -227,7 +227,7 @@ export class ExtensionLinter {
}
this.diagnosticsCollection.set(document.uri, diagnostics);
};
}
}
private locateToken(text: string, begin: number, end: number, token: MarkdownItType.Token, content: string) {
@@ -5,6 +5,7 @@
"es2015"
],
"module": "commonjs",
"noUnusedLocals": true,
"outDir": "./out"
},
"include": [
+65
View File
@@ -0,0 +1,65 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/markdown-it@0.0.2":
version "0.0.2"
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.2.tgz#5d9ad19e6e6508cdd2f2596df86fd0aade598660"
"@types/node@6.0.78", "@types/node@^6.0.46":
version "6.0.78"
resolved "https://registry.yarnpkg.com/@types/node/-/node-6.0.78.tgz#5d4a3f579c1524e01ee21bf474e6fba09198f470"
argparse@^1.0.7:
version "1.0.9"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
dependencies:
sprintf-js "~1.0.2"
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"
linkify-it@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.0.3.tgz#d94a4648f9b1c179d64fa97291268bdb6ce9434f"
dependencies:
uc.micro "^1.0.1"
markdown-it@^8.3.1:
version "8.3.1"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.3.1.tgz#2f4b622948ccdc193d66f3ca2d43125ac4ac7323"
dependencies:
argparse "^1.0.7"
entities "~1.1.1"
linkify-it "^2.0.0"
mdurl "^1.0.1"
uc.micro "^1.0.3"
mdurl@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
parse5@^3.0.2:
version "3.0.2"
resolved "https://registry.yarnpkg.com/parse5/-/parse5-3.0.2.tgz#05eff57f0ef4577fb144a79f8b9a967a6cc44510"
dependencies:
"@types/node" "^6.0.46"
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
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:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"
+1 -2
View File
@@ -1,5 +1,4 @@
src/**
test/**
out/test/**
tsconfig.json
npm-shrinkwrap.json
tsconfig.json
+160 -99
View File
@@ -219,6 +219,11 @@
"title": "%command.deleteBranch%",
"category": "Git"
},
{
"command": "git.renameBranch",
"title": "%command.renameBranch%",
"category": "Git"
},
{
"command": "git.merge",
"title": "%command.merge%",
@@ -229,6 +234,11 @@
"title": "%command.createTag%",
"category": "Git"
},
{
"command": "git.fetch",
"title": "%command.fetch%",
"category": "Git"
},
{
"command": "git.pull",
"title": "%command.pull%",
@@ -264,6 +274,11 @@
"title": "%command.sync%",
"category": "Git"
},
{
"command": "git.syncRebase",
"title": "%command.syncRebase%",
"category": "Git"
},
{
"command": "git.publish",
"title": "%command.publish%",
@@ -279,6 +294,11 @@
"title": "%command.ignore%",
"category": "Git"
},
{
"command": "git.stashIncludeUntracked",
"title": "%command.stashIncludeUntracked%",
"category": "Git"
},
{
"command": "git.stash",
"title": "%command.stash%",
@@ -305,33 +325,37 @@
"command": "git.init",
"when": "config.git.enabled"
},
{
"command": "git.close",
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.refresh",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.openFile",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.openHEADFile",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.openChange",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.stage",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.stageAll",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.stageSelectedRanges",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.stageChange",
@@ -339,7 +363,7 @@
},
{
"command": "git.revertSelectedRanges",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.revertChange",
@@ -347,378 +371,404 @@
},
{
"command": "git.unstage",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.unstageAll",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.unstageSelectedRanges",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.clean",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.cleanAll",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.commit",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.commitStaged",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.commitStagedSigned",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.commitStagedAmend",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.commitAll",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.commitAllSigned",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.commitAllAmend",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.undoCommit",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.checkout",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.branch",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.deleteBranch",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.renameBranch",
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.pull",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.pullFrom",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.pullRebase",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.pullFrom",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.merge",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.createTag",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.fetch",
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.push",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.pushTo",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.pushWithTags",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.sync",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.syncRebase",
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.publish",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.showOutput",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.ignore",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.stashIncludeUntracked",
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.stash",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.stashPop",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
},
{
"command": "git.stashPopLatest",
"when": "config.git.enabled && gitOpenRepositoryCount != 0"
"when": "gitOpenRepositoryCount != 0"
}
],
"scm/title": [
{
"command": "git.init",
"group": "navigation",
"when": "config.git.enabled && !scmProvider && gitOpenRepositoryCount == 0"
"when": "config.git.enabled && !scmProvider && gitOpenRepositoryCount == 0 && workspaceFolderCount != 0"
},
{
"command": "git.commit",
"group": "navigation",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.refresh",
"group": "navigation",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.sync",
"group": "1_sync",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.syncRebase",
"group": "1_sync",
"when": "scmProvider == git && gitState == idle"
},
{
"command": "git.pull",
"group": "1_sync",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.pullRebase",
"group": "1_sync",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.pullFrom",
"group": "1_sync",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.push",
"group": "1_sync",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.pushTo",
"group": "1_sync",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.publish",
"group": "2_publish",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.commitStaged",
"group": "3_commit",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.commitStagedSigned",
"group": "3_commit",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.commitStagedAmend",
"group": "3_commit",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.commitAll",
"group": "3_commit",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.commitAllSigned",
"group": "3_commit",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.commitAllAmend",
"group": "3_commit",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.undoCommit",
"group": "3_commit",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.stageAll",
"group": "4_stage",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.unstageAll",
"group": "4_stage",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.cleanAll",
"group": "4_stage",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.stashIncludeUntracked",
"group": "5_stash",
"when": "scmProvider == git"
},
{
"command": "git.stash",
"group": "5_stash",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.stashPop",
"group": "5_stash",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.stashPopLatest",
"group": "5_stash",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
},
{
"command": "git.showOutput",
"group": "7_repository",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
}
],
"scm/sourceControl": [
{
"command": "git.close",
"group": "navigation",
"when": "config.git.enabled && scmProvider == git"
"when": "scmProvider == git"
}
],
"scm/resourceGroup/context": [
{
"command": "git.stageAll",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == merge",
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "1_modification"
},
{
"command": "git.stageAll",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == merge",
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "inline"
},
{
"command": "git.unstageAll",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == index",
"when": "scmProvider == git && scmResourceGroup == index",
"group": "1_modification"
},
{
"command": "git.unstageAll",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == index",
"when": "scmProvider == git && scmResourceGroup == index",
"group": "inline"
},
{
"command": "git.cleanAll",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "1_modification"
},
{
"command": "git.stageAll",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "1_modification"
},
{
"command": "git.cleanAll",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "inline"
},
{
"command": "git.stageAll",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "inline"
}
],
"scm/resourceState/context": [
{
"command": "git.stage",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == merge",
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "1_modification"
},
{
"command": "git.stage",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == merge",
"when": "scmProvider == git && scmResourceGroup == merge",
"group": "inline"
},
{
"command": "git.openChange",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == index",
"when": "scmProvider == git && scmResourceGroup == index",
"group": "navigation"
},
{
"command": "git.openFile",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == index",
"when": "scmProvider == git && scmResourceGroup == index",
"group": "navigation"
},
{
"command": "git.openHEADFile",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == index",
"when": "scmProvider == git && scmResourceGroup == index",
"group": "navigation"
},
{
"command": "git.unstage",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == index",
"when": "scmProvider == git && scmResourceGroup == index",
"group": "1_modification"
},
{
"command": "git.unstage",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == index",
"when": "scmProvider == git && scmResourceGroup == index",
"group": "inline"
},
{
"command": "git.openChange",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "navigation"
},
{
"command": "git.openHEADFile",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "navigation"
},
{
"command": "git.openFile",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "navigation"
},
{
"command": "git.stage",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "1_modification"
},
{
"command": "git.clean",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "1_modification"
},
{
"command": "git.clean",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "inline"
},
{
"command": "git.stage",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "inline"
},
{
"command": "git.ignore",
"when": "config.git.enabled && scmProvider == git && scmResourceGroup == workingTree",
"when": "scmProvider == git && scmResourceGroup == workingTree",
"group": "1_modification@3"
}
],
@@ -726,37 +776,37 @@
{
"command": "git.openFile",
"group": "navigation",
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != extension && resourceScheme != merge-conflict.conflict-diff"
"when": "gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != extension && resourceScheme != merge-conflict.conflict-diff"
},
{
"command": "git.openChange",
"group": "navigation",
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && !isInDiffEditor && resourceScheme == file"
"when": "gitOpenRepositoryCount != 0 && !isInDiffEditor && resourceScheme == file"
},
{
"command": "git.stageSelectedRanges",
"group": "2_git@1",
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff"
"when": "gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff"
},
{
"command": "git.unstageSelectedRanges",
"group": "2_git@2",
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff"
"when": "gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff"
},
{
"command": "git.revertSelectedRanges",
"group": "2_git@3",
"when": "config.git.enabled && gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff"
"when": "gitOpenRepositoryCount != 0 && isInDiffEditor && resourceScheme != merge-conflict.conflict-diff"
}
],
"scm/change/title": [
{
"command": "git.stageChange",
"when": "config.git.enabled && originalResourceScheme == git"
"when": "originalResourceScheme == git"
},
{
"command": "git.revertChange",
"when": "config.git.enabled && originalResourceScheme == git"
"when": "originalResourceScheme == git"
}
]
},
@@ -765,6 +815,7 @@
"properties": {
"git.enabled": {
"type": "boolean",
"scope": "resource",
"description": "%config.enabled%",
"default": true
},
@@ -785,7 +836,7 @@
"git.autofetch": {
"type": "boolean",
"description": "%config.autofetch%",
"default": true
"default": false
},
"git.confirmSync": {
"type": "boolean",
@@ -818,6 +869,11 @@
"description": "%config.ignoreLegacyWarning%",
"default": false
},
"git.ignoreMissingGitWarning": {
"type": "boolean",
"description": "%config.ignoreMissingGitWarning%",
"default": false
},
"git.ignoreLimitWarning": {
"type": "boolean",
"description": "%config.ignoreLimitWarning%",
@@ -895,13 +951,18 @@
},
"dependencies": {
"byline": "^5.0.0",
"iconv-lite": "0.4.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"
}
}
}
+6 -1
View File
@@ -28,8 +28,10 @@
"command.checkout": "Checkout to...",
"command.branch": "Create Branch...",
"command.deleteBranch": "Delete Branch...",
"command.renameBranch": "Rename Branch...",
"command.merge": "Merge Branch...",
"command.createTag": "Create Tag",
"command.fetch": "Fetch",
"command.pull": "Pull",
"command.pullRebase": "Pull (Rebase)",
"command.pullFrom": "Pull from...",
@@ -37,9 +39,11 @@
"command.pushTo": "Push to...",
"command.pushWithTags": "Push With Tags",
"command.sync": "Sync",
"command.syncRebase": "Sync (Rebase)",
"command.publish": "Publish Branch",
"command.showOutput": "Show Git Output",
"command.ignore": "Add File to .gitignore",
"command.stashIncludeUntracked": "Stash (Include Untracked)",
"command.stash": "Stash",
"command.stashPop": "Pop Stash...",
"command.stashPopLatest": "Pop Latest Stash",
@@ -52,6 +56,7 @@
"config.countBadge": "Controls the git badge counter. `all` counts all changes. `tracked` counts only the tracked changes. `off` turns it off.",
"config.checkoutType": "Controls what type of branches are listed when running `Checkout to...`. `all` shows all refs, `local` shows only the local branchs, `tags` shows only tags and `remote` shows only remote branches.",
"config.ignoreLegacyWarning": "Ignores the legacy Git warning",
"config.ignoreMissingGitWarning": "Ignores the warning when Git is missing",
"config.ignoreLimitWarning": "Ignores the warning when there are too many changes in a repository",
"config.defaultCloneDirectory": "The default location where to clone a git repository",
"config.enableSmartCommit": "Commit all changes when there are no staged changes.",
@@ -63,4 +68,4 @@
"colors.untracked": "Color for untracked resources.",
"colors.ignored": "Color for ignored resources.",
"colors.conflict": "Color for resources with conflicts."
}
}
@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="-0.994 0 16 16" enable-background="new -0.994 0 16 16"><path fill="#C5C5C5" d="M13 6c0 1.461-.636 2.846-1.746 3.797l-5.584 4.951-1.324-1.496 5.595-4.962c.678-.582 1.061-1.413 1.061-2.29 0-1.654-1.345-3-2.997-3-.71 0-1.399.253-1.938.713l-1.521 1.287h2.448l-1.998 2h-3.996v-4l1.998-2v2.692l1.775-1.504c.899-.766 2.047-1.188 3.232-1.188 2.754 0 4.995 2.243 4.995 5z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="-0.994 0 16 16" enable-background="new -0.994 0 16 16"><path fill="#C5C5C5" d="M13 6c0 1.461-.636 2.846-1.746 3.797l-5.584 4.951-1.324-1.496 5.595-4.962c.678-.582 1.061-1.413 1.061-2.29 0-1.654-1.345-3-2.997-3-.71 0-1.399.253-1.938.713l-1.521 1.287h2.448l-1.998 2h-3.996v-4l1.998-2v2.692l1.775-1.504c.899-.766 2.047-1.188 3.232-1.188 2.754 0 4.995 2.243 4.995 5z"/></svg>

Before

Width:  |  Height:  |  Size: 443 B

After

Width:  |  Height:  |  Size: 443 B

@@ -1 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16" viewBox="-0.994 0 16 16" enable-background="new -0.994 0 16 16"><path fill="#424242" d="M13 6c0 1.461-.636 2.846-1.746 3.797l-5.584 4.951-1.324-1.496 5.595-4.962c.678-.582 1.061-1.413 1.061-2.29 0-1.654-1.345-3-2.997-3-.71 0-1.399.253-1.938.713l-1.521 1.287h2.448l-1.998 2h-3.996v-4l1.998-2v2.692l1.775-1.504c.899-.766 2.047-1.188 3.232-1.188 2.754 0 4.995 2.243 4.995 5z"/></svg>
<svg xmlns="http://www.w3.org/2000/svg" width="14" height="14" viewBox="-0.994 0 16 16" enable-background="new -0.994 0 16 16"><path fill="#424242" d="M13 6c0 1.461-.636 2.846-1.746 3.797l-5.584 4.951-1.324-1.496 5.595-4.962c.678-.582 1.061-1.413 1.061-2.29 0-1.654-1.345-3-2.997-3-.71 0-1.399.253-1.938.713l-1.521 1.287h2.448l-1.998 2h-3.996v-4l1.998-2v2.692l1.775-1.504c.899-.766 2.047-1.188 3.232-1.188 2.754 0 4.995 2.243 4.995 5z"/></svg>

Before

Width:  |  Height:  |  Size: 443 B

After

Width:  |  Height:  |  Size: 443 B

+42
View File
@@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import { Model } from './model';
import { SourceControlInputBox, Uri } from 'vscode';
export interface InputBox {
value: string;
}
export interface Repository {
readonly rootUri: Uri;
readonly inputBox: InputBox;
}
export interface API {
getRepositories(): Promise<Repository[]>;
}
export function createApi(modelPromise: Promise<Model>) {
return {
async getRepositories(): Promise<Repository[]> {
const model = await modelPromise;
return model.repositories.map(repository => ({
rootUri: Uri.file(repository.root),
inputBox: {
set value(value: string) {
repository.inputBox.value = value;
},
get value(): string {
return repository.inputBox.value;
}
}
}));
}
};
}
+2 -2
View File
@@ -34,8 +34,8 @@ function main(argv: string[]): void {
return fatal('Skip fetch commands');
}
const output = process.env['VSCODE_GIT_ASKPASS_PIPE'];
const socketPath = process.env['VSCODE_GIT_ASKPASS_HANDLE'];
const output = process.env['VSCODE_GIT_ASKPASS_PIPE'] as string;
const socketPath = process.env['VSCODE_GIT_ASKPASS_HANDLE'] as string;
const request = argv[2];
const host = argv[4].substring(1, argv[4].length - 2);
const opts: http.RequestOptions = {
+1 -1
View File
@@ -28,7 +28,7 @@ function getIPCHandlePath(nonce: string): string {
}
if (process.env['XDG_RUNTIME_DIR']) {
return path.join(process.env['XDG_RUNTIME_DIR'], `vscode-git-askpass-${nonce}.sock`);
return path.join(process.env['XDG_RUNTIME_DIR'] as string, `vscode-git-askpass-${nonce}.sock`);
}
return path.join(os.tmpdir(), `vscode-git-askpass-${nonce}.sock`);
+53 -5
View File
@@ -5,14 +5,22 @@
'use strict';
import { workspace, Disposable, EventEmitter } from 'vscode';
import { workspace, Disposable, EventEmitter, Memento, window, MessageItem, ConfigurationTarget, commands, Uri } from 'vscode';
import { GitErrorCodes } from './git';
import { Repository } from './repository';
import { eventToPromise, filterEvent } from './util';
import { Repository, Operation } from './repository';
import { eventToPromise, filterEvent, onceEvent } from './util';
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
function isRemoteOperation(operation: Operation): boolean {
return operation === Operation.Pull || operation === Operation.Push || operation === Operation.Sync || operation === Operation.Fetch;
}
export class AutoFetcher {
private static Period = 3 * 60 * 1000 /* three minutes */;
private static readonly Period = 3 * 60 * 1000 /* three minutes */;
private static DidInformUser = 'autofetch.didInformUser';
private _onDidChange = new EventEmitter<boolean>();
private onDidChange = this._onDidChange.event;
@@ -23,9 +31,49 @@ export class AutoFetcher {
private disposables: Disposable[] = [];
constructor(private repository: Repository) {
constructor(private repository: Repository, private globalState: Memento) {
workspace.onDidChangeConfiguration(this.onConfiguration, this, this.disposables);
this.onConfiguration();
const onGoodRemoteOperation = filterEvent(repository.onDidRunOperation, ({ operation, error }) => !error && isRemoteOperation(operation));
const onFirstGoodRemoteOperation = onceEvent(onGoodRemoteOperation);
onFirstGoodRemoteOperation(this.onFirstGoodRemoteOperation, this, this.disposables);
}
private async onFirstGoodRemoteOperation(): Promise<void> {
const didInformUser = !this.globalState.get<boolean>(AutoFetcher.DidInformUser);
if (this.enabled && !didInformUser) {
this.globalState.update(AutoFetcher.DidInformUser, true);
}
const shouldInformUser = !this.enabled && didInformUser;
if (!shouldInformUser) {
return;
}
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', "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);
}
this.globalState.update(AutoFetcher.DidInformUser, true);
}
private onConfiguration(): void {
+214 -69
View File
@@ -5,7 +5,7 @@
'use strict';
import { Uri, commands, Disposable, window, workspace, QuickPickItem, OutputChannel, Range, WorkspaceEdit, Position, LineChange, SourceControlResourceState, TextDocumentShowOptions, ViewColumn, ProgressLocation, TextEditor } from 'vscode';
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 { Model } from './model';
@@ -127,6 +127,15 @@ function command(commandId: string, options: CommandOptions = {}): Function {
};
}
const ImageMimetypes = [
'image/png',
'image/gif',
'image/jpeg',
'image/webp',
'image/tiff',
'image/bmp'
];
export class CommandCenter {
private disposables: Disposable[];
@@ -159,8 +168,8 @@ export class CommandCenter {
}
private async _openResource(resource: Resource, preview?: boolean, preserveFocus?: boolean, preserveSelection?: boolean): Promise<void> {
const left = this.getLeftResource(resource);
const right = this.getRightResource(resource);
const left = await this.getLeftResource(resource);
const right = await this.getRightResource(resource);
const title = this.getTitle(resource);
if (!right) {
@@ -184,40 +193,77 @@ export class CommandCenter {
}
if (!left) {
const document = await workspace.openTextDocument(right);
await window.showTextDocument(document, opts);
return;
await commands.executeCommand<void>('vscode.open', right, opts);
} else {
await commands.executeCommand<void>('vscode.diff', left, right, title, opts);
}
return await commands.executeCommand<void>('vscode.diff', left, right, title, opts);
}
private getLeftResource(resource: Resource): Uri | undefined {
private async getURI(uri: Uri, ref: string): Promise<Uri | undefined> {
const repository = this.model.getRepository(uri);
if (!repository) {
return toGitUri(uri, ref);
}
try {
let gitRef = ref;
if (gitRef === '~') {
const uriString = uri.toString();
const [indexStatus] = repository.indexGroup.resourceStates.filter(r => r.resourceUri.toString() === uriString);
gitRef = indexStatus ? '' : 'HEAD';
}
const { size, object } = await repository.lstree(gitRef, uri.fsPath);
const { mimetype, encoding } = await repository.detectObjectType(object);
if (mimetype === 'text/plain') {
return toGitUri(uri, ref);
}
if (size > 1000000) { // 1 MB
return Uri.parse(`data:;label:${path.basename(uri.fsPath)};description:${gitRef},`);
}
if (ImageMimetypes.indexOf(mimetype) > -1) {
const contents = await repository.buffer(gitRef, uri.fsPath);
return Uri.parse(`data:${mimetype};label:${path.basename(uri.fsPath)};description:${gitRef};size:${size};base64,${contents.toString('base64')}`);
}
return Uri.parse(`data:;label:${path.basename(uri.fsPath)};description:${gitRef},`);
} catch (err) {
return toGitUri(uri, ref);
}
}
private async getLeftResource(resource: Resource): Promise<Uri | undefined> {
switch (resource.type) {
case Status.INDEX_MODIFIED:
case Status.INDEX_RENAMED:
return toGitUri(resource.original, 'HEAD');
return this.getURI(resource.original, 'HEAD');
case Status.MODIFIED:
return toGitUri(resource.resourceUri, '~');
return this.getURI(resource.resourceUri, '~');
case Status.DELETED_BY_THEM:
return toGitUri(resource.resourceUri, '');
return this.getURI(resource.resourceUri, '');
}
}
private getRightResource(resource: Resource): Uri | undefined {
private async getRightResource(resource: Resource): Promise<Uri | undefined> {
switch (resource.type) {
case Status.INDEX_MODIFIED:
case Status.INDEX_ADDED:
case Status.INDEX_COPIED:
case Status.INDEX_RENAMED:
return toGitUri(resource.resourceUri, '');
return this.getURI(resource.resourceUri, '');
case Status.INDEX_DELETED:
case Status.DELETED_BY_THEM:
case Status.DELETED:
return toGitUri(resource.resourceUri, 'HEAD');
return this.getURI(resource.resourceUri, 'HEAD');
case Status.MODIFIED:
case Status.UNTRACKED:
@@ -261,6 +307,8 @@ export class CommandCenter {
return '';
}
private static cloneId = 0;
@command('git.clone')
async clone(url?: string): Promise<void> {
if (!url) {
@@ -281,7 +329,8 @@ export class CommandCenter {
}
const config = workspace.getConfiguration('git');
const value = config.get<string>('defaultCloneDirectory') || os.homedir();
let value = config.get<string>('defaultCloneDirectory') || os.homedir();
value = value.replace(/^~/, os.homedir());
const parentPath = await window.showInputBox({
prompt: localize('parent', "Parent Directory"),
@@ -299,12 +348,21 @@ export class CommandCenter {
return;
}
const clonePromise = this.git.clone(url, parentPath);
const tokenSource = new CancellationTokenSource();
const cancelCommandId = `cancelClone${CommandCenter.cloneId++}`;
const commandDisposable = commands.registerCommand(cancelCommandId, () => tokenSource.cancel());
const statusBarItem = window.createStatusBarItem(StatusBarAlignment.Left);
statusBarItem.text = localize('cancel', "$(sync~spin) Cloning repository... Click to cancel");
statusBarItem.tooltip = localize('cancel tooltip', "Cancel clone");
statusBarItem.command = cancelCommandId;
statusBarItem.show();
const clonePromise = this.git.clone(url, parentPath, 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);
// window.withProgress({ location: ProgressLocation.Window, title: localize('cloning', "Cloning git repository...") }, () => clonePromise);
const repositoryPath = await clonePromise;
@@ -330,6 +388,8 @@ export class CommandCenter {
}
*/
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'directory_not_empty' });
} else if (/Cancelled/i.test(err && (err.message || err.stderr || ''))) {
return;
} else {
/* __GDPR__
"clone" : {
@@ -338,41 +398,62 @@ export class CommandCenter {
*/
this.telemetryReporter.sendTelemetryEvent('clone', { outcome: 'error' });
}
throw err;
} finally {
commandDisposable.dispose();
statusBarItem.dispose();
}
}
@command('git.init')
async init(): Promise<void> {
const homeUri = Uri.file(os.homedir());
const defaultUri = workspace.workspaceFolders && workspace.workspaceFolders.length > 0
? Uri.file(workspace.workspaceFolders[0].uri.fsPath)
: homeUri;
let path: string | undefined;
const result = await window.showOpenDialog({
canSelectFiles: false,
canSelectFolders: true,
canSelectMany: false,
defaultUri,
openLabel: localize('init repo', "Initialize Repository")
});
if (workspace.workspaceFolders && workspace.workspaceFolders.length > 1) {
const placeHolder = localize('init', "Pick workspace folder to initialize git repo in");
const items = workspace.workspaceFolders.map(folder => ({ label: folder.name, description: folder.uri.fsPath, folder }));
const item = await window.showQuickPick(items, { placeHolder, ignoreFocusOut: true });
if (!result || result.length === 0) {
return;
}
const uri = result[0];
if (homeUri.toString().startsWith(uri.toString())) {
const yes = localize('create repo', "Initialize Repository");
const answer = await window.showWarningMessage(localize('are you sure', "This will create a Git repository in '{0}'. Are you sure you want to continue?", uri.fsPath), yes);
if (answer !== yes) {
if (!item) {
return;
}
path = item.folder.uri.fsPath;
}
if (!path) {
const homeUri = Uri.file(os.homedir());
const defaultUri = workspace.workspaceFolders && workspace.workspaceFolders.length > 0
? Uri.file(workspace.workspaceFolders[0].uri.fsPath)
: homeUri;
const result = await window.showOpenDialog({
canSelectFiles: false,
canSelectFolders: true,
canSelectMany: false,
defaultUri,
openLabel: localize('init repo', "Initialize Repository")
});
if (!result || result.length === 0) {
return;
}
const uri = result[0];
if (homeUri.toString().startsWith(uri.toString())) {
const yes = localize('create repo', "Initialize Repository");
const answer = await window.showWarningMessage(localize('are you sure', "This will create a Git repository in '{0}'. Are you sure you want to continue?", uri.fsPath), yes);
if (answer !== yes) {
return;
}
}
path = uri.fsPath;
}
const path = uri.fsPath;
await this.git.init(path);
await this.model.tryOpenRepository(path);
}
@@ -426,8 +507,7 @@ export class CommandCenter {
opts.selection = activeTextEditor.selection;
}
const document = await workspace.openTextDocument(uri);
await window.showTextDocument(document, opts);
await commands.executeCommand<void>('vscode.open', uri, opts);
}
}
@@ -447,7 +527,7 @@ export class CommandCenter {
return;
}
const HEAD = this.getLeftResource(resource);
const HEAD = await this.getLeftResource(resource);
if (!HEAD) {
window.showWarningMessage(localize('HEAD not available', "HEAD version of '{0}' is not available.", path.basename(resource.resourceUri.fsPath)));
@@ -494,7 +574,7 @@ export class CommandCenter {
@command('git.stage')
async stage(...resourceStates: SourceControlResourceState[]): Promise<void> {
if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) {
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
const resource = this.getSCMResource();
if (!resource) {
@@ -671,7 +751,7 @@ export class CommandCenter {
@command('git.unstage')
async unstage(...resourceStates: SourceControlResourceState[]): Promise<void> {
if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) {
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
const resource = this.getSCMResource();
if (!resource) {
@@ -737,7 +817,7 @@ export class CommandCenter {
@command('git.clean')
async clean(...resourceStates: SourceControlResourceState[]): Promise<void> {
if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) {
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
const resource = this.getSCMResource();
if (!resource) {
@@ -917,6 +997,7 @@ export class CommandCenter {
}
return await window.showInputBox({
value: opts && opts.defaultMsg,
placeHolder: localize('commit message', "Commit message"),
prompt: localize('provide commit message', "Please provide a commit message"),
ignoreFocusOut: true
@@ -960,7 +1041,15 @@ export class CommandCenter {
@command('git.commitStagedAmend', { repository: true })
async commitStagedAmend(repository: Repository): Promise<void> {
await this.commitWithAnyInput(repository, { all: false, amend: true });
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 });
}
@command('git.commitAll', { repository: true })
@@ -1077,6 +1166,31 @@ export class CommandCenter {
}
}
@command('git.renameBranch', { repository: true })
async renameBranch(repository: Repository): Promise<void> {
const placeHolder = localize('provide branch name', "Please provide a branch name");
const name = await window.showInputBox({ placeHolder });
if (!name || name.trim().length === 0) {
return;
}
try {
await repository.renameBranch(name);
} catch (err) {
switch (err.gitErrorCode) {
case GitErrorCodes.InvalidBranchName:
window.showErrorMessage(localize('invalid branch name', 'Invalid branch name'));
return;
case GitErrorCodes.BranchAlreadyExists:
window.showErrorMessage(localize('branch already exists', "A branch named '{0}' already exists", name));
return;
default:
throw err;
}
}
}
@command('git.merge', { repository: true })
async merge(repository: Repository): Promise<void> {
const config = workspace.getConfiguration('git');
@@ -1134,6 +1248,16 @@ export class CommandCenter {
await repository.tag(name, message);
}
@command('git.fetch', { repository: true })
async fetch(repository: Repository): Promise<void> {
if (repository.remotes.length === 0) {
window.showWarningMessage(localize('no remotes to fetch', "This repository has no remotes configured to fetch from."));
return;
}
await repository.fetch();
}
@command('git.pullFrom', { repository: true })
async pullFrom(repository: Repository): Promise<void> {
const remotes = repository.remotes;
@@ -1240,8 +1364,7 @@ export class CommandCenter {
repository.pushTo(pick.label, branchName);
}
@command('git.sync', { repository: true })
async sync(repository: Repository): Promise<void> {
private async _sync(repository: Repository, rebase: boolean): Promise<void> {
const HEAD = repository.HEAD;
if (!HEAD || !HEAD.upstream) {
@@ -1264,7 +1387,16 @@ export class CommandCenter {
}
}
await repository.sync();
if (rebase) {
await repository.syncRebase();
} else {
await repository.sync();
}
}
@command('git.sync', { repository: true })
sync(repository: Repository): Promise<void> {
return this._sync(repository, false);
}
@command('git._syncAll')
@@ -1280,6 +1412,11 @@ export class CommandCenter {
}));
}
@command('git.syncRebase', { repository: true })
syncRebase(repository: Repository): Promise<void> {
return this._sync(repository, true);
}
@command('git.publish', { repository: true })
async publish(repository: Repository): Promise<void> {
const remotes = repository.remotes;
@@ -1304,14 +1441,9 @@ export class CommandCenter {
await repository.pushTo(choice, branchName, true);
}
@command('git.showOutput')
showOutput(): void {
this.outputChannel.show();
}
@command('git.ignore')
async ignore(...resourceStates: SourceControlResourceState[]): Promise<void> {
if (resourceStates.length === 0 || !(resourceStates[0].resourceUri instanceof Uri)) {
if (resourceStates.length === 0 || (resourceStates[0] && !(resourceStates[0].resourceUri instanceof Uri))) {
const resource = this.getSCMResource();
if (!resource) {
@@ -1332,23 +1464,36 @@ export class CommandCenter {
await this.runByRepository(resources, async (repository, resources) => repository.ignore(resources));
}
@command('git.stash', { repository: true })
async stash(repository: Repository): Promise<void> {
private async _stash(repository: Repository, includeUntracked = false): Promise<void> {
if (repository.workingTreeGroup.resourceStates.length === 0) {
window.showInformationMessage(localize('no changes stash', "There are no changes to stash."));
return;
}
const message = await window.showInputBox({
prompt: localize('provide stash message', "Optionally provide a stash message"),
placeHolder: localize('stash message', "Stash message")
});
const message = await this.getStashMessage();
if (typeof message === 'undefined') {
return;
}
await repository.createStash(message);
await repository.createStash(message, includeUntracked);
}
private async getStashMessage(): Promise<string | undefined> {
return await window.showInputBox({
prompt: localize('provide stash message', "Optionally provide a stash message"),
placeHolder: localize('stash message', "Stash message")
});
}
@command('git.stash', { repository: true })
stash(repository: Repository): Promise<void> {
return this._stash(repository);
}
@command('git.stashIncludeUntracked', { repository: true })
stashIncludeUntracked(repository: Repository): Promise<void> {
return this._stash(repository, true);
}
@command('git.stashPop', { repository: true })
@@ -1384,7 +1529,7 @@ export class CommandCenter {
}
private createCommand(id: string, key: string, method: Function, options: CommandOptions): (...args: any[]) => any {
const result = (...args) => {
const result = (...args: any[]) => {
let result: Promise<any>;
if (!options.repository) {
@@ -1426,14 +1571,14 @@ export class CommandCenter {
message = localize('clean repo', "Please clean your repository working tree before checkout.");
break;
case GitErrorCodes.PushRejected:
message = localize('cant push', "Can't push refs to remote. Run 'Pull' first to integrate your changes.");
message = localize('cant push', "Can't push refs to remote. Try running 'Pull' first to integrate your changes.");
break;
default:
const hint = (err.stderr || err.message || String(err))
.replace(/^error: /mi, '')
.replace(/^> husky.*$/mi, '')
.split(/[\r\n]/)
.filter(line => !!line)
.filter((line: string) => !!line)
[0];
message = hint
@@ -1459,7 +1604,7 @@ export class CommandCenter {
};
// patch this object, so people can call methods directly
this[key] = result;
(this as any)[key] = result;
return result;
}
@@ -1523,4 +1668,4 @@ export class CommandCenter {
dispose(): void {
this.disposables.forEach(d => d.dispose());
}
}
}
+3 -3
View File
@@ -9,7 +9,7 @@ import { workspace, Uri, Disposable, Event, EventEmitter, window } from 'vscode'
import { debounce, throttle } from './decorators';
import { fromGitUri, toGitUri } from './uri';
import { Model, ModelChangeEvent, OriginalResourceChangeEvent } from './model';
import { filterEvent, eventToPromise } from './util';
import { filterEvent, eventToPromise, isDescendant } from './util';
interface CacheRow {
uri: Uri;
@@ -72,7 +72,7 @@ export class GitContentProvider {
const fsPath = uri.fsPath;
for (const root of this.changedRepositoryRoots) {
if (fsPath.startsWith(root)) {
if (isDescendant(root, fsPath)) {
this._onDidChange.fire(uri);
return;
}
@@ -100,7 +100,7 @@ export class GitContentProvider {
if (ref === '~') {
const fileUri = Uri.file(path);
const uriString = fileUri.toString();
const [indexStatus] = repository.indexGroup.resourceStates.filter(r => r.original.toString() === uriString);
const [indexStatus] = repository.indexGroup.resourceStates.filter(r => r.resourceUri.toString() === uriString);
ref = indexStatus ? '' : 'HEAD';
}
+10 -16
View File
@@ -6,7 +6,7 @@
'use strict';
import { window, workspace, Uri, Disposable, Event, EventEmitter, DecorationData, DecorationProvider, ThemeColor } from 'vscode';
import { Repository, GitResourceGroup } from './repository';
import { Repository, GitResourceGroup, Status } from './repository';
import { Model } from './model';
import { debounce } from './decorators';
import { filterEvent } from './util';
@@ -74,34 +74,28 @@ class GitDecorationProvider implements DecorationProvider {
constructor(private repository: Repository) {
this.disposables.push(
window.registerDecorationProvider(this),
repository.onDidRunOperation(this.onDidRunOperation, this)
repository.onDidRunGitStatus(this.onDidRunGitStatus, this)
);
}
private onDidRunOperation(): void {
private onDidRunGitStatus(): void {
let newDecorations = new Map<string, DecorationData>();
this.collectDecorationData(this.repository.indexGroup, newDecorations);
this.collectDecorationData(this.repository.workingTreeGroup, newDecorations);
this.collectDecorationData(this.repository.mergeGroup, newDecorations);
let uris: Uri[] = [];
newDecorations.forEach((value, uriString) => {
if (this.decorations.has(uriString)) {
this.decorations.delete(uriString);
} else {
uris.push(Uri.parse(uriString));
}
});
this.decorations.forEach((value, uriString) => {
uris.push(Uri.parse(uriString));
});
const uris = new Set([...this.decorations.keys()].concat([...newDecorations.keys()]));
this.decorations = newDecorations;
this._onDidChangeDecorations.fire(uris);
this._onDidChangeDecorations.fire([...uris.values()].map(Uri.parse));
}
private collectDecorationData(group: GitResourceGroup, bucket: Map<string, DecorationData>): void {
group.resourceStates.forEach(r => {
if (r.resourceDecoration) {
if (r.resourceDecoration
&& r.type !== Status.DELETED
&& r.type !== Status.INDEX_DELETED
) {
// not deleted and has a decoration
bucket.set(r.original.toString(), r.resourceDecoration);
}
});
+4 -4
View File
@@ -31,7 +31,7 @@ function decorate(decorator: (fn: Function, key: string) => Function): Function
function _memoize(fn: Function, key: string): Function {
const memoizeKey = `$memoize$${key}`;
return function (...args: any[]) {
return function (this: any, ...args: any[]) {
if (!this.hasOwnProperty(memoizeKey)) {
Object.defineProperty(this, memoizeKey, {
configurable: false,
@@ -51,7 +51,7 @@ function _throttle<T>(fn: Function, key: string): Function {
const currentKey = `$throttle$current$${key}`;
const nextKey = `$throttle$next$${key}`;
const trigger = function (...args: any[]) {
const trigger = function (this: any, ...args: any[]) {
if (this[nextKey]) {
return this[nextKey];
}
@@ -81,7 +81,7 @@ export const throttle = decorate(_throttle);
function _sequentialize<T>(fn: Function, key: string): Function {
const currentKey = `__$sequence$${key}`;
return function (...args: any[]) {
return function (this: any, ...args: any[]) {
const currentPromise = this[currentKey] as Promise<any> || Promise.resolve(null);
const run = async () => await fn.apply(this, args);
this[currentKey] = currentPromise.then(run, run);
@@ -95,7 +95,7 @@ export function debounce(delay: number): Function {
return decorate((fn, key) => {
const timerKey = `$debounce$${key}`;
return function (...args: any[]) {
return function (this: any, ...args: any[]) {
clearTimeout(this[timerKey]);
this[timerKey] = setTimeout(() => fn.apply(this, args), delay);
};
+188 -72
View File
@@ -9,9 +9,12 @@ 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 { assign, uniqBy, groupBy, denodeify, IDisposable, toDisposable, dispose, mkdirp } from './util';
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);
@@ -60,8 +63,10 @@ function parseVersion(raw: string): string {
return raw.replace(/^git version /, '');
}
function findSpecificGit(path: string): Promise<IGit> {
function findSpecificGit(path: string, onLookup: (path: string) => void): Promise<IGit> {
return new Promise<IGit>((c, e) => {
onLookup(path);
const buffers: Buffer[] = [];
const child = cp.spawn(path, ['--version']);
child.stdout.on('data', (b: Buffer) => buffers.push(b));
@@ -70,7 +75,7 @@ function findSpecificGit(path: string): Promise<IGit> {
});
}
function findGitDarwin(): Promise<IGit> {
function findGitDarwin(onLookup: (path: string) => void): Promise<IGit> {
return new Promise<IGit>((c, e) => {
cp.exec('which git', (err, gitPathBuffer) => {
if (err) {
@@ -80,8 +85,11 @@ function findGitDarwin(): Promise<IGit> {
const path = gitPathBuffer.toString().replace(/^\s+|\s+$/g, '');
function getVersion(path: string) {
onLookup(path);
// make sure git executes
cp.exec('git --version', (err, stdout) => {
if (err) {
return e('git not found');
}
@@ -109,38 +117,44 @@ function findGitDarwin(): Promise<IGit> {
});
}
function findSystemGitWin32(base: string): Promise<IGit> {
function findSystemGitWin32(base: string, onLookup: (path: string) => void): Promise<IGit> {
if (!base) {
return Promise.reject<IGit>('Not found');
}
return findSpecificGit(path.join(base, 'Git', 'cmd', 'git.exe'));
return findSpecificGit(path.join(base, 'Git', 'cmd', 'git.exe'), onLookup);
}
function findGitWin32(): Promise<IGit> {
return findSystemGitWin32(process.env['ProgramW6432'])
.then(void 0, () => findSystemGitWin32(process.env['ProgramFiles(x86)']))
.then(void 0, () => findSystemGitWin32(process.env['ProgramFiles']))
.then(void 0, () => findSpecificGit('git'));
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));
}
export function findGit(hint: string | undefined): Promise<IGit> {
var first = hint ? findSpecificGit(hint) : Promise.reject<IGit>(null);
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(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> {
const first = hint ? findSpecificGit(hint, onLookup) : Promise.reject<IGit>(null);
return first
.then(void 0, () => {
switch (process.platform) {
case 'darwin': return findGitDarwin();
case 'win32': return findGitWin32();
default: return findSpecificGit('git');
case 'darwin': return findGitDarwin(onLookup);
case 'win32': return findGitWin32(onLookup);
default: return findSpecificGit('git', onLookup);
}
})
.then(null, () => Promise.reject(new Error('Git installation not found.')));
}
export interface IExecutionResult {
export interface IExecutionResult<T extends string | Buffer> {
exitCode: number;
stdout: string;
stdout: T;
stderr: string;
}
@@ -162,50 +176,69 @@ export interface SpawnOptions extends cp.SpawnOptions {
input?: string;
encoding?: string;
log?: boolean;
cancellationToken?: CancellationToken;
}
async function exec(child: cp.ChildProcess, options: SpawnOptions = {}): Promise<IExecutionResult> {
async function exec(child: cp.ChildProcess, cancellationToken?: CancellationToken): Promise<IExecutionResult<Buffer>> {
if (!child.stdout || !child.stderr) {
throw new GitError({
message: 'Failed to get stdout or stderr from git process.'
});
throw new GitError({ message: 'Failed to get stdout or stderr from git process.' });
}
if (cancellationToken && cancellationToken.isCancellationRequested) {
throw new GitError({ message: 'Cancelled' });
}
const disposables: IDisposable[] = [];
const once = (ee: NodeJS.EventEmitter, name: string, fn: Function) => {
const once = (ee: NodeJS.EventEmitter, name: string, fn: (...args: any[]) => void) => {
ee.once(name, fn);
disposables.push(toDisposable(() => ee.removeListener(name, fn)));
};
const on = (ee: NodeJS.EventEmitter, name: string, fn: Function) => {
const on = (ee: NodeJS.EventEmitter, name: string, fn: (...args: any[]) => void) => {
ee.on(name, fn);
disposables.push(toDisposable(() => ee.removeListener(name, fn)));
};
let encoding = options.encoding || 'utf8';
encoding = iconv.encodingExists(encoding) ? encoding : 'utf8';
const [exitCode, stdout, stderr] = await Promise.all<any>([
let result = Promise.all<any>([
new Promise<number>((c, e) => {
once(child, 'error', cpErrorHandler(e));
once(child, 'exit', c);
}),
new Promise<string>(c => {
new Promise<Buffer>(c => {
const buffers: Buffer[] = [];
on(child.stdout, 'data', b => buffers.push(b));
once(child.stdout, 'close', () => c(iconv.decode(Buffer.concat(buffers), encoding)));
on(child.stdout, 'data', (b: Buffer) => buffers.push(b));
once(child.stdout, 'close', () => c(Buffer.concat(buffers)));
}),
new Promise<string>(c => {
const buffers: Buffer[] = [];
on(child.stderr, 'data', b => buffers.push(b));
on(child.stderr, 'data', (b: Buffer) => buffers.push(b));
once(child.stderr, 'close', () => c(Buffer.concat(buffers).toString('utf8')));
})
]);
]) as Promise<[number, Buffer, string]>;
dispose(disposables);
if (cancellationToken) {
const cancellationPromise = new Promise<[number, Buffer, string]>((_, e) => {
onceEvent(cancellationToken.onCancellationRequested)(() => {
try {
child.kill();
} catch (err) {
// noop
}
return { exitCode, stdout, stderr };
e(new GitError({ message: 'Cancelled' }));
});
});
result = Promise.race([result, cancellationPromise]);
}
try {
const [exitCode, stdout, stderr] = await result;
return { exitCode, stdout, stderr };
} finally {
dispose(disposables);
}
}
export interface IGitErrorData {
@@ -288,6 +321,8 @@ export const GitErrorCodes = {
RepositoryIsLocked: 'RepositoryIsLocked',
BranchNotFullyMerged: 'BranchNotFullyMerged',
NoRemoteReference: 'NoRemoteReference',
InvalidBranchName: 'InvalidBranchName',
BranchAlreadyExists: 'BranchAlreadyExists',
NoLocalChanges: 'NoLocalChanges',
NoStashFound: 'NoStashFound',
LocalChangesOverwritten: 'LocalChangesOverwritten'
@@ -312,6 +347,10 @@ function getGitErrorCode(stderr: string): string | undefined {
return GitErrorCodes.BranchNotFullyMerged;
} else if (/Couldn\'t find remote ref/.test(stderr)) {
return GitErrorCodes.NoRemoteReference;
} else if (/A branch named '.+' already exists/.test(stderr)) {
return GitErrorCodes.BranchAlreadyExists;
} else if (/'.+' is not a valid branch name/.test(stderr)) {
return GitErrorCodes.InvalidBranchName;
}
return void 0;
@@ -341,12 +380,12 @@ export class Git {
return;
}
async clone(url: string, parentPath: string): Promise<string> {
async clone(url: string, parentPath: string, cancellationToken?: CancellationToken): Promise<string> {
const folderName = decodeURI(url).replace(/^.*\//, '').replace(/\.git$/, '') || 'repository';
const folderPath = path.join(parentPath, folderName);
await mkdirp(parentPath);
await this.exec(parentPath, ['clone', url, folderPath]);
await this.exec(parentPath, ['clone', url, folderPath], { cancellationToken });
return folderPath;
}
@@ -355,7 +394,7 @@ export class Git {
return path.normalize(result.stdout.trim());
}
async exec(cwd: string, args: string[], options: SpawnOptions = {}): Promise<IExecutionResult> {
async exec(cwd: string, args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> {
options = assign({ cwd }, options || {});
return await this._exec(args, options);
}
@@ -365,21 +404,30 @@ export class Git {
return this.spawn(args, options);
}
private async _exec(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult> {
private async _exec(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> {
const child = this.spawn(args, options);
if (options.input) {
child.stdin.end(options.input, 'utf8');
}
const result = await exec(child, options);
const bufferResult = await exec(child, options.cancellationToken);
if (options.log !== false && result.stderr.length > 0) {
this.log(`${result.stderr}\n`);
if (options.log !== false && bufferResult.stderr.length > 0) {
this.log(`${bufferResult.stderr}\n`);
}
if (result.exitCode) {
return Promise.reject<IExecutionResult>(new GitError({
let encoding = options.encoding || 'utf8';
encoding = iconv.encodingExists(encoding) ? encoding : 'utf8';
const result: IExecutionResult<string> = {
exitCode: bufferResult.exitCode,
stdout: iconv.decode(bufferResult.stdout, encoding),
stderr: bufferResult.stderr
};
if (bufferResult.exitCode) {
return Promise.reject<IExecutionResult<string>>(new GitError({
message: 'Failed to execute git',
stdout: result.stdout,
stderr: result.stderr,
@@ -510,7 +558,7 @@ export class Repository {
}
// TODO@Joao: rename to exec
async run(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult> {
async run(args: string[], options: SpawnOptions = {}): Promise<IExecutionResult<string>> {
return await this.git.exec(this.repositoryRoot, args, options);
}
@@ -539,39 +587,97 @@ export class Repository {
return result.stdout;
}
async buffer(object: string, encoding: string = 'utf8'): Promise<string> {
async bufferString(object: string, encoding: string = 'utf8'): Promise<string> {
const stdout = await this.buffer(object);
return iconv.decode(stdout, iconv.encodingExists(encoding) ? encoding : 'utf8');
}
async buffer(object: string): Promise<Buffer> {
const child = this.stream(['show', object]);
if (!child.stdout) {
return Promise.reject<string>('Can\'t open file from git');
return Promise.reject<Buffer>('Can\'t open file from git');
}
const { exitCode, stdout } = await exec(child, { encoding });
const { exitCode, stdout } = await exec(child);
if (exitCode) {
return Promise.reject<string>(new GitError({
return Promise.reject<Buffer>(new GitError({
message: 'Could not show object.',
exitCode
}));
}
return stdout;
}
// TODO@joao
// return new Promise((c, e) => {
// detectMimesFromStream(child.stdout, null, (err, result) => {
// if (err) {
// e(err);
// } else if (isBinaryMime(result.mimes)) {
// e(<IFileOperationResult>{
// message: localize('fileBinaryError', "File seems to be binary and cannot be opened as text"),
// fileOperationResult: FileOperationResult.FILE_IS_BINARY
// });
// } else {
// c(this.doBuffer(object));
// }
// });
// });
async lstree(treeish: string, path: string): Promise<{ mode: number, object: string, size: number }> {
if (!treeish) { // index
const { stdout } = await this.run(['ls-files', '--stage', '--', path]);
const match = /^(\d+)\s+([0-9a-f]{40})\s+(\d+)/.exec(stdout);
if (!match) {
throw new GitError({ message: 'Error running ls-files' });
}
const [, mode, object] = match;
const catFile = await this.run(['cat-file', '-s', object]);
const size = parseInt(catFile.stdout);
return { mode: parseInt(mode), object, size };
}
const { stdout } = await this.run(['ls-tree', '-l', treeish, '--', path]);
const match = /^(\d+)\s+(\w+)\s+([0-9a-f]{40})\s+(\d+)/.exec(stdout);
if (!match) {
throw new GitError({ message: 'Error running ls-tree' });
}
const [, mode, , object, size] = match;
return { mode: parseInt(mode), object, size: parseInt(size) };
}
async detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }> {
const child = await this.stream(['show', object]);
const buffer = await readBytes(child.stdout, 4100);
try {
child.kill();
} catch (err) {
// noop
}
const encoding = detectUnicodeEncoding(buffer);
let isText = true;
if (encoding !== Encoding.UTF16be && encoding !== Encoding.UTF16le) {
for (let i = 0; i < buffer.length; i++) {
if (buffer.readInt8(i) === 0) {
isText = false;
break;
}
}
}
if (!isText) {
const result = filetype(buffer);
if (!result) {
return { mimetype: 'application/octet-stream' };
} else {
return { mimetype: result.mime };
}
}
if (encoding) {
return { mimetype: 'text/plain', encoding };
} else {
// TODO@JOAO: read the setting OUTSIDE!
return { mimetype: 'text/plain' };
}
}
async add(paths: string[]): Promise<void> {
@@ -591,6 +697,7 @@ export class Repository {
child.stdin.end(data, 'utf8');
const { exitCode, stdout } = await exec(child);
const hash = stdout.toString('utf8');
if (exitCode) {
throw new GitError({
@@ -599,7 +706,7 @@ export class Repository {
});
}
await this.run(['update-index', '--cacheinfo', '100644', stdout, path]);
await this.run(['update-index', '--cacheinfo', '100644', hash, path]);
}
async checkout(treeish: string, paths: string[]): Promise<void> {
@@ -680,6 +787,11 @@ export class Repository {
await this.run(args);
}
async renameBranch(name: string): Promise<void> {
const args = ['branch', '-m', name];
await this.run(args);
}
async merge(ref: string): Promise<void> {
const args = ['merge', ref];
@@ -847,10 +959,14 @@ export class Repository {
}
}
async createStash(message?: string): Promise<void> {
async createStash(message?: string, includeUntracked?: boolean): Promise<void> {
try {
const args = ['stash', 'save'];
if (includeUntracked) {
args.push('-u');
}
if (message) {
args.push('--', message);
}
@@ -869,7 +985,7 @@ export class Repository {
try {
const args = ['stash', 'pop'];
if (typeof index === 'string') {
if (typeof index === 'number') {
args.push(`stash@{${index}}`);
}
@@ -891,7 +1007,7 @@ export class Repository {
const env = { GIT_OPTIONAL_LOCKS: '0' };
const child = this.stream(['status', '-z', '-u'], { env });
const onExit = exitCode => {
const onExit = (exitCode: number) => {
if (exitCode !== 0) {
const stderr = stderrData.join('');
return e(new GitError({
@@ -909,12 +1025,12 @@ export class Repository {
const onStdoutData = (raw: string) => {
parser.update(raw);
if (parser.status.length > 5000) {
if (parser.status.length > limit) {
child.removeListener('exit', onExit);
child.stdout.removeListener('data', onStdoutData);
child.kill();
c({ status: parser.status.slice(0, 5000), didHitLimit: true });
c({ status: parser.status.slice(0, limit), didHitLimit: true });
}
};
@@ -953,7 +1069,7 @@ export class Repository {
async getRefs(): Promise<Ref[]> {
const result = await this.run(['for-each-ref', '--format', '%(refname) %(objectname)']);
const fn = (line): Ref | null => {
const fn = (line: string): Ref | null => {
let match: RegExpExecArray | null;
if (match = /^refs\/heads\/([^ ]+) ([0-9a-f]{40})$/.exec(line)) {
@@ -978,7 +1094,7 @@ export class Repository {
const regex = /^stash@{(\d+)}:(.+)$/;
const rawStashes = result.stdout.trim().split('\n')
.filter(b => !!b)
.map(line => regex.exec(line))
.map(line => regex.exec(line) as RegExpExecArray)
.filter(g => !!g)
.map(([, index, description]: RegExpExecArray) => ({ index: parseInt(index), description }));
@@ -990,7 +1106,7 @@ export class Repository {
const regex = /^([^\s]+)\s+([^\s]+)\s/;
const rawRemotes = result.stdout.trim().split('\n')
.filter(b => !!b)
.map(line => regex.exec(line))
.map(line => regex.exec(line) as RegExpExecArray)
.filter(g => !!g)
.map((groups: RegExpExecArray) => ({ name: groups[1], url: groups[2] }));
+54 -19
View File
@@ -7,7 +7,7 @@
import * as nls from 'vscode-nls';
const localize = nls.config(process.env.VSCODE_NLS_CONFIG)();
import { ExtensionContext, workspace, window, Disposable, commands, Uri } from 'vscode';
import { ExtensionContext, workspace, window, Disposable, commands, Uri, OutputChannel } from 'vscode';
import { findGit, Git, IGit } from './git';
import { Model } from './model';
import { CommandCenter } from './commands';
@@ -16,23 +16,19 @@ import { GitDecorations } from './decorationProvider';
import { Askpass } from './askpass';
import { toDisposable } from './util';
import TelemetryReporter from 'vscode-extension-telemetry';
import { API, createApi } from './api';
async function init(context: ExtensionContext, disposables: Disposable[]): Promise<void> {
async function init(context: ExtensionContext, outputChannel: OutputChannel, disposables: Disposable[]): Promise<Model> {
const { name, version, aiKey } = require(context.asAbsolutePath('./package.json')) as { name: string, version: string, aiKey: string };
const telemetryReporter: TelemetryReporter = new TelemetryReporter(name, version, aiKey);
disposables.push(telemetryReporter);
const outputChannel = window.createOutputChannel('Git');
disposables.push(outputChannel);
const config = workspace.getConfiguration('git');
const enabled = config.get<boolean>('enabled') === true;
const pathHint = workspace.getConfiguration('git').get<string>('path');
const info = await findGit(pathHint);
const info = await findGit(pathHint, path => outputChannel.appendLine(localize('looking', "Looking for git in: {0}", path)));
const askpass = new Askpass();
const env = await askpass.getEnv();
const git = new Git({ gitPath: info.path, version: info.version, env });
const model = new Model(git);
const model = new Model(git, context.globalState);
disposables.push(model);
const onRepository = () => commands.executeCommand('setContext', 'gitOpenRepositoryCount', `${model.repositories.length}`);
@@ -40,15 +36,9 @@ async function init(context: ExtensionContext, disposables: Disposable[]): Promi
model.onDidCloseRepository(onRepository, null, disposables);
onRepository();
if (!enabled) {
const commandCenter = new CommandCenter(git, model, outputChannel, telemetryReporter);
disposables.push(commandCenter);
return;
}
outputChannel.appendLine(localize('using git', "Using git {0} from {1}", info.version, info.path));
const onOutput = str => outputChannel.append(str);
const onOutput = (str: string) => outputChannel.append(str);
git.onOutput.addListener('log', onOutput);
disposables.push(toDisposable(() => git.onOutput.removeListener('log', onOutput)));
@@ -59,14 +49,58 @@ async function init(context: ExtensionContext, disposables: Disposable[]): Promi
);
await checkGitVersion(info);
return model;
}
export function activate(context: ExtensionContext): any {
async function _activate(context: ExtensionContext, disposables: Disposable[]): Promise<Model | undefined> {
const outputChannel = window.createOutputChannel('Git');
commands.registerCommand('git.showOutput', () => outputChannel.show());
disposables.push(outputChannel);
try {
return await init(context, outputChannel, disposables);
} catch (err) {
if (!/Git installation not found/.test(err.message || '')) {
throw err;
}
const config = workspace.getConfiguration('git');
const shouldIgnore = config.get<boolean>('ignoreMissingGitWarning') === true;
if (shouldIgnore) {
return;
}
console.warn(err.message);
outputChannel.appendLine(err.message);
outputChannel.show();
const download = localize('downloadgit', "Download Git");
const neverShowAgain = localize('neverShowAgain', "Don't show again");
const choice = await window.showWarningMessage(
localize('notfound', "Git not found. Install it or configure it using the 'git.path' setting."),
download,
neverShowAgain
);
if (choice === download) {
commands.executeCommand('vscode.open', Uri.parse('https://git-scm.com/'));
} else if (choice === neverShowAgain) {
await config.update('ignoreMissingGitWarning', true, true);
}
}
}
export function activate(context: ExtensionContext): API {
const disposables: Disposable[] = [];
context.subscriptions.push(new Disposable(() => Disposable.from(...disposables).dispose()));
init(context, disposables)
.catch(err => console.error(err));
const activatePromise = _activate(context, disposables);
const modelPromise = activatePromise.then(model => model || Promise.reject<Model>('Git model not found'));
activatePromise.catch(err => console.error(err));
return createApi(modelPromise);
}
async function checkGitVersion(info: IGit): Promise<void> {
@@ -102,5 +136,6 @@ async function checkGitVersion(info: IGit): Promise<void> {
} else if (choice === neverShowAgain) {
await config.update('ignoreLegacyWarning', true, true);
}
// {{SQL CARBON EDIT}}
*/
}
+43 -52
View File
@@ -5,14 +5,15 @@
'use strict';
import { workspace, WorkspaceFoldersChangeEvent, Uri, window, Event, EventEmitter, QuickPickItem, Disposable, SourceControl, SourceControlResourceGroup, TextEditor } from 'vscode';
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 } from './util';
import { dispose, anyEvent, filterEvent, IDisposable, isDescendant } 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();
@@ -44,10 +45,6 @@ interface OpenRepository extends Disposable {
repository: Repository;
}
function isParent(parent: string, child: string): boolean {
return child.startsWith(parent);
}
export class Model {
private _onDidOpenRepository = new EventEmitter<Repository>();
@@ -67,45 +64,17 @@ export class Model {
private possibleGitRepositoryPaths = new Set<string>();
private enabled = false;
private configurationChangeDisposable: Disposable;
private disposables: Disposable[] = [];
constructor(private git: Git) {
const config = workspace.getConfiguration('git');
this.enabled = config.get<boolean>('enabled') === true;
this.configurationChangeDisposable = workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this);
if (this.enabled) {
this.enable();
}
}
private onDidChangeConfiguration(): void {
const config = workspace.getConfiguration('git');
const enabled = config.get<boolean>('enabled') === true;
if (enabled === this.enabled) {
return;
}
this.enabled = enabled;
if (enabled) {
this.enable();
} else {
this.disable();
}
}
private enable(): void {
constructor(private git: Git, private globalState: Memento) {
workspace.onDidChangeWorkspaceFolders(this.onDidChangeWorkspaceFolders, this, this.disposables);
this.onDidChangeWorkspaceFolders({ added: workspace.workspaceFolders || [], removed: [] });
window.onDidChangeVisibleTextEditors(this.onDidChangeVisibleTextEditors, this, this.disposables);
this.onDidChangeVisibleTextEditors(window.visibleTextEditors);
workspace.onDidChangeConfiguration(this.onDidChangeConfiguration, this, this.disposables);
const fsWatcher = workspace.createFileSystemWatcher('**');
this.disposables.push(fsWatcher);
@@ -117,15 +86,6 @@ export class Model {
this.scanWorkspaceFolders();
}
private disable(): void {
const openRepositories = [...this.openRepositories];
openRepositories.forEach(r => r.dispose());
this.openRepositories = [];
this.possibleGitRepositoryPaths.clear();
this.disposables = dispose(this.disposables);
}
/**
* Scans the first level of each workspace folder, looking
* for git repositories.
@@ -169,7 +129,21 @@ export class Model {
.map(folder => this.getOpenRepository(folder.uri))
.filter(r => !!r)
.filter(r => !activeRepositories.has(r!.repository))
.filter(r => !(workspace.workspaceFolders || []).some(f => isParent(f.uri.fsPath, r!.repository.root))) as OpenRepository[];
.filter(r => !(workspace.workspaceFolders || []).some(f => isDescendant(f.uri.fsPath, r!.repository.root))) as OpenRepository[];
possibleRepositoryFolders.forEach(p => this.tryOpenRepository(p.uri.fsPath));
openRepositoriesToDispose.forEach(r => r.dispose());
}
private onDidChangeConfiguration(): void {
const possibleRepositoryFolders = (workspace.workspaceFolders || [])
.filter(folder => workspace.getConfiguration('git', folder.uri).get<boolean>('enabled') === true)
.filter(folder => !this.getOpenRepository(folder.uri));
const openRepositoriesToDispose = this.openRepositories
.map(repository => ({ repository, root: Uri.file(repository.repository.root) }))
.filter(({ root }) => workspace.getConfiguration('git', root).get<boolean>('enabled') !== true)
.map(({ repository }) => repository);
possibleRepositoryFolders.forEach(p => this.tryOpenRepository(p.uri.fsPath));
openRepositoriesToDispose.forEach(r => r.dispose());
@@ -199,6 +173,13 @@ export class Model {
return;
}
const config = workspace.getConfiguration('git', Uri.file(path));
const enabled = config.get<boolean>('enabled') === true;
if (!enabled) {
return;
}
try {
const repositoryRoot = await this.git.getRepositoryRoot(path);
@@ -209,7 +190,7 @@ export class Model {
return;
}
const repository = new Repository(this.git.open(repositoryRoot));
const repository = new Repository(this.git.open(repositoryRoot), this.globalState);
this.open(repository);
} catch (err) {
@@ -292,12 +273,18 @@ export class Model {
}
if (hint instanceof Uri) {
const resourcePath = hint.fsPath;
let resourcePath: string;
if (hint.scheme === 'git') {
resourcePath = fromGitUri(hint).path;
} else {
resourcePath = hint.fsPath;
}
for (const liveRepository of this.openRepositories) {
const relativePath = path.relative(liveRepository.repository.root, resourcePath);
if (!/^\.\./.test(relativePath)) {
if (isDescendant(liveRepository.repository.root, resourcePath)) {
return liveRepository;
}
}
@@ -321,7 +308,11 @@ export class Model {
}
dispose(): void {
this.disable();
this.configurationChangeDisposable.dispose();
const openRepositories = [...this.openRepositories];
openRepositories.forEach(r => r.dispose());
this.openRepositories = [];
this.possibleGitRepositoryPaths.clear();
this.disposables = dispose(this.disposables);
}
}
+90 -39
View File
@@ -5,9 +5,9 @@
'use strict';
import { Uri, Command, EventEmitter, Event, scm, SourceControl, SourceControlInputBox, SourceControlResourceGroup, SourceControlResourceState, SourceControlResourceDecorations, Disposable, ProgressLocation, window, workspace, WorkspaceEdit, ThemeColor, DecorationData } from 'vscode';
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 } from './util';
import { anyEvent, filterEvent, eventToPromise, dispose, find, isDescendant } from './util';
import { memoize, throttle, debounce } from './decorators';
import { toGitUri } from './uri';
import { AutoFetcher } from './autofetch';
@@ -82,7 +82,7 @@ export class Resource implements SourceControlResourceState {
get original(): Uri { return this._resourceUri; }
get renameResourceUri(): Uri | undefined { return this._renameResourceUri; }
private static Icons = {
private static Icons: any = {
light: {
Modified: getIconUri('status-modified', 'light'),
Added: getIconUri('status-added', 'light'),
@@ -171,10 +171,8 @@ export class Resource implements SourceControlResourceState {
}
get decorations(): SourceControlResourceDecorations {
// TODO@joh, still requires restart/redraw in the SCM viewlet
const decorations = workspace.getConfiguration().get<boolean>('git.decorations.enabled');
const light = !decorations ? { iconPath: this.getIconPath('light') } : undefined;
const dark = !decorations ? { iconPath: this.getIconPath('dark') } : undefined;
const light = this._useIcons ? { iconPath: this.getIconPath('light') } : undefined;
const dark = this._useIcons ? { iconPath: this.getIconPath('dark') } : undefined;
const tooltip = this.tooltip;
const strikeThrough = this.strikeThrough;
const faded = this.faded;
@@ -275,6 +273,7 @@ export class Resource implements SourceControlResourceState {
private _resourceGroupType: ResourceGroupType,
private _resourceUri: Uri,
private _type: Status,
private _useIcons: boolean,
private _renameResourceUri?: Uri
) { }
}
@@ -296,11 +295,13 @@ export enum Operation {
Stage = 'Stage',
GetCommitTemplate = 'GetCommitTemplate',
DeleteBranch = 'DeleteBranch',
RenameBranch = 'RenameBranch',
Merge = 'Merge',
Ignore = 'Ignore',
Tag = 'Tag',
Stash = 'Stash',
CheckIgnore = 'CheckIgnore'
CheckIgnore = 'CheckIgnore',
LSTree = 'LSTree'
}
function isReadOnly(operation: Operation): boolean {
@@ -308,6 +309,7 @@ function isReadOnly(operation: Operation): boolean {
case Operation.Show:
case Operation.GetCommitTemplate:
case Operation.CheckIgnore:
case Operation.LSTree:
return true;
default:
return false;
@@ -318,6 +320,8 @@ function shouldShowProgress(operation: Operation): boolean {
switch (operation) {
case Operation.Fetch:
case Operation.CheckIgnore:
case Operation.LSTree:
case Operation.Show:
return false;
default:
return true;
@@ -369,12 +373,18 @@ export interface CommitOptions {
amend?: boolean;
signoff?: boolean;
signCommit?: boolean;
defaultMsg?: string;
}
export interface GitResourceGroup extends SourceControlResourceGroup {
resourceStates: Resource[];
}
export interface OperationResult {
operation: Operation;
error: any;
}
export class Repository implements Disposable {
private _onDidChangeRepository = new EventEmitter<Uri>();
@@ -384,7 +394,7 @@ export class Repository implements Disposable {
readonly onDidChangeState: Event<RepositoryState> = this._onDidChangeState.event;
private _onDidChangeStatus = new EventEmitter<void>();
readonly onDidChangeStatus: Event<void> = this._onDidChangeStatus.event;
readonly onDidRunGitStatus: Event<void> = this._onDidChangeStatus.event;
private _onDidChangeOriginalResource = new EventEmitter<Uri>();
readonly onDidChangeOriginalResource: Event<Uri> = this._onDidChangeOriginalResource.event;
@@ -392,8 +402,8 @@ export class Repository implements Disposable {
private _onRunOperation = new EventEmitter<Operation>();
readonly onRunOperation: Event<Operation> = this._onRunOperation.event;
private _onDidRunOperation = new EventEmitter<Operation>();
readonly onDidRunOperation: Event<Operation> = this._onDidRunOperation.event;
private _onDidRunOperation = new EventEmitter<OperationResult>();
readonly onDidRunOperation: Event<OperationResult> = this._onDidRunOperation.event;
@memoize
get onDidChangeOperations(): Event<void> {
@@ -456,13 +466,14 @@ export class Repository implements Disposable {
private disposables: Disposable[] = [];
constructor(
private readonly repository: BaseRepository
private readonly repository: BaseRepository,
globalState: Memento
) {
const fsWatcher = workspace.createFileSystemWatcher('**');
this.disposables.push(fsWatcher);
const onWorkspaceChange = anyEvent(fsWatcher.onDidChange, fsWatcher.onDidCreate, fsWatcher.onDidDelete);
const onRepositoryChange = filterEvent(onWorkspaceChange, uri => !/^\.\./.test(path.relative(repository.root, uri.fsPath)));
const onRepositoryChange = filterEvent(onWorkspaceChange, uri => isDescendant(repository.root, uri.fsPath));
const onRelevantRepositoryChange = filterEvent(onRepositoryChange, uri => !/\/\.git\/index\.lock$/.test(uri.path));
onRelevantRepositoryChange(this.onFSChange, this, this.disposables);
@@ -470,6 +481,7 @@ export class Repository implements Disposable {
onRelevantGitChange(this._onDidChangeRepository.fire, this._onDidChangeRepository, this.disposables);
this._sourceControl = scm.createSourceControl('git', 'Git', Uri.file(repository.root));
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.disposables.push(this._sourceControl);
@@ -485,7 +497,7 @@ export class Repository implements Disposable {
this.disposables.push(this.indexGroup);
this.disposables.push(this.workingTreeGroup);
this.disposables.push(new AutoFetcher(this));
this.disposables.push(new AutoFetcher(this, globalState));
const statusBar = new StatusBarCommands(this);
this.disposables.push(statusBar);
@@ -598,6 +610,10 @@ export class Repository implements Disposable {
await this.run(Operation.DeleteBranch, () => this.repository.deleteBranch(name, force));
}
async renameBranch(name: string): Promise<void> {
await this.run(Operation.RenameBranch, () => this.repository.renameBranch(name));
}
async merge(ref: string): Promise<void> {
await this.run(Operation.Merge, () => this.repository.merge(ref));
}
@@ -650,10 +666,9 @@ export class Repository implements Disposable {
await this.run(Operation.Push, () => this.repository.push(remote, undefined, false, true));
}
@throttle
async sync(): Promise<void> {
private async _sync(rebase: boolean): Promise<void> {
await this.run(Operation.Sync, async () => {
await this.repository.pull();
await this.repository.pull(rebase);
const shouldPush = this.HEAD && typeof this.HEAD.ahead === 'number' ? this.HEAD.ahead > 0 : true;
@@ -663,22 +678,52 @@ export class Repository implements Disposable {
});
}
@throttle
sync(): Promise<void> {
return this._sync(false);
}
@throttle
async syncRebase(): Promise<void> {
return this._sync(true);
}
async show(ref: string, filePath: string): Promise<string> {
return await this.run(Operation.Show, async () => {
const relativePath = path.relative(this.repository.root, filePath).replace(/\\/g, '/');
const configFiles = workspace.getConfiguration('files', Uri.file(filePath));
const encoding = configFiles.get<string>('encoding');
return await this.repository.buffer(`${ref}:${relativePath}`, encoding);
// TODO@joao: Resource config api
return await this.repository.bufferString(`${ref}:${relativePath}`, encoding);
});
}
async buffer(ref: string, filePath: string): Promise<Buffer> {
return await this.run(Operation.Show, async () => {
const relativePath = path.relative(this.repository.root, filePath).replace(/\\/g, '/');
const configFiles = workspace.getConfiguration('files', Uri.file(filePath));
const encoding = configFiles.get<string>('encoding');
// TODO@joao: REsource config api
return await this.repository.buffer(`${ref}:${relativePath}`);
});
}
lstree(ref: string, filePath: string): Promise<{ mode: number, object: string, size: number }> {
return this.run(Operation.LSTree, () => this.repository.lstree(ref, filePath));
}
detectObjectType(object: string): Promise<{ mimetype: string, encoding?: string }> {
return this.run(Operation.Show, () => this.repository.detectObjectType(object));
}
async getStashes(): Promise<Stash[]> {
return await this.repository.getStashes();
}
async createStash(message?: string): Promise<void> {
return await this.run(Operation.Stash, () => this.repository.createStash(message));
async createStash(message?: string, includeUntracked?: boolean): Promise<void> {
return await this.run(Operation.Stash, () => this.repository.createStash(message, includeUntracked));
}
async popStash(index?: number): Promise<void> {
@@ -715,7 +760,8 @@ export class Repository implements Disposable {
return this.run(Operation.CheckIgnore, () => {
return new Promise<Set<string>>((resolve, reject) => {
filePaths = filePaths.filter(filePath => !path.relative(this.root, filePath).startsWith('..'));
filePaths = filePaths
.filter(filePath => isDescendant(this.root, filePath));
if (filePaths.length === 0) {
// nothing left
@@ -726,7 +772,7 @@ export class Repository implements Disposable {
const child = this.repository.stream(['check-ignore', '-z', '--stdin'], { stdio: [null, null, null] });
child.stdin.end(filePaths.join('\0'), 'utf8');
const onExit = exitCode => {
const onExit = (exitCode: number) => {
if (exitCode === 1) {
// nothing ignored
resolve(new Set<string>());
@@ -762,6 +808,8 @@ export class Repository implements Disposable {
}
const run = async () => {
let error: any = null;
this._operations.start(operation);
this._onRunOperation.fire(operation);
@@ -774,6 +822,8 @@ export class Repository implements Disposable {
return result;
} catch (err) {
error = err;
if (err.gitErrorCode === GitErrorCodes.NotAGitRepository) {
this.state = RepositoryState.Disposed;
}
@@ -781,7 +831,7 @@ export class Repository implements Disposable {
throw err;
} finally {
this._operations.end(operation);
this._onDidRunOperation.fire(operation);
this._onDidRunOperation.fire({ operation, error });
}
};
@@ -813,6 +863,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);
this.isRepositoryHuge = didHitLimit;
@@ -860,30 +911,30 @@ export class Repository implements Disposable {
const renameUri = raw.rename ? Uri.file(path.join(this.repository.root, raw.rename)) : undefined;
switch (raw.x + raw.y) {
case '??': return workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.UNTRACKED));
case '!!': return workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.IGNORED));
case 'DD': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.BOTH_DELETED));
case 'AU': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.ADDED_BY_US));
case 'UD': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.DELETED_BY_THEM));
case 'UA': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.ADDED_BY_THEM));
case 'DU': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.DELETED_BY_US));
case 'AA': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.BOTH_ADDED));
case 'UU': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.BOTH_MODIFIED));
case '??': return workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.UNTRACKED, useIcons));
case '!!': return workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.IGNORED, useIcons));
case 'DD': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.BOTH_DELETED, useIcons));
case 'AU': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.ADDED_BY_US, useIcons));
case 'UD': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.DELETED_BY_THEM, useIcons));
case 'UA': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.ADDED_BY_THEM, useIcons));
case 'DU': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.DELETED_BY_US, useIcons));
case 'AA': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.BOTH_ADDED, useIcons));
case 'UU': return merge.push(new Resource(ResourceGroupType.Merge, uri, Status.BOTH_MODIFIED, useIcons));
}
let isModifiedInIndex = false;
switch (raw.x) {
case 'M': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_MODIFIED)); isModifiedInIndex = true; break;
case 'A': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_ADDED)); break;
case 'D': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_DELETED)); break;
case 'R': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_RENAMED, renameUri)); break;
case 'C': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_COPIED, renameUri)); break;
case 'M': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_MODIFIED, useIcons)); isModifiedInIndex = true; break;
case 'A': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_ADDED, useIcons)); break;
case 'D': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_DELETED, useIcons)); break;
case 'R': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_RENAMED, useIcons, renameUri)); break;
case 'C': index.push(new Resource(ResourceGroupType.Index, uri, Status.INDEX_COPIED, useIcons, renameUri)); break;
}
switch (raw.y) {
case 'M': workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.MODIFIED, renameUri)); break;
case 'D': workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.DELETED, renameUri)); break;
case 'M': workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.MODIFIED, useIcons, renameUri)); break;
case 'D': workingTree.push(new Resource(ResourceGroupType.WorkingTree, uri, Status.DELETED, useIcons, renameUri)); break;
}
});
+2 -2
View File
@@ -20,7 +20,7 @@ class CheckoutStatusBar {
private disposables: Disposable[] = [];
constructor(private repository: Repository) {
repository.onDidChangeStatus(this._onDidChange.fire, this._onDidChange, this.disposables);
repository.onDidRunGitStatus(this._onDidChange.fire, this._onDidChange, this.disposables);
}
get command(): Command | undefined {
@@ -65,7 +65,7 @@ class SyncStatusBar {
}
constructor(private repository: Repository) {
repository.onDidChangeStatus(this.onModelChange, this, this.disposables);
repository.onDidRunGitStatus(this.onModelChange, this, this.disposables);
repository.onDidChangeOperations(this.onOperationsChange, this, this.disposables);
this._onDidChange.fire();
}
+1
View File
@@ -5,6 +5,7 @@
'use strict';
import 'mocha';
import { GitStatusParser } from '../git';
import * as assert from 'assert';
+1 -3
View File
@@ -4,6 +4,4 @@
*--------------------------------------------------------------------------------------------*/
/// <reference path='../../../../src/vs/vscode.d.ts'/>
/// <reference path='../../../../src/vs/vscode.proposed.d.ts'/>
/// <reference types='@types/node'/>
/// <reference types='@types/mocha'/>
/// <reference path='../../../../src/vs/vscode.proposed.d.ts'/>
+87 -7
View File
@@ -6,7 +6,8 @@
'use strict';
import { Event } from 'vscode';
import { dirname } from 'path';
import { dirname, sep } from 'path';
import { Readable } from 'stream';
import * as fs from 'fs';
import * as byline from 'byline';
@@ -86,7 +87,7 @@ export function once(fn: (...args: any[]) => any): (...args: any[]) => any {
export function assign<T>(destination: T, ...sources: any[]): T {
for (const source of sources) {
Object.keys(source).forEach(key => destination[key] = source[key]);
Object.keys(source).forEach(key => (destination as any)[key] = source[key]);
}
return destination;
@@ -115,12 +116,12 @@ export function groupBy<T>(arr: T[], fn: (el: T) => string): { [key: string]: T[
}, Object.create(null));
}
export function denodeify<R>(fn: Function): (...args) => Promise<R> {
return (...args) => new Promise<R>((c, e) => fn(...args, (err, r) => err ? e(err) : c(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)));
}
export function nfcall<R>(fn: Function, ...args): Promise<R> {
return new Promise<R>((c, e) => fn(...args, (err, r) => err ? e(err) : c(r)));
export function nfcall<R>(fn: Function, ...args: any[]): Promise<R> {
return new Promise<R>((c, e) => fn(...args, (err: any, r: any) => err ? e(err) : c(r)));
}
export async function mkdirp(path: string, mode?: number): Promise<boolean> {
@@ -205,4 +206,83 @@ export async function grep(filename: string, pattern: RegExp): Promise<boolean>
stream.on('error', e);
stream.on('end', () => c(false));
});
}
}
export function readBytes(stream: Readable, bytes: number): Promise<Buffer> {
return new Promise<Buffer>((complete, error) => {
let done = false;
let buffer = new Buffer(bytes);
let bytesRead = 0;
stream.on('data', (data: Buffer) => {
let bytesToRead = Math.min(bytes - bytesRead, data.length);
data.copy(buffer, bytesRead, 0, bytesToRead);
bytesRead += bytesToRead;
if (bytesRead === bytes) {
(stream as any).destroy(); // Will trigger the close event eventually
}
});
stream.on('error', (e: Error) => {
if (!done) {
done = true;
error(e);
}
});
stream.on('close', () => {
if (!done) {
done = true;
complete(buffer.slice(0, bytesRead));
}
});
});
}
export enum Encoding {
UTF8 = 'utf8',
UTF16be = 'utf16be',
UTF16le = 'utf16le'
}
export function detectUnicodeEncoding(buffer: Buffer): Encoding | null {
if (buffer.length < 2) {
return null;
}
const b0 = buffer.readUInt8(0);
const b1 = buffer.readUInt8(1);
if (b0 === 0xFE && b1 === 0xFF) {
return Encoding.UTF16be;
}
if (b0 === 0xFF && b1 === 0xFE) {
return Encoding.UTF16le;
}
if (buffer.length < 3) {
return null;
}
const b2 = buffer.readUInt8(2);
if (b0 === 0xEF && b1 === 0xBB && b2 === 0xBF) {
return Encoding.UTF8;
}
return null;
}
export function isDescendant(parent: string, descendant: string): boolean {
if (parent === descendant) {
return true;
}
if (parent.charAt(parent.length - 1) !== sep) {
parent += sep;
}
return descendant.startsWith(parent);
}
+4 -1
View File
@@ -6,7 +6,10 @@
],
"module": "commonjs",
"outDir": "./out",
"strictNullChecks": true,
"typeRoots": [
"./node_modules/@types"
],
"strict": true,
"experimentalDecorators": true
},
"include": [
+261
View File
@@ -0,0 +1,261 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/byline@4.2.31":
version "4.2.31"
resolved "https://registry.yarnpkg.com/@types/byline/-/byline-4.2.31.tgz#0e61fcb9c03e047d21c4496554c7116297ab60cd"
dependencies:
"@types/node" "*"
"@types/file-type@^5.2.1":
version "5.2.1"
resolved "https://registry.yarnpkg.com/@types/file-type/-/file-type-5.2.1.tgz#e7af49e08187b6b7598509c5e416669d25fa3461"
dependencies:
"@types/node" "*"
"@types/mocha@2.2.43":
version "2.2.43"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-2.2.43.tgz#03c54589c43ad048cbcbfd63999b55d0424eec27"
"@types/node@*":
version "8.0.51"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb"
"@types/node@7.0.43":
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"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
dependencies:
balanced-match "^1.0.0"
concat-map "0.0.1"
browser-stdout@1.3.0:
version "1.3.0"
resolved "https://registry.yarnpkg.com/browser-stdout/-/browser-stdout-1.3.0.tgz#f351d32969d32fa5d7a5567154263d928ae3bd1f"
byline@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1"
commander@2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
dependencies:
graceful-readlink ">= 1.0.0"
concat-map@0.0.1:
version "0.0.1"
resolved "https://registry.yarnpkg.com/concat-map/-/concat-map-0.0.1.tgz#d8a96bd77fd68df7793a73036a3ba0d5405d477b"
debug@2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
dependencies:
ms "2.0.0"
diff@3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
escape-string-regexp@1.0.5:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
file-type@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.2.0.tgz#113cfed52e1d6959ab80248906e2f25a8cdccb74"
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
glob@7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
dependencies:
fs.realpath "^1.0.0"
inflight "^1.0.4"
inherits "2"
minimatch "^3.0.2"
once "^1.3.0"
path-is-absolute "^1.0.0"
"graceful-readlink@>= 1.0.0":
version "1.0.1"
resolved "https://registry.yarnpkg.com/graceful-readlink/-/graceful-readlink-1.0.1.tgz#4cafad76bc62f02fa039b2f94e9a3dd3a391a725"
growl@1.9.2:
version "1.9.2"
resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f"
has-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
he@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
iconv-lite@0.4.19:
version "0.4.19"
resolved "https://registry.yarnpkg.com/iconv-lite/-/iconv-lite-0.4.19.tgz#f7468f60135f5e5dad3399c0a81be9a1603a082b"
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
dependencies:
once "^1.3.0"
wrappy "1"
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"
lodash._baseassign@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e"
dependencies:
lodash._basecopy "^3.0.0"
lodash.keys "^3.0.0"
lodash._basecopy@^3.0.0:
version "3.0.1"
resolved "https://registry.yarnpkg.com/lodash._basecopy/-/lodash._basecopy-3.0.1.tgz#8da0e6a876cf344c0ad8a54882111dd3c5c7ca36"
lodash._basecreate@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821"
lodash._getnative@^3.0.0:
version "3.9.1"
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
lodash._isiterateecall@^3.0.0:
version "3.0.9"
resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c"
lodash.create@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7"
dependencies:
lodash._baseassign "^3.0.0"
lodash._basecreate "^3.0.0"
lodash._isiterateecall "^3.0.0"
lodash.isarguments@^3.0.0:
version "3.1.0"
resolved "https://registry.yarnpkg.com/lodash.isarguments/-/lodash.isarguments-3.1.0.tgz#2f573d85c6a24289ff00663b491c1d338ff3458a"
lodash.isarray@^3.0.0:
version "3.0.4"
resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
lodash.keys@^3.0.0:
version "3.1.2"
resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
dependencies:
lodash._getnative "^3.0.0"
lodash.isarguments "^3.0.0"
lodash.isarray "^3.0.0"
minimatch@^3.0.2:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
dependencies:
brace-expansion "^1.1.7"
minimist@0.0.8:
version "0.0.8"
resolved "https://registry.yarnpkg.com/minimist/-/minimist-0.0.8.tgz#857fcabfc3397d2625b8228262e86aa7a011b05d"
mkdirp@0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
dependencies:
minimist "0.0.8"
mocha@^3.2.0:
version "3.5.3"
resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d"
dependencies:
browser-stdout "1.3.0"
commander "2.9.0"
debug "2.6.8"
diff "3.2.0"
escape-string-regexp "1.0.5"
glob "7.1.1"
growl "1.9.2"
he "1.1.1"
json3 "3.3.2"
lodash.create "3.1.1"
mkdirp "0.5.1"
supports-color "3.1.2"
ms@2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.0.0.tgz#5608aeadfc00be6c2901df5f9861788de0d597c8"
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
dependencies:
wrappy "1"
path-is-absolute@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/path-is-absolute/-/path-is-absolute-1.0.1.tgz#174b9268735534ffbc7ace6bf53a5a9e1b5c5f5f"
supports-color@3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5"
dependencies:
has-flag "^1.0.0"
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:
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"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
+1 -2
View File
@@ -3,5 +3,4 @@ client/tsconfig.json
client/src/**
server/tsconfig.json
server/src/**
server/node_modules/@types/**
npm-shrinkwrap.json
server/node_modules/@types/**
+9 -11
View File
@@ -6,7 +6,7 @@
import * as path from 'path';
import { workspace, languages, ExtensionContext, extensions, Uri, TextDocument, ColorInformation, Color, ColorPresentation } from 'vscode';
import { workspace, languages, ExtensionContext, extensions, Uri, TextDocument, ColorInformation, Color, ColorPresentation, LanguageConfiguration } from 'vscode';
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification } from 'vscode-languageclient';
import TelemetryReporter from 'vscode-extension-telemetry';
import { ConfigurationFeature } from 'vscode-languageclient/lib/configuration.proposed';
@@ -50,10 +50,6 @@ interface Settings {
};
}
interface JSONSettings {
schemas: JSONSchemaSettings[];
}
interface JSONSchemaSettings {
fileMatch?: string[];
url?: string;
@@ -71,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=6004'] };
let debugOptions = { execArgv: ['--nolazy', '--inspect'] };
// If the extension is launch in debug mode the debug server options are use
// Otherwise the run options are used
@@ -80,7 +76,7 @@ export function activate(context: ExtensionContext) {
debug: { module: serverModule, transport: TransportKind.ipc, options: debugOptions }
};
let documentSelector = ['json'];
let documentSelector = ['json', 'jsonc'];
// Options to control the language client
let clientOptions: LanguageClientOptions = {
@@ -163,13 +159,15 @@ export function activate(context: ExtensionContext) {
}));
});
languages.setLanguageConfiguration('json', {
let languageConfiguration: LanguageConfiguration = {
wordPattern: /("(?:[^\\\"]*(?:\\.)?)*"?)|[^\s{}\[\],:]+/,
indentationRules: {
increaseIndentPattern: /^.*(\{[^}]*|\[[^\]]*)$/,
decreaseIndentPattern: /^\s*[}\]],?\s*$/
}
});
};
languages.setLanguageConfiguration('json', languageConfiguration);
languages.setLanguageConfiguration('jsonc', languageConfiguration);
}
function getSchemaAssociation(context: ExtensionContext): ISchemaAssociations {
@@ -260,8 +258,8 @@ function getSettings(): Settings {
folderPath = folderPath + '/';
}
collectSchemaSettings(folderSchemas, folderUri.fsPath, folderPath + '*');
};
};
}
}
}
return settings;
}
+1
View File
@@ -3,6 +3,7 @@
"target": "es5",
"module": "commonjs",
"outDir": "./out",
"noUnusedLocals": true,
"lib": [
"es5", "es2015.promise"
]
+36 -8
View File
@@ -7,15 +7,14 @@
"vscode": "0.10.x"
},
"activationEvents": [
"onLanguage:json"
"onLanguage:json", "onLanguage:jsonc"
],
"enableProposedApi": true,
"main": "./client/out/jsonMain",
"scripts": {
"compile": "gulp compile-extension:json-client && gulp compile-extension:json-server",
"postinstall": "cd server && npm install",
"install-client-next": "npm install vscode-languageclient@next -f -S",
"install-client-local": "npm install ../../../vscode-languageserver-node/client -f -S",
"postinstall": "cd server && yarn install",
"install-client-next": "yarn add vscode-languageclient@next",
"update-grammar": "node ../../build/npm/update-grammar.js Microsoft/vscode-JSON.tmLanguage JSON.tmLanguage ./syntaxes/JSON.tmLanguage.json"
},
"contributes": {
@@ -33,14 +32,38 @@
".jscsrc",
".eslintrc",
".babelrc",
".webmanifest",
".code-workspace"
".webmanifest"
],
"filenames": [
".watchmanconfig",
".ember-cli"
],
"mimetypes": [
"application/json",
"application/manifest+json"
],
"configuration": "./language-configuration.json"
},
{
"id": "jsonc",
"aliases": [
"JSON with Comments"
],
"extensions": [
".code-workspace",
"language-configuration.json",
"icon-theme.json",
"color-theme.json"
],
"filenames": [
"settings.json",
"launch.json",
"tasks.json",
"keybindings.json",
"tsconfig.json",
"jsconfig.json"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
@@ -48,6 +71,11 @@
"language": "json",
"scopeName": "source.json",
"path": "./syntaxes/JSON.tmLanguage.json"
},
{
"language": "jsonc",
"scopeName": "source.json",
"path": "./syntaxes/JSON.tmLanguage.json"
}
],
"jsonValidation": [
@@ -133,10 +161,10 @@
},
"dependencies": {
"vscode-extension-telemetry": "0.0.8",
"vscode-languageclient": "3.5.0-next.4",
"vscode-languageclient": "^3.5.0",
"vscode-nls": "2.0.2"
},
"devDependencies": {
"@types/node": "7.0.43"
}
}
}
+6 -6
View File
@@ -10,8 +10,8 @@
"dependencies": {
"jsonc-parser": "^1.0.0",
"request-light": "^0.2.1",
"vscode-json-languageservice": "3.0.0",
"vscode-languageserver": "3.5.0-next.6",
"vscode-json-languageservice": "^3.0.4",
"vscode-languageserver": "^3.5.0",
"vscode-nls": "^2.0.2",
"vscode-uri": "^1.0.1"
},
@@ -21,9 +21,9 @@
"scripts": {
"compile": "gulp compile-extension:json-server",
"watch": "gulp watch-extension:json-server",
"install-service-next": "npm install vscode-json-languageservice@next -f -S",
"install-service-local": "npm install ../../../../vscode-json-languageservice -f -S",
"install-server-next": "npm install vscode-languageserver@next -f -S",
"install-server-local": "npm install ../../../../vscode-languageserver-node/server -f -S"
"install-service-next": "yarn add vscode-json-languageservice@next",
"install-service-local": "npm install ../../../../vscode-json-languageservice -f",
"install-server-next": "yarn add vscode-languageserver@next",
"install-server-local": "npm install ../../../../vscode-languageserver-node/server -f"
}
}
+55 -31
View File
@@ -17,7 +17,8 @@ import fs = require('fs');
import URI from 'vscode-uri';
import * as URL from 'url';
import Strings = require('./utils/strings');
import { JSONDocument, JSONSchema, LanguageSettings, getLanguageService } from 'vscode-json-languageservice';
import { formatError, runSafe } from './utils/errors';
import { JSONDocument, JSONSchema, LanguageSettings, getLanguageService, DocumentLanguageSettings } from 'vscode-json-languageservice';
import { getLanguageModelCache } from './languageModelCache';
import * as nls from 'vscode-nls';
@@ -42,6 +43,10 @@ namespace SchemaContentChangeNotification {
// Create a connection for the server
let connection: IConnection = createConnection();
process.on('unhandledRejection', e => {
connection.console.error(formatError(`Unhandled exception`, e));
});
console.log = connection.console.log.bind(connection.console);
console.error = connection.console.error.bind(connection.console);
@@ -161,7 +166,7 @@ connection.onDidChangeConfiguration((change) => {
let enableFormatter = settings && settings.json && settings.json.format && settings.json.format.enable;
if (enableFormatter) {
if (!formatterRegistration) {
formatterRegistration = connection.client.register(DocumentRangeFormattingRequest.type, { documentSelector: [{ language: 'json' }] });
formatterRegistration = connection.client.register(DocumentRangeFormattingRequest.type, { documentSelector: [{ language: 'json' }, { language: 'jsonc' }] });
}
} else if (formatterRegistration) {
formatterRegistration.then(r => r.dispose());
@@ -251,12 +256,17 @@ function validateTextDocument(textDocument: TextDocument): void {
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics: [] });
return;
}
try {
let jsonDocument = getJSONDocument(textDocument);
let jsonDocument = getJSONDocument(textDocument);
languageService.doValidation(textDocument, jsonDocument).then(diagnostics => {
// Send the computed diagnostics to VSCode.
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
});
let documentSettings: DocumentLanguageSettings = textDocument.languageId === 'jsonc' ? { comments: 'ignore', trailingCommas: 'ignore' } : { comments: 'error', trailingCommas: 'error' };
languageService.doValidation(textDocument, jsonDocument, documentSettings).then(diagnostics => {
// Send the computed diagnostics to VSCode.
connection.sendDiagnostics({ uri: textDocument.uri, diagnostics });
});
} catch (e) {
connection.console.error(formatError(`Error while validating ${textDocument.uri}`, e));
}
}
connection.onDidChangeWatchedFiles((change) => {
@@ -285,48 +295,62 @@ function getJSONDocument(document: TextDocument): JSONDocument {
}
connection.onCompletion(textDocumentPosition => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let jsonDocument = getJSONDocument(document);
return languageService.doComplete(document, textDocumentPosition.position, jsonDocument);
return runSafe(() => {
let document = documents.get(textDocumentPosition.textDocument.uri);
let jsonDocument = getJSONDocument(document);
return languageService.doComplete(document, textDocumentPosition.position, jsonDocument);
}, null, `Error while computing completions for ${textDocumentPosition.textDocument.uri}`);
});
connection.onCompletionResolve(completionItem => {
return languageService.doResolve(completionItem);
return runSafe(() => {
return languageService.doResolve(completionItem);
}, null, `Error while resolving completion proposal`);
});
connection.onHover(textDocumentPositionParams => {
let document = documents.get(textDocumentPositionParams.textDocument.uri);
let jsonDocument = getJSONDocument(document);
return languageService.doHover(document, textDocumentPositionParams.position, jsonDocument);
return runSafe(() => {
let document = documents.get(textDocumentPositionParams.textDocument.uri);
let jsonDocument = getJSONDocument(document);
return languageService.doHover(document, textDocumentPositionParams.position, jsonDocument);
}, null, `Error while computing hover for ${textDocumentPositionParams.textDocument.uri}`);
});
connection.onDocumentSymbol(documentSymbolParams => {
let document = documents.get(documentSymbolParams.textDocument.uri);
let jsonDocument = getJSONDocument(document);
return languageService.findDocumentSymbols(document, jsonDocument);
return runSafe(() => {
let document = documents.get(documentSymbolParams.textDocument.uri);
let jsonDocument = getJSONDocument(document);
return languageService.findDocumentSymbols(document, jsonDocument);
}, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`);
});
connection.onDocumentRangeFormatting(formatParams => {
let document = documents.get(formatParams.textDocument.uri);
return languageService.format(document, formatParams.range, formatParams.options);
return runSafe(() => {
let document = documents.get(formatParams.textDocument.uri);
return languageService.format(document, formatParams.range, formatParams.options);
}, [], `Error while formatting range for ${formatParams.textDocument.uri}`);
});
connection.onRequest(DocumentColorRequest.type, params => {
let document = documents.get(params.textDocument.uri);
if (document) {
let jsonDocument = getJSONDocument(document);
return languageService.findDocumentColors(document, jsonDocument);
}
return [];
return runSafe(() => {
let document = documents.get(params.textDocument.uri);
if (document) {
let jsonDocument = getJSONDocument(document);
return languageService.findDocumentColors(document, jsonDocument);
}
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 jsonDocument = getJSONDocument(document);
return languageService.getColorPresentations(document, jsonDocument, params.color, params.range);
}
return [];
return runSafe(() => {
let document = documents.get(params.textDocument.uri);
if (document) {
let jsonDocument = getJSONDocument(document);
return languageService.getColorPresentations(document, jsonDocument, params.color, params.range);
}
return [];
}, [], `Error while computing color presentationsd for ${params.textDocument.uri}`);
});
// Listen on the connection
@@ -0,0 +1,33 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. 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;
}
}
+1
View File
@@ -5,6 +5,7 @@
"sourceMap": true,
"sourceRoot": "../src",
"outDir": "./out",
"noUnusedLocals": true,
"lib": [
"es5", "es2015.promise"
]
+92
View File
@@ -0,0 +1,92 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/node@7.0.43":
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"
debug@2:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
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"
dependencies:
agent-base "~1.0.1"
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"
dependencies:
agent-base "~1.0.1"
debug "2"
extend "3"
jsonc-parser@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/jsonc-parser/-/jsonc-parser-1.0.0.tgz#ddcc864ae708e60a7a6dd36daea00172fa8d9272"
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"
dependencies:
http-proxy-agent "^0.2.6"
https-proxy-agent "^0.3.5"
vscode-nls "^2.0.2"
vscode-json-languageservice@^3.0.4:
version "3.0.4"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.0.4.tgz#293970ef3179d7793ffd25887acf158d93ff8733"
dependencies:
jsonc-parser "^1.0.0"
vscode-languageserver-types "^3.5.0"
vscode-nls "^2.0.2"
vscode-uri "^1.0.1"
vscode-jsonrpc@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.5.0.tgz#87239d9e166b2d7352245b8a813597804c1d63aa"
vscode-languageserver-protocol@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.0.tgz#067c5cbe27709795398d119692c97ebba1452209"
dependencies:
vscode-jsonrpc "^3.5.0"
vscode-languageserver-types "^3.5.0"
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-languageserver@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver/-/vscode-languageserver-3.5.0.tgz#d28099bc6ddda8c1dd16b707e454e1b1ddae0dba"
dependencies:
vscode-languageserver-protocol "^3.5.0"
vscode-uri "^1.0.1"
vscode-nls@^2.0.2:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"
vscode-uri@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/vscode-uri/-/vscode-uri-1.0.1.tgz#11a86befeac3c4aa3ec08623651a3c81a6d0bbc8"
+47
View File
@@ -0,0 +1,47 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/node@7.0.43":
version "7.0.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c"
applicationinsights@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-0.18.0.tgz#162ebb48a383408bc4de44db32b417307f45bbc1"
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-jsonrpc@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/vscode-jsonrpc/-/vscode-jsonrpc-3.5.0.tgz#87239d9e166b2d7352245b8a813597804c1d63aa"
vscode-languageclient@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/vscode-languageclient/-/vscode-languageclient-3.5.0.tgz#36d02cc186a8365a4467719a290fb200a9ae490a"
dependencies:
vscode-languageserver-protocol "^3.5.0"
vscode-languageserver-protocol@^3.5.0:
version "3.5.0"
resolved "https://registry.yarnpkg.com/vscode-languageserver-protocol/-/vscode-languageserver-protocol-3.5.0.tgz#067c5cbe27709795398d119692c97ebba1452209"
dependencies:
vscode-jsonrpc "^3.5.0"
vscode-languageserver-types "^3.5.0"
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"
winreg@1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.3.tgz#93ad116b2696da87d58f7265a8fcea5254a965d5"
+1 -2
View File
@@ -1,4 +1,3 @@
test/**
src/**
tsconfig.json
npm-shrinkwrap.json
tsconfig.json
+1 -1
View File
@@ -12,7 +12,7 @@
let didShow = false;
const showCspWarning = () => {
if (didShow) {
if (didShow || settings.disableSecurityWarnings) {
return;
}
didShow = true;
+2 -2
View File
@@ -317,8 +317,8 @@
"devDependencies": {
"@types/highlight.js": "9.1.10",
"@types/markdown-it": "0.0.2",
"@types/node": "8.0.33",
"@types/node": "7.0.43",
"gulp-rename": "^1.2.2",
"gulp-replace": "^0.5.4"
}
}
}
+36
View File
@@ -0,0 +1,36 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
export interface Command {
readonly id: string;
execute(...args: any[]): void;
}
export class CommandManager {
private readonly commands = new Map<string, vscode.Disposable>();
public dispose() {
for (const registration of this.commands.values()) {
registration.dispose();
}
this.commands.clear();
}
public register<T extends Command>(command: T): T {
this.registerCommand(command.id, command.execute, command);
return command;
}
private registerCommand(id: string, impl: (...args: any[]) => void, thisArg?: any) {
if (this.commands.has(id)) {
return;
}
this.commands.set(id, vscode.commands.registerCommand(id, impl, thisArg));
}
}
+291
View File
@@ -0,0 +1,291 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as nls from 'vscode-nls';
const localize = nls.config(process.env.VSCODE_NLS_CONFIG)();
import * as vscode from 'vscode';
import * as path from 'path';
import { Command } from './commandManager';
import { ExtensionContentSecurityPolicyArbiter, PreviewSecuritySelector } from './security';
import { getMarkdownUri, MDDocumentContentProvider, isMarkdownFile } from './features/previewContentProvider';
import { Logger } from './logger';
import { TableOfContentsProvider } from './tableOfContentsProvider';
import { MarkdownEngine } from './markdownEngine';
import { TelemetryReporter } from './telemetryReporter';
function getViewColumn(sideBySide: boolean): vscode.ViewColumn | undefined {
const active = vscode.window.activeTextEditor;
if (!active) {
return vscode.ViewColumn.One;
}
if (!sideBySide) {
return active.viewColumn;
}
switch (active.viewColumn) {
case vscode.ViewColumn.One:
return vscode.ViewColumn.Two;
case vscode.ViewColumn.Two:
return vscode.ViewColumn.Three;
}
return active.viewColumn;
}
function showPreview(
cspArbiter: ExtensionContentSecurityPolicyArbiter,
telemetryReporter: TelemetryReporter,
uri?: vscode.Uri,
sideBySide: boolean = false,
) {
let resource = uri;
if (!(resource instanceof vscode.Uri)) {
if (vscode.window.activeTextEditor) {
// we are relaxed and don't check for markdown files
resource = vscode.window.activeTextEditor.document.uri;
}
}
if (!(resource instanceof vscode.Uri)) {
if (!vscode.window.activeTextEditor) {
// this is most likely toggling the preview
return vscode.commands.executeCommand('markdown.showSource');
}
// nothing found that could be shown or toggled
return;
}
const thenable = vscode.commands.executeCommand('vscode.previewHtml',
getMarkdownUri(resource),
getViewColumn(sideBySide),
localize('previewTitle', 'Preview {0}', path.basename(resource.fsPath)),
{
allowScripts: true,
allowSvgs: cspArbiter.shouldAllowSvgsForResource(resource)
});
telemetryReporter.sendTelemetryEvent('openPreview', {
where: sideBySide ? 'sideBySide' : 'inPlace',
how: (uri instanceof vscode.Uri) ? 'action' : 'pallete'
});
return thenable;
}
export class ShowPreviewCommand implements Command {
public readonly id = 'markdown.showPreview';
public constructor(
private readonly cspArbiter: ExtensionContentSecurityPolicyArbiter,
private readonly telemetryReporter: TelemetryReporter
) { }
public execute(uri?: vscode.Uri) {
showPreview(this.cspArbiter, this.telemetryReporter, uri, false);
}
}
export class ShowPreviewToSideCommand implements Command {
public readonly id = 'markdown.showPreviewToSide';
public constructor(
private readonly cspArbiter: ExtensionContentSecurityPolicyArbiter,
private readonly telemetryReporter: TelemetryReporter
) { }
public execute(uri?: vscode.Uri) {
showPreview(this.cspArbiter, this.telemetryReporter, uri, true);
}
}
export class ShowSourceCommand implements Command {
public readonly id = 'markdown.showSource';
public execute(mdUri?: vscode.Uri) {
if (!mdUri) {
return vscode.commands.executeCommand('workbench.action.navigateBack');
}
const docUri = vscode.Uri.parse(mdUri.query);
for (const editor of vscode.window.visibleTextEditors) {
if (editor.document.uri.scheme === docUri.scheme && editor.document.uri.toString() === docUri.toString()) {
return vscode.window.showTextDocument(editor.document, editor.viewColumn);
}
}
return vscode.workspace.openTextDocument(docUri)
.then(vscode.window.showTextDocument);
}
}
export class RefreshPreviewCommand implements Command {
public readonly id = 'markdown.refreshPreview';
public constructor(
private readonly contentProvider: MDDocumentContentProvider
) { }
public execute(resource: string | undefined) {
if (resource) {
const source = vscode.Uri.parse(resource);
this.contentProvider.update(source);
} else if (vscode.window.activeTextEditor && isMarkdownFile(vscode.window.activeTextEditor.document)) {
this.contentProvider.update(getMarkdownUri(vscode.window.activeTextEditor.document.uri));
} else {
// update all generated md documents
for (const document of vscode.workspace.textDocuments) {
if (document.uri.scheme === 'markdown') {
this.contentProvider.update(document.uri);
}
}
}
}
}
export class ShowPreviewSecuritySelectorCommand implements Command {
public readonly id = 'markdown.showPreviewSecuritySelector';
public constructor(
private readonly previewSecuritySelector: PreviewSecuritySelector
) { }
public execute(resource: string | undefined) {
if (resource) {
const source = vscode.Uri.parse(resource).query;
this.previewSecuritySelector.showSecutitySelectorForResource(vscode.Uri.parse(source));
} else {
if (vscode.window.activeTextEditor && vscode.window.activeTextEditor.document.languageId === 'markdown') {
this.previewSecuritySelector.showSecutitySelectorForResource(vscode.window.activeTextEditor.document.uri);
}
}
}
}
export class RevealLineCommand implements Command {
public readonly id = '_markdown.revealLine';
public constructor(
private logger: Logger
) { }
public execute(uri: string, line: number) {
const sourceUri = vscode.Uri.parse(decodeURIComponent(uri));
this.logger.log('revealLine', { uri, sourceUri: sourceUri.toString(), line });
vscode.window.visibleTextEditors
.filter(editor => isMarkdownFile(editor.document) && editor.document.uri.toString() === sourceUri.toString())
.forEach(editor => {
const sourceLine = Math.floor(line);
const fraction = line - sourceLine;
const text = editor.document.lineAt(sourceLine).text;
const start = Math.floor(fraction * text.length);
editor.revealRange(
new vscode.Range(sourceLine, start, sourceLine + 1, 0),
vscode.TextEditorRevealType.AtTop);
});
}
}
export class DidClickCommand implements Command {
public readonly id = '_markdown.didClick';
public execute(uri: string, line: number) {
const sourceUri = vscode.Uri.parse(decodeURIComponent(uri));
return vscode.workspace.openTextDocument(sourceUri)
.then(document => vscode.window.showTextDocument(document))
.then(editor =>
vscode.commands.executeCommand('revealLine', { lineNumber: Math.floor(line), at: 'center' })
.then(() => editor))
.then(editor => {
if (editor) {
editor.selection = new vscode.Selection(
new vscode.Position(Math.floor(line), 0),
new vscode.Position(Math.floor(line), 0));
}
});
}
}
export class MoveCursorToPositionCommand implements Command {
public readonly id = '_markdown.moveCursorToPosition';
public execute(line: number, character: number) {
if (!vscode.window.activeTextEditor) {
return;
}
const position = new vscode.Position(line, character);
const selection = new vscode.Selection(position, position);
vscode.window.activeTextEditor.revealRange(selection);
vscode.window.activeTextEditor.selection = selection;
}
}
export class OnPreviewStyleLoadErrorCommand implements Command {
public readonly id = '_markdown.onPreviewStyleLoadError';
public execute(resources: string[]) {
vscode.window.showWarningMessage(localize('onPreviewStyleLoadError', "Could not load 'markdown.styles': {0}", resources.join(', ')));
}
}
export interface OpenDocumentLinkArgs {
path: string;
fragment: string;
}
export class OpenDocumentLinkCommand implements Command {
private static readonly id = '_markdown.openDocumentLink';
public readonly id = OpenDocumentLinkCommand.id;
public static createCommandUri(
path: string,
fragment: string
): vscode.Uri {
return vscode.Uri.parse(`command:${OpenDocumentLinkCommand.id}?${encodeURIComponent(JSON.stringify({ path, fragment }))}`);
}
public constructor(
private readonly engine: MarkdownEngine
) { }
public execute(args: OpenDocumentLinkArgs) {
const tryRevealLine = async (editor: vscode.TextEditor) => {
if (editor && args.fragment) {
const toc = new TableOfContentsProvider(this.engine, editor.document);
const line = await toc.lookup(args.fragment);
if (!isNaN(line)) {
return editor.revealRange(
new vscode.Range(line, 0, line, 0),
vscode.TextEditorRevealType.AtTop);
}
}
};
const tryOpen = async (path: string) => {
if (vscode.window.activeTextEditor && isMarkdownFile(vscode.window.activeTextEditor.document) && vscode.window.activeTextEditor.document.uri.fsPath === path) {
return tryRevealLine(vscode.window.activeTextEditor);
} else {
const resource = vscode.Uri.file(path);
return vscode.workspace.openTextDocument(resource)
.then(vscode.window.showTextDocument)
.then(tryRevealLine);
}
};
return tryOpen(args.path).catch(() => {
if (path.extname(args.path) === '') {
return tryOpen(args.path + '.md');
}
const resource = vscode.Uri.file(args.path);
return Promise.resolve(void 0)
.then(() => vscode.commands.executeCommand('vscode.open', resource))
.then(() => void 0);
});
}
}
+32 -272
View File
@@ -3,200 +3,52 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as nls from 'vscode-nls';
const localize = nls.config(process.env.VSCODE_NLS_CONFIG)();
import * as vscode from 'vscode';
import * as path from 'path';
import TelemetryReporter from 'vscode-extension-telemetry';
import { MarkdownEngine } from './markdownEngine';
import LinkProvider from './documentLinkProvider';
import MDDocumentSymbolProvider from './documentSymbolProvider';
import { ExtensionContentSecurityPolicyArbiter, PreviewSecuritySelector } from './security';
import { MDDocumentContentProvider, getMarkdownUri, isMarkdownFile } from './previewContentProvider';
import { TableOfContentsProvider } from './tableOfContentsProvider';
import { Logger } from './logger';
import { CommandManager } from './commandManager';
import * as commands from './commands';
import { loadDefaultTelemetryReporter } from './telemetryReporter';
import { loadMarkdownExtensions } from './markdownExtensions';
import LinkProvider from './features/documentLinkProvider';
import MDDocumentSymbolProvider from './features/documentSymbolProvider';
import { MDDocumentContentProvider, getMarkdownUri, isMarkdownFile } from './features/previewContentProvider';
interface IPackageInfo {
name: string;
version: string;
aiKey: string;
}
interface OpenDocumentLinkArgs {
path: string;
fragment: string;
}
const resolveExtensionResources = (extension: vscode.Extension<any>, stylePath: string): vscode.Uri => {
const resource = vscode.Uri.parse(stylePath);
if (resource.scheme) {
return resource;
}
return vscode.Uri.file(path.join(extension.extensionPath, stylePath));
};
var telemetryReporter: TelemetryReporter | null;
export function activate(context: vscode.ExtensionContext) {
const packageInfo = getPackageInfo();
telemetryReporter = packageInfo && new TelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
if (telemetryReporter) {
context.subscriptions.push(telemetryReporter);
}
const telemetryReporter = loadDefaultTelemetryReporter();
context.subscriptions.push(telemetryReporter);
const cspArbiter = new ExtensionContentSecurityPolicyArbiter(context.globalState);
const cspArbiter = new ExtensionContentSecurityPolicyArbiter(context.globalState, context.workspaceState);
const engine = new MarkdownEngine();
const logger = new Logger();
const selector = 'markdown';
const contentProvider = new MDDocumentContentProvider(engine, context, cspArbiter, logger);
const contentProviderRegistration = vscode.workspace.registerTextDocumentContentProvider('markdown', contentProvider);
context.subscriptions.push(vscode.workspace.registerTextDocumentContentProvider(selector, contentProvider));
loadMarkdownExtensions(contentProvider, engine);
context.subscriptions.push(vscode.languages.registerDocumentSymbolProvider(selector, new MDDocumentSymbolProvider(engine)));
context.subscriptions.push(vscode.languages.registerDocumentLinkProvider(selector, new LinkProvider()));
const previewSecuritySelector = new PreviewSecuritySelector(cspArbiter, contentProvider);
for (const extension of vscode.extensions.all) {
const contributes = extension.packageJSON && extension.packageJSON.contributes;
if (!contributes) {
continue;
}
const styles = contributes['markdown.previewStyles'];
if (styles && Array.isArray(styles)) {
for (const style of styles) {
try {
contentProvider.addStyle(resolveExtensionResources(extension, style));
} catch (e) {
// noop
}
}
}
const scripts = contributes['markdown.previewScripts'];
if (scripts && Array.isArray(scripts)) {
for (const script of scripts) {
try {
contentProvider.addScript(resolveExtensionResources(extension, script));
} catch (e) {
// noop
}
}
}
if (contributes['markdown.markdownItPlugins']) {
extension.activate().then(() => {
if (extension.exports && extension.exports.extendMarkdownIt) {
engine.addPlugin((md: any) => extension.exports.extendMarkdownIt(md));
}
});
}
}
const symbolsProvider = new MDDocumentSymbolProvider(engine);
const symbolsProviderRegistration = vscode.languages.registerDocumentSymbolProvider({ language: 'markdown' }, symbolsProvider);
context.subscriptions.push(contentProviderRegistration, symbolsProviderRegistration);
context.subscriptions.push(vscode.languages.registerDocumentLinkProvider('markdown', new LinkProvider()));
context.subscriptions.push(vscode.commands.registerCommand('markdown.showPreview', (uri) => showPreview(cspArbiter, uri, false)));
context.subscriptions.push(vscode.commands.registerCommand('markdown.showPreviewToSide', uri => showPreview(cspArbiter, uri, true)));
context.subscriptions.push(vscode.commands.registerCommand('markdown.showSource', showSource));
context.subscriptions.push(vscode.commands.registerCommand('_markdown.moveCursorToPosition', (line: number, character: number) => {
if (!vscode.window.activeTextEditor) {
return;
}
const position = new vscode.Position(line, character);
const selection = new vscode.Selection(position, position);
vscode.window.activeTextEditor.revealRange(selection);
vscode.window.activeTextEditor.selection = selection;
}));
context.subscriptions.push(vscode.commands.registerCommand('_markdown.revealLine', (uri, line) => {
const sourceUri = vscode.Uri.parse(decodeURIComponent(uri));
logger.log('revealLine', { uri, sourceUri: sourceUri.toString(), line });
vscode.window.visibleTextEditors
.filter(editor => isMarkdownFile(editor.document) && editor.document.uri.toString() === sourceUri.toString())
.forEach(editor => {
const sourceLine = Math.floor(line);
const fraction = line - sourceLine;
const text = editor.document.lineAt(sourceLine).text;
const start = Math.floor(fraction * text.length);
editor.revealRange(
new vscode.Range(sourceLine, start, sourceLine + 1, 0),
vscode.TextEditorRevealType.AtTop);
});
}));
context.subscriptions.push(vscode.commands.registerCommand('_markdown.didClick', (uri: string, line) => {
const sourceUri = vscode.Uri.parse(decodeURIComponent(uri));
return vscode.workspace.openTextDocument(sourceUri)
.then(document => vscode.window.showTextDocument(document))
.then(editor =>
vscode.commands.executeCommand('revealLine', { lineNumber: Math.floor(line), at: 'center' })
.then(() => editor))
.then(editor => {
if (editor) {
editor.selection = new vscode.Selection(
new vscode.Position(Math.floor(line), 0),
new vscode.Position(Math.floor(line), 0));
}
});
}));
context.subscriptions.push(vscode.commands.registerCommand('_markdown.openDocumentLink', (args: OpenDocumentLinkArgs) => {
const tryRevealLine = async (editor: vscode.TextEditor) => {
if (editor && args.fragment) {
const toc = new TableOfContentsProvider(engine, editor.document);
const line = await toc.lookup(args.fragment);
if (!isNaN(line)) {
return editor.revealRange(
new vscode.Range(line, 0, line, 0),
vscode.TextEditorRevealType.AtTop);
}
}
};
if (vscode.window.activeTextEditor && isMarkdownFile(vscode.window.activeTextEditor.document) && vscode.window.activeTextEditor.document.uri.fsPath === args.path) {
return tryRevealLine(vscode.window.activeTextEditor);
} else {
const resource = vscode.Uri.file(args.path);
return vscode.workspace.openTextDocument(resource)
.then(vscode.window.showTextDocument)
.then(tryRevealLine, _ => vscode.commands.executeCommand('vscode.open', resource));
}
}));
context.subscriptions.push(vscode.commands.registerCommand('markdown.showPreviewSecuritySelector', (resource: string | undefined) => {
if (resource) {
const source = vscode.Uri.parse(resource).query;
previewSecuritySelector.showSecutitySelectorForResource(vscode.Uri.parse(source));
} else {
if (vscode.window.activeTextEditor && vscode.window.activeTextEditor.document.languageId === 'markdown') {
previewSecuritySelector.showSecutitySelectorForResource(vscode.window.activeTextEditor.document.uri);
}
}
}));
context.subscriptions.push(vscode.commands.registerCommand('markdown.refreshPreview', (resource: string | undefined) => {
if (resource) {
const source = vscode.Uri.parse(resource);
contentProvider.update(source);
} else if (vscode.window.activeTextEditor && isMarkdownFile(vscode.window.activeTextEditor.document)) {
contentProvider.update(getMarkdownUri(vscode.window.activeTextEditor.document.uri));
} else {
// update all generated md documents
for (const document of vscode.workspace.textDocuments) {
if (document.uri.scheme === 'markdown') {
contentProvider.update(document.uri);
}
}
}
}));
context.subscriptions.push(vscode.commands.registerCommand('_markdown.onPreviewStyleLoadError', (resources: string[]) => {
vscode.window.showWarningMessage(localize('onPreviewStyleLoadError', "Could not load 'markdown.styles': {0}", resources.join(', ')));
}));
const commandManager = new CommandManager();
context.subscriptions.push(commandManager);
commandManager.register(new commands.ShowPreviewCommand(cspArbiter, telemetryReporter));
commandManager.register(new commands.ShowPreviewToSideCommand(cspArbiter, telemetryReporter));
commandManager.register(new commands.ShowSourceCommand());
commandManager.register(new commands.RefreshPreviewCommand(contentProvider));
commandManager.register(new commands.RevealLineCommand(logger));
commandManager.register(new commands.MoveCursorToPositionCommand());
commandManager.register(new commands.ShowPreviewSecuritySelectorCommand(previewSecuritySelector));
commandManager.register(new commands.OnPreviewStyleLoadErrorCommand());
commandManager.register(new commands.DidClickCommand());
commandManager.register(new commands.OpenDocumentLinkCommand(engine));
context.subscriptions.push(vscode.workspace.onDidSaveTextDocument(document => {
if (isMarkdownFile(document)) {
@@ -230,95 +82,3 @@ export function activate(context: vscode.ExtensionContext) {
}
}));
}
function showPreview(cspArbiter: ExtensionContentSecurityPolicyArbiter, uri?: vscode.Uri, sideBySide: boolean = false) {
let resource = uri;
if (!(resource instanceof vscode.Uri)) {
if (vscode.window.activeTextEditor) {
// we are relaxed and don't check for markdown files
resource = vscode.window.activeTextEditor.document.uri;
}
}
if (!(resource instanceof vscode.Uri)) {
if (!vscode.window.activeTextEditor) {
// this is most likely toggling the preview
return vscode.commands.executeCommand('markdown.showSource');
}
// nothing found that could be shown or toggled
return;
}
const thenable = vscode.commands.executeCommand('vscode.previewHtml',
getMarkdownUri(resource),
getViewColumn(sideBySide),
localize('previewTitle', 'Preview {0}', path.basename(resource.fsPath)),
{
allowScripts: true,
allowSvgs: cspArbiter.shouldAllowSvgsForResource(resource)
});
if (telemetryReporter) {
/* __GDPR__
"openPreview" : {
"where" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"how": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
telemetryReporter.sendTelemetryEvent('openPreview', {
where: sideBySide ? 'sideBySide' : 'inPlace',
how: (uri instanceof vscode.Uri) ? 'action' : 'pallete'
});
}
return thenable;
}
function getViewColumn(sideBySide: boolean): vscode.ViewColumn | undefined {
const active = vscode.window.activeTextEditor;
if (!active) {
return vscode.ViewColumn.One;
}
if (!sideBySide) {
return active.viewColumn;
}
switch (active.viewColumn) {
case vscode.ViewColumn.One:
return vscode.ViewColumn.Two;
case vscode.ViewColumn.Two:
return vscode.ViewColumn.Three;
}
return active.viewColumn;
}
function showSource(mdUri: vscode.Uri) {
if (!mdUri) {
return vscode.commands.executeCommand('workbench.action.navigateBack');
}
const docUri = vscode.Uri.parse(mdUri.query);
for (const editor of vscode.window.visibleTextEditors) {
if (editor.document.uri.scheme === docUri.scheme && editor.document.uri.toString() === docUri.toString()) {
return vscode.window.showTextDocument(editor.document, editor.viewColumn);
}
}
return vscode.workspace.openTextDocument(docUri)
.then(vscode.window.showTextDocument);
}
function getPackageInfo(): IPackageInfo | null {
const extention = vscode.extensions.getExtension('Microsoft.vscode-markdown');
if (extention && extention.packageJSON) {
return {
name: extention.packageJSON.name,
version: extention.packageJSON.version,
aiKey: extention.packageJSON.aiKey
};
}
return null;
}
@@ -0,0 +1,160 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
import * as path from 'path';
import { OpenDocumentLinkCommand } from '../commands';
function normalizeLink(
document: vscode.TextDocument,
link: string,
base: string
): vscode.Uri {
const uri = vscode.Uri.parse(link);
if (uri.scheme) {
return uri;
}
// assume it must be a file
let resourcePath = uri.path;
if (!uri.path) {
resourcePath = document.uri.path;
} else if (uri.path[0] === '/') {
const root = vscode.workspace.getWorkspaceFolder(document.uri);
if (root) {
resourcePath = path.join(root.uri.fsPath, uri.path);
}
} else {
resourcePath = path.join(base, uri.path);
}
return OpenDocumentLinkCommand.createCommandUri(resourcePath, uri.fragment);
}
function matchAll(
pattern: RegExp,
text: string
): Array<RegExpMatchArray> {
const out: RegExpMatchArray[] = [];
pattern.lastIndex = 0;
let match: RegExpMatchArray | null;
while ((match = pattern.exec(text))) {
out.push(match);
}
return out;
}
export default class LinkProvider implements vscode.DocumentLinkProvider {
private readonly linkPattern = /(\[[^\]]*\]\(\s*?)(((((?=.*\)\)+)|(?=.*\)\]+))[^\s\)]+?)|([^\s]+?)))\)/g;
private readonly referenceLinkPattern = /(\[([^\]]+)\]\[\s*?)([^\s\]]*?)\]/g;
private readonly definitionPattern = /^([\t ]*\[([^\]]+)\]:\s*)(\S+)/gm;
public provideDocumentLinks(
document: vscode.TextDocument,
_token: vscode.CancellationToken
): vscode.DocumentLink[] {
const base = path.dirname(document.uri.fsPath);
const text = document.getText();
return this.providerInlineLinks(text, document, base)
.concat(this.provideReferenceLinks(text, document, base));
}
private providerInlineLinks(
text: string,
document: vscode.TextDocument,
base: string
): vscode.DocumentLink[] {
const results: vscode.DocumentLink[] = [];
for (const match of matchAll(this.linkPattern, text)) {
const pre = match[1];
const link = match[2];
const offset = (match.index || 0) + pre.length;
const linkStart = document.positionAt(offset);
const linkEnd = document.positionAt(offset + link.length);
try {
results.push(new vscode.DocumentLink(
new vscode.Range(linkStart, linkEnd),
normalizeLink(document, link, base)));
} catch (e) {
// noop
}
}
return results;
}
private provideReferenceLinks(
text: string,
document: vscode.TextDocument,
base: string
): vscode.DocumentLink[] {
const results: vscode.DocumentLink[] = [];
const definitions = this.getDefinitions(text, document);
for (const match of matchAll(this.referenceLinkPattern, text)) {
let linkStart: vscode.Position;
let linkEnd: vscode.Position;
let reference = match[3];
if (reference) { // [text][ref]
const pre = match[1];
const offset = (match.index || 0) + pre.length;
linkStart = document.positionAt(offset);
linkEnd = document.positionAt(offset + reference.length);
} else if (match[2]) { // [ref][]
reference = match[2];
const offset = (match.index || 0) + 1;
linkStart = document.positionAt(offset);
linkEnd = document.positionAt(offset + match[2].length);
} else {
continue;
}
try {
const link = definitions.get(reference);
if (link) {
results.push(new vscode.DocumentLink(
new vscode.Range(linkStart, linkEnd),
vscode.Uri.parse(`command:_markdown.moveCursorToPosition?${encodeURIComponent(JSON.stringify([link.linkRange.start.line, link.linkRange.start.character]))}`)));
}
} catch (e) {
// noop
}
}
for (const definition of Array.from(definitions.values())) {
try {
results.push(new vscode.DocumentLink(
definition.linkRange,
normalizeLink(document, definition.link, base)));
} catch (e) {
// noop
}
}
return results;
}
private getDefinitions(text: string, document: vscode.TextDocument) {
const out = new Map<string, { link: string, linkRange: vscode.Range }>();
for (const match of matchAll(this.definitionPattern, text)) {
const pre = match[1];
const reference = match[2];
const link = match[3].trim();
const offset = (match.index || 0) + pre.length;
const linkStart = document.positionAt(offset);
const linkEnd = document.positionAt(offset + link.length);
out.set(reference, {
link: link,
linkRange: new vscode.Range(linkStart, linkEnd)
});
}
return out;
}
}
@@ -0,0 +1,25 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
import { MarkdownEngine } from '../markdownEngine';
import { TableOfContentsProvider } from '../tableOfContentsProvider';
export default class MDDocumentSymbolProvider implements vscode.DocumentSymbolProvider {
constructor(
private engine: MarkdownEngine
) { }
public async provideDocumentSymbols(document: vscode.TextDocument): Promise<vscode.SymbolInformation[]> {
const toc = await new TableOfContentsProvider(this.engine, document).getToc();
return toc.map(entry => {
return new vscode.SymbolInformation('#'.repeat(entry.level) + ' ' + entry.text, vscode.SymbolKind.Namespace, '', entry.location);
});
}
}
@@ -0,0 +1,318 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
import * as path from 'path';
import { MarkdownEngine } from '../markdownEngine';
import * as nls from 'vscode-nls';
import { Logger } from '../logger';
import { ContentSecurityPolicyArbiter, MarkdownPreviewSecurityLevel } from '../security';
const localize = nls.loadMessageBundle();
const previewStrings = {
cspAlertMessageText: localize('preview.securityMessage.text', 'Some content has been disabled in this document'),
cspAlertMessageTitle: localize('preview.securityMessage.title', 'Potentially unsafe or insecure content has been disabled in the markdown preview. Change the Markdown preview security setting to allow insecure content or enable scripts'),
cspAlertMessageLabel: localize('preview.securityMessage.label', 'Content Disabled Security Warning')
};
export function isMarkdownFile(document: vscode.TextDocument) {
return document.languageId === 'markdown'
&& document.uri.scheme !== 'markdown'; // prevent processing of own documents
}
export function getMarkdownUri(uri: vscode.Uri) {
if (uri.scheme === 'markdown') {
return uri;
}
return uri.with({
scheme: 'markdown',
path: uri.path + '.rendered',
query: uri.toString()
});
}
class MarkdownPreviewConfig {
public static getConfigForResource(resource: vscode.Uri) {
return new MarkdownPreviewConfig(resource);
}
public readonly scrollBeyondLastLine: boolean;
public readonly wordWrap: boolean;
public readonly previewFrontMatter: string;
public readonly lineBreaks: boolean;
public readonly doubleClickToSwitchToEditor: boolean;
public readonly scrollEditorWithPreview: boolean;
public readonly scrollPreviewWithEditorSelection: boolean;
public readonly markEditorSelection: boolean;
public readonly lineHeight: number;
public readonly fontSize: number;
public readonly fontFamily: string | undefined;
public readonly styles: string[];
private constructor(resource: vscode.Uri) {
const editorConfig = vscode.workspace.getConfiguration('editor', resource);
const markdownConfig = vscode.workspace.getConfiguration('markdown', resource);
const markdownEditorConfig = vscode.workspace.getConfiguration('[markdown]');
this.scrollBeyondLastLine = editorConfig.get<boolean>('scrollBeyondLastLine', false);
this.wordWrap = editorConfig.get<string>('wordWrap', 'off') !== 'off';
if (markdownEditorConfig && markdownEditorConfig['editor.wordWrap']) {
this.wordWrap = markdownEditorConfig['editor.wordWrap'] !== 'off';
}
this.previewFrontMatter = markdownConfig.get<string>('previewFrontMatter', 'hide');
this.scrollPreviewWithEditorSelection = !!markdownConfig.get<boolean>('preview.scrollPreviewWithEditorSelection', true);
this.scrollEditorWithPreview = !!markdownConfig.get<boolean>('preview.scrollEditorWithPreview', true);
this.lineBreaks = !!markdownConfig.get<boolean>('preview.breaks', false);
this.doubleClickToSwitchToEditor = !!markdownConfig.get<boolean>('preview.doubleClickToSwitchToEditor', true);
this.markEditorSelection = !!markdownConfig.get<boolean>('preview.markEditorSelection', true);
this.fontFamily = markdownConfig.get<string | undefined>('preview.fontFamily', undefined);
this.fontSize = Math.max(8, +markdownConfig.get<number>('preview.fontSize', NaN));
this.lineHeight = Math.max(0.6, +markdownConfig.get<number>('preview.lineHeight', NaN));
this.styles = markdownConfig.get<string[]>('styles', []);
}
public isEqualTo(otherConfig: MarkdownPreviewConfig) {
for (let key in this) {
if (this.hasOwnProperty(key) && key !== 'styles') {
if (this[key] !== otherConfig[key]) {
return false;
}
}
}
// Check styles
if (this.styles.length !== otherConfig.styles.length) {
return false;
}
for (let i = 0; i < this.styles.length; ++i) {
if (this.styles[i] !== otherConfig.styles[i]) {
return false;
}
}
return true;
}
[key: string]: any;
}
class PreviewConfigManager {
private previewConfigurationsForWorkspaces = new Map<string, MarkdownPreviewConfig>();
public loadAndCacheConfiguration(
resource: vscode.Uri
) {
const config = MarkdownPreviewConfig.getConfigForResource(resource);
this.previewConfigurationsForWorkspaces.set(this.getKey(resource), config);
return config;
}
public shouldUpdateConfiguration(
resource: vscode.Uri
): boolean {
const key = this.getKey(resource);
const currentConfig = this.previewConfigurationsForWorkspaces.get(key);
const newConfig = MarkdownPreviewConfig.getConfigForResource(resource);
return (!currentConfig || !currentConfig.isEqualTo(newConfig));
}
private getKey(
resource: vscode.Uri
): string {
const folder = vscode.workspace.getWorkspaceFolder(resource);
if (!folder) {
return '';
}
return folder.uri.toString();
}
}
export class MDDocumentContentProvider implements vscode.TextDocumentContentProvider {
private _onDidChange = new vscode.EventEmitter<vscode.Uri>();
private _waiting: boolean = false;
private previewConfigurations = new PreviewConfigManager();
private extraStyles: Array<vscode.Uri> = [];
private extraScripts: Array<vscode.Uri> = [];
constructor(
private engine: MarkdownEngine,
private context: vscode.ExtensionContext,
private cspArbiter: ContentSecurityPolicyArbiter,
private logger: Logger
) { }
public addScript(resource: vscode.Uri): void {
this.extraScripts.push(resource);
}
public addStyle(resource: vscode.Uri): void {
this.extraStyles.push(resource);
}
private getMediaPath(mediaFile: string): string {
return vscode.Uri.file(this.context.asAbsolutePath(path.join('media', mediaFile))).toString();
}
private fixHref(resource: vscode.Uri, href: string): string {
if (!href) {
return href;
}
// Use href if it is already an URL
const hrefUri = vscode.Uri.parse(href);
if (['file', 'http', 'https'].indexOf(hrefUri.scheme) >= 0) {
return hrefUri.toString();
}
// Use href as file URI if it is absolute
if (path.isAbsolute(href)) {
return vscode.Uri.file(href).toString();
}
// use a workspace relative path if there is a workspace
let root = vscode.workspace.getWorkspaceFolder(resource);
if (root) {
return vscode.Uri.file(path.join(root.uri.fsPath, href)).toString();
}
// otherwise look relative to the markdown file
return vscode.Uri.file(path.join(path.dirname(resource.fsPath), href)).toString();
}
private computeCustomStyleSheetIncludes(resource: vscode.Uri, config: MarkdownPreviewConfig): string {
if (config.styles && Array.isArray(config.styles)) {
return config.styles.map(style => {
return `<link rel="stylesheet" class="code-user-style" data-source="${style.replace(/"/g, '&quot;')}" href="${this.fixHref(resource, style)}" type="text/css" media="screen">`;
}).join('\n');
}
return '';
}
private getSettingsOverrideStyles(nonce: string, config: MarkdownPreviewConfig): string {
return `<style nonce="${nonce}">
body {
${config.fontFamily ? `font-family: ${config.fontFamily};` : ''}
${isNaN(config.fontSize) ? '' : `font-size: ${config.fontSize}px;`}
${isNaN(config.lineHeight) ? '' : `line-height: ${config.lineHeight};`}
}
</style>`;
}
private getStyles(resource: vscode.Uri, nonce: string, config: MarkdownPreviewConfig): string {
const baseStyles = [
this.getMediaPath('markdown.css'),
this.getMediaPath('tomorrow.css')
].concat(this.extraStyles.map(resource => resource.toString()));
return `${baseStyles.map(href => `<link rel="stylesheet" type="text/css" href="${href}">`).join('\n')}
${this.getSettingsOverrideStyles(nonce, config)}
${this.computeCustomStyleSheetIncludes(resource, config)}`;
}
private getScripts(nonce: string): string {
const scripts = [this.getMediaPath('main.js')].concat(this.extraScripts.map(resource => resource.toString()));
return scripts
.map(source => `<script async src="${source}" nonce="${nonce}" charset="UTF-8"></script>`)
.join('\n');
}
public async provideTextDocumentContent(uri: vscode.Uri): Promise<string> {
const sourceUri = vscode.Uri.parse(uri.query);
let initialLine: number | undefined = undefined;
const editor = vscode.window.activeTextEditor;
if (editor && editor.document.uri.toString() === sourceUri.toString()) {
initialLine = editor.selection.active.line;
}
const document = await vscode.workspace.openTextDocument(sourceUri);
const config = this.previewConfigurations.loadAndCacheConfiguration(sourceUri);
const initialData = {
previewUri: uri.toString(),
source: sourceUri.toString(),
line: initialLine,
scrollPreviewWithEditorSelection: config.scrollPreviewWithEditorSelection,
scrollEditorWithPreview: config.scrollEditorWithPreview,
doubleClickToSwitchToEditor: config.doubleClickToSwitchToEditor,
disableSecurityWarnings: this.cspArbiter.shouldDisableSecurityWarnings()
};
this.logger.log('provideTextDocumentContent', initialData);
// Content Security Policy
const nonce = new Date().getTime() + '' + new Date().getMilliseconds();
const csp = this.getCspForResource(sourceUri, nonce);
const body = await this.engine.render(sourceUri, config.previewFrontMatter === 'hide', document.getText());
return `<!DOCTYPE html>
<html>
<head>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8">
${csp}
<meta id="vscode-markdown-preview-data" data-settings="${JSON.stringify(initialData).replace(/"/g, '&quot;')}" data-strings="${JSON.stringify(previewStrings).replace(/"/g, '&quot;')}">
<script src="${this.getMediaPath('csp.js')}" nonce="${nonce}"></script>
<script src="${this.getMediaPath('loading.js')}" nonce="${nonce}"></script>
${this.getStyles(sourceUri, nonce, config)}
<base href="${document.uri.toString(true)}">
</head>
<body class="vscode-body ${config.scrollBeyondLastLine ? 'scrollBeyondLastLine' : ''} ${config.wordWrap ? 'wordWrap' : ''} ${config.markEditorSelection ? 'showEditorSelection' : ''}">
${body}
<div class="code-line" data-line="${document.lineCount}"></div>
${this.getScripts(nonce)}
</body>
</html>`;
}
public updateConfiguration() {
// update all generated md documents
for (const document of vscode.workspace.textDocuments) {
if (document.uri.scheme === 'markdown') {
const sourceUri = vscode.Uri.parse(document.uri.query);
if (this.previewConfigurations.shouldUpdateConfiguration(sourceUri)) {
this.update(document.uri);
}
}
}
}
get onDidChange(): vscode.Event<vscode.Uri> {
return this._onDidChange.event;
}
public update(uri: vscode.Uri) {
if (!this._waiting) {
this._waiting = true;
setTimeout(() => {
this._waiting = false;
this._onDidChange.fire(uri);
}, 300);
}
}
private getCspForResource(resource: vscode.Uri, nonce: string): string {
switch (this.cspArbiter.getSecurityLevelForResource(resource)) {
case MarkdownPreviewSecurityLevel.AllowInsecureContent:
return `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' http: https: data:; media-src 'self' http: https: data:; script-src 'nonce-${nonce}'; style-src 'self' 'unsafe-inline' http: https: data:; font-src 'self' http: https: data:;">`;
case MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent:
return '';
case MarkdownPreviewSecurityLevel.Strict:
default:
return `<meta http-equiv="Content-Security-Policy" content="default-src 'none'; img-src 'self' https: data:; media-src 'self' https: data:; script-src 'nonce-${nonce}'; style-src 'self' 'unsafe-inline' https: data:; font-src 'self' https: data:;">`;
}
}
}
@@ -42,6 +42,10 @@ export class MarkdownEngine {
this.md = (await import('markdown-it'))({
html: true,
highlight: (str: string, lang: string) => {
// Workaround for highlight not supporting tsx: https://github.com/isagalaev/highlight.js/issues/1155
if (lang && ['tsx', 'typescriptreact'].indexOf(lang.toLocaleLowerCase()) >= 0) {
lang = 'jsx';
}
if (lang && hljs.getLanguage(lang)) {
try {
return `<pre class="hljs"><code><div>${hljs.highlight(lang, str, true).value}</div></code></pre>`;
@@ -0,0 +1,86 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import * as path from 'path';
import { MDDocumentContentProvider } from './features/previewContentProvider';
import { MarkdownEngine } from './markdownEngine';
const resolveExtensionResources = (extension: vscode.Extension<any>, stylePath: string): vscode.Uri => {
const resource = vscode.Uri.parse(stylePath);
if (resource.scheme) {
return resource;
}
return vscode.Uri.file(path.join(extension.extensionPath, stylePath));
};
export function loadMarkdownExtensions(
contentProvider: MDDocumentContentProvider,
engine: MarkdownEngine
) {
for (const extension of vscode.extensions.all) {
const contributes = extension.packageJSON && extension.packageJSON.contributes;
if (!contributes) {
continue;
}
tryLoadPreviewStyles(contributes, contentProvider, extension);
tryLoadPreviewScripts(contributes, contentProvider, extension);
tryLoadMarkdownItPlugins(contributes, extension, engine);
}
}
function tryLoadMarkdownItPlugins(
contributes: any,
extension: vscode.Extension<any>,
engine: MarkdownEngine
) {
if (contributes['markdown.markdownItPlugins']) {
extension.activate().then(() => {
if (extension.exports && extension.exports.extendMarkdownIt) {
engine.addPlugin((md: any) => extension.exports.extendMarkdownIt(md));
}
});
}
}
function tryLoadPreviewScripts(
contributes: any,
contentProvider: MDDocumentContentProvider,
extension: vscode.Extension<any>
) {
const scripts = contributes['markdown.previewScripts'];
if (scripts && Array.isArray(scripts)) {
for (const script of scripts) {
try {
contentProvider.addScript(resolveExtensionResources(extension, script));
}
catch (e) {
// noop
}
}
}
}
function tryLoadPreviewStyles(
contributes: any,
contentProvider: MDDocumentContentProvider,
extension: vscode.Extension<any>
) {
const styles = contributes['markdown.previewStyles'];
if (styles && Array.isArray(styles)) {
for (const style of styles) {
try {
contentProvider.addStyle(resolveExtensionResources(extension, style));
}
catch (e) {
// noop
}
}
}
}
+31 -6
View File
@@ -6,7 +6,7 @@
import * as vscode from 'vscode';
import { getMarkdownUri, MDDocumentContentProvider } from './previewContentProvider';
import { getMarkdownUri, MDDocumentContentProvider } from './features/previewContentProvider';
import * as nls from 'vscode-nls';
@@ -24,14 +24,20 @@ export interface ContentSecurityPolicyArbiter {
setSecurityLevelForResource(resource: vscode.Uri, level: MarkdownPreviewSecurityLevel): Thenable<void>;
shouldAllowSvgsForResource(resource: vscode.Uri): void;
shouldDisableSecurityWarnings(): boolean;
setShouldDisableSecurityWarning(shouldShow: boolean): Thenable<void>;
}
export class ExtensionContentSecurityPolicyArbiter implements ContentSecurityPolicyArbiter {
private readonly old_trusted_workspace_key = 'trusted_preview_workspace:';
private readonly security_level_key = 'preview_security_level:';
private readonly should_disable_security_warning_key = 'preview_should_show_security_warning:';
constructor(
private globalState: vscode.Memento
private globalState: vscode.Memento,
private workspaceState: vscode.Memento
) { }
public getSecurityLevelForResource(resource: vscode.Uri): MarkdownPreviewSecurityLevel {
@@ -57,6 +63,14 @@ export class ExtensionContentSecurityPolicyArbiter implements ContentSecurityPol
return securityLevel === MarkdownPreviewSecurityLevel.AllowInsecureContent || securityLevel === MarkdownPreviewSecurityLevel.AllowScriptsAndAllContent;
}
public shouldDisableSecurityWarnings(): boolean {
return this.workspaceState.get<boolean>(this.should_disable_security_warning_key, false);
}
public setShouldDisableSecurityWarning(disabled: boolean): Thenable<void> {
return this.workspaceState.update(this.should_disable_security_warning_key, disabled);
}
private getRoot(resource: vscode.Uri): vscode.Uri {
if (vscode.workspace.workspaceFolders) {
const folderForResource = vscode.workspace.getWorkspaceFolder(resource);
@@ -82,7 +96,7 @@ export class PreviewSecuritySelector {
public async showSecutitySelectorForResource(resource: vscode.Uri): Promise<void> {
interface PreviewSecurityPickItem extends vscode.QuickPickItem {
type: 'moreinfo' | MarkdownPreviewSecurityLevel;
type: 'moreinfo' | 'toggle' | MarkdownPreviewSecurityLevel;
}
function markActiveWhen(when: boolean): string {
@@ -108,7 +122,13 @@ export class PreviewSecuritySelector {
type: 'moreinfo',
label: localize('moreInfo.title', 'More Information'),
description: ''
}
}, {
type: 'toggle',
label: this.cspArbiter.shouldDisableSecurityWarnings()
? localize('enableSecurityWarning.title', "Enable preview security warnings in this workspace")
: localize('disableSecurityWarning.title', "Disable preview security warning in this workspace"),
description: localize('toggleSecurityWarning.description', 'Does not effect the content security level')
},
], {
placeHolder: localize(
'preview.showPreviewSecuritySelector.title',
@@ -124,9 +144,14 @@ export class PreviewSecuritySelector {
return;
}
await this.cspArbiter.setSecurityLevelForResource(resource, selection.type);
const sourceUri = getMarkdownUri(resource);
if (selection.type === 'toggle') {
this.cspArbiter.setShouldDisableSecurityWarning(!this.cspArbiter.shouldDisableSecurityWarnings());
this.contentProvider.update(sourceUri);
return;
}
await this.cspArbiter.setSecurityLevelForResource(resource, selection.type);
await vscode.commands.executeCommand('_workbench.htmlPreview.updateOptions',
sourceUri,
@@ -0,0 +1,60 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { default as VSCodeTelemetryReporter } from 'vscode-extension-telemetry';
interface IPackageInfo {
name: string;
version: string;
aiKey: string;
}
export interface TelemetryReporter {
dispose(): void;
sendTelemetryEvent(eventName: string, properties?: {
[key: string]: string;
}): void;
}
const nullReporter = new class NullTelemetryReporter implements TelemetryReporter {
sendTelemetryEvent() { /** noop */ }
dispose() { /** noop */ }
};
class ExtensionReporter implements TelemetryReporter {
private readonly _reporter: VSCodeTelemetryReporter;
constructor(
packageInfo: IPackageInfo
) {
this._reporter = new VSCodeTelemetryReporter(packageInfo.name, packageInfo.version, packageInfo.aiKey);
}
sendTelemetryEvent(eventName: string, properties?: {
[key: string]: string;
}) {
this._reporter.sendTelemetryEvent(eventName, properties);
}
dispose() {
this._reporter.dispose();
}
}
export function loadDefaultTelemetryReporter(): TelemetryReporter {
const packageInfo = getPackageInfo();
return packageInfo ? new ExtensionReporter(packageInfo) : nullReporter;
}
function getPackageInfo(): IPackageInfo | null {
const extention = vscode.extensions.getExtension('Microsoft.vscode-markdown');
if (extention && extention.packageJSON) {
return {
name: extention.packageJSON.name,
version: extention.packageJSON.version,
aiKey: extention.packageJSON.aiKey
};
}
return null;
}
@@ -478,7 +478,7 @@
<key>list_paragraph</key>
<dict>
<key>begin</key>
<string>(^|\G)(?=\S)(?![*+-]\s|[0-9]+\.\s)</string>
<string>(^|\G)(?=\S)(?![*+-&gt;]\s|[0-9]+\.\s)</string>
<key>name</key>
<string>meta.paragraph.markdown</string>
<key>patterns</key>
@@ -497,7 +497,7 @@
</dict>
</array>
<key>while</key>
<string>(^|\G)(?!\s*$|#|[ ]{0,3}([-*_][ ]{2,}){3,}[ \t]*$\n?|&gt;|[ ]{0,3}[*+-]|[ ]{0,3}[0-9]+\.)</string>
<string>(^|\G)(?!\s*$|#|[ ]{0,3}([-*_&gt;][ ]{2,}){3,}[ \t]*$\n?|[ ]{0,3}[*+-&gt;]|[ ]{0,3}[0-9]+\.)</string>
</dict>
<key>lists</key>
<dict>
@@ -3191,11 +3191,16 @@
<key>name</key>
<string>punctuation.definition.string.begin.markdown</string>
</dict>
<key>10</key>
<key>9</key>
<dict>
<key>name</key>
<string>string.other.link.description.title.markdown</string>
</dict>
<key>10</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.markdown</string>
</dict>
<key>11</key>
<dict>
<key>name</key>
@@ -3204,12 +3209,12 @@
<key>12</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.markdown</string>
<string>string.other.link.description.title.markdown</string>
</dict>
<key>13</key>
<dict>
<key>name</key>
<string>string.other.link.description.title.markdown</string>
<string>punctuation.definition.string.markdown</string>
</dict>
<key>14</key>
<dict>
@@ -3217,11 +3222,6 @@
<string>punctuation.definition.string.markdown</string>
</dict>
<key>15</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.markdown</string>
</dict>
<key>16</key>
<dict>
<key>name</key>
<string>punctuation.definition.metadata.markdown</string>
@@ -3239,24 +3239,19 @@
<key>5</key>
<dict>
<key>name</key>
<string>invalid.illegal.whitespace.markdown</string>
<string>punctuation.definition.metadata.markdown</string>
</dict>
<key>6</key>
<dict>
<key>name</key>
<string>punctuation.definition.metadata.markdown</string>
<string>punctuation.definition.link.markdown</string>
</dict>
<key>7</key>
<dict>
<key>name</key>
<string>punctuation.definition.link.markdown</string>
</dict>
<key>8</key>
<dict>
<key>name</key>
<string>markup.underline.link.image.markdown</string>
</dict>
<key>9</key>
<key>8</key>
<dict>
<key>name</key>
<string>punctuation.definition.link.markdown</string>
@@ -3266,7 +3261,6 @@
<string>(?x:
(\!\[)((?&lt;square&gt;[^\[\]\\]|\\.|\[\g&lt;square&gt;*+\])*+)(\])
# Match the link text.
([ ])? # Space not allowed
(\() # Opening paren for url
(&lt;?)(\S+?)(&gt;?) # The url
[ \t]* # Optional whitespace
@@ -3503,37 +3497,37 @@
<key>name</key>
<string>punctuation.definition.string.begin.markdown</string>
</dict>
<key>10</key>
<key>9</key>
<dict>
<key>name</key>
<string>string.other.link.description.title.markdown</string>
</dict>
<key>10</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.markdown</string>
</dict>
<key>11</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.markdown</string>
<string>punctuation.definition.string.end.markdown</string>
</dict>
<key>12</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.markdown</string>
<string>string.other.link.description.title.markdown</string>
</dict>
<key>13</key>
<dict>
<key>name</key>
<string>string.other.link.description.title.markdown</string>
<string>punctuation.definition.string.begin.markdown</string>
</dict>
<key>14</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.markdown</string>
</dict>
<key>15</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.markdown</string>
</dict>
<key>16</key>
<key>15</key>
<dict>
<key>name</key>
<string>punctuation.definition.metadata.markdown</string>
@@ -3551,24 +3545,19 @@
<key>5</key>
<dict>
<key>name</key>
<string>invalid.illegal.whitespace.markdown</string>
<string>punctuation.definition.metadata.markdown</string>
</dict>
<key>6</key>
<dict>
<key>name</key>
<string>punctuation.definition.metadata.markdown</string>
<string>punctuation.definition.link.markdown</string>
</dict>
<key>7</key>
<dict>
<key>name</key>
<string>punctuation.definition.link.markdown</string>
</dict>
<key>8</key>
<dict>
<key>name</key>
<string>markup.underline.link.markdown</string>
</dict>
<key>9</key>
<key>8</key>
<dict>
<key>name</key>
<string>punctuation.definition.link.markdown</string>
@@ -3578,7 +3567,6 @@
<string>(?x:
(\[)((?&lt;square&gt;[^\[\]\\]|\\.|\[\g&lt;square&gt;*+\])*+)(\])
# Match the link text.
([ ])? # Space not allowed
(\() # Opening paren for url
(&lt;?)(.*?)(&gt;?) # The url
[ \t]* # Optional whitespace
@@ -303,7 +303,7 @@
<key>list_paragraph</key>
<dict>
<key>begin</key>
<string>(^|\G)(?=\S)(?![*+-]\s|[0-9]+\.\s)</string>
<string>(^|\G)(?=\S)(?![*+-&gt;]\s|[0-9]+\.\s)</string>
<key>name</key>
<string>meta.paragraph.markdown</string>
<key>patterns</key>
@@ -322,7 +322,7 @@
</dict>
</array>
<key>while</key>
<string>(^|\G)(?!\s*$|#|[ ]{0,3}([-*_][ ]{2,}){3,}[ \t]*$\n?|&gt;|[ ]{0,3}[*+-]|[ ]{0,3}[0-9]+\.)</string>
<string>(^|\G)(?!\s*$|#|[ ]{0,3}([-*_&gt;][ ]{2,}){3,}[ \t]*$\n?|[ ]{0,3}[*+-&gt;]|[ ]{0,3}[0-9]+\.)</string>
</dict>
<key>lists</key>
<dict>
@@ -681,11 +681,16 @@
<key>name</key>
<string>punctuation.definition.string.begin.markdown</string>
</dict>
<key>10</key>
<key>9</key>
<dict>
<key>name</key>
<string>string.other.link.description.title.markdown</string>
</dict>
<key>10</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.markdown</string>
</dict>
<key>11</key>
<dict>
<key>name</key>
@@ -694,12 +699,12 @@
<key>12</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.markdown</string>
<string>string.other.link.description.title.markdown</string>
</dict>
<key>13</key>
<dict>
<key>name</key>
<string>string.other.link.description.title.markdown</string>
<string>punctuation.definition.string.markdown</string>
</dict>
<key>14</key>
<dict>
@@ -707,11 +712,6 @@
<string>punctuation.definition.string.markdown</string>
</dict>
<key>15</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.markdown</string>
</dict>
<key>16</key>
<dict>
<key>name</key>
<string>punctuation.definition.metadata.markdown</string>
@@ -729,24 +729,19 @@
<key>5</key>
<dict>
<key>name</key>
<string>invalid.illegal.whitespace.markdown</string>
<string>punctuation.definition.metadata.markdown</string>
</dict>
<key>6</key>
<dict>
<key>name</key>
<string>punctuation.definition.metadata.markdown</string>
<string>punctuation.definition.link.markdown</string>
</dict>
<key>7</key>
<dict>
<key>name</key>
<string>punctuation.definition.link.markdown</string>
</dict>
<key>8</key>
<dict>
<key>name</key>
<string>markup.underline.link.image.markdown</string>
</dict>
<key>9</key>
<key>8</key>
<dict>
<key>name</key>
<string>punctuation.definition.link.markdown</string>
@@ -756,7 +751,6 @@
<string>(?x:
(\!\[)((?&lt;square&gt;[^\[\]\\]|\\.|\[\g&lt;square&gt;*+\])*+)(\])
# Match the link text.
([ ])? # Space not allowed
(\() # Opening paren for url
(&lt;?)(\S+?)(&gt;?) # The url
[ \t]* # Optional whitespace
@@ -993,37 +987,37 @@
<key>name</key>
<string>punctuation.definition.string.begin.markdown</string>
</dict>
<key>10</key>
<key>9</key>
<dict>
<key>name</key>
<string>string.other.link.description.title.markdown</string>
</dict>
<key>10</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.markdown</string>
</dict>
<key>11</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.markdown</string>
<string>punctuation.definition.string.end.markdown</string>
</dict>
<key>12</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.markdown</string>
<string>string.other.link.description.title.markdown</string>
</dict>
<key>13</key>
<dict>
<key>name</key>
<string>string.other.link.description.title.markdown</string>
<string>punctuation.definition.string.begin.markdown</string>
</dict>
<key>14</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.begin.markdown</string>
</dict>
<key>15</key>
<dict>
<key>name</key>
<string>punctuation.definition.string.end.markdown</string>
</dict>
<key>16</key>
<key>15</key>
<dict>
<key>name</key>
<string>punctuation.definition.metadata.markdown</string>
@@ -1041,24 +1035,19 @@
<key>5</key>
<dict>
<key>name</key>
<string>invalid.illegal.whitespace.markdown</string>
<string>punctuation.definition.metadata.markdown</string>
</dict>
<key>6</key>
<dict>
<key>name</key>
<string>punctuation.definition.metadata.markdown</string>
<string>punctuation.definition.link.markdown</string>
</dict>
<key>7</key>
<dict>
<key>name</key>
<string>punctuation.definition.link.markdown</string>
</dict>
<key>8</key>
<dict>
<key>name</key>
<string>markup.underline.link.markdown</string>
</dict>
<key>9</key>
<key>8</key>
<dict>
<key>name</key>
<string>punctuation.definition.link.markdown</string>
@@ -1068,7 +1057,6 @@
<string>(?x:
(\[)((?&lt;square&gt;[^\[\]\\]|\\.|\[\g&lt;square&gt;*+\])*+)(\])
# Match the link text.
([ ])? # Space not allowed
(\() # Opening paren for url
(&lt;?)(.*?)(&gt;?) # The url
[ \t]* # Optional whitespace
@@ -47,6 +47,7 @@ in_words_are ignored.
>> And, they can be nested
1. A numbered list
> Block quotes in list
2. Which is numbered
3. With periods and a space
@@ -1792,6 +1792,50 @@
"hc_black": "default: #FFFFFF"
}
},
{
"c": " ",
"t": "text.html.markdown markup.list.numbered.markdown",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": ">",
"t": "text.html.markdown markup.list.numbered.markdown markup.quote.markdown beginning.punctuation.definition.quote.markdown",
"r": {
"dark_plus": "beginning.punctuation.definition.quote.markdown: #608B4E",
"light_plus": "beginning.punctuation.definition.quote.markdown: #0451A5",
"dark_vs": "beginning.punctuation.definition.quote.markdown: #608B4E",
"light_vs": "beginning.punctuation.definition.quote.markdown: #0451A5",
"hc_black": "default: #FFFFFF"
}
},
{
"c": " ",
"t": "text.html.markdown markup.list.numbered.markdown markup.quote.markdown",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "Block quotes in list",
"t": "text.html.markdown markup.list.numbered.markdown markup.quote.markdown meta.paragraph.markdown",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": "2.",
"t": "text.html.markdown markup.list.numbered.markdown beginning.punctuation.definition.list.markdown",
+3 -3
View File
@@ -1,7 +1,7 @@
{
"compilerOptions": {
"module": "commonjs",
"target": "es5",
"target": "es2017",
"lib": [
"es6",
"es2015.promise",
@@ -9,11 +9,11 @@
],
"outDir": "./out",
"sourceMap": true,
"strictNullChecks": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true
"noUnusedParameters": true,
"strict": true
},
"include": [
"src/**/*"
+171
View File
@@ -0,0 +1,171 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/highlight.js@9.1.10":
version "9.1.10"
resolved "https://registry.yarnpkg.com/@types/highlight.js/-/highlight.js-9.1.10.tgz#b621f809cd9573b80992b90cffc5788208e3069c"
"@types/markdown-it@0.0.2":
version "0.0.2"
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.2.tgz#5d9ad19e6e6508cdd2f2596df86fd0aade598660"
"@types/node@7.0.43":
version "7.0.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-7.0.43.tgz#a187e08495a075f200ca946079c914e1a5fe962c"
applicationinsights@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-0.18.0.tgz#162ebb48a383408bc4de44db32b417307f45bbc1"
argparse@^1.0.7:
version "1.0.9"
resolved "https://registry.yarnpkg.com/argparse/-/argparse-1.0.9.tgz#73d83bc263f86e97f8cc4f6bae1b0e90a7d22c86"
dependencies:
sprintf-js "~1.0.2"
binaryextensions@~1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/binaryextensions/-/binaryextensions-1.0.1.tgz#1e637488b35b58bda5f4774bf96a5212a8c90755"
core-util-is@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/core-util-is/-/core-util-is-1.0.2.tgz#b5fd54220aa2bc5ab57aab7140c940754503c1a7"
entities@~1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/entities/-/entities-1.1.1.tgz#6e5c2d0a5621b5dadaecef80b90edfb5cd7772f0"
escape-string-regexp@^1.0.3:
version "1.0.5"
resolved "https://registry.yarnpkg.com/escape-string-regexp/-/escape-string-regexp-1.0.5.tgz#1b61c0562190a8dff6ae3bb2cf0200ca130b86d4"
gulp-rename@^1.2.2:
version "1.2.2"
resolved "https://registry.yarnpkg.com/gulp-rename/-/gulp-rename-1.2.2.tgz#3ad4428763f05e2764dec1c67d868db275687817"
gulp-replace@^0.5.4:
version "0.5.4"
resolved "https://registry.yarnpkg.com/gulp-replace/-/gulp-replace-0.5.4.tgz#69a67914bbd13c562bff14f504a403796aa0daa9"
dependencies:
istextorbinary "1.0.2"
readable-stream "^2.0.1"
replacestream "^4.0.0"
highlight.js@9.5.0:
version "9.5.0"
resolved "https://registry.yarnpkg.com/highlight.js/-/highlight.js-9.5.0.tgz#46ae51b9db00f70052bcdf196cd404757b6582ae"
inherits@~2.0.3:
version "2.0.3"
resolved "https://registry.yarnpkg.com/inherits/-/inherits-2.0.3.tgz#633c2c83e3da42a502f52466022480f4208261de"
isarray@~1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/isarray/-/isarray-1.0.0.tgz#bb935d48582cba168c06834957a54a3e07124f11"
istextorbinary@1.0.2:
version "1.0.2"
resolved "https://registry.yarnpkg.com/istextorbinary/-/istextorbinary-1.0.2.tgz#ace19354d1a9a0173efeb1084ce0f87b0ad7decf"
dependencies:
binaryextensions "~1.0.0"
textextensions "~1.0.0"
linkify-it@^2.0.0:
version "2.0.3"
resolved "https://registry.yarnpkg.com/linkify-it/-/linkify-it-2.0.3.tgz#d94a4648f9b1c179d64fa97291268bdb6ce9434f"
dependencies:
uc.micro "^1.0.1"
markdown-it-named-headers@0.0.4:
version "0.0.4"
resolved "https://registry.yarnpkg.com/markdown-it-named-headers/-/markdown-it-named-headers-0.0.4.tgz#82efc28324240a6b1e77b9aae501771d5f351c1f"
dependencies:
string "^3.0.1"
markdown-it@^8.4.0:
version "8.4.0"
resolved "https://registry.yarnpkg.com/markdown-it/-/markdown-it-8.4.0.tgz#e2400881bf171f7018ed1bd9da441dac8af6306d"
dependencies:
argparse "^1.0.7"
entities "~1.1.1"
linkify-it "^2.0.0"
mdurl "^1.0.1"
uc.micro "^1.0.3"
mdurl@^1.0.1:
version "1.0.1"
resolved "https://registry.yarnpkg.com/mdurl/-/mdurl-1.0.1.tgz#fe85b2ec75a59037f2adfec100fd6c601761152e"
object-assign@^4.0.1:
version "4.1.1"
resolved "https://registry.yarnpkg.com/object-assign/-/object-assign-4.1.1.tgz#2109adc7965887cfc05cbbd442cac8bfbb360863"
process-nextick-args@~1.0.6:
version "1.0.7"
resolved "https://registry.yarnpkg.com/process-nextick-args/-/process-nextick-args-1.0.7.tgz#150e20b756590ad3f91093f25a4f2ad8bff30ba3"
readable-stream@^2.0.1, readable-stream@^2.0.2:
version "2.3.3"
resolved "https://registry.yarnpkg.com/readable-stream/-/readable-stream-2.3.3.tgz#368f2512d79f9d46fdfc71349ae7878bbc1eb95c"
dependencies:
core-util-is "~1.0.0"
inherits "~2.0.3"
isarray "~1.0.0"
process-nextick-args "~1.0.6"
safe-buffer "~5.1.1"
string_decoder "~1.0.3"
util-deprecate "~1.0.1"
replacestream@^4.0.0:
version "4.0.2"
resolved "https://registry.yarnpkg.com/replacestream/-/replacestream-4.0.2.tgz#0c4140707e4f0323f50de044851708cf58bc37bd"
dependencies:
escape-string-regexp "^1.0.3"
object-assign "^4.0.1"
readable-stream "^2.0.2"
safe-buffer@~5.1.0, safe-buffer@~5.1.1:
version "5.1.1"
resolved "https://registry.yarnpkg.com/safe-buffer/-/safe-buffer-5.1.1.tgz#893312af69b2123def71f57889001671eeb2c853"
sprintf-js@~1.0.2:
version "1.0.3"
resolved "https://registry.yarnpkg.com/sprintf-js/-/sprintf-js-1.0.3.tgz#04e6926f662895354f3dd015203633b857297e2c"
string@^3.0.1:
version "3.3.1"
resolved "https://registry.yarnpkg.com/string/-/string-3.3.1.tgz#8d2757ec1c0e6c526796fbb6b14036a4098398b7"
string_decoder@~1.0.3:
version "1.0.3"
resolved "https://registry.yarnpkg.com/string_decoder/-/string_decoder-1.0.3.tgz#0fc67d7c141825de94282dd536bec6b9bce860ab"
dependencies:
safe-buffer "~5.1.0"
textextensions@~1.0.0:
version "1.0.2"
resolved "https://registry.yarnpkg.com/textextensions/-/textextensions-1.0.2.tgz#65486393ee1f2bb039a60cbba05b0b68bd9501d2"
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"
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:
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:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"
winreg@1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.3.tgz#93ad116b2696da87d58f7265a8fcea5254a965d5"
+5
View File
@@ -21,6 +21,11 @@
},
"contributes": {
"commands": [
{
"category": "%command.category%",
"title": "%command.accept.all-current%",
"command": "merge-conflict.accept.all-current"
},
{
"category": "%command.category%",
"title": "%command.accept.all-incoming%",
@@ -1,5 +1,6 @@
{
"command.category": "Merge Conflict",
"command.accept.all-current": "Accept All Current",
"command.accept.all-incoming": "Accept All Incoming",
"command.accept.all-both": "Accept All Both",
"command.accept.current": "Accept Current",
@@ -13,7 +13,7 @@ export default class MergeConflictCodeLensProvider implements vscode.CodeLensPro
private config: interfaces.IExtensionConfiguration;
private tracker: interfaces.IDocumentMergeConflictTracker;
constructor(private context: vscode.ExtensionContext, trackerService: interfaces.IDocumentMergeConflictTrackerService) {
constructor(trackerService: interfaces.IDocumentMergeConflictTrackerService) {
this.tracker = trackerService.createTracker('codelens');
}
@@ -46,7 +46,7 @@ export default class MergeConflictCodeLensProvider implements vscode.CodeLensPro
}
}
async provideCodeLenses(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.CodeLens[] | null> {
async provideCodeLenses(document: vscode.TextDocument, _token: vscode.CancellationToken): Promise<vscode.CodeLens[] | null> {
if (!this.config || !this.config.enableCodeLens) {
return null;
+14 -14
View File
@@ -24,7 +24,7 @@ export default class CommandHandler implements vscode.Disposable {
private disposables: vscode.Disposable[] = [];
private tracker: interfaces.IDocumentMergeConflictTracker;
constructor(private context: vscode.ExtensionContext, trackerService: interfaces.IDocumentMergeConflictTrackerService) {
constructor(trackerService: interfaces.IDocumentMergeConflictTrackerService) {
this.tracker = trackerService.createTracker('commands');
}
@@ -43,38 +43,38 @@ export default class CommandHandler implements vscode.Disposable {
);
}
private registerTextEditorCommand(command: string, cb: (editor: vscode.TextEditor, ...args) => Promise<void>) {
private registerTextEditorCommand(command: string, cb: (editor: vscode.TextEditor, ...args: any[]) => Promise<void>) {
return vscode.commands.registerCommand(command, (...args) => {
const editor = vscode.window.activeTextEditor;
return editor && cb.call(this, editor, ...args);
});
}
acceptCurrent(editor: vscode.TextEditor, ...args): Promise<void> {
acceptCurrent(editor: vscode.TextEditor, ...args: any[]): Promise<void> {
return this.accept(interfaces.CommitType.Current, editor, ...args);
}
acceptIncoming(editor: vscode.TextEditor, ...args): Promise<void> {
acceptIncoming(editor: vscode.TextEditor, ...args: any[]): Promise<void> {
return this.accept(interfaces.CommitType.Incoming, editor, ...args);
}
acceptBoth(editor: vscode.TextEditor, ...args): Promise<void> {
acceptBoth(editor: vscode.TextEditor, ...args: any[]): Promise<void> {
return this.accept(interfaces.CommitType.Both, editor, ...args);
}
acceptAllCurrent(editor: vscode.TextEditor, ...args): Promise<void> {
acceptAllCurrent(editor: vscode.TextEditor): Promise<void> {
return this.acceptAll(interfaces.CommitType.Current, editor);
}
acceptAllIncoming(editor: vscode.TextEditor, ...args): Promise<void> {
acceptAllIncoming(editor: vscode.TextEditor): Promise<void> {
return this.acceptAll(interfaces.CommitType.Incoming, editor);
}
acceptAllBoth(editor: vscode.TextEditor, ...args): Promise<void> {
acceptAllBoth(editor: vscode.TextEditor): Promise<void> {
return this.acceptAll(interfaces.CommitType.Both, editor);
}
async compare(editor: vscode.TextEditor, conflict: interfaces.IDocumentMergeConflict | null, ...args) {
async compare(editor: vscode.TextEditor, conflict: interfaces.IDocumentMergeConflict | null) {
const fileName = path.basename(editor.document.uri.fsPath);
// No conflict, command executed from command palette
@@ -102,15 +102,15 @@ export default class CommandHandler implements vscode.Disposable {
vscode.commands.executeCommand('vscode.diff', leftUri, rightUri, title);
}
navigateNext(editor: vscode.TextEditor, ...args): Promise<void> {
navigateNext(editor: vscode.TextEditor): Promise<void> {
return this.navigate(editor, NavigationDirection.Forwards);
}
navigatePrevious(editor: vscode.TextEditor, ...args): Promise<void> {
navigatePrevious(editor: vscode.TextEditor): Promise<void> {
return this.navigate(editor, NavigationDirection.Backwards);
}
async acceptSelection(editor: vscode.TextEditor, ...args): Promise<void> {
async acceptSelection(editor: vscode.TextEditor): Promise<void> {
let conflict = await this.findConflictContainingSelection(editor);
if (!conflict) {
@@ -175,7 +175,7 @@ export default class CommandHandler implements vscode.Disposable {
editor.revealRange(navigationResult.conflict.range, vscode.TextEditorRevealType.Default);
}
private async accept(type: interfaces.CommitType, editor: vscode.TextEditor, ...args): Promise<void> {
private async accept(type: interfaces.CommitType, editor: vscode.TextEditor, ...args: any[]): Promise<void> {
let conflict: interfaces.IDocumentMergeConflict | null;
@@ -257,7 +257,7 @@ export default class CommandHandler implements vscode.Disposable {
};
}
let predicate: (conflict) => boolean;
let predicate: (_conflict: any) => boolean;
let fallback: () => interfaces.IDocumentMergeConflict;
if (direction === NavigationDirection.Forwards) {
@@ -4,7 +4,6 @@
*--------------------------------------------------------------------------------------------*/
'use strict';
import * as vscode from 'vscode';
import * as interfaces from './interfaces';
export default class MergeConflictContentProvider implements vscode.TextDocumentContentProvider, vscode.Disposable {
@@ -13,7 +12,7 @@ export default class MergeConflictContentProvider implements vscode.TextDocument
constructor(private context: vscode.ExtensionContext) {
}
begin(config: interfaces.IExtensionConfiguration) {
begin() {
this.context.subscriptions.push(
vscode.workspace.registerTextDocumentContentProvider(MergeConflictContentProvider.scheme, this)
);
+3 -3
View File
@@ -13,7 +13,7 @@ export class Delayer<T> {
public defaultDelay: number;
private timeout: any; // Timer
private completionPromise: Promise<T> | null;
private onSuccess: ((value?: T | Thenable<T> | null) => void) | null;
private onSuccess: ((value?: T | Thenable<T> | undefined) => void) | null;
private task: ITask<T> | null;
constructor(defaultDelay: number) {
@@ -45,7 +45,7 @@ export class Delayer<T> {
if (delay >= 0 || this.timeout === null) {
this.timeout = setTimeout(() => {
this.timeout = null;
this.onSuccess!(null);
this.onSuccess!(undefined);
}, delay >= 0 ? delay : this.defaultDelay);
}
@@ -58,7 +58,7 @@ export class Delayer<T> {
}
this.cancelTimeout();
let result = this.completionPromise;
this.onSuccess!(null);
this.onSuccess!(undefined);
return result;
}
@@ -13,7 +13,7 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict
public commonAncestors: interfaces.IMergeRegion[];
public splitter: vscode.Range;
constructor(document: vscode.TextDocument, descriptor: interfaces.IDocumentMergeConflictDescriptor) {
constructor(descriptor: interfaces.IDocumentMergeConflictDescriptor) {
this.range = descriptor.range;
this.current = descriptor.current;
this.incoming = descriptor.incoming;
@@ -27,7 +27,7 @@ export class DocumentMergeConflict implements interfaces.IDocumentMergeConflict
this.applyEdit(type, editor, edit);
return Promise.resolve(true);
};
}
return editor.edit((edit) => this.applyEdit(type, editor, edit));
}
@@ -116,7 +116,7 @@ export default class DocumentMergeConflictTracker implements vscode.Disposable,
this.cache.clear();
}
private getConflictsOrEmpty(document: vscode.TextDocument, origins: string[]): interfaces.IDocumentMergeConflict[] {
private getConflictsOrEmpty(document: vscode.TextDocument, _origins: string[]): interfaces.IDocumentMergeConflict[] {
const containsConflict = MergeConflictParser.containsConflict(document);
if (!containsConflict) {
+4 -4
View File
@@ -24,8 +24,8 @@ export interface IExtensionConfiguration {
}
export interface IDocumentMergeConflict extends IDocumentMergeConflictDescriptor {
commitEdit(type: CommitType, editor: vscode.TextEditor, edit?: vscode.TextEditorEdit);
applyEdit(type: CommitType, editor: vscode.TextEditor, edit: vscode.TextEditorEdit);
commitEdit(type: CommitType, editor: vscode.TextEditor, edit?: vscode.TextEditorEdit): Thenable<boolean>;
applyEdit(type: CommitType, editor: vscode.TextEditor, edit: vscode.TextEditorEdit): void;
}
export interface IDocumentMergeConflictDescriptor {
@@ -39,10 +39,10 @@ export interface IDocumentMergeConflictDescriptor {
export interface IDocumentMergeConflictTracker {
getConflicts(document: vscode.TextDocument): PromiseLike<IDocumentMergeConflict[]>;
isPending(document: vscode.TextDocument): boolean;
forget(document: vscode.TextDocument);
forget(document: vscode.TextDocument): void;
}
export interface IDocumentMergeConflictTrackerService {
createTracker(origin: string): IDocumentMergeConflictTracker;
forget(document: vscode.TextDocument);
forget(document: vscode.TextDocument): void;
}
@@ -81,7 +81,7 @@ export class MergeConflictParser {
return conflictDescriptors
.filter(Boolean)
.map(descriptor => new DocumentMergeConflict(document, descriptor));
.map(descriptor => new DocumentMergeConflict(descriptor));
}
private static scanItemTolMergeConflictDescriptor(document: vscode.TextDocument, scanned: IScanMergedConflict): interfaces.IDocumentMergeConflictDescriptor | null {
+2 -2
View File
@@ -26,8 +26,8 @@ export default class ServiceWrapper implements vscode.Disposable {
this.services.push(
documentTracker,
new CommandHandler(this.context, documentTracker),
new CodeLensProvider(this.context, documentTracker),
new CommandHandler(documentTracker),
new CodeLensProvider(documentTracker),
new ContentProvider(this.context),
new Decorator(this.context, documentTracker),
);
+5 -1
View File
@@ -6,7 +6,11 @@
],
"module": "commonjs",
"outDir": "./out",
"strictNullChecks": true,
"noImplicitAny": true,
"noImplicitReturns": true,
"noUnusedLocals": true,
"noUnusedParameters": true,
"strict": true,
"experimentalDecorators": true
},
"include": [
+26
View File
@@ -0,0 +1,26 @@
# THIS IS AN AUTOGENERATED FILE. DO NOT EDIT THIS FILE DIRECTLY.
# yarn lockfile v1
"@types/node@8.0.33":
version "8.0.33"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.33.tgz#1126e94374014e54478092830704f6ea89df04cd"
applicationinsights@0.18.0:
version "0.18.0"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-0.18.0.tgz#162ebb48a383408bc4de44db32b417307f45bbc1"
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:
version "2.0.2"
resolved "https://registry.yarnpkg.com/vscode-nls/-/vscode-nls-2.0.2.tgz#808522380844b8ad153499af5c3b03921aea02da"
winreg@1.2.3:
version "1.2.3"
resolved "https://registry.yarnpkg.com/winreg/-/winreg-1.2.3.tgz#93ad116b2696da87d58f7265a8fcea5254a965d5"
+15 -128
View File
@@ -1,129 +1,16 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[
{
"name": "agent-base",
"repositoryURL": "https://github.com/TooTallNate/node-agent-base",
"version": "1.0.2",
[{
"isLicense": true,
"name": "@types/source-map",
"repositoryURL": "https://www.github.com/DefinitelyTyped/DefinitelyTyped",
"license": "MIT",
"isProd": true
},
{
"name": "balanced-match",
"repositoryURL": "https://github.com/juliangruber/balanced-match",
"version": "1.0.0",
"license": "MIT",
"isProd": true
},
{
"name": "brace-expansion",
"repositoryURL": "https://github.com/juliangruber/brace-expansion",
"version": "1.1.8",
"license": "MIT",
"isProd": true
},
{
"name": "concat-map",
"repositoryURL": "https://github.com/substack/node-concat-map",
"version": "0.0.1",
"license": "MIT",
"isProd": true
},
{
"name": "debug",
"repositoryURL": "https://github.com/visionmedia/debug",
"version": "2.6.8",
"license": "MIT",
"isProd": true
},
{
"name": "extend",
"repositoryURL": "https://github.com/justmoon/node-extend",
"version": "3.0.1",
"license": "MIT",
"isProd": true
},
{
"name": "fs.realpath",
"repositoryURL": "https://github.com/isaacs/fs.realpath",
"version": "1.0.0",
"license": "ISC",
"isProd": true
},
{
"name": "glob",
"repositoryURL": "https://github.com/isaacs/node-glob",
"version": "7.1.2",
"license": "ISC",
"isProd": true
},
{
"name": "http-proxy-agent",
"repositoryURL": "https://github.com/TooTallNate/node-http-proxy-agent",
"version": "0.2.7",
"license": "MIT",
"isProd": true
},
{
"name": "https-proxy-agent",
"repositoryURL": "https://github.com/TooTallNate/node-https-proxy-agent",
"version": "0.3.6",
"license": "MIT",
"isProd": true
},
{
"name": "inflight",
"repositoryURL": "https://github.com/npm/inflight",
"version": "1.0.6",
"license": "ISC",
"isProd": true
},
{
"name": "inherits",
"repositoryURL": "https://github.com/isaacs/inherits",
"version": "2.0.3",
"license": "ISC",
"isProd": true
},
{
"name": "minimatch",
"repositoryURL": "https://github.com/isaacs/minimatch",
"version": "3.0.4",
"license": "ISC",
"isProd": true
},
{
"name": "ms",
"repositoryURL": "https://github.com/rauchg/ms.js",
"version": "2.0.0",
"license": "MIT",
"isProd": true
},
{
"name": "once",
"repositoryURL": "https://github.com/isaacs/once",
"version": "1.4.0",
"license": "ISC",
"isProd": true
},
{
"name": "path-is-absolute",
"repositoryURL": "https://github.com/sindresorhus/path-is-absolute",
"version": "1.0.1",
"license": "MIT",
"isProd": true
},
{
"name": "source-map",
"repositoryURL": "https://github.com/mozilla/source-map",
"version": "0.5.6",
"license": "BSD-3-Clause",
"isProd": true
},
{
"name": "wrappy",
"repositoryURL": "https://github.com/npm/wrappy",
"version": "1.0.2",
"license": "ISC",
"isProd": true
}
]
"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."
]
}]
File diff suppressed because it is too large Load Diff
+22 -149
View File
@@ -1,150 +1,23 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[
{
"name": "agent-base",
"repositoryURL": "https://github.com/TooTallNate/node-agent-base",
"version": "1.0.2",
[{
"isLicense": true,
"name": "noice-json-rpc",
"repositoryURL": "https://github.com/nojvek/noice-json-rpc",
"license": "MIT",
"isProd": true
},
{
"name": "balanced-match",
"repositoryURL": "https://github.com/juliangruber/balanced-match",
"version": "0.4.2",
"license": "MIT",
"isProd": true
},
{
"name": "brace-expansion",
"repositoryURL": "https://github.com/juliangruber/brace-expansion",
"version": "1.1.6",
"license": "MIT",
"isProd": true
},
{
"name": "concat-map",
"repositoryURL": "https://github.com/substack/node-concat-map",
"version": "0.0.1",
"license": "MIT",
"isProd": true
},
{
"name": "debug",
"repositoryURL": "https://github.com/visionmedia/debug",
"version": "2.2.0",
"license": "MIT",
"isProd": true
},
{
"name": "extend",
"repositoryURL": "https://github.com/justmoon/node-extend",
"version": "3.0.0",
"license": "MIT",
"isProd": true
},
{
"name": "fs.realpath",
"repositoryURL": "https://github.com/isaacs/fs.realpath",
"version": "1.0.0",
"license": "ISC",
"isProd": true
},
{
"name": "glob",
"repositoryURL": "https://github.com/isaacs/node-glob",
"version": "7.1.0",
"license": "ISC",
"isProd": true
},
{
"name": "http-proxy-agent",
"repositoryURL": "https://github.com/TooTallNate/node-http-proxy-agent",
"version": "0.2.7",
"license": "MIT",
"isProd": true
},
{
"name": "https-proxy-agent",
"repositoryURL": "https://github.com/TooTallNate/node-https-proxy-agent",
"version": "0.3.6",
"license": "MIT",
"isProd": true
},
{
"name": "inflight",
"repositoryURL": "https://github.com/npm/inflight",
"version": "1.0.5",
"license": "ISC",
"isProd": true
},
{
"name": "inherits",
"repositoryURL": "https://github.com/isaacs/inherits",
"version": "2.0.3",
"license": "ISC",
"isProd": true
},
{
"name": "minimatch",
"repositoryURL": "https://github.com/isaacs/minimatch",
"version": "3.0.3",
"license": "ISC",
"isProd": true
},
{
"name": "ms",
"repositoryURL": "https://github.com/rauchg/ms.js",
"version": "0.7.1",
"license": "MIT",
"isProd": true
},
{
"name": "once",
"repositoryURL": "https://github.com/isaacs/once",
"version": "1.4.0",
"license": "ISC",
"isProd": true
},
{
"name": "options",
"repositoryURL": "https://github.com/einaros/options.js",
"version": "0.0.6",
"license": "MIT",
"isProd": true
},
{
"name": "ultron",
"repositoryURL": "https://github.com/unshiftio/ultron",
"version": "1.0.2",
"license": "MIT",
"isProd": true
},
{
"name": "path-is-absolute",
"repositoryURL": "https://github.com/sindresorhus/path-is-absolute",
"version": "1.0.0",
"license": "MIT",
"isProd": true
},
{
"name": "source-map",
"repositoryURL": "https://github.com/mozilla/source-map",
"version": "0.5.6",
"license": "BSD-3-Clause",
"isProd": true
},
{
"name": "wrappy",
"repositoryURL": "https://github.com/npm/wrappy",
"version": "1.0.2",
"license": "ISC",
"isProd": true
},
{
"name": "ws",
"repositoryURL": "https://github.com/websockets/ws",
"version": "1.1.1",
"license": "MIT",
"isProd": true
}
]
"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."
]
}]
File diff suppressed because it is too large Load Diff
File diff suppressed because it is too large Load Diff
+1 -1
View File
@@ -3,7 +3,7 @@
"version": "0.0.1",
"description": "Dependencies shared by all extensions",
"dependencies": {
"typescript": "2.6.1",
"typescript": "2.6.2",
"extensions-modules": "file:../extensions-modules"
},
"scripts": {
+17 -1
View File
@@ -13,7 +13,23 @@
{ "open": "[", "close": "]" },
{ "open": "(", "close": ")" },
{ "open": "\"", "close": "\"", "notIn": ["string"] },
{ "open": "'", "close": "'", "notIn": ["string", "comment"] }
{ "open": "r\"", "close": "\"", "notIn": ["string", "comment"] },
{ "open": "R\"", "close": "\"", "notIn": ["string", "comment"] },
{ "open": "u\"", "close": "\"", "notIn": ["string", "comment"] },
{ "open": "U\"", "close": "\"", "notIn": ["string", "comment"] },
{ "open": "f\"", "close": "\"", "notIn": ["string", "comment"] },
{ "open": "F\"", "close": "\"", "notIn": ["string", "comment"] },
{ "open": "b\"", "close": "\"", "notIn": ["string", "comment"] },
{ "open": "B\"", "close": "\"", "notIn": ["string", "comment"] },
{ "open": "'", "close": "'", "notIn": ["string", "comment"] },
{ "open": "r'", "close": "'", "notIn": ["string", "comment"] },
{ "open": "R'", "close": "'", "notIn": ["string", "comment"] },
{ "open": "u'", "close": "'", "notIn": ["string", "comment"] },
{ "open": "U'", "close": "'", "notIn": ["string", "comment"] },
{ "open": "f'", "close": "'", "notIn": ["string", "comment"] },
{ "open": "F'", "close": "'", "notIn": ["string", "comment"] },
{ "open": "b'", "close": "'", "notIn": ["string", "comment"] },
{ "open": "B'", "close": "'", "notIn": ["string", "comment"] }
],
"surroundingPairs": [
["{", "}"],
+2 -1
View File
@@ -5,7 +5,8 @@
"es2015"
],
"module": "commonjs",
"outDir": "./out"
"outDir": "./out",
"strict": true
},
"include": [
"src/**/*"
+4 -18
View File
@@ -1,23 +1,9 @@
// ATTENTION - THIS DIRECTORY CONTAINS THIRD PARTY OPEN SOURCE MATERIALS:
[{
"name": "textmate/shellscript.tmbundle",
"name": "atom/language-shellscript",
"version": "0.0.0",
"license": "TextMate Bundle License",
"repositoryURL": "https://github.com/textmate/shellscript.tmbundle",
"licenseDetail": [
"Copyright (c) textmate-shellscript.tmbundle project authors",
"",
"If not otherwise specified (see below), files in this repository fall under the following license:",
"",
"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.",
"",
"An exception is made for files in readable text which contain their own license information,",
"or files where an accompanying file exists (in the same directory) with a \"-license\" suffix added",
"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\"."
]
"license": "MIT",
"repositoryURL": "https://github.com/atom/language-shellscript",
"description": "The file syntaxes/shell-unix-bash.tmLanguage.json was derived from the Atom package https://github.com/atom/language-shellscript which was originally converted from the TextMate bundle https://github.com/textmate/shellscript.tmbundle."
}]
+3 -3
View File
@@ -4,12 +4,12 @@
"publisher": "vscode",
"engines": { "vscode": "*" },
"scripts": {
"update-grammar": "node ../../build/npm/update-grammar.js textmate/shellscript.tmbundle Syntaxes/Shell-Unix-Bash.tmLanguage ./syntaxes/Shell-Unix-Bash.tmLanguage.json"
"update-grammar": "node ../../build/npm/update-grammar.js atom/language-shellscript grammars/shell-unix-bash.cson ./syntaxes/shell-unix-bash.tmLanguage.json"
},
"contributes": {
"languages": [{
"id": "shellscript",
"aliases": ["Shell Script (Bash)", "shellscript", "bash", "sh", "zsh"],
"aliases": ["Shell Script", "shellscript", "bash", "sh", "zsh"],
"extensions": [".sh", ".bash", ".bashrc", ".bash_aliases", ".bash_profile", ".bash_login", ".ebuild", ".install", ".profile", ".bash_logout", ".zsh", ".zshrc", ".zprofile", ".zlogin", ".zlogout", ".zshenv", ".zsh-theme"],
"filenames": ["PKGBUILD"],
"firstLine": "^#!.*\\b(bash|zsh|sh|tcsh).*|^#\\s*-\\*-[^*]*mode:\\s*shell-script[^*]*-\\*-",
@@ -19,7 +19,7 @@
"grammars": [{
"language": "shellscript",
"scopeName": "source.shell",
"path": "./syntaxes/Shell-Unix-Bash.tmLanguage.json"
"path": "./syntaxes/shell-unix-bash.tmLanguage.json"
}]
}
}
File diff suppressed because it is too large Load Diff
@@ -1,7 +1,7 @@
[
{
"c": "#!",
"t": "source.shell comment.line.shebang.shell punctuation.definition.comment.line.shebang.shell",
"t": "source.shell comment.line.number-sign.shebang.shell punctuation.definition.comment.shebang.shell",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
@@ -12,7 +12,7 @@
},
{
"c": "/usr/bin/env bash",
"t": "source.shell comment.line.shebang.shell",
"t": "source.shell comment.line.number-sign.shebang.shell",
"r": {
"dark_plus": "comment: #608B4E",
"light_plus": "comment: #008000",
@@ -243,7 +243,7 @@
},
{
"c": "\t",
"t": "source.shell meta.scope.if-block.shell meta.function.shell",
"t": "source.shell meta.scope.if-block.shell",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -1144,7 +1144,7 @@
}
},
{
"c": "code",
"c": "code()",
"t": "source.shell meta.function.shell entity.name.function.shell",
"r": {
"dark_plus": "entity.name.function: #DCDCAA",
@@ -1154,17 +1154,6 @@
"hc_black": "entity.name.function: #DCDCAA"
}
},
{
"c": "()",
"t": "source.shell meta.function.shell punctuation.definition.arguments.shell",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
"dark_vs": "default: #D4D4D4",
"light_vs": "default: #000000",
"hc_black": "default: #FFFFFF"
}
},
{
"c": " ",
"t": "source.shell meta.function.shell",
@@ -1431,7 +1420,7 @@
},
{
"c": "\t",
"t": "source.shell meta.function.shell meta.scope.group.shell meta.scope.if-block.shell",
"t": "source.shell meta.function.shell meta.scope.group.shell",
"r": {
"dark_plus": "default: #D4D4D4",
"light_plus": "default: #000000",
@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{opacity:0;fill:#F6F6F6;} .icon-vs-bg{fill:#656565;} .icon-vs-fg{fill:#F0EFF1;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M4 15c-.97 0-2-.701-2-2v-10c0-1.299 1.03-2 2-2h6.061l3.939 3.556v8.444c0 .97-.701 2-2 2h-8z" id="outline"/><path class="icon-vs-bg" d="M9.641,2H3.964C3.964,2,3,2,3,3c0,0.805,0,7.442,0,10c0,1,0.965,1,0.965,1s7,0,8,0S13,13,13,13V5L9.641,2zM12,13H4V3h5v3h3V13z" id="iconBg"/><path class="icon-vs-fg" d="M4 3h5v3h3v7h-8v-10z" id="iconFg"/></svg>

After

Width:  |  Height:  |  Size: 682 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{opacity:0;fill:#F6F6F6;} .icon-vs-bg{fill:#C5C5C5;} .icon-vs-fg{opacity:0;fill:#F0EFF1;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M4 15c-.97 0-2-.701-2-2v-10c0-1.299 1.03-2 2-2h6.061l3.939 3.556v8.444c0 .97-.701 2-2 2h-8z" id="outline"/><path class="icon-vs-bg" d="M9.641,2H3.964C3.964,2,3,2,3,3c0,0.805,0,7.442,0,10c0,1,0.965,1,0.965,1s7,0,8,0S13,13,13,13V5L9.641,2zM12,13H4V3h5v3h3V13z" id="iconBg"/><path class="icon-vs-fg" d="M4 3h5v3h3v7h-8v-10z" id="iconFg"/></svg>

After

Width:  |  Height:  |  Size: 692 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{opacity:0;fill:#F6F6F6;} .icon-vs-fg{fill:#F0EFF1;} .icon-folder{fill:#656565;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M14 .969h-7.116l-1 2h-2.884c-.97 0-2 .701-2 2v2h-1v1.196l2.323 5.804h11.677s.86-.021 1.43-.565c.344-.332.57-.817.57-1.435v-9c0-1.303-1.005-2-2-2z" id="outline"/><path class="icon-folder" d="M14,2c0,0,1,0,1,1c0,2.36,0,8.205,0,9c0,1-1,0.984-1,0.984V3H8L7,5H3v3h8l3,5H3L1,8h1c0,0,0-2,0-3s1.236-1,1-1h3.5l1-2H14z" id="iconBg"/><path class="icon-vs-fg" d="M3 7.969v-3h4l1-2h6v10l-3-5h-8z" id="iconFg"/></svg>

After

Width:  |  Height:  |  Size: 745 B

@@ -0,0 +1 @@
<svg xmlns="http://www.w3.org/2000/svg" width="16" height="16"><style type="text/css">.icon-canvas-transparent{opacity:0;fill:#F6F6F6;} .icon-vs-out{opacity:0;fill:#F6F6F6;} .icon-vs-fg{opacity:0;fill:#F0EFF1;} .icon-folder{fill:#C5C5C5;}</style><path class="icon-canvas-transparent" d="M16 16h-16v-16h16v16z" id="canvas"/><path class="icon-vs-out" d="M14 .969h-7.116l-1 2h-2.884c-.97 0-2 .701-2 2v2h-1v1.196l2.323 5.804h11.677s.86-.021 1.43-.565c.344-.332.57-.817.57-1.435v-9c0-1.303-1.005-2-2-2z" id="outline"/><path class="icon-folder" d="M14,2c0,0,1,0,1,1c0,2.36,0,8.205,0,9c0,1-1,0.984-1,0.984V3H8L7,5H3v3h8l3,5H3L1,8h1c0,0,0-2,0-3s1.236-1,1-1h3.5l1-2H14z" id="iconBg"/><path class="icon-vs-fg" d="M3 7.969v-3h4l1-2h6v10l-3-5h-8z" id="iconFg"/></svg>

After

Width:  |  Height:  |  Size: 755 B

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