Merge from vscode e3c4990c67c40213af168300d1cfeb71d680f877 (#16569)

This commit is contained in:
Cory Rivera
2021-08-25 16:28:29 -07:00
committed by GitHub
parent ab1112bfb3
commit cb7b7da0a4
1752 changed files with 59525 additions and 33878 deletions

View File

@@ -1,5 +1,5 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
// Licensed under the Source EULA.
/*
* This file imports all public APIs for this extension and used to generate index.d.ts.

View File

@@ -6,11 +6,11 @@
"git": {
"name": "mmims/language-batchfile",
"repositoryUrl": "https://github.com/mmims/language-batchfile",
"commitHash": "95ea8c699f7a8296b15767069868532d52631c46"
"commitHash": "6154ae25a24e01ac9329e7bcf958e093cd8733a9"
}
},
"license": "MIT",
"version": "0.7.5"
"version": "0.7.6"
}
],
"version": 1

View File

@@ -4,9 +4,18 @@
"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/95ea8c699f7a8296b15767069868532d52631c46",
"version": "https://github.com/mmims/language-batchfile/commit/6154ae25a24e01ac9329e7bcf958e093cd8733a9",
"name": "Batch File",
"scopeName": "source.batchfile",
"injections": {
"L:meta.block.repeat.batchfile": {
"patterns": [
{
"include": "#repeatParameter"
}
]
}
},
"patterns": [
{
"include": "#commands"
@@ -46,7 +55,7 @@
"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|cls|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|scp|sc|schtasks|scwcmd|secedit|serverceipoptin|servrmanagercmd|serverweroptin|setspn|setx|sfc|shadow|shift|showmount|shutdown|sort|ssh|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)",
"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|cls|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|scp|scwcmd|secedit|serverceipoptin|servrmanagercmd|serverweroptin|setspn|setx|sfc|sftp|shadow|shift|showmount|shutdown|sort|ssh|ssh-add|ssh-agent|ssh-keygen|ssh-keyscan|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|wmic|wscript|wsl|xcopy)(?=$|\\s)",
"name": "keyword.command.batchfile"
},
{
@@ -285,7 +294,7 @@
"name": "keyword.operator.logical.batchfile"
},
{
"match": "([^ ][^=]*)(=)",
"match": "([^ =]*)(=)",
"captures": {
"1": {
"name": "variable.other.readwrite.batchfile"
@@ -420,8 +429,38 @@
"name": "keyword.control.conditional.batchfile"
},
{
"match": "(?<=^|\\s)(?i)for(?=\\s)",
"name": "keyword.control.repeat.batchfile"
"begin": "(?<=^|[\\s(&^])(?i)for(?=\\s)",
"beginCaptures": {
"0": {
"name": "keyword.control.repeat.batchfile"
}
},
"name": "meta.block.repeat.batchfile",
"end": "\\n",
"patterns": [
{
"begin": "(?<=[\\s^])(?i)in(?=\\s)",
"beginCaptures": {
"0": {
"name": "keyword.control.repeat.in.batchfile"
}
},
"end": "(?<=[\\s)^])(?i)do(?=\\s)|\\n",
"endCaptures": {
"0": {
"name": "keyword.control.repeat.do.batchfile"
}
},
"patterns": [
{
"include": "$self"
}
]
},
{
"include": "$self"
}
]
}
]
},
@@ -436,7 +475,7 @@
"labels": {
"patterns": [
{
"match": "(?i)(?:^\\s*|(?<=goto)\\s*)(:)([^+=,;:\\s].*)$",
"match": "(?i)(?:^\\s*|(?<=call|goto)\\s*)(:)([^+=,;:\\s]\\S*)",
"captures": {
"1": {
"name": "punctuation.separator.batchfile"
@@ -512,6 +551,19 @@
}
]
},
"repeatParameter": {
"patterns": [
{
"match": "(%%)(?:(?i:~[fdpnxsatz]*(?:\\$PATH:)?)?[a-zA-Z])",
"captures": {
"1": {
"name": "punctuation.definition.variable.batchfile"
}
},
"name": "variable.parameter.repeat.batchfile"
}
]
},
"strings": {
"patterns": [
{
@@ -546,15 +598,13 @@
"variables": {
"patterns": [
{
"match": "(%)((~([fdpnxsatz]|\\$PATH:)*)?\\d|\\*)",
"match": "(%)(?:(?i:~[fdpnxsatz]*(?:\\$PATH:)?)?\\d|\\*)",
"captures": {
"1": {
"name": "punctuation.definition.variable.batchfile"
},
"2": {
"name": "variable.parameter.batchfile"
}
}
},
"name": "variable.parameter.batchfile"
},
{
"include": "#variable"

View File

@@ -139,7 +139,7 @@
]
},
"devDependencies": {
"@types/node": "^12.19.9"
"@types/node": "14.x"
},
"repository": {
"type": "git",

View File

@@ -54,6 +54,19 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"default": {
@@ -80,7 +93,13 @@
"properties": {
"onAutoForward": {
"type": "string",
"enum": ["notify", "openBrowser", "openPreview", "silent", "ignore"],
"enum": [
"notify",
"openBrowser",
"openPreview",
"silent",
"ignore"
],
"enumDescriptions": [
"Shows a notification when a port is automatically forwarded.",
"Opens the browser when the port is automatically forwarded. Depending on your settings, this could open an embedded browser.",
@@ -100,9 +119,28 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"defaultSnippets": [{ "body": { "onAutoForward": "ignore" } }],
"defaultSnippets": [
{
"body": {
"onAutoForward": "ignore"
}
}
],
"markdownDescription": "Set default properties that are applied to all ports that don't get properties from the setting `remote.portsAttributes`. For example:\n\n```\n{\n \"onAutoForward\": \"ignore\"\n}\n```",
"additionalProperties": false
},

View File

@@ -162,6 +162,19 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"default": {
@@ -215,6 +228,19 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"defaultSnippets": [
@@ -246,7 +272,27 @@
"string",
"array"
],
"description": "A command to run locally before anything else. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run locally before anything else. This command is run before \"onCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"onCreateCommand": {
"type": [
"string",
"array"
],
"description": "A command to run when creating the container. This command is run after \"initializeCommand\" and before \"updateContentCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"updateContentCommand": {
"type": [
"string",
"array"
],
"description": "A command to run when creating the container and rerun when the workspace content was updated while creating the container. This command is run after \"onCreateCommand\" and before \"postCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -256,7 +302,7 @@
"string",
"array"
],
"description": "A command to run after creating the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run after creating the container. This command is run after \"updateContentCommand\" and before \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -266,7 +312,7 @@
"string",
"array"
],
"description": "A command to run after starting the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run after starting the container. This command is run after \"postCreateCommand\" and before \"postAttachCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -276,11 +322,23 @@
"string",
"array"
],
"description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run when attaching to the container. This command is run after \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"waitFor": {
"type": "string",
"enum": [
"initializeCommand",
"onCreateCommand",
"updateContentCommand",
"postCreateCommand",
"postStartCommand",
"postAttachCommand"
],
"description": "The user command to wait for before continuing execution in the background while the UI is starting up. The default is \"updateContentCommand\"."
},
"devPort": {
"type": "integer",
"description": "The port VS Code can use to connect to its backend."
@@ -299,6 +357,28 @@
"type": "object",
"additionalProperties": true,
"description": "Codespaces-specific configuration."
},
"hostRequirements": {
"type": "object",
"description": "Host hardware requirements.",
"properties": {
"cpus": {
"type": "integer",
"minimum": 1,
"description": "Number of required CPUs."
},
"memory": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required RAM in bytes. Supports units tb, gb, mb and kb."
},
"storage": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required disk space in bytes. Supports units tb, gb, mb and kb."
}
},
"additionalProperties": false
}
},
"required": [
@@ -461,6 +541,19 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"default": {
@@ -514,6 +607,19 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"defaultSnippets": [
@@ -545,7 +651,27 @@
"string",
"array"
],
"description": "A command to run locally before anything else. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run locally before anything else. This command is run before \"onCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"onCreateCommand": {
"type": [
"string",
"array"
],
"description": "A command to run when creating the container. This command is run after \"initializeCommand\" and before \"updateContentCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"updateContentCommand": {
"type": [
"string",
"array"
],
"description": "A command to run when creating the container and rerun when the workspace content was updated while creating the container. This command is run after \"onCreateCommand\" and before \"postCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -555,7 +681,7 @@
"string",
"array"
],
"description": "A command to run after creating the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run after creating the container. This command is run after \"updateContentCommand\" and before \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -565,7 +691,7 @@
"string",
"array"
],
"description": "A command to run after starting the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run after starting the container. This command is run after \"postCreateCommand\" and before \"postAttachCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -575,11 +701,23 @@
"string",
"array"
],
"description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run when attaching to the container. This command is run after \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"waitFor": {
"type": "string",
"enum": [
"initializeCommand",
"onCreateCommand",
"updateContentCommand",
"postCreateCommand",
"postStartCommand",
"postAttachCommand"
],
"description": "The user command to wait for before continuing execution in the background while the UI is starting up. The default is \"updateContentCommand\"."
},
"devPort": {
"type": "integer",
"description": "The port VS Code can use to connect to its backend."
@@ -598,6 +736,28 @@
"type": "object",
"additionalProperties": true,
"description": "Codespaces-specific configuration."
},
"hostRequirements": {
"type": "object",
"description": "Host hardware requirements.",
"properties": {
"cpus": {
"type": "integer",
"minimum": 1,
"description": "Number of required CPUs."
},
"memory": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required RAM in bytes. Supports units tb, gb, mb and kb."
},
"storage": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required disk space in bytes. Supports units tb, gb, mb and kb."
}
},
"additionalProperties": false
}
},
"required": [
@@ -736,6 +896,19 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"default": {
@@ -789,6 +962,19 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"defaultSnippets": [
@@ -820,7 +1006,27 @@
"string",
"array"
],
"description": "A command to run locally before anything else. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run locally before anything else. This command is run before \"onCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"onCreateCommand": {
"type": [
"string",
"array"
],
"description": "A command to run when creating the container. This command is run after \"initializeCommand\" and before \"updateContentCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"updateContentCommand": {
"type": [
"string",
"array"
],
"description": "A command to run when creating the container and rerun when the workspace content was updated while creating the container. This command is run after \"onCreateCommand\" and before \"postCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -830,7 +1036,7 @@
"string",
"array"
],
"description": "A command to run after creating the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run after creating the container. This command is run after \"updateContentCommand\" and before \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -840,7 +1046,7 @@
"string",
"array"
],
"description": "A command to run after starting the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run after starting the container. This command is run after \"postCreateCommand\" and before \"postAttachCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -850,11 +1056,23 @@
"string",
"array"
],
"description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run when attaching to the container. This command is run after \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"waitFor": {
"type": "string",
"enum": [
"initializeCommand",
"onCreateCommand",
"updateContentCommand",
"postCreateCommand",
"postStartCommand",
"postAttachCommand"
],
"description": "The user command to wait for before continuing execution in the background while the UI is starting up. The default is \"updateContentCommand\"."
},
"devPort": {
"type": "integer",
"description": "The port VS Code can use to connect to its backend."
@@ -873,6 +1091,28 @@
"type": "object",
"additionalProperties": true,
"description": "Codespaces-specific configuration."
},
"hostRequirements": {
"type": "object",
"description": "Host hardware requirements.",
"properties": {
"cpus": {
"type": "integer",
"minimum": 1,
"description": "Number of required CPUs."
},
"memory": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required RAM in bytes. Supports units tb, gb, mb and kb."
},
"storage": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required disk space in bytes. Supports units tb, gb, mb and kb."
}
},
"additionalProperties": false
}
},
"required": [
@@ -977,6 +1217,19 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"default": {
@@ -1030,6 +1283,19 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"defaultSnippets": [
@@ -1061,7 +1327,27 @@
"string",
"array"
],
"description": "A command to run locally before anything else. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run locally before anything else. This command is run before \"onCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"onCreateCommand": {
"type": [
"string",
"array"
],
"description": "A command to run when creating the container. This command is run after \"initializeCommand\" and before \"updateContentCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"updateContentCommand": {
"type": [
"string",
"array"
],
"description": "A command to run when creating the container and rerun when the workspace content was updated while creating the container. This command is run after \"onCreateCommand\" and before \"postCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -1071,7 +1357,7 @@
"string",
"array"
],
"description": "A command to run after creating the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run after creating the container. This command is run after \"updateContentCommand\" and before \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -1081,7 +1367,7 @@
"string",
"array"
],
"description": "A command to run after starting the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run after starting the container. This command is run after \"postCreateCommand\" and before \"postAttachCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -1091,11 +1377,23 @@
"string",
"array"
],
"description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run when attaching to the container. This command is run after \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"waitFor": {
"type": "string",
"enum": [
"initializeCommand",
"onCreateCommand",
"updateContentCommand",
"postCreateCommand",
"postStartCommand",
"postAttachCommand"
],
"description": "The user command to wait for before continuing execution in the background while the UI is starting up. The default is \"updateContentCommand\"."
},
"devPort": {
"type": "integer",
"description": "The port VS Code can use to connect to its backend."
@@ -1114,6 +1412,28 @@
"type": "object",
"additionalProperties": true,
"description": "Codespaces-specific configuration."
},
"hostRequirements": {
"type": "object",
"description": "Host hardware requirements.",
"properties": {
"cpus": {
"type": "integer",
"minimum": 1,
"description": "Number of required CPUs."
},
"memory": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required RAM in bytes. Supports units tb, gb, mb and kb."
},
"storage": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required disk space in bytes. Supports units tb, gb, mb and kb."
}
},
"additionalProperties": false
}
},
"required": [
@@ -1187,6 +1507,19 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"default": {
@@ -1240,6 +1573,19 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": [
"http",
"https"
],
"description": "The protocol to use when forwarding this port."
}
},
"defaultSnippets": [
@@ -1271,7 +1617,27 @@
"string",
"array"
],
"description": "A command to run locally before anything else. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run locally before anything else. This command is run before \"onCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"onCreateCommand": {
"type": [
"string",
"array"
],
"description": "A command to run when creating the container. This command is run after \"initializeCommand\" and before \"updateContentCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"updateContentCommand": {
"type": [
"string",
"array"
],
"description": "A command to run when creating the container and rerun when the workspace content was updated while creating the container. This command is run after \"onCreateCommand\" and before \"postCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -1281,7 +1647,7 @@
"string",
"array"
],
"description": "A command to run after creating the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run after creating the container. This command is run after \"updateContentCommand\" and before \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -1291,7 +1657,7 @@
"string",
"array"
],
"description": "A command to run after starting the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run after starting the container. This command is run after \"postCreateCommand\" and before \"postAttachCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -1301,11 +1667,23 @@
"string",
"array"
],
"description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run when attaching to the container. This command is run after \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"waitFor": {
"type": "string",
"enum": [
"initializeCommand",
"onCreateCommand",
"updateContentCommand",
"postCreateCommand",
"postStartCommand",
"postAttachCommand"
],
"description": "The user command to wait for before continuing execution in the background while the UI is starting up. The default is \"updateContentCommand\"."
},
"devPort": {
"type": "integer",
"description": "The port VS Code can use to connect to its backend."
@@ -1324,6 +1702,28 @@
"type": "object",
"additionalProperties": true,
"description": "Codespaces-specific configuration."
},
"hostRequirements": {
"type": "object",
"description": "Host hardware requirements.",
"properties": {
"cpus": {
"type": "integer",
"minimum": 1,
"description": "Number of required CPUs."
},
"memory": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required RAM in bytes. Supports units tb, gb, mb and kb."
},
"storage": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required disk space in bytes. Supports units tb, gb, mb and kb."
}
},
"additionalProperties": false
}
},
"additionalProperties": false

View File

@@ -68,6 +68,16 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": ["http", "https"],
"description": "The protocol to use when forwarding this port."
}
},
"default": {
@@ -120,6 +130,16 @@
"type": "string",
"description": "Label that will be shown in the UI for this port.",
"default": "Application"
},
"requireLocalPort": {
"type": "boolean",
"markdownDescription": "When true, a modal dialog will show if the chosen local port isn't used for forwarding.",
"default": false
},
"protocol": {
"type": "string",
"enum": ["http", "https"],
"description": "The protocol to use when forwarding this port."
}
},
"defaultSnippets": [
@@ -151,7 +171,27 @@
"string",
"array"
],
"description": "A command to run locally before anything else. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run locally before anything else. This command is run before \"onCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"onCreateCommand": {
"type": [
"string",
"array"
],
"description": "A command to run when creating the container. This command is run after \"initializeCommand\" and before \"updateContentCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"updateContentCommand": {
"type": [
"string",
"array"
],
"description": "A command to run when creating the container and rerun when the workspace content was updated while creating the container. This command is run after \"onCreateCommand\" and before \"postCreateCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -161,7 +201,7 @@
"string",
"array"
],
"description": "A command to run after creating the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run after creating the container. This command is run after \"updateContentCommand\" and before \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -171,7 +211,7 @@
"string",
"array"
],
"description": "A command to run after starting the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run after starting the container. This command is run after \"postCreateCommand\" and before \"postAttachCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
@@ -181,11 +221,23 @@
"string",
"array"
],
"description": "A command to run after attaching to the container. If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"description": "A command to run when attaching to the container. This command is run after \"postStartCommand\". If this is a single string, it will be run in a shell. If this is an array of strings, it will be run as a single command without shell.",
"items": {
"type": "string"
}
},
"waitFor": {
"type": "string",
"enum": [
"initializeCommand",
"onCreateCommand",
"updateContentCommand",
"postCreateCommand",
"postStartCommand",
"postAttachCommand"
],
"description": "The user command to wait for before continuing execution in the background while the UI is starting up. The default is \"updateContentCommand\"."
},
"devPort": {
"type": "integer",
"description": "The port VS Code can use to connect to its backend."
@@ -204,6 +256,32 @@
"type": "object",
"additionalProperties": true,
"description": "Codespaces-specific configuration."
},
"hostRequirements": {
"type": "object",
"description": "Host hardware requirements.",
"allOf": [
{
"type": "object",
"properties": {
"cpus": {
"type": "integer",
"minimum": 1,
"description": "Number of required CPUs."
},
"memory": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required RAM in bytes. Supports units tb, gb, mb and kb."
},
"storage": {
"type": "string",
"pattern": "^\\d+([tgmk]b)?$",
"description": "Amount of required disk space in bytes. Supports units tb, gb, mb and kb."
}
}
}
]
}
}
},

View File

@@ -6,7 +6,7 @@
import * as vscode from 'vscode';
import { getLocation, Location, parse } from 'jsonc-parser';
import * as nls from 'vscode-nls';
import { provideInstalledExtensionProposals, provideWorkspaceTrustExtensionProposals } from './extensionsProposals';
import { provideInstalledExtensionProposals } from './extensionsProposals';
const localize = nls.loadMessageBundle();
@@ -60,13 +60,9 @@ export class SettingsDocument {
return provideInstalledExtensionProposals(alreadyConfigured, `: [\n\t"ui"\n]`, range, true);
}
// extensions.supportUntrustedWorkspaces
if (location.path[0] === 'extensions.supportUntrustedWorkspaces' && location.path.length === 2 && location.isAtPropertyKey) {
let alreadyConfigured: string[] = [];
try {
alreadyConfigured = Object.keys(parse(this.document.getText())['extensions.supportUntrustedWorkspaces']);
} catch (e) {/* ignore error */ }
return provideWorkspaceTrustExtensionProposals(alreadyConfigured, range);
// remote.portsAttributes
if (location.path[0] === 'remote.portsAttributes' && location.path.length === 2 && location.isAtPropertyKey) {
return this.providePortsAttributesCompletionItem(range);
}
return this.provideLanguageOverridesCompletionItems(location, position);
@@ -247,6 +243,31 @@ export class SettingsDocument {
return Promise.resolve([]);
}
private providePortsAttributesCompletionItem(range: vscode.Range): vscode.CompletionItem[] {
return [this.newSnippetCompletionItem(
{
label: '\"3000\"',
documentation: 'Single Port Attribute',
range,
snippet: '\n \"${1:3000}\": {\n \"label\": \"${2:Application}\",\n \"onAutoForward\": \"${3:openPreview}\"\n }\n'
}),
this.newSnippetCompletionItem(
{
label: '\"5000-6000\"',
documentation: 'Ranged Port Attribute',
range,
snippet: '\n \"${1:40000-55000}\": {\n \"onAutoForward\": \"${2:ignore}\"\n }\n'
}),
this.newSnippetCompletionItem(
{
label: '\".+\\\\/server.js\"',
documentation: 'Command Match Port Attribute',
range,
snippet: '\n \"${1:.+\\\\/server.js\}\": {\n \"label\": \"${2:Application}\",\n \"onAutoForward\": \"${3:openPreview}\"\n }\n'
})
];
}
private newSimpleCompletionItem(text: string, range: vscode.Range, description?: string, insertText?: string): vscode.CompletionItem {
const item = new vscode.CompletionItem(text);
item.kind = vscode.CompletionItemKind.Value;

View File

@@ -2,10 +2,10 @@
# yarn lockfile v1
"@types/node@^12.19.9":
version "12.19.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.9.tgz#990ad687ad8b26ef6dcc34a4f69c33d40c95b679"
integrity sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==
"@types/node@14.x":
version "14.14.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
jsonc-parser@^2.2.1:
version "2.2.1"

View File

@@ -0,0 +1,2 @@
build/**
cgmanifest.json

View File

@@ -0,0 +1,46 @@
{
"registrations": [
{
"component": {
"type": "git",
"git": {
"name": "dart-lang/dart-syntax-highlight",
"repositoryUrl": "https://github.com/dart-lang/dart-syntax-highlight",
"commitHash": "65f211722c85e9fdf0aa658d5663e6ccaf2ebe25"
}
},
"licenseDetail": [
"Copyright 2020, the Dart project authors.",
"",
"Redistribution and use in source and binary forms, with or without",
"modification, are permitted provided that the following conditions are",
"met:",
"",
" * Redistributions of source code must retain the above copyright",
" notice, this list of conditions and the following disclaimer.",
" * Redistributions in binary form must reproduce the above",
" copyright notice, this list of conditions and the following",
" disclaimer in the documentation and/or other materials provided",
" with the distribution.",
" * Neither the name of Google LLC nor the names of its",
" contributors may be used to endorse or promote products derived",
" from this software without specific prior written permission.",
"",
"THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS",
"\"AS IS\" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT",
"LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR",
"A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT",
"OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,",
"SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT",
"LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,",
"DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY",
"THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT",
"(INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE",
"OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE."
],
"license": "BSD",
"version": "0.0.0"
}
],
"version": 1
}

View File

@@ -0,0 +1,29 @@
{
"comments": {
"lineComment": "//",
"blockComment": [ "/*", "*/" ]
},
"brackets": [
["{", "}"],
["[", "]"],
["(", ")"]
],
"autoClosingPairs": [
{ "open": "{", "close": "}" },
{ "open": "[", "close": "]" },
{ "open": "(", "close": ")" },
{ "open": "'", "close": "'", "notIn": ["string", "comment"] },
{ "open": "\"", "close": "\"", "notIn": ["string"] },
{ "open": "`", "close": "`", "notIn": ["string", "comment"] },
{ "open": "/**", "close": " */", "notIn": ["string"] }
],
"surroundingPairs": [
["{", "}"],
["[", "]"],
["(", ")"],
["<", ">"],
["'", "'"],
["\"", "\""],
["`", "`"]
]
}

View File

@@ -0,0 +1,35 @@
{
"name": "dart",
"displayName": "%displayName%",
"description": "%description%",
"version": "1.0.0",
"publisher": "vscode",
"license": "MIT",
"engines": {
"vscode": "0.10.x"
},
"scripts": {
"update-grammar": "node ../node_modules/vscode-grammar-updater/bin dart-lang/dart-syntax-highlight grammars/dart.json ./syntaxes/dart.tmLanguage.json"
},
"contributes": {
"languages": [
{
"id": "dart",
"extensions": [
".dart"
],
"aliases": [
"Dart"
],
"configuration": "./language-configuration.json"
}
],
"grammars": [
{
"language": "dart",
"scopeName": "source.dart",
"path": "./syntaxes/dart.tmLanguage.json"
}
]
}
}

View File

@@ -0,0 +1,4 @@
{
"displayName": "Dart Language Basics",
"description": "Provides syntax highlighting & bracket matching in Dart files."
}

View File

@@ -0,0 +1,439 @@
{
"information_for_contributors": [
"This file has been converted from https://github.com/dart-lang/dart-syntax-highlight/blob/master/grammars/dart.json",
"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/dart-lang/dart-syntax-highlight/commit/65f211722c85e9fdf0aa658d5663e6ccaf2ebe25",
"name": "Dart",
"scopeName": "source.dart",
"patterns": [
{
"name": "meta.preprocessor.script.dart",
"match": "^(#!.*)$"
},
{
"name": "meta.declaration.dart",
"begin": "^\\w*\\b(library|import|part of|part|export)\\b",
"beginCaptures": {
"0": {
"name": "keyword.other.import.dart"
}
},
"end": ";",
"endCaptures": {
"0": {
"name": "punctuation.terminator.dart"
}
},
"patterns": [
{
"include": "#strings"
},
{
"include": "#comments"
},
{
"name": "keyword.other.import.dart",
"match": "\\b(as|show|hide)\\b"
}
]
},
{
"include": "#comments"
},
{
"include": "#punctuation"
},
{
"include": "#annotations"
},
{
"include": "#keywords"
},
{
"include": "#constants-and-special-vars"
},
{
"include": "#strings"
}
],
"repository": {
"dartdoc": {
"patterns": [
{
"match": "(\\[.*?\\])",
"captures": {
"0": {
"name": "variable.name.source.dart"
}
}
},
{
"match": "^ {4,}(?![ \\*]).*",
"captures": {
"0": {
"name": "variable.name.source.dart"
}
}
},
{
"contentName": "variable.other.source.dart",
"begin": "```.*?$",
"end": "```"
},
{
"match": "(`.*?`)",
"captures": {
"0": {
"name": "variable.other.source.dart"
}
}
},
{
"match": "(`.*?`)",
"captures": {
"0": {
"name": "variable.other.source.dart"
}
}
},
{
"match": "(\\* (( ).*))$",
"captures": {
"2": {
"name": "variable.other.source.dart"
}
}
},
{
"match": "(\\* .*)$"
}
]
},
"comments": {
"patterns": [
{
"name": "comment.block.empty.dart",
"match": "/\\*\\*/",
"captures": {
"0": {
"name": "punctuation.definition.comment.dart"
}
}
},
{
"include": "#comments-doc-oldschool"
},
{
"include": "#comments-doc"
},
{
"include": "#comments-inline"
}
]
},
"comments-doc-oldschool": {
"patterns": [
{
"name": "comment.block.documentation.dart",
"begin": "/\\*\\*",
"end": "\\*/",
"patterns": [
{
"include": "#comments-doc-oldschool"
},
{
"include": "#comments-block"
},
{
"include": "#dartdoc"
}
]
}
]
},
"comments-doc": {
"patterns": [
{
"name": "comment.block.documentation.dart",
"begin": "///",
"while": "^\\s*///",
"patterns": [
{
"include": "#dartdoc"
}
]
}
]
},
"comments-inline": {
"patterns": [
{
"include": "#comments-block"
},
{
"match": "((//).*)$",
"captures": {
"1": {
"name": "comment.line.double-slash.dart"
}
}
}
]
},
"comments-block": {
"patterns": [
{
"name": "comment.block.dart",
"begin": "/\\*",
"end": "\\*/",
"patterns": [
{
"include": "#comments-block"
}
]
}
]
},
"annotations": {
"patterns": [
{
"name": "storage.type.annotation.dart",
"match": "@[a-zA-Z]+"
}
]
},
"constants-and-special-vars": {
"patterns": [
{
"name": "constant.language.dart",
"match": "(?<!\\$)\\b(true|false|null)\\b(?!\\$)"
},
{
"name": "variable.language.dart",
"match": "(?<!\\$)\\b(this|super)\\b(?!\\$)"
},
{
"name": "constant.numeric.dart",
"match": "(?<!\\$)\\b((0(x|X)[0-9a-fA-F]*)|(([0-9]+\\.?[0-9]*)|(\\.[0-9]+))((e|E)(\\+|-)?[0-9]+)?)\\b(?!\\$)"
},
{
"name": "support.class.dart",
"match": "(?<![a-zA-Z0-9_$])([_$]*[A-Z][a-zA-Z0-9_$]*|bool\\b|num\\b|int\\b|double\\b|dynamic\\b)"
},
{
"match": "([_$]*[a-z][a-zA-Z0-9_$]*)(<|\\(|\\s+=>)",
"captures": {
"1": {
"name": "entity.name.function.dart"
}
}
}
]
},
"keywords": {
"patterns": [
{
"name": "keyword.cast.dart",
"match": "(?<!\\$)\\bas\\b(?!\\$)"
},
{
"name": "keyword.control.catch-exception.dart",
"match": "(?<!\\$)\\b(try|on|catch|finally|throw|rethrow)\\b(?!\\$)"
},
{
"name": "keyword.control.dart",
"match": "(?<!\\$)\\b(break|case|continue|default|do|else|for|if|in|return|switch|while)\\b(?!\\$)"
},
{
"name": "keyword.control.dart",
"match": "(?<!\\$)\\b(sync(\\*)?|async(\\*)?|await|yield(\\*)?)\\b(?!\\$)"
},
{
"name": "keyword.control.dart",
"match": "(?<!\\$)\\bassert\\b(?!\\$)"
},
{
"name": "keyword.control.new.dart",
"match": "(?<!\\$)\\b(new)\\b(?!\\$)"
},
{
"name": "keyword.declaration.dart",
"match": "(?<!\\$)\\b(abstract|class|enum|extends|extension|external|factory|implements|get|mixin|native|operator|set|typedef|with|covariant)\\b(?!\\$)"
},
{
"name": "keyword.operator.dart",
"match": "(?<!\\$)\\b(is\\!?)\\b(?!\\$)"
},
{
"name": "keyword.operator.ternary.dart",
"match": "\\?|:"
},
{
"name": "keyword.operator.bitwise.dart",
"match": "(<<|>>>?|~|\\^|\\||&)"
},
{
"name": "keyword.operator.assignment.bitwise.dart",
"match": "((&|\\^|\\||<<|>>>?)=)"
},
{
"name": "keyword.operator.closure.dart",
"match": "(=>)"
},
{
"name": "keyword.operator.comparison.dart",
"match": "(==|!=|<=?|>=?)"
},
{
"name": "keyword.operator.assignment.arithmetic.dart",
"match": "(([+*/%-]|\\~)=)"
},
{
"name": "keyword.operator.assignment.dart",
"match": "(=)"
},
{
"name": "keyword.operator.increment-decrement.dart",
"match": "(\\-\\-|\\+\\+)"
},
{
"name": "keyword.operator.arithmetic.dart",
"match": "(\\-|\\+|\\*|\\/|\\~\\/|%)"
},
{
"name": "keyword.operator.logical.dart",
"match": "(!|&&|\\|\\|)"
},
{
"name": "storage.modifier.dart",
"match": "(?<!\\$)\\b(static|final|const|required|late)\\b(?!\\$)"
},
{
"name": "storage.type.primitive.dart",
"match": "(?<!\\$)\\b(?:void|var)\\b(?!\\$)"
}
]
},
"string-interp": {
"patterns": [
{
"match": "\\$(([a-zA-Z0-9_]+)|\\{([^{}]+)\\})",
"captures": {
"2": {
"name": "variable.parameter.dart"
},
"3": {
"name": "variable.parameter.dart"
}
}
},
{
"name": "constant.character.escape.dart",
"match": "\\\\."
}
]
},
"strings": {
"patterns": [
{
"name": "string.interpolated.triple.double.dart",
"begin": "(?<!r)\"\"\"",
"end": "\"\"\"(?!\")",
"patterns": [
{
"include": "#string-interp"
}
]
},
{
"name": "string.interpolated.triple.single.dart",
"begin": "(?<!r)'''",
"end": "'''(?!')",
"patterns": [
{
"include": "#string-interp"
}
]
},
{
"name": "string.quoted.triple.double.dart",
"begin": "r\"\"\"",
"end": "\"\"\"(?!\")"
},
{
"name": "string.quoted.triple.single.dart",
"begin": "r'''",
"end": "'''(?!')"
},
{
"name": "string.interpolated.double.dart",
"begin": "(?<!\\|r)\"",
"end": "\"",
"patterns": [
{
"name": "invalid.string.newline",
"match": "\\n"
},
{
"include": "#string-interp"
}
]
},
{
"name": "string.quoted.double.dart",
"begin": "r\"",
"end": "\"",
"patterns": [
{
"name": "invalid.string.newline",
"match": "\\n"
}
]
},
{
"name": "string.interpolated.single.dart",
"begin": "(?<!\\|r)'",
"end": "'",
"patterns": [
{
"name": "invalid.string.newline",
"match": "\\n"
},
{
"include": "#string-interp"
}
]
},
{
"name": "string.quoted.single.dart",
"begin": "r'",
"end": "'",
"patterns": [
{
"name": "invalid.string.newline",
"match": "\\n"
}
]
}
]
},
"punctuation": {
"patterns": [
{
"name": "punctuation.comma.dart",
"match": ","
},
{
"name": "punctuation.terminator.dart",
"match": ";"
},
{
"name": "punctuation.dot.dart",
"match": "\\."
}
]
}
}
}

View File

@@ -69,7 +69,7 @@
},
"devDependencies": {
"@types/markdown-it": "0.0.2",
"@types/node": "^12.19.9"
"@types/node": "14.x"
},
"repository": {
"type": "git",

View File

@@ -59,6 +59,7 @@ export class ExtensionLinter {
private readmeQ = new Set<TextDocument>();
private timer: NodeJS.Timer | undefined;
private markdownIt: MarkdownItType.MarkdownIt | undefined;
private parse5: typeof import('parse5') | undefined;
constructor() {
this.disposables.push(
@@ -202,8 +203,10 @@ export class ExtensionLinter {
let svgStart: Diagnostic;
for (const tnp of tokensAndPositions) {
if (tnp.token.type === 'text' && tnp.token.content) {
const parse5 = await import('parse5');
const parser = new parse5.SAXParser({ locationInfo: true });
if (!this.parse5) {
this.parse5 = await import('parse5');
}
const parser = new this.parse5.SAXParser({ locationInfo: true });
parser.on('startTag', (name, attrs, _selfClosing, location) => {
if (name === 'img') {
const src = attrs.find(a => a.name === 'src');

View File

@@ -7,10 +7,10 @@
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.2.tgz#5d9ad19e6e6508cdd2f2596df86fd0aade598660"
integrity sha1-XZrRnm5lCM3S8llt+G/Qqt5ZhmA=
"@types/node@^12.19.9":
version "12.19.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.9.tgz#990ad687ad8b26ef6dcc34a4f69c33d40c95b679"
integrity sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==
"@types/node@14.x":
version "14.14.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
"@types/node@^6.0.46":
version "6.0.78"

View File

@@ -2196,6 +2196,24 @@
"highContrast": "#A7A8A9"
}
},
{
"id": "gitDecoration.stageModifiedResourceForeground",
"description": "%colors.stageModified%",
"defaults": {
"light": "#895503",
"dark": "#E2C08D",
"highContrast": "#E2C08D"
}
},
{
"id": "gitDecoration.stageDeletedResourceForeground",
"description": "%colors.stageDeleted%",
"defaults": {
"light": "#ad0707",
"dark": "#c74e39",
"highContrast": "#c74e39"
}
},
{
"id": "gitDecoration.conflictingResourceForeground",
"description": "%colors.conflict%",
@@ -2366,11 +2384,12 @@
"devDependencies": {
"@types/byline": "4.2.31",
"@types/file-type": "^5.2.1",
"@types/mocha": "2.2.43",
"@types/node": "^12.12.31",
"@types/which": "^1.0.28",
"mocha": "^3.2.0",
"mocha-junit-reporter": "^1.23.3",
"mocha-multi-reporters": "^1.1.7"
"@types/mocha": "^8.2.0",
"@types/node": "14.x",
"@types/which": "^1.0.28"
},
"repository": {
"type": "git",
"url": "https://github.com/microsoft/vscode.git"
}
}

View File

@@ -197,6 +197,8 @@
"submenu.tags": "Tags",
"colors.added": "Color for added resources.",
"colors.modified": "Color for modified resources.",
"colors.stageModified": "Color for modified resources which have been staged.",
"colors.stageDeleted": "Color for deleted resources which have been staged.",
"colors.deleted": "Color for deleted resources.",
"colors.renamed": "Color for renamed or copied resources.",
"colors.untracked": "Color for untracked resources.",

View File

@@ -1947,8 +1947,7 @@ export class CommandCenter {
});
const name = inputTagName.replace(/^\.|\/\.|\.\.|~|\^|:|\/$|\.lock$|\.lock\/|\\|\*|\s|^\s*$|\.$/g, '-');
const message = inputMessage || name;
await repository.tag(name, message);
await repository.tag(name, inputMessage);
}
@command('git.deleteTag', { repository: true })

View File

@@ -3,7 +3,6 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { window, workspace, Uri, Disposable, Event, EventEmitter, FileDecoration, FileDecorationProvider, ThemeColor } from 'vscode';
import * as path from 'path';
import { Repository, GitResourceGroup } from './repository';

View File

@@ -98,4 +98,4 @@ export function debounce(delay: number): Function {
this[timerKey] = setTimeout(() => fn.apply(this, args), delay);
};
});
}
}

View File

@@ -1969,7 +1969,7 @@ export class Repository {
remote.pushUrl = url;
}
// https://github.com/Microsoft/vscode/issues/45271
// https://github.com/microsoft/vscode/issues/45271
remote.isReadOnly = remote.pushUrl === undefined || remote.pushUrl === 'no_push';
}

View File

@@ -6,8 +6,8 @@
import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import { ExtensionContext, workspace, window, Disposable, commands, Uri, OutputChannel } from 'vscode';
import { findGit, Git, IGit } from './git';
import { ExtensionContext, workspace, window, Disposable, commands, OutputChannel } from 'vscode';
import { findGit, Git } from './git';
import { Model } from './model';
import { CommandCenter } from './commands';
import { GitFileSystemProvider } from './fileSystemProvider';
@@ -18,7 +18,7 @@ import TelemetryReporter from 'vscode-extension-telemetry';
import { GitExtension } from './api/git';
import { GitProtocolHandler } from './protocolHandler';
import { GitExtensionImpl } from './api/extension';
// import * as path from 'path';
// import * as path from 'path'; {{SQL CARBON EDIT}}
// import * as fs from 'fs';
import * as os from 'os';
import { GitTimelineProvider } from './timelineProvider';
@@ -191,6 +191,7 @@ export async function activate(context: ExtensionContext): Promise<GitExtension>
return result;
}
/* {{SQL CARBON EDIT}}
async function checkGitv1(info: IGit): Promise<void> {
const config = workspace.getConfiguration('git');
const shouldIgnore = config.get<boolean>('ignoreLegacyWarning') === true;
@@ -246,11 +247,10 @@ async function checkGitWindows(info: IGit): Promise<void> {
}
}
// @ts-expect-error
async function checkGitVersion(info: IGit): Promise<void> {
await checkGitv1(info);
if (process.platform === 'win32') {
await checkGitWindows(info);
}
}
}*/

View File

@@ -268,7 +268,7 @@ export class Model implements IRemoteSourceProviderRegistry, IPushErrorHandlerRe
// This can happen whenever `path` has the wrong case sensitivity in
// case insensitive file systems
// https://github.com/Microsoft/vscode/issues/33498
// https://github.com/microsoft/vscode/issues/33498
const repositoryRoot = Uri.file(rawRoot).fsPath;
if (this.getRepository(repositoryRoot)) {

View File

@@ -18,7 +18,7 @@ export function applyLineChanges(original: TextDocument, modified: TextDocument,
// if this is a deletion at the very end of the document,then we need to account
// for a newline at the end of the last line which may have been deleted
// https://github.com/Microsoft/vscode/issues/59670
// https://github.com/microsoft/vscode/issues/59670
if (isDeletion && diff.originalEndLineNumber === original.lineCount) {
endLine -= 1;
endCharacter = original.lineAt(endLine).range.end.character;

View File

@@ -12,19 +12,19 @@ suite('git', () => {
suite('GitStatusParser', () => {
test('empty parser', () => {
const parser = new GitStatusParser();
assert.deepEqual(parser.status, []);
assert.deepStrictEqual(parser.status, []);
});
test('empty parser 2', () => {
const parser = new GitStatusParser();
parser.update('');
assert.deepEqual(parser.status, []);
assert.deepStrictEqual(parser.status, []);
});
test('simple', () => {
const parser = new GitStatusParser();
parser.update('?? file.txt\0');
assert.deepEqual(parser.status, [
assert.deepStrictEqual(parser.status, [
{ path: 'file.txt', rename: undefined, x: '?', y: '?' }
]);
});
@@ -34,7 +34,7 @@ suite('git', () => {
parser.update('?? file.txt\0');
parser.update('?? file2.txt\0');
parser.update('?? file3.txt\0');
assert.deepEqual(parser.status, [
assert.deepStrictEqual(parser.status, [
{ path: 'file.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file2.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file3.txt', rename: undefined, x: '?', y: '?' }
@@ -51,7 +51,7 @@ suite('git', () => {
parser.update('');
parser.update('?? file3.txt\0');
parser.update('');
assert.deepEqual(parser.status, [
assert.deepStrictEqual(parser.status, [
{ path: 'file.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file2.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file3.txt', rename: undefined, x: '?', y: '?' }
@@ -61,7 +61,7 @@ suite('git', () => {
test('combined', () => {
const parser = new GitStatusParser();
parser.update('?? file.txt\0?? file2.txt\0?? file3.txt\0');
assert.deepEqual(parser.status, [
assert.deepStrictEqual(parser.status, [
{ path: 'file.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file2.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file3.txt', rename: undefined, x: '?', y: '?' }
@@ -72,7 +72,7 @@ suite('git', () => {
const parser = new GitStatusParser();
parser.update('?? file.txt\0?? file2');
parser.update('.txt\0?? file3.txt\0');
assert.deepEqual(parser.status, [
assert.deepStrictEqual(parser.status, [
{ path: 'file.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file2.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file3.txt', rename: undefined, x: '?', y: '?' }
@@ -83,7 +83,7 @@ suite('git', () => {
const parser = new GitStatusParser();
parser.update('?? file.txt');
parser.update('\0?? file2.txt\0?? file3.txt\0');
assert.deepEqual(parser.status, [
assert.deepStrictEqual(parser.status, [
{ path: 'file.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file2.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file3.txt', rename: undefined, x: '?', y: '?' }
@@ -94,7 +94,7 @@ suite('git', () => {
const parser = new GitStatusParser();
parser.update('?? file.txt\0?? file2.txt\0?? file3.txt');
parser.update('\0');
assert.deepEqual(parser.status, [
assert.deepStrictEqual(parser.status, [
{ path: 'file.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file2.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file3.txt', rename: undefined, x: '?', y: '?' }
@@ -104,7 +104,7 @@ suite('git', () => {
test('rename', () => {
const parser = new GitStatusParser();
parser.update('R newfile.txt\0file.txt\0?? file2.txt\0?? file3.txt\0');
assert.deepEqual(parser.status, [
assert.deepStrictEqual(parser.status, [
{ path: 'file.txt', rename: 'newfile.txt', x: 'R', y: ' ' },
{ path: 'file2.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file3.txt', rename: undefined, x: '?', y: '?' }
@@ -115,7 +115,7 @@ suite('git', () => {
const parser = new GitStatusParser();
parser.update('R newfile.txt\0fil');
parser.update('e.txt\0?? file2.txt\0?? file3.txt\0');
assert.deepEqual(parser.status, [
assert.deepStrictEqual(parser.status, [
{ path: 'file.txt', rename: 'newfile.txt', x: 'R', y: ' ' },
{ path: 'file2.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file3.txt', rename: undefined, x: '?', y: '?' }
@@ -127,7 +127,7 @@ suite('git', () => {
parser.update('?? file2.txt\0R new');
parser.update('file.txt\0fil');
parser.update('e.txt\0?? file3.txt\0');
assert.deepEqual(parser.status, [
assert.deepStrictEqual(parser.status, [
{ path: 'file2.txt', rename: undefined, x: '?', y: '?' },
{ path: 'file.txt', rename: 'newfile.txt', x: 'R', y: ' ' },
{ path: 'file3.txt', rename: undefined, x: '?', y: '?' }
@@ -137,7 +137,7 @@ suite('git', () => {
suite('parseGitmodules', () => {
test('empty', () => {
assert.deepEqual(parseGitmodules(''), []);
assert.deepStrictEqual(parseGitmodules(''), []);
});
test('sample', () => {
@@ -146,7 +146,7 @@ suite('git', () => {
url = https://github.com/gabime/spdlog.git
`;
assert.deepEqual(parseGitmodules(sample), [
assert.deepStrictEqual(parseGitmodules(sample), [
{ name: 'deps/spdlog', path: 'deps/spdlog', url: 'https://github.com/gabime/spdlog.git' }
]);
});
@@ -166,7 +166,7 @@ suite('git', () => {
url = https://github.com/gabime/spdlog4.git
`;
assert.deepEqual(parseGitmodules(sample), [
assert.deepStrictEqual(parseGitmodules(sample), [
{ name: 'deps/spdlog', path: 'deps/spdlog', url: 'https://github.com/gabime/spdlog.git' },
{ name: 'deps/spdlog2', path: 'deps/spdlog2', url: 'https://github.com/gabime/spdlog.git' },
{ name: 'deps/spdlog3', path: 'deps/spdlog3', url: 'https://github.com/gabime/spdlog.git' },
@@ -180,7 +180,7 @@ suite('git', () => {
url = https://github.com/gabime/spdlog.git
`;
assert.deepEqual(parseGitmodules(sample), [
assert.deepStrictEqual(parseGitmodules(sample), [
{ name: 'deps/spdlog', path: 'deps/spdlog', url: 'https://github.com/gabime/spdlog.git' }
]);
});
@@ -191,7 +191,7 @@ suite('git', () => {
url=https://github.com/gabime/spdlog.git
`;
assert.deepEqual(parseGitmodules(sample), [
assert.deepStrictEqual(parseGitmodules(sample), [
{ name: 'deps/spdlog', path: 'deps/spdlog', url: 'https://github.com/gabime/spdlog.git' }
]);
});
@@ -207,7 +207,7 @@ john.doe@mail.com
8e5a374372b8393906c7e380dbb09349c5385554
This is a commit message.\x00`;
assert.deepEqual(parseGitCommits(GIT_OUTPUT_SINGLE_PARENT), [{
assert.deepStrictEqual(parseGitCommits(GIT_OUTPUT_SINGLE_PARENT), [{
hash: '52c293a05038d865604c2284aa8698bd087915a1',
message: 'This is a commit message.',
parents: ['8e5a374372b8393906c7e380dbb09349c5385554'],
@@ -227,7 +227,7 @@ john.doe@mail.com
8e5a374372b8393906c7e380dbb09349c5385554 df27d8c75b129ab9b178b386077da2822101b217
This is a commit message.\x00`;
assert.deepEqual(parseGitCommits(GIT_OUTPUT_MULTIPLE_PARENTS), [{
assert.deepStrictEqual(parseGitCommits(GIT_OUTPUT_MULTIPLE_PARENTS), [{
hash: '52c293a05038d865604c2284aa8698bd087915a1',
message: 'This is a commit message.',
parents: ['8e5a374372b8393906c7e380dbb09349c5385554', 'df27d8c75b129ab9b178b386077da2822101b217'],
@@ -247,7 +247,7 @@ john.doe@mail.com
This is a commit message.\x00`;
assert.deepEqual(parseGitCommits(GIT_OUTPUT_NO_PARENTS), [{
assert.deepStrictEqual(parseGitCommits(GIT_OUTPUT_NO_PARENTS), [{
hash: '52c293a05038d865604c2284aa8698bd087915a1',
message: 'This is a commit message.',
parents: [],
@@ -275,7 +275,7 @@ This is a commit message.\x00`;
const output = parseLsTree(input);
assert.deepEqual(output, [
assert.deepStrictEqual(output, [
{ mode: '040000', type: 'tree', object: '0274a81f8ee9ca3669295dc40f510bd2021d0043', size: '-', file: '.vscode' },
{ mode: '100644', type: 'blob', object: '1d487c1817262e4f20efbfa1d04c18f51b0046f6', size: '491570', file: 'Screen Shot 2018-06-01 at 14.48.05.png' },
{ mode: '100644', type: 'blob', object: '686c16e4f019b734655a2576ce8b98749a9ffdb9', size: '764420', file: 'Screen Shot 2018-06-07 at 20.04.59.png' },
@@ -307,7 +307,7 @@ This is a commit message.\x00`;
const output = parseLsFiles(input);
assert.deepEqual(output, [
assert.deepStrictEqual(output, [
{ mode: '100644', object: '7a73a41bfdf76d6f793007240d80983a52f15f97', stage: '0', file: '.vscode/settings.json' },
{ mode: '100644', object: '1d487c1817262e4f20efbfa1d04c18f51b0046f6', stage: '0', file: 'Screen Shot 2018-06-01 at 14.48.05.png' },
{ mode: '100644', object: '686c16e4f019b734655a2576ce8b98749a9ffdb9', stage: '0', file: 'Screen Shot 2018-06-07 at 20.04.59.png' },
@@ -325,72 +325,72 @@ This is a commit message.\x00`;
suite('splitInChunks', () => {
test('unit tests', function () {
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['hello', 'there', 'cool', 'stuff'], 6)],
[['hello'], ['there'], ['cool'], ['stuff']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['hello', 'there', 'cool', 'stuff'], 10)],
[['hello', 'there'], ['cool', 'stuff']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['hello', 'there', 'cool', 'stuff'], 12)],
[['hello', 'there'], ['cool', 'stuff']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['hello', 'there', 'cool', 'stuff'], 14)],
[['hello', 'there', 'cool'], ['stuff']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['hello', 'there', 'cool', 'stuff'], 2000)],
[['hello', 'there', 'cool', 'stuff']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 1)],
[['0'], ['01'], ['012'], ['0'], ['01'], ['012'], ['0'], ['01'], ['012']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 2)],
[['0'], ['01'], ['012'], ['0'], ['01'], ['012'], ['0'], ['01'], ['012']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 3)],
[['0', '01'], ['012'], ['0', '01'], ['012'], ['0', '01'], ['012']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 4)],
[['0', '01'], ['012', '0'], ['01'], ['012', '0'], ['01'], ['012']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 5)],
[['0', '01'], ['012', '0'], ['01', '012'], ['0', '01'], ['012']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 6)],
[['0', '01', '012'], ['0', '01', '012'], ['0', '01', '012']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 7)],
[['0', '01', '012', '0'], ['01', '012', '0'], ['01', '012']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 8)],
[['0', '01', '012', '0'], ['01', '012', '0', '01'], ['012']]
);
assert.deepEqual(
assert.deepStrictEqual(
[...splitInChunks(['0', '01', '012', '0', '01', '012', '0', '01', '012'], 9)],
[['0', '01', '012', '0', '01'], ['012', '0', '01', '012']]
);

View File

@@ -59,8 +59,8 @@ suite('git smoke test', function () {
await eventToPromise(git.onDidOpenRepository);
}
assert.equal(git.repositories.length, 1);
assert.equal(fs.realpathSync(git.repositories[0].rootUri.fsPath), cwd);
assert.strictEqual(git.repositories.length, 1);
assert.strictEqual(fs.realpathSync(git.repositories[0].rootUri.fsPath), cwd);
repository = git.repositories[0];
});
@@ -72,7 +72,7 @@ suite('git smoke test', function () {
await type(appjs, ' world');
await appjs.save();
await repository.status();
assert.equal(repository.state.workingTreeChanges.length, 1);
assert.strictEqual(repository.state.workingTreeChanges.length, 1);
repository.state.workingTreeChanges.some(r => r.uri.path === appjs.uri.path && r.status === Status.MODIFIED);
fs.writeFileSync(file('newfile.txt'), '');
@@ -80,7 +80,7 @@ suite('git smoke test', function () {
await type(newfile, 'hey there');
await newfile.save();
await repository.status();
assert.equal(repository.state.workingTreeChanges.length, 2);
assert.strictEqual(repository.state.workingTreeChanges.length, 2);
repository.state.workingTreeChanges.some(r => r.uri.path === appjs.uri.path && r.status === Status.MODIFIED);
repository.state.workingTreeChanges.some(r => r.uri.path === newfile.uri.path && r.status === Status.UNTRACKED);
});
@@ -90,7 +90,7 @@ suite('git smoke test', function () {
await commands.executeCommand('git.openChange', appjs);
assert(window.activeTextEditor);
assert.equal(window.activeTextEditor!.document.uri.path, appjs.path);
assert.strictEqual(window.activeTextEditor!.document.uri.path, appjs.path);
// TODO: how do we really know this is a diff editor?
});
@@ -100,13 +100,13 @@ suite('git smoke test', function () {
const newfile = uri('newfile.txt');
await commands.executeCommand('git.stage', appjs);
assert.equal(repository.state.workingTreeChanges.length, 1);
assert.strictEqual(repository.state.workingTreeChanges.length, 1);
repository.state.workingTreeChanges.some(r => r.uri.path === newfile.path && r.status === Status.UNTRACKED);
assert.equal(repository.state.indexChanges.length, 1);
assert.strictEqual(repository.state.indexChanges.length, 1);
repository.state.indexChanges.some(r => r.uri.path === appjs.path && r.status === Status.INDEX_MODIFIED);
await commands.executeCommand('git.unstage', appjs);
assert.equal(repository.state.workingTreeChanges.length, 2);
assert.strictEqual(repository.state.workingTreeChanges.length, 2);
repository.state.workingTreeChanges.some(r => r.uri.path === appjs.path && r.status === Status.MODIFIED);
repository.state.workingTreeChanges.some(r => r.uri.path === newfile.path && r.status === Status.UNTRACKED);
});
@@ -117,14 +117,14 @@ suite('git smoke test', function () {
await commands.executeCommand('git.stage', appjs);
await repository.commit('second commit');
assert.equal(repository.state.workingTreeChanges.length, 1);
assert.strictEqual(repository.state.workingTreeChanges.length, 1);
repository.state.workingTreeChanges.some(r => r.uri.path === newfile.path && r.status === Status.UNTRACKED);
assert.equal(repository.state.indexChanges.length, 0);
assert.strictEqual(repository.state.indexChanges.length, 0);
await commands.executeCommand('git.stageAll', appjs);
await repository.commit('third commit');
assert.equal(repository.state.workingTreeChanges.length, 0);
assert.equal(repository.state.indexChanges.length, 0);
assert.strictEqual(repository.state.workingTreeChanges.length, 0);
assert.strictEqual(repository.state.indexChanges.length, 0);
});
test('rename/delete conflict', async function () {

View File

@@ -353,7 +353,7 @@ export class Limiter<T> {
}
queue(factory: () => Promise<T>): Promise<T> {
return new Promise((c, e) => {
return new Promise<T>((c, e) => {
this.outstandingPromises.push({ factory, c, e });
this.consume();
});

View File

@@ -16,31 +16,26 @@
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"
integrity sha512-xNlAmH+lRJdUMXClMTI9Y0pRqIojdxfm7DHsIxoB2iTzu3fnPmSMEN8SsSx0cdwV36d02PWCWaDUoZPDSln+xw==
"@types/mocha@^8.2.0":
version "8.2.3"
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.3.tgz#bbeb55fbc73f28ea6de601fbfa4613f58d785323"
integrity sha512-ekGvFhFgrc2zYQoX4JeZPmVzZxw6Dtllga7iGHzfbYIYkAMUx/sAFP2GdFpLff+vdHXu5fl7WX9AT+TtqYcsyw==
"@types/node@*":
version "8.0.51"
resolved "https://registry.yarnpkg.com/@types/node/-/node-8.0.51.tgz#b31d716fb8d58eeb95c068a039b9b6292817d5fb"
integrity sha512-El3+WJk2D/ppWNd2X05aiP5l2k4EwF7KwheknQZls+I26eSICoWRhRIJ56jGgw2dqNGQ5LtNajmBU2ajS28EvQ==
"@types/node@^12.12.31":
version "12.12.31"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.12.31.tgz#d6b4f9645fee17f11319b508fb1001797425da51"
integrity sha512-T+wnJno8uh27G9c+1T+a1/WYCHzLeDqtsGJkoEdSp2X8RTh3oOCZQcUnjAx90CS8cmmADX51O0FI/tu9s0yssg==
"@types/node@14.x":
version "14.14.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
"@types/which@^1.0.28":
version "1.0.28"
resolved "https://registry.yarnpkg.com/@types/which/-/which-1.0.28.tgz#016e387629b8817bed653fe32eab5d11279c8df6"
integrity sha1-AW44dim4gXvtZT/jLqtdESecjfY=
ansi-regex@^3.0.0:
version "3.0.0"
resolved "https://registry.yarnpkg.com/ansi-regex/-/ansi-regex-3.0.0.tgz#ed0317c322064f79466c02966bddb605ab37d998"
integrity sha1-7QMXwyIGT3lGbAKWa922Bas32Zg=
applicationinsights@1.7.4:
version "1.7.4"
resolved "https://registry.yarnpkg.com/applicationinsights/-/applicationinsights-1.7.4.tgz#e7d96435594d893b00cf49f70a5927105dbb8749"
@@ -66,34 +61,11 @@ async-listener@^0.6.0:
semver "^5.3.0"
shimmer "^1.1.0"
balanced-match@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/balanced-match/-/balanced-match-1.0.0.tgz#89b4d199ab2bee49de164ea02b89ce462d71b767"
integrity sha1-ibTRmasr7kneFk6gK4nORi1xt2c=
brace-expansion@^1.1.7:
version "1.1.8"
resolved "https://registry.yarnpkg.com/brace-expansion/-/brace-expansion-1.1.8.tgz#c07b211c7c952ec1f8efd51a77ef0d1d3990a292"
integrity sha1-wHshHHyVLsH479Uad+8NHTmQopI=
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"
integrity sha1-81HTKWnTL6XXpVZxVCY9korjvR8=
byline@^5.0.0:
version "5.0.0"
resolved "https://registry.yarnpkg.com/byline/-/byline-5.0.0.tgz#741c5216468eadc457b03410118ad77de8c1ddb1"
integrity sha1-dBxSFkaOrcRXsDQQEYrXfejB3bE=
charenc@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/charenc/-/charenc-0.0.2.tgz#c0a1d2f3a7092e03774bfa83f14c0fc5790a8667"
integrity sha1-wKHS86cJLgN3S/qD8UwPxXkKhmc=
cls-hooked@^4.2.2:
version "4.2.2"
resolved "https://registry.yarnpkg.com/cls-hooked/-/cls-hooked-4.2.2.tgz#ad2e9a4092680cdaffeb2d3551da0e225eae1908"
@@ -103,18 +75,6 @@ cls-hooked@^4.2.2:
emitter-listener "^1.0.1"
semver "^5.4.1"
commander@2.9.0:
version "2.9.0"
resolved "https://registry.yarnpkg.com/commander/-/commander-2.9.0.tgz#9c99094176e12240cb22d6c5146098400fe0f7d4"
integrity sha1-nJkJQXbhIkDLItbFFGCYQA/g99Q=
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"
integrity sha1-2Klr13/Wjfd5OnMDajug1UBdR3s=
continuation-local-storage@^3.2.1:
version "3.2.1"
resolved "https://registry.yarnpkg.com/continuation-local-storage/-/continuation-local-storage-3.2.1.tgz#11f613f74e914fe9b34c92ad2d28fe6ae1db7ffb"
@@ -123,32 +83,6 @@ continuation-local-storage@^3.2.1:
async-listener "^0.6.0"
emitter-listener "^1.1.1"
crypt@~0.0.1:
version "0.0.2"
resolved "https://registry.yarnpkg.com/crypt/-/crypt-0.0.2.tgz#88d7ff7ec0dfb86f713dc87bbb42d044d3e6c41b"
integrity sha1-iNf/fsDfuG9xPch7u0LQRNPmxBs=
debug@2.6.8:
version "2.6.8"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.8.tgz#e731531ca2ede27d188222427da17821d68ff4fc"
integrity sha1-5zFTHKLt4n0YgiJCfaF4IdaP9Pw=
dependencies:
ms "2.0.0"
debug@^2.2.0:
version "2.6.9"
resolved "https://registry.yarnpkg.com/debug/-/debug-2.6.9.tgz#5d128515df134ff327e90a4c93f4e077a536341f"
integrity sha512-bC7ElrdJaJnPbAP+1EotYvqZsb3ecl5wi6Bfi6BJTUcNowp6cvspg0jXznRTKDjm/E7AdgFBVeAPVMNcKGsHMA==
dependencies:
ms "2.0.0"
debug@^3.1.0:
version "3.2.7"
resolved "https://registry.yarnpkg.com/debug/-/debug-3.2.7.tgz#72580b7e9145fb39b6676f9c5e5fb100b934179a"
integrity sha512-CFjzYYAi4ThfiQvizrFQevTTXHtnCqWfe7x1AhgEscTz6ZbLbfoLRLPugTQyBth6f8ZERVUSyWHFD/7Wu4t1XQ==
dependencies:
ms "^2.1.1"
diagnostic-channel-publishers@^0.3.3:
version "0.3.5"
resolved "https://registry.yarnpkg.com/diagnostic-channel-publishers/-/diagnostic-channel-publishers-0.3.5.tgz#a84a05fd6cc1d7619fdd17791c17e540119a7536"
@@ -161,11 +95,6 @@ diagnostic-channel@0.2.0:
dependencies:
semver "^5.3.0"
diff@3.2.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/diff/-/diff-3.2.0.tgz#c9ce393a4b7cbd0b058a725c93df299027868ff9"
integrity sha1-yc45Okt8vQsFinJck98pkCeGj/k=
emitter-listener@^1.0.1, emitter-listener@^1.1.1:
version "1.1.2"
resolved "https://registry.yarnpkg.com/emitter-listener/-/emitter-listener-1.1.2.tgz#56b140e8f6992375b3d7cb2cab1cc7432d9632e8"
@@ -173,76 +102,16 @@ emitter-listener@^1.0.1, emitter-listener@^1.1.1:
dependencies:
shimmer "^1.2.0"
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"
integrity sha1-G2HAViGQqN/2rjuyzwIAyhMLhtQ=
file-type@^7.2.0:
version "7.2.0"
resolved "https://registry.yarnpkg.com/file-type/-/file-type-7.2.0.tgz#113cfed52e1d6959ab80248906e2f25a8cdccb74"
integrity sha1-ETz+1S4daVmrgCSJBuLyWozcy3Q=
fs.realpath@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/fs.realpath/-/fs.realpath-1.0.0.tgz#1504ad2523158caa40db4a2787cb01411994ea4f"
integrity sha1-FQStJSMVjKpA20onh8sBQRmU6k8=
glob@7.1.1:
version "7.1.1"
resolved "https://registry.yarnpkg.com/glob/-/glob-7.1.1.tgz#805211df04faaf1c63a3600306cdf5ade50b2ec8"
integrity sha1-gFIR3wT6rxxjo2ADBs31reULLsg=
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"
integrity sha1-TK+tdrxi8C+gObL5Tpo906ORpyU=
growl@1.9.2:
version "1.9.2"
resolved "https://registry.yarnpkg.com/growl/-/growl-1.9.2.tgz#0ea7743715db8d8de2c5ede1775e1b45ac85c02f"
integrity sha1-Dqd0NxXbjY3ixe3hd14bRayFwC8=
has-flag@^1.0.0:
version "1.0.0"
resolved "https://registry.yarnpkg.com/has-flag/-/has-flag-1.0.0.tgz#9d9e793165ce017a00f00418c43f942a7b1d11fa"
integrity sha1-nZ55MWXOAXoA8AQYxD+UKnsdEfo=
he@1.1.1:
version "1.1.1"
resolved "https://registry.yarnpkg.com/he/-/he-1.1.1.tgz#93410fd21b009735151f8868c2f271f3427e23fd"
integrity sha1-k0EP0hsAlzUVH4howvJx80J+I/0=
iconv-lite-umd@0.6.8:
version "0.6.8"
resolved "https://registry.yarnpkg.com/iconv-lite-umd/-/iconv-lite-umd-0.6.8.tgz#5ad310ec126b260621471a2d586f7f37b9958ec0"
integrity sha512-zvXJ5gSwMC9JD3wDzH8CoZGc1pbiJn12Tqjk8BXYCnYz3hYL5GRjHW8LEykjXhV9WgNGI4rgpgHcbIiBfrRq6A==
inflight@^1.0.4:
version "1.0.6"
resolved "https://registry.yarnpkg.com/inflight/-/inflight-1.0.6.tgz#49bd6331d7d02d0c09bc910a1075ba8165b56df9"
integrity sha1-Sb1jMdfQLQwJvJEKEHW6gWW1bfk=
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"
integrity sha1-Yzwsg+PaQqUC9SRmAiSA9CCCYd4=
is-buffer@~1.1.1:
version "1.1.6"
resolved "https://registry.yarnpkg.com/is-buffer/-/is-buffer-1.1.6.tgz#efaa2ea9daa0d7ab2ea13a97b2b8ad51fefbe8be"
integrity sha512-NcdALwpXkTm5Zvvbk7owOUSvVvBKDgKP5/ewfXEznmQFfs4ZRmanOeKBTjRVjka3QFoN6XJ+9F3USqfHqTaU5w==
isexe@^2.0.0:
version "2.0.0"
resolved "https://registry.yarnpkg.com/isexe/-/isexe-2.0.0.tgz#e8fbf374dc556ff8947a10dcb0572d633f2cfa10"
@@ -253,159 +122,6 @@ jschardet@2.3.0:
resolved "https://registry.yarnpkg.com/jschardet/-/jschardet-2.3.0.tgz#06e2636e16c8ada36feebbdc08aa34e6a9b3ff75"
integrity sha512-6I6xT7XN/7sBB7q8ObzKbmv5vN+blzLcboDE1BNEsEfmRXJValMxO6OIRT69ylPBRemS3rw6US+CMCar0OBc9g==
json3@3.3.2:
version "3.3.2"
resolved "https://registry.yarnpkg.com/json3/-/json3-3.3.2.tgz#3c0434743df93e2f5c42aee7b19bcb483575f4e1"
integrity sha1-PAQ0dD35Pi9cQq7nsZvLSDV19OE=
lodash._baseassign@^3.0.0:
version "3.2.0"
resolved "https://registry.yarnpkg.com/lodash._baseassign/-/lodash._baseassign-3.2.0.tgz#8c38a099500f215ad09e59f1722fd0c52bfe0a4e"
integrity sha1-jDigmVAPIVrQnlnxci/QxSv+Ck4=
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"
integrity sha1-jaDmqHbPNEwK2KVIghEd08XHyjY=
lodash._basecreate@^3.0.0:
version "3.0.3"
resolved "https://registry.yarnpkg.com/lodash._basecreate/-/lodash._basecreate-3.0.3.tgz#1bc661614daa7fc311b7d03bf16806a0213cf821"
integrity sha1-G8ZhYU2qf8MRt9A78WgGoCE8+CE=
lodash._getnative@^3.0.0:
version "3.9.1"
resolved "https://registry.yarnpkg.com/lodash._getnative/-/lodash._getnative-3.9.1.tgz#570bc7dede46d61cdcde687d65d3eecbaa3aaff5"
integrity sha1-VwvH3t5G1hzc3mh9ZdPuy6o6r/U=
lodash._isiterateecall@^3.0.0:
version "3.0.9"
resolved "https://registry.yarnpkg.com/lodash._isiterateecall/-/lodash._isiterateecall-3.0.9.tgz#5203ad7ba425fae842460e696db9cf3e6aac057c"
integrity sha1-UgOte6Ql+uhCRg5pbbnPPmqsBXw=
lodash.create@3.1.1:
version "3.1.1"
resolved "https://registry.yarnpkg.com/lodash.create/-/lodash.create-3.1.1.tgz#d7f2849f0dbda7e04682bb8cd72ab022461debe7"
integrity sha1-1/KEnw29p+BGgruM1yqwIkYd6+c=
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"
integrity sha1-L1c9hcaiQon/AGY7SRwdM4/zRYo=
lodash.isarray@^3.0.0:
version "3.0.4"
resolved "https://registry.yarnpkg.com/lodash.isarray/-/lodash.isarray-3.0.4.tgz#79e4eb88c36a8122af86f844aa9bcd851b5fbb55"
integrity sha1-eeTriMNqgSKvhvhEqpvNhRtfu1U=
lodash.keys@^3.0.0:
version "3.1.2"
resolved "https://registry.yarnpkg.com/lodash.keys/-/lodash.keys-3.1.2.tgz#4dbc0472b156be50a0b286855d1bd0b0c656098a"
integrity sha1-TbwEcrFWvlCgsoaFXRvQsMZWCYo=
dependencies:
lodash._getnative "^3.0.0"
lodash.isarguments "^3.0.0"
lodash.isarray "^3.0.0"
lodash@^4.16.4:
version "4.17.15"
resolved "https://registry.yarnpkg.com/lodash/-/lodash-4.17.15.tgz#b447f6670a0455bbfeedd11392eff330ea097548"
integrity sha512-8xOcRHvCjnocdS5cpwXQXVzmmh5e5+saE2QGoeQmbKmRS6J3VQppPOIt0MnmE+4xlZoumy0GPG0D0MVIQbNA1A==
md5@^2.1.0:
version "2.2.1"
resolved "https://registry.yarnpkg.com/md5/-/md5-2.2.1.tgz#53ab38d5fe3c8891ba465329ea23fac0540126f9"
integrity sha1-U6s41f48iJG6RlMp6iP6wFQBJvk=
dependencies:
charenc "~0.0.1"
crypt "~0.0.1"
is-buffer "~1.1.1"
minimatch@^3.0.2:
version "3.0.4"
resolved "https://registry.yarnpkg.com/minimatch/-/minimatch-3.0.4.tgz#5166e286457f03306064be5497e8dbb0c3d32083"
integrity sha512-yJHVQEhyqPLUTgt9B83PXu6W3rx4MvvHvSUvToogpwoGDOUQ+yDrR0HRot+yOCdCO7u4hX3pWft6kWBBcqh0UA==
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"
integrity sha1-hX/Kv8M5fSYluCKCYuhqp6ARsF0=
mkdirp@0.5.1, mkdirp@~0.5.1:
version "0.5.1"
resolved "https://registry.yarnpkg.com/mkdirp/-/mkdirp-0.5.1.tgz#30057438eac6cf7f8c4767f38648d6697d75c903"
integrity sha1-MAV0OOrGz3+MR2fzhkjWaX11yQM=
dependencies:
minimist "0.0.8"
mocha-junit-reporter@^1.23.3:
version "1.23.3"
resolved "https://registry.yarnpkg.com/mocha-junit-reporter/-/mocha-junit-reporter-1.23.3.tgz#941e219dd759ed732f8641e165918aa8b167c981"
integrity sha512-ed8LqbRj1RxZfjt/oC9t12sfrWsjZ3gNnbhV1nuj9R/Jb5/P3Xb4duv2eCfCDMYH+fEu0mqca7m4wsiVjsxsvA==
dependencies:
debug "^2.2.0"
md5 "^2.1.0"
mkdirp "~0.5.1"
strip-ansi "^4.0.0"
xml "^1.0.0"
mocha-multi-reporters@^1.1.7:
version "1.1.7"
resolved "https://registry.yarnpkg.com/mocha-multi-reporters/-/mocha-multi-reporters-1.1.7.tgz#cc7f3f4d32f478520941d852abb64d9988587d82"
integrity sha1-zH8/TTL0eFIJQdhSq7ZNmYhYfYI=
dependencies:
debug "^3.1.0"
lodash "^4.16.4"
mocha@^3.2.0:
version "3.5.3"
resolved "https://registry.yarnpkg.com/mocha/-/mocha-3.5.3.tgz#1e0480fe36d2da5858d1eb6acc38418b26eaa20d"
integrity sha512-/6na001MJWEtYxHOV1WLfsmR4YIynkUEhBwzsb+fk2qmQ3iqsi258l/Q2MWHJMImAcNpZ8DEdYAK72NHoIQ9Eg==
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"
integrity sha1-VgiurfwAvmwpAd9fmGF4jeDVl8g=
ms@^2.1.1:
version "2.1.2"
resolved "https://registry.yarnpkg.com/ms/-/ms-2.1.2.tgz#d09d1f357b443f493382a8eb3ccd183872ae6009"
integrity sha512-sGkPx+VjMtmA6MX27oA4FBFELFCZZ4S4XqeGOXCv68tT+jb3vk/RyaKWP0PTKyWtmLSM0b+adUTEvbs1PEaH2w==
once@^1.3.0:
version "1.4.0"
resolved "https://registry.yarnpkg.com/once/-/once-1.4.0.tgz#583b1aa775961d4b113ac17d9c50baef9dd76bd1"
integrity sha1-WDsap3WWHUsROsF9nFC6753Xa9E=
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"
integrity sha1-F0uSaHNVNP+8es5r9TpanhtcX18=
semver@^5.3.0:
version "5.5.0"
resolved "https://registry.yarnpkg.com/semver/-/semver-5.5.0.tgz#dc4bbc7a6ca9d916dee5d43516f0092b58f7b8ab"
@@ -426,20 +142,6 @@ stack-chain@^1.3.7:
resolved "https://registry.yarnpkg.com/stack-chain/-/stack-chain-1.3.7.tgz#d192c9ff4ea6a22c94c4dd459171e3f00cea1285"
integrity sha1-0ZLJ/06moiyUxN1FkXHj8AzqEoU=
strip-ansi@^4.0.0:
version "4.0.0"
resolved "https://registry.yarnpkg.com/strip-ansi/-/strip-ansi-4.0.0.tgz#a8479022eb1ac368a871389b635262c505ee368f"
integrity sha1-qEeQIusaw2iocTibY1JixQXuNo8=
dependencies:
ansi-regex "^3.0.0"
supports-color@3.1.2:
version "3.1.2"
resolved "https://registry.yarnpkg.com/supports-color/-/supports-color-3.1.2.tgz#72a262894d9d408b956ca05ff37b2ed8a6e2a2d5"
integrity sha1-cqJiiU2dQIuVbKBf83su2KbiotU=
dependencies:
has-flag "^1.0.0"
vscode-extension-telemetry@0.1.7:
version "0.1.7"
resolved "https://registry.yarnpkg.com/vscode-extension-telemetry/-/vscode-extension-telemetry-0.1.7.tgz#18389bc24127c89dade29cd2b71ba69a6ee6ad26"
@@ -463,13 +165,3 @@ which@^1.3.0:
integrity sha512-xcJpopdamTuY5duC/KnTTNBraPK54YwpenP4lzxU8H91GudWpFv38u0CKjclE1Wi2EH2EDz5LRcHcKbCIzqGyg==
dependencies:
isexe "^2.0.0"
wrappy@1:
version "1.0.2"
resolved "https://registry.yarnpkg.com/wrappy/-/wrappy-1.0.2.tgz#b5243d8f3ec1aa35f1364605bc0d1036e30ab69f"
integrity sha1-tSQ9jz7BqjXxNkYFvA0QNuMKtp8=
xml@^1.0.0:
version "1.0.1"
resolved "https://registry.yarnpkg.com/xml/-/xml-1.0.1.tgz#78ba72020029c5bc87b8a81a3cfcd74b4a2fc1e5"
integrity sha1-eLpyAgApxbyHuKgaPPzXS0ovweU=

View File

@@ -4,7 +4,7 @@
"description": "%description%",
"publisher": "vscode",
"license": "MIT",
"version": "0.0.1",
"version": "0.0.2",
"engines": {
"vscode": "^1.41.0"
},
@@ -19,7 +19,8 @@
"web"
],
"activationEvents": [
"onAuthenticationRequest:github"
"onAuthenticationRequest:github",
"onAuthenticationRequest:github-enterprise"
],
"capabilities": {
"virtualWorkspaces": true,
@@ -31,7 +32,14 @@
"commands": [
{
"command": "github.provide-token",
"title": "Manually Provide Token"
"title": "Manually Provide Token",
"category": "GitHub"
},
{
"command": "github-enterprise.provide-token",
"title": "Manually Provide Token",
"category": "GitHub Enterprise"
}
],
"menus": {
@@ -39,6 +47,10 @@
{
"command": "github.provide-token",
"when": "false"
},
{
"command": "github-enterprise.provide-token",
"when": "false"
}
]
},
@@ -46,8 +58,21 @@
{
"label": "GitHub",
"id": "github"
},
{
"label": "GitHub Enterprise",
"id": "github-enterprise"
}
]
],
"configuration": {
"title": "GitHub Enterprise Authentication Provider",
"properties": {
"github-enterprise.uri" : {
"type": "string",
"description": "URI of your GitHub Enterprise Instanace"
}
}
}
},
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
"main": "./out/extension.js",
@@ -67,7 +92,7 @@
"vscode-tas-client": "^0.1.22"
},
"devDependencies": {
"@types/node": "^12.19.9",
"@types/node": "14.x",
"@types/node-fetch": "^2.5.7",
"@types/uuid": "8.0.0"
},

View File

@@ -28,13 +28,11 @@ export type Keytar = {
deletePassword: typeof keytarType['deletePassword'];
};
const SERVICE_ID = `github.auth`;
export class Keychain {
constructor(private context: vscode.ExtensionContext) { }
constructor(private context: vscode.ExtensionContext, private serviceId: string) { }
async setToken(token: string): Promise<void> {
try {
return await this.context.secrets.store(SERVICE_ID, token);
return await this.context.secrets.store(this.serviceId, token);
} catch (e) {
// Ignore
Logger.error(`Setting token failed: ${e}`);
@@ -48,7 +46,7 @@ export class Keychain {
async getToken(): Promise<string | null | undefined> {
try {
return await this.context.secrets.get(SERVICE_ID);
return await this.context.secrets.get(this.serviceId);
} catch (e) {
// Ignore
Logger.error(`Getting token failed: ${e}`);
@@ -58,7 +56,7 @@ export class Keychain {
async deleteToken(): Promise<void> {
try {
return await this.context.secrets.delete(SERVICE_ID);
return await this.context.secrets.delete(this.serviceId);
} catch (e) {
// Ignore
Logger.error(`Deleting token failed: ${e}`);

View File

@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';

View File

@@ -4,9 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { GitHubAuthenticationProvider, onDidChangeSessions } from './github';
import { uriHandler } from './githubServer';
import Logger from './common/logger';
import { GitHubAuthenticationProvider, AuthProviderType } from './github';
import TelemetryReporter from 'vscode-extension-telemetry';
import { createExperimentationService, ExperimentationTelemetry } from './experimentationService';
@@ -17,74 +15,13 @@ export async function activate(context: vscode.ExtensionContext) {
const experimentationService = await createExperimentationService(context, telemetryReporter);
await experimentationService.initialFetch;
context.subscriptions.push(vscode.window.registerUriHandler(uriHandler));
const loginService = new GitHubAuthenticationProvider(context, telemetryReporter);
await loginService.initialize(context);
context.subscriptions.push(vscode.commands.registerCommand('github.provide-token', () => {
return loginService.manuallyProvideToken();
}));
context.subscriptions.push(vscode.authentication.registerAuthenticationProvider('github', 'GitHub', {
onDidChangeSessions: onDidChangeSessions.event,
getSessions: (scopes?: string[]) => loginService.getSessions(scopes),
createSession: async (scopeList: string[]) => {
try {
/* __GDPR__
"login" : { }
*/
telemetryReporter.sendTelemetryEvent('login');
const session = await loginService.createSession(scopeList.sort().join(' '));
Logger.info('Login success!');
onDidChangeSessions.fire({ added: [session], removed: [], changed: [] });
return session;
} catch (e) {
// If login was cancelled, do not notify user.
if (e.message === 'Cancelled') {
/* __GDPR__
"loginCancelled" : { }
*/
telemetryReporter.sendTelemetryEvent('loginCancelled');
throw e;
}
/* __GDPR__
"loginFailed" : { }
*/
telemetryReporter.sendTelemetryEvent('loginFailed');
vscode.window.showErrorMessage(`Sign in failed: ${e}`);
Logger.error(e);
throw e;
}
},
removeSession: async (id: string) => {
try {
/* __GDPR__
"logout" : { }
*/
telemetryReporter.sendTelemetryEvent('logout');
const session = await loginService.removeSession(id);
if (session) {
onDidChangeSessions.fire({ added: [], removed: [session], changed: [] });
}
} catch (e) {
/* __GDPR__
"logoutFailed" : { }
*/
telemetryReporter.sendTelemetryEvent('logoutFailed');
vscode.window.showErrorMessage(`Sign out failed: ${e}`);
Logger.error(e);
throw e;
}
}
}, { supportsMultipleAccounts: false }));
return;
[
AuthProviderType.github,
AuthProviderType['github-enterprise']
].forEach(async type => {
const loginService = new GitHubAuthenticationProvider(context, type, telemetryReporter);
await loginService.initialize();
});
}
// this method is called when your extension is deactivated

View File

@@ -6,13 +6,11 @@
import * as vscode from 'vscode';
import { v4 as uuid } from 'uuid';
import { Keychain } from './common/keychain';
import { GitHubServer, NETWORK_ERROR } from './githubServer';
import { GitHubServer, uriHandler, NETWORK_ERROR } from './githubServer';
import Logger from './common/logger';
import { arrayEquals } from './common/utils';
import { ExperimentationTelemetry } from './experimentationService';
export const onDidChangeSessions = new vscode.EventEmitter<vscode.AuthenticationProviderAuthenticationSessionsChangeEvent>();
interface SessionData {
id: string;
account?: {
@@ -24,18 +22,29 @@ interface SessionData {
accessToken: string;
}
export class GitHubAuthenticationProvider {
export enum AuthProviderType {
github = 'github',
'github-enterprise' = 'github-enterprise'
}
export class GitHubAuthenticationProvider implements vscode.AuthenticationProvider {
private _sessions: vscode.AuthenticationSession[] = [];
private _sessionChangeEmitter = new vscode.EventEmitter<vscode.AuthenticationProviderAuthenticationSessionsChangeEvent>();
private _githubServer: GitHubServer;
private _keychain: Keychain;
constructor(context: vscode.ExtensionContext, telemetryReporter: ExperimentationTelemetry) {
this._keychain = new Keychain(context);
this._githubServer = new GitHubServer(telemetryReporter);
constructor(private context: vscode.ExtensionContext, private type: AuthProviderType, private telemetryReporter: ExperimentationTelemetry) {
this._keychain = new Keychain(context, `${type}.auth`);
this._githubServer = new GitHubServer(type, telemetryReporter);
}
public async initialize(context: vscode.ExtensionContext): Promise<void> {
get onDidChangeSessions() {
return this._sessionChangeEmitter.event;
}
public async initialize(): Promise<void> {
try {
this._sessions = await this.readSessions();
await this.verifySessions();
@@ -43,7 +52,17 @@ export class GitHubAuthenticationProvider {
// Ignore, network request failed
}
context.subscriptions.push(context.secrets.onDidChange(() => this.checkForUpdates()));
let friendlyName = 'GitHub';
if (this.type === AuthProviderType.github) {
this.context.subscriptions.push(vscode.window.registerUriHandler(uriHandler));
}
if (this.type === AuthProviderType['github-enterprise']) {
friendlyName = 'GitHub Enterprise';
}
this.context.subscriptions.push(vscode.commands.registerCommand(`${this.type}.provide-token`, () => this.manuallyProvideToken()));
this.context.subscriptions.push(vscode.authentication.registerAuthenticationProvider(this.type, friendlyName, this, { supportsMultipleAccounts: false }));
this.context.subscriptions.push(this.context.secrets.onDidChange(() => this.checkForUpdates()));
}
async getSessions(scopes?: string[]): Promise<vscode.AuthenticationSession[]> {
@@ -52,12 +71,21 @@ export class GitHubAuthenticationProvider {
: this._sessions;
}
private async afterTokenLoad(token: string): Promise<void> {
if (this.type === AuthProviderType.github) {
this._githubServer.checkIsEdu(token);
}
if (this.type === AuthProviderType['github-enterprise']) {
this._githubServer.checkEnterpriseVersion(token);
}
}
private async verifySessions(): Promise<void> {
const verifiedSessions: vscode.AuthenticationSession[] = [];
const verificationPromises = this._sessions.map(async session => {
try {
await this._githubServer.getUserInfo(session.accessToken);
this._githubServer.checkIsEdu(session.accessToken);
this.afterTokenLoad(session.accessToken);
verifiedSessions.push(session);
} catch (e) {
// Remove sessions that return unauthorized response
@@ -97,7 +125,7 @@ export class GitHubAuthenticationProvider {
}
});
this._sessions.map(session => {
this._sessions.forEach(session => {
const matchesExisting = storedSessions.some(s => s.id === session.id);
// Another window has logged out, remove from our state
if (!matchesExisting) {
@@ -112,7 +140,7 @@ export class GitHubAuthenticationProvider {
});
if (added.length || removed.length) {
onDidChangeSessions.fire({ added, removed, changed: [] });
this._sessionChangeEmitter.fire({ added, removed, changed: [] });
}
}
@@ -163,12 +191,41 @@ export class GitHubAuthenticationProvider {
return this._sessions;
}
public async createSession(scopes: string): Promise<vscode.AuthenticationSession> {
const token = await this._githubServer.login(scopes);
const session = await this.tokenToSession(token, scopes.split(' '));
this._githubServer.checkIsEdu(token);
await this.setToken(session);
return session;
public async createSession(scopes: string[]): Promise<vscode.AuthenticationSession> {
try {
/* __GDPR__
"login" : { }
*/
this.telemetryReporter?.sendTelemetryEvent('login');
const token = await this._githubServer.login(scopes.join(' '));
this.afterTokenLoad(token);
const session = await this.tokenToSession(token, scopes);
await this.setToken(session);
this._sessionChangeEmitter.fire({ added: [session], removed: [], changed: [] });
Logger.info('Login success!');
return session;
} catch (e) {
// If login was cancelled, do not notify user.
if (e.message === 'Cancelled') {
/* __GDPR__
"loginCancelled" : { }
*/
this.telemetryReporter?.sendTelemetryEvent('loginCancelled');
throw e;
}
/* __GDPR__
"loginFailed" : { }
*/
this.telemetryReporter?.sendTelemetryEvent('loginFailed');
vscode.window.showErrorMessage(`Sign in failed: ${e}`);
Logger.error(e);
throw e;
}
}
public async manuallyProvideToken(): Promise<void> {
@@ -196,18 +253,33 @@ export class GitHubAuthenticationProvider {
await this.storeSessions();
}
public async removeSession(id: string): Promise<vscode.AuthenticationSession | undefined> {
Logger.info(`Logging out of ${id}`);
const sessionIndex = this._sessions.findIndex(session => session.id === id);
let session: vscode.AuthenticationSession | undefined;
if (sessionIndex > -1) {
session = this._sessions[sessionIndex];
this._sessions.splice(sessionIndex, 1);
} else {
Logger.error('Session not found');
}
public async removeSession(id: string) {
try {
/* __GDPR__
"logout" : { }
*/
this.telemetryReporter?.sendTelemetryEvent('logout');
await this.storeSessions();
return session;
Logger.info(`Logging out of ${id}`);
const sessionIndex = this._sessions.findIndex(session => session.id === id);
if (sessionIndex > -1) {
const session = this._sessions[sessionIndex];
this._sessions.splice(sessionIndex, 1);
this._sessionChangeEmitter.fire({ added: [], removed: [session], changed: [] });
} else {
Logger.error('Session not found');
}
await this.storeSessions();
} catch (e) {
/* __GDPR__
"logoutFailed" : { }
*/
this.telemetryReporter?.sendTelemetryEvent('logoutFailed');
vscode.window.showErrorMessage(`Sign out failed: ${e}`);
Logger.error(e);
throw e;
}
}
}

View File

@@ -10,6 +10,7 @@ import { v4 as uuid } from 'uuid';
import { PromiseAdapter, promiseFromEvent } from './common/utils';
import Logger from './common/logger';
import { ExperimentationTelemetry } from './experimentationService';
import { AuthProviderType } from './github';
const localize = nls.loadMessageBundle();
@@ -25,10 +26,6 @@ class UriEventHandler extends vscode.EventEmitter<vscode.Uri> implements vscode.
export const uriHandler = new UriEventHandler;
const onDidManuallyProvideToken = new vscode.EventEmitter<string | undefined>();
function parseQuery(uri: vscode.Uri) {
return uri.query.split('&').reduce((prev: any, current) => {
const queryString = current.split('=');
@@ -39,20 +36,21 @@ function parseQuery(uri: vscode.Uri) {
export class GitHubServer {
private _statusBarItem: vscode.StatusBarItem | undefined;
private _onDidManuallyProvideToken = new vscode.EventEmitter<string | undefined>();
private _pendingStates = new Map<string, string[]>();
private _codeExchangePromises = new Map<string, { promise: Promise<string>, cancel: vscode.EventEmitter<void> }>();
constructor(private readonly telemetryReporter: ExperimentationTelemetry) { }
constructor(private type: AuthProviderType, private readonly telemetryReporter: ExperimentationTelemetry) { }
private isTestEnvironment(url: vscode.Uri): boolean {
return /\.azurewebsites\.net$/.test(url.authority) || url.authority.startsWith('localhost:');
return this.type === AuthProviderType['github-enterprise'] || /\.azurewebsites\.net$/.test(url.authority) || url.authority.startsWith('localhost:');
}
// TODO@joaomoreno TODO@RMacfarlane
private async isNoCorsEnvironment(): Promise<boolean> {
const uri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://vscode.github-authentication/did-authenticate`));
return uri.scheme === 'https' && /^vscode\./.test(uri.authority);
const uri = await vscode.env.asExternalUri(vscode.Uri.parse(`${vscode.env.uriScheme}://vscode.github-authentication/dummy`));
return (uri.scheme === 'https' && /^vscode\./.test(uri.authority)) || (uri.scheme === 'http' && /^localhost/.test(uri.authority));
}
public async login(scopes: string): Promise<string> {
@@ -104,7 +102,7 @@ export class GitHubServer {
return Promise.race([
codeExchangePromise.promise,
promiseFromEvent<string | undefined, string>(onDidManuallyProvideToken.event, (token: string | undefined, resolve, reject): void => {
promiseFromEvent<string | undefined, string>(this._onDidManuallyProvideToken.event, (token: string | undefined, resolve, reject): void => {
if (!token) {
reject('Cancelled');
} else {
@@ -164,11 +162,31 @@ export class GitHubServer {
}
};
private getServerUri(path?: string) {
const apiUri = this.type === AuthProviderType['github-enterprise']
? vscode.Uri.parse(vscode.workspace.getConfiguration('github-enterprise').get<string>('uri') || '', true)
: vscode.Uri.parse('https://api.github.com');
if (!path) {
path = '';
}
if (this.type === AuthProviderType['github-enterprise']) {
path = '/api/v3' + path;
}
return vscode.Uri.parse(`${apiUri.scheme}://${apiUri.authority}${path}`);
}
private updateStatusBarItem(isStart?: boolean) {
if (isStart && !this._statusBarItem) {
this._statusBarItem = vscode.window.createStatusBarItem(vscode.StatusBarAlignment.Left);
this._statusBarItem.text = localize('signingIn', "$(mark-github) Signing in to github.com...");
this._statusBarItem.command = 'github.provide-token';
this._statusBarItem = vscode.window.createStatusBarItem('status.git.signIn', vscode.StatusBarAlignment.Left);
this._statusBarItem.name = localize('status.git.signIn.name', "GitHub Sign-in");
this._statusBarItem.text = this.type === AuthProviderType.github
? localize('signingIn', "$(mark-github) Signing in to github.com...")
: localize('signingInEnterprise', "$(mark-github) Signing in to {0}...", this.getServerUri().authority);
this._statusBarItem.command = this.type === AuthProviderType.github
? 'github.provide-token'
: 'github-enterprise.provide-token';
this._statusBarItem.show();
}
@@ -181,7 +199,7 @@ export class GitHubServer {
public async manuallyProvideToken() {
const uriOrToken = await vscode.window.showInputBox({ prompt: 'Token', ignoreFocusOut: true });
if (!uriOrToken) {
onDidManuallyProvideToken.fire(undefined);
this._onDidManuallyProvideToken.fire(undefined);
return;
}
@@ -192,14 +210,14 @@ export class GitHubServer {
} catch (e) {
// If it doesn't look like a URI, treat it as a token.
Logger.info('Treating input as token');
onDidManuallyProvideToken.fire(uriOrToken);
this._onDidManuallyProvideToken.fire(uriOrToken);
}
}
private async getScopes(token: string): Promise<string[]> {
try {
Logger.info('Getting token scopes...');
const result = await fetch('https://api.github.com', {
const result = await fetch(this.getServerUri('/').toString(), {
headers: {
Authorization: `token ${token}`,
'User-Agent': 'Visual-Studio-Code'
@@ -223,7 +241,7 @@ export class GitHubServer {
let result: Response;
try {
Logger.info('Getting user info...');
result = await fetch('https://api.github.com/user', {
result = await fetch(this.getServerUri('/user').toString(), {
headers: {
Authorization: `token ${token}`,
'User-Agent': 'Visual-Studio-Code'
@@ -279,6 +297,34 @@ export class GitHubServer {
} catch (e) {
// No-op
}
}
public async checkEnterpriseVersion(token: string): Promise<void> {
try {
const result = await fetch(this.getServerUri('/meta').toString(), {
headers: {
Authorization: `token ${token}`,
'User-Agent': 'Visual-Studio-Code'
}
});
if (!result.ok) {
return;
}
const json: { verifiable_password_authentication: boolean, installed_version: string } = await result.json();
/* __GDPR__
"ghe-session" : {
"version": { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
}
*/
this.telemetryReporter.sendTelemetryEvent('ghe-session', {
version: json.installed_version
});
} catch {
// No-op
}
}
}

View File

@@ -15,10 +15,10 @@
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.5.tgz#3d03acd3b3414cf67faf999aed11682ed121f22b"
integrity sha512-90hiq6/VqtQgX8Sp0EzeIsv3r+ellbGj4URKj5j30tLlZvRUpnAe9YbYnjl3pJM93GyXU0tghHhvXHq+5rnCKA==
"@types/node@^12.19.9":
version "12.19.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.9.tgz#990ad687ad8b26ef6dcc34a4f69c33d40c95b679"
integrity sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==
"@types/node@14.x":
version "14.14.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
"@types/uuid@8.0.0":
version "8.0.0"

View File

@@ -70,7 +70,7 @@
"vscode-nls": "^4.1.2"
},
"devDependencies": {
"@types/node": "^12.19.9"
"@types/node": "14.x"
},
"repository": {
"type": "git",

View File

@@ -99,16 +99,16 @@
dependencies:
"@types/node" ">= 8"
"@types/node@14.x":
version "14.14.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
"@types/node@>= 8":
version "14.0.23"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.0.23.tgz#676fa0883450ed9da0bb24156213636290892806"
integrity sha512-Z4U8yDAl5TFkmYsZdFPdjeMa57NOvnaf1tljHzhouaPEp7LCj2JKkejpI1ODviIAQuW4CcQmxkQ77rnLsOOoKw==
"@types/node@^12.19.9":
version "12.19.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.9.tgz#990ad687ad8b26ef6dcc34a4f69c33d40c95b679"
integrity sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==
before-after-hook@^2.1.0:
version "2.1.0"
resolved "https://registry.yarnpkg.com/before-after-hook/-/before-after-hook-2.1.0.tgz#b6c03487f44e24200dd30ca5e6a1979c5d2fb635"

View File

@@ -39,12 +39,7 @@ class BinarySize {
export class BinarySizeStatusBarEntry extends PreviewStatusBarEntry {
constructor() {
super({
id: 'imagePreview.binarySize',
name: localize('sizeStatusBar.name', "Image Binary Size"),
alignment: vscode.StatusBarAlignment.Right,
priority: 100,
});
super('status.imagePreview.binarySize', localize('sizeStatusBar.name', "Image Binary Size"), vscode.StatusBarAlignment.Right, 100);
}
public show(owner: string, size: number | undefined) {

View File

@@ -11,9 +11,10 @@ export abstract class PreviewStatusBarEntry extends Disposable {
protected readonly entry: vscode.StatusBarItem;
constructor(options: vscode.StatusBarItemOptions) {
constructor(id: string, name: string, alignment: vscode.StatusBarAlignment, priority: number) {
super();
this.entry = this._register(vscode.window.createStatusBarItem(options));
this.entry = this._register(vscode.window.createStatusBarItem(id, alignment, priority));
this.entry.name = name;
}
protected showItem(owner: string, text: string) {

View File

@@ -12,12 +12,7 @@ const localize = nls.loadMessageBundle();
export class SizeStatusBarEntry extends PreviewStatusBarEntry {
constructor() {
super({
id: 'imagePreview.size',
name: localize('sizeStatusBar.name', "Image Size"),
alignment: vscode.StatusBarAlignment.Right,
priority: 101 /* to the left of editor status (100) */,
});
super('status.imagePreview.size', localize('sizeStatusBar.name', "Image Size"), vscode.StatusBarAlignment.Right, 101 /* to the left of editor status (100) */);
}
public show(owner: string, text: string) {

View File

@@ -19,12 +19,7 @@ export class ZoomStatusBarEntry extends OwnedStatusBarEntry {
public readonly onDidChangeScale = this._onDidChangeScale.event;
constructor() {
super({
id: 'imagePreview.zoom',
name: localize('zoomStatusBar.name', "Image Zoom"),
alignment: vscode.StatusBarAlignment.Right,
priority: 102 /* to the left of editor size entry (101) */,
});
super('status.imagePreview.zoom', localize('zoomStatusBar.name', "Image Zoom"), vscode.StatusBarAlignment.Right, 102 /* to the left of editor size entry (101) */);
this._register(vscode.commands.registerCommand(selectZoomLevelCommandId, async () => {
type MyPickItem = vscode.QuickPickItem & { scale: Scale };

View File

@@ -1,12 +1,12 @@
## Setup
- Clone [Microsoft/vscode](https://github.com/microsoft/vscode)
- Clone [microsoft/vscode](https://github.com/microsoft/vscode)
- Run `yarn` at `/`, this will install
- Dependencies for `/extension/json-language-features/`
- Dependencies for `/extension/json-language-features/server/`
- devDependencies such as `gulp`
- Open `/extensions/json-language-features/` as the workspace in VS Code
- Run the [`Launch Extension`](https://github.com/Microsoft/vscode/blob/master/extensions/json-language-features/.vscode/launch.json) debug target in the Debug View. This will:
- Run the [`Launch Extension`](https://github.com/microsoft/vscode/blob/master/extensions/json-language-features/.vscode/launch.json) debug target in the Debug View. This will:
- Launch the `preLaunchTask` task to compile the extension
- Launch a new VS Code instance with the `json-language-features` extension loaded
- You should see a notification saying the development version of `json-language-features` overwrites the bundled version of `json-language-features`
@@ -18,15 +18,15 @@
### Contribute to vscode-json-languageservice
[Microsoft/vscode-json-languageservice](https://github.com/Microsoft/vscode-json-languageservice) is the library that implements the language smarts for JSON.
[microsoft/vscode-json-languageservice](https://github.com/microsoft/vscode-json-languageservice) is the library that implements the language smarts for JSON.
The JSON language server forwards most the of requests to the service library.
If you want to fix JSON issues or make improvements, you should make changes at [Microsoft/vscode-json-languageservice](https://github.com/Microsoft/vscode-json-languageservice).
If you want to fix JSON issues or make improvements, you should make changes at [microsoft/vscode-json-languageservice](https://github.com/microsoft/vscode-json-languageservice).
However, within this extension, you can run a development version of `vscode-json-languageservice` to debug code or test language features interactively:
#### Linking `vscode-json-languageservice` in `json-language-features/server/`
- Clone [Microsoft/vscode-json-languageservice](https://github.com/Microsoft/vscode-json-languageservice)
- Clone [microsoft/vscode-json-languageservice](https://github.com/microsoft/vscode-json-languageservice)
- Run `npm install` in `vscode-json-languageservice`
- Run `npm link` in `vscode-json-languageservice`. This will compile and link `vscode-json-languageservice`
- In `json-language-features/server/`, run `yarn link vscode-json-languageservice`
@@ -36,4 +36,4 @@ However, within this extension, you can run a development version of `vscode-jso
- Open both `vscode-json-languageservice` and this extension in a single workspace with [multi-root workspace](https://code.visualstudio.com/docs/editor/multi-root-workspaces) feature
- Run `yarn watch` at `json-languagefeatures/server/` to recompile this extension with the linked version of `vscode-json-languageservice`
- Make some changes in `vscode-json-languageservice`
- Now when you run `Launch Extension` debug target, the launched instance will use your development version of `vscode-json-languageservice`. You can interactively test the language features.
- Now when you run `Launch Extension` debug target, the launched instance will use your development version of `vscode-json-languageservice`. You can interactively test the language features.

View File

@@ -7,7 +7,7 @@ import * as nls from 'vscode-nls';
const localize = nls.loadMessageBundle();
import {
workspace, window, languages, commands, ExtensionContext, extensions, Uri, LanguageConfiguration,
workspace, window, languages, commands, ExtensionContext, extensions, Uri,
Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken,
ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext, Hover, MarkdownString,
} from 'vscode';
@@ -101,12 +101,8 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
const documentSelector = ['json', 'jsonc'];
const schemaResolutionErrorStatusBarItem = window.createStatusBarItem({
id: 'status.json.resolveError',
name: localize('json.resolveError', "JSON: Schema Resolution Error"),
alignment: StatusBarAlignment.Right,
priority: 0,
});
const schemaResolutionErrorStatusBarItem = window.createStatusBarItem('status.json.resolveError', StatusBarAlignment.Right, 0);
schemaResolutionErrorStatusBarItem.name = localize('json.resolveError', "JSON: Schema Resolution Error");
schemaResolutionErrorStatusBarItem.text = '$(alert)';
toDispose.push(schemaResolutionErrorStatusBarItem);
@@ -362,17 +358,6 @@ export function startClient(context: ExtensionContext, newLanguageClient: Langua
}
});
const languageConfiguration: LanguageConfiguration = {
wordPattern: /("(?:[^\\\"]*(?:\\.)?)*"?)|[^\s{}\[\],:]+/,
indentationRules: {
increaseIndentPattern: /({+(?=([^"]*"[^"]*")*[^"}]*$))|(\[+(?=([^"]*"[^"]*")*[^"\]]*$))/,
decreaseIndentPattern: /^\s*[}\]],?\s*$/
}
};
languages.setLanguageConfiguration('json', languageConfiguration);
languages.setLanguageConfiguration('jsonc', languageConfiguration);
}
function getSchemaAssociations(_context: ExtensionContext): ISchemaAssociation[] {

View File

@@ -26,7 +26,6 @@
"scripts": {
"compile": "gulp compile-extension:json-language-features-client compile-extension:json-language-features-server",
"watch": "gulp watch-extension:json-language-features-client watch-extension:json-language-features-server",
"postinstall": "cd server && yarn install",
"install-client-next": "yarn add vscode-languageclient@next"
},
"categories": [
@@ -141,7 +140,7 @@
"vscode-nls": "^5.0.0"
},
"devDependencies": {
"@types/node": "^12.19.9"
"@types/node": "14.x"
},
"repository": {
"type": "git",

View File

@@ -218,14 +218,14 @@ To connect to the server from NodeJS, see Remy Suen's great write-up on [how to
## Participate
The source code of the JSON language server can be found in the [VSCode repository](https://github.com/Microsoft/vscode) at [extensions/json-language-features/server](https://github.com/Microsoft/vscode/tree/master/extensions/json-language-features/server).
The source code of the JSON language server can be found in the [VSCode repository](https://github.com/microsoft/vscode) at [extensions/json-language-features/server](https://github.com/microsoft/vscode/tree/master/extensions/json-language-features/server).
File issues and pull requests in the [VSCode GitHub Issues](https://github.com/Microsoft/vscode/issues). See the document [How to Contribute](https://github.com/Microsoft/vscode/wiki/How-to-Contribute) on how to build and run from source.
File issues and pull requests in the [VSCode GitHub Issues](https://github.com/microsoft/vscode/issues). See the document [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute) on how to build and run from source.
Most of the functionality of the server is located in libraries:
- [jsonc-parser](https://github.com/Microsoft/node-jsonc-parser) contains the JSON parser and scanner.
- [vscode-json-languageservice](https://github.com/Microsoft/vscode-json-languageservice) contains the implementation of all features as a re-usable library.
- [vscode-languageserver-node](https://github.com/Microsoft/vscode-languageserver-node) contains the implementation of language server for NodeJS.
- [jsonc-parser](https://github.com/microsoft/node-jsonc-parser) contains the JSON parser and scanner.
- [vscode-json-languageservice](https://github.com/microsoft/vscode-json-languageservice) contains the implementation of all features as a re-usable library.
- [vscode-languageserver-node](https://github.com/microsoft/vscode-languageserver-node) contains the implementation of language server for NodeJS.
Help on any of these projects is very welcome.

View File

@@ -14,13 +14,13 @@
"dependencies": {
"jsonc-parser": "^3.0.0",
"request-light": "^0.4.0",
"vscode-json-languageservice": "^4.1.2",
"vscode-json-languageservice": "^4.1.4",
"vscode-languageserver": "^7.0.0",
"vscode-uri": "^3.0.2"
},
"devDependencies": {
"@types/mocha": "^8.2.0",
"@types/node": "^12.19.9"
"@types/node": "14.x"
},
"scripts": {
"prepublishOnly": "npm run clean && npm run compile",

View File

@@ -6,7 +6,7 @@
import {
Connection,
TextDocuments, InitializeParams, InitializeResult, NotificationType, RequestType,
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit
DocumentRangeFormattingRequest, Disposable, ServerCapabilities, TextDocumentSyncKind, TextEdit, DocumentFormattingRequest, TextDocumentIdentifier, FormattingOptions
} from 'vscode-languageserver';
import { formatError, runSafe, runSafeAsync } from './utils/runner';
@@ -138,6 +138,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
hoverProvider: true,
documentSymbolProvider: true,
documentRangeFormattingProvider: params.initializationOptions?.provideFormatter === true,
documentFormattingProvider: params.initializationOptions?.provideFormatter === true,
colorProvider: {},
foldingRangeProvider: true,
selectionRangeProvider: true,
@@ -206,7 +207,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
let jsonConfigurationSettings: JSONSchemaSettings[] | undefined = undefined;
let schemaAssociations: ISchemaAssociations | SchemaConfiguration[] | undefined = undefined;
let formatterRegistration: Thenable<Disposable> | null = null;
let formatterRegistrations: Thenable<Disposable>[] | null = null;
// The settings have changed. Is send on server activation as well.
connection.onDidChangeConfiguration((change) => {
@@ -224,12 +225,16 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
if (dynamicFormatterRegistration) {
const enableFormatter = settings && settings.json && settings.json.format && settings.json.format.enable;
if (enableFormatter) {
if (!formatterRegistration) {
formatterRegistration = connection.client.register(DocumentRangeFormattingRequest.type, { documentSelector: [{ language: 'json' }, { language: 'jsonc' }] });
if (!formatterRegistrations) {
const documentSelector = [{ language: 'json' }, { language: 'jsonc' }];
formatterRegistrations = [
connection.client.register(DocumentRangeFormattingRequest.type, { documentSelector }),
connection.client.register(DocumentFormattingRequest.type, { documentSelector })
];
}
} else if (formatterRegistration) {
formatterRegistration.then(r => r.dispose());
formatterRegistration = null;
} else if (formatterRegistrations) {
formatterRegistrations.forEach(p => p.then(r => r.dispose()));
formatterRegistrations = null;
}
}
});
@@ -420,19 +425,25 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
}, [], `Error while computing document symbols for ${documentSymbolParams.textDocument.uri}`, token);
});
connection.onDocumentRangeFormatting((formatParams, token) => {
return runSafe(() => {
const document = documents.get(formatParams.textDocument.uri);
if (document) {
const edits = languageService.format(document, formatParams.range, formatParams.options);
if (edits.length > formatterMaxNumberOfEdits) {
const newText = TextDocument.applyEdits(document, edits);
return [TextEdit.replace(Range.create(Position.create(0, 0), document.positionAt(document.getText().length)), newText)];
}
return edits;
function onFormat(textDocument: TextDocumentIdentifier, range: Range | undefined, options: FormattingOptions): TextEdit[] {
const document = documents.get(textDocument.uri);
if (document) {
const edits = languageService.format(document, range ?? getFullRange(document), options);
if (edits.length > formatterMaxNumberOfEdits) {
const newText = TextDocument.applyEdits(document, edits);
return [TextEdit.replace(getFullRange(document), newText)];
}
return [];
}, [], `Error while formatting range for ${formatParams.textDocument.uri}`, token);
return edits;
}
return [];
}
connection.onDocumentRangeFormatting((formatParams, token) => {
return runSafe(() => onFormat(formatParams.textDocument, formatParams.range, formatParams.options), [], `Error while formatting range for ${formatParams.textDocument.uri}`, token);
});
connection.onDocumentFormatting((formatParams, token) => {
return runSafe(() => onFormat(formatParams.textDocument, undefined, formatParams.options), [], `Error while formatting ${formatParams.textDocument.uri}`, token);
});
connection.onDocumentColor((params, token) => {
@@ -495,3 +506,7 @@ export function startServer(connection: Connection, runtime: RuntimeEnvironment)
// Listen on the connection
connection.listen();
}
function getFullRange(document: TextDocument): Range {
return Range.create(Position.create(0, 0), document.positionAt(document.getText().length));
}

View File

@@ -79,4 +79,4 @@ export function getLanguageModelCache<T>(maxEntries: number, cleanupIntervalTime
}
}
};
}
}

View File

@@ -7,10 +7,10 @@
resolved "https://registry.yarnpkg.com/@types/mocha/-/mocha-8.2.0.tgz#3eb56d13a1de1d347ecb1957c6860c911704bc44"
integrity sha512-/Sge3BymXo4lKc31C8OINJgXLaw+7vL1/L1pGiBNpGrBiT8FQiaFpSYV0uhTaG4y78vcMBTMFsWaHDvuD+xGzQ==
"@types/node@^12.19.9":
version "12.19.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.9.tgz#990ad687ad8b26ef6dcc34a4f69c33d40c95b679"
integrity sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==
"@types/node@14.x":
version "14.14.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
agent-base@4:
version "4.1.2"
@@ -105,10 +105,10 @@ request-light@^0.4.0:
https-proxy-agent "^2.2.4"
vscode-nls "^4.1.2"
vscode-json-languageservice@^4.1.2:
version "4.1.2"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-4.1.2.tgz#c3873f791e23488a8b373e02c85c232bd625e27a"
integrity sha512-atAz6m4UZCslB7yk03Qb3/MKn1E5l07063syAEUfKRcVKTVN3t1+/KDlGu1nVCRUFAgz5+18gKidQvO4PVPLdg==
vscode-json-languageservice@^4.1.4:
version "4.1.4"
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-4.1.4.tgz#c83d3d812f8f17ab525724c611d8ff5e8834fc84"
integrity sha512-/UqaE58BVFdePM9l971L6xPRLlCLNk01aovf1Pp9hB/8pytmd2s9ZNEnS1JqYyQEJ1k5/fEBsWOdhQlNo4H7VA==
dependencies:
jsonc-parser "^3.0.0"
minimatch "^3.0.4"

View File

@@ -2,10 +2,10 @@
# yarn lockfile v1
"@types/node@^12.19.9":
version "12.19.9"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.19.9.tgz#990ad687ad8b26ef6dcc34a4f69c33d40c95b679"
integrity sha512-yj0DOaQeUrk3nJ0bd3Y5PeDRJ6W0r+kilosLA+dzF3dola/o9hxhMSg2sFvVcA2UHS5JSOsZp4S0c1OEXc4m1Q==
"@types/node@14.x":
version "14.14.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
agent-base@4:
version "4.2.1"

View File

@@ -31,7 +31,7 @@ function adaptJSON(grammar, replacementScope) {
}
}
var tsGrammarRepo = 'Microsoft/vscode-JSON.tmLanguage';
var tsGrammarRepo = 'microsoft/vscode-JSON.tmLanguage';
updateGrammar.update(tsGrammarRepo, 'JSON.tmLanguage', './syntaxes/JSON.tmLanguage.json');
updateGrammar.update(tsGrammarRepo, 'JSON.tmLanguage', './syntaxes/JSONC.tmLanguage.json', grammar => adaptJSON(grammar, '.json.comments'));

View File

@@ -4,8 +4,8 @@
"component": {
"type": "git",
"git": {
"name": "Microsoft/vscode-JSON.tmLanguage",
"repositoryUrl": "https://github.com/Microsoft/vscode-JSON.tmLanguage",
"name": "microsoft/vscode-JSON.tmLanguage",
"repositoryUrl": "https://github.com/microsoft/vscode-JSON.tmLanguage",
"commitHash": "9bd83f1c252b375e957203f21793316203f61f70"
}
},

View File

@@ -14,5 +14,10 @@
{ "open": "'", "close": "'", "notIn": ["string"] },
{ "open": "\"", "close": "\"", "notIn": ["string", "comment"] },
{ "open": "`", "close": "`", "notIn": ["string", "comment"] }
]
],
"wordPattern": "(\"(?:[^\\\\\\\"]*(?:\\\\.)?)*\"?)|[^\\s{}\\[\\],:]+",
"indentationRules": {
"increaseIndentPattern": "({+(?=([^\"]*\"[^\"]*\")*[^\"}]*$))|(\\[+(?=([^\"]*\"[^\"]*\")*[^\"\\]]*$))",
"decreaseIndentPattern": "^\\s*[}\\]],?\\s*$"
}
}

View File

@@ -29,7 +29,8 @@
".ts.map",
".har",
".jslintrc",
".jsonld"
".jsonld",
".ipynb"
],
"filenames": [
"composer.lock",
@@ -57,6 +58,8 @@
".babelrc"
],
"filenames": [
"babel.config.json",
".babelrc.json",
".ember-cli"
],
"configuration": "./language-configuration.json"

View File

@@ -1,10 +1,10 @@
{
"information_for_contributors": [
"This file has been converted from https://github.com/Microsoft/vscode-JSON.tmLanguage/blob/master/JSON.tmLanguage",
"This file has been converted from https://github.com/microsoft/vscode-JSON.tmLanguage/blob/master/JSON.tmLanguage",
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/Microsoft/vscode-JSON.tmLanguage/commit/9bd83f1c252b375e957203f21793316203f61f70",
"version": "https://github.com/microsoft/vscode-JSON.tmLanguage/commit/9bd83f1c252b375e957203f21793316203f61f70",
"name": "JSON (Javascript Next)",
"scopeName": "source.json",
"patterns": [

View File

@@ -1,10 +1,10 @@
{
"information_for_contributors": [
"This file has been converted from https://github.com/Microsoft/vscode-JSON.tmLanguage/blob/master/JSON.tmLanguage",
"This file has been converted from https://github.com/microsoft/vscode-JSON.tmLanguage/blob/master/JSON.tmLanguage",
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/Microsoft/vscode-JSON.tmLanguage/commit/9bd83f1c252b375e957203f21793316203f61f70",
"version": "https://github.com/microsoft/vscode-JSON.tmLanguage/commit/9bd83f1c252b375e957203f21793316203f61f70",
"name": "JSON with comments",
"scopeName": "source.json.comments",
"patterns": [

View File

@@ -4,7 +4,7 @@
"component": {
"type": "git",
"git": {
"name": " JuliaEditorSupport/atom-language-julia",
"name": "JuliaEditorSupport/atom-language-julia",
"repositoryUrl": "https://github.com/JuliaEditorSupport/atom-language-julia",
"commitHash": "008e02c5ec9440fa9f0ea8a891712c7238f24706"
}
@@ -14,4 +14,4 @@
}
],
"version": 1
}
}

View File

@@ -33,7 +33,7 @@
"git": {
"name": "microsoft/vscode-markdown-tm-grammar",
"repositoryUrl": "https://github.com/microsoft/vscode-markdown-tm-grammar",
"commitHash": "7019b191c3ee38b6c345f3a2a843f223eb92ca1e"
"commitHash": "a612b96d62aa1ce305c4a55dc9d577316fab39da"
}
},
"license": "MIT",

View File

@@ -49,5 +49,6 @@
"start": "^\\s*<!--\\s*#?region\\b.*-->",
"end": "^\\s*<!--\\s*#?endregion\\b.*-->"
}
}
},
"wordPattern": { "pattern": "(\\p{Alphabetic}|\\p{Number}|\\p{Nonspacing_Mark})(((\\p{Alphabetic}|\\p{Number}|\\p{Nonspacing_Mark})|[_])?(\\p{Alphabetic}|\\p{Number}|\\p{Nonspacing_Mark}))*", "flags": "ug" },
}

View File

@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/7019b191c3ee38b6c345f3a2a843f223eb92ca1e",
"version": "https://github.com/microsoft/vscode-markdown-tm-grammar/commit/a612b96d62aa1ce305c4a55dc9d577316fab39da",
"name": "Markdown",
"scopeName": "text.html.markdown",
"patterns": [
@@ -63,7 +63,7 @@
"while": "(^|\\G)\\s*(>) ?"
},
"fenced_code_block_css": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(css|css.erb)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(css|css.erb)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -96,7 +96,7 @@
]
},
"fenced_code_block_basic": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(html|htm|shtml|xhtml|inc|tmpl|tpl)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(html|htm|shtml|xhtml|inc|tmpl|tpl)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -129,7 +129,7 @@
]
},
"fenced_code_block_ini": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(ini|conf)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(ini|conf)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -162,7 +162,7 @@
]
},
"fenced_code_block_java": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(java|bsh)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(java|bsh)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -195,7 +195,7 @@
]
},
"fenced_code_block_lua": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(lua)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(lua)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -228,7 +228,7 @@
]
},
"fenced_code_block_makefile": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(Makefile|makefile|GNUmakefile|OCamlMakefile)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(Makefile|makefile|GNUmakefile|OCamlMakefile)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -261,7 +261,7 @@
]
},
"fenced_code_block_perl": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(perl|pl|pm|pod|t|PL|psgi|vcl)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(perl|pl|pm|pod|t|PL|psgi|vcl)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -294,7 +294,7 @@
]
},
"fenced_code_block_r": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(R|r|s|S|Rprofile|\\{\\.r.+?\\})((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(R|r|s|S|Rprofile|\\{\\.r.+?\\})((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -327,7 +327,7 @@
]
},
"fenced_code_block_ruby": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(ruby|rb|rbx|rjs|Rakefile|rake|cgi|fcgi|gemspec|irbrc|Capfile|ru|prawn|Cheffile|Gemfile|Guardfile|Hobofile|Vagrantfile|Appraisals|Rantfile|Berksfile|Berksfile.lock|Thorfile|Puppetfile)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(ruby|rb|rbx|rjs|Rakefile|rake|cgi|fcgi|gemspec|irbrc|Capfile|ru|prawn|Cheffile|Gemfile|Guardfile|Hobofile|Vagrantfile|Appraisals|Rantfile|Berksfile|Berksfile.lock|Thorfile|Puppetfile)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -360,7 +360,7 @@
]
},
"fenced_code_block_php": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(php|php3|php4|php5|phpt|phtml|aw|ctp)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(php|php3|php4|php5|phpt|phtml|aw|ctp)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -396,7 +396,7 @@
]
},
"fenced_code_block_sql": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(sql|ddl|dml)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(sql|ddl|dml)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -429,7 +429,7 @@
]
},
"fenced_code_block_vs_net": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(vb)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(vb)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -462,7 +462,7 @@
]
},
"fenced_code_block_xml": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(xml|xsd|tld|jsp|pt|cpt|dtml|rss|opml)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(xml|xsd|tld|jsp|pt|cpt|dtml|rss|opml)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -495,7 +495,7 @@
]
},
"fenced_code_block_xsl": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(xsl|xslt)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(xsl|xslt)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -528,7 +528,7 @@
]
},
"fenced_code_block_yaml": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(yaml|yml)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(yaml|yml)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -561,7 +561,7 @@
]
},
"fenced_code_block_dosbatch": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(bat|batch)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(bat|batch)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -594,7 +594,7 @@
]
},
"fenced_code_block_clojure": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(clj|cljs|clojure)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(clj|cljs|clojure)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -627,7 +627,7 @@
]
},
"fenced_code_block_coffee": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(coffee|Cakefile|coffee.erb)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(coffee|Cakefile|coffee.erb)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -660,7 +660,7 @@
]
},
"fenced_code_block_c": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(c|h)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(c|h)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -693,7 +693,7 @@
]
},
"fenced_code_block_cpp": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(cpp|c\\+\\+|cxx)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(cpp|c\\+\\+|cxx)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -726,7 +726,7 @@
]
},
"fenced_code_block_diff": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(patch|diff|rej)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(patch|diff|rej)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -759,7 +759,7 @@
]
},
"fenced_code_block_dockerfile": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(dockerfile|Dockerfile)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(dockerfile|Dockerfile)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -792,7 +792,7 @@
]
},
"fenced_code_block_git_commit": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(COMMIT_EDITMSG|MERGE_MSG)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(COMMIT_EDITMSG|MERGE_MSG)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -825,7 +825,7 @@
]
},
"fenced_code_block_git_rebase": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(git-rebase-todo)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(git-rebase-todo)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -858,7 +858,7 @@
]
},
"fenced_code_block_go": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(go|golang)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(go|golang)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -891,7 +891,7 @@
]
},
"fenced_code_block_groovy": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(groovy|gvy)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(groovy|gvy)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -924,7 +924,7 @@
]
},
"fenced_code_block_pug": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(jade|pug)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(jade|pug)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -957,7 +957,7 @@
]
},
"fenced_code_block_js": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(js|jsx|javascript|es6|mjs|cjs|\\{\\.js.+?\\})((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(js|jsx|javascript|es6|mjs|cjs|\\{\\.js.+?\\})((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -990,7 +990,7 @@
]
},
"fenced_code_block_js_regexp": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(regexp)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(regexp)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1023,7 +1023,7 @@
]
},
"fenced_code_block_json": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(json|json5|sublime-settings|sublime-menu|sublime-keymap|sublime-mousemap|sublime-theme|sublime-build|sublime-project|sublime-completions)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(json|json5|sublime-settings|sublime-menu|sublime-keymap|sublime-mousemap|sublime-theme|sublime-build|sublime-project|sublime-completions)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1056,7 +1056,7 @@
]
},
"fenced_code_block_jsonc": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(jsonc)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(jsonc)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1089,7 +1089,7 @@
]
},
"fenced_code_block_less": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(less)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(less)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1122,7 +1122,7 @@
]
},
"fenced_code_block_objc": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(objectivec|objective-c|mm|objc|obj-c|m|h)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(objectivec|objective-c|mm|objc|obj-c|m|h)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1155,7 +1155,7 @@
]
},
"fenced_code_block_swift": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(swift)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(swift)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1188,7 +1188,7 @@
]
},
"fenced_code_block_scss": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(scss)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(scss)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1221,7 +1221,7 @@
]
},
"fenced_code_block_perl6": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(perl6|p6|pl6|pm6|nqp)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(perl6|p6|pl6|pm6|nqp)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1254,7 +1254,7 @@
]
},
"fenced_code_block_powershell": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(powershell|ps1|psm1|psd1)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(powershell|ps1|psm1|psd1)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1287,7 +1287,7 @@
]
},
"fenced_code_block_python": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(python|py|py3|rpy|pyw|cpy|SConstruct|Sconstruct|sconstruct|SConscript|gyp|gypi|\\{\\.python.+?\\})((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(python|py|py3|rpy|pyw|cpy|SConstruct|Sconstruct|sconstruct|SConscript|gyp|gypi|\\{\\.python.+?\\})((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1320,7 +1320,7 @@
]
},
"fenced_code_block_regexp_python": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(re)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(re)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1353,7 +1353,7 @@
]
},
"fenced_code_block_rust": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(rust|rs|\\{\\.rust.+?\\})((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(rust|rs|\\{\\.rust.+?\\})((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1386,7 +1386,7 @@
]
},
"fenced_code_block_scala": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(scala|sbt)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(scala|sbt)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1419,7 +1419,7 @@
]
},
"fenced_code_block_shell": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(shell|sh|bash|zsh|bashrc|bash_profile|bash_login|profile|bash_logout|.textmate_init|\\{\\.bash.+?\\})((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(shell|sh|bash|zsh|bashrc|bash_profile|bash_login|profile|bash_logout|.textmate_init|\\{\\.bash.+?\\})((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1452,7 +1452,7 @@
]
},
"fenced_code_block_ts": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(typescript|ts)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(typescript|ts)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1485,7 +1485,7 @@
]
},
"fenced_code_block_tsx": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(tsx)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(tsx)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1518,7 +1518,7 @@
]
},
"fenced_code_block_csharp": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(cs|csharp|c#)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(cs|csharp|c#)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1551,7 +1551,7 @@
]
},
"fenced_code_block_fsharp": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(fs|fsharp|f#)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(fs|fsharp|f#)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1584,7 +1584,7 @@
]
},
"fenced_code_block_dart": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(dart)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(dart)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1617,7 +1617,7 @@
]
},
"fenced_code_block_handlebars": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(handlebars|hbs)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(handlebars|hbs)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1650,7 +1650,7 @@
]
},
"fenced_code_block_markdown": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(markdown|md)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(markdown|md)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1683,7 +1683,7 @@
]
},
"fenced_code_block_log": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(log)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(log)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1716,7 +1716,7 @@
]
},
"fenced_code_block_erlang": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(erlang)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(erlang)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1749,7 +1749,7 @@
]
},
"fenced_code_block_elixir": {
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(elixir)((\\s+|:|\\{)[^`~]*)?$)",
"begin": "(^|\\G)(\\s*)(`{3,}|~{3,})\\s*(?i:(elixir)((\\s+|:|\\{|\\?)[^`~]*)?$)",
"name": "markup.fenced_code.block.markdown",
"end": "(^|\\G)(\\2|\\s{0,3})(\\3)\\s*$",
"beginCaptures": {
@@ -1975,7 +1975,15 @@
"name": "punctuation.definition.heading.markdown"
},
"2": {
"name": "entity.name.section.markdown"
"name": "entity.name.section.markdown",
"patterns": [
{
"include": "#inline"
},
{
"include": "text.html.derivative"
}
]
},
"3": {
"name": "punctuation.definition.heading.markdown"
@@ -1990,7 +1998,15 @@
"name": "punctuation.definition.heading.markdown"
},
"2": {
"name": "entity.name.section.markdown"
"name": "entity.name.section.markdown",
"patterns": [
{
"include": "#inline"
},
{
"include": "text.html.derivative"
}
]
},
"3": {
"name": "punctuation.definition.heading.markdown"
@@ -2005,7 +2021,15 @@
"name": "punctuation.definition.heading.markdown"
},
"2": {
"name": "entity.name.section.markdown"
"name": "entity.name.section.markdown",
"patterns": [
{
"include": "#inline"
},
{
"include": "text.html.derivative"
}
]
},
"3": {
"name": "punctuation.definition.heading.markdown"
@@ -2020,7 +2044,15 @@
"name": "punctuation.definition.heading.markdown"
},
"2": {
"name": "entity.name.section.markdown"
"name": "entity.name.section.markdown",
"patterns": [
{
"include": "#inline"
},
{
"include": "text.html.derivative"
}
]
},
"3": {
"name": "punctuation.definition.heading.markdown"
@@ -2035,7 +2067,15 @@
"name": "punctuation.definition.heading.markdown"
},
"2": {
"name": "entity.name.section.markdown"
"name": "entity.name.section.markdown",
"patterns": [
{
"include": "#inline"
},
{
"include": "text.html.derivative"
}
]
},
"3": {
"name": "punctuation.definition.heading.markdown"
@@ -2050,7 +2090,15 @@
"name": "punctuation.definition.heading.markdown"
},
"2": {
"name": "entity.name.section.markdown"
"name": "entity.name.section.markdown",
"patterns": [
{
"include": "#inline"
},
{
"include": "text.html.derivative"
}
]
},
"3": {
"name": "punctuation.definition.heading.markdown"

View File

@@ -1,6 +1,6 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const path = require('path');
const esbuild = require('esbuild');

File diff suppressed because one or more lines are too long

View File

@@ -106,6 +106,13 @@ body.showEditorSelection li.code-line:hover:before {
border-left: none;
}
ul ul,
ul ol,
ol ul,
ol ol {
margin-bottom: 0;
}
img {
max-width: 100%;
max-height: 100%;
@@ -152,6 +159,7 @@ h1 {
table {
border-collapse: collapse;
margin-bottom: 0.7em;
}
th {

View File

@@ -1 +0,0 @@
!function(e){var t={};function n(o){if(t[o])return t[o].exports;var s=t[o]={i:o,l:!1,exports:{}};return e[o].call(s.exports,s,s.exports,n),s.l=!0,s.exports}n.m=e,n.c=t,n.d=function(e,t,o){n.o(e,t)||Object.defineProperty(e,t,{enumerable:!0,get:o})},n.r=function(e){"undefined"!=typeof Symbol&&Symbol.toStringTag&&Object.defineProperty(e,Symbol.toStringTag,{value:"Module"}),Object.defineProperty(e,"__esModule",{value:!0})},n.t=function(e,t){if(1&t&&(e=n(e)),8&t)return e;if(4&t&&"object"==typeof e&&e&&e.__esModule)return e;var o=Object.create(null);if(n.r(o),Object.defineProperty(o,"default",{enumerable:!0,value:e}),2&t&&"string"!=typeof e)for(var s in e)n.d(o,s,function(t){return e[t]}.bind(null,s));return o},n.n=function(e){var t=e&&e.__esModule?function(){return e.default}:function(){return e};return n.d(t,"a",t),t},n.o=function(e,t){return Object.prototype.hasOwnProperty.call(e,t)},n.p="",n(n.s=11)}([function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getSettings=t.getData=void 0;let o=void 0;function s(e){const t=document.getElementById("vscode-markdown-preview-data");if(t){const n=t.getAttribute(e);if(n)return JSON.parse(n)}throw new Error("Could not load data for "+e)}t.getData=s,t.getSettings=function(){if(o)return o;if(o=s("data-settings"),o)return o;throw new Error("Could not load settings")}},,,,,,,,,,,function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0});const o=n(12),s=n(14);window.cspAlerter=new o.CspAlerter,window.styleLoadingMonitor=new s.StyleLoadingMonitor},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.CspAlerter=void 0;const o=n(0),s=n(13);t.CspAlerter=class{constructor(){this.didShow=!1,this.didHaveCspWarning=!1,document.addEventListener("securitypolicyviolation",()=>{this.onCspWarning()}),window.addEventListener("message",e=>{e&&e.data&&"vscode-did-block-svg"===e.data.name&&this.onCspWarning()})}setPoster(e){this.messaging=e,this.didHaveCspWarning&&this.showCspWarning()}onCspWarning(){this.didHaveCspWarning=!0,this.showCspWarning()}showCspWarning(){const e=(0,s.getStrings)(),t=(0,o.getSettings)();if(this.didShow||t.disableSecurityWarnings||!this.messaging)return;this.didShow=!0;const n=document.createElement("a");n.innerText=e.cspAlertMessageText,n.setAttribute("id","code-csp-warning"),n.setAttribute("title",e.cspAlertMessageTitle),n.setAttribute("role","button"),n.setAttribute("aria-label",e.cspAlertMessageLabel),n.onclick=()=>{this.messaging.postMessage("showPreviewSecuritySelector",{source:t.source})},document.body.appendChild(n)}}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.getStrings=void 0,t.getStrings=function(){const e=document.getElementById("vscode-markdown-preview-data");if(e){const t=e.getAttribute("data-strings");if(t)return JSON.parse(t)}throw new Error("Could not load strings")}},function(e,t,n){"use strict";Object.defineProperty(t,"__esModule",{value:!0}),t.StyleLoadingMonitor=void 0;t.StyleLoadingMonitor=class{constructor(){this.unloadedStyles=[],this.finishedLoading=!1;const e=e=>{const t=e.target.dataset.source;this.unloadedStyles.push(t)};window.addEventListener("DOMContentLoaded",()=>{for(const t of document.getElementsByClassName("code-user-style"))t.dataset.source&&(t.onerror=e)}),window.addEventListener("load",()=>{this.unloadedStyles.length&&(this.finishedLoading=!0,this.poster&&this.poster.postMessage("previewStyleLoadError",{unloadedStyles:this.unloadedStyles}))})}setPoster(e){this.poster=e,this.finishedLoading&&e.postMessage("previewStyleLoadError",{unloadedStyles:this.unloadedStyles})}}}]);

View File

@@ -1,39 +1,177 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
const MarkdownIt = require('markdown-it');
export async function activate(ctx: {
dependencies: ReadonlyArray<{ entrypoint: string }>
}) {
export function activate() {
let markdownIt = new MarkdownIt({
html: true
});
// Should we load the deps before this point?
// Also could we await inside `renderMarkup`?
await Promise.all(ctx.dependencies.map(async (dep) => {
try {
const api = await import(dep.entrypoint);
if (api?.extendMarkdownIt) {
markdownIt = api.extendMarkdownIt(markdownIt);
}
} catch (e) {
console.error('Could not load markdown entryPoint', e);
const style = document.createElement('style');
style.classList.add('markdown-style');
style.textContent = `
.emptyMarkdownCell::before {
content: "${document.documentElement.style.getPropertyValue('--notebook-cell-markup-empty-content')}";
font-style: italic;
opacity: 0.6;
}
}));
img {
max-width: 100%;
max-height: 100%;
}
a {
text-decoration: none;
}
a:hover {
text-decoration: underline;
}
a:focus,
input:focus,
select:focus,
textarea:focus {
outline: 1px solid -webkit-focus-ring-color;
outline-offset: -1px;
}
hr {
border: 0;
height: 2px;
border-bottom: 2px solid;
}
h1 {
font-size: 26px;
line-height: 31px;
margin: 0;
margin-bottom: 13px;
}
h2 {
font-size: 19px;
margin: 0;
margin-bottom: 10px;
}
h1,
h2,
h3 {
font-weight: normal;
}
div {
width: 100%;
}
/* Adjust margin of first item in markdown cell */
*:first-child {
margin-top: 0px;
}
/* h1 tags don't need top margin */
h1:first-child {
margin-top: 0;
}
/* Removes bottom margin when only one item exists in markdown cell */
*:only-child,
*:last-child {
margin-bottom: 0;
padding-bottom: 0;
}
/* makes all markdown cells consistent */
div {
min-height: var(--notebook-markdown-min-height);
}
table {
border-collapse: collapse;
border-spacing: 0;
}
table th,
table td {
border: 1px solid;
}
table > thead > tr > th {
text-align: left;
border-bottom: 1px solid;
}
table > thead > tr > th,
table > thead > tr > td,
table > tbody > tr > th,
table > tbody > tr > td {
padding: 5px 10px;
}
table > tbody > tr + tr > td {
border-top: 1px solid;
}
blockquote {
margin: 0 7px 0 5px;
padding: 0 16px 0 10px;
border-left-width: 5px;
border-left-style: solid;
}
code,
.code {
font-size: 1em;
line-height: 1.357em;
}
.code {
white-space: pre-wrap;
}
`;
document.head.append(style);
return {
renderMarkup: (context: { element: HTMLElement, content: string }) => {
const rendered = markdownIt.render(context.content);
context.element.innerHTML = rendered;
renderOutputItem: (outputInfo: { text(): string }, element: HTMLElement) => {
let previewNode: HTMLElement;
if (!element.shadowRoot) {
const previewRoot = element.attachShadow({ mode: 'open' });
// Insert styles into markdown preview shadow dom so that they are applied
for (const markdownStyleNode of document.getElementsByClassName('markdown-style')) {
context.element.appendChild(markdownStyleNode.cloneNode(true));
// Insert styles into markdown preview shadow dom so that they are applied.
// First add default webview style
const defaultStyles = document.getElementById('_defaultStyles') as HTMLStyleElement;
previewRoot.appendChild(defaultStyles.cloneNode(true));
// And then contributed styles
for (const markdownStyleNode of document.getElementsByClassName('markdown-style')) {
previewRoot.appendChild(markdownStyleNode.cloneNode(true));
}
previewNode = document.createElement('div');
previewNode.id = 'preview';
previewRoot.appendChild(previewNode);
} else {
previewNode = element.shadowRoot.getElementById('preview')!;
}
const text = outputInfo.text();
if (text.trim().length === 0) {
previewNode.innerText = '';
previewNode.classList.add('emptyMarkdownCell');
} else {
previewNode.classList.remove('emptyMarkdownCell');
const rendered = markdownIt.render(text);
previewNode.innerHTML = rendered;
}
},
extendMarkdownIt: (f: (md: typeof markdownIt) => void) => {
f(markdownIt);
}
};
}

View File

@@ -26,6 +26,7 @@
"onCommand:markdown.showSource",
"onCommand:markdown.showPreviewSecuritySelector",
"onCommand:markdown.api.render",
"onCommand:markdown.api.reloadPlugins",
"onWebviewPanel:markdown.preview",
"onCustomEditor:vscode.markdown.preview.editor"
],
@@ -40,7 +41,7 @@
}
},
"contributes": {
"notebookMarkupRenderers": [
"notebookRenderer": [
{
"id": "markdownItRenderer",
"displayName": "Markdown it renderer",
@@ -361,7 +362,8 @@
"@types/highlight.js": "10.1.0",
"@types/lodash.throttle": "^4.1.3",
"@types/markdown-it": "0.0.2",
"@types/node": "^12.19.9",
"@types/node": "14.x",
"@types/vscode-webview": "^1.57.0",
"lodash.throttle": "^4.1.1"
},
"repository": {

View File

@@ -31,4 +31,4 @@ export class ActiveLineMarker {
}
element.className += ' code-active-line';
}
}
}

View File

@@ -9,4 +9,4 @@ export function onceDocumentLoaded(f: () => void) {
} else {
f();
}
}
}

View File

@@ -10,8 +10,6 @@ import { getEditorLineNumberForPageOffset, scrollToRevealSourceLine, getLineElem
import { getSettings, getData } from './settings';
import throttle = require('lodash.throttle');
declare let acquireVsCodeApi: any;
let scrollDisabledCount = 0;
const marker = new ActiveLineMarker();
const settings = getSettings();

View File

@@ -41,4 +41,4 @@ export class StyleLoadingMonitor {
poster.postMessage('previewStyleLoadError', { unloadedStyles: this.unloadedStyles });
}
}
}
}

View File

@@ -14,4 +14,4 @@ declare global {
}
window.cspAlerter = new CspAlerter();
window.styleLoadingMonitor = new StyleLoadingMonitor();
window.styleLoadingMonitor = new StyleLoadingMonitor();

View File

@@ -8,5 +8,10 @@
"DOM",
"DOM.Iterable"
]
},
"typeAcquisition": {
"include": [
"@types/vscode-webview"
]
}
}

View File

@@ -35,4 +35,4 @@ export class CommandManager {
this.commands.set(id, vscode.commands.registerCommand(id, impl, thisArg));
}
}
}

View File

@@ -3,11 +3,13 @@
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
export { OpenDocumentLinkCommand } from './openDocumentLink';
export { ShowPreviewCommand, ShowPreviewToSideCommand, ShowLockedPreviewToSideCommand } from './showPreview';
export { ShowSourceCommand } from './showSource';
export { RefreshPreviewCommand } from './refreshPreview';
export { ShowPreviewSecuritySelectorCommand } from './showPreviewSecuritySelector';
export { MoveCursorToPositionCommand } from './moveCursorToPosition';
export { ToggleLockCommand } from './toggleLock';
export { OpenDocumentLinkCommand } from './openDocumentLink';
export { RefreshPreviewCommand } from './refreshPreview';
export { ReloadPlugins } from './reloadPlugins';
export { RenderDocument } from './renderDocument';
export { ShowLockedPreviewToSideCommand, ShowPreviewCommand, ShowPreviewToSideCommand } from './showPreview';
export { ShowPreviewSecuritySelectorCommand } from './showPreviewSecuritySelector';
export { ShowSourceCommand } from './showSource';
export { ToggleLockCommand } from './toggleLock';

View File

@@ -19,4 +19,4 @@ export class RefreshPreviewCommand implements Command {
this.engine.cleanCache();
this.webviewManager.refresh();
}
}
}

View File

@@ -0,0 +1,23 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the Source EULA. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { Command } from '../commandManager';
import { MarkdownPreviewManager } from '../features/previewManager';
import { MarkdownEngine } from '../markdownEngine';
export class ReloadPlugins implements Command {
public readonly id = 'markdown.api.reloadPlugins';
public constructor(
private readonly webviewManager: MarkdownPreviewManager,
private readonly engine: MarkdownEngine,
) { }
public execute(): void {
this.engine.reloadPlugins();
this.engine.cleanCache();
this.webviewManager.refresh();
}
}

View File

@@ -27,4 +27,4 @@ export class ShowPreviewSecuritySelectorCommand implements Command {
this.previewSecuritySelector.showSecuritySelectorForResource(vscode.window.activeTextEditor.document.uri);
}
}
}
}

View File

@@ -23,4 +23,4 @@ export class ShowSourceCommand implements Command {
}
return undefined;
}
}
}

View File

@@ -16,4 +16,4 @@ export class ToggleLockCommand implements Command {
public execute() {
this.previewManager.toggleLock();
}
}
}

View File

@@ -52,12 +52,7 @@ function registerMarkdownLanguageFeatures(
): vscode.Disposable {
const selector: vscode.DocumentSelector = { language: 'markdown', scheme: '*' };
const charPattern = '(\\p{Alphabetic}|\\p{Number}|\\p{Nonspacing_Mark})';
return vscode.Disposable.from(
vscode.languages.setLanguageConfiguration('markdown', {
wordPattern: new RegExp(`${charPattern}((${charPattern}|[_])?${charPattern})*`, 'ug'),
}),
vscode.languages.registerDocumentSymbolProvider(selector, symbolProvider),
vscode.languages.registerDocumentLinkProvider(selector, new LinkProvider()),
vscode.languages.registerFoldingRangeProvider(selector, new MarkdownFoldingProvider(engine)),
@@ -85,5 +80,6 @@ function registerMarkdownCommands(
commandManager.register(new commands.OpenDocumentLinkCommand(engine));
commandManager.register(new commands.ToggleLockCommand(previewManager));
commandManager.register(new commands.RenderDocument(engine));
commandManager.register(new commands.ReloadPlugins(previewManager, engine));
return commandManager;
}

View File

@@ -72,4 +72,4 @@ export default class MDDocumentSymbolProvider implements vscode.DocumentSymbolPr
private getSymbolName(entry: TocEntry): string {
return '#'.repeat(entry.level) + ' ' + entry.text;
}
}
}

View File

@@ -11,8 +11,8 @@ import { Logger } from '../logger';
import { MarkdownContributionProvider } from '../markdownExtensions';
import { Disposable } from '../util/dispose';
import { isMarkdownFile } from '../util/file';
import { normalizeResource, WebviewResourceProvider } from '../util/resources';
import { getVisibleLine, TopmostLineMonitor } from '../util/topmostLineMonitor';
import { WebviewResourceProvider } from '../util/resources';
import { getVisibleLine, LastScrollLocation, TopmostLineMonitor } from '../util/topmostLineMonitor';
import { MarkdownPreviewConfigurationManager } from './previewConfig';
import { MarkdownContentProvider, MarkdownContentProviderOutput } from './previewContentProvider';
import { MarkdownEngine } from '../markdownEngine';
@@ -120,6 +120,8 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
private imageInfo: { readonly id: string, readonly width: number, readonly height: number; }[] = [];
private readonly _fileWatchersBySrc = new Map</* src: */ string, vscode.FileSystemWatcher>();
private readonly _onScrollEmitter = this._register(new vscode.EventEmitter<LastScrollLocation>());
public readonly onScroll = this._onScrollEmitter.event;
constructor(
webview: vscode.WebviewPanel,
@@ -324,7 +326,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
private onDidScrollPreview(line: number) {
this.line = line;
this._onScrollEmitter.fire({ line: this.line, uri: this._resource });
const config = this._previewConfigurations.loadAndCacheConfiguration(this._resource);
if (!config.scrollEditorWithPreview) {
return;
@@ -336,13 +338,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
}
this.isScrolling = true;
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);
scrollEditorToLine(line, editor);
}
}
@@ -427,12 +423,12 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
baseRoots.push(vscode.Uri.file(path.dirname(this._resource.fsPath)));
}
return baseRoots.map(root => normalizeResource(this._resource, root));
return baseRoots;
}
private async onDidClickPreviewLink(href: string) {
let [hrefPath, fragment] = decodeURIComponent(href).split('#');
let [hrefPath, fragment] = href.split('#').map(c => decodeURIComponent(c));
if (hrefPath[0] !== '/') {
// We perviously already resolve absolute paths.
@@ -460,7 +456,7 @@ class MarkdownPreview extends Disposable implements WebviewResourceProvider {
//#region WebviewResourceProvider
asWebviewUri(resource: vscode.Uri) {
return this._webviewPanel.webview.asWebviewUri(normalizeResource(this._resource, resource));
return this._webviewPanel.webview.asWebviewUri(resource);
}
get cspSource() {
@@ -497,11 +493,13 @@ export class StaticMarkdownPreview extends Disposable implements ManagedMarkdown
webview: vscode.WebviewPanel,
contentProvider: MarkdownContentProvider,
previewConfigurations: MarkdownPreviewConfigurationManager,
topmostLineMonitor: TopmostLineMonitor,
logger: Logger,
contributionProvider: MarkdownContributionProvider,
engine: MarkdownEngine,
scrollLine?: number,
): StaticMarkdownPreview {
return new StaticMarkdownPreview(webview, resource, contentProvider, previewConfigurations, logger, contributionProvider, engine);
return new StaticMarkdownPreview(webview, resource, contentProvider, previewConfigurations, topmostLineMonitor, logger, contributionProvider, engine, scrollLine);
}
private readonly preview: MarkdownPreview;
@@ -511,13 +509,15 @@ export class StaticMarkdownPreview extends Disposable implements ManagedMarkdown
resource: vscode.Uri,
contentProvider: MarkdownContentProvider,
private readonly _previewConfigurations: MarkdownPreviewConfigurationManager,
topmostLineMonitor: TopmostLineMonitor,
logger: Logger,
contributionProvider: MarkdownContributionProvider,
engine: MarkdownEngine,
scrollLine?: number,
) {
super();
this.preview = this._register(new MarkdownPreview(this._webviewPanel, resource, undefined, {
const topScrollLocation = scrollLine ? new StartingScrollLine(scrollLine) : undefined;
this.preview = this._register(new MarkdownPreview(this._webviewPanel, resource, topScrollLocation, {
getAdditionalState: () => { return {}; },
openPreviewLinkToMarkdownFile: () => { /* todo */ }
}, engine, contentProvider, _previewConfigurations, logger, contributionProvider));
@@ -529,6 +529,16 @@ export class StaticMarkdownPreview extends Disposable implements ManagedMarkdown
this._register(this._webviewPanel.onDidChangeViewState(e => {
this._onDidChangeViewState.fire(e);
}));
this._register(this.preview.onScroll((scrollInfo) => {
topmostLineMonitor.setPreviousEditorLine(scrollInfo);
}));
this._register(topmostLineMonitor.onDidChanged(event => {
if (this.preview.isPreviewOf(event.resource)) {
this.preview.scrollTo(event.line);
}
}));
}
private readonly _onDispose = this._register(new vscode.EventEmitter<void>());
@@ -789,3 +799,18 @@ export class DynamicMarkdownPreview extends Disposable implements ManagedMarkdow
}
}
/**
* Change the top-most visible line of `editor` to be at `line`
*/
export function scrollEditorToLine(
line: number,
editor: vscode.TextEditor
) {
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);
}

View File

@@ -4,6 +4,7 @@
*--------------------------------------------------------------------------------------------*/
import * as vscode from 'vscode';
import { equals } from '../util/arrays';
export class MarkdownPreviewConfiguration {
public static getForResource(resource: vscode.Uri) {
@@ -21,7 +22,7 @@ export class MarkdownPreviewConfiguration {
public readonly lineHeight: number;
public readonly fontSize: number;
public readonly fontFamily: string | undefined;
public readonly styles: string[];
public readonly styles: readonly string[];
private constructor(resource: vscode.Uri) {
const editorConfig = vscode.workspace.getConfiguration('editor', resource);
@@ -49,7 +50,7 @@ export class MarkdownPreviewConfiguration {
}
public isEqualTo(otherConfig: MarkdownPreviewConfiguration) {
for (let key in this) {
for (const key in this) {
if (this.hasOwnProperty(key) && key !== 'styles') {
if (this[key] !== otherConfig[key]) {
return false;
@@ -57,17 +58,7 @@ export class MarkdownPreviewConfiguration {
}
}
// 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;
return equals(this.styles, otherConfig.styles);
}
[key: string]: any;

View File

@@ -81,7 +81,7 @@ export class MarkdownContentProvider {
const nonce = new Date().getTime() + '' + new Date().getMilliseconds();
const csp = this.getCsp(resourceProvider, sourceUri, nonce);
const body = await this.engine.render(markdownDocument);
const body = await this.engine.render(markdownDocument, resourceProvider);
const html = `<!DOCTYPE html>
<html style="${escapeAttribute(this.getSettingsOverrideStyles(config))}">
<head>

View File

@@ -9,9 +9,10 @@ import { MarkdownEngine } from '../markdownEngine';
import { MarkdownContributionProvider } from '../markdownExtensions';
import { Disposable, disposeAll } from '../util/dispose';
import { TopmostLineMonitor } from '../util/topmostLineMonitor';
import { DynamicMarkdownPreview, ManagedMarkdownPreview, StartingScrollFragment, StaticMarkdownPreview } from './preview';
import { DynamicMarkdownPreview, ManagedMarkdownPreview, StartingScrollFragment, StaticMarkdownPreview, scrollEditorToLine } from './preview';
import { MarkdownPreviewConfigurationManager } from './previewConfig';
import { MarkdownContentProvider } from './previewContentProvider';
import { isMarkdownFile } from '../util/file';
export interface DynamicPreviewSettings {
readonly resourceColumn: vscode.ViewColumn;
@@ -75,6 +76,17 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
super();
this._register(vscode.window.registerWebviewPanelSerializer(DynamicMarkdownPreview.viewType, this));
this._register(vscode.window.registerCustomEditorProvider(this.customEditorViewType, this));
this._register(vscode.window.onDidChangeActiveTextEditor(textEditor => {
// When at a markdown file, apply existing scroll settings
if (textEditor && textEditor.document && isMarkdownFile(textEditor.document)) {
const line = this._topmostLineMonitor.getPreviousEditorLineByUri(textEditor.document.uri);
if (line) {
scrollEditorToLine(line, textEditor);
}
}
}));
}
public refresh() {
@@ -160,14 +172,18 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
document: vscode.TextDocument,
webview: vscode.WebviewPanel
): Promise<void> {
const lineNumber = this._topmostLineMonitor.getPreviousEditorLineByUri(document.uri);
const preview = StaticMarkdownPreview.revive(
document.uri,
webview,
this._contentProvider,
this._previewConfigurations,
this._topmostLineMonitor,
this._logger,
this._contributions,
this._engine);
this._engine,
lineNumber
);
this.registerStaticPreview(preview);
}
@@ -175,11 +191,14 @@ export class MarkdownPreviewManager extends Disposable implements vscode.Webview
resource: vscode.Uri,
previewSettings: DynamicPreviewSettings
): DynamicMarkdownPreview {
const activeTextEditorURI = vscode.window.activeTextEditor?.document.uri;
const scrollLine = (activeTextEditorURI?.toString() === resource.toString()) ? vscode.window.activeTextEditor?.visibleRanges[0].start.line : undefined;
const preview = DynamicMarkdownPreview.create(
{
resource,
resourceColumn: previewSettings.resourceColumn,
locked: previewSettings.locked,
line: scrollLine,
},
previewSettings.previewColumn,
this._contentProvider,

View File

@@ -4,13 +4,13 @@
*--------------------------------------------------------------------------------------------*/
import { MarkdownIt, Token } from 'markdown-it';
import * as path from 'path';
import * as vscode from 'vscode';
import { MarkdownContributionProvider as MarkdownContributionProvider } from './markdownExtensions';
import { Slugifier } from './slugify';
import { SkinnyTextDocument } from './tableOfContentsProvider';
import { hash } from './util/hash';
import { isOfScheme, MarkdownFileExtensions, Schemes } from './util/links';
import { isOfScheme, Schemes } from './util/links';
import { WebviewResourceProvider } from './util/resources';
const UNICODE_NEWLINE_REGEX = /\u2028|\u2029/g;
@@ -62,12 +62,14 @@ export interface RenderOutput {
interface RenderEnv {
containingImages: { src: string }[];
currentDocument: vscode.Uri | undefined;
resourceProvider: WebviewResourceProvider | undefined;
}
export class MarkdownEngine {
private md?: Promise<MarkdownIt>;
private currentDocument?: vscode.Uri;
private _slugCount = new Map<string, number>();
private _tokenCache = new TokenCache();
@@ -113,7 +115,7 @@ export class MarkdownEngine {
this.addLineNumberRenderer(md, renderName);
}
this.addImageStabilizer(md);
this.addImageRenderer(md);
this.addFencedRenderer(md);
this.addLinkNormalizer(md);
this.addLinkValidator(md);
@@ -128,6 +130,10 @@ export class MarkdownEngine {
return md;
}
public reloadPlugins() {
this.md = undefined;
}
private tokenizeDocument(
document: SkinnyTextDocument,
config: MarkdownItConfig,
@@ -138,27 +144,18 @@ export class MarkdownEngine {
return cached;
}
this.currentDocument = document.uri;
const tokens = this.tokenizeString(document.getText(), engine);
this._tokenCache.update(document, config, tokens);
return tokens;
}
public async renderText(document: vscode.Uri, text: string): Promise<string> { // {{SQL CARBON EDIT}} - Add renderText method
const config = this.getConfig(document);
const engine = await this.getEngine(config);
this.currentDocument = document;
return engine.render(text, config);
}
private tokenizeString(text: string, engine: MarkdownIt) {
this._slugCount = new Map<string, number>();
return engine.parse(text.replace(UNICODE_NEWLINE_REGEX, ''), {});
}
public async render(input: SkinnyTextDocument | string): Promise<RenderOutput> {
public async render(input: SkinnyTextDocument | string, resourceProvider?: WebviewResourceProvider): Promise<RenderOutput> {
const config = this.getConfig(typeof input === 'string' ? undefined : input.uri);
const engine = await this.getEngine(config);
@@ -167,7 +164,9 @@ export class MarkdownEngine {
: this.tokenizeDocument(input, config, engine);
const env: RenderEnv = {
containingImages: []
containingImages: [],
currentDocument: typeof input === 'string' ? undefined : input.uri,
resourceProvider,
};
const html = engine.renderer.render(tokens, {
@@ -200,12 +199,12 @@ export class MarkdownEngine {
};
}
private addLineNumberRenderer(md: any, ruleName: string): void {
private addLineNumberRenderer(md: MarkdownIt, ruleName: string): void {
const original = md.renderer.rules[ruleName];
md.renderer.rules[ruleName] = (tokens: any, idx: number, options: any, env: any, self: any) => {
md.renderer.rules[ruleName] = (tokens: Token[], idx: number, options: any, env: any, self: any) => {
const token = tokens[idx];
if (token.map && token.map.length) {
token.attrSet('data-line', token.map[0]);
token.attrSet('data-line', token.map[0] + '');
token.attrJoin('class', 'code-line');
}
@@ -217,9 +216,9 @@ export class MarkdownEngine {
};
}
private addImageStabilizer(md: any): void {
private addImageRenderer(md: MarkdownIt): void {
const original = md.renderer.rules.image;
md.renderer.rules.image = (tokens: any, idx: number, options: any, env: RenderEnv, self: any) => {
md.renderer.rules.image = (tokens: Token[], idx: number, options: any, env: RenderEnv, self: any) => {
const token = tokens[idx];
token.attrJoin('class', 'loading');
@@ -228,6 +227,11 @@ export class MarkdownEngine {
env.containingImages?.push({ src });
const imgHash = hash(src);
token.attrSet('id', `image-hash-${imgHash}`);
if (!token.attrGet('data-src')) {
token.attrSet('src', this.toResourceUri(src, env.currentDocument, env.resourceProvider));
token.attrSet('data-src', src);
}
}
if (original) {
@@ -238,9 +242,9 @@ export class MarkdownEngine {
};
}
private addFencedRenderer(md: any): void {
private addFencedRenderer(md: MarkdownIt): void {
const original = md.renderer.rules['fenced'];
md.renderer.rules['fenced'] = (tokens: any, idx: number, options: any, env: any, self: any) => {
md.renderer.rules['fenced'] = (tokens: Token[], idx: number, options: any, env: any, self: any) => {
const token = tokens[idx];
if (token.map && token.map.length) {
token.attrJoin('class', 'hljs');
@@ -250,7 +254,7 @@ export class MarkdownEngine {
};
}
private addLinkNormalizer(md: any): void {
private addLinkNormalizer(md: MarkdownIt): void {
const normalizeLink = md.normalizeLink;
md.normalizeLink = (link: string) => {
try {
@@ -259,43 +263,6 @@ export class MarkdownEngine {
return normalizeLink(vscode.Uri.parse(link).with({ scheme: vscode.env.uriScheme }).toString());
}
// Support file:// links
if (isOfScheme(Schemes.file, link)) {
// Ensure link is relative by prepending `/` so that it uses the <base> element URI
// when resolving the absolute URL
return normalizeLink('/' + link.replace(/^file:/, 'file'));
}
// If original link doesn't look like a url with a scheme, assume it must be a link to a file in workspace
if (!/^[a-z\-]+:/i.test(link)) {
// Use a fake scheme for parsing
let uri = vscode.Uri.parse('markdown-link:' + link);
// Relative paths should be resolved correctly inside the preview but we need to
// handle absolute paths specially (for images) to resolve them relative to the workspace root
if (uri.path[0] === '/') {
const root = vscode.workspace.getWorkspaceFolder(this.currentDocument!);
if (root) {
const fileUri = vscode.Uri.joinPath(root.uri, uri.fsPath).with({
fragment: uri.fragment,
query: uri.query,
});
// Ensure fileUri is relative by prepending `/` so that it uses the <base> element URI
// when resolving the absolute URL
uri = vscode.Uri.parse('markdown-link:' + '/' + fileUri.toString(true).replace(/^\S+?:/, fileUri.scheme));
}
}
const extname = path.extname(uri.fsPath);
if (uri.fragment && (extname === '' || MarkdownFileExtensions.includes(extname))) {
uri = uri.with({
fragment: this.slugifier.fromHeading(uri.fragment).value
});
}
return normalizeLink(uri.toString(true).replace(/^markdown-link:/, ''));
}
} catch (e) {
// noop
}
@@ -303,7 +270,7 @@ export class MarkdownEngine {
};
}
private addLinkValidator(md: any): void {
private addLinkValidator(md: MarkdownIt): void {
const validateLink = md.validateLink;
md.validateLink = (link: string) => {
return validateLink(link)
@@ -313,9 +280,9 @@ export class MarkdownEngine {
};
}
private addNamedHeaders(md: any): void {
private addNamedHeaders(md: MarkdownIt): void {
const original = md.renderer.rules.heading_open;
md.renderer.rules.heading_open = (tokens: any, idx: number, options: any, env: any, self: any) => {
md.renderer.rules.heading_open = (tokens: Token[], idx: number, options: any, env: any, self: any) => {
const title = tokens[idx + 1].children.reduce((acc: string, t: any) => acc + t.content, '');
let slug = this.slugifier.fromHeading(title);
@@ -338,12 +305,12 @@ export class MarkdownEngine {
};
}
private addLinkRenderer(md: any): void {
const old_render = md.renderer.rules.link_open || ((tokens: any, idx: number, options: any, _env: any, self: any) => {
private addLinkRenderer(md: MarkdownIt): void {
const old_render = md.renderer.rules.link_open || ((tokens: Token[], idx: number, options: any, _env: any, self: any) => {
return self.renderToken(tokens, idx, options);
});
md.renderer.rules.link_open = (tokens: any, idx: number, options: any, env: any, self: any) => {
md.renderer.rules.link_open = (tokens: Token[], idx: number, options: any, env: any, self: any) => {
const token = tokens[idx];
const hrefIndex = token.attrIndex('href');
if (hrefIndex >= 0) {
@@ -353,6 +320,50 @@ export class MarkdownEngine {
return old_render(tokens, idx, options, env, self);
};
}
private toResourceUri(href: string, currentDocument: vscode.Uri | undefined, resourceProvider: WebviewResourceProvider | undefined): string {
try {
// Support file:// links
if (isOfScheme(Schemes.file, href)) {
const uri = vscode.Uri.parse(href);
if (resourceProvider) {
return resourceProvider.asWebviewUri(uri).toString(true);
}
// Not sure how to resolve this
return href;
}
// If original link doesn't look like a url with a scheme, assume it must be a link to a file in workspace
if (!/^[a-z\-]+:/i.test(href)) {
// Use a fake scheme for parsing
let uri = vscode.Uri.parse('markdown-link:' + href);
// Relative paths should be resolved correctly inside the preview but we need to
// handle absolute paths specially to resolve them relative to the workspace root
if (uri.path[0] === '/' && currentDocument) {
const root = vscode.workspace.getWorkspaceFolder(currentDocument);
if (root) {
uri = vscode.Uri.joinPath(root.uri, uri.fsPath).with({
fragment: uri.fragment,
query: uri.query,
});
if (resourceProvider) {
return resourceProvider.asWebviewUri(uri).toString(true);
} else {
uri = uri.with({ scheme: 'markdown-link' });
}
}
}
return uri.toString(true).replace(/^markdown-link:/, '');
}
return href;
} catch {
return href;
}
}
}
async function getMarkdownOptions(md: () => MarkdownIt) {

View File

@@ -37,11 +37,11 @@ suite('markdown.engine', () => {
const engine = createNewMarkdownEngine();
assert.deepStrictEqual((await engine.render(input)), {
html: '<p data-line="0" class="code-line">'
+ '<img src="img.png" alt="" class="loading" id="image-hash--754511435"> '
+ '<img src="img.png" alt="" class="loading" id="image-hash--754511435" data-src="img.png"> '
+ '<a href="no-img.png" data-href="no-img.png"></a> '
+ '<img src="http://example.org/img.png" alt="" class="loading" id="image-hash--1903814170"> '
+ '<img src="img.png" alt="" class="loading" id="image-hash--754511435"> '
+ '<img src="./img2.png" alt="" class="loading" id="image-hash-265238964">'
+ '<img src="http://example.org/img.png" alt="" class="loading" id="image-hash--1903814170" data-src="http://example.org/img.png"> '
+ '<img src="img.png" alt="" class="loading" id="image-hash--754511435" data-src="img.png"> '
+ '<img src="./img2.png" alt="" class="loading" id="image-hash-265238964" data-src="./img2.png">'
+ '</p>\n'
,
containingImages: [{ src: 'img.png' }, { src: 'http://example.org/img.png' }, { src: 'img.png' }, { src: './img2.png' }],

View File

@@ -18,7 +18,7 @@ suite('markdown.WorkspaceSymbolProvider', () => {
test('Should not return anything for empty workspace', async () => {
const provider = new MarkdownWorkspaceSymbolProvider(symbolProvider, new InMemoryWorkspaceMarkdownDocumentProvider([]));
assert.deepEqual(await provider.provideWorkspaceSymbols(''), []);
assert.deepStrictEqual(await provider.provideWorkspaceSymbols(''), []);
});
test('Should return symbols from workspace with one markdown file', async () => {

View File

@@ -15,4 +15,4 @@ export function equals<T>(one: ReadonlyArray<T>, other: ReadonlyArray<T>, itemEq
}
return true;
}
}

View File

@@ -39,4 +39,4 @@ export abstract class Disposable {
protected get isDisposed() {
return this._isDisposed;
}
}
}

View File

@@ -7,4 +7,4 @@ import * as vscode from 'vscode';
export function isMarkdownFile(document: vscode.TextDocument) {
return document.languageId === 'markdown';
}
}

View File

@@ -36,4 +36,4 @@ class LazyValue<T> implements Lazy<T> {
export function lazy<T>(getValue: () => T): Lazy<T> {
return new LazyValue<T>(getValue);
}
}

View File

@@ -14,7 +14,6 @@ export const Schemes = {
data: 'data:',
vscode: 'vscode:',
'vscode-insiders': 'vscode-insiders:',
'vscode-resource': 'vscode-resource:',
};
const knownSchemes = [

View File

@@ -11,23 +11,3 @@ export interface WebviewResourceProvider {
readonly cspSource: string;
}
export function normalizeResource(
base: vscode.Uri,
resource: vscode.Uri
): vscode.Uri {
// If we have a windows path and are loading a workspace with an authority,
// make sure we use a unc path with an explicit localhost authority.
//
// Otherwise, the `<base>` rule will insert the authority into the resolved resource
// URI incorrectly.
if (base.authority && !resource.authority) {
const driveMatch = resource.path.match(/^\/(\w):\//);
if (driveMatch) {
return vscode.Uri.file(`\\\\localhost\\${driveMatch[1]}$\\${resource.fsPath.replace(/^\w:\\/, '')}`).with({
fragment: resource.fragment,
query: resource.query
});
}
}
return resource;
}

View File

@@ -7,18 +7,32 @@ import * as vscode from 'vscode';
import { Disposable } from '../util/dispose';
import { isMarkdownFile } from './file';
export interface LastScrollLocation {
readonly line: number;
readonly uri: vscode.Uri;
}
export class TopmostLineMonitor extends Disposable {
private readonly pendingUpdates = new Map<string, number>();
private readonly throttle = 50;
private previousEditorInfo = new Map<string, LastScrollLocation>();
public isPrevEditorCustom = false;
constructor() {
super();
if (vscode.window.activeTextEditor) {
const line = getVisibleLine(vscode.window.activeTextEditor);
this.setPreviousEditorLine({ uri: vscode.window.activeTextEditor.document.uri, line: line ?? 0 });
}
this._register(vscode.window.onDidChangeTextEditorVisibleRanges(event => {
if (isMarkdownFile(event.textEditor.document)) {
const line = getVisibleLine(event.textEditor);
if (typeof line === 'number') {
this.updateLine(event.textEditor.document.uri, line);
this.setPreviousEditorLine({ uri: event.textEditor.document.uri, line: line });
}
}
}));
@@ -27,7 +41,16 @@ export class TopmostLineMonitor extends Disposable {
private readonly _onChanged = this._register(new vscode.EventEmitter<{ readonly resource: vscode.Uri, readonly line: number }>());
public readonly onDidChanged = this._onChanged.event;
private updateLine(
public setPreviousEditorLine(scrollLocation: LastScrollLocation): void {
this.previousEditorInfo.set(scrollLocation.uri.toString(), scrollLocation);
}
public getPreviousEditorLineByUri(resource: vscode.Uri): number | undefined {
const scrollLoc = this.previousEditorInfo.get(resource.toString());
return scrollLoc?.line;
}
public updateLine(
resource: vscode.Uri,
line: number
) {

View File

@@ -26,10 +26,15 @@
resolved "https://registry.yarnpkg.com/@types/markdown-it/-/markdown-it-0.0.2.tgz#5d9ad19e6e6508cdd2f2596df86fd0aade598660"
integrity sha1-XZrRnm5lCM3S8llt+G/Qqt5ZhmA=
"@types/node@^12.19.9":
version "12.20.6"
resolved "https://registry.yarnpkg.com/@types/node/-/node-12.20.6.tgz#7b73cce37352936e628c5ba40326193443cfba25"
integrity sha512-sRVq8d+ApGslmkE9e3i+D3gFGk7aZHAT+G4cIpIEdLJYPsWiSPwcAnJEjddLQQDqV3Ra2jOclX/Sv6YrvGYiWA==
"@types/node@14.x":
version "14.14.43"
resolved "https://registry.yarnpkg.com/@types/node/-/node-14.14.43.tgz#26bcbb0595b305400e8ceaf9a127a7f905ae49c8"
integrity sha512-3pwDJjp1PWacPTpH0LcfhgjvurQvrZFBrC6xxjaUEZ7ifUtT32jtjPxEMMblpqd2Mvx+k8haqQJLQxolyGN/cQ==
"@types/vscode-webview@^1.57.0":
version "1.57.0"
resolved "https://registry.yarnpkg.com/@types/vscode-webview/-/vscode-webview-1.57.0.tgz#bad5194d45ae8d03afc1c0f67f71ff5e7a243bbf"
integrity sha512-x3Cb/SMa1IwRHfSvKaZDZOTh4cNoG505c3NjTqGlMC082m++x/ETUmtYniDsw6SSmYzZXO8KBNhYxR0+VqymqA==
applicationinsights@1.7.4:
version "1.7.4"

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