diff --git a/package-lock.json b/package-lock.json index d1ca8b05e78f0..114cfbd760420 100644 --- a/package-lock.json +++ b/package-lock.json @@ -26,14 +26,14 @@ "@vscode/windows-mutex": "^0.5.0", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", - "@xterm/addon-clipboard": "^0.2.0-beta.47", - "@xterm/addon-image": "^0.9.0-beta.64", - "@xterm/addon-search": "^0.16.0-beta.64", - "@xterm/addon-serialize": "^0.14.0-beta.64", - "@xterm/addon-unicode11": "^0.9.0-beta.64", - "@xterm/addon-webgl": "^0.19.0-beta.64", - "@xterm/headless": "^5.6.0-beta.64", - "@xterm/xterm": "^5.6.0-beta.64", + "@xterm/addon-clipboard": "^0.2.0-beta.48", + "@xterm/addon-image": "^0.9.0-beta.65", + "@xterm/addon-search": "^0.16.0-beta.65", + "@xterm/addon-serialize": "^0.14.0-beta.65", + "@xterm/addon-unicode11": "^0.9.0-beta.65", + "@xterm/addon-webgl": "^0.19.0-beta.65", + "@xterm/headless": "^5.6.0-beta.65", + "@xterm/xterm": "^5.6.0-beta.65", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", "jschardet": "3.1.3", @@ -42,7 +42,7 @@ "native-is-elevated": "0.7.0", "native-keymap": "^3.3.5", "native-watchdog": "^1.4.1", - "node-pty": "1.1.0-beta21", + "node-pty": "^1.1.0-beta22", "open": "^8.4.2", "tas-client-umd": "0.2.0", "v8-inspect-profiler": "^0.1.1", @@ -3505,65 +3505,65 @@ } }, "node_modules/@xterm/addon-clipboard": { - "version": "0.2.0-beta.47", - "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.2.0-beta.47.tgz", - "integrity": "sha512-mJHV1770gwVckj4mgjdxegt4zLL5WGCoJblTqaLbgEF7xOwsJUzvGk38qsZ4ZpdTa2ti76H0pkb1CpZGrXL9qg==", + "version": "0.2.0-beta.48", + "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.2.0-beta.48.tgz", + "integrity": "sha512-oTrGoGMOQaW7PINAShhNR3duV8l2No/DbJ9rtfSBjfoQ9clWe0K+4fUHdJIuzW65AZsiLo9oh5IbHLWxlFP3Jg==", "dependencies": { "js-base64": "^3.7.5" }, "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-image": { - "version": "0.9.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.9.0-beta.64.tgz", - "integrity": "sha512-1Aqqytx/z/Khecf5xrO++f/p5EQX4uG87TbbAmE0OQys/JgKMnNggDzqon5bpHboimLfQiFPw716NbTqMphjfw==", + "version": "0.9.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.9.0-beta.65.tgz", + "integrity": "sha512-Ud5FI5cGtpbz8yYCHC4QINlbC1K04Mex1JD5oAWPFwjlOz/Si/DhqbY1QBDl6QrUmSUUTZc5DKT3v3nN5WbZxQ==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-search": { - "version": "0.16.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0-beta.64.tgz", - "integrity": "sha512-vUsvTkEOFJwv8nVtiiGr/vTMeQhu62VkUejY2h1+yZagnVEusGVPU1JYoqBTLu5HM4cFiTGsJYXFI/0apASXYA==", + "version": "0.16.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0-beta.65.tgz", + "integrity": "sha512-eHfbbgFCS3AcD8YSvGFIkW9NW4pfGHrtRDWIojM/zqmyi3JaCmHUgZmlxbaANwBlgLiNpJLDq7cmoz//86NgGw==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-serialize": { - "version": "0.14.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.64.tgz", - "integrity": "sha512-0AqVveTV3Pr9Lp+beJYOP5WuRvIrPSDGAK24da7BRGcLIKVq8pok1FdlM9jPeUbkX0DKo6Ortm77qeb2Z+n8+A==", + "version": "0.14.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.65.tgz", + "integrity": "sha512-NlvXVtFAHpLKEDzd+6/68yPFQ4Oe02jvQH6+a8p+gcxbSEyYj1l0sqqeABQ3gC5QDCmQepk6BQVB8Rpz/e4HgQ==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-unicode11": { - "version": "0.9.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.64.tgz", - "integrity": "sha512-3+PKu+DXFq32xlsYfnI058/T8dTY2tQhRpJLP2CNR/jVWk5uBkVO0dBV0Srqj5QOAlAhzzZuS6TbsVRXORptqw==", + "version": "0.9.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.65.tgz", + "integrity": "sha512-sH9mu2GEIVuc6cs6HxsmCXn6KKzCa5D+Zyl1Pt9d2S4FKqSB17Fc4mVukCOMW7wUR9UChKTbxmByGJK+4xwdCA==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-webgl": { - "version": "0.19.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.64.tgz", - "integrity": "sha512-cxTkMPAXPQAZnWqahNu7ff9mbJvM1sQqKnZWiFZAHTsZXym4oa3KCB4pjH4didSyYkhkPY/17E8I0UOUpvv0Yw==", + "version": "0.19.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.65.tgz", + "integrity": "sha512-gPwP8ozqrLFWOlo9eh2I+acxq0Z6obG7GpL8HpJ+B+q6+vjfxoXHQ6vV04W90aoAvbLpScHcT/JtXA58GcH2vw==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/headless": { - "version": "5.6.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/headless/-/headless-5.6.0-beta.64.tgz", - "integrity": "sha512-my08kgH2K3CBEtBg/o8lamtD6BYNBv03Akq747Lajv0QzOiwan7B4r2xdbA6i9sovB+MdjFs0XP1ksc3EpKakg==" + "version": "5.6.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/headless/-/headless-5.6.0-beta.65.tgz", + "integrity": "sha512-gQICZsBkFHQEb/K+dc+KN4u5aBwrDPgai0S7W8/KT7fqTPWz8Cgjq119WQLshnzfLeMMFPYGttNHFGUbpp/wmw==" }, "node_modules/@xterm/xterm": { - "version": "5.6.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.6.0-beta.64.tgz", - "integrity": "sha512-iSKS6tQTFpoN5y487eptlxkUT0jqK5hrvtFQMLugMcQdn7gCUCiFGa4Z1RdqKYSGvAypka+b9gMKPrKWZ7Q3yQ==" + "version": "5.6.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.6.0-beta.65.tgz", + "integrity": "sha512-o6IIg4hqs994gtSQMbzQM6OUeLIXPG6RUxjoref0KJX4PIa/BqQjwQLPuSxnjOFeRQIvhZ2mSAPfGWJQ6jEGAg==" }, "node_modules/@xtuc/ieee754": { "version": "1.2.0", @@ -13520,9 +13520,9 @@ } }, "node_modules/node-pty": { - "version": "1.1.0-beta21", - "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.1.0-beta21.tgz", - "integrity": "sha512-FYpnY9g8qMQLTpqyeY9NVli6YfCWwvG6v6gmaDBbPjlc1VMp/+Zivq0SStDrRr1aciGnFCZzpL0BzdMnmbDnAw==", + "version": "1.1.0-beta22", + "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.1.0-beta22.tgz", + "integrity": "sha512-CpT334H2oAIULlENvd9U+VBW4ZL+G3clOnpXYzUIurlPCLnl/9xen/KDHBLRcwhZuWcHxIrsCxR1TDCdVDtr0w==", "hasInstallScript": true, "dependencies": { "node-addon-api": "^7.1.0" diff --git a/package.json b/package.json index 7fbc5d9c91d75..5c441319f438f 100644 --- a/package.json +++ b/package.json @@ -83,14 +83,14 @@ "@vscode/windows-mutex": "^0.5.0", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", - "@xterm/addon-clipboard": "^0.2.0-beta.47", - "@xterm/addon-image": "^0.9.0-beta.64", - "@xterm/addon-search": "^0.16.0-beta.64", - "@xterm/addon-serialize": "^0.14.0-beta.64", - "@xterm/addon-unicode11": "^0.9.0-beta.64", - "@xterm/addon-webgl": "^0.19.0-beta.64", - "@xterm/headless": "^5.6.0-beta.64", - "@xterm/xterm": "^5.6.0-beta.64", + "@xterm/addon-clipboard": "^0.2.0-beta.48", + "@xterm/addon-image": "^0.9.0-beta.65", + "@xterm/addon-search": "^0.16.0-beta.65", + "@xterm/addon-serialize": "^0.14.0-beta.65", + "@xterm/addon-unicode11": "^0.9.0-beta.65", + "@xterm/addon-webgl": "^0.19.0-beta.65", + "@xterm/headless": "^5.6.0-beta.65", + "@xterm/xterm": "^5.6.0-beta.65", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", "jschardet": "3.1.3", @@ -99,7 +99,7 @@ "native-is-elevated": "0.7.0", "native-keymap": "^3.3.5", "native-watchdog": "^1.4.1", - "node-pty": "1.1.0-beta21", + "node-pty": "^1.1.0-beta22", "open": "^8.4.2", "tas-client-umd": "0.2.0", "v8-inspect-profiler": "^0.1.1", diff --git a/remote/package-lock.json b/remote/package-lock.json index 58725751af9ee..5f8891ee061a1 100644 --- a/remote/package-lock.json +++ b/remote/package-lock.json @@ -20,14 +20,14 @@ "@vscode/vscode-languagedetection": "1.0.21", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", - "@xterm/addon-clipboard": "^0.2.0-beta.47", - "@xterm/addon-image": "^0.9.0-beta.64", - "@xterm/addon-search": "^0.16.0-beta.64", - "@xterm/addon-serialize": "^0.14.0-beta.64", - "@xterm/addon-unicode11": "^0.9.0-beta.64", - "@xterm/addon-webgl": "^0.19.0-beta.64", - "@xterm/headless": "^5.6.0-beta.64", - "@xterm/xterm": "^5.6.0-beta.64", + "@xterm/addon-clipboard": "^0.2.0-beta.48", + "@xterm/addon-image": "^0.9.0-beta.65", + "@xterm/addon-search": "^0.16.0-beta.65", + "@xterm/addon-serialize": "^0.14.0-beta.65", + "@xterm/addon-unicode11": "^0.9.0-beta.65", + "@xterm/addon-webgl": "^0.19.0-beta.65", + "@xterm/headless": "^5.6.0-beta.65", + "@xterm/xterm": "^5.6.0-beta.65", "cookie": "^0.4.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", @@ -35,7 +35,7 @@ "kerberos": "2.1.1", "minimist": "^1.2.6", "native-watchdog": "^1.4.1", - "node-pty": "1.1.0-beta21", + "node-pty": "^1.1.0-beta22", "tas-client-umd": "0.2.0", "vscode-oniguruma": "1.7.0", "vscode-regexpp": "^3.1.0", @@ -233,65 +233,65 @@ "hasInstallScript": true }, "node_modules/@xterm/addon-clipboard": { - "version": "0.2.0-beta.47", - "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.2.0-beta.47.tgz", - "integrity": "sha512-mJHV1770gwVckj4mgjdxegt4zLL5WGCoJblTqaLbgEF7xOwsJUzvGk38qsZ4ZpdTa2ti76H0pkb1CpZGrXL9qg==", + "version": "0.2.0-beta.48", + "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.2.0-beta.48.tgz", + "integrity": "sha512-oTrGoGMOQaW7PINAShhNR3duV8l2No/DbJ9rtfSBjfoQ9clWe0K+4fUHdJIuzW65AZsiLo9oh5IbHLWxlFP3Jg==", "dependencies": { "js-base64": "^3.7.5" }, "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-image": { - "version": "0.9.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.9.0-beta.64.tgz", - "integrity": "sha512-1Aqqytx/z/Khecf5xrO++f/p5EQX4uG87TbbAmE0OQys/JgKMnNggDzqon5bpHboimLfQiFPw716NbTqMphjfw==", + "version": "0.9.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.9.0-beta.65.tgz", + "integrity": "sha512-Ud5FI5cGtpbz8yYCHC4QINlbC1K04Mex1JD5oAWPFwjlOz/Si/DhqbY1QBDl6QrUmSUUTZc5DKT3v3nN5WbZxQ==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-search": { - "version": "0.16.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0-beta.64.tgz", - "integrity": "sha512-vUsvTkEOFJwv8nVtiiGr/vTMeQhu62VkUejY2h1+yZagnVEusGVPU1JYoqBTLu5HM4cFiTGsJYXFI/0apASXYA==", + "version": "0.16.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0-beta.65.tgz", + "integrity": "sha512-eHfbbgFCS3AcD8YSvGFIkW9NW4pfGHrtRDWIojM/zqmyi3JaCmHUgZmlxbaANwBlgLiNpJLDq7cmoz//86NgGw==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-serialize": { - "version": "0.14.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.64.tgz", - "integrity": "sha512-0AqVveTV3Pr9Lp+beJYOP5WuRvIrPSDGAK24da7BRGcLIKVq8pok1FdlM9jPeUbkX0DKo6Ortm77qeb2Z+n8+A==", + "version": "0.14.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.65.tgz", + "integrity": "sha512-NlvXVtFAHpLKEDzd+6/68yPFQ4Oe02jvQH6+a8p+gcxbSEyYj1l0sqqeABQ3gC5QDCmQepk6BQVB8Rpz/e4HgQ==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-unicode11": { - "version": "0.9.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.64.tgz", - "integrity": "sha512-3+PKu+DXFq32xlsYfnI058/T8dTY2tQhRpJLP2CNR/jVWk5uBkVO0dBV0Srqj5QOAlAhzzZuS6TbsVRXORptqw==", + "version": "0.9.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.65.tgz", + "integrity": "sha512-sH9mu2GEIVuc6cs6HxsmCXn6KKzCa5D+Zyl1Pt9d2S4FKqSB17Fc4mVukCOMW7wUR9UChKTbxmByGJK+4xwdCA==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-webgl": { - "version": "0.19.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.64.tgz", - "integrity": "sha512-cxTkMPAXPQAZnWqahNu7ff9mbJvM1sQqKnZWiFZAHTsZXym4oa3KCB4pjH4didSyYkhkPY/17E8I0UOUpvv0Yw==", + "version": "0.19.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.65.tgz", + "integrity": "sha512-gPwP8ozqrLFWOlo9eh2I+acxq0Z6obG7GpL8HpJ+B+q6+vjfxoXHQ6vV04W90aoAvbLpScHcT/JtXA58GcH2vw==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/headless": { - "version": "5.6.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/headless/-/headless-5.6.0-beta.64.tgz", - "integrity": "sha512-my08kgH2K3CBEtBg/o8lamtD6BYNBv03Akq747Lajv0QzOiwan7B4r2xdbA6i9sovB+MdjFs0XP1ksc3EpKakg==" + "version": "5.6.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/headless/-/headless-5.6.0-beta.65.tgz", + "integrity": "sha512-gQICZsBkFHQEb/K+dc+KN4u5aBwrDPgai0S7W8/KT7fqTPWz8Cgjq119WQLshnzfLeMMFPYGttNHFGUbpp/wmw==" }, "node_modules/@xterm/xterm": { - "version": "5.6.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.6.0-beta.64.tgz", - "integrity": "sha512-iSKS6tQTFpoN5y487eptlxkUT0jqK5hrvtFQMLugMcQdn7gCUCiFGa4Z1RdqKYSGvAypka+b9gMKPrKWZ7Q3yQ==" + "version": "5.6.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.6.0-beta.65.tgz", + "integrity": "sha512-o6IIg4hqs994gtSQMbzQM6OUeLIXPG6RUxjoref0KJX4PIa/BqQjwQLPuSxnjOFeRQIvhZ2mSAPfGWJQ6jEGAg==" }, "node_modules/agent-base": { "version": "7.1.1", @@ -748,9 +748,9 @@ } }, "node_modules/node-pty": { - "version": "1.1.0-beta21", - "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.1.0-beta21.tgz", - "integrity": "sha512-FYpnY9g8qMQLTpqyeY9NVli6YfCWwvG6v6gmaDBbPjlc1VMp/+Zivq0SStDrRr1aciGnFCZzpL0BzdMnmbDnAw==", + "version": "1.1.0-beta22", + "resolved": "https://registry.npmjs.org/node-pty/-/node-pty-1.1.0-beta22.tgz", + "integrity": "sha512-CpT334H2oAIULlENvd9U+VBW4ZL+G3clOnpXYzUIurlPCLnl/9xen/KDHBLRcwhZuWcHxIrsCxR1TDCdVDtr0w==", "hasInstallScript": true, "dependencies": { "node-addon-api": "^7.1.0" diff --git a/remote/package.json b/remote/package.json index c107b048e45c0..0d0a37e4b9046 100644 --- a/remote/package.json +++ b/remote/package.json @@ -15,14 +15,14 @@ "@vscode/vscode-languagedetection": "1.0.21", "@vscode/windows-process-tree": "^0.6.0", "@vscode/windows-registry": "^1.1.0", - "@xterm/addon-clipboard": "^0.2.0-beta.47", - "@xterm/addon-image": "^0.9.0-beta.64", - "@xterm/addon-search": "^0.16.0-beta.64", - "@xterm/addon-serialize": "^0.14.0-beta.64", - "@xterm/addon-unicode11": "^0.9.0-beta.64", - "@xterm/addon-webgl": "^0.19.0-beta.64", - "@xterm/headless": "^5.6.0-beta.64", - "@xterm/xterm": "^5.6.0-beta.64", + "@xterm/addon-clipboard": "^0.2.0-beta.48", + "@xterm/addon-image": "^0.9.0-beta.65", + "@xterm/addon-search": "^0.16.0-beta.65", + "@xterm/addon-serialize": "^0.14.0-beta.65", + "@xterm/addon-unicode11": "^0.9.0-beta.65", + "@xterm/addon-webgl": "^0.19.0-beta.65", + "@xterm/headless": "^5.6.0-beta.65", + "@xterm/xterm": "^5.6.0-beta.65", "cookie": "^0.4.0", "http-proxy-agent": "^7.0.0", "https-proxy-agent": "^7.0.2", @@ -30,7 +30,7 @@ "kerberos": "2.1.1", "minimist": "^1.2.6", "native-watchdog": "^1.4.1", - "node-pty": "1.1.0-beta21", + "node-pty": "^1.1.0-beta22", "tas-client-umd": "0.2.0", "vscode-oniguruma": "1.7.0", "vscode-regexpp": "^3.1.0", diff --git a/remote/web/package-lock.json b/remote/web/package-lock.json index b971ca265f03e..04199f4e652db 100644 --- a/remote/web/package-lock.json +++ b/remote/web/package-lock.json @@ -13,13 +13,13 @@ "@vscode/iconv-lite-umd": "0.7.0", "@vscode/tree-sitter-wasm": "^0.0.4", "@vscode/vscode-languagedetection": "1.0.21", - "@xterm/addon-clipboard": "^0.2.0-beta.47", - "@xterm/addon-image": "^0.9.0-beta.64", - "@xterm/addon-search": "^0.16.0-beta.64", - "@xterm/addon-serialize": "^0.14.0-beta.64", - "@xterm/addon-unicode11": "^0.9.0-beta.64", - "@xterm/addon-webgl": "^0.19.0-beta.64", - "@xterm/xterm": "^5.6.0-beta.64", + "@xterm/addon-clipboard": "^0.2.0-beta.48", + "@xterm/addon-image": "^0.9.0-beta.65", + "@xterm/addon-search": "^0.16.0-beta.65", + "@xterm/addon-serialize": "^0.14.0-beta.65", + "@xterm/addon-unicode11": "^0.9.0-beta.65", + "@xterm/addon-webgl": "^0.19.0-beta.65", + "@xterm/xterm": "^5.6.0-beta.65", "jschardet": "3.1.3", "tas-client-umd": "0.2.0", "vscode-oniguruma": "1.7.0", @@ -87,60 +87,60 @@ } }, "node_modules/@xterm/addon-clipboard": { - "version": "0.2.0-beta.47", - "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.2.0-beta.47.tgz", - "integrity": "sha512-mJHV1770gwVckj4mgjdxegt4zLL5WGCoJblTqaLbgEF7xOwsJUzvGk38qsZ4ZpdTa2ti76H0pkb1CpZGrXL9qg==", + "version": "0.2.0-beta.48", + "resolved": "https://registry.npmjs.org/@xterm/addon-clipboard/-/addon-clipboard-0.2.0-beta.48.tgz", + "integrity": "sha512-oTrGoGMOQaW7PINAShhNR3duV8l2No/DbJ9rtfSBjfoQ9clWe0K+4fUHdJIuzW65AZsiLo9oh5IbHLWxlFP3Jg==", "dependencies": { "js-base64": "^3.7.5" }, "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-image": { - "version": "0.9.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.9.0-beta.64.tgz", - "integrity": "sha512-1Aqqytx/z/Khecf5xrO++f/p5EQX4uG87TbbAmE0OQys/JgKMnNggDzqon5bpHboimLfQiFPw716NbTqMphjfw==", + "version": "0.9.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-image/-/addon-image-0.9.0-beta.65.tgz", + "integrity": "sha512-Ud5FI5cGtpbz8yYCHC4QINlbC1K04Mex1JD5oAWPFwjlOz/Si/DhqbY1QBDl6QrUmSUUTZc5DKT3v3nN5WbZxQ==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-search": { - "version": "0.16.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0-beta.64.tgz", - "integrity": "sha512-vUsvTkEOFJwv8nVtiiGr/vTMeQhu62VkUejY2h1+yZagnVEusGVPU1JYoqBTLu5HM4cFiTGsJYXFI/0apASXYA==", + "version": "0.16.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-search/-/addon-search-0.16.0-beta.65.tgz", + "integrity": "sha512-eHfbbgFCS3AcD8YSvGFIkW9NW4pfGHrtRDWIojM/zqmyi3JaCmHUgZmlxbaANwBlgLiNpJLDq7cmoz//86NgGw==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-serialize": { - "version": "0.14.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.64.tgz", - "integrity": "sha512-0AqVveTV3Pr9Lp+beJYOP5WuRvIrPSDGAK24da7BRGcLIKVq8pok1FdlM9jPeUbkX0DKo6Ortm77qeb2Z+n8+A==", + "version": "0.14.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-serialize/-/addon-serialize-0.14.0-beta.65.tgz", + "integrity": "sha512-NlvXVtFAHpLKEDzd+6/68yPFQ4Oe02jvQH6+a8p+gcxbSEyYj1l0sqqeABQ3gC5QDCmQepk6BQVB8Rpz/e4HgQ==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-unicode11": { - "version": "0.9.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.64.tgz", - "integrity": "sha512-3+PKu+DXFq32xlsYfnI058/T8dTY2tQhRpJLP2CNR/jVWk5uBkVO0dBV0Srqj5QOAlAhzzZuS6TbsVRXORptqw==", + "version": "0.9.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-unicode11/-/addon-unicode11-0.9.0-beta.65.tgz", + "integrity": "sha512-sH9mu2GEIVuc6cs6HxsmCXn6KKzCa5D+Zyl1Pt9d2S4FKqSB17Fc4mVukCOMW7wUR9UChKTbxmByGJK+4xwdCA==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/addon-webgl": { - "version": "0.19.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.64.tgz", - "integrity": "sha512-cxTkMPAXPQAZnWqahNu7ff9mbJvM1sQqKnZWiFZAHTsZXym4oa3KCB4pjH4didSyYkhkPY/17E8I0UOUpvv0Yw==", + "version": "0.19.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/addon-webgl/-/addon-webgl-0.19.0-beta.65.tgz", + "integrity": "sha512-gPwP8ozqrLFWOlo9eh2I+acxq0Z6obG7GpL8HpJ+B+q6+vjfxoXHQ6vV04W90aoAvbLpScHcT/JtXA58GcH2vw==", "peerDependencies": { - "@xterm/xterm": "^5.6.0-beta.64" + "@xterm/xterm": "^5.6.0-beta.65" } }, "node_modules/@xterm/xterm": { - "version": "5.6.0-beta.64", - "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.6.0-beta.64.tgz", - "integrity": "sha512-iSKS6tQTFpoN5y487eptlxkUT0jqK5hrvtFQMLugMcQdn7gCUCiFGa4Z1RdqKYSGvAypka+b9gMKPrKWZ7Q3yQ==" + "version": "5.6.0-beta.65", + "resolved": "https://registry.npmjs.org/@xterm/xterm/-/xterm-5.6.0-beta.65.tgz", + "integrity": "sha512-o6IIg4hqs994gtSQMbzQM6OUeLIXPG6RUxjoref0KJX4PIa/BqQjwQLPuSxnjOFeRQIvhZ2mSAPfGWJQ6jEGAg==" }, "node_modules/js-base64": { "version": "3.7.7", diff --git a/remote/web/package.json b/remote/web/package.json index 27be6a503bdc7..a4a18b9369cb0 100644 --- a/remote/web/package.json +++ b/remote/web/package.json @@ -8,13 +8,13 @@ "@vscode/iconv-lite-umd": "0.7.0", "@vscode/tree-sitter-wasm": "^0.0.4", "@vscode/vscode-languagedetection": "1.0.21", - "@xterm/addon-clipboard": "^0.2.0-beta.47", - "@xterm/addon-image": "^0.9.0-beta.64", - "@xterm/addon-search": "^0.16.0-beta.64", - "@xterm/addon-serialize": "^0.14.0-beta.64", - "@xterm/addon-unicode11": "^0.9.0-beta.64", - "@xterm/addon-webgl": "^0.19.0-beta.64", - "@xterm/xterm": "^5.6.0-beta.64", + "@xterm/addon-clipboard": "^0.2.0-beta.48", + "@xterm/addon-image": "^0.9.0-beta.65", + "@xterm/addon-search": "^0.16.0-beta.65", + "@xterm/addon-serialize": "^0.14.0-beta.65", + "@xterm/addon-unicode11": "^0.9.0-beta.65", + "@xterm/addon-webgl": "^0.19.0-beta.65", + "@xterm/xterm": "^5.6.0-beta.65", "jschardet": "3.1.3", "tas-client-umd": "0.2.0", "vscode-oniguruma": "1.7.0", diff --git a/src/vs/platform/actions/common/actions.ts b/src/vs/platform/actions/common/actions.ts index 0c4cf7598cc44..b49b11c86872f 100644 --- a/src/vs/platform/actions/common/actions.ts +++ b/src/vs/platform/actions/common/actions.ts @@ -230,6 +230,7 @@ export class MenuId { static readonly ChatInlineResourceAnchorContext = new MenuId('ChatInlineResourceAnchorContext'); static readonly ChatInlineSymbolAnchorContext = new MenuId('ChatInlineSymbolAnchorContext'); static readonly ChatCommandCenter = new MenuId('ChatCommandCenter'); + static readonly ChatAttachmentsContext = new MenuId('ChatAttachmentsContext'); static readonly AccessibleView = new MenuId('AccessibleView'); static readonly MultiDiffEditorFileToolbar = new MenuId('MultiDiffEditorFileToolbar'); static readonly DiffEditorHunkToolbar = new MenuId('DiffEditorHunkToolbar'); diff --git a/src/vs/workbench/api/common/extHost.api.impl.ts b/src/vs/workbench/api/common/extHost.api.impl.ts index 2e335cbaa5da6..8c04da5bb7c44 100644 --- a/src/vs/workbench/api/common/extHost.api.impl.ts +++ b/src/vs/workbench/api/common/extHost.api.impl.ts @@ -1454,7 +1454,7 @@ export function createApiFactoryAndRegisterActors(accessor: ServicesAccessor): I }, registerChatParticipantDetectionProvider(provider: vscode.ChatParticipantDetectionProvider) { checkProposedApiEnabled(extension, 'chatParticipantAdditions'); - return extHostChatAgents2.registerChatParticipantDetectionProvider(provider); + return extHostChatAgents2.registerChatParticipantDetectionProvider(extension, provider); }, }; diff --git a/src/vs/workbench/api/common/extHostChatAgents2.ts b/src/vs/workbench/api/common/extHostChatAgents2.ts index cc1ecb1291290..c31f91957d7fb 100644 --- a/src/vs/workbench/api/common/extHostChatAgents2.ts +++ b/src/vs/workbench/api/common/extHostChatAgents2.ts @@ -285,7 +285,7 @@ export class ExtHostChatAgents2 extends Disposable implements ExtHostChatAgentsS private readonly _proxy: MainThreadChatAgentsShape2; private static _participantDetectionProviderIdPool = 0; - private readonly _participantDetectionProviders = new Map(); + private readonly _participantDetectionProviders = new Map(); private readonly _sessionDisposables: DisposableMap = this._register(new DisposableMap()); private readonly _completionDisposables: DisposableMap = this._register(new DisposableMap()); @@ -323,9 +323,9 @@ export class ExtHostChatAgents2 extends Disposable implements ExtHostChatAgentsS return agent.apiAgent; } - registerChatParticipantDetectionProvider(provider: vscode.ChatParticipantDetectionProvider): vscode.Disposable { + registerChatParticipantDetectionProvider(extension: IExtensionDescription, provider: vscode.ChatParticipantDetectionProvider): vscode.Disposable { const handle = ExtHostChatAgents2._participantDetectionProviderIdPool++; - this._participantDetectionProviders.set(handle, provider); + this._participantDetectionProviders.set(handle, new ExtHostParticipantDetector(extension, provider)); this._proxy.$registerChatParticipantDetectionProvider(handle); return toDisposable(() => { this._participantDetectionProviders.delete(handle); @@ -336,13 +336,18 @@ export class ExtHostChatAgents2 extends Disposable implements ExtHostChatAgentsS async $detectChatParticipant(handle: number, requestDto: Dto, context: { history: IChatAgentHistoryEntryDto[] }, options: { location: ChatAgentLocation; participants?: vscode.ChatParticipantMetadata[] }, token: CancellationToken): Promise { const { request, location, history } = await this._createRequest(requestDto, context); - const provider = this._participantDetectionProviders.get(handle); - if (!provider) { + const detector = this._participantDetectionProviders.get(handle); + if (!detector) { return undefined; } - return provider.provideParticipantDetection( - typeConvert.ChatAgentRequest.to(request, location), + const extRequest = typeConvert.ChatAgentRequest.to(request, location); + if (request.userSelectedModelId && isProposedApiEnabled(detector.extension, 'chatParticipantAdditions')) { + extRequest.userSelectedModel = await this._languageModels.getLanguageModelByIdentifier(detector.extension, request.userSelectedModelId); + } + + return detector.provider.provideParticipantDetection( + extRequest, { history }, { participants: options.participants, location: typeConvert.ChatLocation.to(options.location) }, token @@ -588,6 +593,13 @@ export class ExtHostChatAgents2 extends Disposable implements ExtHostChatAgentsS } } +class ExtHostParticipantDetector { + constructor( + public readonly extension: IExtensionDescription, + public readonly provider: vscode.ChatParticipantDetectionProvider, + ) { } +} + class ExtHostChatAgent { private _followupProvider: vscode.ChatFollowupProvider | undefined; diff --git a/src/vs/workbench/api/common/extHostCodeMapper.ts b/src/vs/workbench/api/common/extHostCodeMapper.ts index 055d52b3d4b49..0f6b9d1292238 100644 --- a/src/vs/workbench/api/common/extHostCodeMapper.ts +++ b/src/vs/workbench/api/common/extHostCodeMapper.ts @@ -8,7 +8,7 @@ import { CancellationToken } from '../../../base/common/cancellation.js'; import { IExtensionDescription } from '../../../platform/extensions/common/extensions.js'; import { ICodeMapperResult } from '../../contrib/chat/common/chatCodeMapperService.js'; import * as extHostProtocol from './extHost.protocol.js'; -import { TextEdit } from './extHostTypeConverters.js'; +import { ChatAgentResult, DocumentContextItem, TextEdit } from './extHostTypeConverters.js'; import { URI } from '../../../base/common/uri.js'; export class ExtHostCodeMapper implements extHostProtocol.ExtHostCodeMapperShape { @@ -45,10 +45,25 @@ export class ExtHostCodeMapper implements extHostProtocol.ExtHostCodeMapperShape codeBlocks: internalRequest.codeBlocks.map(block => { return { code: block.code, - resource: URI.revive(block.resource) + resource: URI.revive(block.resource), + markdownBeforeBlock: block.markdownBeforeBlock }; }), - conversation: internalRequest.conversation + conversation: internalRequest.conversation.map(item => { + if (item.type === 'request') { + return { + type: 'request', + message: item.message + } satisfies vscode.ConversationRequest; + } else { + return { + type: 'response', + message: item.message, + result: item.result ? ChatAgentResult.to(item.result) : undefined, + references: item.references?.map(DocumentContextItem.to) + } satisfies vscode.ConversationResponse; + } + }) }; const result = await provider.provideMappedEdits(request, stream, token); diff --git a/src/vs/workbench/api/common/extHostTypeConverters.ts b/src/vs/workbench/api/common/extHostTypeConverters.ts index 2eeed81cbec9e..14f182efbe17b 100644 --- a/src/vs/workbench/api/common/extHostTypeConverters.ts +++ b/src/vs/workbench/api/common/extHostTypeConverters.ts @@ -1629,7 +1629,7 @@ export namespace MappedEditsContext { ); } - export function from(extContext: vscode.MappedEditsContext): languages.MappedEditsContext { + export function from(extContext: vscode.MappedEditsContext): Dto { return { documents: extContext.documents.map((subArray) => subArray.map(DocumentContextItem.from) @@ -1643,6 +1643,7 @@ export namespace MappedEditsContext { { type: 'response', message: item.message, + result: item.result ? ChatAgentResult.from(item.result) : undefined, references: item.references?.map(DocumentContextItem.from) } )) @@ -1663,13 +1664,21 @@ export namespace DocumentContextItem { ); } - export function from(item: vscode.DocumentContextItem): languages.DocumentContextItem { + export function from(item: vscode.DocumentContextItem): Dto { return { - uri: URI.from(item.uri), + uri: item.uri, version: item.version, ranges: item.ranges.map(r => Range.from(r)), }; } + + export function to(item: Dto): vscode.DocumentContextItem { + return { + uri: URI.revive(item.uri), + version: item.version, + ranges: item.ranges.map(r => Range.to(r)), + }; + } } export namespace NotebookRange { @@ -2831,6 +2840,13 @@ export namespace ChatAgentResult { nextQuestion: result.nextQuestion, }; } + export function from(result: vscode.ChatResult): Dto { + return { + errorDetails: result.errorDetails, + metadata: result.metadata, + nextQuestion: result.nextQuestion, + }; + } } export namespace ChatAgentUserActionEvent { diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.ts index cb5c64f760b2e..c9c0311cc8d95 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatClearActions.ts @@ -19,6 +19,7 @@ import { ChatEditorInput } from '../chatEditorInput.js'; import { ChatViewPane } from '../chatViewPane.js'; import { CONTEXT_IN_CHAT_SESSION, CONTEXT_CHAT_ENABLED, CONTEXT_CHAT_EDITING_PARTICIPANT_REGISTERED } from '../../common/chatContextKeys.js'; import { IViewsService } from '../../../../services/views/common/viewsService.js'; +import { ChatAgentLocation } from '../../common/chatAgents.js'; export const ACTION_ID_NEW_CHAT = `workbench.action.chat.newChat`; @@ -139,7 +140,7 @@ export function registerNewChatActions() { const viewsService = accessor.get(IViewsService); let widget = widgetService.lastFocusedWidget; - if (!widget) { + if (!widget || widget.location !== ChatAgentLocation.EditingSession) { const chatView = await viewsService.openView(EDITS_VIEW_ID) as ChatViewPane; widget = chatView.widget; } diff --git a/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts b/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts index fdff4f2c19797..94d12546a42c3 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/chatExecuteActions.ts @@ -167,7 +167,7 @@ export class CancelAction extends Action2 { menu: { id: MenuId.ChatExecute, when: CONTEXT_CHAT_REQUEST_IN_PROGRESS, - order: 2, + order: 4, group: 'navigation', }, keybinding: { diff --git a/src/vs/workbench/contrib/chat/browser/actions/codeBlockOperations.ts b/src/vs/workbench/contrib/chat/browser/actions/codeBlockOperations.ts index e4d58e6fdea9e..161860a4efc64 100644 --- a/src/vs/workbench/contrib/chat/browser/actions/codeBlockOperations.ts +++ b/src/vs/workbench/contrib/chat/browser/actions/codeBlockOperations.ts @@ -8,15 +8,13 @@ import { VSBuffer } from '../../../../../base/common/buffer.js'; import { CancellationTokenSource } from '../../../../../base/common/cancellation.js'; import { CharCode } from '../../../../../base/common/charCode.js'; import { isCancellationError } from '../../../../../base/common/errors.js'; -import { ResourceMap } from '../../../../../base/common/map.js'; import { isEqual } from '../../../../../base/common/resources.js'; import * as strings from '../../../../../base/common/strings.js'; -import { URI } from '../../../../../base/common/uri.js'; import { IActiveCodeEditor, isCodeEditor, isDiffEditor } from '../../../../../editor/browser/editorBrowser.js'; import { IBulkEditService, ResourceTextEdit } from '../../../../../editor/browser/services/bulkEditService.js'; import { ICodeEditorService } from '../../../../../editor/browser/services/codeEditorService.js'; import { Range } from '../../../../../editor/common/core/range.js'; -import { ConversationRequest, ConversationResponse, DocumentContextItem, isLocation, IWorkspaceFileEdit, IWorkspaceTextEdit } from '../../../../../editor/common/languages.js'; +import { ConversationRequest, ConversationResponse, DocumentContextItem, IWorkspaceFileEdit, IWorkspaceTextEdit } from '../../../../../editor/common/languages.js'; import { ILanguageService } from '../../../../../editor/common/languages/language.js'; import { ITextModel } from '../../../../../editor/common/model.js'; import { ILanguageFeaturesService } from '../../../../../editor/common/services/languageFeatures.js'; @@ -31,7 +29,8 @@ import { InlineChatController } from '../../../inlineChat/browser/inlineChatCont import { insertCell } from '../../../notebook/browser/controller/cellOperations.js'; import { IActiveNotebookEditor, INotebookEditor } from '../../../notebook/browser/notebookBrowser.js'; import { CellKind, NOTEBOOK_EDITOR_ID } from '../../../notebook/common/notebookCommon.js'; -import { ChatUserAction, IChatContentReference, IChatService } from '../../common/chatService.js'; +import { getReferencesAsDocumentContext } from '../../common/chatCodeMapperService.js'; +import { ChatUserAction, IChatService } from '../../common/chatService.js'; import { isRequestVM, isResponseVM } from '../../common/chatViewModel.js'; import { ICodeBlockActionContext } from '../codeBlockPart.js'; @@ -404,32 +403,6 @@ function getChatConversation(context: ICodeBlockActionContext): (ConversationReq } } -function getReferencesAsDocumentContext(res: readonly IChatContentReference[]): DocumentContextItem[] { - const map = new ResourceMap(); - for (const r of res) { - let uri; - let range; - if (URI.isUri(r.reference)) { - uri = r.reference; - } else if (isLocation(r.reference)) { - uri = r.reference.uri; - range = r.reference.range; - } - if (uri) { - const item = map.get(uri); - if (item) { - if (range) { - item.ranges.push(range); - } - } else { - map.set(uri, { uri, version: -1, ranges: range ? [range] : [] }); - } - } - } - return [...map.values()]; -} - - function reindent(codeBlockContent: string, model: ITextModel, seletionStartLine: number): string { const newContent = strings.splitLines(codeBlockContent); if (newContent.length === 0) { diff --git a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts index bec60f8fd124a..dda6330c614ac 100644 --- a/src/vs/workbench/contrib/chat/browser/chat.contribution.ts +++ b/src/vs/workbench/contrib/chat/browser/chat.contribution.ts @@ -3,6 +3,7 @@ * Licensed under the MIT License. See License.txt in the project root for license information. *--------------------------------------------------------------------------------------------*/ +import { timeout } from '../../../../base/common/async.js'; import { MarkdownString, isMarkdownString } from '../../../../base/common/htmlContent.js'; import { Disposable } from '../../../../base/common/lifecycle.js'; import { Schemas } from '../../../../base/common/network.js'; @@ -263,6 +264,11 @@ class ChatSlashStaticSlashCommandsContribution extends Disposable { progress.report({ content: new MarkdownString(defaultAgent.metadata.helpTextPostfix), kind: 'markdownContent' }); } } + + // Without this, the response will be done before it renders and so it will not stream. This ensures that if the response starts + // rendering during the next 200ms, then it will be streamed. Once it starts streaming, the whole response streams even after + // it has received all response data has been received. + await timeout(200); })); } } diff --git a/src/vs/workbench/contrib/chat/browser/chatContentParts/chatReferencesContentPart.ts b/src/vs/workbench/contrib/chat/browser/chatContentParts/chatReferencesContentPart.ts index 2ca9d305f544d..0c31726d04843 100644 --- a/src/vs/workbench/contrib/chat/browser/chatContentParts/chatReferencesContentPart.ts +++ b/src/vs/workbench/contrib/chat/browser/chatContentParts/chatReferencesContentPart.ts @@ -6,6 +6,7 @@ import * as dom from '../../../../../base/browser/dom.js'; import { Button } from '../../../../../base/browser/ui/button/button.js'; import { IListRenderer, IListVirtualDelegate } from '../../../../../base/browser/ui/list/list.js'; +import { IAction } from '../../../../../base/common/actions.js'; import { coalesce } from '../../../../../base/common/arrays.js'; import { Codicon } from '../../../../../base/common/codicons.js'; import { Emitter, Event } from '../../../../../base/common/event.js'; @@ -15,13 +16,13 @@ import { basename } from '../../../../../base/common/path.js'; import { basenameOrAuthority, isEqualAuthority } from '../../../../../base/common/resources.js'; import { ThemeIcon } from '../../../../../base/common/themables.js'; import { URI } from '../../../../../base/common/uri.js'; -import { localize } from '../../../../../nls.js'; +import { localize, localize2 } from '../../../../../nls.js'; +import { createAndFillInContextMenuActions } from '../../../../../platform/actions/browser/menuEntryActionViewItem.js'; import { MenuWorkbenchToolBar } from '../../../../../platform/actions/browser/toolbar.js'; -import { MenuId } from '../../../../../platform/actions/common/actions.js'; -import { IClipboardService } from '../../../../../platform/clipboard/common/clipboardService.js'; +import { Action2, IMenuService, MenuId, registerAction2 } from '../../../../../platform/actions/common/actions.js'; import { IContextMenuService } from '../../../../../platform/contextview/browser/contextView.js'; import { FileKind } from '../../../../../platform/files/common/files.js'; -import { IInstantiationService } from '../../../../../platform/instantiation/common/instantiation.js'; +import { IInstantiationService, ServicesAccessor } from '../../../../../platform/instantiation/common/instantiation.js'; import { ILabelService } from '../../../../../platform/label/common/label.js'; import { WorkbenchList } from '../../../../../platform/list/browser/listService.js'; import { IOpenerService } from '../../../../../platform/opener/common/opener.js'; @@ -30,12 +31,14 @@ import { IThemeService } from '../../../../../platform/theme/common/themeService import { fillEditorsDragData } from '../../../../browser/dnd.js'; import { IResourceLabel, ResourceLabels } from '../../../../browser/labels.js'; import { ColorScheme } from '../../../../browser/web.api.js'; +import { ResourceContextKey } from '../../../../common/contextkeys.js'; import { SETTINGS_AUTHORITY } from '../../../../services/preferences/common/preferences.js'; import { createFileIconThemableTreeContainerScope } from '../../../files/browser/views/explorerView.js'; +import { ExplorerFolderContext } from '../../../files/common/files.js'; import { ChatResponseReferencePartStatusKind, IChatContentReference, IChatWarningMessage } from '../../common/chatService.js'; import { IChatVariablesService } from '../../common/chatVariables.js'; import { IChatRendererContent, IChatResponseViewModel } from '../../common/chatViewModel.js'; -import { ChatTreeItem } from '../chat.js'; +import { ChatTreeItem, IChatWidgetService } from '../chat.js'; import { IDisposableReference, ResourcePool } from './chatCollections.js'; import { IChatContentPart } from './chatContentParts.js'; @@ -59,8 +62,9 @@ export class ChatCollapsibleListContentPart extends Disposable implements IChatC element: IChatResponseViewModel, contentReferencesListPool: CollapsibleListPool, @IOpenerService openerService: IOpenerService, + @IMenuService menuService: IMenuService, + @IInstantiationService private readonly instantiationService: IInstantiationService, @IContextMenuService private readonly contextMenuService: IContextMenuService, - @IClipboardService private readonly clipboardService: IClipboardService, ) { super(); @@ -120,34 +124,32 @@ export class ChatCollapsibleListContentPart extends Disposable implements IChatC } } })); - this._register(list.onContextMenu((e) => { - e.browserEvent.preventDefault(); - e.browserEvent.stopPropagation(); - if (e.element && 'reference' in e.element && typeof e.element.reference === 'object') { - const uriOrLocation = 'variableName' in e.element.reference ? e.element.reference.value : e.element.reference; - const uri = URI.isUri(uriOrLocation) ? uriOrLocation : - uriOrLocation?.uri; - if (uri) { - this.contextMenuService.showContextMenu({ - getAnchor: () => e.anchor, - getActions: () => { - return [{ - id: 'workbench.action.chat.copyReference', - title: localize('copyReference', "Copy"), - label: localize('copyReference', "Copy"), - tooltip: localize('copyReference', "Copy"), - enabled: e.element?.kind === 'reference', - class: undefined, - run: () => { - void this.clipboardService.writeResources([uri]); - } - }]; - } - }); - } + this._register(list.onContextMenu(e => { + dom.EventHelper.stop(e.browserEvent, true); + + const uri = e.element && getResourceForElement(e.element); + if (!uri) { + return; } + this.contextMenuService.showContextMenu({ + getAnchor: () => e.anchor, + getActions: () => { + const menu = menuService.getMenuActions(MenuId.ChatAttachmentsContext, list.contextKeyService, { shouldForwardArgs: true, arg: uri }); + const primary: IAction[] = []; + createAndFillInContextMenuActions(menu, primary); + return primary; + } + }); + })); + + const resourceContextKey = this._register(this.instantiationService.createInstance(ResourceContextKey)); + this._register(list.onDidChangeFocus(e => { + resourceContextKey.reset(); + const element = e.elements.length ? e.elements[0] : undefined; + const uri = element && getResourceForElement(element); + resourceContextKey.set(uri ?? null); })); const maxItemsShown = 6; @@ -197,20 +199,6 @@ export class CollapsibleListPool extends Disposable { const container = $('.chat-used-context-list'); this._register(createFileIconThemableTreeContainerScope(container, this.themeService)); - const getDragURI = (element: IChatCollapsibleListItem): URI | null => { - if (element.kind === 'warning') { - return null; - } - const { reference } = element; - if (typeof reference === 'string' || 'variableName' in reference) { - return null; - } else if (URI.isUri(reference)) { - return reference; - } else { - return reference.uri; - } - }; - const list = this.instantiationService.createInstance( WorkbenchList, 'ChatListRenderer', @@ -239,9 +227,9 @@ export class CollapsibleListPool extends Disposable { getWidgetAriaLabel: () => localize('chatCollapsibleList', "Collapsible Chat List") }, dnd: { - getDragURI: (element: IChatCollapsibleListItem) => getDragURI(element)?.toString() ?? null, + getDragURI: (element: IChatCollapsibleListItem) => getResourceForElement(element)?.toString() ?? null, getDragLabel: (elements, originalEvent) => { - const uris: URI[] = coalesce(elements.map(getDragURI)); + const uris: URI[] = coalesce(elements.map(getResourceForElement)); if (!uris.length) { return undefined; } else if (uris.length === 1) { @@ -256,7 +244,7 @@ export class CollapsibleListPool extends Disposable { onDragStart: (data, originalEvent) => { try { const elements = data.getData() as IChatCollapsibleListItem[]; - const uris: URI[] = coalesce(elements.map(getDragURI)); + const uris: URI[] = coalesce(elements.map(getResourceForElement)); this.instantiationService.invokeFunction(accessor => fillEditorsDragData(accessor, uris, originalEvent)); } catch { // noop @@ -294,8 +282,8 @@ class CollapsibleListDelegate implements IListVirtualDelegate { @@ -414,3 +402,58 @@ class CollapsibleListRenderer implements IListRenderer { + const chatWidgetService = accessor.get(IChatWidgetService); + const variablesService = accessor.get(IChatVariablesService); + + if (!resource) { + return; + } + + const widget = chatWidgetService.lastFocusedWidget; + if (!widget) { + return; + } + + variablesService.attachContext('file', resource, widget.location); + } +}); + +//#endregion diff --git a/src/vs/workbench/contrib/chat/browser/chatEditingService.ts b/src/vs/workbench/contrib/chat/browser/chatEditingService.ts index 3321419dba3a0..14874cf40adf9 100644 --- a/src/vs/workbench/contrib/chat/browser/chatEditingService.ts +++ b/src/vs/workbench/contrib/chat/browser/chatEditingService.ts @@ -574,6 +574,7 @@ class ChatEditingSession extends Disposable implements IChatEditingSession { @ITextModelService private readonly _textModelService: ITextModelService, @IBulkEditService public readonly _bulkEditService: IBulkEditService, @IEditorGroupsService private readonly _editorGroupsService: IEditorGroupsService, + @IEditorService private readonly editorService: IEditorService, ) { super(); } @@ -708,7 +709,8 @@ class ChatEditingSession extends Disposable implements IChatEditingSession { private async _acceptTextEdits(resource: URI, textEdits: TextEdit[]): Promise { const entry = await this._getOrCreateModifiedFileEntry(resource); - entry.appyEdits(textEdits); + entry.applyEdits(textEdits); + await this.editorService.openEditor({ original: { resource: entry.originalURI }, modified: { resource: entry.modifiedURI }, options: { inactive: true } }); } private async _resolve(): Promise { @@ -796,7 +798,7 @@ class ModifiedFileEntry extends Disposable implements IModifiedFileEntry { this._register(resourceRef); } - appyEdits(textEdits: TextEdit[]): void { + applyEdits(textEdits: TextEdit[]): void { this.doc.applyEdits(textEdits); this._stateObs.set(ModifiedFileEntryState.Undecided, undefined); } diff --git a/src/vs/workbench/contrib/chat/browser/chatWidget.ts b/src/vs/workbench/contrib/chat/browser/chatWidget.ts index 13849afedf0ad..3de9f7c3bf16e 100644 --- a/src/vs/workbench/contrib/chat/browser/chatWidget.ts +++ b/src/vs/workbench/contrib/chat/browser/chatWidget.ts @@ -984,7 +984,7 @@ export class ChatWidget extends Disposable implements IChatWidget { this.tree.getHTMLElement().style.height = `${listHeight}px`; // Push the welcome message down so it doesn't change position when followups appear - const followupsOffset = 100 - this.inputPart.followupsHeight; + const followupsOffset = Math.max(100 - this.inputPart.followupsHeight, 0); this.welcomeMessageContainer.style.height = `${listHeight - followupsOffset}px`; this.welcomeMessageContainer.style.paddingBottom = `${followupsOffset}px`; this.renderer.layout(width); diff --git a/src/vs/workbench/contrib/chat/common/chatCodeMapperService.ts b/src/vs/workbench/contrib/chat/common/chatCodeMapperService.ts index 150cda7efd83e..bb6b812551f85 100644 --- a/src/vs/workbench/contrib/chat/common/chatCodeMapperService.ts +++ b/src/vs/workbench/contrib/chat/common/chatCodeMapperService.ts @@ -6,12 +6,15 @@ import { CancellationToken } from '../../../../base/common/cancellation.js'; import { CharCode } from '../../../../base/common/charCode.js'; import { IDisposable } from '../../../../base/common/lifecycle.js'; +import { ResourceMap } from '../../../../base/common/map.js'; import { splitLinesIncludeSeparators } from '../../../../base/common/strings.js'; import { isString } from '../../../../base/common/types.js'; import { URI } from '../../../../base/common/uri.js'; -import { TextEdit } from '../../../../editor/common/languages.js'; +import { DocumentContextItem, isLocation, TextEdit } from '../../../../editor/common/languages.js'; import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js'; +import { IChatAgentResult } from './chatAgents.js'; import { IChatResponseModel } from './chatModel.js'; +import { IChatContentReference } from './chatService.js'; export interface ICodeMapperResponse { @@ -19,8 +22,9 @@ export interface ICodeMapperResponse { } export interface ICodeMapperCodeBlock { - code: string; - resource: URI; + readonly code: string; + readonly resource: URI; + readonly markdownBeforeBlock?: string; } export interface ConversationRequest { @@ -31,16 +35,17 @@ export interface ConversationRequest { export interface ConversationResponse { readonly type: 'response'; readonly message: string; - // readonly references?: DocumentContextItem[]; + readonly result?: IChatAgentResult; + readonly references?: DocumentContextItem[]; } export interface ICodeMapperRequest { - codeBlocks: ICodeMapperCodeBlock[]; - conversation: (ConversationRequest | ConversationResponse)[]; + readonly codeBlocks: ICodeMapperCodeBlock[]; + readonly conversation: (ConversationResponse | ConversationRequest)[]; } export interface ICodeMapperResult { - errorMessage?: string; + readonly errorMessage?: string; } export interface ICodeMapperProvider { @@ -103,7 +108,7 @@ export class CodeMapperService implements ICodeMapperService { fence = undefined; if (currentBlockUri) { // report the code block if we have a URI - codeBlocks.push({ code: currentBlock.join(''), resource: currentBlockUri }); + codeBlocks.push({ code: currentBlock.join(''), resource: currentBlockUri, markdownBeforeBlock: markdownBeforeBlock.join('') }); currentBlock.length = 0; markdownBeforeBlock.length = 0; currentBlockUri = undefined; @@ -123,7 +128,24 @@ export class CodeMapperService implements ICodeMapperService { currentBlockUri = lineOrUri; } } - return this.mapCode({ codeBlocks, conversation: [] }, response, token); + const conversation: (ConversationRequest | ConversationResponse)[] = []; + for (const request of responseModel.session.getRequests()) { + const response = request.response; + if (!response || response === responseModel) { + break; + } + conversation.push({ + type: 'request', + message: request.message.text + }); + conversation.push({ + type: 'response', + message: response.response.toMarkdown(), + result: response.result, + references: getReferencesAsDocumentContext(response.contentReferences) + }); + } + return this.mapCode({ codeBlocks, conversation }, response, token); } } @@ -155,3 +177,29 @@ function isLineIncomplete(line: string) { const lastChar = line.charCodeAt(line.length - 1); return lastChar !== CharCode.LineFeed && lastChar !== CharCode.CarriageReturn; } + + +export function getReferencesAsDocumentContext(res: readonly IChatContentReference[]): DocumentContextItem[] { + const map = new ResourceMap(); + for (const r of res) { + let uri; + let range; + if (URI.isUri(r.reference)) { + uri = r.reference; + } else if (isLocation(r.reference)) { + uri = r.reference.uri; + range = r.reference.range; + } + if (uri) { + const item = map.get(uri); + if (item) { + if (range) { + item.ranges.push(range); + } + } else { + map.set(uri, { uri, version: -1, ranges: range ? [range] : [] }); + } + } + } + return [...map.values()]; +} diff --git a/src/vs/workbench/contrib/debug/browser/repl.ts b/src/vs/workbench/contrib/debug/browser/repl.ts index 7e33db78057e0..613fed3ce95ba 100644 --- a/src/vs/workbench/contrib/debug/browser/repl.ts +++ b/src/vs/workbench/contrib/debug/browser/repl.ts @@ -210,6 +210,7 @@ export class Repl extends FilterViewPane implements IHistoryNavigationWidget { this.refreshReplElements(true); if (this.styleChangedWhenInvisible) { this.styleChangedWhenInvisible = false; + this.tree?.updateChildren(undefined, true, false); this.onDidStyleChange(); } } diff --git a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts index 81904a45cec17..ec2a3a69d0aaa 100644 --- a/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/browser/fileActions.contribution.ts @@ -767,6 +767,36 @@ MenuRegistry.appendMenuItem(MenuId.MenubarGoMenu, { }); +// Chat used attachment anchor context menu + +MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, { + group: 'navigation', + order: 10, + command: openToSideCommand, + when: ContextKeyExpr.and(ResourceContextKey.HasResource, ExplorerFolderContext.toNegated()) +}); + +MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, { + group: 'navigation', + order: 20, + command: revealInsideBarCommand, + when: ResourceContextKey.IsFileSystemResource +}); + +MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, { + group: '1_cutcopypaste', + order: 10, + command: copyPathCommand, + when: ResourceContextKey.IsFileSystemResource +}); + +MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, { + group: '1_cutcopypaste', + order: 20, + command: copyRelativePathCommand, + when: ResourceContextKey.IsFileSystemResource +}); + // Chat resource anchor context menu MenuRegistry.appendMenuItem(MenuId.ChatInlineResourceAnchorContext, { diff --git a/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts b/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts index 1d75d5e5e44ca..5581931a9e7d1 100644 --- a/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts +++ b/src/vs/workbench/contrib/files/electron-sandbox/fileActions.contribution.ts @@ -97,6 +97,15 @@ appendToCommandPalette({ category: category }, REVEAL_IN_OS_WHEN_CONTEXT); +// Menu registration - chat attachments context + +MenuRegistry.appendMenuItem(MenuId.ChatAttachmentsContext, { + group: 'navigation', + order: 20, + command: revealInOsCommand, + when: REVEAL_IN_OS_WHEN_CONTEXT +}); + // Menu registration - chat inline anchor MenuRegistry.appendMenuItem(MenuId.ChatInlineResourceAnchorContext, { diff --git a/src/vs/workbench/contrib/scm/browser/media/scm.css b/src/vs/workbench/contrib/scm/browser/media/scm.css index 0c72ca522f9ae..4ba122fa37019 100644 --- a/src/vs/workbench/contrib/scm/browser/media/scm.css +++ b/src/vs/workbench/contrib/scm/browser/media/scm.css @@ -168,6 +168,12 @@ line-height: 18px; } +.scm-view .monaco-list-row .history-item > .label-container > .label > .count { + font-size: 12px; + margin-left: 0; + padding-left: 4px; +} + .scm-view .monaco-list-row .history-item > .label-container > .label > .codicon { font-size: 14px; color: inherit !important; diff --git a/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts b/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts index 4de2e1841eb22..79ae478779259 100644 --- a/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts +++ b/src/vs/workbench/contrib/scm/browser/scmHistoryViewPane.ts @@ -365,17 +365,27 @@ class HistoryItemRenderer implements ITreeRenderer { const labelConfig = this._badgesConfig.read(reader); - const firstColoredRef = historyItem.references?.find(ref => ref.color); templateData.labelContainer.textContent = ''; + const references = historyItem.references ? + historyItem.references.slice(0) : []; + + // If the first reference is colored, we render it + // separately since we have to show the description + // for the first colored reference. + if (references.length > 0 && references[0].color) { + this._renderBadge([references[0]], true, templateData); + + // Remove the rendered reference from the collection + references.splice(0, 1); + } + // Group history item references by color - const historyItemRefsByColor = groupBy2( - (historyItem.references ?? []), - ref => ref.color ? ref.color : ''); + const historyItemRefsByColor = groupBy2(references, ref => ref.color ? ref.color : ''); for (const [key, historyItemRefs] of Object.entries(historyItemRefsByColor)) { - // Skip badges with no color + // If needed skip badges without a color if (key === '' && labelConfig !== 'all') { continue; } @@ -383,35 +393,44 @@ class HistoryItemRenderer implements ITreeRenderer ThemeIcon.isThemeIcon(ref.icon) ? ref.icon.id : ''); for (const [key, historyItemRefs] of Object.entries(historyItemRefByIconId)) { - if (key === '' || historyItemRefs.length === 0) { + // Skip badges without an icon + if (key === '') { continue; } - this._renderBadge(historyItemRefs[0], historyItemRefs[0] === firstColoredRef, templateData); + this._renderBadge(historyItemRefs, false, templateData); } } })); } - private _renderBadge(historyItemRef: ISCMHistoryItemRef, showDescription: boolean, templateData: HistoryItemTemplate): void { - if (!ThemeIcon.isThemeIcon(historyItemRef.icon)) { + private _renderBadge(historyItemRefs: ISCMHistoryItemRef[], showDescription: boolean, templateData: HistoryItemTemplate): void { + if (historyItemRefs.length === 0 || !ThemeIcon.isThemeIcon(historyItemRefs[0].icon)) { return; } const elements = h('div.label', { style: { - color: historyItemRef.color ? asCssVariable(historyItemHoverLabelForeground) : asCssVariable(foreground), - backgroundColor: historyItemRef.color ? asCssVariable(historyItemRef.color) : asCssVariable(historyItemHoverDefaultLabelBackground) + color: historyItemRefs[0].color ? asCssVariable(historyItemHoverLabelForeground) : asCssVariable(foreground), + backgroundColor: historyItemRefs[0].color ? asCssVariable(historyItemRefs[0].color) : asCssVariable(historyItemHoverDefaultLabelBackground) } }, [ + h('div.count@count', { + style: { + display: historyItemRefs.length > 1 ? '' : 'none' + } + }), h('div.icon@icon'), - h('div.description@description') + h('div.description@description', { + style: { + display: showDescription ? '' : 'none' + } + }) ]); - elements.icon.classList.add(...ThemeIcon.asClassNameArray(historyItemRef.icon)); - - elements.description.textContent = historyItemRef.name; - elements.description.style.display = showDescription ? '' : 'none'; + elements.count.textContent = historyItemRefs.length > 1 ? historyItemRefs.length.toString() : ''; + elements.icon.classList.add(...ThemeIcon.asClassNameArray(historyItemRefs[0].icon)); + elements.description.textContent = showDescription ? historyItemRefs[0].name : ''; append(templateData.labelContainer, elements.root); } diff --git a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts index c821d7ccf4888..bac17da1e196b 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalInstance.ts @@ -756,6 +756,7 @@ export class TerminalInstance extends Disposable implements ITerminalInstance { Terminal, this._cols, this._rows, + undefined, this._scopedInstantiationService.createInstance(TerminalInstanceColorProvider, this._targetRef), this.capabilities, this._processManager.shellIntegrationNonce, diff --git a/src/vs/workbench/contrib/terminal/browser/terminalService.ts b/src/vs/workbench/contrib/terminal/browser/terminalService.ts index b1da8a45dd898..88a2aace6aeca 100644 --- a/src/vs/workbench/contrib/terminal/browser/terminalService.ts +++ b/src/vs/workbench/contrib/terminal/browser/terminalService.ts @@ -1028,6 +1028,7 @@ export class TerminalService extends Disposable implements ITerminalService { ctor, options.cols, options.rows, + undefined, options.colorProvider, options.capabilities || new TerminalCapabilityStore(), '', diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermAddonImporter.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermAddonImporter.ts new file mode 100644 index 0000000000000..b78debc63c2ba --- /dev/null +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermAddonImporter.ts @@ -0,0 +1,54 @@ +/*--------------------------------------------------------------------------------------------- + * Copyright (c) Microsoft Corporation. All rights reserved. + * Licensed under the MIT License. See License.txt in the project root for license information. + *--------------------------------------------------------------------------------------------*/ + +import type { ClipboardAddon as ClipboardAddonType } from '@xterm/addon-clipboard'; +import type { ImageAddon as ImageAddonType } from '@xterm/addon-image'; +import type { SearchAddon as SearchAddonType } from '@xterm/addon-search'; +import type { SerializeAddon as SerializeAddonType } from '@xterm/addon-serialize'; +import type { Unicode11Addon as Unicode11AddonType } from '@xterm/addon-unicode11'; +import type { WebglAddon as WebglAddonType } from '@xterm/addon-webgl'; +import { importAMDNodeModule } from '../../../../../amdX.js'; + +export interface IXtermAddonNameToCtor { + clipboard: typeof ClipboardAddonType; + image: typeof ImageAddonType; + search: typeof SearchAddonType; + serialize: typeof SerializeAddonType; + unicode11: typeof Unicode11AddonType; + webgl: typeof WebglAddonType; +} + +// This interface lets a maps key and value be linked with generics +interface IImportedXtermAddonMap extends Map { + get(name: K): IXtermAddonNameToCtor[K] | undefined; + set(name: K, value: IXtermAddonNameToCtor[K]): this; +} + +const importedAddons: IImportedXtermAddonMap = new Map(); + +/** + * Exposes a simple interface to consumers, encapsulating the messy import xterm + * addon import and caching logic. + */ +export class XtermAddonImporter { + async importAddon(name: T): Promise { + let addon = importedAddons.get(name); + if (!addon) { + switch (name) { + case 'clipboard': addon = (await importAMDNodeModule('@xterm/addon-clipboard', 'lib/addon-clipboard.js')).ClipboardAddon as IXtermAddonNameToCtor[T]; break; + case 'image': addon = (await importAMDNodeModule('@xterm/addon-image', 'lib/addon-image.js')).ImageAddon as IXtermAddonNameToCtor[T]; break; + case 'search': addon = (await importAMDNodeModule('@xterm/addon-search', 'lib/addon-search.js')).SearchAddon as IXtermAddonNameToCtor[T]; break; + case 'serialize': addon = (await importAMDNodeModule('@xterm/addon-serialize', 'lib/addon-serialize.js')).SerializeAddon as IXtermAddonNameToCtor[T]; break; + case 'unicode11': addon = (await importAMDNodeModule('@xterm/addon-unicode11', 'lib/addon-unicode11.js')).Unicode11Addon as IXtermAddonNameToCtor[T]; break; + case 'webgl': addon = (await importAMDNodeModule('@xterm/addon-webgl', 'lib/addon-webgl.js')).WebglAddon as IXtermAddonNameToCtor[T]; break; + } + if (!addon) { + throw new Error(`Could not load addon ${name}`); + } + importedAddons.set(name, addon); + } + return addon as IXtermAddonNameToCtor[T]; + } +} diff --git a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts index c5bd84fa99799..9683b7597a642 100644 --- a/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts +++ b/src/vs/workbench/contrib/terminal/browser/xterm/xtermTerminal.ts @@ -31,7 +31,6 @@ import { DecorationAddon } from './decorationAddon.js'; import { ITerminalCapabilityStore, ITerminalCommand, TerminalCapability } from '../../../../../platform/terminal/common/capabilities/capabilities.js'; import { Emitter } from '../../../../../base/common/event.js'; import { ITelemetryService } from '../../../../../platform/telemetry/common/telemetry.js'; -import { importAMDNodeModule } from '../../../../../amdX.js'; import { IContextKey, IContextKeyService } from '../../../../../platform/contextkey/common/contextkey.js'; import { TerminalContextKeys } from '../../common/terminalContextKey.js'; import { IClipboardService } from '../../../../../platform/clipboard/common/clipboardService.js'; @@ -41,17 +40,12 @@ import { IMouseWheelEvent, StandardWheelEvent } from '../../../../../base/browse import { ILayoutService } from '../../../../../platform/layout/browser/layoutService.js'; import { AccessibilitySignal, IAccessibilitySignalService } from '../../../../../platform/accessibilitySignal/browser/accessibilitySignalService.js'; import { scrollbarSliderActiveBackground, scrollbarSliderBackground, scrollbarSliderHoverBackground } from '../../../../../platform/theme/common/colorRegistry.js'; +import { XtermAddonImporter } from './xtermAddonImporter.js'; const enum RenderConstants { SmoothScrollDuration = 125 } -let ClipboardAddon: typeof ClipboardAddonType; -let ImageAddon: typeof ImageAddonType; -let SearchAddon: typeof SearchAddonType; -let SerializeAddon: typeof SerializeAddonType; -let Unicode11Addon: typeof Unicode11AddonType; -let WebglAddon: typeof WebglAddonType; function getFullBufferLineAsString(lineIndex: number, buffer: IBuffer): { lineData: string | undefined; lineIndex: number } { let line = buffer.getLine(lineIndex); @@ -180,6 +174,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach xtermCtor: typeof RawXtermTerminal, cols: number, rows: number, + private readonly _xtermAddonLoader: XtermAddonImporter = new XtermAddonImporter(), private readonly _xtermColorProvider: IXtermColorProvider, private readonly _capabilities: ITerminalCapabilityStore, shellIntegrationNonce: string, @@ -281,7 +276,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach this.raw.loadAddon(this._decorationAddon); this._shellIntegrationAddon = new ShellIntegrationAddon(shellIntegrationNonce, disableShellIntegrationReporting, this._telemetryService, this._logService); this.raw.loadAddon(this._shellIntegrationAddon); - this._getClipboardAddonConstructor().then(ClipboardAddon => { + this._xtermAddonLoader.importAddon('clipboard').then(ClipboardAddon => { this._clipboardAddon = this._instantiationService.createInstance(ClipboardAddon, undefined, { async readText(type: ClipboardSelectionType): Promise { return _clipboardService.readText(type === 'p' ? 'selection' : 'clipboard'); @@ -309,7 +304,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach async getContentsAsHtml(): Promise { if (!this._serializeAddon) { - const Addon = await this._getSerializeAddonConstructor(); + const Addon = await this._xtermAddonLoader.importAddon('serialize'); this._serializeAddon = new Addon(); this.raw.loadAddon(this._serializeAddon); } @@ -319,7 +314,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach async getSelectionAsHtml(command?: ITerminalCommand): Promise { if (!this._serializeAddon) { - const Addon = await this._getSerializeAddonConstructor(); + const Addon = await this._xtermAddonLoader.importAddon('serialize'); this._serializeAddon = new Addon(); this.raw.loadAddon(this._serializeAddon); } @@ -485,7 +480,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach private _searchAddonPromise: Promise | undefined; private _getSearchAddon(): Promise { if (!this._searchAddonPromise) { - this._searchAddonPromise = this._getSearchAddonConstructor().then((AddonCtor) => { + this._searchAddonPromise = this._xtermAddonLoader.importAddon('search').then((AddonCtor) => { this._searchAddon = new AddonCtor({ highlightLimit: XtermTerminalConstants.SearchHighlightLimit }); this.raw.loadAddon(this._searchAddon); this._searchAddon.onDidChangeResults((results: { resultIndex: number; resultCount: number }) => { @@ -687,7 +682,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach } } - const Addon = await this._getWebglAddonConstructor(); + const Addon = await this._xtermAddonLoader.importAddon('webgl'); this._webglAddon = new Addon(); try { this.raw.loadAddon(this._webglAddon); @@ -722,7 +717,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach // Only allow the image addon when webgl is being used to avoid possible GPU issues if (this._terminalConfigurationService.config.enableImages && this._webglAddon) { if (!this._imageAddon) { - const AddonCtor = await this._getImageAddonConstructor(); + const AddonCtor = await this._xtermAddonLoader.importAddon('image'); this._imageAddon = new AddonCtor(); this.raw.loadAddon(this._imageAddon); } @@ -736,48 +731,6 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach } } - protected async _getClipboardAddonConstructor(): Promise { - if (!ClipboardAddon) { - ClipboardAddon = (await importAMDNodeModule('@xterm/addon-clipboard', 'lib/addon-clipboard.js')).ClipboardAddon; - } - return ClipboardAddon; - } - - protected async _getImageAddonConstructor(): Promise { - if (!ImageAddon) { - ImageAddon = (await importAMDNodeModule('@xterm/addon-image', 'lib/addon-image.js')).ImageAddon; - } - return ImageAddon; - } - - protected async _getSearchAddonConstructor(): Promise { - if (!SearchAddon) { - SearchAddon = (await importAMDNodeModule('@xterm/addon-search', 'lib/addon-search.js')).SearchAddon; - } - return SearchAddon; - } - - protected async _getUnicode11Constructor(): Promise { - if (!Unicode11Addon) { - Unicode11Addon = (await importAMDNodeModule('@xterm/addon-unicode11', 'lib/addon-unicode11.js')).Unicode11Addon; - } - return Unicode11Addon; - } - - protected async _getWebglAddonConstructor(): Promise { - if (!WebglAddon) { - WebglAddon = (await importAMDNodeModule('@xterm/addon-webgl', 'lib/addon-webgl.js')).WebglAddon; - } - return WebglAddon; - } - - protected async _getSerializeAddonConstructor(): Promise { - if (!SerializeAddon) { - SerializeAddon = (await importAMDNodeModule('@xterm/addon-serialize', 'lib/addon-serialize.js')).SerializeAddon; - } - return SerializeAddon; - } - private _disposeOfWebglRenderer(): void { try { this._webglAddon?.dispose(); @@ -849,7 +802,7 @@ export class XtermTerminal extends Disposable implements IXtermTerminal, IDetach private async _updateUnicodeVersion(): Promise { if (!this._unicode11Addon && this._terminalConfigurationService.config.unicodeVersion === '11') { - const Addon = await this._getUnicode11Constructor(); + const Addon = await this._xtermAddonLoader.importAddon('unicode11'); this._unicode11Addon = new Addon(); this.raw.loadAddon(this._unicode11Addon); } diff --git a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts index 82b32af67f009..ac776887732de 100644 --- a/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts +++ b/src/vs/workbench/contrib/terminal/test/browser/xterm/xtermTerminal.test.ts @@ -7,7 +7,6 @@ import type { WebglAddon } from '@xterm/addon-webgl'; import type { IEvent, Terminal } from '@xterm/xterm'; import { deepStrictEqual, strictEqual } from 'assert'; import { importAMDNodeModule } from '../../../../../../amdX.js'; -import { isSafari } from '../../../../../../base/browser/browser.js'; import { Color, RGBA } from '../../../../../../base/common/color.js'; import { Emitter } from '../../../../../../base/common/event.js'; import { ensureNoDisposablesAreLeakedInTestSuite } from '../../../../../../base/test/common/utils.js'; @@ -23,6 +22,7 @@ import { XtermTerminal } from '../../../browser/xterm/xtermTerminal.js'; import { ITerminalConfiguration, TERMINAL_VIEW_ID } from '../../../common/terminal.js'; import { registerColors, TERMINAL_BACKGROUND_COLOR, TERMINAL_CURSOR_BACKGROUND_COLOR, TERMINAL_CURSOR_FOREGROUND_COLOR, TERMINAL_FOREGROUND_COLOR, TERMINAL_INACTIVE_SELECTION_BACKGROUND_COLOR, TERMINAL_SELECTION_BACKGROUND_COLOR, TERMINAL_SELECTION_FOREGROUND_COLOR } from '../../../common/terminalColorRegistry.js'; import { workbenchInstantiationService } from '../../../../../test/browser/workbenchTestServices.js'; +import { IXtermAddonNameToCtor, XtermAddonImporter } from '../../../browser/xterm/xtermAddonImporter.js'; registerColors(); @@ -45,11 +45,12 @@ class TestWebglAddon implements WebglAddon { clearTextureAtlas() { } } -class TestXtermTerminal extends XtermTerminal { - webglAddonPromise: Promise = Promise.resolve(TestWebglAddon); - // Force synchronous to avoid async when activating the addon - protected override _getWebglAddonConstructor() { - return this.webglAddonPromise; +class TestXtermAddonImporter extends XtermAddonImporter { + override async importAddon(name: T): Promise { + if (name === 'webgl') { + return Promise.resolve(TestWebglAddon) as any; + } + return super.importAddon(name); } } @@ -90,7 +91,7 @@ suite('XtermTerminal', () => { let instantiationService: TestInstantiationService; let configurationService: TestConfigurationService; let themeService: TestThemeService; - let xterm: TestXtermTerminal; + let xterm: XtermTerminal; let XTermBaseCtor: typeof Terminal; setup(async () => { @@ -113,7 +114,7 @@ suite('XtermTerminal', () => { XTermBaseCtor = (await importAMDNodeModule('@xterm/xterm', 'lib/xterm.js')).Terminal; const capabilityStore = store.add(new TerminalCapabilityStore()); - xterm = store.add(instantiationService.createInstance(TestXtermTerminal, XTermBaseCtor, 80, 30, { getBackgroundColor: () => undefined }, capabilityStore, '', true)); + xterm = store.add(instantiationService.createInstance(XtermTerminal, XTermBaseCtor, 80, 30, new TestXtermAddonImporter(), { getBackgroundColor: () => undefined }, capabilityStore, '', true)); TestWebglAddon.shouldThrow = false; TestWebglAddon.isEnabled = false; @@ -130,7 +131,7 @@ suite('XtermTerminal', () => { [PANEL_BACKGROUND]: '#ff0000', [SIDE_BAR_BACKGROUND]: '#00ff00' })); - xterm = store.add(instantiationService.createInstance(XtermTerminal, XTermBaseCtor, 80, 30, { getBackgroundColor: () => new Color(new RGBA(255, 0, 0)) }, store.add(new TerminalCapabilityStore()), '', true)); + xterm = store.add(instantiationService.createInstance(XtermTerminal, XTermBaseCtor, 80, 30, new TestXtermAddonImporter(), { getBackgroundColor: () => new Color(new RGBA(255, 0, 0)) }, store.add(new TerminalCapabilityStore()), '', true)); strictEqual(xterm.raw.options.theme?.background, '#ff0000'); }); test('should react to and apply theme changes', () => { @@ -159,7 +160,7 @@ suite('XtermTerminal', () => { 'terminal.ansiBrightCyan': '#150000', 'terminal.ansiBrightWhite': '#160000', })); - xterm = store.add(instantiationService.createInstance(XtermTerminal, XTermBaseCtor, 80, 30, { getBackgroundColor: () => undefined }, store.add(new TerminalCapabilityStore()), '', true)); + xterm = store.add(instantiationService.createInstance(XtermTerminal, XTermBaseCtor, 80, 30, new TestXtermAddonImporter(), { getBackgroundColor: () => undefined }, store.add(new TerminalCapabilityStore()), '', true)); deepStrictEqual(xterm.raw.options.theme, { background: undefined, foreground: '#000200', @@ -245,40 +246,4 @@ suite('XtermTerminal', () => { }); }); }); - - suite('renderers', () => { - // This is skipped until the webgl renderer bug is fixed in Chromium - // https://bugs.chromium.org/p/chromium/issues/detail?id=1476475 - test.skip('should re-evaluate gpu acceleration auto when the setting is changed', async () => { - // Check initial state - strictEqual(TestWebglAddon.isEnabled, false); - - // Open xterm as otherwise the webgl addon won't activate - const container = document.createElement('div'); - xterm.attachToElement(container); - - // Auto should activate the webgl addon - await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'auto' } }); - configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); - await xterm.webglAddonPromise; // await addon activate - if (isSafari) { - strictEqual(TestWebglAddon.isEnabled, false, 'The webgl renderer is always disabled on Safari'); - } else { - strictEqual(TestWebglAddon.isEnabled, true); - } - - // Turn off to reset state - await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'off' } }); - configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); - await xterm.webglAddonPromise; // await addon activate - strictEqual(TestWebglAddon.isEnabled, false); - - // Set to auto again but throw when activating the webgl addon - TestWebglAddon.shouldThrow = true; - await configurationService.setUserConfiguration('terminal', { integrated: { ...defaultTerminalConfig, gpuAcceleration: 'auto' } }); - configurationService.onDidChangeConfigurationEmitter.fire({ affectsConfiguration: () => true } as any); - await xterm.webglAddonPromise; // await addon activate - strictEqual(TestWebglAddon.isEnabled, false); - }); - }); }); diff --git a/src/vs/workbench/contrib/terminalContrib/accessibility/test/browser/bufferContentTracker.test.ts b/src/vs/workbench/contrib/terminalContrib/accessibility/test/browser/bufferContentTracker.test.ts index e2c5d9e3a5e64..bd476ae6bdd6f 100644 --- a/src/vs/workbench/contrib/terminalContrib/accessibility/test/browser/bufferContentTracker.test.ts +++ b/src/vs/workbench/contrib/terminalContrib/accessibility/test/browser/bufferContentTracker.test.ts @@ -79,7 +79,7 @@ suite('Buffer Content Tracker', () => { capabilities.add(TerminalCapability.NaiveCwdDetection, null!); } const TerminalCtor = (await importAMDNodeModule('@xterm/xterm', 'lib/xterm.js')).Terminal; - xterm = store.add(instantiationService.createInstance(XtermTerminal, TerminalCtor, 80, 30, { getBackgroundColor: () => undefined }, capabilities, '', true)); + xterm = store.add(instantiationService.createInstance(XtermTerminal, TerminalCtor, 80, 30, undefined, { getBackgroundColor: () => undefined }, capabilities, '', true)); const container = document.createElement('div'); xterm.raw.open(container); configurationService = new TestConfigurationService({ terminal: { integrated: { tabs: { separator: ' - ', title: '${cwd}', description: '${cwd}' } } } }); diff --git a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.ts b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.ts index a86483a6a6fcf..6aac826a90366 100644 --- a/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.ts +++ b/src/vs/workbench/contrib/terminalContrib/chat/browser/terminalChatWidget.ts @@ -104,12 +104,7 @@ export class TerminalChatWidget extends Disposable { this._focusTracker = this._register(trackFocus(this._container)); this._register(this._focusTracker.onDidFocus(() => this._focusedContextKey.set(true))); - this._register(this._focusTracker.onDidBlur(() => { - this._focusedContextKey.set(false); - if (!this.inlineChatWidget.responseContent) { - this.hide(); - } - })); + this._register(this._focusTracker.onDidBlur(() => this._focusedContextKey.set(false))); this.hide(); } diff --git a/src/vs/workbench/contrib/terminalContrib/commandGuide/browser/terminal.commandGuide.contribution.ts b/src/vs/workbench/contrib/terminalContrib/commandGuide/browser/terminal.commandGuide.contribution.ts index ec3adb8093704..ef18811c74866 100644 --- a/src/vs/workbench/contrib/terminalContrib/commandGuide/browser/terminal.commandGuide.contribution.ts +++ b/src/vs/workbench/contrib/terminalContrib/commandGuide/browser/terminal.commandGuide.contribution.ts @@ -80,7 +80,7 @@ class TerminalCommandGuideContribution extends Disposable implements ITerminalCo if (!rect) { return; } - const mouseCursorY = Math.floor(e.offsetY / (rect.height / xterm.raw.rows)); + const mouseCursorY = Math.floor((e.clientY - rect.top) / (rect.height / xterm.raw.rows)); const command = this._instance.capabilities.get(TerminalCapability.CommandDetection)?.getCommandForLine(xterm.raw.buffer.active.viewportY + mouseCursorY); if (command && 'getOutput' in command) { xterm.markTracker.showCommandGuide(command); diff --git a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing.ts b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing.ts index 7f148d7fecf15..4ff47d600d311 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/browser/terminalLinkParsing.ts @@ -109,14 +109,19 @@ function generateLinkSuffixRegex(eolOnly: boolean) { // "foo", lines 339-341 [#171880] // "foo", lines 339-341, characters 12-789 [#178287] `['"]?(?:,? |: ?| on )lines? ${r()}(?:-${re()})?(?:,? (?:col(?:umn)?|characters?) ${c()}(?:-${ce()})?)?` + eolSuffix, + // () and [] are interchangeable // foo(339) // foo(339,12) // foo(339, 12) // foo (339) - // ... + // foo (339,12) + // foo (339, 12) // foo: (339) - // ... - `:? ?[\\[\\(]${r()}(?:, ?${c()})?[\\]\\)]` + eolSuffix, + // foo: (339,12) + // foo: (339, 12) + // foo(339:12) [#229842] + // foo (339:12) [#229842] + `:? ?[\\[\\(]${r()}(?:(?:, ?|:)${c()})?[\\]\\)]` + eolSuffix, ]; const suffixClause = lineAndColumnRegexClauses diff --git a/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLinkParsing.test.ts b/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLinkParsing.test.ts index 3f61393ab7110..099e639ee820e 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLinkParsing.test.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLinkParsing.test.ts @@ -125,6 +125,8 @@ const testLinks: ITestLink[] = [ { link: 'foo: (339)', prefix: undefined, suffix: ': (339)', hasRow: true, hasCol: false }, { link: 'foo: (339,12)', prefix: undefined, suffix: ': (339,12)', hasRow: true, hasCol: true }, { link: 'foo: (339, 12)', prefix: undefined, suffix: ': (339, 12)', hasRow: true, hasCol: true }, + { link: 'foo(339:12)', prefix: undefined, suffix: '(339:12)', hasRow: true, hasCol: true }, + { link: 'foo (339:12)', prefix: undefined, suffix: ' (339:12)', hasRow: true, hasCol: true }, // Square brackets { link: 'foo[339]', prefix: undefined, suffix: '[339]', hasRow: true, hasCol: false }, @@ -136,6 +138,8 @@ const testLinks: ITestLink[] = [ { link: 'foo: [339]', prefix: undefined, suffix: ': [339]', hasRow: true, hasCol: false }, { link: 'foo: [339,12]', prefix: undefined, suffix: ': [339,12]', hasRow: true, hasCol: true }, { link: 'foo: [339, 12]', prefix: undefined, suffix: ': [339, 12]', hasRow: true, hasCol: true }, + { link: 'foo[339:12]', prefix: undefined, suffix: '[339:12]', hasRow: true, hasCol: true }, + { link: 'foo [339:12]', prefix: undefined, suffix: ' [339:12]', hasRow: true, hasCol: true }, // OCaml-style { link: '"foo", line 339, character 12', prefix: '"', suffix: '", line 339, character 12', hasRow: true, hasCol: true }, diff --git a/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLocalLinkDetector.test.ts b/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLocalLinkDetector.test.ts index 70d503f1526ef..df3d642769a3e 100644 --- a/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLocalLinkDetector.test.ts +++ b/src/vs/workbench/contrib/terminalContrib/links/test/browser/terminalLocalLinkDetector.test.ts @@ -110,6 +110,8 @@ const supportedLinkFormats: LinkFormatInfo[] = [ { urlFormat: '{0}({1}, {2})', line: '5', column: '3' }, { urlFormat: '{0} ({1}, {2})', line: '5', column: '3' }, { urlFormat: '{0}: ({1}, {2})', line: '5', column: '3' }, + { urlFormat: '{0}({1}:{2})', line: '5', column: '3' }, + { urlFormat: '{0} ({1}:{2})', line: '5', column: '3' }, { urlFormat: '{0}:{1}', line: '5' }, { urlFormat: '{0}:{1}:{2}', line: '5', column: '3' }, { urlFormat: '{0} {1}:{2}', line: '5', column: '3' }, @@ -121,6 +123,8 @@ const supportedLinkFormats: LinkFormatInfo[] = [ { urlFormat: '{0}[{1}, {2}]', line: '5', column: '3' }, { urlFormat: '{0} [{1}, {2}]', line: '5', column: '3' }, { urlFormat: '{0}: [{1}, {2}]', line: '5', column: '3' }, + { urlFormat: '{0}[{1}:{2}]', line: '5', column: '3' }, + { urlFormat: '{0} [{1}:{2}]', line: '5', column: '3' }, { urlFormat: '{0}",{1}', line: '5' }, { urlFormat: '{0}\',{1}', line: '5' }, { urlFormat: '{0}#{1}', line: '5' }, diff --git a/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.ts b/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.ts index 3a07a2806feda..11350dd2893dc 100644 --- a/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.ts +++ b/src/vs/workbench/contrib/testing/browser/testResultsView/testResultsOutput.ts @@ -353,9 +353,8 @@ export class TerminalMessagePeek extends Disposable implements IPeekOutputRender if (prev) { prev.xterm.clearBuffer(); prev.xterm.clearSearchDecorations(); - // clearBuffer tries to retain the prompt line, but this doesn't exist for tests. - // So clear the screen (J) and move to home (H) to ensure previous data is cleaned up. - prev.xterm.write(`\x1b[2J\x1b[0;0H`); + // clearBuffer tries to retain the prompt. Reset prompt, scrolling state, etc. + prev.xterm.write(`\x1bc`); return prev; } diff --git a/src/vs/workbench/electron-sandbox/desktop.contribution.ts b/src/vs/workbench/electron-sandbox/desktop.contribution.ts index f6bae665b130d..72527bf9ba539 100644 --- a/src/vs/workbench/electron-sandbox/desktop.contribution.ts +++ b/src/vs/workbench/electron-sandbox/desktop.contribution.ts @@ -251,7 +251,7 @@ import { MAX_ZOOM_LEVEL, MIN_ZOOM_LEVEL } from '../../platform/window/electron-s ], 'default': isLinux ? 'never' : 'auto', 'scope': ConfigurationScope.APPLICATION, - 'markdownDescription': localize('window.customTitleBarVisibility', "Adjust when the custom title bar should be shown. The custom title bar can be hidden when in full screen mode with `windowed`. The custom title bar can only be hidden in none full screen mode with `never` when {0} is set to `native`.", '`#window.titleBarStyle#`'), + 'markdownDescription': localize('window.customTitleBarVisibility', "Adjust when the custom title bar should be shown. The custom title bar can be hidden when in full screen mode with `windowed`. The custom title bar can only be hidden in non full screen mode with `never` when {0} is set to `native`.", '`#window.titleBarStyle#`'), }, 'window.dialogStyle': { 'type': 'string', diff --git a/src/vs/workbench/services/preferences/common/preferencesModels.ts b/src/vs/workbench/services/preferences/common/preferencesModels.ts index 8bc828292b109..e97874375fae9 100644 --- a/src/vs/workbench/services/preferences/common/preferencesModels.ts +++ b/src/vs/workbench/services/preferences/common/preferencesModels.ts @@ -422,7 +422,8 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, if (!model.isDisposed()) { visit(model.getValue(), visitor); } - return settings.length > 0 ? [{ + return settings.length > 0 ? [{ + id: model.isDisposed() ? '' : model.id, sections: [ { settings @@ -431,7 +432,7 @@ function parse(model: ITextModel, isSettingsProperty: (currentProperty: string, title: '', titleRange: nullRange, range - }] : []; + } satisfies ISettingsGroup] : []; } export class WorkspaceConfigurationEditorModel extends SettingsEditorModel { @@ -844,7 +845,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements const metadata = this.collectMetadata(resultGroups); return resultGroups.length ? - { + { allGroups: this.settingsGroups, filteredGroups, matches, @@ -894,9 +895,10 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements filterMatches = filterMatches .map(filteredMatch => { // Fix match ranges to offset from setting start line - return { + return { setting: filteredMatch.setting, score: filteredMatch.score, + matchType: filteredMatch.matchType, matches: filteredMatch.matches && filteredMatch.matches.map(match => { return new Range( match.startLineNumber - filteredMatch.setting.range.startLineNumber, @@ -965,7 +967,7 @@ export class DefaultSettingsEditorModel extends AbstractSettingsModel implements } private getGroup(resultGroup: ISearchResultGroup): ISettingsGroup { - return { + return { id: resultGroup.id, range: nullRange, title: resultGroup.label, diff --git a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts index bb3c6a2ac975a..f7f38038aeb67 100644 --- a/src/vs/workbench/services/themes/browser/fileIconThemeData.ts +++ b/src/vs/workbench/services/themes/browser/fileIconThemeData.ts @@ -395,12 +395,14 @@ export class FileIconThemeLoader { const fonts = iconThemeDocument.fonts; const fontSizes = new Map(); if (Array.isArray(fonts)) { - const defaultFontSize = fonts[0].size || '150%'; + const defaultFontSize = this.tryNormalizeFontSize(fonts[0].size) || '150%'; fonts.forEach(font => { const src = font.src.map(l => `${asCSSUrl(resolvePath(l.path))} format('${l.format}')`).join(', '); cssRules.push(`@font-face { src: ${src}; font-family: '${font.id}'; font-weight: ${font.weight}; font-style: ${font.style}; font-display: block; }`); - if (font.size !== undefined && font.size !== defaultFontSize) { - fontSizes.set(font.id, font.size); + + const fontSize = this.tryNormalizeFontSize(font.size); + if (fontSize !== undefined && fontSize !== defaultFontSize) { + fontSizes.set(font.id, fontSize); } }); cssRules.push(`.show-file-icons .file-icon::before, .show-file-icons .folder-icon::before, .show-file-icons .rootfolder-icon::before { font-family: '${fonts[0].id}'; font-size: ${defaultFontSize}; }`); @@ -455,6 +457,27 @@ export class FileIconThemeLoader { return result; } + /** + * Try converting absolute font sizes to relative values. + * + * This allows them to be scaled nicely depending on where they are used. + */ + private tryNormalizeFontSize(size: string | undefined): string | undefined { + if (!size) { + return undefined; + } + + const defaultFontSizeInPx = 13; + + if (size.endsWith('px')) { + const value = parseInt(size, 10); + if (!isNaN(value)) { + return Math.round((value / defaultFontSizeInPx) * 100) + '%'; + } + } + + return size; + } } function handleParentFolder(key: string, selectors: string[]): string { diff --git a/src/vs/workbench/services/themes/common/fileIconThemeSchema.ts b/src/vs/workbench/services/themes/common/fileIconThemeSchema.ts index a8f07fb74a4f1..4d18093f41e14 100644 --- a/src/vs/workbench/services/themes/common/fileIconThemeSchema.ts +++ b/src/vs/workbench/services/themes/common/fileIconThemeSchema.ts @@ -185,7 +185,7 @@ const schema: IJSONSchema = { }, size: { type: 'string', - description: nls.localize('schema.font-size', 'The default size of the font. See https://developer.mozilla.org/en-US/docs/Web/CSS/font-size for valid values.'), + description: nls.localize('schema.font-size', 'The default size of the font. We strongly recommend using a percentage value, for example: 125%.'), pattern: fontSizeRegex } }, diff --git a/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts b/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts index 1d71b61768a91..69061d64ffd1e 100644 --- a/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts +++ b/src/vscode-dts/vscode.proposed.mappedEditsProvider.d.ts @@ -19,6 +19,7 @@ declare module 'vscode' { export interface ConversationResponse { readonly type: 'response'; readonly message: string; + readonly result?: ChatResult; readonly references?: DocumentContextItem[]; } @@ -53,7 +54,7 @@ declare module 'vscode' { } export interface MappedEditsRequest { - readonly codeBlocks: { code: string; resource: Uri }[]; + readonly codeBlocks: { code: string; resource: Uri; markdownBeforeBlock?: string }[]; readonly conversation: (ConversationRequest | ConversationResponse)[]; // for every prior response that contains codeblocks, make sure we pass the code as well as the resources based on the reported codemapper URIs }