mirror of
https://github.com/microsoft/vscode.git
synced 2026-10-05 15:36:22 +01:00
Merge remote-tracking branch 'upstream/master' into rebornix/notebook
This commit is contained in:
commit
8d8580260f
257 files changed
+5971
-3106
No files matched your search
@@ -8,7 +8,7 @@ This project incorporates components from the projects listed below. The origina
|
||||
1. atom/language-clojure version 0.22.7 (https://github.com/atom/language-clojure)
|
||||
2. atom/language-coffee-script version 0.49.3 (https://github.com/atom/language-coffee-script)
|
||||
3. atom/language-java version 0.31.3 (https://github.com/atom/language-java)
|
||||
4. atom/language-sass version 0.61.4 (https://github.com/atom/language-sass)
|
||||
4. atom/language-sass version 0.62.1 (https://github.com/atom/language-sass)
|
||||
5. atom/language-shellscript version 0.26.0 (https://github.com/atom/language-shellscript)
|
||||
6. atom/language-xml version 0.35.2 (https://github.com/atom/language-xml)
|
||||
7. Colorsublime-Themes version 0.1.0 (https://github.com/Colorsublime/Colorsublime-Themes)
|
||||
@@ -27,13 +27,13 @@ This project incorporates components from the projects listed below. The origina
|
||||
20. Ionic documentation version 1.2.4 (https://github.com/ionic-team/ionic-site)
|
||||
21. ionide/ionide-fsgrammar (https://github.com/ionide/ionide-fsgrammar)
|
||||
22. jeff-hykin/cpp-textmate-grammar version 1.12.11 (https://github.com/jeff-hykin/cpp-textmate-grammar)
|
||||
23. jeff-hykin/cpp-textmate-grammar version 1.14.9 (https://github.com/jeff-hykin/cpp-textmate-grammar)
|
||||
23. jeff-hykin/cpp-textmate-grammar version 1.14.13 (https://github.com/jeff-hykin/cpp-textmate-grammar)
|
||||
24. js-beautify version 1.6.8 (https://github.com/beautify-web/js-beautify)
|
||||
25. Jxck/assert version 1.0.0 (https://github.com/Jxck/assert)
|
||||
26. language-docker (https://github.com/moby/moby)
|
||||
27. language-go version 0.44.3 (https://github.com/atom/language-go)
|
||||
28. language-less version 0.34.2 (https://github.com/atom/language-less)
|
||||
29. language-php version 0.44.2 (https://github.com/atom/language-php)
|
||||
29. language-php version 0.44.3 (https://github.com/atom/language-php)
|
||||
30. language-rust version 0.4.12 (https://github.com/zargony/atom-language-rust)
|
||||
31. MagicStack/MagicPython version 1.1.1 (https://github.com/MagicStack/MagicPython)
|
||||
32. marked version 0.6.2 (https://github.com/markedjs/marked)
|
||||
@@ -589,7 +589,7 @@ END OF HTML 5.1 W3C Working Draft NOTICES AND INFORMATION
|
||||
=========================================
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2017 Yuki Ueda
|
||||
Copyright (c) 2019 Yuki Ueda
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -118,6 +118,32 @@ steps:
|
||||
displayName: Run integration tests
|
||||
condition: and(succeeded(), eq(variables['VSCODE_STEP_ON_IT'], 'false'))
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
yarn gulp "vscode-linux-x64-build-deb"
|
||||
yarn gulp "vscode-linux-x64-build-rpm"
|
||||
yarn gulp "vscode-linux-x64-prepare-snap"
|
||||
displayName: Build packages
|
||||
|
||||
- task: SFP.build-tasks.custom-build-task-1.EsrpCodeSigning@1
|
||||
inputs:
|
||||
ConnectedServiceName: 'ESRP CodeSign'
|
||||
FolderPath: '.build/linux/rpm/x86_64'
|
||||
Pattern: '*.rpm'
|
||||
signConfigType: inlineSignParams
|
||||
inlineOperation: |
|
||||
[
|
||||
{
|
||||
"keyCode": "CP-450779-Pgp",
|
||||
"operationSetCode": "LinuxSign",
|
||||
"parameters": [ ],
|
||||
"toolName": "sign",
|
||||
"toolVersion": "1.0"
|
||||
}
|
||||
]
|
||||
SessionTimeout: 120
|
||||
displayName: Codesign rpm
|
||||
|
||||
- script: |
|
||||
set -e
|
||||
AZURE_DOCUMENTDB_MASTERKEY="$(builds-docdb-key-readwrite)" \
|
||||
|
||||
@@ -31,7 +31,6 @@ node build/azure-pipelines/common/createAsset.js "server-$PLATFORM_LINUX" archiv
|
||||
node build/azure-pipelines/common/symbols.js "$VSCODE_MIXIN_PASSWORD" "$VSCODE_HOCKEYAPP_TOKEN" "x64" "$VSCODE_HOCKEYAPP_ID_LINUX64"
|
||||
|
||||
# Publish DEB
|
||||
yarn gulp "vscode-linux-x64-build-deb"
|
||||
PLATFORM_DEB="linux-deb-x64"
|
||||
DEB_ARCH="amd64"
|
||||
DEB_FILENAME="$(ls $REPO/.build/linux/deb/$DEB_ARCH/deb/)"
|
||||
@@ -40,7 +39,6 @@ DEB_PATH="$REPO/.build/linux/deb/$DEB_ARCH/deb/$DEB_FILENAME"
|
||||
node build/azure-pipelines/common/createAsset.js "$PLATFORM_DEB" package "$DEB_FILENAME" "$DEB_PATH"
|
||||
|
||||
# Publish RPM
|
||||
yarn gulp "vscode-linux-x64-build-rpm"
|
||||
PLATFORM_RPM="linux-rpm-x64"
|
||||
RPM_ARCH="x86_64"
|
||||
RPM_FILENAME="$(ls $REPO/.build/linux/rpm/$RPM_ARCH/ | grep .rpm)"
|
||||
@@ -49,8 +47,6 @@ RPM_PATH="$REPO/.build/linux/rpm/$RPM_ARCH/$RPM_FILENAME"
|
||||
node build/azure-pipelines/common/createAsset.js "$PLATFORM_RPM" package "$RPM_FILENAME" "$RPM_PATH"
|
||||
|
||||
# Publish Snap
|
||||
yarn gulp "vscode-linux-x64-prepare-snap"
|
||||
|
||||
# Pack snap tarball artifact, in order to preserve file perms
|
||||
mkdir -p $REPO/.build/linux/snap-tarball
|
||||
SNAP_TARBALL_PATH="$REPO/.build/linux/snap-tarball/snap-x64.tar.gz"
|
||||
|
||||
@@ -16,7 +16,7 @@
|
||||
},
|
||||
{
|
||||
"name": "ms-vscode.node-debug2",
|
||||
"version": "1.41.0",
|
||||
"version": "1.41.3",
|
||||
"repo": "https://github.com/Microsoft/vscode-node-debug2",
|
||||
"metadata": {
|
||||
"id": "36d19e17-7569-4841-a001-947eb18602b2",
|
||||
@@ -31,7 +31,7 @@
|
||||
},
|
||||
{
|
||||
"name": "ms-vscode.references-view",
|
||||
"version": "0.0.38",
|
||||
"version": "0.0.42",
|
||||
"repo": "https://github.com/Microsoft/vscode-reference-view",
|
||||
"metadata": {
|
||||
"id": "dc489f46-520d-4556-ae85-1f9eab3c412d",
|
||||
|
||||
@@ -50,10 +50,6 @@
|
||||
"name": "vs/workbench/contrib/comments",
|
||||
"project": "vscode-workbench"
|
||||
},
|
||||
{
|
||||
"name": "vs/workbench/contrib/testCustomEditors",
|
||||
"project": "vscode-workbench"
|
||||
},
|
||||
{
|
||||
"name": "vs/workbench/contrib/debug",
|
||||
"project": "vscode-workbench"
|
||||
|
||||
@@ -964,10 +964,10 @@ Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Applications\{#ExeBas
|
||||
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Applications\{#ExeBasename}.exe\DefaultIcon"; ValueType: string; ValueName: ""; ValueData: "{app}\resources\app\resources\win32\default.ico"
|
||||
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\Applications\{#ExeBasename}.exe\shell\open\command"; ValueType: string; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""
|
||||
|
||||
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu, {#ShellNameShort}}"; Tasks: addcontextmenufiles; Flags: uninsdeletekey
|
||||
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Tasks: addcontextmenufiles; Flags: uninsdeletekey
|
||||
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufiles
|
||||
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\*\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%1"""; Tasks: addcontextmenufiles
|
||||
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu, {#ShellNameShort}}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey
|
||||
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "{cm:OpenWithCodeContextMenu,{#ShellNameShort}}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey
|
||||
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}"; ValueType: expandsz; ValueName: "Icon"; ValueData: "{app}\{#ExeBasename}.exe"; Tasks: addcontextmenufolders
|
||||
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\shell\{#RegValueName}\command"; ValueType: expandsz; ValueName: ""; ValueData: """{app}\{#ExeBasename}.exe"" ""%V"""; Tasks: addcontextmenufolders
|
||||
Root: {#SoftwareClassesRootKey}; Subkey: "Software\Classes\directory\background\shell\{#RegValueName}"; ValueType: expandsz; ValueName: ""; ValueData: "Open w&ith {#ShellNameShort}"; Tasks: addcontextmenufolders; Flags: uninsdeletekey
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema#",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "Configures an attached to container",
|
||||
"allowComments": true,
|
||||
"type": "object",
|
||||
@@ -18,6 +18,10 @@
|
||||
"type": "integer"
|
||||
}
|
||||
},
|
||||
"settings": {
|
||||
"$ref": "vscode://schemas/settings/machine",
|
||||
"description": "Machine specific settings that should be copied into the container."
|
||||
},
|
||||
"remoteEnv": {
|
||||
"type": "object",
|
||||
"additionalProperties": {
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/schema#",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "Defines a dev container",
|
||||
"allowComments": true,
|
||||
"type": "object",
|
||||
@@ -84,6 +84,13 @@
|
||||
"type": "boolean",
|
||||
"description": "Controls whether on Linux the container's user should be updated with the local user's UID and GID. On by default."
|
||||
},
|
||||
"mounts": {
|
||||
"type": "array",
|
||||
"description": "Mount points to set up when creating the container. See Docker's documentation for the --mount option for the supported syntax.",
|
||||
"items": {
|
||||
"type": "string"
|
||||
}
|
||||
},
|
||||
"runArgs": {
|
||||
"type": "array",
|
||||
"description": "The arguments required when starting in the container.",
|
||||
|
||||
@@ -16,7 +16,13 @@ void Rectangle::set_values (int x, int y) {
|
||||
height = y;
|
||||
}
|
||||
|
||||
long double operator "" _w(long double);
|
||||
#define MY_MACRO(a, b)
|
||||
|
||||
int main () {
|
||||
1.2_w; // calls operator "" _w(1.2L)
|
||||
asm("movl %a %b");
|
||||
MY_MACRO(1, 2);
|
||||
Rectangle rect;
|
||||
rect.set_values (3,4);
|
||||
cout << "area: " << rect.area();
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
"c": "_UCRT",
|
||||
"t": "source.cpp meta.preprocessor.conditional.cpp entity.name.function.preprocessor.cpp",
|
||||
"r": {
|
||||
"dark_plus": "entity.name.function: #DCDCAA",
|
||||
"light_plus": "entity.name.function: #795E26",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"dark_plus": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_plus": "entity.name.function.preprocessor: #0000FF",
|
||||
"dark_vs": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_vs": "entity.name.function.preprocessor: #0000FF",
|
||||
"hc_black": "entity.name.function: #DCDCAA"
|
||||
}
|
||||
},
|
||||
@@ -91,10 +91,10 @@
|
||||
"c": "_UCRT",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp",
|
||||
"r": {
|
||||
"dark_plus": "entity.name.function: #DCDCAA",
|
||||
"light_plus": "entity.name.function: #795E26",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"dark_plus": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_plus": "entity.name.function.preprocessor: #0000FF",
|
||||
"dark_vs": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_vs": "entity.name.function.preprocessor: #0000FF",
|
||||
"hc_black": "entity.name.function: #DCDCAA"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
"c": "_UCRT",
|
||||
"t": "source.cpp meta.preprocessor.conditional.cpp entity.name.function.preprocessor.cpp",
|
||||
"r": {
|
||||
"dark_plus": "entity.name.function: #DCDCAA",
|
||||
"light_plus": "entity.name.function: #795E26",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"dark_plus": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_plus": "entity.name.function.preprocessor: #0000FF",
|
||||
"dark_vs": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_vs": "entity.name.function.preprocessor: #0000FF",
|
||||
"hc_black": "entity.name.function: #DCDCAA"
|
||||
}
|
||||
},
|
||||
@@ -80,10 +80,10 @@
|
||||
"c": "_UCRT",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp",
|
||||
"r": {
|
||||
"dark_plus": "entity.name.function: #DCDCAA",
|
||||
"light_plus": "entity.name.function: #795E26",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"dark_plus": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_plus": "entity.name.function.preprocessor: #0000FF",
|
||||
"dark_vs": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_vs": "entity.name.function.preprocessor: #0000FF",
|
||||
"hc_black": "entity.name.function: #DCDCAA"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
"c": "DOCTEST_IMPLEMENT_FIXTURE",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp",
|
||||
"r": {
|
||||
"dark_plus": "entity.name.function: #DCDCAA",
|
||||
"light_plus": "entity.name.function: #795E26",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"dark_plus": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_plus": "entity.name.function.preprocessor: #0000FF",
|
||||
"dark_vs": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_vs": "entity.name.function.preprocessor: #0000FF",
|
||||
"hc_black": "entity.name.function: #DCDCAA"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -36,10 +36,10 @@
|
||||
"c": "B4G_DEBUG_CHECK",
|
||||
"t": "source.cpp meta.preprocessor.conditional.cpp entity.name.function.preprocessor.cpp",
|
||||
"r": {
|
||||
"dark_plus": "entity.name.function: #DCDCAA",
|
||||
"light_plus": "entity.name.function: #795E26",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"dark_plus": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_plus": "entity.name.function.preprocessor: #0000FF",
|
||||
"dark_vs": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_vs": "entity.name.function.preprocessor: #0000FF",
|
||||
"hc_black": "entity.name.function: #DCDCAA"
|
||||
}
|
||||
},
|
||||
@@ -1807,10 +1807,10 @@
|
||||
"c": "movw $0x38, %ax; ltr %ax",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp string.quoted.double.cpp meta.embedded.assembly.cpp",
|
||||
"r": {
|
||||
"dark_plus": "meta.embedded: #D4D4D4",
|
||||
"light_plus": "meta.embedded: #000000",
|
||||
"dark_vs": "meta.embedded: #D4D4D4",
|
||||
"light_vs": "meta.embedded: #000000",
|
||||
"dark_plus": "meta.embedded.assembly: #CE9178",
|
||||
"light_plus": "meta.embedded.assembly: #A31515",
|
||||
"dark_vs": "meta.embedded.assembly: #CE9178",
|
||||
"light_vs": "meta.embedded.assembly: #A31515",
|
||||
"hc_black": "meta.embedded: #FFFFFF"
|
||||
}
|
||||
},
|
||||
|
||||
@@ -190,10 +190,10 @@
|
||||
"c": "EXTERN_C",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp",
|
||||
"r": {
|
||||
"dark_plus": "entity.name.function: #DCDCAA",
|
||||
"light_plus": "entity.name.function: #795E26",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"dark_plus": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_plus": "entity.name.function.preprocessor: #0000FF",
|
||||
"dark_vs": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_vs": "entity.name.function.preprocessor: #0000FF",
|
||||
"hc_black": "entity.name.function: #DCDCAA"
|
||||
}
|
||||
},
|
||||
@@ -1011,6 +1011,281 @@
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "long",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp",
|
||||
"r": {
|
||||
"dark_plus": "storage.type: #569CD6",
|
||||
"light_plus": "storage.type: #0000FF",
|
||||
"dark_vs": "storage.type: #569CD6",
|
||||
"light_vs": "storage.type: #0000FF",
|
||||
"hc_black": "storage.type: #569CD6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp meta.qualified_type.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "double",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp",
|
||||
"r": {
|
||||
"dark_plus": "storage.type: #569CD6",
|
||||
"light_plus": "storage.type: #0000FF",
|
||||
"dark_vs": "storage.type: #569CD6",
|
||||
"light_vs": "storage.type: #0000FF",
|
||||
"hc_black": "storage.type: #569CD6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "operator",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp meta.head.function.definition.special.operator-overload.cpp keyword.other.operator.overload.cpp",
|
||||
"r": {
|
||||
"dark_plus": "keyword.other.operator: #C586C0",
|
||||
"light_plus": "keyword.other.operator: #AF00DB",
|
||||
"dark_vs": "keyword: #569CD6",
|
||||
"light_vs": "keyword: #0000FF",
|
||||
"hc_black": "keyword.other.operator: #C586C0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "\"\"",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp meta.head.function.definition.special.operator-overload.cpp entity.name.operator.custom-literal.cpp",
|
||||
"r": {
|
||||
"dark_plus": "entity.name.operator.custom-literal: #DCDCAA",
|
||||
"light_plus": "entity.name.operator.custom-literal: #795E26",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "_w",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp meta.head.function.definition.special.operator-overload.cpp entity.name.operator.custom-literal.cpp",
|
||||
"r": {
|
||||
"dark_plus": "entity.name.operator.custom-literal: #DCDCAA",
|
||||
"light_plus": "entity.name.operator.custom-literal: #795E26",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "(",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp meta.head.function.definition.special.operator-overload.cpp punctuation.section.parameters.begin.bracket.round.special.operator-overload.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "long",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp meta.head.function.definition.special.operator-overload.cpp meta.function.definition.parameters.special.operator-overload.cpp meta.parameter.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp",
|
||||
"r": {
|
||||
"dark_plus": "storage.type: #569CD6",
|
||||
"light_plus": "storage.type: #0000FF",
|
||||
"dark_vs": "storage.type: #569CD6",
|
||||
"light_vs": "storage.type: #0000FF",
|
||||
"hc_black": "storage.type: #569CD6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp meta.head.function.definition.special.operator-overload.cpp meta.function.definition.parameters.special.operator-overload.cpp meta.parameter.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "double",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp meta.head.function.definition.special.operator-overload.cpp meta.function.definition.parameters.special.operator-overload.cpp meta.parameter.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp",
|
||||
"r": {
|
||||
"dark_plus": "storage.type: #569CD6",
|
||||
"light_plus": "storage.type: #0000FF",
|
||||
"dark_vs": "storage.type: #569CD6",
|
||||
"light_vs": "storage.type: #0000FF",
|
||||
"hc_black": "storage.type: #569CD6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": ")",
|
||||
"t": "source.cpp meta.function.definition.special.operator-overload.cpp meta.head.function.definition.special.operator-overload.cpp punctuation.section.parameters.end.bracket.round.special.operator-overload.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": ";",
|
||||
"t": "source.cpp punctuation.terminator.statement.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "#",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp punctuation.definition.directive.cpp",
|
||||
"r": {
|
||||
"dark_plus": "keyword.control: #C586C0",
|
||||
"light_plus": "keyword.control: #AF00DB",
|
||||
"dark_vs": "keyword.control: #569CD6",
|
||||
"light_vs": "keyword.control: #0000FF",
|
||||
"hc_black": "keyword.control: #C586C0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "define",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp keyword.control.directive.define.cpp",
|
||||
"r": {
|
||||
"dark_plus": "keyword.control: #C586C0",
|
||||
"light_plus": "keyword.control: #AF00DB",
|
||||
"dark_vs": "keyword.control: #569CD6",
|
||||
"light_vs": "keyword.control: #0000FF",
|
||||
"hc_black": "keyword.control: #C586C0"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp",
|
||||
"r": {
|
||||
"dark_plus": "meta.preprocessor: #569CD6",
|
||||
"light_plus": "meta.preprocessor: #0000FF",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "meta.preprocessor: #569CD6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "MY_MACRO",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp entity.name.function.preprocessor.cpp",
|
||||
"r": {
|
||||
"dark_plus": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_plus": "entity.name.function.preprocessor: #0000FF",
|
||||
"dark_vs": "entity.name.function.preprocessor: #569CD6",
|
||||
"light_vs": "entity.name.function.preprocessor: #0000FF",
|
||||
"hc_black": "entity.name.function: #DCDCAA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "(",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp punctuation.definition.parameters.begin.preprocessor.cpp",
|
||||
"r": {
|
||||
"dark_plus": "meta.preprocessor: #569CD6",
|
||||
"light_plus": "meta.preprocessor: #0000FF",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "meta.preprocessor: #569CD6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "a",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp variable.parameter.preprocessor.cpp",
|
||||
"r": {
|
||||
"dark_plus": "variable: #9CDCFE",
|
||||
"light_plus": "variable: #001080",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "variable: #9CDCFE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": ",",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp punctuation.separator.parameters.cpp",
|
||||
"r": {
|
||||
"dark_plus": "meta.preprocessor: #569CD6",
|
||||
"light_plus": "meta.preprocessor: #0000FF",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "meta.preprocessor: #569CD6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp",
|
||||
"r": {
|
||||
"dark_plus": "meta.preprocessor: #569CD6",
|
||||
"light_plus": "meta.preprocessor: #0000FF",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "meta.preprocessor: #569CD6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "b",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp variable.parameter.preprocessor.cpp",
|
||||
"r": {
|
||||
"dark_plus": "variable: #9CDCFE",
|
||||
"light_plus": "variable: #001080",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "variable: #9CDCFE"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": ")",
|
||||
"t": "source.cpp meta.preprocessor.macro.cpp punctuation.definition.parameters.end.preprocessor.cpp",
|
||||
"r": {
|
||||
"dark_plus": "meta.preprocessor: #569CD6",
|
||||
"light_plus": "meta.preprocessor: #0000FF",
|
||||
"dark_vs": "meta.preprocessor: #569CD6",
|
||||
"light_vs": "meta.preprocessor: #0000FF",
|
||||
"hc_black": "meta.preprocessor: #569CD6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "int",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.qualified_type.cpp storage.type.primitive.cpp storage.type.built-in.primitive.cpp",
|
||||
@@ -1099,6 +1374,292 @@
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "1",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.numeric.decimal.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": ".",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.numeric.decimal.point.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "2",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.numeric.decimal.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "_w",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp keyword.other.unit.user-defined.cpp",
|
||||
"r": {
|
||||
"dark_plus": "keyword.other.unit: #B5CEA8",
|
||||
"light_plus": "keyword.other.unit: #09885A",
|
||||
"dark_vs": "keyword.other.unit: #B5CEA8",
|
||||
"light_vs": "keyword.other.unit: #09885A",
|
||||
"hc_black": "keyword.other.unit: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": ";",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp",
|
||||
"r": {
|
||||
"dark_plus": "comment: #6A9955",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #6A9955",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "//",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp punctuation.definition.comment.cpp",
|
||||
"r": {
|
||||
"dark_plus": "comment: #6A9955",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #6A9955",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " calls operator \"\" _w(1.2L)",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp comment.line.double-slash.cpp",
|
||||
"r": {
|
||||
"dark_plus": "comment: #6A9955",
|
||||
"light_plus": "comment: #008000",
|
||||
"dark_vs": "comment: #6A9955",
|
||||
"light_vs": "comment: #008000",
|
||||
"hc_black": "comment: #7CA668"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "asm",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp storage.type.asm.cpp",
|
||||
"r": {
|
||||
"dark_plus": "storage.type: #569CD6",
|
||||
"light_plus": "storage.type: #0000FF",
|
||||
"dark_vs": "storage.type: #569CD6",
|
||||
"light_vs": "storage.type: #0000FF",
|
||||
"hc_black": "storage.type: #569CD6"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "(",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp punctuation.section.parens.begin.bracket.round.assembly.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "\"",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp string.quoted.double.cpp punctuation.definition.string.begin.assembly.cpp",
|
||||
"r": {
|
||||
"dark_plus": "string: #CE9178",
|
||||
"light_plus": "string: #A31515",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "string: #CE9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "movl %a %b",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp string.quoted.double.cpp meta.embedded.assembly.cpp",
|
||||
"r": {
|
||||
"dark_plus": "meta.embedded.assembly: #CE9178",
|
||||
"light_plus": "meta.embedded.assembly: #A31515",
|
||||
"dark_vs": "meta.embedded.assembly: #CE9178",
|
||||
"light_vs": "meta.embedded.assembly: #A31515",
|
||||
"hc_black": "meta.embedded: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "\"",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp string.quoted.double.cpp punctuation.definition.string.end.assembly.cpp",
|
||||
"r": {
|
||||
"dark_plus": "string: #CE9178",
|
||||
"light_plus": "string: #A31515",
|
||||
"dark_vs": "string: #CE9178",
|
||||
"light_vs": "string: #A31515",
|
||||
"hc_black": "string: #CE9178"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": ")",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp meta.asm.cpp punctuation.section.parens.end.bracket.round.assembly.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": ";",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "MY_MACRO",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp entity.name.function.call.cpp",
|
||||
"r": {
|
||||
"dark_plus": "entity.name.function: #DCDCAA",
|
||||
"light_plus": "entity.name.function: #795E26",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "entity.name.function: #DCDCAA"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "(",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.begin.bracket.round.function.call.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "1",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.numeric.decimal.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": ",",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.separator.delimiter.comma.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " ",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": "2",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp constant.numeric.decimal.cpp",
|
||||
"r": {
|
||||
"dark_plus": "constant.numeric: #B5CEA8",
|
||||
"light_plus": "constant.numeric: #09885A",
|
||||
"dark_vs": "constant.numeric: #B5CEA8",
|
||||
"light_vs": "constant.numeric: #09885A",
|
||||
"hc_black": "constant.numeric: #B5CEA8"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": ")",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.section.arguments.end.bracket.round.function.call.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": ";",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp punctuation.terminator.statement.cpp",
|
||||
"r": {
|
||||
"dark_plus": "default: #D4D4D4",
|
||||
"light_plus": "default: #000000",
|
||||
"dark_vs": "default: #D4D4D4",
|
||||
"light_vs": "default: #000000",
|
||||
"hc_black": "default: #FFFFFF"
|
||||
}
|
||||
},
|
||||
{
|
||||
"c": " Rectangle rect",
|
||||
"t": "source.cpp meta.function.definition.cpp meta.body.function.definition.cpp",
|
||||
|
||||
@@ -5,8 +5,8 @@
|
||||
|
||||
import * as fs from 'fs';
|
||||
import * as path from 'path';
|
||||
import { commands, CompletionItem, CompletionItemKind, ExtensionContext, languages, Position, Range, SnippetString, TextEdit, window, workspace } from 'vscode';
|
||||
import { Disposable, LanguageClient, LanguageClientOptions, ServerOptions, TransportKind } from 'vscode-languageclient';
|
||||
import { commands, CompletionItem, CompletionItemKind, ExtensionContext, languages, Position, Range, SnippetString, TextEdit, window, workspace, TextDocument, CompletionContext, CancellationToken, ProviderResult, CompletionList } from 'vscode';
|
||||
import { Disposable, LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, ProvideCompletionItemsSignature } from 'vscode-languageclient';
|
||||
import * as nls from 'vscode-nls';
|
||||
import { getCustomDataPathsFromAllExtensions, getCustomDataPathsInAllWorkspaces } from './customData';
|
||||
|
||||
@@ -43,6 +43,31 @@ export function activate(context: ExtensionContext) {
|
||||
},
|
||||
initializationOptions: {
|
||||
dataPaths
|
||||
},
|
||||
middleware: {
|
||||
// testing the replace / insert mode
|
||||
provideCompletionItem(document: TextDocument, position: Position, context: CompletionContext, token: CancellationToken, next: ProvideCompletionItemsSignature): ProviderResult<CompletionItem[] | CompletionList> {
|
||||
function updateRanges(item: CompletionItem) {
|
||||
const range = item.range;
|
||||
if (range && range.end.isAfter(position) && range.start.isBeforeOrEqual(position)) {
|
||||
item.range2 = { inserting: new Range(range.start, position), replacing: range };
|
||||
item.range = undefined;
|
||||
}
|
||||
}
|
||||
function updateProposals(r: CompletionItem[] | CompletionList | null | undefined): CompletionItem[] | CompletionList | null | undefined {
|
||||
if (r) {
|
||||
(Array.isArray(r) ? r : r.items).forEach(updateRanges);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
const isThenable = <T>(obj: ProviderResult<T>): obj is Thenable<T> => obj && (<any>obj)['then'];
|
||||
|
||||
const r = next(document, position, context, token);
|
||||
if (isThenable<CompletionItem[] | CompletionList | null | undefined>(r)) {
|
||||
return r.then(updateProposals);
|
||||
}
|
||||
return updateProposals(r);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
@@ -783,6 +783,17 @@
|
||||
}
|
||||
}
|
||||
],
|
||||
"configurationDefaults": {
|
||||
"[css]": {
|
||||
"editor.suggest.insertMode": "replace"
|
||||
},
|
||||
"[scss]": {
|
||||
"editor.suggest.insertMode": "replace"
|
||||
},
|
||||
"[less]": {
|
||||
"editor.suggest.insertMode": "replace"
|
||||
}
|
||||
},
|
||||
"jsonValidation": [
|
||||
{
|
||||
"fileMatch": "*.css-data.json",
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "CSS contributions to package.json",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"main": "./out/cssServerMain",
|
||||
"dependencies": {
|
||||
"vscode-css-languageservice": "^4.0.3-next.22",
|
||||
"vscode-css-languageservice": "^4.0.3-next.24",
|
||||
"vscode-languageserver": "^6.0.0-next.3"
|
||||
},
|
||||
"devDependencies": {
|
||||
|
||||
@@ -781,10 +781,10 @@ supports-color@^5.3.0:
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
vscode-css-languageservice@^4.0.3-next.22:
|
||||
version "4.0.3-next.22"
|
||||
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.3-next.22.tgz#ddb23a7086807f0e098f069ad91a8e3b7a696cbb"
|
||||
integrity sha512-j7+S/0LPn/pTe/CQ8WscDttW5J3aY5Ls6bo/Cz8ZdlBjHl7DbrbZ2rEl5Qd6aKbg0ZdgjWVxGqjjgZFzh+O9/w==
|
||||
vscode-css-languageservice@^4.0.3-next.24:
|
||||
version "4.0.3-next.24"
|
||||
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.3-next.24.tgz#6190fb5af4621b7efc1a0772c1a178d996ffb42d"
|
||||
integrity sha512-7CPBmaQnvkgL7MXZK9vt5R5CwFaQ9TCqWt9aCi9dGm1g0uAgFOwk8+K5+fV2pasI+aoOvb/kLcFjxSSRD03KdA==
|
||||
dependencies:
|
||||
vscode-languageserver-textdocument "^1.0.0-next.4"
|
||||
vscode-languageserver-types "^3.15.0-next.6"
|
||||
|
||||
@@ -8,13 +8,13 @@ import * as fs from 'fs';
|
||||
import * as nls from 'vscode-nls';
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { languages, ExtensionContext, IndentAction, Position, TextDocument, Range, CompletionItem, CompletionItemKind, SnippetString, workspace, Disposable, FormattingOptions, CancellationToken, ProviderResult, TextEdit } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, TextDocumentPositionParams, DocumentRangeFormattingParams, DocumentRangeFormattingRequest } from 'vscode-languageclient';
|
||||
import { languages, ExtensionContext, IndentAction, Position, TextDocument, Range, CompletionItem, CompletionItemKind, SnippetString, workspace, Disposable, FormattingOptions, CancellationToken, ProviderResult, TextEdit, CompletionContext, CompletionList } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, ServerOptions, TransportKind, RequestType, TextDocumentPositionParams, DocumentRangeFormattingParams, DocumentRangeFormattingRequest, ProvideCompletionItemsSignature } from 'vscode-languageclient';
|
||||
import { EMPTY_ELEMENTS } from './htmlEmptyTagsShared';
|
||||
import { activateTagClosing } from './tagClosing';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
import { getCustomDataPathsInAllWorkspaces, getCustomDataPathsFromAllExtensions } from './customData';
|
||||
import { activateMatchingTagPosition as activateMatchingTagSelection } from './matchingTag';
|
||||
import { activateMirrorCursor } from './mirrorCursor';
|
||||
|
||||
namespace TagCloseRequest {
|
||||
export const type: RequestType<TextDocumentPositionParams, string, any, any> = new RequestType('html/tag');
|
||||
@@ -72,6 +72,31 @@ export function activate(context: ExtensionContext) {
|
||||
dataPaths,
|
||||
provideFormatter: false, // tell the server to not provide formatting capability and ignore the `html.format.enable` setting.
|
||||
},
|
||||
middleware: {
|
||||
// testing the replace / insert mode
|
||||
provideCompletionItem(document: TextDocument, position: Position, context: CompletionContext, token: CancellationToken, next: ProvideCompletionItemsSignature): ProviderResult<CompletionItem[] | CompletionList> {
|
||||
function updateRanges(item: CompletionItem) {
|
||||
const range = item.range;
|
||||
if (range && range.end.isAfter(position) && range.start.isBeforeOrEqual(position)) {
|
||||
item.range2 = { inserting: new Range(range.start, position), replacing: range };
|
||||
item.range = undefined;
|
||||
}
|
||||
}
|
||||
function updateProposals(r: CompletionItem[] | CompletionList | null | undefined): CompletionItem[] | CompletionList | null | undefined {
|
||||
if (r) {
|
||||
(Array.isArray(r) ? r : r.items).forEach(updateRanges);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
const isThenable = <T>(obj: ProviderResult<T>): obj is Thenable<T> => obj && (<any>obj)['then'];
|
||||
|
||||
const r = next(document, position, context, token);
|
||||
if (isThenable<CompletionItem[] | CompletionList | null | undefined>(r)) {
|
||||
return r.then(updateProposals);
|
||||
}
|
||||
return updateProposals(r);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
// Create the language client and start the client.
|
||||
@@ -93,7 +118,7 @@ export function activate(context: ExtensionContext) {
|
||||
return client.sendRequest(MatchingTagPositionRequest.type, param);
|
||||
};
|
||||
|
||||
disposable = activateMatchingTagSelection(matchingTagPositionRequestor, { html: true, handlebars: true }, 'html.autoSelectingMatchingTags');
|
||||
disposable = activateMirrorCursor(matchingTagPositionRequestor, { html: true, handlebars: true }, 'html.mirrorCursorOnMatchingTag');
|
||||
toDispose.push(disposable);
|
||||
|
||||
disposable = client.onTelemetry(e => {
|
||||
|
||||
@@ -1,143 +0,0 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import {
|
||||
window,
|
||||
workspace,
|
||||
Disposable,
|
||||
TextDocument,
|
||||
Position,
|
||||
TextEditorSelectionChangeEvent,
|
||||
Selection,
|
||||
Range,
|
||||
WorkspaceEdit
|
||||
} from 'vscode';
|
||||
|
||||
export function activateMatchingTagPosition(
|
||||
matchingTagPositionProvider: (document: TextDocument, position: Position) => Thenable<Position | null>,
|
||||
supportedLanguages: { [id: string]: boolean },
|
||||
configName: string
|
||||
): Disposable {
|
||||
let disposables: Disposable[] = [];
|
||||
|
||||
window.onDidChangeTextEditorSelection(event => onDidChangeTextEditorSelection(event), null, disposables);
|
||||
|
||||
let isEnabled = false;
|
||||
updateEnabledState();
|
||||
|
||||
window.onDidChangeActiveTextEditor(updateEnabledState, null, disposables);
|
||||
|
||||
function updateEnabledState() {
|
||||
isEnabled = false;
|
||||
let editor = window.activeTextEditor;
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
let document = editor.document;
|
||||
if (!supportedLanguages[document.languageId]) {
|
||||
return;
|
||||
}
|
||||
if (!workspace.getConfiguration(undefined, document.uri).get<boolean>(configName)) {
|
||||
return;
|
||||
}
|
||||
isEnabled = true;
|
||||
}
|
||||
|
||||
let prevCursorCount = 0;
|
||||
let cursorCount = 0;
|
||||
let inMirrorMode = false;
|
||||
|
||||
function onDidChangeTextEditorSelection(event: TextEditorSelectionChangeEvent) {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
prevCursorCount = cursorCount;
|
||||
cursorCount = event.selections.length;
|
||||
|
||||
if (cursorCount === 1) {
|
||||
if (inMirrorMode && prevCursorCount === 2) {
|
||||
return;
|
||||
}
|
||||
if (event.selections[0].isEmpty) {
|
||||
matchingTagPositionProvider(event.textEditor.document, event.selections[0].active).then(position => {
|
||||
if (position && window.activeTextEditor) {
|
||||
inMirrorMode = true;
|
||||
const newCursor = new Selection(position.line, position.character, position.line, position.character);
|
||||
window.activeTextEditor.selections = [...window.activeTextEditor.selections, newCursor];
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
if (cursorCount === 2 && inMirrorMode) {
|
||||
// Check two cases
|
||||
if (event.selections[0].isEmpty && event.selections[1].isEmpty) {
|
||||
const charBeforePrimarySelection = getCharBefore(event.textEditor.document, event.selections[0].anchor);
|
||||
const charAfterPrimarySelection = getCharAfter(event.textEditor.document, event.selections[0].anchor);
|
||||
const charBeforeSecondarySelection = getCharBefore(event.textEditor.document, event.selections[1].anchor);
|
||||
const charAfterSecondarySelection = getCharAfter(event.textEditor.document, event.selections[1].anchor);
|
||||
|
||||
// Exit mirror mode when cursor position no longer mirror
|
||||
// Unless it's in the case of `<|></|>`
|
||||
const charBeforeBothPositionRoughlyEqual =
|
||||
charBeforePrimarySelection === charBeforeSecondarySelection ||
|
||||
(charBeforePrimarySelection === '/' && charBeforeSecondarySelection === '<') ||
|
||||
(charBeforeSecondarySelection === '/' && charBeforePrimarySelection === '<');
|
||||
const charAfterBothPositionRoughlyEqual =
|
||||
charAfterPrimarySelection === charAfterSecondarySelection ||
|
||||
(charAfterPrimarySelection === ' ' && charAfterSecondarySelection === '>') ||
|
||||
(charAfterSecondarySelection === ' ' && charAfterPrimarySelection === '>');
|
||||
|
||||
if (!charBeforeBothPositionRoughlyEqual || !charAfterBothPositionRoughlyEqual) {
|
||||
inMirrorMode = false;
|
||||
window.activeTextEditor!.selections = [window.activeTextEditor!.selections[0]];
|
||||
return;
|
||||
} else {
|
||||
// Need to cleanup in the case of <div |></div |>
|
||||
if (
|
||||
charBeforePrimarySelection === ' ' &&
|
||||
charAfterPrimarySelection === '>' &&
|
||||
charBeforeSecondarySelection === ' ' &&
|
||||
charAfterSecondarySelection === '>'
|
||||
) {
|
||||
const primaryBeforeSecondary =
|
||||
event.textEditor.document.offsetAt(event.selections[0].anchor) <
|
||||
event.textEditor.document.offsetAt(event.selections[1].anchor);
|
||||
|
||||
if (primaryBeforeSecondary) {
|
||||
inMirrorMode = false;
|
||||
const cleanupEdit = new WorkspaceEdit();
|
||||
const cleanupRange = new Range(event.selections[1].anchor.translate(0, -1), event.selections[1].anchor);
|
||||
cleanupEdit.replace(event.textEditor.document.uri, cleanupRange, '');
|
||||
window.activeTextEditor!.selections = [window.activeTextEditor!.selections[0]];
|
||||
workspace.applyEdit(cleanupEdit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Disposable.from(...disposables);
|
||||
}
|
||||
|
||||
function getCharBefore(document: TextDocument, position: Position) {
|
||||
const offset = document.offsetAt(position);
|
||||
if (offset === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return document.getText(new Range(document.positionAt(offset - 1), position));
|
||||
}
|
||||
|
||||
function getCharAfter(document: TextDocument, position: Position) {
|
||||
const offset = document.offsetAt(position);
|
||||
if (offset === document.getText().length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return document.getText(new Range(position, document.positionAt(offset + 1)));
|
||||
}
|
||||
@@ -0,0 +1,233 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Microsoft Corporation. All rights reserved.
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import {
|
||||
window,
|
||||
workspace,
|
||||
Disposable,
|
||||
TextDocument,
|
||||
Position,
|
||||
TextEditorSelectionChangeEvent,
|
||||
Selection,
|
||||
Range,
|
||||
WorkspaceEdit
|
||||
} from 'vscode';
|
||||
|
||||
export function activateMirrorCursor(
|
||||
matchingTagPositionProvider: (document: TextDocument, position: Position) => Thenable<Position | null>,
|
||||
supportedLanguages: { [id: string]: boolean },
|
||||
configName: string
|
||||
): Disposable {
|
||||
let disposables: Disposable[] = [];
|
||||
|
||||
window.onDidChangeTextEditorSelection(event => onDidChangeTextEditorSelection(event), null, disposables);
|
||||
|
||||
let isEnabled = false;
|
||||
updateEnabledState();
|
||||
|
||||
window.onDidChangeActiveTextEditor(updateEnabledState, null, disposables);
|
||||
|
||||
function updateEnabledState() {
|
||||
isEnabled = false;
|
||||
let editor = window.activeTextEditor;
|
||||
if (!editor) {
|
||||
return;
|
||||
}
|
||||
let document = editor.document;
|
||||
if (!supportedLanguages[document.languageId]) {
|
||||
return;
|
||||
}
|
||||
if (!workspace.getConfiguration(undefined, document.uri).get<boolean>(configName)) {
|
||||
return;
|
||||
}
|
||||
isEnabled = true;
|
||||
}
|
||||
|
||||
let prevCursors: readonly Selection[] = [];
|
||||
let cursors: readonly Selection[] = [];
|
||||
let inMirrorMode = false;
|
||||
|
||||
function onDidChangeTextEditorSelection(event: TextEditorSelectionChangeEvent) {
|
||||
if (!isEnabled) {
|
||||
return;
|
||||
}
|
||||
|
||||
prevCursors = cursors;
|
||||
cursors = event.selections;
|
||||
|
||||
if (cursors.length === 1) {
|
||||
if (inMirrorMode && prevCursors.length === 2) {
|
||||
if (cursors[0].isEqual(prevCursors[0]) || cursors[0].isEqual(prevCursors[1])) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
if (event.selections[0].isEmpty) {
|
||||
matchingTagPositionProvider(event.textEditor.document, event.selections[0].active).then(matchingTagPosition => {
|
||||
if (matchingTagPosition && window.activeTextEditor) {
|
||||
const charBeforeAndAfterPositionsRoughtlyEqual = isCharBeforeAndAfterPositionsRoughtlyEqual(
|
||||
event.textEditor.document,
|
||||
event.selections[0].anchor,
|
||||
new Position(matchingTagPosition.line, matchingTagPosition.character)
|
||||
);
|
||||
|
||||
if (charBeforeAndAfterPositionsRoughtlyEqual) {
|
||||
inMirrorMode = true;
|
||||
const newCursor = new Selection(
|
||||
matchingTagPosition.line,
|
||||
matchingTagPosition.character,
|
||||
matchingTagPosition.line,
|
||||
matchingTagPosition.character
|
||||
);
|
||||
window.activeTextEditor.selections = [...window.activeTextEditor.selections, newCursor];
|
||||
}
|
||||
}
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
const exitMirrorMode = () => {
|
||||
inMirrorMode = false;
|
||||
window.activeTextEditor!.selections = [window.activeTextEditor!.selections[0]];
|
||||
};
|
||||
|
||||
if (cursors.length === 2 && inMirrorMode) {
|
||||
if (event.selections[0].isEmpty && event.selections[1].isEmpty) {
|
||||
if (
|
||||
prevCursors.length === 2 &&
|
||||
event.selections[0].anchor.line !== prevCursors[0].anchor.line &&
|
||||
event.selections[1].anchor.line !== prevCursors[0].anchor.line
|
||||
) {
|
||||
exitMirrorMode();
|
||||
return;
|
||||
}
|
||||
|
||||
const charBeforeAndAfterPositionsRoughtlyEqual = isCharBeforeAndAfterPositionsRoughtlyEqual(
|
||||
event.textEditor.document,
|
||||
event.selections[0].anchor,
|
||||
event.selections[1].anchor
|
||||
);
|
||||
|
||||
if (!charBeforeAndAfterPositionsRoughtlyEqual) {
|
||||
exitMirrorMode();
|
||||
return;
|
||||
} else {
|
||||
// Need to cleanup in the case of <div |></div |>
|
||||
if (
|
||||
shouldDoCleanupForHtmlAttributeInput(
|
||||
event.textEditor.document,
|
||||
event.selections[0].anchor,
|
||||
event.selections[1].anchor
|
||||
)
|
||||
) {
|
||||
const cleanupEdit = new WorkspaceEdit();
|
||||
const cleanupRange = new Range(event.selections[1].anchor.translate(0, -1), event.selections[1].anchor);
|
||||
cleanupEdit.replace(event.textEditor.document.uri, cleanupRange, '');
|
||||
exitMirrorMode();
|
||||
workspace.applyEdit(cleanupEdit);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return Disposable.from(...disposables);
|
||||
}
|
||||
|
||||
function getCharBefore(document: TextDocument, position: Position) {
|
||||
const offset = document.offsetAt(position);
|
||||
if (offset === 0) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return document.getText(new Range(document.positionAt(offset - 1), position));
|
||||
}
|
||||
|
||||
function getCharAfter(document: TextDocument, position: Position) {
|
||||
const offset = document.offsetAt(position);
|
||||
if (offset === document.getText().length) {
|
||||
return '';
|
||||
}
|
||||
|
||||
return document.getText(new Range(position, document.positionAt(offset + 1)));
|
||||
}
|
||||
|
||||
// Check if chars before and after the two positions are equal
|
||||
// For the chars before, `<` and `/` are consiered equal to handle the case of `<|></|>`
|
||||
function isCharBeforeAndAfterPositionsRoughtlyEqual(document: TextDocument, firstPos: Position, secondPos: Position) {
|
||||
const charBeforePrimarySelection = getCharBefore(document, firstPos);
|
||||
const charAfterPrimarySelection = getCharAfter(document, firstPos);
|
||||
const charBeforeSecondarySelection = getCharBefore(document, secondPos);
|
||||
const charAfterSecondarySelection = getCharAfter(document, secondPos);
|
||||
|
||||
/**
|
||||
* Special case for exiting
|
||||
* |<div>
|
||||
* |</div>
|
||||
*/
|
||||
if (
|
||||
charBeforePrimarySelection === ' ' &&
|
||||
charBeforeSecondarySelection === ' ' &&
|
||||
charAfterPrimarySelection === '<' &&
|
||||
charAfterSecondarySelection === '<'
|
||||
) {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Special case for exiting
|
||||
* | <div>
|
||||
* | </div>
|
||||
*/
|
||||
if (charBeforePrimarySelection === '\n' && charBeforeSecondarySelection === '\n') {
|
||||
return false;
|
||||
}
|
||||
/**
|
||||
* Special case for exiting
|
||||
* <div>|
|
||||
* </div>|
|
||||
*/
|
||||
if (charAfterPrimarySelection === '\n' && charAfterSecondarySelection === '\n') {
|
||||
return false;
|
||||
}
|
||||
|
||||
// Exit mirror mode when cursor position no longer mirror
|
||||
// Unless it's in the case of `<|></|>`
|
||||
const charBeforeBothPositionRoughlyEqual =
|
||||
charBeforePrimarySelection === charBeforeSecondarySelection ||
|
||||
(charBeforePrimarySelection === '/' && charBeforeSecondarySelection === '<') ||
|
||||
(charBeforeSecondarySelection === '/' && charBeforePrimarySelection === '<');
|
||||
const charAfterBothPositionRoughlyEqual =
|
||||
charAfterPrimarySelection === charAfterSecondarySelection ||
|
||||
(charAfterPrimarySelection === ' ' && charAfterSecondarySelection === '>') ||
|
||||
(charAfterSecondarySelection === ' ' && charAfterPrimarySelection === '>');
|
||||
|
||||
return charBeforeBothPositionRoughlyEqual && charAfterBothPositionRoughlyEqual;
|
||||
}
|
||||
|
||||
function shouldDoCleanupForHtmlAttributeInput(document: TextDocument, firstPos: Position, secondPos: Position) {
|
||||
// Need to cleanup in the case of <div |></div |>
|
||||
const charBeforePrimarySelection = getCharBefore(document, firstPos);
|
||||
const charAfterPrimarySelection = getCharAfter(document, firstPos);
|
||||
const charBeforeSecondarySelection = getCharBefore(document, secondPos);
|
||||
const charAfterSecondarySelection = getCharAfter(document, secondPos);
|
||||
|
||||
const primaryBeforeSecondary = document.offsetAt(firstPos) < document.offsetAt(secondPos);
|
||||
|
||||
/**
|
||||
* Check two cases
|
||||
* <div |></div >
|
||||
* <div | id="a"></div >
|
||||
* Before 1st cursor: ` `
|
||||
* After 1st cursor: `>` or ` `
|
||||
* Before 2nd cursor: ` `
|
||||
* After 2nd cursor: `>`
|
||||
*/
|
||||
return (
|
||||
primaryBeforeSecondary &&
|
||||
charBeforePrimarySelection === ' ' &&
|
||||
(charAfterPrimarySelection === '>' || charAfterPrimarySelection === ' ') &&
|
||||
charBeforeSecondarySelection === ' ' &&
|
||||
charAfterSecondarySelection === '>'
|
||||
);
|
||||
}
|
||||
@@ -161,11 +161,11 @@
|
||||
"default": true,
|
||||
"description": "%html.autoClosingTags%"
|
||||
},
|
||||
"html.autoSelectingMatchingTags": {
|
||||
"html.mirrorCursorOnMatchingTag": {
|
||||
"type": "boolean",
|
||||
"scope": "resource",
|
||||
"default": true,
|
||||
"description": "%html.autoSelectingMatchingTags%"
|
||||
"description": "%html.mirrorCursorOnMatchingTag%"
|
||||
},
|
||||
"html.trace.server": {
|
||||
"type": "string",
|
||||
@@ -180,6 +180,14 @@
|
||||
}
|
||||
}
|
||||
},
|
||||
"configurationDefaults": {
|
||||
"[html]": {
|
||||
"editor.suggest.insertMode": "replace"
|
||||
},
|
||||
"[handlebars]": {
|
||||
"editor.suggest.insertMode": "replace"
|
||||
}
|
||||
},
|
||||
"jsonValidation": [
|
||||
{
|
||||
"fileMatch": "*.html-data.json",
|
||||
|
||||
@@ -25,5 +25,5 @@
|
||||
"html.validate.scripts": "Controls whether the built-in HTML language support validates embedded scripts.",
|
||||
"html.validate.styles": "Controls whether the built-in HTML language support validates embedded styles.",
|
||||
"html.autoClosingTags": "Enable/disable autoclosing of HTML tags.",
|
||||
"html.autoSelectingMatchingTags": "Enable/disable auto selecting matching HTML tags."
|
||||
"html.mirrorCursorOnMatchingTag": "Enable/disable mirroring cursor on matching HTML tag."
|
||||
}
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "HTML contributions to package.json",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
|
||||
@@ -9,7 +9,7 @@
|
||||
},
|
||||
"main": "./out/htmlServerMain",
|
||||
"dependencies": {
|
||||
"vscode-css-languageservice": "^4.0.3-next.22",
|
||||
"vscode-css-languageservice": "^4.0.3-next.24",
|
||||
"vscode-html-languageservice": "^3.0.4-next.11",
|
||||
"vscode-languageserver": "^6.0.0-next.3",
|
||||
"vscode-nls": "^4.1.1",
|
||||
|
||||
@@ -611,10 +611,10 @@ supports-color@^5.3.0:
|
||||
dependencies:
|
||||
has-flag "^3.0.0"
|
||||
|
||||
vscode-css-languageservice@^4.0.3-next.22:
|
||||
version "4.0.3-next.22"
|
||||
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.3-next.22.tgz#ddb23a7086807f0e098f069ad91a8e3b7a696cbb"
|
||||
integrity sha512-j7+S/0LPn/pTe/CQ8WscDttW5J3aY5Ls6bo/Cz8ZdlBjHl7DbrbZ2rEl5Qd6aKbg0ZdgjWVxGqjjgZFzh+O9/w==
|
||||
vscode-css-languageservice@^4.0.3-next.24:
|
||||
version "4.0.3-next.24"
|
||||
resolved "https://registry.yarnpkg.com/vscode-css-languageservice/-/vscode-css-languageservice-4.0.3-next.24.tgz#6190fb5af4621b7efc1a0772c1a178d996ffb42d"
|
||||
integrity sha512-7CPBmaQnvkgL7MXZK9vt5R5CwFaQ9TCqWt9aCi9dGm1g0uAgFOwk8+K5+fV2pasI+aoOvb/kLcFjxSSRD03KdA==
|
||||
dependencies:
|
||||
vscode-languageserver-textdocument "^1.0.0-next.4"
|
||||
vscode-languageserver-types "^3.15.0-next.6"
|
||||
|
||||
@@ -13,5 +13,4 @@ Supported image formats:
|
||||
- `*.bmp`
|
||||
- `*.gif`
|
||||
- `*.ico`
|
||||
- `*.tga`
|
||||
- `*.webp`
|
||||
@@ -2,7 +2,7 @@
|
||||
"name": "image-preview",
|
||||
"displayName": "%displayName%",
|
||||
"description": "%description%",
|
||||
"extensionKind": "ui",
|
||||
"extensionKind": ["ui", "workspace"],
|
||||
"version": "1.0.0",
|
||||
"publisher": "vscode",
|
||||
"icon": "icon.png",
|
||||
|
||||
@@ -10,8 +10,16 @@ import { xhr, XHRResponse, getErrorStatusDescription } from 'request-light';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
import { workspace, window, languages, commands, ExtensionContext, extensions, Uri, LanguageConfiguration, Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken, ProviderResult, TextEdit, Range, Disposable } from 'vscode';
|
||||
import { LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType, DidChangeConfigurationNotification, HandleDiagnosticsSignature, ResponseError, DocumentRangeFormattingParams, DocumentRangeFormattingRequest } from 'vscode-languageclient';
|
||||
import {
|
||||
workspace, window, languages, commands, ExtensionContext, extensions, Uri, LanguageConfiguration,
|
||||
Diagnostic, StatusBarAlignment, TextEditor, TextDocument, FormattingOptions, CancellationToken,
|
||||
ProviderResult, TextEdit, Range, Position, Disposable, CompletionItem, CompletionList, CompletionContext
|
||||
} from 'vscode';
|
||||
import {
|
||||
LanguageClient, LanguageClientOptions, RequestType, ServerOptions, TransportKind, NotificationType,
|
||||
DidChangeConfigurationNotification, HandleDiagnosticsSignature, ResponseError, DocumentRangeFormattingParams,
|
||||
DocumentRangeFormattingRequest, ProvideCompletionItemsSignature
|
||||
} from 'vscode-languageclient';
|
||||
import TelemetryReporter from 'vscode-extension-telemetry';
|
||||
|
||||
import { hash } from './utils/hash';
|
||||
@@ -36,6 +44,10 @@ namespace SchemaAssociationNotification {
|
||||
export const type: NotificationType<ISchemaAssociations, any> = new NotificationType('json/schemaAssociations');
|
||||
}
|
||||
|
||||
namespace ResultLimitReachedNotification {
|
||||
export const type: NotificationType<string, any> = new NotificationType('json/resultLimitReached');
|
||||
}
|
||||
|
||||
interface IPackageInfo {
|
||||
name: string;
|
||||
version: string;
|
||||
@@ -132,6 +144,29 @@ export function activate(context: ExtensionContext) {
|
||||
}
|
||||
|
||||
next(uri, diagnostics);
|
||||
},
|
||||
// testing the replace / insert mode
|
||||
provideCompletionItem(document: TextDocument, position: Position, context: CompletionContext, token: CancellationToken, next: ProvideCompletionItemsSignature): ProviderResult<CompletionItem[] | CompletionList> {
|
||||
function updateRanges(item: CompletionItem) {
|
||||
const range = item.range;
|
||||
if (range && range.end.isAfter(position) && range.start.isBeforeOrEqual(position)) {
|
||||
item.range2 = { inserting: new Range(range.start, position), replacing: range };
|
||||
item.range = undefined;
|
||||
}
|
||||
}
|
||||
function updateProposals(r: CompletionItem[] | CompletionList | null | undefined): CompletionItem[] | CompletionList | null | undefined {
|
||||
if (r) {
|
||||
(Array.isArray(r) ? r : r.items).forEach(updateRanges);
|
||||
}
|
||||
return r;
|
||||
}
|
||||
const isThenable = <T>(obj: ProviderResult<T>): obj is Thenable<T> => obj && (<any>obj)['then'];
|
||||
|
||||
const r = next(document, position, context, token);
|
||||
if (isThenable<CompletionItem[] | CompletionList | null | undefined>(r)) {
|
||||
return r.then(updateProposals);
|
||||
}
|
||||
return updateProposals(r);
|
||||
}
|
||||
}
|
||||
};
|
||||
@@ -239,6 +274,12 @@ export function activate(context: ExtensionContext) {
|
||||
updateFormatterRegistration();
|
||||
toDispose.push({ dispose: () => rangeFormatting && rangeFormatting.dispose() });
|
||||
toDispose.push(workspace.onDidChangeConfiguration(e => e.affectsConfiguration('html.format.enable') && updateFormatterRegistration()));
|
||||
|
||||
|
||||
client.onNotification(ResultLimitReachedNotification.type, message => {
|
||||
window.showInformationMessage(`${message}\nUse setting 'json.maxItemsComputed' to configure the limit.`);
|
||||
});
|
||||
|
||||
});
|
||||
|
||||
let languageConfiguration: LanguageConfiguration = {
|
||||
@@ -320,6 +361,8 @@ function getSchemaAssociation(_context: ExtensionContext): ISchemaAssociations {
|
||||
function getSettings(): Settings {
|
||||
let httpSettings = workspace.getConfiguration('http');
|
||||
|
||||
let resultLimit: number = Math.trunc(Math.max(0, Number(workspace.getConfiguration().get('json.maxItemsComputed')))) || 5000;
|
||||
|
||||
let settings: Settings = {
|
||||
http: {
|
||||
proxy: httpSettings.get('proxy'),
|
||||
@@ -327,7 +370,7 @@ function getSettings(): Settings {
|
||||
},
|
||||
json: {
|
||||
schemas: [],
|
||||
resultLimit: 5000
|
||||
resultLimit
|
||||
}
|
||||
};
|
||||
let schemaSettingsById: { [schemaId: string]: JSONSchemaSettings } = Object.create(null);
|
||||
@@ -422,5 +465,4 @@ function readJSONFile(location: string) {
|
||||
console.log(`Problems reading ${location}: ${e}`);
|
||||
return {};
|
||||
}
|
||||
|
||||
}
|
||||
@@ -1,113 +1,125 @@
|
||||
{
|
||||
"name": "json-language-features",
|
||||
"displayName": "%displayName%",
|
||||
"description": "%description%",
|
||||
"version": "1.0.0",
|
||||
"publisher": "vscode",
|
||||
"license": "MIT",
|
||||
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
|
||||
"engines": {
|
||||
"vscode": "0.10.x"
|
||||
},
|
||||
"icon": "icons/json.png",
|
||||
"activationEvents": [
|
||||
"onLanguage:json",
|
||||
"onLanguage:jsonc"
|
||||
],
|
||||
"main": "./client/out/jsonMain",
|
||||
"enableProposedApi": true,
|
||||
"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": [
|
||||
"Programming Languages"
|
||||
],
|
||||
"contributes": {
|
||||
"configuration": {
|
||||
"id": "json",
|
||||
"order": 20,
|
||||
"type": "object",
|
||||
"title": "JSON",
|
||||
"properties": {
|
||||
"json.schemas": {
|
||||
"type": "array",
|
||||
"scope": "resource",
|
||||
"description": "%json.schemas.desc%",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"default": {
|
||||
"fileMatch": [
|
||||
"/myfile"
|
||||
],
|
||||
"url": "schemaURL"
|
||||
},
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string",
|
||||
"default": "/user.schema.json",
|
||||
"description": "%json.schemas.url.desc%"
|
||||
},
|
||||
"fileMatch": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": "MyFile.json",
|
||||
"description": "%json.schemas.fileMatch.item.desc%"
|
||||
},
|
||||
"minItems": 1,
|
||||
"description": "%json.schemas.fileMatch.desc%"
|
||||
},
|
||||
"schema": {
|
||||
"$ref": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "%json.schemas.schema.desc%"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"json.format.enable": {
|
||||
"type": "boolean",
|
||||
"scope": "window",
|
||||
"default": true,
|
||||
"description": "%json.format.enable.desc%"
|
||||
},
|
||||
"json.trace.server": {
|
||||
"type": "string",
|
||||
"scope": "window",
|
||||
"enum": [
|
||||
"off",
|
||||
"messages",
|
||||
"verbose"
|
||||
],
|
||||
"default": "off",
|
||||
"description": "%json.tracing.desc%"
|
||||
},
|
||||
"json.colorDecorators.enable": {
|
||||
"type": "boolean",
|
||||
"scope": "window",
|
||||
"default": true,
|
||||
"description": "%json.colorDecorators.enable.desc%",
|
||||
"deprecationMessage": "%json.colorDecorators.enable.deprecationMessage%"
|
||||
}
|
||||
}
|
||||
"name": "json-language-features",
|
||||
"displayName": "%displayName%",
|
||||
"description": "%description%",
|
||||
"version": "1.0.0",
|
||||
"publisher": "vscode",
|
||||
"license": "MIT",
|
||||
"aiKey": "AIF-d9b70cd4-b9f9-4d70-929b-a071c400b217",
|
||||
"engines": {
|
||||
"vscode": "0.10.x"
|
||||
},
|
||||
"configurationDefaults": {
|
||||
"[json]": {
|
||||
"editor.quickSuggestions": {
|
||||
"strings": true
|
||||
"icon": "icons/json.png",
|
||||
"activationEvents": [
|
||||
"onLanguage:json",
|
||||
"onLanguage:jsonc"
|
||||
],
|
||||
"main": "./client/out/jsonMain",
|
||||
"enableProposedApi": true,
|
||||
"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": [
|
||||
"Programming Languages"
|
||||
],
|
||||
"contributes": {
|
||||
"configuration": {
|
||||
"id": "json",
|
||||
"order": 20,
|
||||
"type": "object",
|
||||
"title": "JSON",
|
||||
"properties": {
|
||||
"json.schemas": {
|
||||
"type": "array",
|
||||
"scope": "resource",
|
||||
"description": "%json.schemas.desc%",
|
||||
"items": {
|
||||
"type": "object",
|
||||
"default": {
|
||||
"fileMatch": [
|
||||
"/myfile"
|
||||
],
|
||||
"url": "schemaURL"
|
||||
},
|
||||
"properties": {
|
||||
"url": {
|
||||
"type": "string",
|
||||
"default": "/user.schema.json",
|
||||
"description": "%json.schemas.url.desc%"
|
||||
},
|
||||
"fileMatch": {
|
||||
"type": "array",
|
||||
"items": {
|
||||
"type": "string",
|
||||
"default": "MyFile.json",
|
||||
"description": "%json.schemas.fileMatch.item.desc%"
|
||||
},
|
||||
"minItems": 1,
|
||||
"description": "%json.schemas.fileMatch.desc%"
|
||||
},
|
||||
"schema": {
|
||||
"$ref": "http://json-schema.org/draft-07/schema#",
|
||||
"description": "%json.schemas.schema.desc%"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"json.format.enable": {
|
||||
"type": "boolean",
|
||||
"scope": "window",
|
||||
"default": true,
|
||||
"description": "%json.format.enable.desc%"
|
||||
},
|
||||
"json.trace.server": {
|
||||
"type": "string",
|
||||
"scope": "window",
|
||||
"enum": [
|
||||
"off",
|
||||
"messages",
|
||||
"verbose"
|
||||
],
|
||||
"default": "off",
|
||||
"description": "%json.tracing.desc%"
|
||||
},
|
||||
"json.colorDecorators.enable": {
|
||||
"type": "boolean",
|
||||
"scope": "window",
|
||||
"default": true,
|
||||
"description": "%json.colorDecorators.enable.desc%",
|
||||
"deprecationMessage": "%json.colorDecorators.enable.deprecationMessage%"
|
||||
},
|
||||
"json.maxItemsComputed": {
|
||||
"type": "number",
|
||||
"default": 5000,
|
||||
"description": "%json.maxItemsComputed.desc%"
|
||||
}
|
||||
}
|
||||
},
|
||||
"configurationDefaults": {
|
||||
"[json]": {
|
||||
"editor.quickSuggestions": {
|
||||
"strings": true
|
||||
},
|
||||
"editor.suggest.insertMode": "replace"
|
||||
},
|
||||
"[jsonc]": {
|
||||
"editor.quickSuggestions": {
|
||||
"strings": true
|
||||
},
|
||||
"editor.suggest.insertMode": "replace"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"request-light": "^0.2.5",
|
||||
"vscode-extension-telemetry": "0.1.1",
|
||||
"vscode-languageclient": "^6.0.0-next.3",
|
||||
"vscode-nls": "^4.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.11.7"
|
||||
}
|
||||
},
|
||||
"dependencies": {
|
||||
"request-light": "^0.2.5",
|
||||
"vscode-extension-telemetry": "0.1.1",
|
||||
"vscode-languageclient": "^6.0.0-next.3",
|
||||
"vscode-nls": "^4.1.1"
|
||||
},
|
||||
"devDependencies": {
|
||||
"@types/node": "^12.11.7"
|
||||
}
|
||||
}
|
||||
@@ -11,5 +11,6 @@
|
||||
"json.colorDecorators.enable.desc": "Enables or disables color decorators",
|
||||
"json.colorDecorators.enable.deprecationMessage": "The setting `json.colorDecorators.enable` has been deprecated in favor of `editor.colorDecorators`.",
|
||||
"json.schemaResolutionErrorMessage": "Unable to resolve schema.",
|
||||
"json.clickToRetry": "Click to retry."
|
||||
"json.clickToRetry": "Click to retry.",
|
||||
"json.maxItemsComputed.desc": "The maximum number of outline symbols and folding regions computed (limited for performance reasons)."
|
||||
}
|
||||
@@ -63,6 +63,7 @@ The server supports the following settings:
|
||||
- `fileMatch`: an array of file names or paths (separated by `/`). `*` can be used as a wildcard.
|
||||
- `url`: The URL of the schema, optional when also a schema is provided.
|
||||
- `schema`: The schema content.
|
||||
- `resultLimit`: The max number foldig ranges and otline symbols to be computed (for performance reasons)
|
||||
|
||||
```json
|
||||
{
|
||||
@@ -153,6 +154,16 @@ Notification:
|
||||
- method: 'json/schemaContent'
|
||||
- params: `string` the URL of the schema that has changed.
|
||||
|
||||
### Item Limit
|
||||
|
||||
If the setting `resultLimit` is set, the JSON language server will limit the number of folding ranges and document symbols computed.
|
||||
When the limit is reached, a notification `json/resultLimitReached` is sent that can be shown that camn be shown to the user.
|
||||
|
||||
Notification:
|
||||
- method: 'json/resultLimitReached'
|
||||
- params: a human readable string to show to the user.
|
||||
|
||||
|
||||
## Try
|
||||
|
||||
The JSON language server is shipped with [Visual Studio Code](https://code.visualstudio.com/) as part of the built-in VSCode extension `json-language-features`. The server is started when the first JSON file is opened. The [VSCode JSON documentation](https://code.visualstudio.com/docs/languages/json) for detailed information on the user experience and has more information on how to configure the language support.
|
||||
|
||||
@@ -14,7 +14,7 @@
|
||||
"dependencies": {
|
||||
"jsonc-parser": "^2.2.0",
|
||||
"request-light": "^0.2.5",
|
||||
"vscode-json-languageservice": "^3.4.7",
|
||||
"vscode-json-languageservice": "^3.4.9",
|
||||
"vscode-languageserver": "^6.0.0-next.3",
|
||||
"vscode-uri": "^2.1.1"
|
||||
},
|
||||
|
||||
@@ -35,6 +35,10 @@ namespace SchemaContentChangeNotification {
|
||||
export const type: NotificationType<string, any> = new NotificationType('json/schemaContent');
|
||||
}
|
||||
|
||||
namespace ResultLimitReachedNotification {
|
||||
export const type: NotificationType<string, any> = new NotificationType('json/resultLimitReached');
|
||||
}
|
||||
|
||||
namespace ForceValidateRequest {
|
||||
export const type: RequestType<string, Diagnostic[], any, any> = new RequestType('json/validate');
|
||||
}
|
||||
@@ -211,7 +215,7 @@ namespace LimitExceededWarnings {
|
||||
} else {
|
||||
warning = { features: { [name]: name } };
|
||||
warning.timeout = setTimeout(() => {
|
||||
connection.window.showInformationMessage(`${posix.basename(uri)}: For performance reasons, ${Object.keys(warning.features).join(' and ')} have been limited to ${resultLimit} items.`);
|
||||
connection.sendNotification(ResultLimitReachedNotification.type, `${posix.basename(uri)}: For performance reasons, ${Object.keys(warning.features).join(' and ')} have been limited to ${resultLimit} items.`);
|
||||
warning.timeout = undefined;
|
||||
}, 2000);
|
||||
pendingWarnings[uri] = warning;
|
||||
|
||||
@@ -80,10 +80,10 @@ request-light@^0.2.5:
|
||||
https-proxy-agent "^2.2.3"
|
||||
vscode-nls "^4.1.1"
|
||||
|
||||
vscode-json-languageservice@^3.4.7:
|
||||
version "3.4.7"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.7.tgz#8d85f3c1d46a1e58e9867d747552fb8c83d934fd"
|
||||
integrity sha512-y3MN2+/yph3yoIHGmHu4ScYpm285L58XVvfGkd49xTQzLja4apxSbwzsYcP9QsqS0W7KuvoyiPhqksiudoMwjg==
|
||||
vscode-json-languageservice@^3.4.9:
|
||||
version "3.4.9"
|
||||
resolved "https://registry.yarnpkg.com/vscode-json-languageservice/-/vscode-json-languageservice-3.4.9.tgz#7ce485bb0f9a07b4d879c988baac9be2222909ad"
|
||||
integrity sha512-4VCpZ9ooea/Zc/MTnj1ccc9C7rqcoinKVQLhLoi6jw6yueSf4y4tg/YIUiPPVMlEAG7ZCPS+NVmqxisQ+mOsSw==
|
||||
dependencies:
|
||||
jsonc-parser "^2.2.0"
|
||||
vscode-languageserver-textdocument "^1.0.0-next.4"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "Markdown contributions to package.json",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -29,4 +29,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -242,8 +242,11 @@ export class MarkdownEngine {
|
||||
if (uri.path[0] === '/') {
|
||||
const root = vscode.workspace.getWorkspaceFolder(this.currentDocument!);
|
||||
if (root) {
|
||||
uri = uri.with({
|
||||
path: path.join(root.uri.fsPath, uri.path),
|
||||
const fileUri = vscode.Uri.file(path.join(root.uri.fsPath, uri.fsPath));
|
||||
uri = fileUri.with({
|
||||
scheme: uri.scheme,
|
||||
fragment: uri.fragment,
|
||||
query: uri.query,
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
* Licensed under the MIT License. See License.txt in the project root for license information.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Location, getLocation, createScanner, SyntaxKind, ScanError } from 'jsonc-parser';
|
||||
import { Location, getLocation, createScanner, SyntaxKind, ScanError, JSONScanner } from 'jsonc-parser';
|
||||
import { basename } from 'path';
|
||||
import { BowerJSONContribution } from './bowerJSONContribution';
|
||||
import { PackageJSONContribution } from './packageJSONContribution';
|
||||
@@ -111,7 +111,7 @@ export class JSONCompletionItemProvider implements CompletionItemProvider {
|
||||
add: (suggestion: CompletionItem) => {
|
||||
if (!proposed[suggestion.label]) {
|
||||
proposed[suggestion.label] = true;
|
||||
suggestion.range = overwriteRange;
|
||||
suggestion.range2 = { replacing: overwriteRange, inserting: new Range(overwriteRange.start, overwriteRange.start) };
|
||||
items.push(suggestion);
|
||||
}
|
||||
},
|
||||
@@ -123,8 +123,9 @@ export class JSONCompletionItemProvider implements CompletionItemProvider {
|
||||
let collectPromise: Thenable<any> | null = null;
|
||||
|
||||
if (location.isAtPropertyKey) {
|
||||
const addValue = !location.previousNode || !location.previousNode.colonOffset;
|
||||
const isLast = this.isLast(document, position);
|
||||
const scanner = createScanner(document.getText(), true);
|
||||
const addValue = !location.previousNode || !this.hasColonAfter(scanner, location.previousNode.offset + location.previousNode.length);
|
||||
const isLast = this.isLast(scanner, document.offsetAt(position));
|
||||
collectPromise = this.jsonContribution.collectPropertySuggestions(fileName, location, currentWord, addValue, isLast, collector);
|
||||
} else {
|
||||
if (location.path.length === 0) {
|
||||
@@ -153,15 +154,19 @@ export class JSONCompletionItemProvider implements CompletionItemProvider {
|
||||
return text.substring(i + 1, position.character);
|
||||
}
|
||||
|
||||
private isLast(document: TextDocument, position: Position): boolean {
|
||||
const scanner = createScanner(document.getText(), true);
|
||||
scanner.setPosition(document.offsetAt(position));
|
||||
private isLast(scanner: JSONScanner, offset: number): boolean {
|
||||
scanner.setPosition(offset);
|
||||
let nextToken = scanner.scan();
|
||||
if (nextToken === SyntaxKind.StringLiteral && scanner.getTokenError() === ScanError.UnexpectedEndOfString) {
|
||||
nextToken = scanner.scan();
|
||||
}
|
||||
return nextToken === SyntaxKind.CloseBraceToken || nextToken === SyntaxKind.EOF;
|
||||
}
|
||||
private hasColonAfter(scanner: JSONScanner, offset: number): boolean {
|
||||
scanner.setPosition(offset);
|
||||
return scanner.scan() === SyntaxKind.ColonToken;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
export const xhrDisabled = () => Promise.reject({ responseText: 'Use of online resources is disabled.' });
|
||||
@@ -3,7 +3,7 @@
|
||||
"version": "0.0.1",
|
||||
"description": "Dependencies shared by all extensions",
|
||||
"dependencies": {
|
||||
"typescript": "3.7.3-insiders.20191123"
|
||||
"typescript": "3.7.3"
|
||||
},
|
||||
"scripts": {
|
||||
"postinstall": "node ./postinstall"
|
||||
|
||||
@@ -19,6 +19,11 @@
|
||||
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:search-result ./tsconfig.json"
|
||||
},
|
||||
"contributes": {
|
||||
"configurationDefaults": {
|
||||
"[search-result]": {
|
||||
"editor.lineNumbers": "off"
|
||||
}
|
||||
},
|
||||
"commands": [
|
||||
{
|
||||
"command": "searchResult.rerunSearch",
|
||||
@@ -28,6 +33,15 @@
|
||||
"light": "./src/media/refresh-light.svg",
|
||||
"dark": "./src/media/refresh-dark.svg"
|
||||
}
|
||||
},
|
||||
{
|
||||
"command": "searchResult.rerunSearchWithContext",
|
||||
"title": "%searchResult.rerunSearchWithContext.title%",
|
||||
"category": "Search Result",
|
||||
"icon": {
|
||||
"light": "./src/media/refresh-light.svg",
|
||||
"dark": "./src/media/refresh-dark.svg"
|
||||
}
|
||||
}
|
||||
],
|
||||
"menus": {
|
||||
@@ -35,6 +49,7 @@
|
||||
{
|
||||
"command": "searchResult.rerunSearch",
|
||||
"when": "editorLangId == search-result",
|
||||
"alt": "searchResult.rerunSearchWithContext",
|
||||
"group": "navigation"
|
||||
}
|
||||
]
|
||||
|
||||
@@ -1,5 +1,6 @@
|
||||
{
|
||||
"displayName": "Search Result",
|
||||
"description": "Provides syntax highlighting and language features for tabbed search results.",
|
||||
"searchResult.rerunSearch.title": "Search Again"
|
||||
"searchResult.rerunSearch.title": "Search Again",
|
||||
"searchResult.rerunSearchWithContext.title": "Search Again (With Context)"
|
||||
}
|
||||
@@ -7,81 +7,93 @@ import * as vscode from 'vscode';
|
||||
import * as pathUtils from 'path';
|
||||
|
||||
const FILE_LINE_REGEX = /^(\S.*):$/;
|
||||
const RESULT_LINE_REGEX = /^(\s+)(\d+):(\s+)(.*)$/;
|
||||
const RESULT_LINE_REGEX = /^(\s+)(\d+)(:| )(\s+)(.*)$/;
|
||||
const SEARCH_RESULT_SELECTOR = { language: 'search-result' };
|
||||
const DIRECTIVES = ['# Query:', '# Flags:', '# Including:', '# Excluding:', '# ContextLines:'];
|
||||
const FLAGS = ['RegExp', 'CaseSensitive', 'IgnoreExcludeSettings', 'WordMatch'];
|
||||
|
||||
let cachedLastParse: { version: number, parse: ParsedSearchResults } | undefined;
|
||||
|
||||
export function activate() {
|
||||
export function activate(context: vscode.ExtensionContext) {
|
||||
context.subscriptions.push(
|
||||
vscode.commands.registerCommand('searchResult.rerunSearch', () => vscode.commands.executeCommand('search.action.rerunEditorSearch')),
|
||||
vscode.commands.registerCommand('searchResult.rerunSearchWithContext', () => vscode.commands.executeCommand('search.action.rerunEditorSearchWithContext')),
|
||||
|
||||
vscode.commands.registerCommand('searchResult.rerunSearch', () => vscode.commands.executeCommand('search.action.rerunEditorSearch'));
|
||||
vscode.languages.registerDocumentSymbolProvider(SEARCH_RESULT_SELECTOR, {
|
||||
provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.DocumentSymbol[] {
|
||||
const results = parseSearchResults(document, token)
|
||||
.filter(isFileLine)
|
||||
.map(line => new vscode.DocumentSymbol(
|
||||
line.path,
|
||||
'',
|
||||
vscode.SymbolKind.File,
|
||||
line.allLocations.map(({ originSelectionRange }) => originSelectionRange!).reduce((p, c) => p.union(c), line.location.originSelectionRange!),
|
||||
line.location.originSelectionRange!,
|
||||
));
|
||||
|
||||
vscode.languages.registerDocumentSymbolProvider(SEARCH_RESULT_SELECTOR, {
|
||||
provideDocumentSymbols(document: vscode.TextDocument, token: vscode.CancellationToken): vscode.DocumentSymbol[] {
|
||||
const results = parseSearchResults(document, token)
|
||||
.filter(isFileLine)
|
||||
.map(line => new vscode.DocumentSymbol(
|
||||
line.path,
|
||||
'',
|
||||
vscode.SymbolKind.File,
|
||||
line.allLocations.map(({ originSelectionRange }) => originSelectionRange!).reduce((p, c) => p.union(c), line.location.originSelectionRange!),
|
||||
line.location.originSelectionRange!,
|
||||
));
|
||||
|
||||
return results;
|
||||
}
|
||||
});
|
||||
|
||||
vscode.languages.registerCompletionItemProvider(SEARCH_RESULT_SELECTOR, {
|
||||
provideCompletionItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
||||
|
||||
const line = document.lineAt(position.line);
|
||||
if (position.line > 3) { return []; }
|
||||
if (position.character === 0 || (position.character === 1 && line.text === '#')) {
|
||||
const header = Array.from({ length: 4 }).map((_, i) => document.lineAt(i).text);
|
||||
|
||||
return ['# Query:', '# Flags:', '# Including:', '# Excluding:']
|
||||
.filter(suggestion => header.every(line => line.indexOf(suggestion) === -1))
|
||||
.map(flag => ({ label: flag, insertText: (flag.slice(position.character)) + ' ' }));
|
||||
return results;
|
||||
}
|
||||
}),
|
||||
|
||||
if (line.text.indexOf('# Flags:') === -1) { return []; }
|
||||
vscode.languages.registerCompletionItemProvider(SEARCH_RESULT_SELECTOR, {
|
||||
provideCompletionItems(document: vscode.TextDocument, position: vscode.Position): vscode.CompletionItem[] {
|
||||
|
||||
return ['RegExp', 'CaseSensitive', 'IgnoreExcludeSettings', 'WordMatch']
|
||||
.filter(flag => line.text.indexOf(flag) === -1)
|
||||
.map(flag => ({ label: flag, insertText: flag + ' ' }));
|
||||
}
|
||||
}, '#');
|
||||
const line = document.lineAt(position.line);
|
||||
if (position.line > 3) { return []; }
|
||||
if (position.character === 0 || (position.character === 1 && line.text === '#')) {
|
||||
const header = Array.from({ length: DIRECTIVES.length }).map((_, i) => document.lineAt(i).text);
|
||||
|
||||
vscode.languages.registerDefinitionProvider(SEARCH_RESULT_SELECTOR, {
|
||||
provideDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.DefinitionLink[] {
|
||||
const lineResult = parseSearchResults(document, token)[position.line];
|
||||
if (!lineResult) { return []; }
|
||||
if (lineResult.type === 'file') {
|
||||
// TODO: The multi-match peek UX isnt very smooth.
|
||||
// return lineResult.allLocations.length > 1 ? lineResult.allLocations : [lineResult.location];
|
||||
return [];
|
||||
return DIRECTIVES
|
||||
.filter(suggestion => header.every(line => line.indexOf(suggestion) === -1))
|
||||
.map(flag => ({ label: flag, insertText: (flag.slice(position.character)) + ' ' }));
|
||||
}
|
||||
|
||||
if (line.text.indexOf('# Flags:') === -1) { return []; }
|
||||
|
||||
return FLAGS
|
||||
.filter(flag => line.text.indexOf(flag) === -1)
|
||||
.map(flag => ({ label: flag, insertText: flag + ' ' }));
|
||||
}
|
||||
}, '#'),
|
||||
|
||||
return [lineResult.location];
|
||||
}
|
||||
});
|
||||
vscode.languages.registerDefinitionProvider(SEARCH_RESULT_SELECTOR, {
|
||||
provideDefinition(document: vscode.TextDocument, position: vscode.Position, token: vscode.CancellationToken): vscode.DefinitionLink[] {
|
||||
const lineResult = parseSearchResults(document, token)[position.line];
|
||||
if (!lineResult) { return []; }
|
||||
if (lineResult.type === 'file') {
|
||||
// TODO: The multi-match peek UX isnt very smooth.
|
||||
// return lineResult.allLocations.length > 1 ? lineResult.allLocations : [lineResult.location];
|
||||
return [];
|
||||
}
|
||||
|
||||
vscode.languages.registerDocumentLinkProvider(SEARCH_RESULT_SELECTOR, {
|
||||
async provideDocumentLinks(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.DocumentLink[]> {
|
||||
return parseSearchResults(document, token)
|
||||
.filter(({ type }) => type === 'file')
|
||||
.map(({ location }) => ({ range: location.originSelectionRange!, target: location.targetUri }));
|
||||
}
|
||||
});
|
||||
const translateRangeSidewaysBy = (r: vscode.Range, n: number) =>
|
||||
r.with({ start: new vscode.Position(r.start.line, Math.max(0, n - r.start.character)), end: new vscode.Position(r.end.line, Math.max(0, n - r.end.character)) });
|
||||
|
||||
vscode.window.onDidChangeActiveTextEditor(e => {
|
||||
if (e?.document.languageId === 'search-result') {
|
||||
// Clear the parse whenever we open a new editor.
|
||||
// Conservative because things like the URI might remain constant even if the contents change, and re-parsing even large files is relatively fast.
|
||||
cachedLastParse = undefined;
|
||||
}
|
||||
});
|
||||
return [{
|
||||
...lineResult.location,
|
||||
targetSelectionRange: translateRangeSidewaysBy(lineResult.location.targetSelectionRange!, position.character - 1)
|
||||
}];
|
||||
}
|
||||
}),
|
||||
|
||||
vscode.languages.registerDocumentLinkProvider(SEARCH_RESULT_SELECTOR, {
|
||||
async provideDocumentLinks(document: vscode.TextDocument, token: vscode.CancellationToken): Promise<vscode.DocumentLink[]> {
|
||||
return parseSearchResults(document, token)
|
||||
.filter(({ type }) => type === 'file')
|
||||
.map(({ location }) => ({ range: location.originSelectionRange!, target: location.targetUri }));
|
||||
}
|
||||
}),
|
||||
|
||||
vscode.window.onDidChangeActiveTextEditor(e => {
|
||||
if (e?.document.languageId === 'search-result') {
|
||||
// Clear the parse whenever we open a new editor.
|
||||
// Conservative because things like the URI might remain constant even if the contents change, and re-parsing even large files is relatively fast.
|
||||
cachedLastParse = undefined;
|
||||
}
|
||||
}),
|
||||
|
||||
{ dispose() { cachedLastParse = undefined; } }
|
||||
);
|
||||
}
|
||||
|
||||
|
||||
@@ -160,13 +172,14 @@ function parseSearchResults(document: vscode.TextDocument, token: vscode.Cancell
|
||||
|
||||
const resultLine = RESULT_LINE_REGEX.exec(line);
|
||||
if (resultLine) {
|
||||
const [, indentation, _lineNumber, resultIndentation] = resultLine;
|
||||
const [, indentation, _lineNumber, seperator, resultIndentation] = resultLine;
|
||||
const lineNumber = +_lineNumber - 1;
|
||||
const resultStart = (indentation + _lineNumber + ':' + resultIndentation).length;
|
||||
const resultStart = (indentation + _lineNumber + seperator + resultIndentation).length;
|
||||
const metadataOffset = (indentation + _lineNumber + seperator).length;
|
||||
|
||||
const location: vscode.LocationLink = {
|
||||
targetRange: new vscode.Range(Math.max(lineNumber - 3, 0), 0, lineNumber + 3, line.length),
|
||||
targetSelectionRange: new vscode.Range(lineNumber, 0, lineNumber, line.length),
|
||||
targetSelectionRange: new vscode.Range(lineNumber, metadataOffset, lineNumber, metadataOffset),
|
||||
targetUri: currentTarget,
|
||||
originSelectionRange: new vscode.Range(i, resultStart, i, line.length),
|
||||
};
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
"scopeName": "text.searchResult",
|
||||
"patterns": [
|
||||
{
|
||||
"match": "^# (Query|Flags|Including|Excluding): .*$",
|
||||
"match": "^# (Query|Flags|Including|Excluding|ContextLines): .*$",
|
||||
"name": "comment"
|
||||
},
|
||||
{
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"entity.name.function",
|
||||
"support.function",
|
||||
"support.constant.handlebars",
|
||||
"source.powershell variable.other.member"
|
||||
"source.powershell variable.other.member",
|
||||
"entity.name.operator.custom-literal" // See https://en.cppreference.com/w/cpp/language/user_literal
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#DCDCAA"
|
||||
|
||||
@@ -171,7 +171,8 @@
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"meta.preprocessor"
|
||||
"meta.preprocessor",
|
||||
"entity.name.function.preprocessor"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#569cd6"
|
||||
@@ -226,6 +227,7 @@
|
||||
"scope": [
|
||||
"string",
|
||||
"entity.name.operator.custom-literal.string",
|
||||
"meta.embedded.assembly"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#ce9178"
|
||||
|
||||
@@ -9,7 +9,8 @@
|
||||
"entity.name.function",
|
||||
"support.function",
|
||||
"support.constant.handlebars",
|
||||
"source.powershell variable.other.member"
|
||||
"source.powershell variable.other.member",
|
||||
"entity.name.operator.custom-literal" // See https://en.cppreference.com/w/cpp/language/user_literal
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#795E26"
|
||||
|
||||
@@ -169,7 +169,8 @@
|
||||
},
|
||||
{
|
||||
"scope": [
|
||||
"meta.preprocessor"
|
||||
"meta.preprocessor",
|
||||
"entity.name.function.preprocessor"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#0000ff"
|
||||
@@ -218,6 +219,7 @@
|
||||
"scope": [
|
||||
"string",
|
||||
"entity.name.operator.custom-literal.string",
|
||||
"meta.embedded.assembly"
|
||||
],
|
||||
"settings": {
|
||||
"foreground": "#a31515"
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
{
|
||||
"$schema": "http://json-schema.org/draft-04/schema#",
|
||||
"$schema": "http://json-schema.org/draft-07/schema#",
|
||||
"title": "TypeScript contributions to package.json",
|
||||
"type": "object",
|
||||
"properties": {
|
||||
@@ -28,4 +28,4 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -60,7 +60,7 @@ export interface ITypeScriptServer {
|
||||
}
|
||||
|
||||
export interface TsServerDelegate {
|
||||
onFatalError(command: string): void;
|
||||
onFatalError(command: string, error: Error): void;
|
||||
}
|
||||
|
||||
export interface TsServerProcess {
|
||||
@@ -222,21 +222,13 @@ export class ProcessBasedTsServer extends Disposable implements ITypeScriptServe
|
||||
if (!executeInfo.token || !executeInfo.token.isCancellationRequested) {
|
||||
/* __GDPR__
|
||||
"languageServiceErrorResponse" : {
|
||||
"command" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"message" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
|
||||
"stack" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
|
||||
"errortext" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
|
||||
"${include}": [
|
||||
"${TypeScriptCommonProperties}"
|
||||
"${TypeScriptCommonProperties}",
|
||||
"${TypeScriptRequestErrorProperties}"
|
||||
]
|
||||
}
|
||||
*/
|
||||
this._telemetryReporter.logTelemetry('languageServiceErrorResponse', {
|
||||
command: err.serverCommand,
|
||||
message: err.serverMessage || '',
|
||||
stack: err.serverStack || '',
|
||||
errortext: err.serverErrorText || '',
|
||||
});
|
||||
this._telemetryReporter.logTelemetry('languageServiceErrorResponse', err.telemetry);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -367,9 +359,8 @@ export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServ
|
||||
} else if (SyntaxRoutingTsServer.sharedCommands.has(command)) {
|
||||
// Dispatch to both server but only return from syntax one
|
||||
|
||||
const enum RequestState { Unresolved, Resolved, Errored }
|
||||
let syntaxRequestState = RequestState.Unresolved;
|
||||
let semanticRequestState = RequestState.Unresolved;
|
||||
let syntaxRequestState: RequestState.State = RequestState.Unresolved;
|
||||
let semanticRequestState: RequestState.State = RequestState.Unresolved;
|
||||
|
||||
// Also make sure we never cancel requests to just one server
|
||||
let token: vscode.CancellationToken | undefined = undefined;
|
||||
@@ -394,16 +385,16 @@ export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServ
|
||||
semanticRequest
|
||||
.then(result => {
|
||||
semanticRequestState = RequestState.Resolved;
|
||||
if (syntaxRequestState === RequestState.Errored) {
|
||||
if (syntaxRequestState.type === RequestState.Type.Errored) {
|
||||
// We've gone out of sync
|
||||
this._delegate.onFatalError(command);
|
||||
this._delegate.onFatalError(command, syntaxRequestState.err);
|
||||
}
|
||||
return result;
|
||||
}, err => {
|
||||
semanticRequestState = RequestState.Errored;
|
||||
semanticRequestState = new RequestState.Errored(err);
|
||||
if (syntaxRequestState === RequestState.Resolved) {
|
||||
// We've gone out of sync
|
||||
this._delegate.onFatalError(command);
|
||||
this._delegate.onFatalError(command, err);
|
||||
}
|
||||
throw err;
|
||||
});
|
||||
@@ -413,16 +404,16 @@ export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServ
|
||||
syntaxRequest
|
||||
.then(result => {
|
||||
syntaxRequestState = RequestState.Resolved;
|
||||
if (semanticRequestState === RequestState.Errored) {
|
||||
if (semanticRequestState.type === RequestState.Type.Errored) {
|
||||
// We've gone out of sync
|
||||
this._delegate.onFatalError(command);
|
||||
this._delegate.onFatalError(command, semanticRequestState.err);
|
||||
}
|
||||
return result;
|
||||
}, err => {
|
||||
syntaxRequestState = RequestState.Errored;
|
||||
syntaxRequestState = new RequestState.Errored(err);
|
||||
if (semanticRequestState === RequestState.Resolved) {
|
||||
// We've gone out of sync
|
||||
this._delegate.onFatalError(command);
|
||||
this._delegate.onFatalError(command, err);
|
||||
}
|
||||
throw err;
|
||||
});
|
||||
@@ -433,3 +424,21 @@ export class SyntaxRoutingTsServer extends Disposable implements ITypeScriptServ
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
namespace RequestState {
|
||||
export const enum Type { Unresolved, Resolved, Errored }
|
||||
|
||||
export const Unresolved = { type: Type.Unresolved } as const;
|
||||
|
||||
export const Resolved = { type: Type.Resolved } as const;
|
||||
|
||||
export class Errored {
|
||||
readonly type = Type.Errored;
|
||||
|
||||
constructor(
|
||||
public readonly err: Error
|
||||
) { }
|
||||
}
|
||||
|
||||
export type State = typeof Unresolved | typeof Resolved | Errored;
|
||||
}
|
||||
@@ -7,6 +7,7 @@ import * as Proto from '../protocol';
|
||||
import { escapeRegExp } from '../utils/regexp';
|
||||
import { TypeScriptVersion } from '../utils/versionProvider';
|
||||
|
||||
|
||||
export class TypeScriptServerError extends Error {
|
||||
public static create(
|
||||
serverId: string,
|
||||
@@ -31,6 +32,23 @@ export class TypeScriptServerError extends Error {
|
||||
|
||||
public get serverCommand() { return this.response.command; }
|
||||
|
||||
public get telemetry() {
|
||||
/* __GDPR__FRAGMENT__
|
||||
"TypeScriptRequestErrorProperties" : {
|
||||
"command" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
|
||||
"message" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
|
||||
"stack" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" },
|
||||
"errortext" : { "classification": "CallstackOrException", "purpose": "PerformanceAndHealth" }
|
||||
}
|
||||
*/
|
||||
return {
|
||||
command: this.serverCommand,
|
||||
message: this.serverMessage || '',
|
||||
stack: this.serverStack || '',
|
||||
errortext: this.serverErrorText || '',
|
||||
} as const;
|
||||
}
|
||||
|
||||
/**
|
||||
* Given a `errorText` from a tsserver request indicating failure in handling a request,
|
||||
* prepares a payload for telemetry-logging.
|
||||
|
||||
@@ -11,7 +11,9 @@ import BufferSyncSupport from './features/bufferSyncSupport';
|
||||
import { DiagnosticKind, DiagnosticsManager } from './features/diagnostics';
|
||||
import * as Proto from './protocol';
|
||||
import { ITypeScriptServer } from './tsServer/server';
|
||||
import { ITypeScriptServiceClient, ServerResponse, TypeScriptRequests, ExecConfig } from './typescriptService';
|
||||
import { TypeScriptServerError } from './tsServer/serverError';
|
||||
import { TypeScriptServerSpawner } from './tsServer/spawner';
|
||||
import { ExecConfig, ITypeScriptServiceClient, ServerResponse, TypeScriptRequests } from './typescriptService';
|
||||
import API from './utils/api';
|
||||
import { TsServerLogLevel, TypeScriptServiceConfiguration } from './utils/configuration';
|
||||
import { Disposable } from './utils/dispose';
|
||||
@@ -25,7 +27,6 @@ import Tracer from './utils/tracer';
|
||||
import { inferredProjectConfig } from './utils/tsconfig';
|
||||
import { TypeScriptVersionPicker } from './utils/versionPicker';
|
||||
import { TypeScriptVersion, TypeScriptVersionProvider } from './utils/versionProvider';
|
||||
import { TypeScriptServerSpawner } from './tsServer/spawner';
|
||||
|
||||
const localize = nls.loadMessageBundle();
|
||||
|
||||
@@ -314,7 +315,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||
this.onDidChangeTypeScriptVersion(currentVersion);
|
||||
let mytoken = ++this.token;
|
||||
const handle = this.typescriptServerSpawner.spawn(currentVersion, this.configuration, this.pluginManager, {
|
||||
onFatalError: (command) => this.fatalError(command),
|
||||
onFatalError: (command, err) => this.fatalError(command, err),
|
||||
});
|
||||
this.serverState = new ServerState.Running(handle, apiVersion, undefined, true);
|
||||
this.lastStart = Date.now();
|
||||
@@ -670,7 +671,7 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||
}
|
||||
|
||||
if (config?.nonRecoverable) {
|
||||
execution.catch(() => this.fatalError(command));
|
||||
execution.catch(err => this.fatalError(command, err));
|
||||
}
|
||||
|
||||
return execution;
|
||||
@@ -704,14 +705,16 @@ export default class TypeScriptServiceClient extends Disposable implements IType
|
||||
return this.bufferSyncSupport.interuptGetErr(f);
|
||||
}
|
||||
|
||||
private fatalError(command: string): void {
|
||||
private fatalError(command: string, error: Error): void {
|
||||
/* __GDPR__
|
||||
"fatalError" : {
|
||||
"${include}": [ "${TypeScriptCommonProperties}" ],
|
||||
"command" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" }
|
||||
"${include}": [
|
||||
"${TypeScriptCommonProperties}",
|
||||
"${TypeScriptRequestErrorProperties}"
|
||||
]
|
||||
}
|
||||
*/
|
||||
this.logTelemetry('fatalError', { command });
|
||||
this.logTelemetry('fatalError', { command, ...(error instanceof TypeScriptServerError ? error.telemetry : {}) });
|
||||
console.error(`A non-recoverable error occured while executing tsserver command: ${command}`);
|
||||
|
||||
if (this.serverState.type === ServerState.Type.Running) {
|
||||
|
||||
@@ -101,5 +101,5 @@ export class ResourceMap<T> {
|
||||
}
|
||||
|
||||
export function isWindowsPath(path: string): boolean {
|
||||
return /^[a-zA-Z]:\\/.test(path);
|
||||
return /^[a-zA-Z]:[\/\\]/.test(path);
|
||||
}
|
||||
@@ -2824,14 +2824,12 @@ export class ProtocolServer implements vscode.DebugAdapter {
|
||||
private _sequence: number = 1;
|
||||
private _pendingRequests = new Map<number, (response: DebugProtocol.Response) => void>();
|
||||
|
||||
constructor() {
|
||||
}
|
||||
|
||||
public handleMessage(message: DebugProtocol.ProtocolMessage): void {
|
||||
this.dispatch(message);
|
||||
}
|
||||
|
||||
public stop(): void {
|
||||
public dispose() {
|
||||
}
|
||||
|
||||
public sendEvent(event: DebugProtocol.Event): void {
|
||||
@@ -3817,7 +3815,7 @@ export class MockDebugAdapterDescriptorFactory implements vscode.DebugAdapterDes
|
||||
}
|
||||
|
||||
createDebugAdapterDescriptor(_session: vscode.DebugSession, _executable: vscode.DebugAdapterExecutable | undefined): vscode.ProviderResult<vscode.DebugAdapterDescriptor> {
|
||||
return new vscode.DebugAdapterInlineImplementation(new MockDebugSession(this.memfs));
|
||||
return <any>new vscode.DebugAdapterInlineImplementation(new MockDebugSession(this.memfs));
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -916,4 +916,23 @@ suite('workspace-namespace', () => {
|
||||
const expected2 = 'import2;import1;';
|
||||
assert.equal(document.getText(), expected2);
|
||||
});
|
||||
|
||||
test('The api workspace.applyEdit failed for some case of mixing resourceChange and textEdit #80688', async function () {
|
||||
const file1 = await createRandomFile();
|
||||
const file2 = await createRandomFile();
|
||||
let we = new vscode.WorkspaceEdit();
|
||||
we.insert(file1, new vscode.Position(0, 0), 'import1;');
|
||||
we.insert(file1, new vscode.Position(0, 0), 'import2;');
|
||||
|
||||
const file2Name = basename(file2.fsPath);
|
||||
const file2NewUri = vscode.Uri.parse(file2.toString().replace(file2Name, `new/${file2Name}`));
|
||||
we.renameFile(file2, file2NewUri);
|
||||
|
||||
await vscode.workspace.applyEdit(we);
|
||||
|
||||
const document = await vscode.workspace.openTextDocument(file1);
|
||||
const expected = 'import1;import2;';
|
||||
// const expected2 = 'import2;import1;';
|
||||
assert.equal(document.getText(), expected);
|
||||
});
|
||||
});
|
||||
@@ -13,7 +13,7 @@ suite('workspace-namespace', () => {
|
||||
teardown(closeAllEditors);
|
||||
|
||||
test('rootPath', () => {
|
||||
assert.ok(pathEquals(vscode.workspace.rootPath!, join(__dirname, '../../testWorkspace')));
|
||||
assert.equal(vscode.workspace.rootPath, undefined);
|
||||
});
|
||||
|
||||
test('workspaceFile', () => {
|
||||
|
||||
@@ -8,53 +8,52 @@ import * as jsoncParser from 'jsonc-parser';
|
||||
|
||||
export function activate(context: vscode.ExtensionContext): any {
|
||||
|
||||
const tokenModifiers = ['static', 'abstract', 'deprecated'];
|
||||
const tokenTypes = ['strings', 'types', 'structs', 'classes', 'functions', 'variables'];
|
||||
const legend = new vscode.SemanticColoringLegend(tokenTypes, tokenModifiers);
|
||||
const tokenTypes = ['type', 'struct', 'class', 'interface', 'enum', 'parameterType', 'function', 'variable'];
|
||||
const tokenModifiers = ['static', 'abstract', 'deprecated', 'declaration', 'documentation', 'member', 'async'];
|
||||
|
||||
/*
|
||||
* A certain token (at index `i` is encoded using 5 uint32 integers):
|
||||
* - at index `5*i` - `deltaLine`: token line number, relative to `SemanticColoringArea.line`
|
||||
* - at index `5*i+1` - `startCharacter`: token start character offset inside the line (inclusive)
|
||||
* - at index `5*i+2` - `endCharacter`: token end character offset inside the line (exclusive)
|
||||
* - at index `5*i+3` - `tokenType`: will be looked up in `SemanticColoringLegend.tokenTypes`
|
||||
* - at index `5*i+4` - `tokenModifiers`: each set bit will be looked up in `SemanticColoringLegend.tokenModifiers`
|
||||
*/
|
||||
const legend = new vscode.SemanticTokensLegend(tokenTypes, tokenModifiers);
|
||||
|
||||
const semanticHighlightProvider: vscode.SemanticColoringProvider = {
|
||||
provideSemanticColoring(document: vscode.TextDocument): vscode.ProviderResult<vscode.SemanticColoring> {
|
||||
const result: number[] = [];
|
||||
const semanticHighlightProvider: vscode.SemanticTokensProvider = {
|
||||
provideSemanticTokens(document: vscode.TextDocument): vscode.ProviderResult<vscode.SemanticTokens> {
|
||||
const builder = new vscode.SemanticTokensBuilder();
|
||||
|
||||
function addToken(value: string, startLine: number, startCharacter: number, length: number) {
|
||||
const [type, ...modifiers] = value.split('.');
|
||||
|
||||
let tokenType = legend.tokenTypes.indexOf(type);
|
||||
if (tokenType === -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
let tokenModifiers = 0;
|
||||
for (let i = 0; i < modifiers.length; i++) {
|
||||
const index = legend.tokenModifiers.indexOf(modifiers[i]);
|
||||
if (index !== -1) {
|
||||
tokenModifiers = tokenModifiers | 1 << index;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
builder.push(startLine, startCharacter, length, tokenType, tokenModifiers);
|
||||
}
|
||||
|
||||
const visitor: jsoncParser.JSONVisitor = {
|
||||
onObjectProperty: (property: string, _offset: number, length: number, startLine: number, startCharacter: number) => {
|
||||
result.push(startLine);
|
||||
result.push(startCharacter);
|
||||
result.push(startCharacter + length);
|
||||
|
||||
|
||||
const [type, ...modifiers] = property.split('.');
|
||||
let tokenType = legend.tokenTypes.indexOf(type);
|
||||
if (tokenType === -1) {
|
||||
tokenType = 0;
|
||||
onObjectProperty: (property: string, _offset: number, _length: number, startLine: number, startCharacter: number) => {
|
||||
addToken(property, startLine, startCharacter, property.length + 2);
|
||||
},
|
||||
onLiteralValue: (value: any, _offset: number, length: number, startLine: number, startCharacter: number) => {
|
||||
if (typeof value === 'string') {
|
||||
addToken(value, startLine, startCharacter, length);
|
||||
}
|
||||
result.push(tokenType);
|
||||
|
||||
let tokenModifiers = 0;
|
||||
for (let i = 0; i < modifiers.length; i++) {
|
||||
const index = legend.tokenModifiers.indexOf(modifiers[i]);
|
||||
if (index !== -1) {
|
||||
tokenModifiers = tokenModifiers | 1 << index;
|
||||
}
|
||||
}
|
||||
result.push(tokenModifiers);
|
||||
}
|
||||
};
|
||||
jsoncParser.visit(document.getText(), visitor);
|
||||
return new vscode.SemanticColoring([new vscode.SemanticColoringArea(0, new Uint32Array(result))]);
|
||||
|
||||
return new vscode.SemanticTokens(builder.build());
|
||||
}
|
||||
};
|
||||
|
||||
|
||||
context.subscriptions.push(vscode.languages.registerSemanticColoringProvider({ pattern: '**/color-test.json' }, semanticHighlightProvider, legend));
|
||||
context.subscriptions.push(vscode.languages.registerSemanticTokensProvider({ pattern: '**/*semantic-test.json' }, semanticHighlightProvider, legend));
|
||||
|
||||
}
|
||||
@@ -8,7 +8,7 @@
|
||||
"engines": {
|
||||
"vscode": "^1.25.0"
|
||||
},
|
||||
"extensionKind": "ui",
|
||||
"extensionKind": [ "ui" ],
|
||||
"scripts": {
|
||||
"compile": "node ./node_modules/vscode/bin/compile -watch -p ./",
|
||||
"vscode:prepublish": "node ../../node_modules/gulp/bin/gulp.js --gulpfile ../../build/gulpfile.extensions.js compile-extension:vscode-test-resolver ./tsconfig.json"
|
||||
|
||||
@@ -2,7 +2,7 @@
|
||||
# yarn lockfile v1
|
||||
|
||||
|
||||
typescript@3.7.3-insiders.20191123:
|
||||
version "3.7.3-insiders.20191123"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.3-insiders.20191123.tgz#f3bef33a2a3f6e02f11bcc0c20b6f0de526f17fd"
|
||||
integrity sha512-b+tLx4D0a6SeuaCa7iehdgkRKHsS67FkioQWw+0REjVNOYZ+AqJ0NjlnomK1hEUvSzSNrH9Du+m+Yiv7JlVpSg==
|
||||
typescript@3.7.3:
|
||||
version "3.7.3"
|
||||
resolved "https://registry.yarnpkg.com/typescript/-/typescript-3.7.3.tgz#b36840668a16458a7025b9eabfad11b66ab85c69"
|
||||
integrity sha512-Mcr/Qk7hXqFBXMN7p7Lusj1ktCBydylfQM/FZCk5glCNQJrCUKPkMHdo9R0MTFWsC/4kPFvDS0fDPvukfCkFsw==
|
||||
+3
-3
@@ -1,7 +1,7 @@
|
||||
{
|
||||
"name": "code-oss-dev",
|
||||
"version": "1.41.0",
|
||||
"distro": "30dcc7436405dfa68898d0f3843551c589fc9008",
|
||||
"version": "1.42.0",
|
||||
"distro": "17f1b806c349d58f96b4aef97ae59d836e2c5605",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
},
|
||||
@@ -53,7 +53,7 @@
|
||||
"vscode-ripgrep": "^1.5.7",
|
||||
"vscode-sqlite3": "4.0.9",
|
||||
"vscode-textmate": "4.4.0",
|
||||
"xterm": "4.3.0-beta.28",
|
||||
"xterm": "4.3.0-beta.28.vscode.1",
|
||||
"xterm-addon-search": "0.4.0-beta4",
|
||||
"xterm-addon-web-links": "0.2.1",
|
||||
"xterm-addon-webgl": "0.4.0-beta.11",
|
||||
|
||||
+1
-1
@@ -20,7 +20,7 @@
|
||||
"vscode-proxy-agent": "^0.5.2",
|
||||
"vscode-ripgrep": "^1.5.7",
|
||||
"vscode-textmate": "4.4.0",
|
||||
"xterm": "4.3.0-beta.28",
|
||||
"xterm": "4.3.0-beta.28.vscode.1",
|
||||
"xterm-addon-search": "0.4.0-beta4",
|
||||
"xterm-addon-web-links": "0.2.1",
|
||||
"xterm-addon-webgl": "0.4.0-beta.11",
|
||||
|
||||
@@ -5,7 +5,7 @@
|
||||
"onigasm-umd": "2.2.5",
|
||||
"semver-umd": "^5.5.3",
|
||||
"vscode-textmate": "4.4.0",
|
||||
"xterm": "4.3.0-beta.28",
|
||||
"xterm": "4.3.0-beta.28.vscode.1",
|
||||
"xterm-addon-search": "0.4.0-beta4",
|
||||
"xterm-addon-web-links": "0.2.1",
|
||||
"xterm-addon-webgl": "0.4.0-beta.11"
|
||||
|
||||
@@ -46,7 +46,7 @@ xterm-addon-webgl@0.4.0-beta.11:
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.4.0-beta.11.tgz#0e4a7242e2353cf74aba55e5a5bdc0b4ec87ad10"
|
||||
integrity sha512-AteDxm1RFy1WnjY9r5iJSETozLebvUkR+jextdZk/ASsK21vsYK0DuVWwRI8afgiN2hUVhxcxuHEJUOV+CJDQA==
|
||||
|
||||
xterm@4.3.0-beta.28:
|
||||
version "4.3.0-beta.28"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.3.0-beta.28.tgz#80f7c4ba8f6ee3c953e6f33f8ce5aef08d5a8354"
|
||||
integrity sha512-WWZ4XCvce5h+klL6ObwtMauJff/n2KGGOwJJkDbJhrAjVy2a77GKgAedJTDDFGgKJ6ix1d7puHtVSSKflIVaDQ==
|
||||
xterm@4.3.0-beta.28.vscode.1:
|
||||
version "4.3.0-beta.28.vscode.1"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.3.0-beta.28.vscode.1.tgz#89b85398b5801708e833d08bf92b2124fa128943"
|
||||
integrity sha512-JNHNZyDtAWnybJTrenPzD6g/yXpHOvPqmjau91Up4onRbjQYMSNlth17SqaES68DKn/+4kcIl2c/RG5SXJjvGw==
|
||||
+4
-4
@@ -433,10 +433,10 @@ xterm-addon-webgl@0.4.0-beta.11:
|
||||
resolved "https://registry.yarnpkg.com/xterm-addon-webgl/-/xterm-addon-webgl-0.4.0-beta.11.tgz#0e4a7242e2353cf74aba55e5a5bdc0b4ec87ad10"
|
||||
integrity sha512-AteDxm1RFy1WnjY9r5iJSETozLebvUkR+jextdZk/ASsK21vsYK0DuVWwRI8afgiN2hUVhxcxuHEJUOV+CJDQA==
|
||||
|
||||
xterm@4.3.0-beta.28:
|
||||
version "4.3.0-beta.28"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.3.0-beta.28.tgz#80f7c4ba8f6ee3c953e6f33f8ce5aef08d5a8354"
|
||||
integrity sha512-WWZ4XCvce5h+klL6ObwtMauJff/n2KGGOwJJkDbJhrAjVy2a77GKgAedJTDDFGgKJ6ix1d7puHtVSSKflIVaDQ==
|
||||
xterm@4.3.0-beta.28.vscode.1:
|
||||
version "4.3.0-beta.28.vscode.1"
|
||||
resolved "https://registry.yarnpkg.com/xterm/-/xterm-4.3.0-beta.28.vscode.1.tgz#89b85398b5801708e833d08bf92b2124fa128943"
|
||||
integrity sha512-JNHNZyDtAWnybJTrenPzD6g/yXpHOvPqmjau91Up4onRbjQYMSNlth17SqaES68DKn/+4kcIl2c/RG5SXJjvGw==
|
||||
|
||||
yauzl@^2.9.2:
|
||||
version "2.10.0"
|
||||
|
||||
Vendored
-3
@@ -1,3 +0,0 @@
|
||||
declare module 'vscode-ripgrep' {
|
||||
export const rgPath: string;
|
||||
}
|
||||
@@ -972,6 +972,7 @@ export const EventHelper = {
|
||||
export interface IFocusTracker extends Disposable {
|
||||
onDidFocus: Event<void>;
|
||||
onDidBlur: Event<void>;
|
||||
refreshState?(): void;
|
||||
}
|
||||
|
||||
export function saveParentsScrollTop(node: Element): number[] {
|
||||
@@ -1000,6 +1001,8 @@ class FocusTracker extends Disposable implements IFocusTracker {
|
||||
private readonly _onDidBlur = this._register(new Emitter<void>());
|
||||
public readonly onDidBlur: Event<void> = this._onDidBlur.event;
|
||||
|
||||
private _refreshStateHandler: () => void;
|
||||
|
||||
constructor(element: HTMLElement | Window) {
|
||||
super();
|
||||
let hasFocus = isAncestor(document.activeElement, <HTMLElement>element);
|
||||
@@ -1026,9 +1029,24 @@ class FocusTracker extends Disposable implements IFocusTracker {
|
||||
}
|
||||
};
|
||||
|
||||
this._refreshStateHandler = () => {
|
||||
let currentNodeHasFocus = isAncestor(document.activeElement, <HTMLElement>element);
|
||||
if (currentNodeHasFocus !== hasFocus) {
|
||||
if (hasFocus) {
|
||||
onBlur();
|
||||
} else {
|
||||
onFocus();
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
this._register(domEvent(element, EventType.FOCUS, true)(onFocus));
|
||||
this._register(domEvent(element, EventType.BLUR, true)(onBlur));
|
||||
}
|
||||
|
||||
refreshState() {
|
||||
this._refreshStateHandler();
|
||||
}
|
||||
}
|
||||
|
||||
export function trackFocus(element: HTMLElement | Window): IFocusTracker {
|
||||
@@ -1079,6 +1097,11 @@ function _$<T extends Element>(namespace: Namespace, description: string, attrs?
|
||||
|
||||
Object.keys(attrs).forEach(name => {
|
||||
const value = attrs![name];
|
||||
|
||||
if (typeof value === 'undefined') {
|
||||
return;
|
||||
}
|
||||
|
||||
if (/^on\w+$/.test(name)) {
|
||||
(<any>result)[name] = value;
|
||||
} else if (name === 'selected') {
|
||||
|
||||
@@ -15,7 +15,6 @@ import { cloneAndChange } from 'vs/base/common/objects';
|
||||
import { escape } from 'vs/base/common/strings';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { renderCodicons } from 'vs/base/browser/ui/codiconLabel/codiconLabel';
|
||||
|
||||
export interface MarkdownRenderOptions extends FormattedTextRenderOptions {
|
||||
codeBlockRenderer?: (modeId: string, value: string) => Promise<string>;
|
||||
@@ -63,7 +62,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
||||
if (uri.query) {
|
||||
uri = uri.with({ query: _uriMassage(uri.query) });
|
||||
}
|
||||
return uri.toString();
|
||||
return uri.toString(true);
|
||||
};
|
||||
|
||||
// signal to code-block render that the
|
||||
@@ -73,10 +72,6 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
||||
|
||||
const renderer = new marked.Renderer();
|
||||
renderer.image = (href: string, title: string, text: string) => {
|
||||
if (href && href.indexOf('vscode-icon://codicon/') === 0) {
|
||||
return renderCodicons(`$(${URI.parse(href).path.substr(1)})`);
|
||||
}
|
||||
|
||||
let dimensions: string[] = [];
|
||||
let attributes: string[] = [];
|
||||
if (href) {
|
||||
@@ -178,7 +173,7 @@ export function renderMarkdown(markdown: IMarkdownString, options: MarkdownRende
|
||||
renderer
|
||||
};
|
||||
|
||||
const allowedSchemes = [Schemas.http, Schemas.https, Schemas.mailto, Schemas.data, Schemas.file, Schemas.vscodeRemote];
|
||||
const allowedSchemes = [Schemas.http, Schemas.https, Schemas.mailto, Schemas.data, Schemas.file, Schemas.vscodeRemote, Schemas.vscodeRemoteResource];
|
||||
if (markdown.isTrusted) {
|
||||
allowedSchemes.push(Schemas.command);
|
||||
}
|
||||
|
||||
@@ -396,7 +396,6 @@
|
||||
.codicon-debug-breakpoint-function:before { content: "\eb88" }
|
||||
.codicon-debug-breakpoint-function-disabled:before { content: "\eb88" }
|
||||
.codicon-debug-breakpoint-stackframe-active:before { content: "\eb89" }
|
||||
.codicon-debug-breakpoint-stackframe-dot:before { content: "\eb8a" }
|
||||
.codicon-debug-breakpoint-stackframe:before { content: "\eb8b" }
|
||||
.codicon-debug-breakpoint-stackframe-focused:before { content: "\eb8b" }
|
||||
.codicon-debug-breakpoint-unsupported:before { content: "\eb8c" }
|
||||
|
||||
@@ -604,8 +604,8 @@ export class SerializableGrid<T extends ISerializableView> extends Grid<T> {
|
||||
export type GridNodeDescriptor = { size?: number, groups?: GridNodeDescriptor[] };
|
||||
export type GridDescriptor = { orientation: Orientation, groups?: GridNodeDescriptor[] };
|
||||
|
||||
export function sanitizeGridNodeDescriptor(nodeDescriptor: GridNodeDescriptor): void {
|
||||
if (nodeDescriptor.groups && nodeDescriptor.groups.length <= 1) {
|
||||
export function sanitizeGridNodeDescriptor(nodeDescriptor: GridNodeDescriptor, rootNode: boolean): void {
|
||||
if (!rootNode && nodeDescriptor.groups && nodeDescriptor.groups.length <= 1) {
|
||||
nodeDescriptor.groups = undefined;
|
||||
}
|
||||
|
||||
@@ -617,7 +617,7 @@ export function sanitizeGridNodeDescriptor(nodeDescriptor: GridNodeDescriptor):
|
||||
let totalDefinedSizeCount = 0;
|
||||
|
||||
for (const child of nodeDescriptor.groups) {
|
||||
sanitizeGridNodeDescriptor(child);
|
||||
sanitizeGridNodeDescriptor(child, false);
|
||||
|
||||
if (child.size) {
|
||||
totalDefinedSize += child.size;
|
||||
@@ -665,7 +665,7 @@ function getDimensions(node: ISerializedNode, orientation: Orientation): { width
|
||||
}
|
||||
|
||||
export function createSerializedGrid(gridDescriptor: GridDescriptor): ISerializedGrid {
|
||||
sanitizeGridNodeDescriptor(gridDescriptor);
|
||||
sanitizeGridNodeDescriptor(gridDescriptor, true);
|
||||
|
||||
const root = createSerializedNode(gridDescriptor);
|
||||
const { width, height } = getDimensions(root, gridDescriptor.orientation);
|
||||
|
||||
@@ -1086,6 +1086,8 @@ export class GridView implements IDisposable {
|
||||
throw new Error('Invalid JSON: \'width\' property must be a number.');
|
||||
} else if (typeof json.height !== 'number') {
|
||||
throw new Error('Invalid JSON: \'height\' property must be a number.');
|
||||
} else if (json.root?.type !== 'branch') {
|
||||
throw new Error('Invalid JSON: \'root\' property must have \'type\' value of branch.');
|
||||
}
|
||||
|
||||
const orientation = json.orientation;
|
||||
|
||||
@@ -9,6 +9,7 @@ import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlighte
|
||||
import { IMatch } from 'vs/base/common/filters';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import { Range } from 'vs/base/common/range';
|
||||
import { equals } from 'vs/base/common/objects';
|
||||
|
||||
export interface IIconLabelCreationOptions {
|
||||
supportHighlights?: boolean;
|
||||
@@ -26,6 +27,7 @@ export interface IIconLabelValueOptions {
|
||||
labelEscapeNewLines?: boolean;
|
||||
descriptionMatches?: IMatch[];
|
||||
readonly separator?: string;
|
||||
readonly domId?: string;
|
||||
}
|
||||
|
||||
class FastLabelNode {
|
||||
@@ -164,21 +166,23 @@ class Label {
|
||||
|
||||
private label: string | string[] | undefined = undefined;
|
||||
private singleLabel: HTMLElement | undefined = undefined;
|
||||
private options: IIconLabelValueOptions | undefined;
|
||||
|
||||
constructor(private container: HTMLElement) { }
|
||||
|
||||
setLabel(label: string | string[], options?: IIconLabelValueOptions): void {
|
||||
if (this.label === label) {
|
||||
if (this.label === label && equals(this.options, options)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.label = label;
|
||||
this.options = options;
|
||||
|
||||
if (typeof label === 'string') {
|
||||
if (!this.singleLabel) {
|
||||
this.container.innerHTML = '';
|
||||
dom.removeClass(this.container, 'multiple');
|
||||
this.singleLabel = dom.append(this.container, dom.$('a.label-name'));
|
||||
this.singleLabel = dom.append(this.container, dom.$('a.label-name', { id: options?.domId }));
|
||||
}
|
||||
|
||||
this.singleLabel.textContent = label;
|
||||
@@ -189,8 +193,9 @@ class Label {
|
||||
|
||||
for (let i = 0; i < label.length; i++) {
|
||||
const l = label[i];
|
||||
const id = options?.domId && `${options?.domId}_${i}`;
|
||||
|
||||
dom.append(this.container, dom.$('a.label-name', { 'data-icon-label-count': label.length, 'data-icon-label-index': i }, l));
|
||||
dom.append(this.container, dom.$('a.label-name', { id, 'data-icon-label-count': label.length, 'data-icon-label-index': i }, l));
|
||||
|
||||
if (i < label.length - 1) {
|
||||
dom.append(this.container, dom.$('span.label-separator', undefined, options?.separator || '/'));
|
||||
@@ -224,21 +229,23 @@ class LabelWithHighlights {
|
||||
|
||||
private label: string | string[] | undefined = undefined;
|
||||
private singleLabel: HighlightedLabel | undefined = undefined;
|
||||
private options: IIconLabelValueOptions | undefined;
|
||||
|
||||
constructor(private container: HTMLElement, private supportCodicons: boolean) { }
|
||||
|
||||
setLabel(label: string | string[], options?: IIconLabelValueOptions): void {
|
||||
if (this.label === label) {
|
||||
if (this.label === label && equals(this.options, options)) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.label = label;
|
||||
this.options = options;
|
||||
|
||||
if (typeof label === 'string') {
|
||||
if (!this.singleLabel) {
|
||||
this.container.innerHTML = '';
|
||||
dom.removeClass(this.container, 'multiple');
|
||||
this.singleLabel = new HighlightedLabel(dom.append(this.container, dom.$('a.label-name')), this.supportCodicons);
|
||||
this.singleLabel = new HighlightedLabel(dom.append(this.container, dom.$('a.label-name', { id: options?.domId })), this.supportCodicons);
|
||||
}
|
||||
|
||||
this.singleLabel.set(label, options?.matches, options?.title, options?.labelEscapeNewLines);
|
||||
@@ -254,8 +261,9 @@ class LabelWithHighlights {
|
||||
for (let i = 0; i < label.length; i++) {
|
||||
const l = label[i];
|
||||
const m = matches ? matches[i] : undefined;
|
||||
const id = options?.domId && `${options?.domId}_${i}`;
|
||||
|
||||
const name = dom.$('a.label-name', { 'data-icon-label-count': label.length, 'data-icon-label-index': i });
|
||||
const name = dom.$('a.label-name', { id, 'data-icon-label-count': label.length, 'data-icon-label-index': i });
|
||||
const highlightedLabel = new HighlightedLabel(dom.append(this.container, name), this.supportCodicons);
|
||||
highlightedLabel.set(l, m, options?.title, options?.labelEscapeNewLines);
|
||||
|
||||
|
||||
@@ -702,6 +702,9 @@ export interface IAccessibilityProvider<T> {
|
||||
* https://www.w3.org/TR/wai-aria/#aria-level
|
||||
*/
|
||||
getAriaLevel?(element: T): number | undefined;
|
||||
|
||||
onDidChangeActiveDescendant?: Event<void>;
|
||||
getActiveDescendantId?(element: T): string | undefined;
|
||||
}
|
||||
|
||||
export class DefaultStyleController implements IStyleController {
|
||||
@@ -1115,6 +1118,7 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
||||
private spliceable: ISpliceable<T>;
|
||||
private styleController: IStyleController;
|
||||
private typeLabelController?: TypeLabelController<T>;
|
||||
private accessibilityProvider?: IAccessibilityProvider<T>;
|
||||
|
||||
protected readonly disposables = new DisposableStore();
|
||||
|
||||
@@ -1200,8 +1204,14 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
||||
|
||||
const baseRenderers: IListRenderer<T, ITraitTemplateData>[] = [this.focus.renderer, this.selection.renderer];
|
||||
|
||||
if (_options.accessibilityProvider) {
|
||||
baseRenderers.push(new AccessibiltyRenderer<T>(_options.accessibilityProvider));
|
||||
this.accessibilityProvider = _options.accessibilityProvider;
|
||||
|
||||
if (this.accessibilityProvider) {
|
||||
baseRenderers.push(new AccessibiltyRenderer<T>(this.accessibilityProvider));
|
||||
|
||||
if (this.accessibilityProvider.onDidChangeActiveDescendant) {
|
||||
this.accessibilityProvider.onDidChangeActiveDescendant(this.onDidChangeActiveDescendant, this, this.disposables);
|
||||
}
|
||||
}
|
||||
|
||||
renderers = renderers.map(r => new PipelineRenderer(r.templateId, [...baseRenderers, r]));
|
||||
@@ -1623,14 +1633,24 @@ export class List<T> implements ISpliceable<T>, IDisposable {
|
||||
|
||||
private _onFocusChange(): void {
|
||||
const focus = this.focus.get();
|
||||
DOM.toggleClass(this.view.domNode, 'element-focused', focus.length > 0);
|
||||
this.onDidChangeActiveDescendant();
|
||||
}
|
||||
|
||||
private onDidChangeActiveDescendant(): void {
|
||||
const focus = this.focus.get();
|
||||
|
||||
if (focus.length > 0) {
|
||||
this.view.domNode.setAttribute('aria-activedescendant', this.view.getElementDomId(focus[0]));
|
||||
let id: string | undefined;
|
||||
|
||||
if (this.accessibilityProvider?.getActiveDescendantId) {
|
||||
id = this.accessibilityProvider.getActiveDescendantId(this.view.element(focus[0]));
|
||||
}
|
||||
|
||||
this.view.domNode.setAttribute('aria-activedescendant', id || this.view.getElementDomId(focus[0]));
|
||||
} else {
|
||||
this.view.domNode.removeAttribute('aria-activedescendant');
|
||||
}
|
||||
|
||||
DOM.toggleClass(this.view.domNode, 'element-focused', focus.length > 0);
|
||||
}
|
||||
|
||||
private _onSelectionChange(): void {
|
||||
|
||||
@@ -161,12 +161,16 @@ function asListOptions<T, TFilterData, TRef>(modelProvider: () => ITreeModel<T,
|
||||
}
|
||||
},
|
||||
accessibilityProvider: options.accessibilityProvider && {
|
||||
...options.accessibilityProvider,
|
||||
getAriaLabel(e) {
|
||||
return options.accessibilityProvider!.getAriaLabel(e.element);
|
||||
},
|
||||
getAriaLevel(node) {
|
||||
return node.depth;
|
||||
}
|
||||
},
|
||||
getActiveDescendantId: options.accessibilityProvider.getActiveDescendantId && (node => {
|
||||
return options.accessibilityProvider!.getActiveDescendantId!(node.element);
|
||||
})
|
||||
},
|
||||
keyboardNavigationLabelProvider: options.keyboardNavigationLabelProvider && {
|
||||
...options.keyboardNavigationLabelProvider,
|
||||
|
||||
@@ -6,7 +6,7 @@
|
||||
import { ComposedTreeDelegate, IAbstractTreeOptions, IAbstractTreeOptionsUpdate } from 'vs/base/browser/ui/tree/abstractTree';
|
||||
import { ObjectTree, IObjectTreeOptions, CompressibleObjectTree, ICompressibleTreeRenderer, ICompressibleKeyboardNavigationLabelProvider, ICompressibleObjectTreeOptions } from 'vs/base/browser/ui/tree/objectTree';
|
||||
import { IListVirtualDelegate, IIdentityProvider, IListDragAndDrop, IListDragOverReaction } from 'vs/base/browser/ui/list/list';
|
||||
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeSorter, ICollapseStateChangeEvent, IAsyncDataSource, ITreeDragAndDrop, TreeError, WeakMapper } from 'vs/base/browser/ui/tree/tree';
|
||||
import { ITreeElement, ITreeNode, ITreeRenderer, ITreeEvent, ITreeMouseEvent, ITreeContextMenuEvent, ITreeSorter, ICollapseStateChangeEvent, IAsyncDataSource, ITreeDragAndDrop, TreeError, WeakMapper, ITreeFilter, TreeVisibility, TreeFilterResult } from 'vs/base/browser/ui/tree/tree';
|
||||
import { IDisposable, dispose, DisposableStore } from 'vs/base/common/lifecycle';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { timeout, CancelablePromise, createCancelablePromise } from 'vs/base/common/async';
|
||||
@@ -20,6 +20,7 @@ import { values } from 'vs/base/common/map';
|
||||
import { ScrollEvent } from 'vs/base/common/scrollable';
|
||||
import { ICompressedTreeNode, ICompressedTreeElement } from 'vs/base/browser/ui/tree/compressedObjectTreeModel';
|
||||
import { IThemable } from 'vs/base/common/styler';
|
||||
import { isFilterResult, getVisibleState } from 'vs/base/browser/ui/tree/indexTreeModel';
|
||||
|
||||
interface IAsyncDataTreeNode<TInput, T> {
|
||||
element: TInput | T;
|
||||
@@ -229,9 +230,16 @@ function asObjectTreeOptions<TInput, T, TFilterData>(options?: IAsyncDataTreeOpt
|
||||
}
|
||||
},
|
||||
accessibilityProvider: options.accessibilityProvider && {
|
||||
...options.accessibilityProvider,
|
||||
getAriaLabel(e) {
|
||||
return options.accessibilityProvider!.getAriaLabel(e.element as T);
|
||||
}
|
||||
},
|
||||
getAriaLevel: options.accessibilityProvider!.getAriaLevel && (node => {
|
||||
return options.accessibilityProvider!.getAriaLevel!(node.element as T);
|
||||
}),
|
||||
getActiveDescendantId: options.accessibilityProvider.getActiveDescendantId && (node => {
|
||||
return options.accessibilityProvider!.getActiveDescendantId!(node.element as T);
|
||||
})
|
||||
},
|
||||
filter: options.filter && {
|
||||
filter(e, parentVisibility) {
|
||||
@@ -760,12 +768,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
|
||||
result = createCancelablePromise(async () => {
|
||||
const children = await this.dataSource.getChildren(node.element!);
|
||||
|
||||
if (this.sorter) {
|
||||
children.sort(this.sorter.compare.bind(this.sorter));
|
||||
}
|
||||
|
||||
return children;
|
||||
return this.processChildren(children);
|
||||
});
|
||||
|
||||
this.refreshPromises.set(node, result);
|
||||
@@ -924,6 +927,14 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
|
||||
};
|
||||
}
|
||||
|
||||
protected processChildren(children: T[]): T[] {
|
||||
if (this.sorter) {
|
||||
children.sort(this.sorter.compare.bind(this.sorter));
|
||||
}
|
||||
|
||||
return children;
|
||||
}
|
||||
|
||||
// view state
|
||||
|
||||
getViewState(): IAsyncDataTreeViewState {
|
||||
@@ -1066,6 +1077,7 @@ export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends As
|
||||
|
||||
protected readonly tree!: CompressibleObjectTree<IAsyncDataTreeNode<TInput, T>, TFilterData>;
|
||||
protected readonly compressibleNodeMapper: CompressibleAsyncDataTreeNodeMapper<TInput, T, TFilterData> = new WeakMapper(node => new CompressibleAsyncDataTreeNodeWrapper(node));
|
||||
private filter?: ITreeFilter<T, TFilterData>;
|
||||
|
||||
constructor(
|
||||
user: string,
|
||||
@@ -1077,6 +1089,7 @@ export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends As
|
||||
options: ICompressibleAsyncDataTreeOptions<T, TFilterData> = {}
|
||||
) {
|
||||
super(user, container, virtualDelegate, renderers, dataSource, options);
|
||||
this.filter = options.filter;
|
||||
}
|
||||
|
||||
protected createTree(
|
||||
@@ -1176,14 +1189,16 @@ export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends As
|
||||
if (compressedNode) {
|
||||
for (let i = 0; i < compressedNode.elements.length; i++) {
|
||||
const id = getId(compressedNode.elements[i].element as T);
|
||||
const element = compressedNode.elements[compressedNode.elements.length - 1].element as T;
|
||||
|
||||
if (oldSelection.has(id)) {
|
||||
selection.push(compressedNode.elements[compressedNode.elements.length - 1].element as T);
|
||||
// github.com/microsoft/vscode/issues/85938
|
||||
if (oldSelection.has(id) && selection.indexOf(element) === -1) {
|
||||
selection.push(element);
|
||||
didChangeSelection = true;
|
||||
}
|
||||
|
||||
if (oldFocus.has(id)) {
|
||||
focus.push(compressedNode.elements[compressedNode.elements.length - 1].element as T);
|
||||
if (oldFocus.has(id) && focus.indexOf(element) === -1) {
|
||||
focus.push(element);
|
||||
didChangeFocus = true;
|
||||
}
|
||||
}
|
||||
@@ -1202,4 +1217,34 @@ export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends As
|
||||
this.setFocus(focus);
|
||||
}
|
||||
}
|
||||
|
||||
// For compressed async data trees, `TreeVisibility.Recurse` doesn't currently work
|
||||
// and we have to filter everything beforehand
|
||||
// Related to #85193 and #85835
|
||||
protected processChildren(children: T[]): T[] {
|
||||
if (this.filter) {
|
||||
children = children.filter(e => {
|
||||
const result = this.filter!.filter(e, TreeVisibility.Visible);
|
||||
const visibility = getVisibility(result);
|
||||
|
||||
if (visibility === TreeVisibility.Recurse) {
|
||||
throw new Error('Recursive tree visibility not supported in async data compressed trees');
|
||||
}
|
||||
|
||||
return visibility === TreeVisibility.Visible;
|
||||
});
|
||||
}
|
||||
|
||||
return super.processChildren(children);
|
||||
}
|
||||
}
|
||||
|
||||
function getVisibility<TFilterData>(filterResult: TreeFilterResult<TFilterData>): TreeVisibility {
|
||||
if (typeof filterResult === 'boolean') {
|
||||
return filterResult ? TreeVisibility.Visible : TreeVisibility.Hidden;
|
||||
} else if (isFilterResult(filterResult)) {
|
||||
return getVisibleState(filterResult.visibility);
|
||||
} else {
|
||||
return getVisibleState(filterResult);
|
||||
}
|
||||
}
|
||||
@@ -11,7 +11,7 @@ import { IObjectTreeModelOptions, ObjectTreeModel, IObjectTreeModel } from 'vs/b
|
||||
|
||||
// Exported only for test reasons, do not use directly
|
||||
export interface ICompressedTreeElement<T> extends ITreeElement<T> {
|
||||
readonly children?: Iterator<ICompressedTreeElement<T>> | ICompressedTreeElement<T>[];
|
||||
readonly children?: ISequence<ICompressedTreeElement<T>>;
|
||||
readonly incompressible?: boolean;
|
||||
}
|
||||
|
||||
|
||||
@@ -172,13 +172,28 @@ export module Iterator {
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
export function chain<T>(iterator: Iterator<T>): ChainableIterator<T> {
|
||||
return new ChainableIterator(iterator);
|
||||
}
|
||||
}
|
||||
|
||||
export class ChainableIterator<T> implements Iterator<T> {
|
||||
|
||||
constructor(private it: Iterator<T>) { }
|
||||
|
||||
next(): IteratorResult<T> { return this.it.next(); }
|
||||
map<R>(fn: (t: T) => R): ChainableIterator<R> { return new ChainableIterator(Iterator.map(this.it, fn)); }
|
||||
filter(fn: (t: T) => boolean): ChainableIterator<T> { return new ChainableIterator(Iterator.filter(this.it, fn)); }
|
||||
}
|
||||
|
||||
export type ISequence<T> = Iterator<T> | T[];
|
||||
|
||||
export function getSequenceIterator<T>(arg: Iterator<T> | T[]): Iterator<T> {
|
||||
export function getSequenceIterator<T>(arg: ISequence<T> | undefined): Iterator<T> {
|
||||
if (Array.isArray(arg)) {
|
||||
return Iterator.fromArray(arg);
|
||||
} else if (!arg) {
|
||||
return Iterator.empty();
|
||||
} else {
|
||||
return arg;
|
||||
}
|
||||
|
||||
@@ -199,6 +199,13 @@ export function detectEncodingByBOMFromBuffer(buffer: Buffer | VSBuffer | null,
|
||||
return null;
|
||||
}
|
||||
|
||||
// we explicitly ignore a specific set of encodings from auto guessing
|
||||
// - ASCII: we never want this encoding (most UTF-8 files would happily detect as
|
||||
// ASCII files and then you could not type non-ASCII characters anymore)
|
||||
// - UTF-16: we have our own detection logic for UTF-16
|
||||
// - UTF-32: we do not support this encoding in VSCode
|
||||
const IGNORE_ENCODINGS = ['ascii', 'utf-16', 'utf-32'];
|
||||
|
||||
/**
|
||||
* Guesses the encoding from buffer.
|
||||
*/
|
||||
@@ -210,15 +217,9 @@ async function guessEncodingByBuffer(buffer: Buffer): Promise<string | null> {
|
||||
return null;
|
||||
}
|
||||
|
||||
// Ignore 'ascii' as guessed encoding because that
|
||||
// is almost never what we want, rather fallback
|
||||
// to the configured encoding then. Otherwise,
|
||||
// opening a ascii-only file with auto guessing
|
||||
// enabled will put the file into 'ascii' mode
|
||||
// and thus typing any special characters is
|
||||
// not possible anymore.
|
||||
if (guessed.encoding.toLowerCase() === 'ascii') {
|
||||
return null;
|
||||
const enc = guessed.encoding.toLowerCase();
|
||||
if (0 <= IGNORE_ENCODINGS.indexOf(enc)) {
|
||||
return null; // see comment above why we ignore some encodings
|
||||
}
|
||||
|
||||
return toIconvLiteEncoding(guessed.encoding);
|
||||
|
||||
@@ -787,7 +787,7 @@ suite('SerializableGrid', function () {
|
||||
test('sanitizeGridNodeDescriptor', () => {
|
||||
const nodeDescriptor = { groups: [{ size: 0.2 }, { size: 0.2 }, { size: 0.6, groups: [{}, {}] }] };
|
||||
const nodeDescriptorCopy = deepClone<GridNodeDescriptor>(nodeDescriptor);
|
||||
sanitizeGridNodeDescriptor(nodeDescriptorCopy);
|
||||
sanitizeGridNodeDescriptor(nodeDescriptorCopy, true);
|
||||
assert.deepEqual(nodeDescriptorCopy, { groups: [{ size: 0.2 }, { size: 0.2 }, { size: 0.6, groups: [{ size: 0.5 }, { size: 0.5 }] }] });
|
||||
});
|
||||
|
||||
|
||||
@@ -50,8 +50,8 @@ import { IFileService } from 'vs/platform/files/common/files';
|
||||
import { DiskFileSystemProvider } from 'vs/platform/files/electron-browser/diskFileSystemProvider';
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { IProductService } from 'vs/platform/product/common/productService';
|
||||
import { IUserDataSyncService, IUserDataSyncStoreService, ISettingsMergeService, registerConfiguration, IUserDataSyncLogService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { UserDataSyncService, UserDataAutoSync } from 'vs/platform/userDataSync/common/userDataSyncService';
|
||||
import { IUserDataSyncService, IUserDataSyncStoreService, ISettingsMergeService, registerConfiguration, IUserDataSyncLogService, IUserDataSyncUtilService } from 'vs/platform/userDataSync/common/userDataSync';
|
||||
import { UserDataSyncService } from 'vs/platform/userDataSync/common/userDataSyncService';
|
||||
import { UserDataSyncStoreService } from 'vs/platform/userDataSync/common/userDataSyncStoreService';
|
||||
import { UserDataSyncChannel } from 'vs/platform/userDataSync/common/userDataSyncIpc';
|
||||
import { SettingsMergeChannelClient } from 'vs/platform/userDataSync/common/settingsSyncIpc';
|
||||
@@ -63,6 +63,8 @@ import { AuthTokenService } from 'vs/platform/auth/electron-browser/authTokenSer
|
||||
import { AuthTokenChannel } from 'vs/platform/auth/common/authTokenIpc';
|
||||
import { ICredentialsService } from 'vs/platform/credentials/common/credentials';
|
||||
import { KeytarCredentialsService } from 'vs/platform/credentials/node/credentialsService';
|
||||
import { UserDataSyncUtilServiceClient } from 'vs/platform/userDataSync/common/keybindingsSyncIpc';
|
||||
import { UserDataAutoSync } from 'vs/platform/userDataSync/electron-browser/userDataAutoSync';
|
||||
|
||||
export interface ISharedProcessConfiguration {
|
||||
readonly machineId: string;
|
||||
@@ -186,6 +188,7 @@ async function main(server: Server, initData: ISharedProcessInitData, configurat
|
||||
services.set(IUserDataSyncLogService, new SyncDescriptor(UserDataSyncLogService));
|
||||
const settingsMergeChannel = server.getChannel('settingsMerge', activeWindowRouter);
|
||||
services.set(ISettingsMergeService, new SettingsMergeChannelClient(settingsMergeChannel));
|
||||
services.set(IUserDataSyncUtilService, new UserDataSyncUtilServiceClient(server.getChannel('userDataSyncUtil', activeWindowRouter)));
|
||||
services.set(IUserDataSyncStoreService, new SyncDescriptor(UserDataSyncStoreService));
|
||||
services.set(IUserDataSyncService, new SyncDescriptor(UserDataSyncService));
|
||||
registerConfiguration();
|
||||
|
||||
@@ -9,11 +9,10 @@ import { StandardWheelEvent, IMouseWheelEvent } from 'vs/base/browser/mouseEvent
|
||||
import { RunOnceScheduler, TimeoutTimer } from 'vs/base/common/async';
|
||||
import { Disposable } from 'vs/base/common/lifecycle';
|
||||
import * as platform from 'vs/base/common/platform';
|
||||
import { HitTestContext, IViewZoneData, MouseTarget, MouseTargetFactory } from 'vs/editor/browser/controller/mouseTarget';
|
||||
import { HitTestContext, IViewZoneData, MouseTarget, MouseTargetFactory, PointerHandlerLastRenderData } from 'vs/editor/browser/controller/mouseTarget';
|
||||
import * as editorBrowser from 'vs/editor/browser/editorBrowser';
|
||||
import { ClientCoordinates, EditorMouseEvent, EditorMouseEventFactory, GlobalEditorMouseMoveMonitor, createEditorPagePosition } from 'vs/editor/browser/editorDom';
|
||||
import { ViewController } from 'vs/editor/browser/view/viewController';
|
||||
import { IViewCursorRenderData } from 'vs/editor/browser/viewParts/viewCursors/viewCursor';
|
||||
import { EditorZoom } from 'vs/editor/common/config/editorZoom';
|
||||
import { Position } from 'vs/editor/common/core/position';
|
||||
import { Selection } from 'vs/editor/common/core/selection';
|
||||
@@ -46,9 +45,9 @@ export interface IPointerHandlerHelper {
|
||||
focusTextArea(): void;
|
||||
|
||||
/**
|
||||
* Get the last rendered information of the cursors.
|
||||
* Get the last rendered information for cursors & textarea.
|
||||
*/
|
||||
getLastViewCursorsRenderData(): IViewCursorRenderData[];
|
||||
getLastRenderData(): PointerHandlerLastRenderData;
|
||||
|
||||
shouldSuppressMouseDownOnViewZone(viewZoneId: string): boolean;
|
||||
shouldSuppressMouseDownOnWidget(widgetId: string): boolean;
|
||||
@@ -158,13 +157,11 @@ export class MouseHandler extends ViewEventHandler {
|
||||
return null;
|
||||
}
|
||||
|
||||
const lastViewCursorsRenderData = this.viewHelper.getLastViewCursorsRenderData();
|
||||
return this.mouseTargetFactory.createMouseTarget(lastViewCursorsRenderData, editorPos, pos, null);
|
||||
return this.mouseTargetFactory.createMouseTarget(this.viewHelper.getLastRenderData(), editorPos, pos, null);
|
||||
}
|
||||
|
||||
protected _createMouseTarget(e: EditorMouseEvent, testEventTarget: boolean): editorBrowser.IMouseTarget {
|
||||
const lastViewCursorsRenderData = this.viewHelper.getLastViewCursorsRenderData();
|
||||
return this.mouseTargetFactory.createMouseTarget(lastViewCursorsRenderData, e.editorPos, e.pos, testEventTarget ? e.target : null);
|
||||
return this.mouseTargetFactory.createMouseTarget(this.viewHelper.getLastRenderData(), e.editorPos, e.pos, testEventTarget ? e.target : null);
|
||||
}
|
||||
|
||||
private _getMouseColumn(e: EditorMouseEvent): number {
|
||||
|
||||
@@ -89,6 +89,13 @@ interface IHitTestResult {
|
||||
hitTarget: Element | null;
|
||||
}
|
||||
|
||||
export class PointerHandlerLastRenderData {
|
||||
constructor(
|
||||
public readonly lastViewCursorsRenderData: IViewCursorRenderData[],
|
||||
public readonly lastTextareaPosition: Position | null
|
||||
) { }
|
||||
}
|
||||
|
||||
export class MouseTarget implements IMouseTarget {
|
||||
|
||||
public readonly element: Element | null;
|
||||
@@ -232,19 +239,19 @@ export class HitTestContext {
|
||||
public readonly viewDomNode: HTMLElement;
|
||||
public readonly lineHeight: number;
|
||||
public readonly typicalHalfwidthCharacterWidth: number;
|
||||
public readonly lastViewCursorsRenderData: IViewCursorRenderData[];
|
||||
public readonly lastRenderData: PointerHandlerLastRenderData;
|
||||
|
||||
private readonly _context: ViewContext;
|
||||
private readonly _viewHelper: IPointerHandlerHelper;
|
||||
|
||||
constructor(context: ViewContext, viewHelper: IPointerHandlerHelper, lastViewCursorsRenderData: IViewCursorRenderData[]) {
|
||||
constructor(context: ViewContext, viewHelper: IPointerHandlerHelper, lastRenderData: PointerHandlerLastRenderData) {
|
||||
this.model = context.model;
|
||||
const options = context.configuration.options;
|
||||
this.layoutInfo = options.get(EditorOption.layoutInfo);
|
||||
this.viewDomNode = viewHelper.viewDomNode;
|
||||
this.lineHeight = options.get(EditorOption.lineHeight);
|
||||
this.typicalHalfwidthCharacterWidth = options.get(EditorOption.fontInfo).typicalHalfwidthCharacterWidth;
|
||||
this.lastViewCursorsRenderData = lastViewCursorsRenderData;
|
||||
this.lastRenderData = lastRenderData;
|
||||
this._context = context;
|
||||
this._viewHelper = viewHelper;
|
||||
}
|
||||
@@ -462,8 +469,8 @@ export class MouseTargetFactory {
|
||||
return false;
|
||||
}
|
||||
|
||||
public createMouseTarget(lastViewCursorsRenderData: IViewCursorRenderData[], editorPos: EditorPagePosition, pos: PageCoordinates, target: HTMLElement | null): IMouseTarget {
|
||||
const ctx = new HitTestContext(this._context, this._viewHelper, lastViewCursorsRenderData);
|
||||
public createMouseTarget(lastRenderData: PointerHandlerLastRenderData, editorPos: EditorPagePosition, pos: PageCoordinates, target: HTMLElement | null): IMouseTarget {
|
||||
const ctx = new HitTestContext(this._context, this._viewHelper, lastRenderData);
|
||||
const request = new HitTestRequest(ctx, editorPos, pos, target);
|
||||
try {
|
||||
const r = MouseTargetFactory._createMouseTarget(ctx, request, false);
|
||||
@@ -544,7 +551,7 @@ export class MouseTargetFactory {
|
||||
|
||||
if (request.target) {
|
||||
// Check if we've hit a painted cursor
|
||||
const lastViewCursorsRenderData = ctx.lastViewCursorsRenderData;
|
||||
const lastViewCursorsRenderData = ctx.lastRenderData.lastViewCursorsRenderData;
|
||||
|
||||
for (const d of lastViewCursorsRenderData) {
|
||||
|
||||
@@ -560,7 +567,7 @@ export class MouseTargetFactory {
|
||||
// first or last rendered view line dom node, therefore help it out
|
||||
// and first check if we are on top of a cursor
|
||||
|
||||
const lastViewCursorsRenderData = ctx.lastViewCursorsRenderData;
|
||||
const lastViewCursorsRenderData = ctx.lastRenderData.lastViewCursorsRenderData;
|
||||
const mouseContentHorizontalOffset = request.mouseContentHorizontalOffset;
|
||||
const mouseVerticalOffset = request.mouseVerticalOffset;
|
||||
|
||||
@@ -602,7 +609,10 @@ export class MouseTargetFactory {
|
||||
private static _hitTestTextArea(ctx: HitTestContext, request: ResolvedHitTestRequest): MouseTarget | null {
|
||||
// Is it the textarea?
|
||||
if (ElementPath.isTextArea(request.targetPath)) {
|
||||
return request.fulfill(MouseTargetType.TEXTAREA);
|
||||
if (ctx.lastRenderData.lastTextareaPosition) {
|
||||
return request.fulfill(MouseTargetType.CONTENT_TEXT, ctx.lastRenderData.lastTextareaPosition);
|
||||
}
|
||||
return request.fulfill(MouseTargetType.TEXTAREA, ctx.lastRenderData.lastTextareaPosition);
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -77,6 +77,12 @@ export class TextAreaHandler extends ViewPart {
|
||||
private _visibleTextArea: VisibleTextAreaData | null;
|
||||
private _selections: Selection[];
|
||||
|
||||
/**
|
||||
* The position at which the textarea was rendered.
|
||||
* This is useful for hit-testing and determining the mouse position.
|
||||
*/
|
||||
private _lastRenderPosition: Position | null;
|
||||
|
||||
public readonly textArea: FastDomNode<HTMLTextAreaElement>;
|
||||
public readonly textAreaCover: FastDomNode<HTMLElement>;
|
||||
private readonly _textAreaInput: TextAreaInput;
|
||||
@@ -104,6 +110,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
|
||||
this._visibleTextArea = null;
|
||||
this._selections = [new Selection(1, 1, 1, 1)];
|
||||
this._lastRenderPosition = null;
|
||||
|
||||
// Text Area (The focus will always be in the textarea when the cursor is blinking)
|
||||
this.textArea = createFastDomNode(document.createElement('textarea'));
|
||||
@@ -413,13 +420,18 @@ export class TextAreaHandler extends ViewPart {
|
||||
this._textAreaInput.refreshFocusState();
|
||||
}
|
||||
|
||||
public getLastRenderData(): Position | null {
|
||||
return this._lastRenderPosition;
|
||||
}
|
||||
|
||||
// --- end view API
|
||||
|
||||
private _primaryCursorPosition: Position = new Position(1, 1);
|
||||
private _primaryCursorVisibleRange: HorizontalPosition | null = null;
|
||||
|
||||
public prepareRender(ctx: RenderingContext): void {
|
||||
const primaryCursorPosition = new Position(this._selections[0].positionLineNumber, this._selections[0].positionColumn);
|
||||
this._primaryCursorVisibleRange = ctx.visibleRangeForPosition(primaryCursorPosition);
|
||||
this._primaryCursorPosition = new Position(this._selections[0].positionLineNumber, this._selections[0].positionColumn);
|
||||
this._primaryCursorVisibleRange = ctx.visibleRangeForPosition(this._primaryCursorPosition);
|
||||
}
|
||||
|
||||
public render(ctx: RestrictedRenderingContext): void {
|
||||
@@ -431,6 +443,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
if (this._visibleTextArea) {
|
||||
// The text area is visible for composition reasons
|
||||
this._renderInsideEditor(
|
||||
null,
|
||||
this._visibleTextArea.top - this._scrollTop,
|
||||
this._contentLeft + this._visibleTextArea.left - this._scrollLeft,
|
||||
this._visibleTextArea.width,
|
||||
@@ -465,6 +478,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
// For the popup emoji input, we will make the text area as high as the line height
|
||||
// We will also make the fontSize and lineHeight the correct dimensions to help with the placement of these pickers
|
||||
this._renderInsideEditor(
|
||||
this._primaryCursorPosition,
|
||||
top, left,
|
||||
canUseZeroSizeTextarea ? 0 : 1, this._lineHeight
|
||||
);
|
||||
@@ -472,12 +486,14 @@ export class TextAreaHandler extends ViewPart {
|
||||
}
|
||||
|
||||
this._renderInsideEditor(
|
||||
this._primaryCursorPosition,
|
||||
top, left,
|
||||
canUseZeroSizeTextarea ? 0 : 1, canUseZeroSizeTextarea ? 0 : 1
|
||||
);
|
||||
}
|
||||
|
||||
private _renderInsideEditor(top: number, left: number, width: number, height: number): void {
|
||||
private _renderInsideEditor(renderedPosition: Position | null, top: number, left: number, width: number, height: number): void {
|
||||
this._lastRenderPosition = renderedPosition;
|
||||
const ta = this.textArea;
|
||||
const tac = this.textAreaCover;
|
||||
|
||||
@@ -495,6 +511,7 @@ export class TextAreaHandler extends ViewPart {
|
||||
}
|
||||
|
||||
private _renderAtTopLeft(): void {
|
||||
this._lastRenderPosition = null;
|
||||
const ta = this.textArea;
|
||||
const tac = this.textAreaCover;
|
||||
|
||||
|
||||
@@ -274,7 +274,11 @@ export class TextAreaInput extends Disposable {
|
||||
|
||||
this._register(dom.addDisposableListener(textArea.domNode, 'compositionend', (e: CompositionEvent) => {
|
||||
this._lastTextAreaEvent = TextAreaInputEventType.compositionend;
|
||||
|
||||
// https://github.com/microsoft/monaco-editor/issues/1663
|
||||
// On iOS 13.2, Chinese system IME randomly trigger an additional compositionend event with empty data
|
||||
if (!this._isDoingComposition) {
|
||||
return;
|
||||
}
|
||||
if (compositionDataInValid(e.locale)) {
|
||||
// https://github.com/Microsoft/monaco-editor/issues/339
|
||||
const [newState, typeInput] = deduceInputFromTextAreaValue(/*couldBeEmojiInput*/false, /*couldBeTypingAtOffset0*/false);
|
||||
|
||||
@@ -48,6 +48,7 @@ import { ViewEventHandler } from 'vs/editor/common/viewModel/viewEventHandler';
|
||||
import { IViewModel } from 'vs/editor/common/viewModel/viewModel';
|
||||
import { IThemeService, getThemeTypeSelector } from 'vs/platform/theme/common/themeService';
|
||||
import { EditorOption } from 'vs/editor/common/config/editorOptions';
|
||||
import { PointerHandlerLastRenderData } from 'vs/editor/browser/controller/mouseTarget';
|
||||
|
||||
|
||||
export interface IContentWidgetData {
|
||||
@@ -244,8 +245,10 @@ export class View extends ViewEventHandler {
|
||||
this.focus();
|
||||
},
|
||||
|
||||
getLastViewCursorsRenderData: () => {
|
||||
return this.viewCursors.getLastRenderData() || [];
|
||||
getLastRenderData: (): PointerHandlerLastRenderData => {
|
||||
const lastViewCursorsRenderData = this.viewCursors.getLastRenderData() || [];
|
||||
const lastTextareaPosition = this._textAreaHandler.getLastRenderData();
|
||||
return new PointerHandlerLastRenderData(lastViewCursorsRenderData, lastTextareaPosition);
|
||||
},
|
||||
shouldSuppressMouseDownOnViewZone: (viewZoneId: string) => {
|
||||
return this.viewZones.shouldSuppressMouseDownOnViewZone(viewZoneId);
|
||||
|
||||
@@ -57,7 +57,7 @@ export abstract class AbstractLineHighlightOverlay extends DynamicViewOverlay {
|
||||
const renderSelections = isRenderedUsingBorder ? this._selections.slice(0, 1) : this._selections;
|
||||
|
||||
const cursorsLineNumbers = renderSelections.map(s => s.positionLineNumber);
|
||||
cursorsLineNumbers.sort();
|
||||
cursorsLineNumbers.sort((a, b) => a - b);
|
||||
if (!arrays.equals(this._cursorLineNumbers, cursorsLineNumbers)) {
|
||||
this._cursorLineNumbers = cursorsLineNumbers;
|
||||
hasChanged = true;
|
||||
|
||||
@@ -33,6 +33,7 @@ import { Color } from 'vs/base/common/color';
|
||||
import { GestureEvent, EventType, Gesture } from 'vs/base/browser/touch';
|
||||
import { MinimapCharRendererFactory } from 'vs/editor/browser/viewParts/minimap/minimapCharRendererFactory';
|
||||
import { MinimapPosition } from 'vs/editor/common/model';
|
||||
import { once } from 'vs/base/common/functional';
|
||||
|
||||
function getMinimapLineHeight(renderMinimap: RenderMinimap, scale: number): number {
|
||||
if (renderMinimap === RenderMinimap.Text) {
|
||||
@@ -73,7 +74,7 @@ class MinimapOptions {
|
||||
|
||||
public readonly fontScale: number;
|
||||
|
||||
public readonly charRenderer: MinimapCharRenderer;
|
||||
public readonly charRenderer: () => MinimapCharRenderer;
|
||||
|
||||
/**
|
||||
* container dom node left position (in CSS px)
|
||||
@@ -117,7 +118,7 @@ class MinimapOptions {
|
||||
const minimapOpts = options.get(EditorOption.minimap);
|
||||
this.showSlider = minimapOpts.showSlider;
|
||||
this.fontScale = Math.round(minimapOpts.scale * pixelRatio);
|
||||
this.charRenderer = MinimapCharRendererFactory.create(this.fontScale, fontInfo.fontFamily);
|
||||
this.charRenderer = once(() => MinimapCharRendererFactory.create(this.fontScale, fontInfo.fontFamily));
|
||||
this.pixelRatio = pixelRatio;
|
||||
this.typicalHalfwidthCharacterWidth = fontInfo.typicalHalfwidthCharacterWidth;
|
||||
this.lineHeight = options.get(EditorOption.lineHeight);
|
||||
@@ -850,6 +851,11 @@ export class Minimap extends ViewPart {
|
||||
charWidth: number): void {
|
||||
const y = (lineNumber - layout.startLineNumber) * lineHeight;
|
||||
|
||||
// Skip rendering the line if it's vertically outside our viewport
|
||||
if (y + height < 0 || y > this._options.canvasOuterHeight) {
|
||||
return;
|
||||
}
|
||||
|
||||
// Cache line offset data so that it is only read once per line
|
||||
let lineIndexToXOffset = lineOffsetMap.get(lineNumber);
|
||||
const isFirstDecorationForLine = !lineIndexToXOffset;
|
||||
@@ -900,6 +906,7 @@ export class Minimap extends ViewPart {
|
||||
|
||||
private renderLines(layout: MinimapLayout): RenderData {
|
||||
const renderMinimap = this._options.renderMinimap;
|
||||
const charRenderer = this._options.charRenderer();
|
||||
const startLineNumber = layout.startLineNumber;
|
||||
const endLineNumber = layout.endLineNumber;
|
||||
const minimapLineHeight = getMinimapLineHeight(renderMinimap, this._options.fontScale);
|
||||
@@ -941,7 +948,7 @@ export class Minimap extends ViewPart {
|
||||
useLighterFont,
|
||||
renderMinimap,
|
||||
this._tokensColorTracker,
|
||||
this._options.charRenderer,
|
||||
charRenderer,
|
||||
dy,
|
||||
tabSize,
|
||||
lineInfo.data[lineIndex]!,
|
||||
|
||||
@@ -874,6 +874,7 @@ export class CodeEditorWidget extends Disposable implements editorBrowser.ICodeE
|
||||
|
||||
public onHide(): void {
|
||||
this._modelData?.view.refreshFocusState();
|
||||
this._focusTracker.refreshState();
|
||||
}
|
||||
|
||||
public getContribution<T extends editorCommon.IEditorContribution>(id: string): T {
|
||||
@@ -1806,6 +1807,12 @@ class CodeEditorWidgetFocusTracker extends Disposable {
|
||||
public hasFocus(): boolean {
|
||||
return this._hasFocus;
|
||||
}
|
||||
|
||||
public refreshState(): void {
|
||||
if (this._domFocusTracker.refreshState) {
|
||||
this._domFocusTracker.refreshState();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
const squigglyStart = encodeURIComponent(`<svg xmlns='http://www.w3.org/2000/svg' viewBox='0 0 6 3' enable-background='new 0 0 6 3' height='3' width='6'><g fill='`);
|
||||
|
||||
@@ -128,12 +128,13 @@ class VisualEditorState {
|
||||
this.inlineDiffMargins = [];
|
||||
for (let i = 0, length = newDecorations.zones.length; i < length; i++) {
|
||||
const viewZone = <editorBrowser.IViewZone>newDecorations.zones[i];
|
||||
viewZone.suppressMouseDown = false;
|
||||
viewZone.suppressMouseDown = true;
|
||||
let zoneId = viewChangeAccessor.addZone(viewZone);
|
||||
this._zones.push(zoneId);
|
||||
this._zonesMap[String(zoneId)] = true;
|
||||
|
||||
if (newDecorations.zones[i].diff && viewZone.marginDomNode && this._clipboardService) {
|
||||
viewZone.suppressMouseDown = false;
|
||||
this.inlineDiffMargins.push(new InlineDiffMargin(zoneId, viewZone.marginDomNode, editor, newDecorations.zones[i].diff!, this._contextMenuService, this._clipboardService));
|
||||
}
|
||||
}
|
||||
|
||||
@@ -263,6 +263,13 @@ function migrateOptions(options: IEditorOptions): void {
|
||||
} else if (<any>autoIndent === false) {
|
||||
options.autoIndent = 'advanced';
|
||||
}
|
||||
|
||||
const matchBrackets = options.matchBrackets;
|
||||
if (<any>matchBrackets === true) {
|
||||
options.matchBrackets = 'always';
|
||||
} else if (<any>matchBrackets === false) {
|
||||
options.matchBrackets = 'never';
|
||||
}
|
||||
}
|
||||
|
||||
function deepCloneAndMigrateOptions(_options: IEditorOptions): IEditorOptions {
|
||||
|
||||
@@ -481,9 +481,9 @@ export interface IEditorOptions {
|
||||
showFoldingControls?: 'always' | 'mouseover';
|
||||
/**
|
||||
* Enable highlighting of matching brackets.
|
||||
* Defaults to true.
|
||||
* Defaults to 'always'.
|
||||
*/
|
||||
matchBrackets?: boolean;
|
||||
matchBrackets?: 'never' | 'near' | 'always';
|
||||
/**
|
||||
* Enable rendering of whitespace.
|
||||
* Defaults to none.
|
||||
@@ -2271,7 +2271,7 @@ class EditorRulers extends SimpleEditorOption<EditorOption.rulers, number[]> {
|
||||
for (let value of input) {
|
||||
rulers.push(EditorIntOption.clampedInt(value, 0, 0, 10000));
|
||||
}
|
||||
rulers.sort();
|
||||
rulers.sort((a, b) => a - b);
|
||||
return rulers;
|
||||
}
|
||||
return this.defaultValue;
|
||||
@@ -3356,9 +3356,11 @@ export const EditorOptions = {
|
||||
EditorOption.links, 'links', true,
|
||||
{ description: nls.localize('links', "Controls whether the editor should detect links and make them clickable.") }
|
||||
)),
|
||||
matchBrackets: register(new EditorBooleanOption(
|
||||
EditorOption.matchBrackets, 'matchBrackets', true,
|
||||
{ description: nls.localize('matchBrackets', "Highlight matching brackets when one of them is selected.") }
|
||||
matchBrackets: register(new EditorStringEnumOption(
|
||||
EditorOption.matchBrackets, 'matchBrackets',
|
||||
'always' as 'never' | 'near' | 'always',
|
||||
['always', 'near', 'never'] as const,
|
||||
{ description: nls.localize('matchBrackets', "Highlight matching brackets.") }
|
||||
)),
|
||||
minimap: register(new EditorMinimap()),
|
||||
mouseStyle: register(new EditorStringEnumOption(
|
||||
|
||||
@@ -898,7 +898,7 @@ export interface ITextModel {
|
||||
* @param position The position at which to start the search.
|
||||
* @internal
|
||||
*/
|
||||
findEnclosingBrackets(position: IPosition): [Range, Range] | null;
|
||||
findEnclosingBrackets(position: IPosition, maxDuration?: number): [Range, Range] | null;
|
||||
|
||||
/**
|
||||
* Given a `position`, if the position is on top or near a bracket,
|
||||
|
||||
@@ -34,6 +34,7 @@ import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||
import { VSBufferReadableStream, VSBuffer } from 'vs/base/common/buffer';
|
||||
import { TokensStore, MultilineTokens, countEOL, MultilineTokens2, TokensStore2 } from 'vs/editor/common/model/tokensStore';
|
||||
import { Color } from 'vs/base/common/color';
|
||||
import { Constants } from 'vs/base/common/uint';
|
||||
|
||||
function createTextBufferBuilder() {
|
||||
return new PieceTreeTextBufferBuilder();
|
||||
@@ -2341,16 +2342,21 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
return null;
|
||||
}
|
||||
|
||||
public findEnclosingBrackets(_position: IPosition): [Range, Range] | null {
|
||||
public findEnclosingBrackets(_position: IPosition, maxDuration = Constants.MAX_SAFE_SMALL_INTEGER): [Range, Range] | null {
|
||||
const position = this.validatePosition(_position);
|
||||
const lineCount = this.getLineCount();
|
||||
const savedCounts = new Map<number, number[]>();
|
||||
|
||||
let counts: number[] = [];
|
||||
const resetCounts = (modeBrackets: RichEditBrackets | null) => {
|
||||
counts = [];
|
||||
for (let i = 0, len = modeBrackets ? modeBrackets.brackets.length : 0; i < len; i++) {
|
||||
counts[i] = 0;
|
||||
const resetCounts = (languageId: number, modeBrackets: RichEditBrackets | null) => {
|
||||
if (!savedCounts.has(languageId)) {
|
||||
let tmp = [];
|
||||
for (let i = 0, len = modeBrackets ? modeBrackets.brackets.length : 0; i < len; i++) {
|
||||
tmp[i] = 0;
|
||||
}
|
||||
savedCounts.set(languageId, tmp);
|
||||
}
|
||||
counts = savedCounts.get(languageId)!;
|
||||
};
|
||||
const searchInRange = (modeBrackets: RichEditBrackets, lineNumber: number, lineText: string, searchStartOffset: number, searchEndOffset: number): [Range, Range] | null => {
|
||||
while (true) {
|
||||
@@ -2380,7 +2386,12 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
|
||||
let languageId: LanguageId = -1;
|
||||
let modeBrackets: RichEditBrackets | null = null;
|
||||
const startTime = Date.now();
|
||||
for (let lineNumber = position.lineNumber; lineNumber <= lineCount; lineNumber++) {
|
||||
const elapsedTime = Date.now() - startTime;
|
||||
if (elapsedTime > maxDuration) {
|
||||
return null;
|
||||
}
|
||||
const lineTokens = this._getLineTokens(lineNumber);
|
||||
const tokenCount = lineTokens.getCount();
|
||||
const lineText = this._buffer.getLineContent(lineNumber);
|
||||
@@ -2396,7 +2407,7 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
if (languageId !== tokenLanguageId) {
|
||||
languageId = tokenLanguageId;
|
||||
modeBrackets = LanguageConfigurationRegistry.getBracketsSupport(languageId);
|
||||
resetCounts(modeBrackets);
|
||||
resetCounts(languageId, modeBrackets);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2415,7 +2426,7 @@ export class TextModel extends Disposable implements model.ITextModel {
|
||||
}
|
||||
languageId = tokenLanguageId;
|
||||
modeBrackets = LanguageConfigurationRegistry.getBracketsSupport(languageId);
|
||||
resetCounts(modeBrackets);
|
||||
resetCounts(languageId, modeBrackets);
|
||||
}
|
||||
|
||||
const searchInToken = (!!modeBrackets && !ignoreBracketsInToken(lineTokens.getStandardTokenType(tokenIndex)));
|
||||
|
||||
@@ -121,7 +121,7 @@ export interface IEncodedTokens {
|
||||
getMetadata(tokenIndex: number): number;
|
||||
|
||||
clear(): void;
|
||||
acceptDeleteRange(startDeltaLine: number, startCharacter: number, endDeltaLine: number, endCharacter: number): void;
|
||||
acceptDeleteRange(horizontalShiftForFirstLineTokens: number, startDeltaLine: number, startCharacter: number, endDeltaLine: number, endCharacter: number): void;
|
||||
acceptInsertText(deltaLine: number, character: number, eolCount: number, firstLineLength: number, lastLineLength: number, firstCharCode: number): void;
|
||||
}
|
||||
|
||||
@@ -173,7 +173,7 @@ export class SparseEncodedTokens implements IEncodedTokens {
|
||||
this._tokenCount = 0;
|
||||
}
|
||||
|
||||
public acceptDeleteRange(startDeltaLine: number, startCharacter: number, endDeltaLine: number, endCharacter: number): void {
|
||||
public acceptDeleteRange(horizontalShiftForFirstLineTokens: number, startDeltaLine: number, startCharacter: number, endDeltaLine: number, endCharacter: number): void {
|
||||
// This is a bit complex, here are the cases I used to think about this:
|
||||
//
|
||||
// 1. The token starts before the deletion range
|
||||
@@ -292,9 +292,13 @@ export class SparseEncodedTokens implements IEncodedTokens {
|
||||
tokenDeltaLine -= deletedLineCount;
|
||||
} else if (tokenDeltaLine === endDeltaLine && tokenStartCharacter >= endCharacter) {
|
||||
// 4. (continued) The token starts after the deletion range, on the last line where a deletion occurs
|
||||
if (horizontalShiftForFirstLineTokens && tokenDeltaLine === 0) {
|
||||
tokenStartCharacter += horizontalShiftForFirstLineTokens;
|
||||
tokenEndCharacter += horizontalShiftForFirstLineTokens;
|
||||
}
|
||||
tokenDeltaLine -= deletedLineCount;
|
||||
tokenStartCharacter -= endCharacter;
|
||||
tokenEndCharacter -= endCharacter;
|
||||
tokenStartCharacter -= (endCharacter - startCharacter);
|
||||
tokenEndCharacter -= (endCharacter - startCharacter);
|
||||
} else {
|
||||
throw new Error(`Not possible!`);
|
||||
}
|
||||
@@ -373,8 +377,8 @@ export class SparseEncodedTokens implements IEncodedTokens {
|
||||
}
|
||||
}
|
||||
// => the token must move and keep its size constant
|
||||
tokenDeltaLine += eolCount;
|
||||
if (tokenDeltaLine === deltaLine) {
|
||||
tokenDeltaLine += eolCount;
|
||||
// this token is on the line where the insertion is taking place
|
||||
if (eolCount === 0) {
|
||||
tokenStartCharacter += firstLineLength;
|
||||
@@ -384,6 +388,8 @@ export class SparseEncodedTokens implements IEncodedTokens {
|
||||
tokenStartCharacter = lastLineLength + (tokenStartCharacter - character);
|
||||
tokenEndCharacter = tokenStartCharacter + tokenLength;
|
||||
}
|
||||
} else {
|
||||
tokenDeltaLine += eolCount;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -527,9 +533,9 @@ export class MultilineTokens2 {
|
||||
const deletedBefore = -firstLineIndex;
|
||||
this.startLineNumber -= deletedBefore;
|
||||
|
||||
this.tokens.acceptDeleteRange(0, 0, lastLineIndex, range.endColumn - 1);
|
||||
this.tokens.acceptDeleteRange(range.startColumn - 1, 0, 0, lastLineIndex, range.endColumn - 1);
|
||||
} else {
|
||||
this.tokens.acceptDeleteRange(firstLineIndex, range.startColumn - 1, lastLineIndex, range.endColumn - 1);
|
||||
this.tokens.acceptDeleteRange(0, firstLineIndex, range.startColumn - 1, lastLineIndex, range.endColumn - 1);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1465,31 +1465,31 @@ export interface CodeLensProvider {
|
||||
resolveCodeLens?(model: model.ITextModel, codeLens: CodeLens, token: CancellationToken): ProviderResult<CodeLens>;
|
||||
}
|
||||
|
||||
export interface SemanticColoringLegend {
|
||||
export interface SemanticTokensLegend {
|
||||
readonly tokenTypes: string[];
|
||||
readonly tokenModifiers: string[];
|
||||
}
|
||||
|
||||
export interface SemanticColoringArea {
|
||||
/**
|
||||
* The zero-based line value where this token block begins.
|
||||
*/
|
||||
readonly line: number;
|
||||
/**
|
||||
* The actual token block encoded data.
|
||||
*/
|
||||
export interface SemanticTokens {
|
||||
readonly resultId?: string;
|
||||
readonly data: Uint32Array;
|
||||
|
||||
}
|
||||
|
||||
export interface SemanticColoring {
|
||||
readonly areas: SemanticColoringArea[];
|
||||
dispose(): void;
|
||||
export interface SemanticTokensEdit {
|
||||
readonly start: number;
|
||||
readonly deleteCount: number;
|
||||
readonly data?: Uint32Array;
|
||||
}
|
||||
|
||||
export interface SemanticColoringProvider {
|
||||
getLegend(): SemanticColoringLegend;
|
||||
provideSemanticColoring(model: model.ITextModel, token: CancellationToken): ProviderResult<SemanticColoring>;
|
||||
export interface SemanticTokensEdits {
|
||||
readonly resultId?: string;
|
||||
readonly edits: SemanticTokensEdit[];
|
||||
}
|
||||
|
||||
export interface SemanticTokensProvider {
|
||||
getLegend(): SemanticTokensLegend;
|
||||
provideSemanticTokens(model: model.ITextModel, lastResultId: string | null, ranges: Range[] | null, token: CancellationToken): ProviderResult<SemanticTokens | SemanticTokensEdits>;
|
||||
releaseSemanticTokens(resultId: string | undefined): void;
|
||||
}
|
||||
|
||||
// --- feature registries ------
|
||||
@@ -1597,7 +1597,7 @@ export const FoldingRangeProviderRegistry = new LanguageFeatureRegistry<FoldingR
|
||||
/**
|
||||
* @internal
|
||||
*/
|
||||
export const SemanticColoringProviderRegistry = new LanguageFeatureRegistry<SemanticColoringProvider>();
|
||||
export const SemanticTokensProviderRegistry = new LanguageFeatureRegistry<SemanticTokensProvider>();
|
||||
|
||||
/**
|
||||
* @internal
|
||||
|
||||
@@ -17,6 +17,7 @@ import { IMarkerDecorationsService } from 'vs/editor/common/services/markersDeco
|
||||
import { Schemas } from 'vs/base/common/network';
|
||||
import { Emitter, Event } from 'vs/base/common/event';
|
||||
import { withUndefinedAsNull } from 'vs/base/common/types';
|
||||
import { minimapWarning, minimapError } from 'vs/platform/theme/common/colorRegistry';
|
||||
|
||||
function MODEL_ID(resource: URI): string {
|
||||
return resource.toString();
|
||||
@@ -205,7 +206,7 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
|
||||
color = themeColorFromId(overviewRulerWarning);
|
||||
zIndex = 20;
|
||||
minimap = {
|
||||
color,
|
||||
color: themeColorFromId(minimapWarning),
|
||||
position: MinimapPosition.Inline
|
||||
};
|
||||
break;
|
||||
@@ -220,7 +221,7 @@ export class MarkerDecorationsService extends Disposable implements IMarkerDecor
|
||||
color = themeColorFromId(overviewRulerError);
|
||||
zIndex = 30;
|
||||
minimap = {
|
||||
color,
|
||||
color: themeColorFromId(minimapError),
|
||||
position: MinimapPosition.Inline
|
||||
};
|
||||
break;
|
||||
|
||||
@@ -14,7 +14,7 @@ import { Range } from 'vs/editor/common/core/range';
|
||||
import { DefaultEndOfLine, EndOfLinePreference, EndOfLineSequence, IIdentifiedSingleEditOperation, ITextBuffer, ITextBufferFactory, ITextModel, ITextModelCreationOptions } from 'vs/editor/common/model';
|
||||
import { TextModel, createTextBuffer } from 'vs/editor/common/model/textModel';
|
||||
import { IModelLanguageChangedEvent, IModelContentChangedEvent } from 'vs/editor/common/model/textModelEvents';
|
||||
import { LanguageIdentifier, SemanticColoringProviderRegistry, SemanticColoringProvider, SemanticColoring, SemanticColoringLegend } from 'vs/editor/common/modes';
|
||||
import { LanguageIdentifier, SemanticTokensProviderRegistry, SemanticTokensProvider, SemanticTokensLegend, SemanticTokens, SemanticTokensEdits } from 'vs/editor/common/modes';
|
||||
import { PLAINTEXT_LANGUAGE_IDENTIFIER } from 'vs/editor/common/modes/modesRegistry';
|
||||
import { ILanguageSelection } from 'vs/editor/common/services/modeService';
|
||||
import { IModelService } from 'vs/editor/common/services/modelService';
|
||||
@@ -459,22 +459,22 @@ class SemanticColoringFeature extends Disposable {
|
||||
|
||||
class SemanticStyling extends Disposable {
|
||||
|
||||
private _caches: WeakMap<SemanticColoringProvider, SemanticColoringProviderStyling>;
|
||||
private _caches: WeakMap<SemanticTokensProvider, SemanticColoringProviderStyling>;
|
||||
|
||||
constructor(
|
||||
private readonly _themeService: IThemeService
|
||||
) {
|
||||
super();
|
||||
this._caches = new WeakMap<SemanticColoringProvider, SemanticColoringProviderStyling>();
|
||||
this._caches = new WeakMap<SemanticTokensProvider, SemanticColoringProviderStyling>();
|
||||
if (this._themeService) {
|
||||
// workaround for tests which use undefined... :/
|
||||
this._register(this._themeService.onThemeChange(() => {
|
||||
this._caches = new WeakMap<SemanticColoringProvider, SemanticColoringProviderStyling>();
|
||||
this._caches = new WeakMap<SemanticTokensProvider, SemanticColoringProviderStyling>();
|
||||
}));
|
||||
}
|
||||
}
|
||||
|
||||
public get(provider: SemanticColoringProvider): SemanticColoringProviderStyling {
|
||||
public get(provider: SemanticTokensProvider): SemanticColoringProviderStyling {
|
||||
if (!this._caches.has(provider)) {
|
||||
this._caches.set(provider, new SemanticColoringProviderStyling(provider.getLegend(), this._themeService));
|
||||
}
|
||||
@@ -580,7 +580,7 @@ class SemanticColoringProviderStyling {
|
||||
private readonly _hashTable: HashTable;
|
||||
|
||||
constructor(
|
||||
private readonly _legend: SemanticColoringLegend,
|
||||
private readonly _legend: SemanticTokensLegend,
|
||||
private readonly _themeService: IThemeService
|
||||
) {
|
||||
this._hashTable = new HashTable();
|
||||
@@ -611,13 +611,39 @@ class SemanticColoringProviderStyling {
|
||||
}
|
||||
}
|
||||
|
||||
const enum SemanticColoringConstants {
|
||||
/**
|
||||
* Let's aim at having 8KB buffers if possible...
|
||||
* So that would be 8192 / (5 * 4) = 409.6 tokens per area
|
||||
*/
|
||||
DesiredTokensPerArea = 400,
|
||||
|
||||
/**
|
||||
* Try to keep the total number of areas under 1024 if possible,
|
||||
* simply compensate by having more tokens per area...
|
||||
*/
|
||||
DesiredMaxAreas = 1024,
|
||||
}
|
||||
|
||||
class SemanticTokensResponse {
|
||||
constructor(
|
||||
private readonly _provider: SemanticTokensProvider,
|
||||
public readonly resultId: string | undefined,
|
||||
public readonly data: Uint32Array
|
||||
) { }
|
||||
|
||||
public dispose(): void {
|
||||
this._provider.releaseSemanticTokens(this.resultId);
|
||||
}
|
||||
}
|
||||
|
||||
class ModelSemanticColoring extends Disposable {
|
||||
|
||||
private _isDisposed: boolean;
|
||||
private readonly _model: ITextModel;
|
||||
private readonly _semanticStyling: SemanticStyling;
|
||||
private readonly _fetchSemanticTokens: RunOnceScheduler;
|
||||
private _currentResponse: SemanticColoring | null;
|
||||
private _currentResponse: SemanticTokensResponse | null;
|
||||
private _currentRequestCancellationTokenSource: CancellationTokenSource | null;
|
||||
|
||||
constructor(model: ITextModel, themeService: IThemeService, stylingProvider: SemanticStyling) {
|
||||
@@ -626,17 +652,21 @@ class ModelSemanticColoring extends Disposable {
|
||||
this._isDisposed = false;
|
||||
this._model = model;
|
||||
this._semanticStyling = stylingProvider;
|
||||
this._fetchSemanticTokens = this._register(new RunOnceScheduler(() => this._fetchSemanticTokensNow(), 500));
|
||||
this._fetchSemanticTokens = this._register(new RunOnceScheduler(() => this._fetchSemanticTokensNow(), 300));
|
||||
this._currentResponse = null;
|
||||
this._currentRequestCancellationTokenSource = null;
|
||||
|
||||
this._register(this._model.onDidChangeContent(e => this._fetchSemanticTokens.schedule()));
|
||||
this._register(SemanticColoringProviderRegistry.onDidChange(e => this._fetchSemanticTokens.schedule()));
|
||||
this._register(this._model.onDidChangeContent(e => {
|
||||
if (!this._fetchSemanticTokens.isScheduled()) {
|
||||
this._fetchSemanticTokens.schedule();
|
||||
}
|
||||
}));
|
||||
this._register(SemanticTokensProviderRegistry.onDidChange(e => this._fetchSemanticTokens.schedule()));
|
||||
if (themeService) {
|
||||
// workaround for tests which use undefined... :/
|
||||
this._register(themeService.onThemeChange(_ => {
|
||||
// clear out existing tokens
|
||||
this._setSemanticTokens(null, null, []);
|
||||
this._setSemanticTokens(null, null, null, []);
|
||||
this._fetchSemanticTokens.schedule();
|
||||
}));
|
||||
}
|
||||
@@ -673,90 +703,208 @@ class ModelSemanticColoring extends Disposable {
|
||||
});
|
||||
|
||||
const styling = this._semanticStyling.get(provider);
|
||||
const request = Promise.resolve(provider.provideSemanticColoring(this._model, this._currentRequestCancellationTokenSource.token));
|
||||
|
||||
const lastResultId = this._currentResponse ? this._currentResponse.resultId || null : null;
|
||||
const request = Promise.resolve(provider.provideSemanticTokens(this._model, lastResultId, null, this._currentRequestCancellationTokenSource.token));
|
||||
|
||||
request.then((res) => {
|
||||
this._currentRequestCancellationTokenSource = null;
|
||||
contentChangeListener.dispose();
|
||||
this._setSemanticTokens(res || null, styling, pendingChanges);
|
||||
this._setSemanticTokens(provider, res || null, styling, pendingChanges);
|
||||
}, (err) => {
|
||||
errors.onUnexpectedError(err);
|
||||
this._currentRequestCancellationTokenSource = null;
|
||||
contentChangeListener.dispose();
|
||||
this._setSemanticTokens(null, styling, pendingChanges);
|
||||
this._setSemanticTokens(provider, null, styling, pendingChanges);
|
||||
});
|
||||
}
|
||||
|
||||
private _setSemanticTokens(tokens: SemanticColoring | null, styling: SemanticColoringProviderStyling | null, pendingChanges: IModelContentChangedEvent[]): void {
|
||||
private static _isSemanticTokens(v: SemanticTokens | SemanticTokensEdits): v is SemanticTokens {
|
||||
return v && !!((<SemanticTokens>v).data);
|
||||
}
|
||||
|
||||
private static _isSemanticTokensEdits(v: SemanticTokens | SemanticTokensEdits): v is SemanticTokensEdits {
|
||||
return v && Array.isArray((<SemanticTokensEdits>v).edits);
|
||||
}
|
||||
|
||||
private static _copy(src: Uint32Array, srcOffset: number, dest: Uint32Array, destOffset: number, length: number): void {
|
||||
for (let i = 0; i < length; i++) {
|
||||
dest[destOffset + i] = src[srcOffset + i];
|
||||
}
|
||||
}
|
||||
|
||||
private _setSemanticTokens(provider: SemanticTokensProvider | null, tokens: SemanticTokens | SemanticTokensEdits | null, styling: SemanticColoringProviderStyling | null, pendingChanges: IModelContentChangedEvent[]): void {
|
||||
const currentResponse = this._currentResponse;
|
||||
if (this._currentResponse) {
|
||||
this._currentResponse.dispose();
|
||||
this._currentResponse = null;
|
||||
}
|
||||
if (this._isDisposed) {
|
||||
// disposed!
|
||||
if (tokens) {
|
||||
tokens.dispose();
|
||||
if (provider && tokens) {
|
||||
provider.releaseSemanticTokens(tokens.resultId);
|
||||
}
|
||||
return;
|
||||
}
|
||||
this._currentResponse = tokens;
|
||||
if (!this._currentResponse || !styling) {
|
||||
if (!provider || !tokens || !styling) {
|
||||
this._model.setSemanticTokens(null);
|
||||
return;
|
||||
}
|
||||
|
||||
const result: MultilineTokens2[] = [];
|
||||
for (const area of this._currentResponse.areas) {
|
||||
const srcTokens = area.data;
|
||||
const tokenCount = srcTokens.length / 5;
|
||||
let destTokens = new Uint32Array(4 * tokenCount);
|
||||
let destOffset = 0;
|
||||
for (let i = 0; i < tokenCount; i++) {
|
||||
const srcOffset = 5 * i;
|
||||
const deltaLine = srcTokens[srcOffset];
|
||||
const startCharacter = srcTokens[srcOffset + 1];
|
||||
const endCharacter = srcTokens[srcOffset + 2];
|
||||
const tokenTypeIndex = srcTokens[srcOffset + 3];
|
||||
const tokenModifierSet = srcTokens[srcOffset + 4];
|
||||
const metadata = styling.getMetadata(tokenTypeIndex, tokenModifierSet);
|
||||
if (metadata !== Constants.NO_STYLING) {
|
||||
destTokens[destOffset] = deltaLine;
|
||||
destTokens[destOffset + 1] = startCharacter;
|
||||
destTokens[destOffset + 2] = endCharacter;
|
||||
destTokens[destOffset + 3] = metadata;
|
||||
destOffset += 4;
|
||||
if (ModelSemanticColoring._isSemanticTokensEdits(tokens)) {
|
||||
if (!currentResponse) {
|
||||
// not possible!
|
||||
this._model.setSemanticTokens(null);
|
||||
return;
|
||||
}
|
||||
if (tokens.edits.length === 0) {
|
||||
// nothing to do!
|
||||
tokens = {
|
||||
resultId: tokens.resultId,
|
||||
data: currentResponse.data
|
||||
};
|
||||
} else {
|
||||
let deltaLength = 0;
|
||||
for (const edit of tokens.edits) {
|
||||
deltaLength += (edit.data ? edit.data.length : 0) - edit.deleteCount;
|
||||
}
|
||||
}
|
||||
|
||||
if (destOffset !== destTokens.length) {
|
||||
destTokens = destTokens.subarray(0, destOffset);
|
||||
const srcData = currentResponse.data;
|
||||
const destData = new Uint32Array(srcData.length + deltaLength);
|
||||
|
||||
let srcLastStart = srcData.length;
|
||||
let destLastStart = destData.length;
|
||||
for (let i = tokens.edits.length - 1; i >= 0; i--) {
|
||||
const edit = tokens.edits[i];
|
||||
|
||||
const copyCount = srcLastStart - (edit.start + edit.deleteCount);
|
||||
if (copyCount > 0) {
|
||||
ModelSemanticColoring._copy(srcData, srcLastStart - copyCount, destData, destLastStart - copyCount, copyCount);
|
||||
destLastStart -= copyCount;
|
||||
}
|
||||
|
||||
if (edit.data) {
|
||||
ModelSemanticColoring._copy(edit.data, 0, destData, destLastStart - edit.data.length, edit.data.length);
|
||||
destLastStart -= edit.data.length;
|
||||
}
|
||||
|
||||
srcLastStart = edit.start;
|
||||
}
|
||||
|
||||
if (srcLastStart > 0) {
|
||||
ModelSemanticColoring._copy(srcData, 0, destData, 0, srcLastStart);
|
||||
}
|
||||
|
||||
tokens = {
|
||||
resultId: tokens.resultId,
|
||||
data: destData
|
||||
};
|
||||
}
|
||||
const tokens = new MultilineTokens2(area.line, new SparseEncodedTokens(destTokens));
|
||||
result.push(tokens);
|
||||
}
|
||||
|
||||
// Adjust incoming semantic tokens
|
||||
if (pendingChanges.length > 0) {
|
||||
// More changes occurred while the request was running
|
||||
// We need to:
|
||||
// 1. Adjust incoming semantic tokens
|
||||
// 2. Request them again
|
||||
for (const change of pendingChanges) {
|
||||
for (const area of result) {
|
||||
for (const singleChange of change.changes) {
|
||||
area.applyEdit(singleChange.range, singleChange.text);
|
||||
if (ModelSemanticColoring._isSemanticTokens(tokens)) {
|
||||
|
||||
this._currentResponse = new SemanticTokensResponse(provider, tokens.resultId, tokens.data);
|
||||
|
||||
const srcData = tokens.data;
|
||||
const tokenCount = (tokens.data.length / 5) | 0;
|
||||
const tokensPerArea = Math.max(Math.ceil(tokenCount / SemanticColoringConstants.DesiredMaxAreas), SemanticColoringConstants.DesiredTokensPerArea);
|
||||
|
||||
const result: MultilineTokens2[] = [];
|
||||
|
||||
let tokenIndex = 0;
|
||||
let lastLineNumber = 1;
|
||||
let lastStartCharacter = 0;
|
||||
while (tokenIndex < tokenCount) {
|
||||
const tokenStartIndex = tokenIndex;
|
||||
let tokenEndIndex = Math.min(tokenStartIndex + tokensPerArea, tokenCount);
|
||||
|
||||
// Keep tokens on the same line in the same area...
|
||||
if (tokenEndIndex < tokenCount) {
|
||||
|
||||
let smallTokenEndIndex = tokenEndIndex;
|
||||
while (smallTokenEndIndex - 1 > tokenStartIndex && srcData[5 * smallTokenEndIndex] === 0) {
|
||||
smallTokenEndIndex--;
|
||||
}
|
||||
|
||||
if (smallTokenEndIndex - 1 === tokenStartIndex) {
|
||||
// there are so many tokens on this line that our area would be empty, we must now go right
|
||||
let bigTokenEndIndex = tokenEndIndex;
|
||||
while (bigTokenEndIndex + 1 < tokenCount && srcData[5 * bigTokenEndIndex] === 0) {
|
||||
bigTokenEndIndex++;
|
||||
}
|
||||
tokenEndIndex = bigTokenEndIndex;
|
||||
} else {
|
||||
tokenEndIndex = smallTokenEndIndex;
|
||||
}
|
||||
}
|
||||
|
||||
let destData = new Uint32Array((tokenEndIndex - tokenStartIndex) * 4);
|
||||
let destOffset = 0;
|
||||
let areaLine = 0;
|
||||
while (tokenIndex < tokenEndIndex) {
|
||||
const srcOffset = 5 * tokenIndex;
|
||||
const deltaLine = srcData[srcOffset];
|
||||
const deltaCharacter = srcData[srcOffset + 1];
|
||||
const lineNumber = lastLineNumber + deltaLine;
|
||||
const startCharacter = (deltaLine === 0 ? lastStartCharacter + deltaCharacter : deltaCharacter);
|
||||
const length = srcData[srcOffset + 2];
|
||||
const tokenTypeIndex = srcData[srcOffset + 3];
|
||||
const tokenModifierSet = srcData[srcOffset + 4];
|
||||
const metadata = styling.getMetadata(tokenTypeIndex, tokenModifierSet);
|
||||
|
||||
if (metadata !== Constants.NO_STYLING) {
|
||||
if (areaLine === 0) {
|
||||
areaLine = lineNumber;
|
||||
}
|
||||
destData[destOffset] = lineNumber - areaLine;
|
||||
destData[destOffset + 1] = startCharacter;
|
||||
destData[destOffset + 2] = startCharacter + length;
|
||||
destData[destOffset + 3] = metadata;
|
||||
destOffset += 4;
|
||||
}
|
||||
|
||||
lastLineNumber = lineNumber;
|
||||
lastStartCharacter = startCharacter;
|
||||
tokenIndex++;
|
||||
}
|
||||
|
||||
if (destOffset !== destData.length) {
|
||||
destData = destData.subarray(0, destOffset);
|
||||
}
|
||||
|
||||
const tokens = new MultilineTokens2(areaLine, new SparseEncodedTokens(destData));
|
||||
result.push(tokens);
|
||||
}
|
||||
|
||||
this._fetchSemanticTokens.schedule();
|
||||
// Adjust incoming semantic tokens
|
||||
if (pendingChanges.length > 0) {
|
||||
// More changes occurred while the request was running
|
||||
// We need to:
|
||||
// 1. Adjust incoming semantic tokens
|
||||
// 2. Request them again
|
||||
for (const change of pendingChanges) {
|
||||
for (const area of result) {
|
||||
for (const singleChange of change.changes) {
|
||||
area.applyEdit(singleChange.range, singleChange.text);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (!this._fetchSemanticTokens.isScheduled()) {
|
||||
this._fetchSemanticTokens.schedule();
|
||||
}
|
||||
}
|
||||
|
||||
this._model.setSemanticTokens(result);
|
||||
return;
|
||||
}
|
||||
|
||||
this._model.setSemanticTokens(result);
|
||||
this._model.setSemanticTokens(null);
|
||||
}
|
||||
|
||||
private _getSemanticColoringProvider(): SemanticColoringProvider | null {
|
||||
const result = SemanticColoringProviderRegistry.ordered(this._model);
|
||||
private _getSemanticColoringProvider(): SemanticTokensProvider | null {
|
||||
const result = SemanticTokensProviderRegistry.ordered(this._model);
|
||||
return (result.length > 0 ? result[0] : null);
|
||||
}
|
||||
}
|
||||
@@ -5,7 +5,7 @@
|
||||
|
||||
import * as nls from 'vs/nls';
|
||||
import { Color, RGBA } from 'vs/base/common/color';
|
||||
import { activeContrastBorder, editorBackground, editorForeground, registerColor, editorWarningForeground, editorInfoForeground, editorWarningBorder, editorInfoBorder, contrastBorder } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { activeContrastBorder, editorBackground, editorForeground, registerColor, editorWarningForeground, editorInfoForeground, editorWarningBorder, editorInfoBorder, contrastBorder, editorFindMatchHighlight } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
|
||||
|
||||
/**
|
||||
@@ -15,7 +15,7 @@ export const editorLineHighlight = registerColor('editor.lineHighlightBackground
|
||||
export const editorLineHighlightBorder = registerColor('editor.lineHighlightBorder', { dark: '#282828', light: '#eeeeee', hc: '#f38518' }, nls.localize('lineHighlightBorderBox', 'Background color for the border around the line at the cursor position.'));
|
||||
export const editorRangeHighlight = registerColor('editor.rangeHighlightBackground', { dark: '#ffffff0b', light: '#fdff0033', hc: null }, nls.localize('rangeHighlight', 'Background color of highlighted ranges, like by quick open and find features. The color must not be opaque so as not to hide underlying decorations.'), true);
|
||||
export const editorRangeHighlightBorder = registerColor('editor.rangeHighlightBorder', { dark: null, light: null, hc: activeContrastBorder }, nls.localize('rangeHighlightBorder', 'Background color of the border around highlighted ranges.'), true);
|
||||
export const editorSymbolHighlight = registerColor('editor.symbolHighlightBackground', { dark: editorRangeHighlight, light: editorRangeHighlight, hc: null }, nls.localize('symbolHighlight', 'Background color of highlighted symbol, like for go to definition or go next/previous symbol. The color must not be opaque so as not to hide underlying decorations.'), true);
|
||||
export const editorSymbolHighlight = registerColor('editor.symbolHighlightBackground', { dark: editorFindMatchHighlight, light: editorFindMatchHighlight, hc: null }, nls.localize('symbolHighlight', 'Background color of highlighted symbol, like for go to definition or go next/previous symbol. The color must not be opaque so as not to hide underlying decorations.'), true);
|
||||
export const editorSymbolHighlightBorder = registerColor('editor.symbolHighlightBorder', { dark: null, light: null, hc: activeContrastBorder }, nls.localize('symbolHighlightBorder', 'Background color of the border around highlighted symbols.'), true);
|
||||
|
||||
export const editorCursorForeground = registerColor('editorCursor.foreground', { dark: '#AEAFAD', light: Color.black, hc: Color.white }, nls.localize('caret', 'Color of the editor cursor.'));
|
||||
|
||||
@@ -116,7 +116,7 @@ export class BracketMatchingController extends Disposable implements editorCommo
|
||||
private _lastVersionId: number;
|
||||
private _decorations: string[];
|
||||
private readonly _updateBracketsSoon: RunOnceScheduler;
|
||||
private _matchBrackets: boolean;
|
||||
private _matchBrackets: 'never' | 'near' | 'always';
|
||||
|
||||
constructor(
|
||||
editor: ICodeEditor
|
||||
@@ -132,7 +132,7 @@ export class BracketMatchingController extends Disposable implements editorCommo
|
||||
this._updateBracketsSoon.schedule();
|
||||
this._register(editor.onDidChangeCursorPosition((e) => {
|
||||
|
||||
if (!this._matchBrackets) {
|
||||
if (this._matchBrackets === 'never') {
|
||||
// Early exit if nothing needs to be done!
|
||||
// Leave some form of early exit check here if you wish to continue being a cursor position change listener ;)
|
||||
return;
|
||||
@@ -153,12 +153,13 @@ export class BracketMatchingController extends Disposable implements editorCommo
|
||||
this._updateBracketsSoon.schedule();
|
||||
}));
|
||||
this._register(editor.onDidChangeConfiguration((e) => {
|
||||
this._matchBrackets = this._editor.getOption(EditorOption.matchBrackets);
|
||||
if (!this._matchBrackets && this._decorations.length > 0) {
|
||||
// Remove existing decorations if bracket matching is off
|
||||
if (e.hasChanged(EditorOption.matchBrackets)) {
|
||||
this._matchBrackets = this._editor.getOption(EditorOption.matchBrackets);
|
||||
this._decorations = this._editor.deltaDecorations(this._decorations, []);
|
||||
this._lastBracketsData = [];
|
||||
this._lastVersionId = 0;
|
||||
this._updateBracketsSoon.schedule();
|
||||
}
|
||||
this._updateBracketsSoon.schedule();
|
||||
}));
|
||||
}
|
||||
|
||||
@@ -262,7 +263,7 @@ export class BracketMatchingController extends Disposable implements editorCommo
|
||||
});
|
||||
|
||||
private _updateBrackets(): void {
|
||||
if (!this._matchBrackets) {
|
||||
if (this._matchBrackets === 'never') {
|
||||
return;
|
||||
}
|
||||
this._recomputeBrackets();
|
||||
@@ -332,8 +333,8 @@ export class BracketMatchingController extends Disposable implements editorCommo
|
||||
} else {
|
||||
let brackets = model.matchBracket(position);
|
||||
let options = BracketMatchingController._DECORATION_OPTIONS_WITH_OVERVIEW_RULER;
|
||||
if (!brackets) {
|
||||
brackets = model.findEnclosingBrackets(position);
|
||||
if (!brackets && this._matchBrackets === 'always') {
|
||||
brackets = model.findEnclosingBrackets(position, 20 /* give at most 20ms to compute */);
|
||||
options = BracketMatchingController._DECORATION_OPTIONS_WITHOUT_OVERVIEW_RULER;
|
||||
}
|
||||
newData[newDataLen++] = new BracketsData(position, brackets, options);
|
||||
|
||||
@@ -148,19 +148,29 @@ export class ContextMenuController implements IEditorContribution {
|
||||
// translate them into other actions
|
||||
for (let group of groups) {
|
||||
const [, actions] = group;
|
||||
let addedItems = 0;
|
||||
for (const action of actions) {
|
||||
if (action instanceof SubmenuItemAction) {
|
||||
const subActions = this._getMenuActions(model, action.item.submenu);
|
||||
if (subActions.length > 0) {
|
||||
result.push(new ContextSubMenu(action.label, subActions));
|
||||
addedItems++;
|
||||
}
|
||||
} else {
|
||||
result.push(action);
|
||||
addedItems++;
|
||||
}
|
||||
}
|
||||
result.push(new Separator());
|
||||
|
||||
if (addedItems) {
|
||||
result.push(new Separator());
|
||||
}
|
||||
}
|
||||
result.pop(); // remove last separator
|
||||
|
||||
if (result.length) {
|
||||
result.pop(); // remove last separator
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
|
||||
|
||||
@@ -7,7 +7,7 @@ import * as dom from 'vs/base/browser/dom';
|
||||
import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlightedLabel';
|
||||
import { IIdentityProvider, IKeyboardNavigationLabelProvider, IListVirtualDelegate } from 'vs/base/browser/ui/list/list';
|
||||
import { IDataSource, ITreeNode, ITreeRenderer, ITreeSorter, ITreeFilter } from 'vs/base/browser/ui/tree/tree';
|
||||
import { values, forEach } from 'vs/base/common/collections';
|
||||
import { values } from 'vs/base/common/collections';
|
||||
import { createMatches, FuzzyScore } from 'vs/base/common/filters';
|
||||
import 'vs/css!./media/outlineTree';
|
||||
import 'vs/css!./media/symbol-icons';
|
||||
@@ -22,6 +22,8 @@ import { MarkerSeverity } from 'vs/platform/markers/common/markers';
|
||||
import { IThemeService, registerThemingParticipant, ITheme, ICssStyleCollector } from 'vs/platform/theme/common/themeService';
|
||||
import { registerColor, listErrorForeground, listWarningForeground, foreground } from 'vs/platform/theme/common/colorRegistry';
|
||||
import { IdleValue } from 'vs/base/common/async';
|
||||
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
|
||||
import { URI } from 'vs/base/common/uri';
|
||||
|
||||
export type OutlineItem = OutlineGroup | OutlineElement;
|
||||
|
||||
@@ -278,27 +280,26 @@ export class OutlineFilter implements ITreeFilter<OutlineItem> {
|
||||
[SymbolKind.TypeParameter]: 'showTypeParameters',
|
||||
});
|
||||
|
||||
private readonly _filteredTypes = new Set<SymbolKind>();
|
||||
|
||||
constructor(
|
||||
private readonly _prefix: string,
|
||||
@IConfigurationService private readonly _configService: IConfigurationService,
|
||||
) {
|
||||
this.update();
|
||||
}
|
||||
|
||||
update() {
|
||||
this._filteredTypes.clear();
|
||||
forEach(OutlineFilter.configNameToKind, entry => {
|
||||
const key = `${this._prefix}.${entry.key}`;
|
||||
if (this._configService.getValue<boolean>(key) === false) {
|
||||
this._filteredTypes.add(entry.value);
|
||||
}
|
||||
});
|
||||
}
|
||||
@ITextResourceConfigurationService private readonly _textResourceConfigService: ITextResourceConfigurationService,
|
||||
) { }
|
||||
|
||||
filter(element: OutlineItem): boolean {
|
||||
return !(element instanceof OutlineElement) || !this._filteredTypes.has(element.symbol.kind);
|
||||
const outline = OutlineModel.get(element);
|
||||
let uri: URI | undefined;
|
||||
|
||||
if (outline) {
|
||||
uri = outline.textModel.uri;
|
||||
}
|
||||
|
||||
if (!(element instanceof OutlineElement)) {
|
||||
return true;
|
||||
}
|
||||
|
||||
const configName = OutlineFilter.kindToConfigName[element.symbol.kind];
|
||||
const configKey = `${this._prefix}.${configName}`;
|
||||
return this._textResourceConfigService.getValue(uri, configKey);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Loaded 100 of 257 files, more files were not shown because too many files have changed in this diff.
Show more
Reference in new issue
Block a user