Merge branch 'master' into feature/multi-cursor-on-search

This commit is contained in:
Rob Lourens
2019-11-12 14:22:12 -06:00
committed by GitHub
148 changed files with 2385 additions and 1408 deletions
+1 -1
View File
@@ -31,7 +31,7 @@
},
{
"name": "ms-vscode.references-view",
"version": "0.0.34",
"version": "0.0.35",
"repo": "https://github.com/Microsoft/vscode-reference-view",
"metadata": {
"id": "dc489f46-520d-4556-ae85-1f9eab3c412d",
+1 -1
View File
@@ -54,7 +54,7 @@ function createCompile(src: string, build: boolean, emitError?: boolean) {
const input = es.through();
const output = input
.pipe(utf8Filter)
.pipe(bom())
.pipe(bom()) // this is required to preserve BOM in test files that loose it otherwise
.pipe(utf8Filter.restore)
.pipe(tsFilter)
.pipe(util.loadSourcemaps())
+2 -2
View File
@@ -957,10 +957,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: "Open w&ith {#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: "Open w&ith {#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
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=%1 als Editor f
AddToPath=Zu PATH hinzufügen (nach dem Neustart verfügbar)
RunAfter=%1 nach der Installation ausführen
Other=Andere:
SourceFile=%1-Quelldatei
SourceFile=%1-Quelldatei
OpenWithCodeContextMenu=Mit %1 öffnen
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=Register %1 as an editor for supported file types
AddToPath=Add to PATH (requires shell restart)
RunAfter=Run %1 after installation
Other=Other:
SourceFile=%1 Source File
SourceFile=%1 Source File
OpenWithCodeContextMenu=Open with %1
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=Registrar %1 como editor para tipos de archivo admitidos
AddToPath=Agregar a PATH (disponible después de reiniciar)
RunAfter=Ejecutar %1 después de la instalación
Other=Otros:
SourceFile=Archivo de origen %1
SourceFile=Archivo de origen %1
OpenWithCodeContextMenu=Abrir con %1
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=Inscrire %1 en tant qu'
AddToPath=Ajouter à PATH (disponible après le redémarrage)
RunAfter=Exécuter %1 après l'installation
Other=Autre :
SourceFile=Fichier source %1
SourceFile=Fichier source %1
OpenWithCodeContextMenu=Ouvrir avec %1
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=%1 regisztr
AddToPath=Hozzáadás a PATH-hoz (újraindítás után lesz elérhető)
RunAfter=%1 indítása a telepítés után
Other=Egyéb:
SourceFile=%1 forrásfájl
SourceFile=%1 forrásfájl
OpenWithCodeContextMenu=Megnyitás a következővel: %1
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=Registra %1 come editor per i tipi di file supportati
AddToPath=Aggiungi a PATH (disponibile dopo il riavvio)
RunAfter=Esegui %1 dopo l'installazione
Other=Altro:
SourceFile=File di origine %1
SourceFile=File di origine %1
OpenWithCodeContextMenu=Apri con %1
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=
AddToPath=PATH への追加(再起動後に使用可能)
RunAfter=インストール後に %1 を実行する
Other=その他:
SourceFile=%1 ソース ファイル
SourceFile=%1 ソース ファイル
OpenWithCodeContextMenu=%1 で開く
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=%1
AddToPath=PATH에 추가(다시 시작한 후 사용 가능)
RunAfter=설치 후 %1 실행
Other=기타:
SourceFile=%1 원본 파일
SourceFile=%1 원본 파일
OpenWithCodeContextMenu=%1(으)로 열기
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=Registre %1 como um editor para tipos de arquivos suportados
AddToPath=Adicione em PATH (disponível após reiniciar)
RunAfter=Executar %1 após a instalação
Other=Outros:
SourceFile=Arquivo Fonte %1
SourceFile=Arquivo Fonte %1
OpenWithCodeContextMenu=Abrir com %1
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=
AddToPath=Добавить в PATH (доступно после перезагрузки)
RunAfter=Запустить %1 после установки
Other=Другое:
SourceFile=Исходный файл %1
SourceFile=Исходный файл %1
OpenWithCodeContextMenu=Открыть с помощью %1
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=%1 uygulamas
AddToPath=PATH'e ekle (yeniden başlattıktan sonra kullanılabilir)
RunAfter=Kurulumdan sonra %1 uygulamasını çalıştır.
Other=Diğer:
SourceFile=%1 Kaynak Dosyası
SourceFile=%1 Kaynak Dosyası
OpenWithCodeContextMenu=%1 İle Aç
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=
AddToPath=添加到 PATH (重启后生效)
RunAfter=安装后运行 %1
Other=其他:
SourceFile=%1 源文件
SourceFile=%1 源文件
OpenWithCodeContextMenu=通过 %1 打开
+2 -1
View File
@@ -5,4 +5,5 @@ AssociateWithFiles=
AddToPath=加入 PATH 中 (重新啟動後生效)
RunAfter=安裝後執行 %1
Other=其他:
SourceFile=%1 來源檔案
SourceFile=%1 來源檔案
OpenWithCodeContextMenu=以 %1 開啟
+2 -2
View File
@@ -6,11 +6,11 @@
"git": {
"name": "jeff-hykin/cpp-textmate-grammar",
"repositoryUrl": "https://github.com/jeff-hykin/cpp-textmate-grammar",
"commitHash": "d937b80a19706d518e5fe52357d7c50d34a26e60"
"commitHash": "fedd206d1b2803f31a278e9b5f098ce4bc76e532"
}
},
"license": "MIT",
"version": "1.14.11",
"version": "1.14.13",
"description": "The files syntaxes/c.json and syntaxes/c++.json were derived from https://github.com/atom/language-c which was originally converted from the C TextMate bundle https://github.com/textmate/c.tmbundle."
},
{
+2 -2
View File
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/d937b80a19706d518e5fe52357d7c50d34a26e60",
"version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/fedd206d1b2803f31a278e9b5f098ce4bc76e532",
"name": "C",
"scopeName": "source.c",
"patterns": [
@@ -1177,7 +1177,7 @@
]
},
"member_access": {
"match": "((?:[a-zA-Z_]\\w*|(?<=\\]|\\)))\\s*)(?:((?:\\.\\*|\\.))|((?:->\\*|->)))((?:[a-zA-Z_]\\w*\\s*(?:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*(\\b(?!(?:atomic_uint_least64_t|atomic_uint_least16_t|atomic_uint_least32_t|atomic_uint_least8_t|atomic_int_least16_t|atomic_uint_fast64_t|atomic_uint_fast32_t|atomic_int_least64_t|atomic_int_least32_t|pthread_rwlockattr_t|atomic_uint_fast16_t|pthread_mutexattr_t|atomic_int_fast16_t|atomic_uint_fast8_t|atomic_int_fast64_t|atomic_int_least8_t|atomic_int_fast32_t|atomic_int_fast8_t|pthread_condattr_t|atomic_uintptr_t|atomic_ptrdiff_t|pthread_rwlock_t|atomic_uintmax_t|pthread_mutex_t|atomic_intmax_t|atomic_intptr_t|atomic_char32_t|atomic_char16_t|pthread_attr_t|atomic_wchar_t|uint_least64_t|uint_least32_t|uint_least16_t|pthread_cond_t|pthread_once_t|uint_fast64_t|uint_fast16_t|atomic_size_t|uint_least8_t|int_least64_t|int_least32_t|int_least16_t|pthread_key_t|atomic_ullong|atomic_ushort|uint_fast32_t|atomic_schar|atomic_short|uint_fast8_t|int_fast64_t|int_fast32_t|int_fast16_t|atomic_ulong|atomic_llong|int_least8_t|atomic_uchar|memory_order|suseconds_t|int_fast8_t|atomic_bool|atomic_char|atomic_uint|atomic_long|atomic_int|useconds_t|_Imaginary|uintptr_t|pthread_t|in_addr_t|blksize_t|in_port_t|uintmax_t|uintmax_t|blkcnt_t|uint16_t|unsigned|_Complex|uint32_t|intptr_t|intmax_t|intmax_t|uint64_t|u_quad_t|int64_t|int32_t|ssize_t|caddr_t|clock_t|uint8_t|u_short|swblk_t|segsz_t|int16_t|fixpt_t|daddr_t|nlink_t|qaddr_t|size_t|time_t|mode_t|signed|quad_t|ushort|u_long|u_char|double|int8_t|ino_t|uid_t|pid_t|_Bool|float|dev_t|div_t|short|gid_t|off_t|u_int|key_t|id_t|uint|long|void|char|bool|id_t|int)\\b)[a-zA-Z_]\\w*\\b(?!\\())",
"match": "((?:[a-zA-Z_]\\w*|(?<=\\]|\\)))\\s*)(?:((?:\\.\\*|\\.))|((?:->\\*|->)))((?:[a-zA-Z_]\\w*\\s*(?:(?:(?:\\.\\*|\\.))|(?:(?:->\\*|->)))\\s*)*)\\s*(\\b(?!(?:atomic_uint_least64_t|atomic_uint_least16_t|atomic_uint_least32_t|atomic_uint_least8_t|atomic_int_least16_t|atomic_uint_fast64_t|atomic_uint_fast32_t|atomic_int_least64_t|atomic_int_least32_t|pthread_rwlockattr_t|atomic_uint_fast16_t|pthread_mutexattr_t|atomic_int_fast16_t|atomic_uint_fast8_t|atomic_int_fast64_t|atomic_int_least8_t|atomic_int_fast32_t|atomic_int_fast8_t|pthread_condattr_t|atomic_uintptr_t|atomic_ptrdiff_t|pthread_rwlock_t|atomic_uintmax_t|pthread_mutex_t|atomic_intmax_t|atomic_intptr_t|atomic_char32_t|atomic_char16_t|pthread_attr_t|atomic_wchar_t|uint_least64_t|uint_least32_t|uint_least16_t|pthread_cond_t|pthread_once_t|uint_fast64_t|uint_fast16_t|atomic_size_t|uint_least8_t|int_least64_t|int_least32_t|int_least16_t|pthread_key_t|atomic_ullong|atomic_ushort|uint_fast32_t|atomic_schar|atomic_short|uint_fast8_t|int_fast64_t|int_fast32_t|int_fast16_t|atomic_ulong|atomic_llong|int_least8_t|atomic_uchar|memory_order|suseconds_t|int_fast8_t|atomic_bool|atomic_char|atomic_uint|atomic_long|atomic_int|useconds_t|_Imaginary|blksize_t|pthread_t|in_addr_t|uintptr_t|in_port_t|uintmax_t|uintmax_t|blkcnt_t|uint16_t|unsigned|_Complex|uint32_t|intptr_t|intmax_t|intmax_t|uint64_t|u_quad_t|int64_t|int32_t|ssize_t|caddr_t|clock_t|uint8_t|u_short|swblk_t|segsz_t|int16_t|fixpt_t|daddr_t|nlink_t|qaddr_t|size_t|time_t|mode_t|signed|quad_t|ushort|u_long|u_char|double|int8_t|ino_t|uid_t|pid_t|_Bool|float|dev_t|div_t|short|gid_t|off_t|u_int|key_t|id_t|uint|long|void|char|bool|id_t|int)\\b)[a-zA-Z_]\\w*\\b(?!\\())",
"captures": {
"1": {
"name": "variable.other.object.access.c"
File diff suppressed because one or more lines are too long
+5 -5
View File
@@ -4,7 +4,7 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/97fe1e78f90c3234240831c5164374a7353a7a0c",
"version": "https://github.com/jeff-hykin/cpp-textmate-grammar/commit/fedd206d1b2803f31a278e9b5f098ce4bc76e532",
"name": "C++",
"scopeName": "source.cpp",
"patterns": [
@@ -966,7 +966,7 @@
]
},
"class_declare": {
"match": "(class)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])",
"match": "((?<!\\w)class(?!\\w))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])",
"captures": {
"1": {
"name": "storage.type.class.declare.cpp"
@@ -3307,7 +3307,7 @@
]
},
"enum_declare": {
"match": "(enum)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])",
"match": "((?<!\\w)enum(?!\\w))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])",
"captures": {
"1": {
"name": "storage.type.enum.declare.cpp"
@@ -12450,7 +12450,7 @@
]
},
"struct_declare": {
"match": "(struct)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])",
"match": "((?<!\\w)struct(?!\\w))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])",
"captures": {
"1": {
"name": "storage.type.struct.declare.cpp"
@@ -15976,7 +15976,7 @@
]
},
"union_declare": {
"match": "(union)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])",
"match": "((?<!\\w)union(?!\\w))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))(((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))?(?:(?:\\&|\\*)((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z))))*(?:\\&|\\*))?((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))\\b(?!override\\W|override\\$|final\\W|final\\$)((?<!\\w)(?:[a-zA-Z_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))(?:[a-zA-Z0-9_]|(?:\\\\u[0-9a-fA-F]{4}|\\\\U[0-9a-fA-F]{8}))*(?!\\w))((?:(?:(?>\\s+)|(\\/\\*)((?>(?:[^\\*]|(?>\\*+)[^\\/])*)((?>\\*+)\\/)))+?|(?:(?:(?:(?:\\b|(?<=\\W))|(?=\\W))|\\A)|\\Z)))(?=\\S)(?![:{])",
"captures": {
"1": {
"name": "storage.type.union.declare.cpp"
+5 -2
View File
@@ -1819,8 +1819,11 @@ export class Repository {
}
// Else, remove all lines starting with whitespace followed by `#`.
//TODO: Support core.commentChar
return message.replace(/^\s*#.*$\n?/gm, '').trim();
// TODO: Support core.commentChar
return message.replace(/^(\s*#)(.*)$(\n?)/gm, (_, prefix, content, suffix) => {
// https://github.com/microsoft/vscode/issues/84201#issuecomment-552834814
return /^\d/.test(content) ? `${prefix}${content}${suffix}` : '';
}).trim();
}
async getMergeMessage(): Promise<string | undefined> {
+2 -2
View File
@@ -6,12 +6,12 @@
"git": {
"name": "atom/language-sass",
"repositoryUrl": "https://github.com/atom/language-sass",
"commitHash": "d01d29191ab323fb3cf8bde9df0429f8e07902ff"
"commitHash": "f52ab12f7f9346cc2568129d8c4419bd3d506b47"
}
},
"license": "MIT",
"description": "The file syntaxes/scss.json was derived from the Atom package https://github.com/atom/language-sass which was originally converted from the TextMate bundle https://github.com/alexsancho/SASS.tmbundle.",
"version": "0.62.0"
"version": "0.62.1"
}
],
"version": 1
+165 -16
View File
@@ -4,13 +4,19 @@
"If you want to provide a fix or improvement, please create a pull request against the original repository.",
"Once accepted there, we are happy to receive an update request."
],
"version": "https://github.com/atom/language-sass/commit/d01d29191ab323fb3cf8bde9df0429f8e07902ff",
"version": "https://github.com/atom/language-sass/commit/f52ab12f7f9346cc2568129d8c4419bd3d506b47",
"name": "SCSS",
"scopeName": "source.css.scss",
"patterns": [
{
"include": "#variable_setting"
},
{
"include": "#at_rule_forward"
},
{
"include": "#at_rule_use"
},
{
"include": "#at_rule_include"
},
@@ -239,6 +245,55 @@
}
]
},
"at_rule_forward": {
"begin": "\\s*((@)forward\\b)\\s*",
"captures": {
"1": {
"name": "keyword.control.at-rule.forward.scss"
},
"2": {
"name": "punctuation.definition.keyword.scss"
}
},
"end": "\\s*(?=;)",
"name": "meta.at-rule.forward.scss",
"patterns": [
{
"match": "\\b(as|hide|show)\\b",
"name": "keyword.control.operator"
},
{
"match": "\\b([\\w-]+)(\\*)",
"captures": {
"1": {
"name": "entity.other.attribute-name.module.scss"
},
"2": {
"name": "punctuation.definition.wildcard.scss"
}
}
},
{
"match": "\\b[\\w-]+\\b",
"name": "entity.name.function.scss"
},
{
"include": "#variable"
},
{
"include": "#string_single"
},
{
"include": "#string_double"
},
{
"include": "#comment_line"
},
{
"include": "#comment_block"
}
]
},
"at_rule_function": {
"patterns": [
{
@@ -336,12 +391,18 @@
"at_rule_include": {
"patterns": [
{
"begin": "(?<=@include)\\s+([\\w-]+)\\s*(\\()",
"begin": "(?<=@include)\\s+(?:([\\w-]+)\\s*(\\.))?([\\w-]+)\\s*(\\()",
"beginCaptures": {
"1": {
"name": "entity.name.function.scss"
"name": "variable.scss"
},
"2": {
"name": "punctuation.access.module.scss"
},
"3": {
"name": "entity.name.function.scss"
},
"4": {
"name": "punctuation.definition.parameters.begin.bracket.round.scss"
}
},
@@ -359,12 +420,18 @@
]
},
{
"match": "(?<=@include)\\s+([\\w-]+)",
"match": "(?<=@include)\\s+(?:([\\w-]+)\\s*(\\.))?([\\w-]+)",
"captures": {
"0": {
"name": "meta.at-rule.include.scss"
},
"1": {
"name": "variable.scss"
},
"2": {
"name": "punctuation.access.module.scss"
},
"3": {
"name": "entity.name.function.scss"
}
}
@@ -794,6 +861,64 @@
}
]
},
"at_rule_use": {
"begin": "\\s*((@)use\\b)\\s*",
"captures": {
"1": {
"name": "keyword.control.at-rule.use.scss"
},
"2": {
"name": "punctuation.definition.keyword.scss"
}
},
"end": "\\s*(?=;)",
"name": "meta.at-rule.use.scss",
"patterns": [
{
"match": "\\b(as|with)\\b",
"name": "keyword.control.operator"
},
{
"match": "\\b[\\w-]+\\b",
"name": "variable.scss"
},
{
"match": "\\*",
"name": "variable.language.expanded-namespace.scss"
},
{
"include": "#string_single"
},
{
"include": "#string_double"
},
{
"include": "#comment_line"
},
{
"include": "#comment_block"
},
{
"begin": "\\(",
"beginCaptures": {
"0": {
"name": "punctuation.definition.parameters.begin.bracket.round.scss"
}
},
"end": "\\)",
"endCaptures": {
"0": {
"name": "punctuation.definition.parameters.end.bracket.round.scss"
}
},
"patterns": [
{
"include": "#function_attributes"
}
]
}
]
},
"at_rule_warn": {
"begin": "\\s*((@)(warn|debug|error)\\b)\\s*",
"captures": {
@@ -890,12 +1015,18 @@
"name": "keyword.other.default.scss"
},
"constant_functions": {
"begin": "([\\w-]+)(\\()",
"begin": "(?:([\\w-]+)(\\.))?([\\w-]+)(\\()",
"beginCaptures": {
"1": {
"name": "support.function.misc.scss"
"name": "variable.scss"
},
"2": {
"name": "punctuation.access.module.scss"
},
"3": {
"name": "support.function.misc.scss"
},
"4": {
"name": "punctuation.section.function.scss"
}
},
@@ -1050,10 +1181,10 @@
"name": "variable.interpolation.scss",
"patterns": [
{
"include": "#property_values"
"include": "#variable"
},
{
"include": "#variable"
"include": "#property_values"
}
]
},
@@ -1118,10 +1249,10 @@
"include": "#map"
},
{
"include": "#property_values"
"include": "#variable"
},
{
"include": "#variable"
"include": "#property_values"
}
]
},
@@ -1326,7 +1457,7 @@
]
},
"selector_attribute": {
"match": "(?xi)\n(\\[)\n\\s*\n(\n (?:\n [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+?\n)\n(?:\n \\s*([~|^$*]?=)\\s*\n (?:\n (\n (?:\n [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n )\n |\n ((\")(.*?)(\"))\n |\n ((')(.*?)('))\n )\n)?\n\\s*\n(\\])",
"match": "(?xi)\n(\\[)\n\\s*\n(\n (?:\n [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\.?\\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+?\n)\n(?:\n \\s*([~|^$*]?=)\\s*\n (?:\n (\n (?:\n [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\.?\\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n )\n |\n ((\")(.*?)(\"))\n |\n ((')(.*?)('))\n )\n)?\n\\s*\n(\\])",
"name": "meta.attribute-selector.scss",
"captures": {
"1": {
@@ -1421,7 +1552,7 @@
}
},
"selector_class": {
"match": "(?x)\n(\\.) # Valid class-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n) # Followed by either:\n(?= $ # - End of the line\n | [\\s,.\\#)\\[:{>+~|] # - Another selector\n | /\\* # - A block comment\n | ; # - A semicolon\n)",
"match": "(?x)\n(\\.) # Valid class-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\.?\\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n) # Followed by either:\n(?= $ # - End of the line\n | [\\s,\\#)\\[:{>+~|] # - Another selector\n | \\.[^$] # - Class selector, negating module variable\n | /\\* # - A block comment\n | ; # - A semicolon\n)",
"name": "entity.other.attribute-name.class.css",
"captures": {
"1": {
@@ -1449,7 +1580,7 @@
"name": "entity.name.tag.custom.scss"
},
"selector_id": {
"match": "(?x)\n(\\#) # Valid id-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n) # Followed by either:\n(?= $ # - End of the line\n | [\\s,.\\#)\\[:{>+~|] # - Another selector\n | /\\* # - A block comment\n)",
"match": "(?x)\n(\\#) # Valid id-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\.?\\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n) # Followed by either:\n(?= $ # - End of the line\n | [\\s,\\#)\\[:{>+~|] # - Another selector\n | \\.[^$] # - Class selector, negating module variable\n | /\\* # - A block comment\n)",
"name": "entity.other.attribute-name.id.css",
"captures": {
"1": {
@@ -1473,7 +1604,7 @@
}
},
"selector_placeholder": {
"match": "(?x)\n(%) # Valid placeholder-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n) # Followed by either:\n(?= ; # - End of statement\n | $ # - End of the line\n | [\\s,.\\#)\\[:{>+~|] # - Another selector\n | /\\* # - A block comment\n)",
"match": "(?x)\n(%) # Valid placeholder-name\n(\n (?: [-a-zA-Z_0-9]|[^\\x00-\\x7F] # Valid identifier characters\n | \\\\(?:[0-9a-fA-F]{1,6}|.) # Escape sequence\n | \\#\\{ # Interpolation (escaped to avoid Coffeelint errors)\n | \\.\\$ # Possible start of interpolation module scope variable\n | \\$ # Possible start of interpolation variable\n | } # Possible end of interpolation\n )+\n) # Followed by either:\n(?= ; # - End of statement\n | $ # - End of the line\n | [\\s,\\#)\\[:{>+~|] # - Another selector\n | \\.[^$] # - Class selector, negating module variable\n | /\\* # - A block comment\n)",
"name": "entity.other.attribute-name.placeholder.css",
"captures": {
"1": {
@@ -1723,8 +1854,26 @@
]
},
"variables": {
"match": "(\\$|\\-\\-)[A-Za-z0-9_-]+\\b",
"name": "variable.scss"
"patterns": [
{
"match": "\\b([\\w-]+)(\\.)(\\$[\\w-]+)\\b",
"captures": {
"1": {
"name": "variable.scss"
},
"2": {
"name": "punctuation.access.module.scss"
},
"3": {
"name": "variable.scss"
}
}
},
{
"match": "(\\$|\\-\\-)[A-Za-z0-9_-]+\\b",
"name": "variable.scss"
}
]
}
}
}
@@ -30,7 +30,7 @@
"format.placeOpenBraceOnNewLineForFunctions": "Defines whether an open brace is put onto a new line for functions or not.",
"format.placeOpenBraceOnNewLineForControlBlocks": "Defines whether an open brace is put onto a new line for control blocks or not.",
"format.semicolons": "Defines handling of optional semicolons. Requires using TypeScript 3.7 or newer in the workspace.",
"format.semicolons.ignore": "Don’t insert or remove any semicolons.",
"format.semicolons.ignore": "Don't insert or remove any semicolons.",
"format.semicolons.insert": "Insert semicolons at statement ends.",
"format.semicolons.remove": "Remove unnecessary semicolons.",
"javascript.validate.enable": "Enable/disable JavaScript validation.",
@@ -43,8 +43,8 @@
"typescript.selectTypeScriptVersion.title": "Select TypeScript Version...",
"typescript.reportStyleChecksAsWarnings": "Report style checks as warnings.",
"javascript.implicitProjectConfig.checkJs": "Enable/disable semantic checking of JavaScript files. Existing jsconfig.json or tsconfig.json files override this setting. Requires using TypeScript 2.3.1 or newer in the workspace.",
"typescript.npm": "Specifies the path to the NPM executable used for Automatic Type Acquisition. Requires using TypeScript 2.3.4 or newer in the workspace.",
"typescript.check.npmIsInstalled": "Check if NPM is installed for Automatic Type Acquisition.",
"typescript.npm": "Specifies the path to the npm executable used for Automatic Type Acquisition. Requires using TypeScript 2.3.4 or newer in the workspace.",
"typescript.check.npmIsInstalled": "Check if npm is installed for Automatic Type Acquisition.",
"configuration.suggest.names": "Enable/disable including unique names from the file in JavaScript suggestions. Note that name suggestions are always disabled in JavaScript code that is semantically checked using `@ts-check` or `checkJs`.",
"typescript.tsc.autoDetect": "Controls auto detection of tsc tasks.",
"typescript.tsc.autoDetect.off": "Disable this feature.",
+43 -7
View File
@@ -344,7 +344,7 @@ function enableProblems(context: vscode.ExtensionContext): void {
}
function updateDiagnostics(document: vscode.TextDocument, collection: vscode.DiagnosticCollection): void {
if (document && document.fileName === '/large.ts') {
if (document && document.fileName === '/sample-folder/large.ts') {
collection.set(document.uri, [{
code: '',
message: 'cannot assign twice to immutable variable `storeHouses`',
@@ -366,9 +366,9 @@ function updateDiagnostics(document: vscode.TextDocument, collection: vscode.Dia
}
}
function enableSearch(_context: vscode.ExtensionContext, _memFs: MemFS): void {
// NOT YET SUPPORTED
//context.subscriptions.push(vscode.workspace.registerFileSearchProvider(SCHEME, memFs));
function enableSearch(context: vscode.ExtensionContext, memFs: MemFS): void {
context.subscriptions.push(vscode.workspace.registerFileSearchProvider(SCHEME, memFs));
context.subscriptions.push(vscode.workspace.registerTextSearchProvider(SCHEME, memFs));
}
function enableTasks(): void {
@@ -546,7 +546,7 @@ export class Directory implements vscode.FileStat {
export type Entry = File | Directory;
export class MemFS implements vscode.FileSystemProvider, vscode.FileSearchProvider {
export class MemFS implements vscode.FileSystemProvider, vscode.FileSearchProvider, vscode.TextSearchProvider {
root = new Directory(vscode.Uri.parse('memfs:/'), '');
@@ -796,16 +796,52 @@ export class MemFS implements vscode.FileSystemProvider, vscode.FileSearchProvid
// --- search provider
provideFileSearchResults(query: vscode.FileSearchQuery, _options: vscode.FileSearchOptions, _token: vscode.CancellationToken): vscode.ProviderResult<vscode.Uri[]> {
return this._findFiles(query.pattern);
}
private _findFiles(query: string | undefined): vscode.Uri[] {
const files = this._getFiles();
const result: vscode.Uri[] = [];
const pattern = new RegExp(this._convertSimple2RegExpPattern(query.pattern));
const pattern = query ? new RegExp(this._convertSimple2RegExpPattern(query)) : null;
for (const file of files) {
if (pattern.exec(file.name)) {
if (!pattern || pattern.exec(file.name)) {
result.push(file.uri);
}
}
return result;
}
private _textDecoder = new TextDecoder();
provideTextSearchResults(query: vscode.TextSearchQuery, options: vscode.TextSearchOptions, progress: vscode.Progress<vscode.TextSearchResult>, _token: vscode.CancellationToken) {
const result: vscode.TextSearchComplete = { limitHit: false };
const files = this._findFiles(options.includes[0]);
if (files) {
for (const file of files) {
const content = this._textDecoder.decode(this.readFile(file));
const lines = content.split('\n');
for (let i = 0; i < lines.length; i++) {
const line = lines[i];
const index = line.indexOf(query.pattern);
if (index !== -1) {
progress.report({
uri: file,
ranges: new vscode.Range(new vscode.Position(i, index), new vscode.Position(i, index + query.pattern.length)),
preview: {
text: line,
matches: new vscode.Range(new vscode.Position(0, index), new vscode.Position(0, index + query.pattern.length))
}
});
}
}
}
}
return result;
}
}
@@ -23,6 +23,8 @@ suite('workspace-fs', () => {
assert.equal(typeof stat.mtime, 'number');
assert.equal(typeof stat.ctime, 'number');
assert.ok(stat.mtime > 0);
assert.ok(stat.ctime > 0);
const entries = await vscode.workspace.fs.readDirectory(root);
assert.ok(entries.length > 0);
+1
View File
@@ -73,6 +73,7 @@
"@types/semver": "^5.5.0",
"@types/sinon": "^1.16.36",
"@types/webpack": "^4.4.10",
"@types/windows-foreground-love": "^0.3.0",
"@types/winreg": "^1.2.30",
"@types/yauzl": "^2.9.1",
"@types/yazl": "^2.4.2",
+1
View File
@@ -10,6 +10,7 @@
"alwaysStrict": true,
"strictBindCallApply": true,
"strictNullChecks": true,
"strictPropertyInitialization": true,
"forceConsistentCasingInFileNames": true,
"baseUrl": ".",
"paths": {
-10
View File
@@ -1,10 +0,0 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
declare module 'windows-foreground-love' {
export function allowSetForegroundWindow(pid?: number): boolean;
}
+10
View File
@@ -26,6 +26,7 @@ export class FastDomNode<T extends HTMLElement> {
private _position: string;
private _visibility: string;
private _layerHint: boolean;
private _contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint';
constructor(domNode: T) {
this.domNode = domNode;
@@ -47,6 +48,7 @@ export class FastDomNode<T extends HTMLElement> {
this._position = '';
this._visibility = '';
this._layerHint = false;
this._contain = 'none';
}
public setMaxWidth(maxWidth: number): void {
@@ -206,6 +208,14 @@ export class FastDomNode<T extends HTMLElement> {
(<any>this.domNode.style).willChange = this._layerHint ? 'transform' : 'auto';
}
public setContain(contain: 'none' | 'strict' | 'content' | 'size' | 'layout' | 'style' | 'paint'): void {
if (this._contain === contain) {
return;
}
this._contain = contain;
(<any>this.domNode.style).contain = this._contain;
}
public setAttribute(name: string, value: string): void {
this.domNode.setAttribute(name, value);
}
@@ -90,4 +90,5 @@
display: flex;
align-items: center;
justify-content: center;
margin-right: 10px;
}
@@ -5,7 +5,7 @@
@font-face {
font-family: "codicon";
src: url("./codicon.ttf?7197ad7e38e9644da47ec42494d56501") format("truetype");
src: url("./codicon.ttf?3443fb4013ab5a04c23a30f912dd6627") format("truetype");
}
.codicon[class*='codicon-'] {
@@ -19,11 +19,6 @@
user-select: none;
-webkit-user-select: none;
-ms-user-select: none;
/* Hack to get web rendering to align to pixel grid */
transform: rotate(0);
-webkit-transform: rotate(0.1deg);
-moz-transform: rotate(0);
}
+5 -11
View File
@@ -1198,7 +1198,11 @@ export class List<T> implements ISpliceable<T>, IDisposable {
this.view = new ListView(container, virtualDelegate, renderers, viewOptions);
this.updateAriaRole();
if (typeof _options.ariaRole !== 'string') {
this.view.domNode.setAttribute('role', ListAriaRootRole.TREE);
} else {
this.view.domNode.setAttribute('role', _options.ariaRole);
}
this.styleElement = DOM.createStyleSheet(this.view.domNode);
@@ -1610,19 +1614,9 @@ export class List<T> implements ISpliceable<T>, IDisposable {
this.view.domNode.removeAttribute('aria-activedescendant');
}
this.updateAriaRole();
DOM.toggleClass(this.view.domNode, 'element-focused', focus.length > 0);
}
private updateAriaRole(): void {
if (typeof this.options.ariaRole !== 'string') {
this.view.domNode.setAttribute('role', ListAriaRootRole.TREE);
} else {
this.view.domNode.setAttribute('role', this.options.ariaRole);
}
}
private _onSelectionChange(): void {
const selection = this.selection.get();
@@ -99,6 +99,7 @@ export abstract class AbstractScrollbar extends Widget {
this.slider.setHeight(height);
}
this.slider.setLayerHinting(true);
this.slider.setContain('strict');
this.domNode.domNode.appendChild(this.slider.domNode);
+74 -3
View File
@@ -264,7 +264,7 @@ function dfs<TInput, T>(node: IAsyncDataTreeNode<TInput, T>, fn: (node: IAsyncDa
export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable {
protected readonly tree: ObjectTree<IAsyncDataTreeNode<TInput, T>, TFilterData>;
private readonly root: IAsyncDataTreeNode<TInput, T>;
protected readonly root: IAsyncDataTreeNode<TInput, T>;
private readonly nodes = new Map<null | T, IAsyncDataTreeNode<TInput, T>>();
private readonly sorter?: ITreeSorter<T>;
private readonly collapseByDefault?: { (e: T): boolean; };
@@ -859,7 +859,7 @@ export class AsyncDataTree<TInput, T, TFilterData = void> implements IDisposable
return childrenToRefresh;
}
private render(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): void {
protected render(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): void {
const children = node.children.map(node => this.asTreeElement(node, viewStateContext));
this.tree.setChildren(node === this.root ? null : node, children);
@@ -1031,7 +1031,7 @@ export interface ICompressibleAsyncDataTreeOptionsUpdate extends IAsyncDataTreeO
export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends AsyncDataTree<TInput, T, TFilterData> {
protected readonly tree: CompressibleObjectTree<IAsyncDataTreeNode<TInput, T>, TFilterData>;
protected readonly tree!: CompressibleObjectTree<IAsyncDataTreeNode<TInput, T>, TFilterData>;
protected readonly compressibleNodeMapper: CompressibleAsyncDataTreeNodeMapper<TInput, T, TFilterData> = new WeakMapper(node => new CompressibleAsyncDataTreeNodeWrapper(node));
constructor(
@@ -1098,4 +1098,75 @@ export class CompressibleAsyncDataTree<TInput, T, TFilterData = void> extends As
return { focus, selection, expanded, scrollTop: this.scrollTop };
}
protected render(node: IAsyncDataTreeNode<TInput, T>, viewStateContext?: IAsyncDataTreeViewStateContext<TInput, T>): void {
if (!this.identityProvider) {
return super.render(node, viewStateContext);
}
// Preserve traits across compressions. Hacky but does the trick.
// This is hard to fix properly since it requires rewriting the traits
// across trees and lists. Let's just keep it this way for now.
const getId = (element: T) => this.identityProvider!.getId(element).toString();
const getUncompressedIds = (nodes: IAsyncDataTreeNode<TInput, T>[]): Set<string> => {
const result = new Set<string>();
for (const node of nodes) {
const compressedNode = this.tree.getCompressedTreeNode(node === this.root ? null : node);
if (!compressedNode.element) {
continue;
}
for (const node of compressedNode.element.elements) {
result.add(getId(node.element as T));
}
}
return result;
};
const oldSelection = getUncompressedIds(this.tree.getSelection() as IAsyncDataTreeNode<TInput, T>[]);
const oldFocus = getUncompressedIds(this.tree.getFocus() as IAsyncDataTreeNode<TInput, T>[]);
super.render(node, viewStateContext);
const selection = this.getSelection();
let didChangeSelection = false;
const focus = this.getFocus();
let didChangeFocus = false;
const visit = (node: ITreeNode<ICompressedTreeNode<IAsyncDataTreeNode<TInput, T>> | null, TFilterData>) => {
const compressedNode = node.element;
if (compressedNode) {
for (let i = 0; i < compressedNode.elements.length; i++) {
const id = getId(compressedNode.elements[i].element as T);
if (oldSelection.has(id)) {
selection.push(compressedNode.elements[compressedNode.elements.length - 1].element as T);
didChangeSelection = true;
}
if (oldFocus.has(id)) {
focus.push(compressedNode.elements[compressedNode.elements.length - 1].element as T);
didChangeFocus = true;
}
}
}
node.children.forEach(visit);
};
visit(this.tree.getCompressedTreeNode(node === this.root ? null : node));
if (didChangeSelection) {
this.setSelection(selection);
}
if (didChangeFocus) {
this.setFocus(focus);
}
}
}
+8 -7
View File
@@ -199,8 +199,6 @@ export function detectEncodingByBOMFromBuffer(buffer: Buffer | VSBuffer | null,
return null;
}
const IGNORE_ENCODINGS = ['ascii', 'utf-8', 'utf-16', 'utf-32'];
/**
* Guesses the encoding from buffer.
*/
@@ -212,11 +210,14 @@ async function guessEncodingByBuffer(buffer: Buffer): Promise<string | null> {
return null;
}
const enc = guessed.encoding.toLowerCase();
// Ignore encodings that cannot guess correctly
// (http://chardet.readthedocs.io/en/latest/supported-encodings.html)
if (0 <= IGNORE_ENCODINGS.indexOf(enc)) {
// 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;
}
@@ -134,6 +134,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider {
private styles: IQuickOpenStyles;
// @ts-ignore (legacy widget - to be replaced with quick input)
private renderer: Renderer;
private keyDownSeenSinceShown = false;
constructor(container: HTMLElement, callbacks: IQuickOpenCallbacks, options: IQuickOpenOptions) {
super();
@@ -170,6 +171,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider {
this._register(DOM.addDisposableListener(this.element, DOM.EventType.FOCUS, e => this.gainingFocus(), true));
this._register(DOM.addDisposableListener(this.element, DOM.EventType.BLUR, e => this.loosingFocus(e), true));
this._register(DOM.addDisposableListener(this.element, DOM.EventType.KEY_DOWN, e => {
this.keyDownSeenSinceShown = true;
const keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e);
if (keyboardEvent.keyCode === KeyCode.Escape) {
DOM.EventHelper.stop(e, true);
@@ -220,6 +222,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider {
this._register(DOM.addDisposableListener(this.inputBox.inputElement, DOM.EventType.INPUT, (e: Event) => this.onType()));
this._register(DOM.addDisposableListener(this.inputBox.inputElement, DOM.EventType.KEY_DOWN, (e: KeyboardEvent) => {
this.keyDownSeenSinceShown = true;
const keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e);
const shouldOpenInBackground = this.shouldOpenInBackground(keyboardEvent);
@@ -300,6 +303,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider {
}));
this._register(DOM.addDisposableListener(this.treeContainer, DOM.EventType.KEY_DOWN, e => {
this.keyDownSeenSinceShown = true;
const keyboardEvent: StandardKeyboardEvent = new StandardKeyboardEvent(e);
// Only handle when in quick navigation mode
@@ -320,7 +324,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider {
const keyCode = keyboardEvent.keyCode;
// Only handle when in quick navigation mode
if (!this.quickNavigateConfiguration) {
if (!this.quickNavigateConfiguration || !this.keyDownSeenSinceShown) {
return;
}
@@ -595,6 +599,7 @@ export class QuickOpenWidget extends Disposable implements IModelProvider {
this.visible = true;
this.isLoosingFocus = false;
this.quickNavigateConfiguration = options ? options.quickNavigateConfiguration : undefined;
this.keyDownSeenSinceShown = false;
// Adjust UI for quick navigate mode
if (this.quickNavigateConfiguration) {
@@ -189,6 +189,20 @@ suite('Encoding', () => {
assert.equal(mimes.seemsBinary, false);
});
test('autoGuessEncoding (UTF8)', async function () {
const file = getPathFromAmdModule(require, './fixtures/some_file.css');
const buffer = await readExactlyByFile(file, 512 * 8);
const mimes = await encoding.detectEncodingFromBuffer(buffer, true);
assert.equal(mimes.encoding, 'utf8');
});
test('autoGuessEncoding (ASCII)', async function () {
const file = getPathFromAmdModule(require, './fixtures/some_ansi.css');
const buffer = await readExactlyByFile(file, 512 * 8);
const mimes = await encoding.detectEncodingFromBuffer(buffer, true);
assert.equal(mimes.encoding, null);
});
test('autoGuessEncoding (ShiftJIS)', async function () {
const file = getPathFromAmdModule(require, './fixtures/some.shiftjis.txt');
const buffer = await readExactlyByFile(file, 512 * 8);
@@ -0,0 +1,42 @@
/*---------------------------------------------------------------------------------------------
* Copyright (c) Microsoft Corporation. All rights reserved.
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
/*----------------------------------------------------------
The base color for this template is #5c87b2. If you'd like
to use a different color start by replacing all instances of
#5c87b2 with your new color.
öäüßßß
----------------------------------------------------------*/
body
{
background-color: #5c87b2;
font-size: .75em;
font-family: Segoe UI, Verdana, Helvetica, Sans-Serif;
margin: 8px;
padding: 0;
color: #696969;
}
h1, h2, h3, h4, h5, h6
{
color: #000;
font-size: 40px;
margin: 0px;
}
textarea
{
font-family: Consolas
}
#results
{
margin-top: 2em;
margin-left: 2em;
color: black;
font-size: medium;
}
@@ -7,6 +7,8 @@
The base color for this template is #5c87b2. If you'd like
to use a different color start by replacing all instances of
#5c87b2 with your new color.
öäüßßß
----------------------------------------------------------*/
body
{
@@ -25,12 +27,12 @@ h1, h2, h3, h4, h5, h6
margin: 0px;
}
textarea
textarea
{
font-family: Consolas
}
#results
#results
{
margin-top: 2em;
margin-left: 2em;
+5 -2
View File
@@ -11,7 +11,6 @@ import { Disposable } from 'vs/base/common/lifecycle';
import { request } from 'vs/base/parts/request/browser/request';
import { isFolderToOpen, isWorkspaceToOpen } from 'vs/platform/windows/common/windows';
import { isEqual } from 'vs/base/common/resources';
import { isStandalone } from 'vs/base/browser/browser';
interface ICredential {
service: string;
@@ -223,7 +222,7 @@ class WorkspaceProvider implements IWorkspaceProvider {
if (options?.reuse) {
window.location.href = targetHref;
} else {
if (isStandalone) {
if (this.isRunningInPWA()) { // TODO@ben figure out why browser.isStandalone would not work?
window.open(targetHref, '_blank', 'toolbar=no'); // ensures to open another 'standalone' window!
} else {
window.open(targetHref);
@@ -232,6 +231,10 @@ class WorkspaceProvider implements IWorkspaceProvider {
}
}
private isRunningInPWA(): boolean {
return (window.matchMedia && window.matchMedia('(display-mode: standalone)').matches);
}
private createTargetUrl(workspace: IWorkspace, options?: { reuse?: boolean, payload?: object }): string | undefined {
// Empty
@@ -544,6 +544,7 @@ export class ViewLines extends ViewPart implements IVisibleLinesHost<ViewLine>,
// (3) handle scrolling
this._linesContent.setLayerHinting(this._canUseLayerHinting);
this._linesContent.setContain('strict');
const adjustedScrollTop = this._context.viewLayout.getCurrentScrollTop() - viewportData.bigNumbersDelta;
this._linesContent.setTop(-adjustedScrollTop);
this._linesContent.setLeft(-this._context.viewLayout.getCurrentScrollLeft());
@@ -78,6 +78,7 @@ export class Margin extends ViewPart {
public render(ctx: RestrictedRenderingContext): void {
this._domNode.setLayerHinting(this._canUseLayerHinting);
this._domNode.setContain('strict');
const adjustedScrollTop = ctx.scrollTop - ctx.bigNumbersDelta;
this._domNode.setTop(-adjustedScrollTop);
@@ -503,6 +503,7 @@ export class Minimap extends ViewPart {
this._slider.setPosition('absolute');
this._slider.setClassName('minimap-slider');
this._slider.setLayerHinting(true);
this._slider.setContain('strict');
this._domNode.appendChild(this._slider);
this._sliderHorizontal = createFastDomNode(document.createElement('div'));
@@ -215,6 +215,7 @@ export class DecorationsOverviewRuler extends ViewPart {
this._domNode.setClassName('decorationsOverviewRuler');
this._domNode.setPosition('absolute');
this._domNode.setLayerHinting(true);
this._domNode.setContain('strict');
this._domNode.setAttribute('aria-hidden', 'true');
this._updateSettings(false);
@@ -26,6 +26,7 @@ export class OverviewRuler extends ViewEventHandler implements IOverviewRuler {
this._domNode.setClassName(cssClassName);
this._domNode.setPosition('absolute');
this._domNode.setLayerHinting(true);
this._domNode.setContain('strict');
this._zoneManager = new OverviewZoneManager((lineNumber: number) => this._context.viewLayout.getVerticalOffsetForLineNumber(lineNumber));
this._zoneManager.setDOMWidth(0);
+2 -2
View File
@@ -3155,10 +3155,10 @@ export const EditorOptions = {
['default', 'all'] as const,
{
enumDescriptions: [
nls.localize('cursorSurroundingLinesStyle.default', "`cursorSurroundingLines` is enforced only when triggered from keyboard and api"),
nls.localize('cursorSurroundingLinesStyle.default', "`cursorSurroundingLines` is enforced only when triggered via the keyboard or API."),
nls.localize('cursorSurroundingLinesStyle.all', "`cursorSurroundingLines` is enforced always.")
],
description: nls.localize('cursorSurroundingLinesStyle', "Controls when `cursorSurroundingLines` should be enforced")
description: nls.localize('cursorSurroundingLinesStyle', "Controls when `cursorSurroundingLines` should be enforced.")
}
)),
cursorWidth: register(new EditorIntOption(
@@ -209,16 +209,20 @@ export class FileService extends Disposable implements IFileService {
});
}
private async toFileStat(provider: IFileSystemProvider, resource: URI, stat: IStat | { type: FileType } & Partial<IStat>, siblings: number | undefined, resolveMetadata: boolean, recurse: (stat: IFileStat, siblings?: number) => boolean): Promise<IFileStat>;
private async toFileStat(provider: IFileSystemProvider, resource: URI, stat: IStat, siblings: number | undefined, resolveMetadata: true, recurse: (stat: IFileStat, siblings?: number) => boolean): Promise<IFileStatWithMetadata>;
private async toFileStat(provider: IFileSystemProvider, resource: URI, stat: IStat | { type: FileType } & Partial<IStat>, siblings: number | undefined, resolveMetadata: boolean, recurse: (stat: IFileStat, siblings?: number) => boolean): Promise<IFileStat> {
// convert to file stat
const fileStat: IFileStat = {
resource,
name: getBaseLabel(resource),
isFile: (stat.type & FileType.File) !== 0,
isDirectory: (stat.type & FileType.Directory) !== 0,
isSymbolicLink: (stat.type & FileType.SymbolicLink) !== 0,
isReadonly: !!(provider.capabilities & FileSystemProviderCapabilities.Readonly),
mtime: stat.mtime,
ctime: stat.ctime,
size: stat.size,
etag: etag({ mtime: stat.mtime, size: stat.size })
};
+28 -5
View File
@@ -207,8 +207,17 @@ export enum FileType {
export interface IStat {
type: FileType;
/**
* The last modification date represented as millis from unix epoch.
*/
mtime: number;
/**
* The creation date represented as millis from unix epoch.
*/
ctime: number;
size: number;
}
@@ -583,14 +592,21 @@ interface IBaseStat {
size?: number;
/**
* The last modification date represented
* as millis from unix epoch.
* The last modification date represented as millis from unix epoch.
*
* The value may or may not be resolved as
* it is optional.
*/
mtime?: number;
/**
* The creation date represented as millis from unix epoch.
*
* The value may or may not be resolved as
* it is optional.
*/
ctime?: number;
/**
* A unique identifier thet represents the
* current state of the file or directory.
@@ -608,6 +624,7 @@ interface IBaseStat {
export interface IBaseStatWithMetadata extends IBaseStat {
mtime: number;
ctime: number;
etag: string;
size: number;
}
@@ -618,14 +635,19 @@ export interface IBaseStatWithMetadata extends IBaseStat {
export interface IFileStat extends IBaseStat {
/**
* The resource is a directory
* The resource is a file.
*/
isFile: boolean;
/**
* The resource is a directory.
*/
isDirectory: boolean;
/**
* The resource is a symbolic link.
*/
isSymbolicLink?: boolean;
isSymbolicLink: boolean;
/**
* The children of the file stat or undefined if none.
@@ -635,6 +657,7 @@ export interface IFileStat extends IBaseStat {
export interface IFileStatWithMetadata extends IFileStat, IBaseStatWithMetadata {
mtime: number;
ctime: number;
etag: string;
size: number;
children?: IFileStatWithMetadata[];
@@ -703,7 +726,7 @@ export interface IResolveFileOptions {
readonly resolveSingleChildDescendants?: boolean;
/**
* Will resolve mtime, size and etag of files if enabled. This can have a negative impact
* Will resolve mtime, ctime, size and etag of files if enabled. This can have a negative impact
* on performance and thus should only be used when these values are required.
*/
readonly resolveMetadata?: boolean;
@@ -80,7 +80,7 @@ export class DiskFileSystemProvider extends Disposable implements
return {
type: this.toType(stat, isSymbolicLink),
ctime: stat.ctime.getTime(),
ctime: stat.birthtime.getTime(), // intentionally not using ctime here, we want the creation time
mtime: stat.mtime.getTime(),
size: stat.size
};
@@ -134,7 +134,7 @@ suite('Disk File Service', function () {
// we see random test failures when accessing the native file system. To
// diagnose further, we retry node.js file access tests up to 3 times to
// rule out any random disk issue.
this.retries(3);
// this.retries(3);
setup(async () => {
const logService = new NullLogService();
@@ -213,23 +213,35 @@ suite('Disk File Service', function () {
assert.equal(exists, false);
});
test('resolve', async () => {
const resolved = await service.resolve(URI.file(testDir), { resolveTo: [URI.file(join(testDir, 'deep'))] });
assert.equal(resolved.children!.length, 8);
test('resolve - file', async () => {
const resource = URI.file(getPathFromAmdModule(require, './fixtures/resolver/index.html'));
const resolved = await service.resolve(resource);
const deep = (getByName(resolved, 'deep')!);
assert.equal(deep.children!.length, 4);
assert.equal(resolved.name, 'index.html');
assert.equal(resolved.isFile, true);
assert.equal(resolved.isDirectory, false);
assert.equal(resolved.isSymbolicLink, false);
assert.equal(resolved.resource.toString(), resource.toString());
assert.equal(resolved.children, undefined);
assert.ok(resolved.mtime! > 0);
assert.ok(resolved.ctime! > 0);
assert.ok(resolved.size! > 0);
});
test('resolve - directory', async () => {
const testsElements = ['examples', 'other', 'index.html', 'site.css'];
const result = await service.resolve(URI.file(getPathFromAmdModule(require, './fixtures/resolver')));
const resource = URI.file(getPathFromAmdModule(require, './fixtures/resolver'));
const result = await service.resolve(resource);
assert.ok(result);
assert.equal(result.resource.toString(), resource.toString());
assert.equal(result.name, 'resolver');
assert.ok(result.children);
assert.ok(result.children!.length > 0);
assert.ok(result!.isDirectory);
assert.ok(result.mtime! > 0);
assert.ok(result.ctime! > 0);
assert.equal(result.children!.length, testsElements.length);
assert.ok(result.children!.every(entry => {
@@ -242,12 +254,18 @@ suite('Disk File Service', function () {
assert.ok(basename(value.resource.fsPath));
if (['examples', 'other'].indexOf(basename(value.resource.fsPath)) >= 0) {
assert.ok(value.isDirectory);
assert.equal(value.mtime, undefined);
assert.equal(value.ctime, undefined);
} else if (basename(value.resource.fsPath) === 'index.html') {
assert.ok(!value.isDirectory);
assert.ok(!value.children);
assert.equal(value.mtime, undefined);
assert.equal(value.ctime, undefined);
} else if (basename(value.resource.fsPath) === 'site.css') {
assert.ok(!value.isDirectory);
assert.ok(!value.children);
assert.equal(value.mtime, undefined);
assert.equal(value.ctime, undefined);
} else {
assert.ok(!'Unexpected value ' + basename(value.resource.fsPath));
}
@@ -260,9 +278,12 @@ suite('Disk File Service', function () {
const result = await service.resolve(URI.file(getPathFromAmdModule(require, './fixtures/resolver')), { resolveMetadata: true });
assert.ok(result);
assert.equal(result.name, 'resolver');
assert.ok(result.children);
assert.ok(result.children!.length > 0);
assert.ok(result!.isDirectory);
assert.ok(result.mtime! > 0);
assert.ok(result.ctime! > 0);
assert.equal(result.children!.length, testsElements.length);
assert.ok(result.children!.every(entry => {
@@ -277,18 +298,32 @@ suite('Disk File Service', function () {
assert.ok(basename(value.resource.fsPath));
if (['examples', 'other'].indexOf(basename(value.resource.fsPath)) >= 0) {
assert.ok(value.isDirectory);
assert.ok(value.mtime! > 0);
assert.ok(value.ctime! > 0);
} else if (basename(value.resource.fsPath) === 'index.html') {
assert.ok(!value.isDirectory);
assert.ok(!value.children);
assert.ok(value.mtime! > 0);
assert.ok(value.ctime! > 0);
} else if (basename(value.resource.fsPath) === 'site.css') {
assert.ok(!value.isDirectory);
assert.ok(!value.children);
assert.ok(value.mtime! > 0);
assert.ok(value.ctime! > 0);
} else {
assert.ok(!'Unexpected value ' + basename(value.resource.fsPath));
}
});
});
test('resolve - directory with resolveTo', async () => {
const resolved = await service.resolve(URI.file(testDir), { resolveTo: [URI.file(join(testDir, 'deep'))] });
assert.equal(resolved.children!.length, 8);
const deep = (getByName(resolved, 'deep')!);
assert.equal(deep.children!.length, 4);
});
test('resolve - directory - resolveTo single directory', async () => {
const resolverFixturesPath = getPathFromAmdModule(require, './fixtures/resolver');
const result = await service.resolve(URI.file(resolverFixturesPath), { resolveTo: [URI.file(join(resolverFixturesPath, 'other/deep'))] });
@@ -1458,15 +1493,15 @@ suite('Disk File Service', function () {
}
test('createFile', async () => {
assertCreateFile(contents => VSBuffer.fromString(contents));
return assertCreateFile(contents => VSBuffer.fromString(contents));
});
test('createFile (readable)', async () => {
assertCreateFile(contents => bufferToReadable(VSBuffer.fromString(contents)));
return assertCreateFile(contents => bufferToReadable(VSBuffer.fromString(contents)));
});
test('createFile (stream)', async () => {
assertCreateFile(contents => bufferToStream(VSBuffer.fromString(contents)));
return assertCreateFile(contents => bufferToStream(VSBuffer.fromString(contents)));
});
async function assertCreateFile(converter: (content: string) => VSBuffer | VSBufferReadable | VSBufferReadableStream): Promise<void> {
@@ -157,7 +157,7 @@ export class InstantiationService implements IInstantiationService {
graph.lookupOrInsertNode(item);
// a weak but working heuristic for cycle checks
if (cycleCount++ > 100) {
if (cycleCount++ > 150) {
throw new CyclicDependencyError(graph);
}
+3
View File
@@ -5986,6 +5986,9 @@ declare module 'vscode' {
/**
* Create a new directory (Note, that new files are created via `write`-calls).
*
* *Note* that missing directories are created automatically, e.g this call has
* `mkdirp` semantics.
*
* @param uri The uri of the new folder.
*/
createDirectory(uri: Uri): Thenable<void>;
@@ -33,11 +33,11 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape {
private static _convertOpenOptions(options: MainThreadDialogOpenOptions): IOpenDialogOptions {
const result: IOpenDialogOptions = {
openLabel: options.openLabel,
openLabel: options.openLabel || undefined,
canSelectFiles: options.canSelectFiles || (!options.canSelectFiles && !options.canSelectFolders),
canSelectFolders: options.canSelectFolders,
canSelectMany: options.canSelectMany,
defaultUri: URI.revive(options.defaultUri)
defaultUri: options.defaultUri ? URI.revive(options.defaultUri) : undefined
};
if (options.filters) {
result.filters = [];
@@ -48,8 +48,8 @@ export class MainThreadDialogs implements MainThreadDiaglogsShape {
private static _convertSaveOptions(options: MainThreadDialogSaveOptions): ISaveDialogOptions {
const result: ISaveDialogOptions = {
defaultUri: URI.revive(options.defaultUri),
saveLabel: options.saveLabel
defaultUri: options.defaultUri ? URI.revive(options.defaultUri) : undefined,
saveLabel: options.saveLabel || undefined
};
if (options.filters) {
result.filters = [];
@@ -233,7 +233,7 @@ export class MainThreadDocuments implements MainThreadDocumentsShape {
initialValue,
useResourcePath: Boolean(resource && resource.path)
}).then(model => {
const resource = model.getResource();
const resource = model.resource;
if (!this._modelIsSynced.has(resource.toString())) {
throw new Error(`expected URI ${resource.toString()} to have come to LIFE`);
@@ -52,10 +52,10 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape {
$stat(uri: UriComponents): Promise<IStat> {
return this._fileService.resolve(URI.revive(uri), { resolveMetadata: true }).then(stat => {
return {
ctime: 0,
ctime: stat.ctime,
mtime: stat.mtime,
size: stat.size,
type: MainThreadFileSystem._getFileType(stat)
type: MainThreadFileSystem._asFileType(stat)
};
}).catch(MainThreadFileSystem._handleError);
}
@@ -67,12 +67,22 @@ export class MainThreadFileSystem implements MainThreadFileSystemShape {
err.name = FileSystemProviderErrorCode.FileNotADirectory;
throw err;
}
return !stat.children ? [] : stat.children.map(child => [child.name, MainThreadFileSystem._getFileType(child)] as [string, FileType]);
return !stat.children ? [] : stat.children.map(child => [child.name, MainThreadFileSystem._asFileType(child)] as [string, FileType]);
}).catch(MainThreadFileSystem._handleError);
}
private static _getFileType(stat: IFileStat): FileType {
return (stat.isDirectory ? FileType.Directory : FileType.File) + (stat.isSymbolicLink ? FileType.SymbolicLink : 0);
private static _asFileType(stat: IFileStat): FileType {
let res = 0;
if (stat.isFile) {
res += FileType.File;
} else if (stat.isDirectory) {
res += FileType.Directory;
}
if (stat.isSymbolicLink) {
res += FileType.SymbolicLink;
}
return res;
}
$readFile(uri: UriComponents): Promise<VSBuffer> {
@@ -51,7 +51,7 @@ class TrimWhitespaceParticipant implements ISaveParticipantParticipant {
}
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise<void> {
if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
if (this.configurationService.getValue('files.trimTrailingWhitespace', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.resource })) {
this.doTrimTrailingWhitespace(model.textEditorModel, env.reason === SaveReason.AUTO);
}
}
@@ -113,7 +113,7 @@ export class FinalNewLineParticipant implements ISaveParticipantParticipant {
}
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise<void> {
if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
if (this.configurationService.getValue('files.insertFinalNewline', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.resource })) {
this.doInsertFinalNewLine(model.textEditorModel);
}
}
@@ -147,7 +147,7 @@ export class TrimFinalNewLinesParticipant implements ISaveParticipantParticipant
}
async participate(model: IResolvedTextFileEditorModel, env: { reason: SaveReason; }): Promise<void> {
if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.getResource() })) {
if (this.configurationService.getValue('files.trimFinalNewlines', { overrideIdentifier: model.textEditorModel.getLanguageIdentifier().language, resource: model.resource })) {
this.doTrimFinalNewLines(model.textEditorModel, env.reason === SaveReason.AUTO);
}
}
@@ -257,7 +257,7 @@ class CodeActionOnSaveParticipant implements ISaveParticipant {
const model = editorModel.textEditorModel;
const settingsOverrides = { overrideIdentifier: model.getLanguageIdentifier().language, resource: editorModel.getResource() };
const settingsOverrides = { overrideIdentifier: model.getLanguageIdentifier().language, resource: editorModel.resource };
const setting = this._configurationService.getValue<ICodeActionsOnSaveOptions>('editor.codeActionsOnSave', settingsOverrides);
if (!setting) {
return undefined;
@@ -343,7 +343,7 @@ class ExtHostSaveParticipant implements ISaveParticipantParticipant {
return new Promise<any>((resolve, reject) => {
setTimeout(() => reject(localize('timeout.onWillSave', "Aborted onWillSaveTextDocument-event after 1750ms")), 1750);
this._proxy.$participateInSave(editorModel.getResource(), env.reason).then(values => {
this._proxy.$participateInSave(editorModel.resource, env.reason).then(values => {
if (!values.every(success => success)) {
return Promise.reject(new Error('listener failed'));
}
@@ -12,6 +12,7 @@ import { INotificationService } from 'vs/platform/notification/common/notificati
import { isUndefinedOrNull, isNumber } from 'vs/base/common/types';
import { Registry } from 'vs/platform/registry/common/platform';
import { IExtensionService } from 'vs/workbench/services/extensions/common/extensions';
import { ILogService } from 'vs/platform/log/common/log';
@extHostNamedCustomer(MainContext.MainThreadTreeViews)
export class MainThreadTreeViews extends Disposable implements MainThreadTreeViewsShape {
@@ -23,13 +24,16 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
extHostContext: IExtHostContext,
@IViewsService private readonly viewsService: IViewsService,
@INotificationService private readonly notificationService: INotificationService,
@IExtensionService private readonly extensionService: IExtensionService
@IExtensionService private readonly extensionService: IExtensionService,
@ILogService private readonly logService: ILogService
) {
super();
this._proxy = extHostContext.getProxy(ExtHostContext.ExtHostTreeViews);
}
$registerTreeViewDataProvider(treeViewId: string, options: { showCollapseAll: boolean, canSelectMany: boolean }): void {
this.logService.trace('MainThreadTreeViews#$registerTreeViewDataProvider', treeViewId, options);
this.extensionService.whenInstalledExtensionsRegistered().then(() => {
const dataProvider = new TreeViewDataProvider(treeViewId, this._proxy, this.notificationService);
this._dataProviders.set(treeViewId, dataProvider);
@@ -49,6 +53,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
}
$reveal(treeViewId: string, item: ITreeItem, parentChain: ITreeItem[], options: IRevealOptions): Promise<void> {
this.logService.trace('MainThreadTreeViews#$reveal', treeViewId, item, parentChain, options);
return this.viewsService.openView(treeViewId, options.focus)
.then(() => {
const viewer = this.getTreeView(treeViewId);
@@ -60,6 +66,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
}
$refresh(treeViewId: string, itemsToRefreshByHandle: { [treeItemHandle: string]: ITreeItem }): Promise<void> {
this.logService.trace('MainThreadTreeViews#$refresh', treeViewId, itemsToRefreshByHandle);
const viewer = this.getTreeView(treeViewId);
const dataProvider = this._dataProviders.get(treeViewId);
if (viewer && dataProvider) {
@@ -70,6 +78,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
}
$setMessage(treeViewId: string, message: string): void {
this.logService.trace('MainThreadTreeViews#$setMessage', treeViewId, message);
const viewer = this.getTreeView(treeViewId);
if (viewer) {
viewer.message = message;
@@ -77,6 +87,8 @@ export class MainThreadTreeViews extends Disposable implements MainThreadTreeVie
}
$setTitle(treeViewId: string, title: string): void {
this.logService.trace('MainThreadTreeViews#$setTitle', treeViewId, title);
const viewer = this.getTreeView(treeViewId);
if (viewer) {
viewer.title = title;
+117 -2
View File
@@ -3,10 +3,17 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { IDisposable } from 'vs/base/common/lifecycle';
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import * as vscode from 'vscode';
import { ExtHostSearchShape } from '../common/extHost.protocol';
import { ExtHostSearchShape, MainThreadSearchShape, MainContext } from '../common/extHost.protocol';
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { FileSearchManager } from 'vs/workbench/services/search/common/fileSearchManager';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
import { ILogService } from 'vs/platform/log/common/log';
import { IRawFileQuery, ISearchCompleteStats, IFileQuery, IRawTextQuery, IRawQuery, ITextQuery, IFolderQuery } from 'vs/workbench/services/search/common/search';
import { URI, UriComponents } from 'vs/base/common/uri';
import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager';
export interface IExtHostSearch extends ExtHostSearchShape {
registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable;
@@ -14,3 +21,111 @@ export interface IExtHostSearch extends ExtHostSearchShape {
}
export const IExtHostSearch = createDecorator<IExtHostSearch>('IExtHostSearch');
export class ExtHostSearch implements ExtHostSearchShape {
protected readonly _proxy: MainThreadSearchShape = this.extHostRpc.getProxy(MainContext.MainThreadSearch);
protected _handlePool: number = 0;
private readonly _textSearchProvider = new Map<number, vscode.TextSearchProvider>();
private readonly _textSearchUsedSchemes = new Set<string>();
private readonly _fileSearchProvider = new Map<number, vscode.FileSearchProvider>();
private readonly _fileSearchUsedSchemes = new Set<string>();
private readonly _fileSearchManager = new FileSearchManager();
constructor(
@IExtHostRpcService private extHostRpc: IExtHostRpcService,
@IURITransformerService protected _uriTransformer: IURITransformerService,
@ILogService protected _logService: ILogService
) { }
protected _transformScheme(scheme: string): string {
return this._uriTransformer.transformOutgoingScheme(scheme);
}
registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable {
if (this._textSearchUsedSchemes.has(scheme)) {
throw new Error(`a text search provider for the scheme '${scheme}' is already registered`);
}
this._textSearchUsedSchemes.add(scheme);
const handle = this._handlePool++;
this._textSearchProvider.set(handle, provider);
this._proxy.$registerTextSearchProvider(handle, this._transformScheme(scheme));
return toDisposable(() => {
this._textSearchUsedSchemes.delete(scheme);
this._textSearchProvider.delete(handle);
this._proxy.$unregisterProvider(handle);
});
}
registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider): IDisposable {
if (this._fileSearchUsedSchemes.has(scheme)) {
throw new Error(`a file search provider for the scheme '${scheme}' is already registered`);
}
this._fileSearchUsedSchemes.add(scheme);
const handle = this._handlePool++;
this._fileSearchProvider.set(handle, provider);
this._proxy.$registerFileSearchProvider(handle, this._transformScheme(scheme));
return toDisposable(() => {
this._fileSearchUsedSchemes.delete(scheme);
this._fileSearchProvider.delete(handle);
this._proxy.$unregisterProvider(handle);
});
}
$provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: vscode.CancellationToken): Promise<ISearchCompleteStats> {
const query = reviveQuery(rawQuery);
const provider = this._fileSearchProvider.get(handle);
if (provider) {
return this._fileSearchManager.fileSearch(query, provider, batch => {
this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource));
}, token);
} else {
throw new Error('unknown provider: ' + handle);
}
}
$clearCache(cacheKey: string): Promise<void> {
this._fileSearchManager.clearCache(cacheKey);
return Promise.resolve(undefined);
}
$provideTextSearchResults(handle: number, session: number, rawQuery: IRawTextQuery, token: vscode.CancellationToken): Promise<ISearchCompleteStats> {
const provider = this._textSearchProvider.get(handle);
if (!provider || !provider.provideTextSearchResults) {
throw new Error(`Unknown provider ${handle}`);
}
const query = reviveQuery(rawQuery);
const engine = this.createTextSearchManager(query, provider);
return engine.search(progress => this._proxy.$handleTextMatch(handle, session, progress), token);
}
protected createTextSearchManager(query: ITextQuery, provider: vscode.TextSearchProvider): TextSearchManager {
return new TextSearchManager(query, provider, {
readdir: resource => Promise.resolve([]), // TODO@rob implement
toCanonicalName: encoding => encoding
});
}
}
export function reviveQuery<U extends IRawQuery>(rawQuery: U): U extends IRawTextQuery ? ITextQuery : IFileQuery {
return {
...<any>rawQuery, // TODO@rob ???
...{
folderQueries: rawQuery.folderQueries && rawQuery.folderQueries.map(reviveFolderQuery),
extraFileResources: rawQuery.extraFileResources && rawQuery.extraFileResources.map(components => URI.revive(components))
}
};
}
function reviveFolderQuery(rawFolderQuery: IFolderQuery<UriComponents>): IFolderQuery<URI> {
return {
...rawFolderQuery,
folder: URI.revive(rawFolderQuery.folder)
};
}
+11 -6
View File
@@ -24,6 +24,7 @@ import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitData
import { createDecorator } from 'vs/platform/instantiation/common/instantiation';
import { Schemas } from 'vs/base/common/network';
import * as Platform from 'vs/base/common/platform';
import { ILogService } from 'vs/platform/log/common/log';
export interface IExtHostTask extends ExtHostTaskShape {
@@ -374,6 +375,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
protected readonly _editorService: IExtHostDocumentsAndEditors;
protected readonly _configurationService: IExtHostConfiguration;
protected readonly _terminalService: IExtHostTerminalService;
protected readonly _logService: ILogService;
protected _handleCounter: number;
protected _handlers: Map<number, HandlerData>;
protected _taskExecutions: Map<string, TaskExecutionImpl>;
@@ -393,7 +395,8 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
@IExtHostWorkspace workspaceService: IExtHostWorkspace,
@IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors,
@IExtHostConfiguration configurationService: IExtHostConfiguration,
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService,
@ILogService logService: ILogService
) {
this._proxy = extHostRpc.getProxy(MainContext.MainThreadTask);
this._workspaceProvider = workspaceService;
@@ -406,6 +409,7 @@ export abstract class ExtHostTaskBase implements ExtHostTaskShape {
this._providedCustomExecutions2 = new Map<string, types.CustomExecution>();
this._notProvidedCustomExecutions = new Set<string>();
this._activeCustomExecutions2 = new Map<string, types.CustomExecution>();
this._logService = logService;
}
public registerTaskProvider(extension: IExtensionDescription, type: string, provider: vscode.TaskProvider): vscode.Disposable {
@@ -661,9 +665,10 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
@IExtHostWorkspace workspaceService: IExtHostWorkspace,
@IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors,
@IExtHostConfiguration configurationService: IExtHostConfiguration,
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService,
@ILogService logService: ILogService
) {
super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService);
super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService, logService);
if (initData.remote.isRemote && initData.remote.authority) {
this.registerTaskSystem(Schemas.vscodeRemote, {
scheme: Schemas.vscodeRemote,
@@ -696,7 +701,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
if (value) {
for (let task of value) {
if (!task.definition || !validTypes[task.definition.type]) {
console.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`);
this._logService.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`);
}
const taskDTO: tasks.TaskDTO | undefined = TaskDTO.from(task, handler.extension);
@@ -707,7 +712,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
// is invoked, we have to be able to map it back to our data.
taskIdPromises.push(this.addCustomExecution(taskDTO, task, true));
} else {
console.warn('Only custom execution tasks supported.');
this._logService.warn('Only custom execution tasks supported.');
}
}
}
@@ -721,7 +726,7 @@ export class WorkerExtHostTask extends ExtHostTaskBase {
if (CustomExecutionDTO.is(resolvedTaskDTO.execution)) {
return resolvedTaskDTO;
} else {
console.warn('Only custom execution tasks supported.');
this._logService.warn('Only custom execution tasks supported.');
}
return undefined;
}
@@ -198,7 +198,13 @@ class ExtHostTreeView<T> extends Disposable {
private refreshPromise: Promise<void> = Promise.resolve();
private refreshQueue: Promise<void> = Promise.resolve();
constructor(private viewId: string, options: vscode.TreeViewOptions<T>, private proxy: MainThreadTreeViewsShape, private commands: CommandsConverter, private logService: ILogService, private extension: IExtensionDescription) {
constructor(
private viewId: string, options: vscode.TreeViewOptions<T>,
private proxy: MainThreadTreeViewsShape,
private commands: CommandsConverter,
private logService: ILogService,
private extension: IExtensionDescription
) {
super();
if (extension.contributes && extension.contributes.views) {
for (const location in extension.contributes.views) {
@@ -250,7 +256,7 @@ class ExtHostTreeView<T> extends Disposable {
getChildren(parentHandle: TreeItemHandle | Root): Promise<ITreeItem[]> {
const parentElement = parentHandle ? this.getExtensionElement(parentHandle) : undefined;
if (parentHandle && !parentElement) {
console.error(`No tree item with id \'${parentHandle}\' found.`);
this.logService.error(`No tree item with id \'${parentHandle}\' found.`);
return Promise.resolve([]);
}
+2 -2
View File
@@ -1143,8 +1143,8 @@ export class SelectionRange {
export class CallHierarchyItem {
_sessionId: string;
_itemId: string;
_sessionId?: string;
_itemId?: string;
kind: SymbolKind;
name: string;
@@ -18,7 +18,7 @@ import { ExtHostTask } from 'vs/workbench/api/node/extHostTask';
import { ExtHostDebugService } from 'vs/workbench/api/node/extHostDebugService';
import { IExtHostDebugService } from 'vs/workbench/api/common/extHostDebugService';
import { IExtHostSearch } from 'vs/workbench/api/common/extHostSearch';
import { ExtHostSearch } from 'vs/workbench/api/node/extHostSearch';
import { NativeExtHostSearch } from 'vs/workbench/api/node/extHostSearch';
import { ExtensionStoragePaths } from 'vs/workbench/api/node/extHostStoragePaths';
import { IExtensionStoragePaths } from 'vs/workbench/api/common/extHostStoragePaths';
import { IExtHostExtensionService } from 'vs/workbench/api/common/extHostExtensionService';
@@ -38,7 +38,7 @@ registerSingleton(IExtHostDocumentsAndEditors, ExtHostDocumentsAndEditors);
registerSingleton(IExtHostTerminalService, ExtHostTerminalService);
registerSingleton(IExtHostTask, ExtHostTask);
registerSingleton(IExtHostDebugService, ExtHostDebugService);
registerSingleton(IExtHostSearch, ExtHostSearch);
registerSingleton(IExtHostSearch, NativeExtHostSearch);
registerSingleton(IExtensionStoragePaths, ExtensionStoragePaths);
registerSingleton(IExtHostExtensionService, ExtHostExtensionService);
registerSingleton(IExtHostStorage, ExtHostStorage);
+20 -99
View File
@@ -3,47 +3,37 @@
* Licensed under the MIT License. See License.txt in the project root for license information.
*--------------------------------------------------------------------------------------------*/
import { CancellationToken } from 'vs/base/common/cancellation';
import { IDisposable, toDisposable } from 'vs/base/common/lifecycle';
import { URI, UriComponents } from 'vs/base/common/uri';
import { URI } from 'vs/base/common/uri';
import * as pfs from 'vs/base/node/pfs';
import { ILogService } from 'vs/platform/log/common/log';
import { IFileQuery, IFolderQuery, IRawFileQuery, IRawQuery, IRawTextQuery, ISearchCompleteStats, ITextQuery, isSerializedFileMatch, ISerializedSearchProgressItem } from 'vs/workbench/services/search/common/search';
import { FileSearchManager } from 'vs/workbench/services/search/common/fileSearchManager';
import { IFileQuery, IRawFileQuery, ISearchCompleteStats, isSerializedFileMatch, ISerializedSearchProgressItem, ITextQuery } from 'vs/workbench/services/search/common/search';
import { SearchService } from 'vs/workbench/services/search/node/rawSearchService';
import { RipgrepSearchProvider } from 'vs/workbench/services/search/node/ripgrepSearchProvider';
import { OutputChannel } from 'vs/workbench/services/search/node/ripgrepSearchUtils';
import { TextSearchManager } from 'vs/workbench/services/search/node/textSearchManager';
import * as vscode from 'vscode';
import { ExtHostSearchShape, MainContext, MainThreadSearchShape } from '../common/extHost.protocol';
import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IURITransformerService } from 'vs/workbench/api/common/extHostUriTransformerService';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { ExtHostSearch, reviveQuery } from 'vs/workbench/api/common/extHostSearch';
import { Schemas } from 'vs/base/common/network';
import { NativeTextSearchManager } from 'vs/workbench/services/search/node/textSearchManager';
import { TextSearchManager } from 'vs/workbench/services/search/common/textSearchManager';
export class ExtHostSearch implements ExtHostSearchShape {
export class NativeExtHostSearch extends ExtHostSearch {
private readonly _proxy: MainThreadSearchShape;
private readonly _textSearchProvider = new Map<number, vscode.TextSearchProvider>();
private readonly _textSearchUsedSchemes = new Set<string>();
private readonly _fileSearchProvider = new Map<number, vscode.FileSearchProvider>();
private readonly _fileSearchUsedSchemes = new Set<string>();
private _handlePool: number = 0;
protected _pfs: typeof pfs = pfs; // allow extending for tests
private _internalFileSearchHandle: number = -1;
private _internalFileSearchProvider: SearchService | null = null;
private _fileSearchManager: FileSearchManager;
protected _pfs: typeof pfs = pfs; // allow extending for tests
constructor(
@IExtHostRpcService extHostRpc: IExtHostRpcService,
@IExtHostInitDataService initData: IExtHostInitDataService,
@IURITransformerService private _uriTransformer: IURITransformerService,
@ILogService private _logService: ILogService,
@IURITransformerService _uriTransformer: IURITransformerService,
@ILogService _logService: ILogService,
) {
this._proxy = extHostRpc.getProxy(MainContext.MainThreadSearch);
this._fileSearchManager = new FileSearchManager();
super(extHostRpc, _uriTransformer, _logService);
if (initData.remote.isRemote && initData.remote.authority) {
this._registerEHSearchProviders();
@@ -52,8 +42,8 @@ export class ExtHostSearch implements ExtHostSearchShape {
private _registerEHSearchProviders(): void {
const outputChannel = new OutputChannel(this._logService);
this.registerTextSearchProvider('file', new RipgrepSearchProvider(outputChannel));
this.registerInternalFileSearchProvider('file', new SearchService());
this.registerTextSearchProvider(Schemas.file, new RipgrepSearchProvider(outputChannel));
this.registerInternalFileSearchProvider(Schemas.file, new SearchService());
}
private registerInternalFileSearchProvider(scheme: string, provider: SearchService): IDisposable {
@@ -67,59 +57,16 @@ export class ExtHostSearch implements ExtHostSearchShape {
});
}
private _transformScheme(scheme: string): string {
return this._uriTransformer.transformOutgoingScheme(scheme);
}
registerTextSearchProvider(scheme: string, provider: vscode.TextSearchProvider): IDisposable {
if (this._textSearchUsedSchemes.has(scheme)) {
throw new Error(`a text search provider for the scheme '${scheme}' is already registered`);
}
this._textSearchUsedSchemes.add(scheme);
const handle = this._handlePool++;
this._textSearchProvider.set(handle, provider);
this._proxy.$registerTextSearchProvider(handle, this._transformScheme(scheme));
return toDisposable(() => {
this._textSearchUsedSchemes.delete(scheme);
this._textSearchProvider.delete(handle);
this._proxy.$unregisterProvider(handle);
});
}
registerFileSearchProvider(scheme: string, provider: vscode.FileSearchProvider): IDisposable {
if (this._fileSearchUsedSchemes.has(scheme)) {
throw new Error(`a file search provider for the scheme '${scheme}' is already registered`);
}
this._fileSearchUsedSchemes.add(scheme);
const handle = this._handlePool++;
this._fileSearchProvider.set(handle, provider);
this._proxy.$registerFileSearchProvider(handle, this._transformScheme(scheme));
return toDisposable(() => {
this._fileSearchUsedSchemes.delete(scheme);
this._fileSearchProvider.delete(handle);
this._proxy.$unregisterProvider(handle);
});
}
$provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: CancellationToken): Promise<ISearchCompleteStats> {
$provideFileSearchResults(handle: number, session: number, rawQuery: IRawFileQuery, token: vscode.CancellationToken): Promise<ISearchCompleteStats> {
const query = reviveQuery(rawQuery);
if (handle === this._internalFileSearchHandle) {
return this.doInternalFileSearch(handle, session, query, token);
} else {
const provider = this._fileSearchProvider.get(handle);
if (provider) {
return this._fileSearchManager.fileSearch(query, provider, batch => {
this._proxy.$handleFileMatch(handle, session, batch.map(p => p.resource));
}, token);
} else {
throw new Error('unknown provider: ' + handle);
}
}
return super.$provideFileSearchResults(handle, session, rawQuery, token);
}
private doInternalFileSearch(handle: number, session: number, rawQuery: IFileQuery, token: CancellationToken): Promise<ISearchCompleteStats> {
private doInternalFileSearch(handle: number, session: number, rawQuery: IFileQuery, token: vscode.CancellationToken): Promise<ISearchCompleteStats> {
const onResult = (ev: ISerializedSearchProgressItem) => {
if (isSerializedFileMatch(ev)) {
ev = [ev];
@@ -147,37 +94,11 @@ export class ExtHostSearch implements ExtHostSearchShape {
this._internalFileSearchProvider.clearCache(cacheKey);
}
this._fileSearchManager.clearCache(cacheKey);
return Promise.resolve(undefined);
return super.$clearCache(cacheKey);
}
$provideTextSearchResults(handle: number, session: number, rawQuery: IRawTextQuery, token: CancellationToken): Promise<ISearchCompleteStats> {
const provider = this._textSearchProvider.get(handle);
if (!provider || !provider.provideTextSearchResults) {
throw new Error(`Unknown provider ${handle}`);
}
const query = reviveQuery(rawQuery);
const engine = new TextSearchManager(query, provider, this._pfs);
return engine.search(progress => this._proxy.$handleTextMatch(handle, session, progress), token);
protected createTextSearchManager(query: ITextQuery, provider: vscode.TextSearchProvider): TextSearchManager {
return new NativeTextSearchManager(query, provider);
}
}
function reviveQuery<U extends IRawQuery>(rawQuery: U): U extends IRawTextQuery ? ITextQuery : IFileQuery {
return {
...<any>rawQuery, // TODO
...{
folderQueries: rawQuery.folderQueries && rawQuery.folderQueries.map(reviveFolderQuery),
extraFileResources: rawQuery.extraFileResources && rawQuery.extraFileResources.map(components => URI.revive(components))
}
};
}
function reviveFolderQuery(rawFolderQuery: IFolderQuery<UriComponents>): IFolderQuery<URI> {
return {
...rawFolderQuery,
folder: URI.revive(rawFolderQuery.folder)
};
}
+5 -3
View File
@@ -22,6 +22,7 @@ import { IExtHostRpcService } from 'vs/workbench/api/common/extHostRpcService';
import { IExtHostInitDataService } from 'vs/workbench/api/common/extHostInitDataService';
import { ExtHostTaskBase, TaskHandleDTO, TaskDTO, CustomExecutionDTO, HandlerData } from 'vs/workbench/api/common/extHostTask';
import { Schemas } from 'vs/base/common/network';
import { ILogService } from 'vs/platform/log/common/log';
export class ExtHostTask extends ExtHostTaskBase {
private _variableResolver: ExtHostVariableResolverService | undefined;
@@ -32,9 +33,10 @@ export class ExtHostTask extends ExtHostTaskBase {
@IExtHostWorkspace workspaceService: IExtHostWorkspace,
@IExtHostDocumentsAndEditors editorService: IExtHostDocumentsAndEditors,
@IExtHostConfiguration configurationService: IExtHostConfiguration,
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService
@IExtHostTerminalService extHostTerminalService: IExtHostTerminalService,
@ILogService logService: ILogService
) {
super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService);
super(extHostRpc, initData, workspaceService, editorService, configurationService, extHostTerminalService, logService);
if (initData.remote.isRemote && initData.remote.authority) {
this.registerTaskSystem(Schemas.vscodeRemote, {
scheme: Schemas.vscodeRemote,
@@ -71,7 +73,7 @@ export class ExtHostTask extends ExtHostTaskBase {
if (value) {
for (let task of value) {
if (!task.definition || !validTypes[task.definition.type]) {
console.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`);
this._logService.warn(`The task [${task.source}, ${task.name}] uses an undefined task type. The task will be ignored in the future.`);
}
const taskDTO: tasks.TaskDTO | undefined = TaskDTO.from(task, handler.extension);
+7
View File
@@ -747,6 +747,13 @@ export abstract class Layout extends Disposable implements IWorkbenchLayoutServi
if (config.silentNotifications) {
this.notificationService.setFilter(NotificationsFilter.ERROR);
}
this.state.zenMode.transitionDisposables.add(this.configurationService.onDidChangeConfiguration(c => {
const silentNotificationsKey = 'zenMode.silentNotifications';
if (c.affectsConfiguration(silentNotificationsKey)) {
const filter = this.configurationService.getValue(silentNotificationsKey) ? NotificationsFilter.ERROR : NotificationsFilter.OFF;
this.notificationService.setFilter(filter);
}
}));
if (config.centerLayout) {
this.centerEditorLayout(true, true);
@@ -93,7 +93,7 @@ export abstract class BaseBinaryResourceEditor extends BaseEditor {
}
const [binaryContainer, scrollbar] = assertAllDefined(this.binaryContainer, this.scrollbar);
this.resourceViewerContext = ResourceViewer.show({ name: model.getName(), resource: model.getResource(), size: model.getSize(), etag: model.getETag(), mime: model.getMime() }, binaryContainer, scrollbar, {
this.resourceViewerContext = ResourceViewer.show({ name: model.getName(), resource: model.resource, size: model.getSize(), etag: model.getETag(), mime: model.getMime() }, binaryContainer, scrollbar, {
openInternalClb: () => this.handleOpenInternalCallback(input, options),
openExternalClb: this.environmentService.configuration.remoteAuthority ? undefined : resource => this.callbacks.openExternal(resource),
metadataClb: meta => this.handleMetadataChanged(meta)
@@ -6,7 +6,7 @@
import 'vs/css!./media/editorstatus';
import * as nls from 'vs/nls';
import { runAtThisOrScheduleAtNextAnimationFrame } from 'vs/base/browser/dom';
import { format } from 'vs/base/common/strings';
import { format, compare } from 'vs/base/common/strings';
import { extname, basename, isEqual } from 'vs/base/common/resources';
import { areFunctions, withNullAsUndefined, withUndefinedAsNull } from 'vs/base/common/types';
import { URI } from 'vs/base/common/uri';
@@ -50,6 +50,8 @@ import { Event } from 'vs/base/common/event';
import { IAccessibilityService, AccessibilitySupport } from 'vs/platform/accessibility/common/accessibility';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { IStatusbarEntryAccessor, IStatusbarService, StatusbarAlignment, IStatusbarEntry } from 'vs/workbench/services/statusbar/common/statusbar';
import { IMarker, IMarkerService, MarkerSeverity, IMarkerData } from 'vs/platform/markers/common/markers';
import { find } from 'vs/base/common/arrays';
class SideBySideEditorEncodingSupport implements IEncodingSupport {
constructor(private master: IEncodingSupport, private details: IEncodingSupport) { }
@@ -282,6 +284,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
private readonly eolElement = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
private readonly modeElement = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
private readonly metadataElement = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
private readonly currentProblemStatus: ShowCurrentMarkerInStatusbarContribution = this._register(this.instantiationService.createInstance(ShowCurrentMarkerInStatusbarContribution));
private readonly state = new State();
private readonly activeEditorListeners = this._register(new DisposableStore());
@@ -299,7 +302,8 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
@IConfigurationService private readonly configurationService: IConfigurationService,
@INotificationService private readonly notificationService: INotificationService,
@IAccessibilityService private readonly accessibilityService: IAccessibilityService,
@IStatusbarService private readonly statusbarService: IStatusbarService
@IStatusbarService private readonly statusbarService: IStatusbarService,
@IInstantiationService private readonly instantiationService: IInstantiationService,
) {
super();
@@ -577,6 +581,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
this.onEncodingChange(activeControl, activeCodeEditor);
this.onIndentationChange(activeCodeEditor);
this.onMetadataChange(activeControl);
this.currentProblemStatus.update(activeCodeEditor);
// Dispose old active editor listeners
this.activeEditorListeners.clear();
@@ -594,6 +599,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
// Hook Listener for Selection changes
this.activeEditorListeners.add(activeCodeEditor.onDidChangeCursorPosition((event: ICursorPositionChangedEvent) => {
this.onSelectionChange(activeCodeEditor);
this.currentProblemStatus.update(activeCodeEditor);
}));
// Hook Listener for mode changes
@@ -604,6 +610,7 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
// Hook Listener for content changes
this.activeEditorListeners.add(activeCodeEditor.onDidChangeModelContent((e) => {
this.onEOLChange(activeCodeEditor);
this.currentProblemStatus.update(activeCodeEditor);
const selections = activeCodeEditor.getSelections();
if (selections) {
@@ -824,6 +831,130 @@ export class EditorStatus extends Disposable implements IWorkbenchContribution {
}
}
class ShowCurrentMarkerInStatusbarContribution extends Disposable {
private readonly statusBarEntryAccessor: MutableDisposable<IStatusbarEntryAccessor>;
private editor: ICodeEditor | undefined = undefined;
private markers: IMarker[] = [];
private currentMarker: IMarker | null = null;
constructor(
@IStatusbarService private readonly statusbarService: IStatusbarService,
@IMarkerService private readonly markerService: IMarkerService,
@IConfigurationService private readonly configurationService: IConfigurationService,
) {
super();
this.statusBarEntryAccessor = this._register(new MutableDisposable<IStatusbarEntryAccessor>());
this._register(markerService.onMarkerChanged(changedResources => this.onMarkerChanged(changedResources)));
this._register(Event.filter(configurationService.onDidChangeConfiguration, e => e.affectsConfiguration('problems.showCurrentInStatus'))(() => this.updateStatus()));
}
update(editor: ICodeEditor | undefined): void {
this.editor = editor;
this.updateStatus();
}
private updateStatus(): void {
const previousMarker = this.currentMarker;
this.currentMarker = this.getMarker();
if (this.hasToUpdateStatus(previousMarker, this.currentMarker)) {
if (this.currentMarker) {
const line = this.currentMarker.message.split(/\r\n|\r|\n/g)[0];
const text = `${this.getType(this.currentMarker)} ${line}`;
if (!this.statusBarEntryAccessor.value) {
this.statusBarEntryAccessor.value = this.statusbarService.addEntry({ text: '' }, 'statusbar.currentProblem', nls.localize('currentProblem', "Current Problem"), StatusbarAlignment.LEFT);
}
this.statusBarEntryAccessor.value.update({ text });
} else {
this.statusBarEntryAccessor.clear();
}
}
}
private hasToUpdateStatus(previousMarker: IMarker | null, currentMarker: IMarker | null): boolean {
if (!currentMarker) {
return true;
}
if (!previousMarker) {
return true;
}
return IMarkerData.makeKey(previousMarker) !== IMarkerData.makeKey(currentMarker);
}
private getType(marker: IMarker): string {
switch (marker.severity) {
case MarkerSeverity.Error: return '$(error)';
case MarkerSeverity.Warning: return '$(warning)';
case MarkerSeverity.Info: return '$(info)';
}
return '';
}
private getMarker(): IMarker | null {
if (!this.configurationService.getValue<boolean>('problems.showCurrentInStatus')) {
return null;
}
if (!this.editor) {
return null;
}
const model = this.editor.getModel();
if (!model) {
return null;
}
const position = this.editor.getPosition();
if (!position) {
return null;
}
return find(this.markers, marker => Range.containsPosition(marker, position)) || null;
}
private onMarkerChanged(changedResources: ReadonlyArray<URI>): void {
if (!this.editor) {
return;
}
const model = this.editor.getModel();
if (!model) {
return;
}
if (model && !changedResources.some(r => isEqual(model.uri, r))) {
return;
}
this.updateMarkers();
}
private updateMarkers(): void {
if (!this.editor) {
return;
}
const model = this.editor.getModel();
if (!model) {
return;
}
if (model) {
this.markers = this.markerService.read({
resource: model.uri,
severities: MarkerSeverity.Error | MarkerSeverity.Warning | MarkerSeverity.Info
});
this.markers.sort(compareMarker);
} else {
this.markers = [];
}
this.updateStatus();
}
}
function compareMarker(a: IMarker, b: IMarker): number {
let res = compare(a.resource.toString(), b.resource.toString());
if (res === 0) {
res = MarkerSeverity.compare(a.severity, b.severity);
}
if (res === 0) {
res = Range.compareRangesUsingStarts(a, b);
}
return res;
}
function isWritableCodeEditor(codeEditor: ICodeEditor | undefined): boolean {
if (!codeEditor) {
return false;
@@ -33,6 +33,7 @@ import { EditorMemento } from 'vs/workbench/browser/parts/editor/baseEditor';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { EditorActivation, IEditorOptions } from 'vs/platform/editor/common/editor';
import { IClipboardService } from 'vs/platform/clipboard/common/clipboardService';
import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService';
/**
* The text editor that leverages the diff text editor for the editing experience.
@@ -55,8 +56,9 @@ export class TextDiffEditor extends BaseTextEditor implements ITextDiffEditor {
@ITextFileService textFileService: ITextFileService,
@IHostService hostService: IHostService,
@IClipboardService private _clipboardService: IClipboardService,
@IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService
) {
super(TextDiffEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService);
super(TextDiffEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService, autoSaveConfigurationService);
}
protected getEditorMemento<T>(editorGroupService: IEditorGroupsService, key: string, limit: number = 10): IEditorMemento<T> {
@@ -16,7 +16,7 @@ import { IStorageService } from 'vs/platform/storage/common/storage';
import { IInstantiationService } from 'vs/platform/instantiation/common/instantiation';
import { ITelemetryService } from 'vs/platform/telemetry/common/telemetry';
import { IThemeService } from 'vs/platform/theme/common/themeService';
import { ITextFileService, SaveReason, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles';
import { ITextFileService, SaveReason } from 'vs/workbench/services/textfile/common/textfiles';
import { ITextResourceConfigurationService } from 'vs/editor/common/services/resourceConfiguration';
import { IEditorOptions } from 'vs/editor/common/config/editorOptions';
import { isDiffEditor, isCodeEditor, getCodeEditor } from 'vs/editor/browser/editorBrowser';
@@ -24,6 +24,7 @@ import { IEditorGroupsService, IEditorGroup } from 'vs/workbench/services/editor
import { CancellationToken } from 'vs/base/common/cancellation';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IAutoSaveConfigurationService, AutoSaveMode } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService';
const TEXT_EDITOR_VIEW_STATE_PREFERENCE_KEY = 'textEditorViewState';
@@ -53,7 +54,8 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
@ITextFileService private readonly _textFileService: ITextFileService,
@IEditorService protected editorService: IEditorService,
@IEditorGroupsService protected editorGroupService: IEditorGroupsService,
@IHostService private readonly hostService: IHostService
@IHostService private readonly hostService: IHostService,
@IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService
) {
super(id, telemetryService, themeService, storageService);
@@ -165,7 +167,7 @@ export abstract class BaseTextEditor extends BaseEditor implements ITextEditor {
}
private maybeTriggerSaveAll(reason: SaveReason): void {
const mode = this.textFileService.getAutoSaveMode();
const mode = this.autoSaveConfigurationService.getAutoSaveMode();
// Determine if we need to save all. In case of a window focus change we also save if auto save mode
// is configured to be ON_FOCUS_CHANGE (editor focus change)
@@ -24,6 +24,7 @@ import { IEditorGroupsService } from 'vs/workbench/services/editor/common/editor
import { CancellationToken } from 'vs/base/common/cancellation';
import { IEditorService } from 'vs/workbench/services/editor/common/editorService';
import { IHostService } from 'vs/workbench/services/host/browser/host';
import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService';
/**
* An editor implementation that is capable of showing the contents of resource inputs. Uses
@@ -41,9 +42,10 @@ export class AbstractTextResourceEditor extends BaseTextEditor {
@IEditorGroupsService editorGroupService: IEditorGroupsService,
@ITextFileService textFileService: ITextFileService,
@IEditorService editorService: IEditorService,
@IHostService hostService: IHostService
@IHostService hostService: IHostService,
@IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService
) {
super(id, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService);
super(id, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService, autoSaveConfigurationService);
}
getTitle(): string | undefined {
@@ -205,8 +207,9 @@ export class TextResourceEditor extends AbstractTextResourceEditor {
@ITextFileService textFileService: ITextFileService,
@IEditorService editorService: IEditorService,
@IEditorGroupsService editorGroupService: IEditorGroupsService,
@IHostService hostService: IHostService
@IHostService hostService: IHostService,
@IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService
) {
super(TextResourceEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, editorGroupService, textFileService, editorService, hostService);
super(TextResourceEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, editorGroupService, textFileService, editorService, hostService, autoSaveConfigurationService);
}
}
@@ -84,6 +84,7 @@ interface QuickInputUI {
onDidTriggerButton: Event<IQuickInputButton>;
ignoreFocusOut: boolean;
keyMods: Writeable<IKeyMods>;
keyDownSeenSinceShown: boolean;
isScreenReaderOptimized(): boolean;
show(controller: QuickInput): void;
setVisibilities(visibilities: Visibilities): void;
@@ -216,6 +217,7 @@ class QuickInput extends Disposable implements IQuickInput {
}
}),
);
this.ui.keyDownSeenSinceShown = false;
this.ui.show(this);
this.visible = true;
this.update();
@@ -554,6 +556,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
}
}));
this.visibleDisposables.add(this.ui.inputBox.onKeyDown(event => {
this.ui.keyDownSeenSinceShown = true;
switch (event.keyCode) {
case KeyCode.DownArrow:
this.ui.list.focus('Next');
@@ -652,7 +655,7 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
private registerQuickNavigation() {
return dom.addDisposableListener(this.ui.container, dom.EventType.KEY_UP, e => {
if (this.canSelectMany || !this.quickNavigate) {
if (this.canSelectMany || !this.quickNavigate || !this.ui.keyDownSeenSinceShown) {
return;
}
@@ -699,10 +702,11 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
}
protected update() {
super.update();
if (!this.visible) {
return;
}
this.ui.setVisibilities(this.canSelectMany ? { title: !!this.title || !!this.step, checkAll: true, inputBox: true, visibleCount: true, count: true, ok: true, list: true, message: !!this.validationMessage } : { title: !!this.title || !!this.step, inputBox: true, visibleCount: true, list: true, message: !!this.validationMessage, customButton: this.customButton, ok: this.ok });
super.update();
if (this.ui.inputBox.value !== this.value) {
this.ui.inputBox.value = this.value;
}
@@ -763,7 +767,6 @@ class QuickPick<T extends IQuickPickItem> extends QuickInput implements IQuickPi
this.ui.list.matchOnLabel = this.matchOnLabel;
this.ui.setComboboxAccessibility(true);
this.ui.inputBox.setAttribute('aria-label', QuickPick.INPUT_BOX_ARIA_LABEL);
this.ui.setVisibilities(this.canSelectMany ? { title: !!this.title || !!this.step, checkAll: true, inputBox: true, visibleCount: true, count: true, ok: true, list: true, message: !!this.validationMessage } : { title: !!this.title || !!this.step, inputBox: true, visibleCount: true, list: true, message: !!this.validationMessage, customButton: this.customButton, ok: this.ok });
}
}
@@ -857,10 +860,11 @@ class InputBox extends QuickInput implements IInputBox {
}
protected update() {
super.update();
if (!this.visible) {
return;
}
this.ui.setVisibilities({ title: !!this.title || !!this.step, inputBox: true, message: true });
super.update();
if (this.ui.inputBox.value !== this.value) {
this.ui.inputBox.value = this.value;
}
@@ -882,7 +886,6 @@ class InputBox extends QuickInput implements IInputBox {
this.ui.message.textContent = this.validationMessage;
this.showMessageDecoration(Severity.Error);
}
this.ui.setVisibilities({ title: !!this.title || !!this.step, inputBox: true, message: true });
}
}
@@ -1111,6 +1114,7 @@ export class QuickInputService extends Component implements IQuickInputService {
inputBox.setFocus();
}));
this._register(dom.addDisposableListener(container, dom.EventType.KEY_DOWN, (e: KeyboardEvent) => {
this.getUI().keyDownSeenSinceShown = true;
const event = new StandardKeyboardEvent(e);
switch (event.keyCode) {
case KeyCode.Enter:
@@ -1172,6 +1176,7 @@ export class QuickInputService extends Component implements IQuickInputService {
onDidTriggerButton: this.onDidTriggerButtonEmitter.event,
ignoreFocusOut: false,
keyMods: this.keyMods,
keyDownSeenSinceShown: false,
isScreenReaderOptimized: () => this.isScreenReaderOptimized(),
show: controller => this.show(controller),
hide: () => this.hide(),
@@ -22,7 +22,7 @@ import { HighlightedLabel } from 'vs/base/browser/ui/highlightedlabel/highlighte
import { memoize } from 'vs/base/common/decorators';
import { range } from 'vs/base/common/arrays';
import * as platform from 'vs/base/common/platform';
import { listFocusBackground, pickerGroupBorder, pickerGroupForeground, activeContrastBorder } from 'vs/platform/theme/common/colorRegistry';
import { listFocusBackground, pickerGroupBorder, pickerGroupForeground, activeContrastBorder, listFocusForeground } from 'vs/platform/theme/common/colorRegistry';
import { registerThemingParticipant } from 'vs/platform/theme/common/themeService';
import { ActionBar } from 'vs/base/browser/ui/actionbar/actionbar';
import { Action } from 'vs/base/common/actions';
@@ -590,18 +590,21 @@ function compareEntries(elementA: ListElement, elementB: ListElement, lookFor: s
}
registerThemingParticipant((theme, collector) => {
// Override inactive focus foreground with active focus foreground for single-pick case.
const listInactiveFocusForeground = theme.getColor(listFocusForeground);
if (listInactiveFocusForeground) {
collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused { color: ${listInactiveFocusForeground}; }`);
}
// Override inactive focus background with active focus background for single-pick case.
const listInactiveFocusBackground = theme.getColor(listFocusBackground);
if (listInactiveFocusBackground) {
collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused { background-color: ${listInactiveFocusBackground}; }`);
collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused:hover { background-color: ${listInactiveFocusBackground}; }`);
}
// dotted instead of solid (as in listWidget.ts) to match QuickOpen
const activeContrast = theme.getColor(activeContrastBorder);
if (activeContrast) {
collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused { border: 1px dotted ${activeContrast}; }`);
collector.addRule(`.quick-input-list .monaco-list .monaco-list-row { border: 1px solid transparent; }`);
collector.addRule(`.quick-input-list .monaco-list .quick-input-list-entry { padding: 0 5px; height: 18px; align-items: center; }`);
collector.addRule(`.quick-input-list .monaco-list .quick-input-list-entry-action-bar { margin-top: 0; }`);
collector.addRule(`.quick-input-list .monaco-list .monaco-list-row.focused { outline: 1px dotted ${activeContrast}; outline-offset: -1px; }`);
}
const pickerGroupBorderColor = theme.getColor(pickerGroupBorder);
if (pickerGroupBorderColor) {
@@ -16,7 +16,7 @@ import { Mode, IEntryRunContext, IAutoFocus, IQuickNavigateConfiguration, IModel
import { QuickOpenEntry, QuickOpenModel, QuickOpenEntryGroup, QuickOpenItemAccessorClass } from 'vs/base/parts/quickopen/browser/quickOpenModel';
import { QuickOpenWidget, HideReason } from 'vs/base/parts/quickopen/browser/quickOpenWidget';
import { ContributableActionProvider } from 'vs/workbench/browser/actions';
import { ITextFileService, AutoSaveMode } from 'vs/workbench/services/textfile/common/textfiles';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { Registry } from 'vs/platform/registry/common/platform';
import { IResourceInput } from 'vs/platform/editor/common/editor';
import { IModeService } from 'vs/editor/common/services/modeService';
@@ -51,6 +51,7 @@ import { IQuickInputService, IQuickPickItem } from 'vs/platform/quickinput/commo
import { CancellationTokenSource, CancellationToken } from 'vs/base/common/cancellation';
import { IStorageService } from 'vs/platform/storage/common/storage';
import { registerSingleton } from 'vs/platform/instantiation/common/extensions';
import { IAutoSaveConfigurationService, AutoSaveMode } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService';
const HELP_PREFIX = '?';
@@ -735,7 +736,8 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry {
@ITextFileService private readonly textFileService: ITextFileService,
@IConfigurationService private readonly configurationService: IConfigurationService,
@ILabelService labelService: ILabelService,
@IFileService fileService: IFileService
@IFileService fileService: IFileService,
@IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService
) {
super(editorService);
@@ -753,7 +755,7 @@ export class EditorHistoryEntry extends EditorQuickOpenEntry {
this.description = labelService.getUriLabel(resources.dirname(this.resource), { relative: true });
this.dirty = this.resource && this.textFileService.isDirty(this.resource);
if (this.dirty && this.textFileService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) {
if (this.dirty && this.autoSaveConfigurationService.getAutoSaveMode() === AutoSaveMode.AFTER_SHORT_DELAY) {
this.dirty = false; // no dirty decoration if auto save is on with a short timeout
}
}
@@ -611,7 +611,15 @@ export class CustomTreeView extends Disposable implements ITreeView {
if (tree && this.visible) {
this.refreshing = true;
await Promise.all(elements.map(element => tree.updateChildren(element, true)));
elements.map(element => tree.rerender(element));
elements.map(element => {
try {
tree.rerender(element);
} catch {
// noop
}
});
this.refreshing = false;
this.updateContentAreas();
if (this.focused) {
@@ -23,7 +23,7 @@ import { DefaultPanelDndController } from 'vs/base/browser/ui/splitview/panelvie
import { WorkbenchTree, IListService } from 'vs/platform/list/browser/listService';
import { IWorkbenchThemeService, IFileIconTheme } from 'vs/workbench/services/themes/common/workbenchThemeService';
import { ITreeConfiguration, ITreeOptions } from 'vs/base/parts/tree/browser/tree';
import { Event, Emitter } from 'vs/base/common/event';
import { Event } from 'vs/base/common/event';
import { IConfigurationService } from 'vs/platform/configuration/common/configuration';
import { IWorkbenchLayoutService } from 'vs/workbench/services/layout/browser/layoutService';
import { localize } from 'vs/nls';
@@ -328,12 +328,11 @@ export abstract class ViewContainerViewlet extends PanelViewlet implements IView
export abstract class FilterViewContainerViewlet extends ViewContainerViewlet {
private constantViewDescriptors: Map<string, IViewDescriptor> = new Map();
private allViews: Map<string, Map<string, IViewDescriptor>> = new Map();
private filterValue: string;
protected onDidChangeFilterValue: Emitter<string> = new Emitter();
private filterValue: string | undefined;
constructor(
viewletId: string,
onDidChangeFilterValue: Event<string>,
@IConfigurationService configurationService: IConfigurationService,
@IWorkbenchLayoutService layoutService: IWorkbenchLayoutService,
@ITelemetryService telemetryService: ITelemetryService,
@@ -345,7 +344,7 @@ export abstract class FilterViewContainerViewlet extends ViewContainerViewlet {
@IWorkspaceContextService contextService: IWorkspaceContextService
) {
super(viewletId, `${viewletId}.state`, false, configurationService, layoutService, telemetryService, storageService, instantiationService, themeService, contextMenuService, extensionService, contextService);
this._register(this.onDidChangeFilterValue.event(newFilterValue => {
this._register(onDidChangeFilterValue(newFilterValue => {
this.filterValue = newFilterValue;
this.onFilterChanged(newFilterValue);
}));
@@ -19,7 +19,7 @@ export class BinaryEditorModel extends EditorModel {
private readonly mime: string;
constructor(
private readonly resource: URI,
public readonly resource: URI,
private readonly name: string | undefined,
@IFileService private readonly fileService: IFileService
) {
@@ -49,13 +49,6 @@ export class BinaryEditorModel extends EditorModel {
return this.name || basename(this.resource);
}
/**
* The resource of the binary resource.
*/
getResource(): URI {
return this.resource;
}
/**
* The size of the binary resource if known.
*/
@@ -17,7 +17,9 @@ import { withUndefinedAsNull } from 'vs/base/common/types';
* The base text editor model leverages the code editor model. This class is only intended to be subclassed and not instantiated.
*/
export abstract class BaseTextEditorModel extends EditorModel implements ITextEditorModel, IModeSupport {
protected textEditorModelHandle: URI | null = null;
private createdEditorModel: boolean | undefined;
private readonly modelDisposeListener = this._register(new MutableDisposable());
@@ -16,8 +16,9 @@ import { ITextResourceConfigurationService } from 'vs/editor/common/services/res
import { ITextBufferFactory } from 'vs/editor/common/model';
import { createTextBufferFactory } from 'vs/editor/common/model/textModel';
import { IResolvedTextEditorModel } from 'vs/editor/common/services/resolverService';
import { IWorkingCopyService, IWorkingCopy } from 'vs/workbench/services/workingCopy/common/workingCopyService';
export class UntitledTextEditorModel extends BaseTextEditorModel implements IEncodingSupport {
export class UntitledTextEditorModel extends BaseTextEditorModel implements IEncodingSupport, IWorkingCopy {
static DEFAULT_CONTENT_CHANGE_BUFFER_DELAY = CONTENT_CHANGE_EVENT_BUFFER_DELAY;
@@ -30,33 +31,33 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IEnc
private readonly _onDidChangeEncoding: Emitter<void> = this._register(new Emitter<void>());
readonly onDidChangeEncoding: Event<void> = this._onDidChangeEncoding.event;
private dirty: boolean = false;
private versionId: number = 0;
private readonly contentChangeEventScheduler: RunOnceScheduler;
readonly capabilities = 0;
private dirty = false;
private versionId = 0;
private readonly contentChangeEventScheduler = this._register(new RunOnceScheduler(() => this._onDidChangeContent.fire(), UntitledTextEditorModel.DEFAULT_CONTENT_CHANGE_BUFFER_DELAY));
private configuredEncoding?: string;
constructor(
private readonly preferredMode: string | undefined,
private readonly resource: URI,
private _hasAssociatedFilePath: boolean,
public readonly resource: URI,
public readonly hasAssociatedFilePath: boolean,
private readonly initialValue: string | undefined,
private preferredEncoding: string | undefined,
@IModeService modeService: IModeService,
@IModelService modelService: IModelService,
@IBackupFileService private readonly backupFileService: IBackupFileService,
@ITextResourceConfigurationService private readonly configurationService: ITextResourceConfigurationService
@ITextResourceConfigurationService private readonly configurationService: ITextResourceConfigurationService,
@IWorkingCopyService private readonly workingCopyService: IWorkingCopyService
) {
super(modelService, modeService);
this.contentChangeEventScheduler = this._register(new RunOnceScheduler(() => this._onDidChangeContent.fire(), UntitledTextEditorModel.DEFAULT_CONTENT_CHANGE_BUFFER_DELAY));
// Make known to working copy service
this._register(this.workingCopyService.registerWorkingCopy(this));
this.registerListeners();
}
get hasAssociatedFilePath(): boolean {
return this._hasAssociatedFilePath;
}
private registerListeners(): void {
// Config Changes
@@ -114,10 +115,6 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IEnc
this._onDidChangeDirty.fire();
}
getResource(): URI {
return this.resource;
}
revert(): void {
this.setDirty(false);
@@ -147,7 +144,7 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IEnc
}
// untitled associated to file path are dirty right away as well as untitled with content
this.setDirty(this._hasAssociatedFilePath || !!backup || !!this.initialValue);
this.setDirty(this.hasAssociatedFilePath || !!backup || !!this.initialValue);
let untitledContents: ITextBufferFactory;
if (backup) {
@@ -190,7 +187,7 @@ export class UntitledTextEditorModel extends BaseTextEditorModel implements IEnc
// mark the untitled text editor as non-dirty once its content becomes empty and we do
// not have an associated path set. we never want dirty indicator in that case.
if (!this._hasAssociatedFilePath && this.textEditorModel.getLineCount() === 1 && this.textEditorModel.getLineContent(1) === '') {
if (!this.hasAssociatedFilePath && this.textEditorModel.getLineCount() === 1 && this.textEditorModel.getLineContent(1) === '') {
this.setDirty(false);
}
@@ -6,10 +6,11 @@
import { URI as Uri } from 'vs/base/common/uri';
import { IBackupFileService } from 'vs/workbench/services/backup/common/backup';
import { Disposable } from 'vs/base/common/lifecycle';
import { ITextFileService, TextFileModelChangeEvent, StateChange, IAutoSaveConfiguration } from 'vs/workbench/services/textfile/common/textfiles';
import { ITextFileService, TextFileModelChangeEvent, StateChange } from 'vs/workbench/services/textfile/common/textfiles';
import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
import { IWorkbenchContribution } from 'vs/workbench/common/contributions';
import { CONTENT_CHANGE_EVENT_BUFFER_DELAY } from 'vs/platform/files/common/files';
import { IAutoSaveConfigurationService, IAutoSaveConfiguration } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService';
const AUTO_SAVE_AFTER_DELAY_DISABLED_TIME = CONTENT_CHANGE_EVENT_BUFFER_DELAY + 500;
@@ -21,6 +22,7 @@ export class BackupModelTracker extends Disposable implements IWorkbenchContribu
@IBackupFileService private readonly backupFileService: IBackupFileService,
@ITextFileService private readonly textFileService: ITextFileService,
@IUntitledTextEditorService private readonly untitledTextEditorService: IUntitledTextEditorService,
@IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService
) {
super();
@@ -38,8 +40,8 @@ export class BackupModelTracker extends Disposable implements IWorkbenchContribu
this._register(this.untitledTextEditorService.onDidChangeContent(e => this.onUntitledModelChanged(e)));
this._register(this.untitledTextEditorService.onDidDisposeModel(e => this.discardBackup(e)));
// Listen to config changes
this._register(this.textFileService.onAutoSaveConfigurationChange(c => this.onAutoSaveConfigurationChange(c)));
// Listen to auto save config changes
this._register(this.autoSaveConfigurationService.onAutoSaveConfigurationChange(c => this.onAutoSaveConfigurationChange(c)));
}
private onAutoSaveConfigurationChange(configuration: IAutoSaveConfiguration): void {
@@ -800,7 +800,7 @@ class DisconnectAction extends Action {
private readonly session: IDebugSession,
@ICommandService private readonly commandService: ICommandService
) {
super(`action.${DISCONNECT_ID}`, DISCONNECT_LABEL, 'debug-action disconnect');
super(`action.${DISCONNECT_ID}`, DISCONNECT_LABEL, 'debug-action codicon-debug-disconnect');
}
public run(): Promise<any> {
@@ -416,7 +416,7 @@ export class ConfigurationManager implements IConfigurationManager {
return candidates.then(debuggers => {
debuggers.sort((first, second) => first.label.localeCompare(second.label));
const picks = debuggers.map(c => ({ label: c.label, debugger: c }));
return this.quickInputService.pick<{ label: string, debugger: Debugger | undefined }>([...picks, { type: 'separator' }, { label: 'More...', debugger: undefined }], { placeHolder: nls.localize('selectDebug', "Select Environment") })
return this.quickInputService.pick<{ label: string, debugger: Debugger | undefined }>([...picks, { type: 'separator' }, { label: nls.localize('more', "More..."), debugger: undefined }], { placeHolder: nls.localize('selectDebug', "Select Environment") })
.then(picked => {
if (picked && picked.debugger) {
return picked.debugger;
@@ -488,8 +488,6 @@ export class DebugService implements IDebugService {
}
const errorMessage = error instanceof Error ? error.message : error;
this.telemetryDebugMisconfiguration(session.configuration ? session.configuration.type : undefined, errorMessage);
await this.showError(errorMessage, isErrorWithActions(error) ? error.actions : []);
return false;
}
@@ -1201,19 +1199,6 @@ export class DebugService implements IDebugService {
});
}
private telemetryDebugMisconfiguration(debugType: string | undefined, message: string): Promise<any> {
/* __GDPR__
"debugMisconfiguration" : {
"type" : { "classification": "SystemMetaData", "purpose": "FeatureInsight" },
"error": { "classification": "CallstackOrException", "purpose": "FeatureInsight" }
}
*/
return this.telemetryService.publicLog('debugMisconfiguration', {
type: debugType,
error: message
});
}
private telemetryDebugAddBreakpoint(breakpoint: IBreakpoint, context: string): Promise<any> {
/* __GDPR__
"debugAddBreakpoint" : {
@@ -142,7 +142,7 @@ export class LinkDetector {
private decorateLink(link: HTMLElement, onclick: () => void) {
link.classList.add('link');
link.title = platform.isMacintosh ? nls.localize('fileLinkMac', "Cmd + click to follow link") : nls.localize('fileLink', "Ctrl + click to follow link");
link.onmousemove = (event) => link.classList.toggle('pointer', platform.isMacintosh ? event.metaKey : event.ctrlKey);
link.onmousemove = (event) => { link.classList.toggle('pointer', platform.isMacintosh ? event.metaKey : event.ctrlKey); };
link.onmouseleave = () => link.classList.remove('pointer');
link.onclick = (event) => {
const selection = window.getSelection();
@@ -120,7 +120,8 @@
}
.monaco-editor .debug-top-stack-frame.debug-breakpoint-and-top-stack-frame,
.monaco-editor .inline-breakpoint-widget.debug-breakpoint-and-top-stack-frame-at-column {
.monaco-editor .debug-breakpoint.debug-top-stack-frame,
.monaco-editor .debug-breakpoint-and-top-stack-frame-at-column {
background: url('current-and-breakpoint.svg') center center no-repeat;
}
@@ -17,9 +17,9 @@
.monaco-workbench .debug-toolbar .monaco-action-bar .action-item.select-container {
margin-right: 7px;
}
.monaco-workbench .debug-toolbar .monaco-action-bar .action-item.select-container .monaco-select-box,
.monaco-workbench .start-debug-action-item .select-container .monaco-select-box {
padding: 0 22px 0 6px;
}
@@ -140,9 +140,7 @@
text-transform: uppercase;
}
.debug-viewlet .debug-call-stack .thread:hover > .state,
.debug-viewlet .debug-call-stack .session:hover > .state,
.debug-viewlet .debug-call-stack .monaco-list-row.focused .state {
.debug-viewlet .debug-call-stack .monaco-list-row:hover .state {
display: none;
}
@@ -159,6 +157,7 @@
width: 16px;
height: 100%;
margin-right: 8px;
vertical-align: text-top;
}
.debug-viewlet .debug-call-stack .thread > .state > .label,
@@ -240,7 +239,7 @@
overflow: hidden;
}
.debug-viewlet .debug-call-stack .monaco-list:focus .monaco-list-row.selected.focused .codicon {
.debug-viewlet .debug-call-stack .monaco-list:focus .monaco-list-row.selected .codicon {
color: inherit !important;
}
@@ -167,18 +167,22 @@ export class ExperimentService extends Disposable implements IExperimentService
this.storageService.store(storageKey, JSON.stringify(experimentState), StorageScope.GLOBAL);
}
protected getExperiments(): Promise<IRawExperiment[] | null> {
protected async getExperiments(): Promise<IRawExperiment[] | null> {
if (!this.productService.experimentsUrl || this.configurationService.getValue('workbench.enableExperiments') === false) {
return Promise.resolve([]);
return [];
}
return this.requestService.request({ type: 'GET', url: this.productService.experimentsUrl }, CancellationToken.None).then(context => {
try {
const context = await this.requestService.request({ type: 'GET', url: this.productService.experimentsUrl }, CancellationToken.None);
if (context.res.statusCode !== 200) {
return Promise.resolve(null);
return null;
}
return asJson(context).then((result: any) => {
return result && Array.isArray(result['experiments']) ? result['experiments'] : [];
});
}, () => Promise.resolve(null));
const result: any = await asJson(context);
return result && Array.isArray(result['experiments']) ? result['experiments'] : [];
} catch (_e) {
// Bad request or invalid JSON
return null;
}
}
private loadExperiments(): Promise<any> {
@@ -506,15 +506,6 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
private async promptForImportantExeBasedExtension(): Promise<boolean> {
const storageKey = 'extensionsAssistant/workspaceRecommendationsIgnore';
const config = this.configurationService.getValue<IExtensionsConfiguration>(ConfigurationKey);
if (config.ignoreRecommendations
|| config.showRecommendationsOnlyOnDemand
|| this.storageService.getBoolean(storageKey, StorageScope.WORKSPACE, false)) {
return false;
}
let recommendationsToSuggest = Object.keys(this._importantExeBasedRecommendations);
const installed = await this.extensionManagementService.getInstalled(ExtensionType.User);
@@ -527,13 +518,23 @@ export class ExtensionTipsService extends Disposable implements IExtensionTipsSe
"exeName": { "classification": "PublicNonPersonalData", "purpose": "FeatureInsight" }
}
*/
this.telemetryService.publicLog('exeExtensionRecommendations:alreadyInstalled', { extensionId, exeName: tip.exeFriendlyName || basename(tip.windowsPath!) });
this.telemetryService.publicLog('exeExtensionRecommendations:alreadyInstalled', { extensionId, exeName: basename(tip.windowsPath!) });
});
if (recommendationsToSuggest.length === 0) {
return false;
}
const storageKey = 'extensionsAssistant/workspaceRecommendationsIgnore';
const config = this.configurationService.getValue<IExtensionsConfiguration>(ConfigurationKey);
if (config.ignoreRecommendations
|| config.showRecommendationsOnlyOnDemand
|| this.storageService.getBoolean(storageKey, StorageScope.WORKSPACE, false)) {
return false;
}
recommendationsToSuggest = this.filterIgnoredOrNotAllowed(recommendationsToSuggest);
if (recommendationsToSuggest.length === 0) {
return false;
@@ -442,7 +442,7 @@ export class ExtensionsViewlet extends ViewContainerViewlet implements IExtensio
if (this.searchBox) {
this.searchBox.layout({ height: 20, width: dimension.width - 34 });
}
super.layout(new Dimension(dimension.width, dimension.height - 38));
super.layout(new Dimension(dimension.width, dimension.height - 41));
}
getOptimalWidth(): number {
@@ -25,7 +25,7 @@
}
.extensions-viewlet > .extensions {
height: calc(100% - 38px);
height: calc(100% - 41px);
}
.extensions-viewlet > .extensions .extension-view-header .monaco-action-bar {
@@ -8,7 +8,7 @@ import { URI } from 'vs/base/common/uri';
import * as resources from 'vs/base/common/resources';
import { IEditorViewState } from 'vs/editor/common/editorCommon';
import { toResource, SideBySideEditorInput, IWorkbenchEditorConfiguration, SideBySideEditor as SideBySideEditorChoice } from 'vs/workbench/common/editor';
import { ITextFileService, ITextFileEditorModel } from 'vs/workbench/services/textfile/common/textfiles';
import { ITextFileService, ITextFileEditorModel, TextFileModelChangeEvent, ModelState } from 'vs/workbench/services/textfile/common/textfiles';
import { FileOperationEvent, FileOperation, IFileService, FileChangeType, FileChangesEvent } from 'vs/platform/files/common/files';
import { FileEditorInput } from 'vs/workbench/contrib/files/common/editors/fileEditorInput';
import { ILifecycleService } from 'vs/platform/lifecycle/common/lifecycle';
@@ -61,6 +61,9 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut
// Update editors from disk changes
this._register(this.fileService.onFileChanges(e => this.onFileChanges(e)));
// Open editors from dirty text file models
this._register(this.textFileService.models.onModelsDirty(e => this.onTextFilesDirty(e)));
// Editor changing
this._register(this.editorService.onDidVisibleEditorsChange(() => this.handleOutOfWorkspaceWatchers()));
@@ -95,7 +98,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut
return resource ? this.textFileService.models.get(resource) : undefined;
}))
.filter(model => !model.isDirty()),
m => m.getResource().toString()
m => m.resource.toString()
).forEach(model => this.queueModelLoad(model));
}
}
@@ -296,7 +299,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut
// and updated right after.
distinct(coalesce([...e.getUpdated(), ...e.getAdded()]
.map(u => this.textFileService.models.get(u.resource)))
.filter(model => model && !model.isDirty()), m => m.getResource().toString())
.filter(model => model && !model.isDirty()), m => m.resource.toString())
.forEach(model => this.queueModelLoad(model));
}
@@ -305,7 +308,7 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut
// Load model to update (use a queue to prevent accumulation of loads
// when the load actually takes long. At most we only want the queue
// to have a size of 2 (1 running load and 1 queued load).
const queue = this.modelLoadQueue.queueFor(model.getResource());
const queue = this.modelLoadQueue.queueFor(model.resource);
if (queue.size <= 1) {
queue.queue(() => model.load().then(undefined, onUnexpectedError));
}
@@ -359,6 +362,31 @@ export class FileEditorTracker extends Disposable implements IWorkbenchContribut
});
}
private onTextFilesDirty(e: readonly TextFileModelChangeEvent[]): void {
// If files become dirty but are not opened, we open it in the background unless there are pending to be saved
this.doOpenDirtyResources(distinct(e.filter(e => {
// Only dirty models that are not PENDING_SAVE
const model = this.textFileService.models.get(e.resource);
const shouldOpen = model?.isDirty() && !model.hasState(ModelState.PENDING_SAVE);
// Only if not open already
return shouldOpen && !this.editorService.isOpen({ resource: e.resource });
}).map(e => e.resource), r => r.toString()));
}
private doOpenDirtyResources(resources: URI[]): void {
// Open
this.editorService.openEditors(resources.map(resource => {
return {
resource,
options: { inactive: true, pinned: true, preserveFocus: true }
};
}));
}
dispose(): void {
super.dispose();
@@ -32,6 +32,7 @@ import { IEditorGroupView } from 'vs/workbench/browser/parts/editor/editor';
import { createErrorWithActions } from 'vs/base/common/errorsWithActions';
import { MutableDisposable } from 'vs/base/common/lifecycle';
import { EditorActivation, IEditorOptions } from 'vs/platform/editor/common/editor';
import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService';
/**
* An implementation of editor for file system resources.
@@ -56,9 +57,10 @@ export class TextFileEditor extends BaseTextEditor {
@IEditorGroupsService editorGroupService: IEditorGroupsService,
@ITextFileService textFileService: ITextFileService,
@IHostService hostService: IHostService,
@IExplorerService private readonly explorerService: IExplorerService
@IExplorerService private readonly explorerService: IExplorerService,
@IAutoSaveConfigurationService autoSaveConfigurationService: IAutoSaveConfigurationService
) {
super(TextFileEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService);
super(TextFileEditor.ID, telemetryService, instantiationService, storageService, configurationService, themeService, textFileService, editorService, editorGroupService, hostService, autoSaveConfigurationService);
this.updateRestoreViewStateConfiguration();
@@ -18,7 +18,7 @@ import { isMacintosh } from 'vs/base/common/platform';
import { FilesExplorerFocusCondition, ExplorerRootContext, ExplorerFolderContext, ExplorerResourceNotReadonlyContext, ExplorerResourceCut, IExplorerService, ExplorerResourceMoveableToTrash, ExplorerViewletVisibleContext } from 'vs/workbench/contrib/files/common/files';
import { ADD_ROOT_FOLDER_COMMAND_ID, ADD_ROOT_FOLDER_LABEL } from 'vs/workbench/browser/actions/workspaceCommands';
import { CLOSE_SAVED_EDITORS_COMMAND_ID, CLOSE_EDITORS_IN_GROUP_COMMAND_ID, CLOSE_EDITOR_COMMAND_ID, CLOSE_OTHER_EDITORS_IN_GROUP_COMMAND_ID } from 'vs/workbench/browser/parts/editor/editorCommands';
import { AutoSaveContext } from 'vs/workbench/services/textfile/common/textfiles';
import { AutoSaveContext } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService';
import { ResourceContextKey } from 'vs/workbench/common/resources';
import { WorkbenchListDoubleSelection } from 'vs/platform/list/browser/listService';
import { URI } from 'vs/base/common/uri';
@@ -471,7 +471,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, ({
id: DOWNLOAD_COMMAND_ID,
title: DOWNLOAD_LABEL,
},
when: ContextKeyExpr.or(ContextKeyExpr.and(ResourceContextKey.Scheme.notEqualsTo(Schemas.file), IsWebContext.toNegated()), ContextKeyExpr.and(ResourceContextKey.Scheme.notEqualsTo(Schemas.file), ExplorerFolderContext.toNegated()))
when: ContextKeyExpr.or(ContextKeyExpr.and(ResourceContextKey.Scheme.notEqualsTo(Schemas.file), IsWebContext.toNegated()), ContextKeyExpr.and(ResourceContextKey.Scheme.notEqualsTo(Schemas.file), ExplorerFolderContext.toNegated(), ExplorerRootContext.toNegated()))
}));
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
@@ -495,7 +495,7 @@ MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
id: ADD_ROOT_FOLDER_COMMAND_ID,
title: ADD_ROOT_FOLDER_LABEL
},
when: ContextKeyExpr.and(ExplorerRootContext)
when: ExplorerRootContext
});
MenuRegistry.appendMenuItem(MenuId.ExplorerContext, {
@@ -5,7 +5,6 @@
import 'vs/css!./media/fileactions';
import * as nls from 'vs/nls';
import * as types from 'vs/base/common/types';
import { isWindows, isWeb } from 'vs/base/common/platform';
import * as extpath from 'vs/base/common/extpath';
import { extname, basename } from 'vs/base/common/path';
@@ -17,7 +16,7 @@ import { Action } from 'vs/base/common/actions';
import { dispose, IDisposable } from 'vs/base/common/lifecycle';
import { VIEWLET_ID, IExplorerService, IFilesConfiguration } from 'vs/workbench/contrib/files/common/files';
import { ITextFileService } from 'vs/workbench/services/textfile/common/textfiles';
import { IFileService, AutoSaveConfiguration } from 'vs/platform/files/common/files';
import { IFileService } from 'vs/platform/files/common/files';
import { toResource, SideBySideEditor } from 'vs/workbench/common/editor';
import { ExplorerViewlet } from 'vs/workbench/contrib/files/browser/explorerViewlet';
import { IUntitledTextEditorService } from 'vs/workbench/services/untitled/common/untitledTextEditorService';
@@ -47,6 +46,7 @@ import { ExplorerItem, NewExplorerItem } from 'vs/workbench/contrib/files/common
import { onUnexpectedError, getErrorMessage } from 'vs/base/common/errors';
import { asDomUri, triggerDownload } from 'vs/base/browser/dom';
import { mnemonicButtonLabel } from 'vs/base/common/labels';
import { IAutoSaveConfigurationService } from 'vs/workbench/services/autoSaveConfiguration/common/autoSaveConfigurationService';
export const NEW_FILE_COMMAND_ID = 'explorer.newFile';
export const NEW_FILE_LABEL = nls.localize('newFile', "New File");
@@ -496,26 +496,13 @@ export class ToggleAutoSaveAction extends Action {
constructor(
id: string,
label: string,
@IConfigurationService private readonly configurationService: IConfigurationService
@IAutoSaveConfigurationService private readonly autoSaveConfigurationService: IAutoSaveConfigurationService
) {
super(id, label);
}
run(): Promise<any> {
const setting = this.configurationService.inspect('files.autoSave');
let userAutoSaveConfig = setting.user;
if (types.isUndefinedOrNull(userAutoSaveConfig)) {
userAutoSaveConfig = setting.default; // use default if setting not defined
}
let newAutoSaveValue: string;
if ([AutoSaveConfiguration.AFTER_DELAY, AutoSaveConfiguration.ON_FOCUS_CHANGE, AutoSaveConfiguration.ON_WINDOW_CHANGE].some(s => s === userAutoSaveConfig)) {
newAutoSaveValue = AutoSaveConfiguration.OFF;
} else {
newAutoSaveValue = AutoSaveConfiguration.AFTER_DELAY;
}
return this.configurationService.updateValue('files.autoSave', newAutoSaveValue, ConfigurationTarget.USER);
return this.autoSaveConfigurationService.toggleAutoSave();
}
}

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