From 91f83212788ced6e6bc65adf75acaeb66ef8cb14 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Fri, 20 Dec 2024 02:08:30 -0800 Subject: [PATCH 01/90] delete autoenable --- src/vs/platform/void/common/refreshModelService.ts | 2 -- 1 file changed, 2 deletions(-) diff --git a/src/vs/platform/void/common/refreshModelService.ts b/src/vs/platform/void/common/refreshModelService.ts index 39d243b5..123a12c7 100644 --- a/src/vs/platform/void/common/refreshModelService.ts +++ b/src/vs/platform/void/common/refreshModelService.ts @@ -62,7 +62,6 @@ export class RefreshModelService extends Disposable implements IRefreshModelServ private readonly _onDidChangeState = new Emitter(); readonly onDidChangeState: Event = this._onDidChangeState.event; // this is primarily for use in react, so react can listen + update on state changes - private readonly _onDidAutoEnable = new Emitter(); constructor( @IVoidSettingsService private readonly voidSettingsService: IVoidSettingsService, @@ -152,7 +151,6 @@ export class RefreshModelService extends Disposable implements IRefreshModelServ if (enableProviderOnSuccess) { this.voidSettingsService.setSettingOfProvider(providerName, 'enabled', true) - this._onDidAutoEnable.fire(providerName) } this._setRefreshState(providerName, 'success') From 382275fa9fc70d21532ed03663ee6e52a45cbe05 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 21 Dec 2024 00:00:57 -0800 Subject: [PATCH 02/90] delete built-in extensions so the build works --- package-lock.json | 224 +++++++++++++++++++++++++++++++++------------- package.json | 1 + product.json | 48 ---------- 3 files changed, 163 insertions(+), 110 deletions(-) diff --git a/package-lock.json b/package-lock.json index 307f13cf..b362a33d 100644 --- a/package-lock.json +++ b/package-lock.json @@ -39,6 +39,7 @@ "@xterm/addon-webgl": "^0.19.0-beta.64", "@xterm/headless": "^5.6.0-beta.64", "@xterm/xterm": "^5.6.0-beta.64", + "ajv": "^8.17.1", "diff": "^7.0.0", "groq-sdk": "^0.9.0", "http-proxy-agent": "^7.0.0", @@ -1503,6 +1504,30 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/@eslint/eslintrc/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, + "node_modules/@eslint/eslintrc/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/@eslint/js": { "version": "8.36.0", "resolved": "https://registry.npmjs.org/@eslint/js/-/js-8.36.0.tgz", @@ -4480,15 +4505,15 @@ } }, "node_modules/ajv": { - "version": "6.12.6", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", - "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", - "dev": true, + "version": "8.17.1", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", + "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", + "license": "MIT", "dependencies": { - "fast-deep-equal": "^3.1.1", - "fast-json-stable-stringify": "^2.0.0", - "json-schema-traverse": "^0.4.1", - "uri-js": "^4.2.2" + "fast-deep-equal": "^3.1.3", + "fast-uri": "^3.0.1", + "json-schema-traverse": "^1.0.0", + "require-from-string": "^2.0.2" }, "funding": { "type": "github", @@ -4512,28 +4537,6 @@ } } }, - "node_modules/ajv-formats/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/ajv-formats/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/ajv-keywords": { "version": "5.1.0", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-5.1.0.tgz", @@ -7815,6 +7818,23 @@ "url": "https://opencollective.com/eslint" } }, + "node_modules/eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/eslint/node_modules/glob-parent": { "version": "6.0.2", "resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-6.0.2.tgz", @@ -7827,6 +7847,13 @@ "node": ">=10.13.0" } }, + "node_modules/eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/esniff": { "version": "2.0.1", "resolved": "https://registry.npmjs.org/esniff/-/esniff-2.0.1.tgz", @@ -8202,8 +8229,7 @@ "node_modules/fast-deep-equal": { "version": "3.1.3", "resolved": "https://registry.npmjs.org/fast-deep-equal/-/fast-deep-equal-3.1.3.tgz", - "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==", - "dev": true + "integrity": "sha512-f3qQ9oQy9j2AhBe/H9VC91wLmKBCCU/gDOnKNAYG5hswO7BLKj09Hc5HYNz9cGI++xlpDCIgDaitVs03ATR84Q==" }, "node_modules/fast-fifo": { "version": "1.3.2", @@ -8231,7 +8257,8 @@ "version": "2.1.0", "resolved": "https://registry.npmjs.org/fast-json-stable-stringify/-/fast-json-stable-stringify-2.1.0.tgz", "integrity": "sha512-lhd/wF+Lk98HZoTCtlVraHtfh5XYijIjalXck7saUtuanSDyLMxnHhSXEDJqHxD7msR8D0uCmqlkwjCV8xvwHw==", - "dev": true + "dev": true, + "license": "MIT" }, "node_modules/fast-levenshtein": { "version": "2.0.6", @@ -8242,8 +8269,7 @@ "node_modules/fast-uri": { "version": "3.0.3", "resolved": "https://registry.npmjs.org/fast-uri/-/fast-uri-3.0.3.tgz", - "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==", - "dev": true + "integrity": "sha512-aLrHthzCjH5He4Z2H9YZ+v6Ujb9ocRuW6ZzkJQOrTxleEijANq4v1TsaPaVG1PZcuurEzrLcWRyYBYXD5cEiaw==" }, "node_modules/fast-xml-parser": { "version": "4.5.1", @@ -8372,6 +8398,23 @@ "webpack": "^4.0.0 || ^5.0.0" } }, + "node_modules/file-loader/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/file-loader/node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -8381,6 +8424,13 @@ "ajv": "^6.9.1" } }, + "node_modules/file-loader/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/file-loader/node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", @@ -10446,6 +10496,23 @@ "node": ">=0.4.0" } }, + "node_modules/gulp-eslint/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/gulp-eslint/node_modules/ansi-regex": { "version": "3.0.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-3.0.1.tgz", @@ -10719,6 +10786,13 @@ "js-yaml": "bin/js-yaml.js" } }, + "node_modules/gulp-eslint/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/gulp-eslint/node_modules/levn": { "version": "0.3.0", "resolved": "https://registry.npmjs.org/levn/-/levn-0.3.0.tgz", @@ -13840,10 +13914,10 @@ "dev": true }, "node_modules/json-schema-traverse": { - "version": "0.4.1", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", - "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", - "dev": true + "version": "1.0.0", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", + "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", + "license": "MIT" }, "node_modules/json-stable-stringify-without-jsonify": { "version": "1.0.1", @@ -18671,7 +18745,6 @@ "version": "2.0.2", "resolved": "https://registry.npmjs.org/require-from-string/-/require-from-string-2.0.2.tgz", "integrity": "sha512-Xf0nWe6RseziFMu+Ap9biiUbmplq6S9/p+7w7YXP/JBHhrUDDUhwa+vANyubuqfZWTveU//DYVGsDG7RKL/vEw==", - "dev": true, "engines": { "node": ">=0.10.0" } @@ -19157,28 +19230,6 @@ "url": "https://opencollective.com/webpack" } }, - "node_modules/schema-utils/node_modules/ajv": { - "version": "8.17.1", - "resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz", - "integrity": "sha512-B/gBuNg5SiMTrPkC+A2+cW0RszwxYmn6VYxB/inlBStS5nx6xHIt/ehKRhIMhqusl7a8LjQoZnjCs5vhwxOQ1g==", - "dev": true, - "dependencies": { - "fast-deep-equal": "^3.1.3", - "fast-uri": "^3.0.1", - "json-schema-traverse": "^1.0.0", - "require-from-string": "^2.0.2" - }, - "funding": { - "type": "github", - "url": "https://github.com/sponsors/epoberezkin" - } - }, - "node_modules/schema-utils/node_modules/json-schema-traverse": { - "version": "1.0.0", - "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-1.0.0.tgz", - "integrity": "sha512-NM8/P9n3XjXhIZn1lLhkFaACTOURQXjWhV4BA/RnOv8xvgqtqpAX9IO4mRQxSx1Rlo4tqzeqb0sOlruaOy3dug==", - "dev": true - }, "node_modules/scope-tailwind": { "version": "1.0.5", "resolved": "https://registry.npmjs.org/scope-tailwind/-/scope-tailwind-1.0.5.tgz", @@ -20705,6 +20756,23 @@ "node": ">=6.0.0" } }, + "node_modules/table/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/table/node_modules/ansi-regex": { "version": "4.1.1", "resolved": "https://registry.npmjs.org/ansi-regex/-/ansi-regex-4.1.1.tgz", @@ -20729,6 +20797,13 @@ "node": ">=4" } }, + "node_modules/table/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/table/node_modules/string-width": { "version": "3.1.0", "resolved": "https://registry.npmjs.org/string-width/-/string-width-3.1.0.tgz", @@ -22149,6 +22224,7 @@ "resolved": "https://registry.npmjs.org/uri-js/-/uri-js-4.4.1.tgz", "integrity": "sha512-7rKUyy33Q1yc98pQ1DAmLtwX109F7TIfWlW1Ydo8Wl1ii1SeHieeh0HHfPeL2fMXK6z0s8ecKs9frCuLJvndBg==", "dev": true, + "license": "BSD-2-Clause", "dependencies": { "punycode": "^2.1.0" } @@ -22721,6 +22797,23 @@ "node": ">= 0.10" } }, + "node_modules/webpack/node_modules/ajv": { + "version": "6.12.6", + "resolved": "https://registry.npmjs.org/ajv/-/ajv-6.12.6.tgz", + "integrity": "sha512-j3fVLgvTo527anyYyJOGTYJbG+vnnQYvE0m5mmkc1TK+nxAppkCLMIL0aZ4dblVCNoGShhm+kzE4ZUykBoMg4g==", + "dev": true, + "license": "MIT", + "dependencies": { + "fast-deep-equal": "^3.1.1", + "fast-json-stable-stringify": "^2.0.0", + "json-schema-traverse": "^0.4.1", + "uri-js": "^4.2.2" + }, + "funding": { + "type": "github", + "url": "https://github.com/sponsors/epoberezkin" + } + }, "node_modules/webpack/node_modules/ajv-keywords": { "version": "3.5.2", "resolved": "https://registry.npmjs.org/ajv-keywords/-/ajv-keywords-3.5.2.tgz", @@ -22752,6 +22845,13 @@ "node": ">=4.0" } }, + "node_modules/webpack/node_modules/json-schema-traverse": { + "version": "0.4.1", + "resolved": "https://registry.npmjs.org/json-schema-traverse/-/json-schema-traverse-0.4.1.tgz", + "integrity": "sha512-xbbCH5dCYU5T8LcEhhuh7HJ88HXuW3qsI3Y0zOZFKfZEHcpWiHU/Jxzk629Brsab/mMiHQti9wMP+845RPe3Vg==", + "dev": true, + "license": "MIT" + }, "node_modules/webpack/node_modules/schema-utils": { "version": "3.3.0", "resolved": "https://registry.npmjs.org/schema-utils/-/schema-utils-3.3.0.tgz", diff --git a/package.json b/package.json index ab294d7b..d3d97a89 100644 --- a/package.json +++ b/package.json @@ -103,6 +103,7 @@ "@xterm/addon-webgl": "^0.19.0-beta.64", "@xterm/headless": "^5.6.0-beta.64", "@xterm/xterm": "^5.6.0-beta.64", + "ajv": "^8.17.1", "diff": "^7.0.0", "groq-sdk": "^0.9.0", "http-proxy-agent": "^7.0.0", diff --git a/product.json b/product.json index d892feaf..5554573c 100644 --- a/product.json +++ b/product.json @@ -36,53 +36,5 @@ "itemUrl": "https://open-vsx.org/vscode/item" }, "builtInExtensions": [ - { - "name": "ms-vscode.js-debug-companion", - "version": "1.1.3", - "sha256": "7380a890787452f14b2db7835dfa94de538caf358ebc263f9d46dd68ac52de93", - "repo": "https://github.com/microsoft/vscode-js-debug-companion", - "metadata": { - "id": "99cb0b7f-7354-4278-b8da-6cc79972169d", - "publisherId": { - "publisherId": "5f5636e7-69ed-4afe-b5d6-8d231fb3d3ee", - "publisherName": "ms-vscode", - "displayName": "Microsoft", - "flags": "verified" - }, - "publisherDisplayName": "Microsoft" - } - }, - { - "name": "ms-vscode.js-debug", - "version": "1.93.0", - "sha256": "9339cb8e6b77f554df54d79e71f533279cb76b0f9b04c207f633bfd507442b6a", - "repo": "https://github.com/microsoft/vscode-js-debug", - "metadata": { - "id": "25629058-ddac-4e17-abba-74678e126c5d", - "publisherId": { - "publisherId": "5f5636e7-69ed-4afe-b5d6-8d231fb3d3ee", - "publisherName": "ms-vscode", - "displayName": "Microsoft", - "flags": "verified" - }, - "publisherDisplayName": "Microsoft" - } - }, - { - "name": "ms-vscode.vscode-js-profile-table", - "version": "1.0.9", - "sha256": "3b62ee4276a2bbea3fe230f94b1d5edd915b05966090ea56f882e1e0ab53e1a6", - "repo": "https://github.com/microsoft/vscode-js-profile-visualizer", - "metadata": { - "id": "7e52b41b-71ad-457b-ab7e-0620f1fc4feb", - "publisherId": { - "publisherId": "5f5636e7-69ed-4afe-b5d6-8d231fb3d3ee", - "publisherName": "ms-vscode", - "displayName": "Microsoft", - "flags": "verified" - }, - "publisherDisplayName": "Microsoft" - } - } ] } From 81282e16b3c3e4f47a4313c9018217e42521458e Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 21 Dec 2024 00:15:14 -0800 Subject: [PATCH 03/90] minor contrib update --- CONTRIBUTING.md | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/CONTRIBUTING.md b/CONTRIBUTING.md index a84e550f..7aaab546 100644 --- a/CONTRIBUTING.md +++ b/CONTRIBUTING.md @@ -54,7 +54,7 @@ To build Void, open `void/` inside VSCode. Then: 4. Run. - Run `./scripts/code.sh` (Mac/Linux). - Run `./scripts/code.bat` (Windows). - - This command should open up the built IDE. You can always press Ctrl+Shift+P and run "Reload Window" inside the new window to see changes without re-building, unless they're React changes. + - This command should open up the built IDE. You can always press Ctrl+R (Cmd+R) inside the new window to see changes without re-building, or press or Ctrl+Shift+P in the new window and run "Reload Window". #### Building Void from Terminal @@ -80,7 +80,6 @@ Alternatively, if you want to build Void from the terminal, instead of pressing - ## Bundling We don't usually recommend bundling. Instead, you should probably just build. If you're sure you want to bundle Void into an executable app, make sure you've built first, then run one of the following commands. This will create a folder named `VSCode-darwin-arm64` (or similar) in the repo's parent's directory. Be patient - compiling can take ~25 minutes. From 97fd332c4ed2babd4491b10d292fd9b9042d0993 Mon Sep 17 00:00:00 2001 From: mp Date: Fri, 20 Dec 2024 20:44:03 -0800 Subject: [PATCH 04/90] add code editor block --- .../contrib/void/browser/quickEditActions.ts | 5 +- .../browser/react/src/markdown/BlockCode.tsx | 9 +- .../react/src/markdown/ChatMarkdownRender.tsx | 12 +- .../react/src/sidebar-tsx/SidebarChat.tsx | 19 ++-- .../src/sidebar-tsx/SidebarThreadSelector.tsx | 10 +- .../void/browser/react/src/util/inputs.tsx | 82 ++++++++++++-- .../react/src/util/mountFnGenerator.tsx | 8 +- .../void/browser/react/src/util/services.tsx | 103 +++++++++++++++--- .../src/void-settings-tsx/ModelDropdown.tsx | 6 +- .../react/src/void-settings-tsx/Settings.tsx | 26 +++-- .../contrib/void/browser/sidebarPane.ts | 18 +-- 11 files changed, 227 insertions(+), 71 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/quickEditActions.ts b/src/vs/workbench/contrib/void/browser/quickEditActions.ts index 784011d2..9d5314a8 100644 --- a/src/vs/workbench/contrib/void/browser/quickEditActions.ts +++ b/src/vs/workbench/contrib/void/browser/quickEditActions.ts @@ -10,7 +10,6 @@ import { Disposable } from '../../../../base/common/lifecycle.js'; import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js'; import { mountCtrlK } from './react/out/ctrl-k-tsx/index.js'; -import { getReactServices } from './helpers/reactServicesHelper.js'; import { URI } from '../../../../base/common/uri.js'; @@ -83,12 +82,10 @@ class VoidQuickEditService extends Disposable implements IQuickEditService { accessor.addZone(viewZone) this._instantiationService.invokeFunction(accessor => { - const services = getReactServices(accessor) - const props: QuickEditPropsType = { quickEditId: this.quickEditId++, } - mountCtrlK(domNode, services, props) + mountCtrlK(domNode, accessor, props) }) // disposeInThisEditorFns.push(() => { editor.changeViewZones(accessor => { if (zoneId) accessor.removeZone(zoneId) }) }) diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx index b2c83e66..479ea70b 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx @@ -6,6 +6,7 @@ import React, { ReactNode } from "react" import SyntaxHighlighter from "react-syntax-highlighter"; import { atomOneDarkReasonable } from "react-syntax-highlighter/dist/esm/styles/hljs"; +import { VoidCodeEditor } from '../util/inputs.js'; export const BlockCode = ({ text, buttonsOnHover, language }: { text: string, buttonsOnHover?: ReactNode, language?: string }) => { @@ -27,7 +28,11 @@ export const BlockCode = ({ text, buttonsOnHover, language }: { text: string, bu )} -
+ {/*
-
+
*/} ) diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx index c1750d81..3fa5140c 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/ChatMarkdownRender.tsx @@ -6,7 +6,7 @@ import React, { JSX, useCallback, useEffect, useState } from 'react' import { marked, MarkedToken, Token } from 'marked' import { BlockCode } from './BlockCode.js' -import { useService } from '../util/services.js' +import { useAccessor } from '../util/services.js' enum CopyButtonState { @@ -18,13 +18,13 @@ enum CopyButtonState { const COPY_FEEDBACK_TIMEOUT = 1000 // amount of time to say 'Copied!' const CodeButtonsOnHover = ({ diffRepr: text }: { diffRepr: string }) => { + const accessor = useAccessor() + const [copyButtonState, setCopyButtonState] = useState(CopyButtonState.Copy) - const inlineDiffService = useService('inlineDiffService') - - const clipboardService = useService('clipboardService') - - + const inlineDiffService = accessor.get('IInlineDiffsService') + const clipboardService = accessor.get('IClipboardService') useEffect(() => { + if (copyButtonState !== CopyButtonState.Copy) { setTimeout(() => { setCopyButtonState(CopyButtonState.Copy) diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index 75cc5419..c9abf942 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -6,12 +6,11 @@ import React, { ButtonHTMLAttributes, FormEvent, FormHTMLAttributes, Fragment, useCallback, useEffect, useRef, useState } from 'react'; -import { useSettingsState, useService, useSidebarState, useThreadsState } from '../util/services.js'; -import { ChatMessage, CodeSelection, CodeStagingSelection } from '../../../threadHistoryService.js'; +import { useAccessor, useThreadsState } from '../util/services.js'; +import { ChatMessage, CodeSelection, CodeStagingSelection, IThreadHistoryService } from '../../../threadHistoryService.js'; import { BlockCode } from '../markdown/BlockCode.js'; import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js'; -import { IModelService } from '../../../../../../../editor/common/services/model.js'; import { URI } from '../../../../../../../base/common/uri.js'; import { EndOfLinePreference } from '../../../../../../../editor/common/model.js'; import { IDisposable } from '../../../../../../../base/common/lifecycle.js'; @@ -19,9 +18,12 @@ import { ErrorDisplay } from './ErrorDisplay.js'; import { OnError, ServiceSendLLMMessageParams } from '../../../../../../../platform/void/common/llmMessageTypes.js'; import { getCmdKey } from '../../../helpers/getCmdKey.js' import { HistoryInputBox, InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js'; -import { VoidInputBox } from '../util/inputs.js'; +import { VoidCodeEditor, VoidInputBox } from '../util/inputs.js'; import { ModelDropdown } from '../void-settings-tsx/ModelDropdown.js'; import { ctrlLSystem, generateCtrlLPrompt } from '../../../prompt/prompts.js'; +import { ISidebarStateService } from '../../../sidebarStateService.js'; +import { ILLMMessageService } from '../../../../../../../platform/void/common/llmMessageService.js'; +import { IModelService } from '../../../../../../../editor/common/services/model.js'; const IconX = ({ size, className = '' }: { size: number, className?: string }) => { @@ -285,11 +287,12 @@ export const SidebarChat = () => { const inputBoxRef: React.MutableRefObject = useRef(null); - const modelService = useService('modelService') + const accessor = useAccessor() + const modelService = accessor.get('IModelService') // ----- HIGHER STATE ----- // sidebar state - const sidebarStateService = useService('sidebarStateService') + const sidebarStateService = accessor.get('ISidebarStateService') useEffect(() => { const disposables: IDisposable[] = [] disposables.push( @@ -301,9 +304,9 @@ export const SidebarChat = () => { // threads state const threadsState = useThreadsState() - const threadsStateService = useService('threadsStateService') + const threadsStateService = accessor.get('IThreadHistoryService') - const llmMessageService = useService('llmMessageService') + const llmMessageService = accessor.get('ILLMMessageService') // ----- SIDEBAR CHAT state (local) ----- diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx index 6a2b1943..e6adb5f2 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarThreadSelector.tsx @@ -4,7 +4,9 @@ *--------------------------------------------------------------------------------------------*/ import React from "react"; -import { useService, useThreadsState } from '../util/services.js'; +import { useAccessor, useThreadsState } from '../util/services.js'; +import { IThreadHistoryService } from '../../../threadHistoryService.js'; +import { ISidebarStateService } from '../../../sidebarStateService.js'; const truncate = (s: string) => { @@ -18,8 +20,10 @@ const truncate = (s: string) => { export const SidebarThreadSelector = () => { const threadsState = useThreadsState() - const threadsStateService = useService('threadsStateService') - const sidebarStateService = useService('sidebarStateService') + + const accessor = useAccessor() + const threadsStateService = accessor.get('IThreadHistoryService') + const sidebarStateService = accessor.get('ISidebarStateService') const { allThreads } = threadsState diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx index 6cfcf9a5..7d82965a 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx @@ -4,19 +4,26 @@ *--------------------------------------------------------------------------------------------*/ import React, { useCallback, useEffect, useRef } from 'react'; -import { useIsDark, useService } from '../util/services.js'; import { IInputBoxStyles, InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js'; import { defaultCheckboxStyles, defaultInputBoxStyles, defaultSelectBoxStyles } from '../../../../../../../platform/theme/browser/defaultStyles.js'; import { SelectBox } from '../../../../../../../base/browser/ui/selectBox/selectBox.js'; import { IDisposable } from '../../../../../../../base/common/lifecycle.js'; import { Checkbox } from '../../../../../../../base/browser/ui/toggle/toggle.js'; +import { CodeEditorWidget } from '../../../../../../../editor/browser/widget/codeEditor/codeEditorWidget.js' +import { useAccessor } from './services.js'; +// type guard +const isConstructor = (f: any) + : f is { new(...params: any[]): any } => { + return !!f.prototype && f.prototype.constructor === f; +} + export const WidgetComponent = ({ ctor, propsFn, dispose, onCreateInstance, children, className } : { - ctor: { new(...params: CtorParams): Instance }, - propsFn: (container: HTMLDivElement) => CtorParams, + ctor: { new(...params: CtorParams): Instance } | ((container: HTMLDivElement) => Instance), + propsFn: (container: HTMLDivElement) => CtorParams, // unused if fn onCreateInstance: (instance: Instance) => IDisposable[], dispose: (instance: Instance) => void, children?: React.ReactNode, @@ -26,7 +33,7 @@ export const WidgetComponent = ({ ctor, prop const containerRef = useRef(null); useEffect(() => { - const instance = new ctor(...propsFn(containerRef.current!)); + const instance = isConstructor(ctor) ? new ctor(...propsFn(containerRef.current!)) : ctor(containerRef.current!) const disposables = onCreateInstance(instance); return () => { disposables.forEach(d => d.dispose()); @@ -48,7 +55,9 @@ export const VoidInputBox = ({ onChangeText, onCreateInstance, inputBoxRef, plac multiline: boolean; }) => { - const contextViewProvider = useService('contextViewService'); + const accessor = useAccessor() + + const contextViewProvider = accessor.get('IContextViewService') return [ @@ -189,7 +198,8 @@ export const VoidSelectBox = ({ onChangeSelection, onCreateInstance, selectB selectBoxRef?: React.MutableRefObject; options: readonly { text: string, value: T }[]; }) => { - const contextViewProvider = useService('contextViewService'); + const accessor = useAccessor() + const contextViewProvider = accessor.get('IContextViewService') let containerRef = useRef(null); @@ -237,6 +247,61 @@ export const VoidSelectBox = ({ onChangeSelection, onCreateInstance, selectB }; + +export const VoidCodeEditor = ({ initValue, language }: { initValue: string, language: string | undefined }) => { + const divRef = useRef(null) + + const accessor = useAccessor() + const instantiationService = accessor.get('IInstantiationService') + const modelService = accessor.get('IModelService') + + return
+ + instantiationService.createInstance( + CodeEditorWidget, + container, + { + automaticLayout: true, + wordWrap: 'on', + scrollbar: { + vertical: 'hidden', + horizontal: 'auto', + } + }, + { + isSimpleWidget: true, + }) + , [instantiationService]) + } + + onCreateInstance={useCallback((editor: CodeEditorWidget) => { + + const model = modelService.createModel(initValue, null) + editor.setModel(model); + model.setLanguage(language ?? 'plaintext') + + const container = editor.getDomNode() + const parentNode = container?.parentElement + if (parentNode) + parentNode.style.height = `${editor.getScrollHeight() + 1}px` // the +1 is if there's a half pixel issue + + return [] + }, [modelService, initValue, language])} + + dispose={useCallback((editor: CodeEditorWidget) => { + editor.dispose(); + }, [])} + + // ignored + propsFn={useCallback(() => { return [] }, [])} + + /> +
+ +} + + // export const VoidScrollableElt = ({ options, children }: { options: ScrollableElementCreationOptions, children: React.ReactNode }) => { // const instanceRef = useRef(null); // const [childrenPortal, setChildrenPortal] = useState(null) @@ -270,8 +335,6 @@ export const VoidSelectBox = ({ onChangeSelection, onCreateInstance, selectB // options: readonly { text: string, value: T }[]; // onChangeSelection: (value: T) => void; // }) => { -// const contextViewProvider = useService('contextViewService'); -// const contextMenuProvider = useService('contextMenuService'); // return ({ onChangeSelection, onCreateInstance, selectB // }) => { // const containerRef = useRef(null); -// const themeService = useService('themeService'); -// const contextViewService = useService('contextViewService'); -// const hoverService = useService('hoverService'); // useEffect(() => { // if (!containerRef.current) return; diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx index b674e7d5..78df4a21 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/mountFnGenerator.tsx @@ -6,15 +6,17 @@ import React, { useEffect, useState } from 'react'; import * as ReactDOM from 'react-dom/client' import { _registerServices } from './services.js'; -import { ReactServicesType } from '../../../helpers/reactServicesHelper.js'; -export const mountFnGenerator = (Component: (params: any) => React.ReactNode) => (rootElement: HTMLElement, services: ReactServicesType, props?: any) => { + +import { ServicesAccessor } from '../../../../../../../editor/browser/editorExtensions.js'; + +export const mountFnGenerator = (Component: (params: any) => React.ReactNode) => (rootElement: HTMLElement, accessor: ServicesAccessor, props?: any) => { if (typeof document === 'undefined') { console.error('index.tsx error: document was undefined') return } - const disposables = _registerServices(services) + const disposables = _registerServices(accessor) const root = ReactDOM.createRoot(rootElement) diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx index 2cee2419..6404e108 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/services.tsx @@ -3,11 +3,10 @@ * Void Editor additions licensed under the AGPL 3.0 License. *--------------------------------------------------------------------------------------------*/ -import { useState, useEffect } from 'react' +import React, { useState, useEffect } from 'react' import { ThreadsState } from '../../../threadHistoryService.js' import { RefreshableProviderName, SettingsOfProvider } from '../../../../../../../platform/void/common/voidSettingsTypes.js' import { IDisposable } from '../../../../../../../base/common/lifecycle.js' -import { ReactServicesType } from '../../../helpers/reactServicesHelper.js' import { VoidSidebarState } from '../../../sidebarStateService.js' import { VoidSettingsState } from '../../../../../../../platform/void/common/voidSettingsService.js' import { ColorScheme } from '../../../../../../../platform/theme/common/theme.js' @@ -15,9 +14,35 @@ import { VoidQuickEditState } from '../../../quickEditStateService.js' import { RefreshModelStateOfProvider } from '../../../../../../../platform/void/common/refreshModelService.js' -// normally to do this you'd use a useEffect that calls .onDidChangeState(), but useEffect mounts too late and misses initial state changes -let services: ReactServicesType + + +import { ServicesAccessor } from '../../../../../../../editor/browser/editorExtensions.js'; +import { IModelService } from '../../../../../../../editor/common/services/model.js'; +import { IClipboardService } from '../../../../../../../platform/clipboard/common/clipboardService.js'; +import { IContextViewService, IContextMenuService } from '../../../../../../../platform/contextview/browser/contextView.js'; +import { IFileService } from '../../../../../../../platform/files/common/files.js'; +import { IHoverService } from '../../../../../../../platform/hover/browser/hover.js'; +import { IThemeService } from '../../../../../../../platform/theme/common/themeService.js'; +import { ILLMMessageService } from '../../../../../../../platform/void/common/llmMessageService.js'; +import { IRefreshModelService } from '../../../../../../../platform/void/common/refreshModelService.js'; +import { IVoidSettingsService } from '../../../../../../../platform/void/common/voidSettingsService.js'; +import { IInlineDiffsService } from '../../../inlineDiffsService.js'; +import { IQuickEditStateService } from '../../../quickEditStateService.js'; +import { ISidebarStateService } from '../../../sidebarStateService.js'; +import { IThreadHistoryService } from '../../../threadHistoryService.js'; +import { IInstantiationService } from '../../../../../../../platform/instantiation/common/instantiation.js' +import { ICodeEditorService } from '../../../../../../../editor/browser/services/codeEditorService.js' +import { ICommandService } from '../../../../../../../platform/commands/common/commands.js' +import { IContextKeyService } from '../../../../../../../platform/contextkey/common/contextkey.js' +import { INotificationService } from '../../../../../../../platform/notification/common/notification.js' +import { IAccessibilityService } from '../../../../../../../platform/accessibility/common/accessibility.js' +import { ILanguageConfigurationService } from '../../../../../../../editor/common/languages/languageConfigurationRegistry.js' +import { ILanguageFeaturesService } from '../../../../../../../editor/common/services/languageFeatures.js' + + + +// normally to do this you'd use a useEffect that calls .onDidChangeState(), but useEffect mounts too late and misses initial state changes // even if React hasn't mounted yet, the variables are always updated to the latest state. // React listens by adding a setState function to these listeners. @@ -43,7 +68,7 @@ const colorThemeStateListeners: Set<(s: ColorScheme) => void> = new Set() // must call this before you can use any of the hooks below // this should only be called ONCE! this is the only place you don't need to dispose onDidChange. If you use state.onDidChange anywhere else, make sure to dispose it! let wasCalled = false -export const _registerServices = (services_: ReactServicesType) => { +export const _registerServices = (accessor: ServicesAccessor) => { const disposables: IDisposable[] = [] @@ -54,8 +79,18 @@ export const _registerServices = (services_: ReactServicesType) => { } wasCalled = true - services = services_ - const { sidebarStateService, quickEditStateService, settingsStateService, threadsStateService, refreshModelService, themeService, } = services + _registerAccessor(accessor) + + const stateServices = { + quickEditStateService: accessor.get(IQuickEditStateService), + sidebarStateService: accessor.get(ISidebarStateService), + threadsStateService: accessor.get(IThreadHistoryService), + settingsStateService: accessor.get(IVoidSettingsService), + refreshModelService: accessor.get(IRefreshModelService), + themeService: accessor.get(IThemeService), + } + + const { sidebarStateService, quickEditStateService, settingsStateService, threadsStateService, refreshModelService, themeService, } = stateServices quickEditState = quickEditStateService.state disposables.push( @@ -110,14 +145,56 @@ export const _registerServices = (services_: ReactServicesType) => { } -// -- services -- -export const useService = (serviceName: T): ReactServicesType[T] => { - if (services === null) { - throw new Error('useAccessor must be used within an AccessorProvider') - } - return services[serviceName] +const getReactAccessor = (accessor: ServicesAccessor) => { + const reactAccessor = { + IModelService: accessor.get(IModelService), + IClipboardService: accessor.get(IClipboardService), + IContextViewService: accessor.get(IContextViewService), + IContextMenuService: accessor.get(IContextMenuService), + IFileService: accessor.get(IFileService), + IHoverService: accessor.get(IHoverService), + IThemeService: accessor.get(IThemeService), + ILLMMessageService: accessor.get(ILLMMessageService), + IRefreshModelService: accessor.get(IRefreshModelService), + IVoidSettingsService: accessor.get(IVoidSettingsService), + IInlineDiffsService: accessor.get(IInlineDiffsService), + IQuickEditStateService: accessor.get(IQuickEditStateService), + ISidebarStateService: accessor.get(ISidebarStateService), + IThreadHistoryService: accessor.get(IThreadHistoryService), + + IInstantiationService: accessor.get(IInstantiationService), + ICodeEditorService: accessor.get(ICodeEditorService), + ICommandService: accessor.get(ICommandService), + IContextKeyService: accessor.get(IContextKeyService), + INotificationService: accessor.get(INotificationService), + IAccessibilityService: accessor.get(IAccessibilityService), + ILanguageConfigurationService: accessor.get(ILanguageConfigurationService), + ILanguageFeaturesService: accessor.get(ILanguageFeaturesService), + + } as const + return reactAccessor } +type ReactAccessor = ReturnType + + +let reactAccessor_: ReactAccessor | null = null +const _registerAccessor = (accessor: ServicesAccessor) => { + const reactAccessor = getReactAccessor(accessor) + reactAccessor_ = reactAccessor +} + +// -- services -- +export const useAccessor = () => { + if (!reactAccessor_) { + throw new Error(`⚠️ Void useAccessor was called before _registerServices!`) + } + + return { get: (service: S): ReactAccessor[S] => reactAccessor_![service] } +} + + + // -- state of services -- export const useQuickEditState = () => { diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx index 59abfcde..edb55f90 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx @@ -5,13 +5,15 @@ import { useCallback, useEffect, useRef, useState } from 'react' import { FeatureName, featureNames, ModelSelection, modelSelectionsEqual, ProviderName, providerNames } from '../../../../../../../platform/void/common/voidSettingsTypes.js' -import { useSettingsState, useRefreshModelState, useService } from '../util/services.js' +import { useSettingsState, useRefreshModelState, useAccessor } from '../util/services.js' import { VoidSelectBox } from '../util/inputs.js' import { SelectBox } from '../../../../../../../base/browser/ui/selectBox/selectBox.js' const ModelSelectBox = ({ featureName }: { featureName: FeatureName }) => { - const voidSettingsService = useService('settingsStateService') + const accessor = useAccessor() + + const voidSettingsService = accessor.get('IVoidSettingsService') const settingsState = useSettingsState() let weChangedText = false diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx index cc00422e..f1d95780 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/Settings.tsx @@ -3,7 +3,7 @@ import { InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox import { ProviderName, SettingName, displayInfoOfSettingName, providerNames, VoidModelInfo, featureFlagNames, displayInfoOfFeatureFlag, customSettingNamesOfProvider, RefreshableProviderName, refreshableProviderNames, displayInfoOfProviderName } from '../../../../../../../platform/void/common/voidSettingsTypes.js' import ErrorBoundary from '../sidebar-tsx/ErrorBoundary.js' import { VoidCheckBox, VoidInputBox, VoidSelectBox, VoidSwitch } from '../util/inputs.js' -import { useIsDark, useRefreshModelListener, useRefreshModelState, useService, useSettingsState } from '../util/services.js' +import { useAccessor, useIsDark, useRefreshModelListener, useRefreshModelState, useSettingsState } from '../util/services.js' import { X, RefreshCw, Loader2, Check } from 'lucide-react' import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js' @@ -12,7 +12,9 @@ import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js' // models const RefreshModelButton = ({ providerName }: { providerName: RefreshableProviderName }) => { const refreshModelState = useRefreshModelState() - const refreshModelService = useService('refreshModelService') + + const accessor = useAccessor() + const refreshModelService = accessor.get('IRefreshModelService') const [justFinished, setJustSucceeded] = useState(false) @@ -60,7 +62,10 @@ const RefreshableModels = () => { const AddModelMenu = ({ onSubmit }: { onSubmit: () => void }) => { - const settingsStateService = useService('settingsStateService') + + const accessor = useAccessor() + const settingsStateService = accessor.get('IVoidSettingsService') + const settingsState = useSettingsState() const providerNameRef = useRef(null) @@ -147,7 +152,9 @@ const AddModelMenuFull = () => { export const ModelDump = () => { - const settingsStateService = useService('settingsStateService') + const accessor = useAccessor() + const settingsStateService = accessor.get('IVoidSettingsService') + const settingsState = useSettingsState() // a dump of all the enabled providers' models @@ -204,7 +211,9 @@ const ProviderSetting = ({ providerName, settingName }: { providerName: Provider const { title: providerTitle, } = displayInfoOfProviderName(providerName) const { title: settingTitle, placeholder, subTextMd } = displayInfoOfSettingName(providerName, settingName) - const voidSettingsService = useService('settingsStateService') + + const accessor = useAccessor() + const voidSettingsService = accessor.get('IVoidSettingsService') let weChangedTextRef = false @@ -243,7 +252,8 @@ const ProviderSetting = ({ providerName, settingName }: { providerName: Provider const SettingsForProvider = ({ providerName }: { providerName: ProviderName }) => { const voidSettingsState = useSettingsState() - const voidSettingsService = useService('settingsStateService') + const accessor = useAccessor() + const voidSettingsService = accessor.get('IVoidSettingsService') const { enabled } = voidSettingsState.settingsOfProvider[providerName] const settingNames = customSettingNamesOfProvider(providerName) @@ -286,7 +296,9 @@ export const VoidProviderSettings = () => { export const VoidFeatureFlagSettings = () => { - const voidSettingsService = useService('settingsStateService') + const accessor = useAccessor() + const voidSettingsService = accessor.get('IVoidSettingsService') + const voidSettingsState = useSettingsState() return <> diff --git a/src/vs/workbench/contrib/void/browser/sidebarPane.ts b/src/vs/workbench/contrib/void/browser/sidebarPane.ts index bbe7cf4b..519a96c2 100644 --- a/src/vs/workbench/contrib/void/browser/sidebarPane.ts +++ b/src/vs/workbench/contrib/void/browser/sidebarPane.ts @@ -25,7 +25,7 @@ import { IViewPaneOptions, ViewPane } from '../../../browser/parts/views/viewPan import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js'; import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js'; -import { IDisposable } from '../../../../base/common/lifecycle.js'; +// import { IDisposable } from '../../../../base/common/lifecycle.js'; import { IConfigurationService } from '../../../../platform/configuration/common/configuration.js'; import { IThemeService } from '../../../../platform/theme/common/themeService.js'; import { IContextMenuService } from '../../../../platform/contextview/browser/contextView.js'; @@ -33,16 +33,12 @@ import { IKeybindingService } from '../../../../platform/keybinding/common/keybi import { IOpenerService } from '../../../../platform/opener/common/opener.js'; import { ITelemetryService } from '../../../../platform/telemetry/common/telemetry.js'; import { IHoverService } from '../../../../platform/hover/browser/hover.js'; - import { mountSidebar } from './react/out/sidebar-tsx/index.js'; -import { getReactServices } from './helpers/reactServicesHelper.js'; import { Codicon } from '../../../../base/common/codicons.js'; import { Orientation } from '../../../../base/browser/ui/sash/sash.js'; -// import { Orientation } from '../../../../base/browser/ui/sash/sash.js'; -// import { Codicon } from '../../../../base/common/codicons.js'; -// import { Codicon } from '../../../../base/common/codicons.js'; - +// import { IDisposable } from '../../../../base/common/lifecycle.js'; +import { IDisposable } from '../../../../base/common/lifecycle.js'; // compare against search.contribution.ts and debug.contribution.ts, scm.contribution.ts (source control) @@ -62,6 +58,8 @@ class SidebarViewPane extends ViewPane { @IOpenerService openerService: IOpenerService, @ITelemetryService telemetryService: ITelemetryService, @IHoverService hoverService: IHoverService, + // @ICodeEditorService private readonly editorService: ICodeEditorService, + // @IContextKeyService private readonly editorContextKeyService: IContextKeyService, ) { super(options, keybindingService, contextMenuService, configurationService, contextKeyService, viewDescriptorService, instantiationService, openerService, themeService, telemetryService, hoverService) @@ -76,10 +74,8 @@ class SidebarViewPane extends ViewPane { // gets set immediately this.instantiationService.invokeFunction(accessor => { - const services = getReactServices(accessor) - // mount react - const disposables: IDisposable[] | undefined = mountSidebar(parent, services); + const disposables: IDisposable[] | undefined = mountSidebar(parent, accessor); disposables?.forEach(d => this._register(d)) }); } @@ -88,8 +84,6 @@ class SidebarViewPane extends ViewPane { super.layoutBody(height, width) this.element.style.height = `${height}px` this.element.style.width = `${width}px` - - } } From 3fb6a4890da4b827923de7c214c214d9d2f19014 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 21 Dec 2024 17:51:10 -0800 Subject: [PATCH 05/90] watermark --- src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts b/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts index 88c9cf34..82f094e3 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts @@ -104,7 +104,7 @@ export class EditorGroupWatermark extends Disposable { const isDark = theme === ColorScheme.DARK || theme === ColorScheme.HIGH_CONTRAST_DARK elements.icon.style.maxWidth = '220px' elements.icon.style.opacity = '50%' - elements.icon.style.filter = isDark ? 'brightness(.5)' : 'invert(1)' + elements.icon.style.filter = isDark ? '' : 'invert(1)' //brightness(.5) } updateTheme() this._register( From 7cc57bf0862ff0bb97b819675b2d9b6310f474fb Mon Sep 17 00:00:00 2001 From: mp Date: Sat, 21 Dec 2024 18:19:16 -0800 Subject: [PATCH 06/90] input styles --- .gitignore | 1 + .../void/browser/react/src/sidebar-tsx/SidebarChat.tsx | 6 +++--- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/.gitignore b/.gitignore index b73ce578..5daf304c 100644 --- a/.gitignore +++ b/.gitignore @@ -21,3 +21,4 @@ vscode.db product.overrides.json *.snap.actual .vscode-test +.tmp/ diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index c9abf942..98926fd4 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -509,11 +509,11 @@ export const SidebarChat = () => { // .split(' ') // .map(style => `@@[&_textarea]:!void-${style}`) // apply styles to ancestor textarea elements // .join(' ') + - // ` outline-none` + // ` outline-none border-none` // .split(' ') // .map(style => `@@[&_div.monaco-inputbox]:!void-${style}`) // .join(' '); - `@@[&_textarea]:!void-bg-transparent @@[&_textarea]:!void-outline-none @@[&_textarea]:!void-text-vscode-input-fg @@[&_textarea]:!void-min-h-[81px] @@[&_textarea]:!void-max-h-[500px] @@[&_div.monaco-inputbox]:!void-outline-none` + `@@[&_textarea]:!void-bg-transparent @@[&_textarea]:!void-outline-none @@[&_textarea]:!void-text-vscode-input-fg @@[&_textarea]:!void-min-h-[81px] @@[&_textarea]:!void-max-h-[500px] @@[&_div.monaco-inputbox]:!void-border-none @@[&_div.monaco-inputbox]:!void-outline-none` } > @@ -531,7 +531,7 @@ export const SidebarChat = () => { className='flex flex-row justify-between items-end gap-1' > {/* submit options */} -
+
From 5fb30fed8760051be739916b9d99790868030b6f Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 21 Dec 2024 18:29:13 -0800 Subject: [PATCH 07/90] sidebar action --- .../contrib/void/browser/sidebarActions.ts | 33 ++++++++++++++++++- .../void/browser/sidebarStateService.ts | 15 +++------ 2 files changed, 36 insertions(+), 12 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/sidebarActions.ts b/src/vs/workbench/contrib/void/browser/sidebarActions.ts index 7f61c729..7939a46f 100644 --- a/src/vs/workbench/contrib/void/browser/sidebarActions.ts +++ b/src/vs/workbench/contrib/void/browser/sidebarActions.ts @@ -18,11 +18,13 @@ import { IEditorService } from '../../../services/editor/common/editorService.js import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js'; import { IRange } from '../../../../editor/common/core/range.js'; import { ITextModel } from '../../../../editor/common/model.js'; -import { VOID_VIEW_ID } from './sidebarPane.js'; +import { VOID_VIEW_CONTAINER_ID, VOID_VIEW_ID } from './sidebarPane.js'; import { IMetricsService } from '../../../../platform/void/common/metricsService.js'; import { ISidebarStateService } from './sidebarStateService.js'; import { ICommandService } from '../../../../platform/commands/common/commands.js'; import { OPEN_VOID_SETTINGS_ACTION_ID } from './voidSettingsPane.js'; +import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../../common/contributions.js'; +import { IViewsService } from '../../../services/views/common/viewsService.js'; // ---------- Register commands and keybindings ---------- @@ -180,3 +182,32 @@ registerAction2(class extends Action2 { commandService.executeCommand(OPEN_VOID_SETTINGS_ACTION_ID) } }) + + +export const VOID_OPEN_SIDEBAR_ACTION_ID = 'void.openSidebar' +registerAction2(class extends Action2 { + constructor() { + super({ + id: VOID_OPEN_SIDEBAR_ACTION_ID, + title: 'Open Void Sidebar', + }) + } + run(accessor: ServicesAccessor): void { + const viewsService = accessor.get(IViewsService) + viewsService.openViewContainer(VOID_VIEW_CONTAINER_ID); + viewsService.openView(VOID_VIEW_ID); + } +}); + +// mount at start + + +export class SidebarStartContribution implements IWorkbenchContribution { + static readonly ID = 'workbench.contrib.startupVoidSidebar'; + constructor( + @ICommandService private readonly commandService: ICommandService, + ) { + this.commandService.executeCommand(VOID_OPEN_SIDEBAR_ACTION_ID) + } +} +registerWorkbenchContribution2(SidebarStartContribution.ID, SidebarStartContribution, WorkbenchPhase.BlockRestore); diff --git a/src/vs/workbench/contrib/void/browser/sidebarStateService.ts b/src/vs/workbench/contrib/void/browser/sidebarStateService.ts index 683a3ed4..e711002f 100644 --- a/src/vs/workbench/contrib/void/browser/sidebarStateService.ts +++ b/src/vs/workbench/contrib/void/browser/sidebarStateService.ts @@ -1,9 +1,9 @@ import { Emitter, Event } from '../../../../base/common/event.js'; import { Disposable } from '../../../../base/common/lifecycle.js'; +import { ICommandService } from '../../../../platform/commands/common/commands.js'; import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js'; -import { IViewsService } from '../../../services/views/common/viewsService.js'; -import { VOID_VIEW_CONTAINER_ID, VOID_VIEW_ID } from './sidebarPane.js'; +import { VOID_OPEN_SIDEBAR_ACTION_ID } from './sidebarActions.js'; // service that manages sidebar's state @@ -23,8 +23,6 @@ export interface ISidebarStateService { onDidBlurChat: Event; fireFocusChat(): void; fireBlurChat(): void; - - openSidebarView(): void; } export const ISidebarStateService = createDecorator('voidSidebarStateService'); @@ -47,7 +45,7 @@ class VoidSidebarStateService extends Disposable implements ISidebarStateService state: VoidSidebarState constructor( - @IViewsService private readonly _viewsService: IViewsService, + @ICommandService private readonly commandService: ICommandService, ) { super() @@ -59,7 +57,7 @@ class VoidSidebarStateService extends Disposable implements ISidebarStateService setState(newState: Partial) { // make sure view is open if the tab changes if ('currentTab' in newState) { - this.openSidebarView() + this.commandService.executeCommand(VOID_OPEN_SIDEBAR_ACTION_ID) } this.state = { ...this.state, ...newState } @@ -74,11 +72,6 @@ class VoidSidebarStateService extends Disposable implements ISidebarStateService this._onBlurChat.fire() } - openSidebarView() { - this._viewsService.openViewContainer(VOID_VIEW_CONTAINER_ID); - this._viewsService.openView(VOID_VIEW_ID); - } - } registerSingleton(ISidebarStateService, VoidSidebarStateService, InstantiationType.Eager); From e647ce00548e9fd369e41792c6e854b3d6e6d497 Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 21 Dec 2024 18:46:45 -0800 Subject: [PATCH 08/90] fix + mount sidebar on init --- .../browser/helpers/reactServicesHelper.ts | 54 ------------------- .../contrib/void/browser/sidebarActions.ts | 33 +----------- .../contrib/void/browser/sidebarPane.ts | 30 +++++++++++ .../void/browser/sidebarStateService.ts | 2 +- .../contrib/void/browser/voidSettingsPane.ts | 4 +- 5 files changed, 33 insertions(+), 90 deletions(-) delete mode 100644 src/vs/workbench/contrib/void/browser/helpers/reactServicesHelper.ts diff --git a/src/vs/workbench/contrib/void/browser/helpers/reactServicesHelper.ts b/src/vs/workbench/contrib/void/browser/helpers/reactServicesHelper.ts deleted file mode 100644 index 08ad3fdb..00000000 --- a/src/vs/workbench/contrib/void/browser/helpers/reactServicesHelper.ts +++ /dev/null @@ -1,54 +0,0 @@ -import { ServicesAccessor } from '../../../../../editor/browser/editorExtensions.js'; -import { IModelService } from '../../../../../editor/common/services/model.js'; -import { IClipboardService } from '../../../../../platform/clipboard/common/clipboardService.js'; -import { IContextViewService, IContextMenuService } from '../../../../../platform/contextview/browser/contextView.js'; -import { IFileService } from '../../../../../platform/files/common/files.js'; -import { IHoverService } from '../../../../../platform/hover/browser/hover.js'; -import { IThemeService } from '../../../../../platform/theme/common/themeService.js'; -import { ILLMMessageService } from '../../../../../platform/void/common/llmMessageService.js'; -import { IRefreshModelService } from '../../../../../platform/void/common/refreshModelService.js'; -import { IVoidSettingsService } from '../../../../../platform/void/common/voidSettingsService.js'; -import { IInlineDiffsService } from '../inlineDiffsService.js'; -import { IQuickEditStateService } from '../quickEditStateService.js'; -import { ISidebarStateService } from '../sidebarStateService.js'; -import { IThreadHistoryService } from '../threadHistoryService.js'; - -export type ReactServicesType = { - quickEditStateService: IQuickEditStateService; - sidebarStateService: ISidebarStateService; - settingsStateService: IVoidSettingsService; - threadsStateService: IThreadHistoryService; - fileService: IFileService; - modelService: IModelService; - inlineDiffService: IInlineDiffsService; - llmMessageService: ILLMMessageService; - clipboardService: IClipboardService; - refreshModelService: IRefreshModelService; - - themeService: IThemeService, - hoverService: IHoverService, - - contextViewService: IContextViewService; - contextMenuService: IContextMenuService; -} - - -export const getReactServices = (accessor: ServicesAccessor): ReactServicesType => { - return { - quickEditStateService: accessor.get(IQuickEditStateService), - settingsStateService: accessor.get(IVoidSettingsService), - sidebarStateService: accessor.get(ISidebarStateService), - threadsStateService: accessor.get(IThreadHistoryService), - fileService: accessor.get(IFileService), - modelService: accessor.get(IModelService), - inlineDiffService: accessor.get(IInlineDiffsService), - llmMessageService: accessor.get(ILLMMessageService), - clipboardService: accessor.get(IClipboardService), - themeService: accessor.get(IThemeService), - hoverService: accessor.get(IHoverService), - refreshModelService: accessor.get(IRefreshModelService), - contextViewService: accessor.get(IContextViewService), - contextMenuService: accessor.get(IContextMenuService), - } -} - diff --git a/src/vs/workbench/contrib/void/browser/sidebarActions.ts b/src/vs/workbench/contrib/void/browser/sidebarActions.ts index 7939a46f..7f61c729 100644 --- a/src/vs/workbench/contrib/void/browser/sidebarActions.ts +++ b/src/vs/workbench/contrib/void/browser/sidebarActions.ts @@ -18,13 +18,11 @@ import { IEditorService } from '../../../services/editor/common/editorService.js import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js'; import { IRange } from '../../../../editor/common/core/range.js'; import { ITextModel } from '../../../../editor/common/model.js'; -import { VOID_VIEW_CONTAINER_ID, VOID_VIEW_ID } from './sidebarPane.js'; +import { VOID_VIEW_ID } from './sidebarPane.js'; import { IMetricsService } from '../../../../platform/void/common/metricsService.js'; import { ISidebarStateService } from './sidebarStateService.js'; import { ICommandService } from '../../../../platform/commands/common/commands.js'; import { OPEN_VOID_SETTINGS_ACTION_ID } from './voidSettingsPane.js'; -import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../../common/contributions.js'; -import { IViewsService } from '../../../services/views/common/viewsService.js'; // ---------- Register commands and keybindings ---------- @@ -182,32 +180,3 @@ registerAction2(class extends Action2 { commandService.executeCommand(OPEN_VOID_SETTINGS_ACTION_ID) } }) - - -export const VOID_OPEN_SIDEBAR_ACTION_ID = 'void.openSidebar' -registerAction2(class extends Action2 { - constructor() { - super({ - id: VOID_OPEN_SIDEBAR_ACTION_ID, - title: 'Open Void Sidebar', - }) - } - run(accessor: ServicesAccessor): void { - const viewsService = accessor.get(IViewsService) - viewsService.openViewContainer(VOID_VIEW_CONTAINER_ID); - viewsService.openView(VOID_VIEW_ID); - } -}); - -// mount at start - - -export class SidebarStartContribution implements IWorkbenchContribution { - static readonly ID = 'workbench.contrib.startupVoidSidebar'; - constructor( - @ICommandService private readonly commandService: ICommandService, - ) { - this.commandService.executeCommand(VOID_OPEN_SIDEBAR_ACTION_ID) - } -} -registerWorkbenchContribution2(SidebarStartContribution.ID, SidebarStartContribution, WorkbenchPhase.BlockRestore); diff --git a/src/vs/workbench/contrib/void/browser/sidebarPane.ts b/src/vs/workbench/contrib/void/browser/sidebarPane.ts index 519a96c2..e6da184f 100644 --- a/src/vs/workbench/contrib/void/browser/sidebarPane.ts +++ b/src/vs/workbench/contrib/void/browser/sidebarPane.ts @@ -39,6 +39,11 @@ import { Codicon } from '../../../../base/common/codicons.js'; import { Orientation } from '../../../../base/browser/ui/sash/sash.js'; // import { IDisposable } from '../../../../base/common/lifecycle.js'; import { IDisposable } from '../../../../base/common/lifecycle.js'; +import { Action2, registerAction2 } from '../../../../platform/actions/common/actions.js'; +import { ServicesAccessor } from '../../../../editor/browser/editorExtensions.js'; +import { IViewsService } from '../../../services/views/common/viewsService.js'; +import { IWorkbenchContribution, registerWorkbenchContribution2, WorkbenchPhase } from '../../../common/contributions.js'; +import { ICommandService } from '../../../../platform/commands/common/commands.js'; // compare against search.contribution.ts and debug.contribution.ts, scm.contribution.ts (source control) @@ -142,3 +147,28 @@ viewsRegistry.registerViews([{ // }, }], container); + +// open sidebar +export const VOID_OPEN_SIDEBAR_ACTION_ID = 'void.openSidebar' +registerAction2(class extends Action2 { + constructor() { + super({ + id: VOID_OPEN_SIDEBAR_ACTION_ID, + title: 'Open Void Sidebar', + }) + } + run(accessor: ServicesAccessor): void { + const viewsService = accessor.get(IViewsService) + viewsService.openViewContainer(VOID_VIEW_CONTAINER_ID); + } +}); + +export class SidebarStartContribution implements IWorkbenchContribution { + static readonly ID = 'workbench.contrib.startupVoidSidebar'; + constructor( + @ICommandService private readonly commandService: ICommandService, + ) { + this.commandService.executeCommand(VOID_OPEN_SIDEBAR_ACTION_ID) + } +} +registerWorkbenchContribution2(SidebarStartContribution.ID, SidebarStartContribution, WorkbenchPhase.AfterRestored); diff --git a/src/vs/workbench/contrib/void/browser/sidebarStateService.ts b/src/vs/workbench/contrib/void/browser/sidebarStateService.ts index e711002f..010b8abd 100644 --- a/src/vs/workbench/contrib/void/browser/sidebarStateService.ts +++ b/src/vs/workbench/contrib/void/browser/sidebarStateService.ts @@ -3,7 +3,7 @@ import { Disposable } from '../../../../base/common/lifecycle.js'; import { ICommandService } from '../../../../platform/commands/common/commands.js'; import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js'; import { createDecorator } from '../../../../platform/instantiation/common/instantiation.js'; -import { VOID_OPEN_SIDEBAR_ACTION_ID } from './sidebarActions.js'; +import { VOID_OPEN_SIDEBAR_ACTION_ID } from './sidebarPane.js'; // service that manages sidebar's state diff --git a/src/vs/workbench/contrib/void/browser/voidSettingsPane.ts b/src/vs/workbench/contrib/void/browser/voidSettingsPane.ts index 3b7515b8..eeaf7cba 100644 --- a/src/vs/workbench/contrib/void/browser/voidSettingsPane.ts +++ b/src/vs/workbench/contrib/void/browser/voidSettingsPane.ts @@ -24,7 +24,6 @@ import { ContextKeyExpr } from '../../../../platform/contextkey/common/contextke import { mountVoidSettings } from './react/out/void-settings-tsx/index.js' -import { getReactServices } from './helpers/reactServicesHelper.js'; import { Codicon } from '../../../../base/common/codicons.js'; import { IDisposable } from '../../../../base/common/lifecycle.js'; import { DomScrollableElement } from '../../../../base/browser/ui/scrollbar/scrollableElement.js'; @@ -89,8 +88,7 @@ class VoidSettingsPane extends EditorPane { // Mount React into the scrollable content this.instantiationService.invokeFunction(accessor => { - const services = getReactServices(accessor); - const disposables: IDisposable[] | undefined = mountVoidSettings(scrollableContent, services); + const disposables: IDisposable[] | undefined = mountVoidSettings(scrollableContent, accessor); setTimeout(() => { // this is a complete hack and I don't really understand how scrollbar works here this._scrollbar?.scanDomNode(); From 6298be394d5ceb2d5e8ddccb9fc000cd6b78dad6 Mon Sep 17 00:00:00 2001 From: Mathew Pareles Date: Sat, 21 Dec 2024 21:13:16 -0800 Subject: [PATCH 09/90] indentation --- .../react/src/sidebar-tsx/SidebarChat.tsx | 2 +- .../void/browser/react/src/util/inputs.tsx | 52 +++++++++++++++++- textureAtlas.png | Bin 0 -> 23831 bytes 3 files changed, 52 insertions(+), 2 deletions(-) create mode 100644 textureAtlas.png diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index 98926fd4..b00954f9 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -531,7 +531,7 @@ export const SidebarChat = () => { className='flex flex-row justify-between items-end gap-1' > {/* submit options */} -
+
diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx index 7d82965a..5995ea78 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx @@ -246,7 +246,44 @@ export const VoidSelectBox = ({ onChangeSelection, onCreateInstance, selectB />; }; +// makes it so that code in the sidebar isnt too tabbed out +const normalizeIndentation = (code: string): string => { + const lines = code.split('\n') + let minLeadingSpaces = Infinity + + // find the minimum number of leading spaces + for (const line of lines) { + if (line.trim() === '') continue; + let leadingSpaces = 0; + for (let i = 0; i < line.length; i++) { + const char = line[i]; + if (char === '\t' || char === ' ') { + leadingSpaces += 1; + } else { break; } + } + minLeadingSpaces = Math.min(minLeadingSpaces, leadingSpaces) + } + + // remove the leading spaces + return lines.map(line => { + if (line.trim() === '') return line; + + let spacesToRemove = minLeadingSpaces; + let i = 0; + while (spacesToRemove > 0 && i < line.length) { + const char = line[i]; + if (char === '\t' || char === ' ') { + spacesToRemove -= 1; + i++; + } else { break; } + } + + return line.slice(i); + + }).join('\n') + +} export const VoidCodeEditor = ({ initValue, language }: { initValue: string, language: string | undefined }) => { const divRef = useRef(null) @@ -255,6 +292,8 @@ export const VoidCodeEditor = ({ initValue, language }: { initValue: string, lan const instantiationService = accessor.get('IInstantiationService') const modelService = accessor.get('IModelService') + initValue = normalizeIndentation(initValue) + return
@@ -267,7 +306,18 @@ export const VoidCodeEditor = ({ initValue, language }: { initValue: string, lan scrollbar: { vertical: 'hidden', horizontal: 'auto', - } + }, + lineNumbers: 'off', + folding: false, + lineDecorationsWidth: 0, + scrollBeyondLastLine: false, + minimap: { enabled: false }, + overviewRulerLanes: 0, + hideCursorInOverviewRuler: true, + overviewRulerBorder: false, + renderLineHighlight: 'none', + glyphMargin: false, + readOnly: true, }, { isSimpleWidget: true, diff --git a/textureAtlas.png b/textureAtlas.png new file mode 100644 index 0000000000000000000000000000000000000000..9810b9570f18ced83e65b53f0cc3e5e135a47b4b GIT binary patch literal 23831 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 Date: Sat, 21 Dec 2024 22:37:08 -0800 Subject: [PATCH 10/90] selection --- .../browser/react/src/markdown/BlockCode.tsx | 60 +++++++++++++++++++ .../react/src/sidebar-tsx/SidebarChat.tsx | 39 +++++++++--- .../void/browser/react/src/util/inputs.tsx | 29 ++++++--- .../src/void-settings-tsx/ModelDropdown.tsx | 17 ++++-- 4 files changed, 126 insertions(+), 19 deletions(-) diff --git a/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx b/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx index 479ea70b..46f9e086 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/markdown/BlockCode.tsx @@ -9,6 +9,66 @@ import { atomOneDarkReasonable } from "react-syntax-highlighter/dist/esm/styles/ import { VoidCodeEditor } from '../util/inputs.js'; + +export function getLanguageFromFileName(fileName: string): string { + if (!fileName) return 'plaintext'; + + const ext = fileName.toLowerCase().split('.').pop(); + if (!ext) return 'plaintext'; + + const extensionMap: { [key: string]: string } = { + // Web + 'html': 'html', + 'htm': 'html', + 'css': 'css', + 'scss': 'scss', + 'less': 'less', + 'js': 'javascript', + 'jsx': 'javascript', + 'ts': 'typescript', + 'tsx': 'typescript', + 'json': 'json', + 'jsonc': 'json', + + // Programming Languages + 'py': 'python', + 'java': 'java', + 'cpp': 'cpp', + 'cc': 'cpp', + 'h': 'cpp', + 'hpp': 'cpp', + 'cs': 'csharp', + 'go': 'go', + 'rs': 'rust', + 'rb': 'ruby', + 'php': 'php', + 'sh': 'shell', + 'bash': 'shell', + 'zsh': 'shell', + + // Markup/Config + 'md': 'markdown', + 'markdown': 'markdown', + 'xml': 'xml', + 'svg': 'xml', + 'yaml': 'yaml', + 'yml': 'yaml', + 'ini': 'ini', + 'toml': 'ini', + + // Other + 'sql': 'sql', + 'graphql': 'graphql', + 'gql': 'graphql', + 'dockerfile': 'dockerfile', + 'docker': 'dockerfile' + }; + + return extensionMap[ext] || 'plaintext'; +} + + + export const BlockCode = ({ text, buttonsOnHover, language }: { text: string, buttonsOnHover?: ReactNode, language?: string }) => { const customStyle = { diff --git a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx index b00954f9..73d3ae1e 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/sidebar-tsx/SidebarChat.tsx @@ -9,7 +9,7 @@ import React, { ButtonHTMLAttributes, FormEvent, FormHTMLAttributes, Fragment, u import { useAccessor, useThreadsState } from '../util/services.js'; import { ChatMessage, CodeSelection, CodeStagingSelection, IThreadHistoryService } from '../../../threadHistoryService.js'; -import { BlockCode } from '../markdown/BlockCode.js'; +import { BlockCode, getLanguageFromFileName } from '../markdown/BlockCode.js'; import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js'; import { URI } from '../../../../../../../base/common/uri.js'; import { EndOfLinePreference } from '../../../../../../../editor/common/model.js'; @@ -86,6 +86,29 @@ const IconSquare = ({ size, className = '' }: { size: number, className?: string ); }; + +export const IconWarning = ({ size, className = '' }: { size: number, className?: string }) => { + return ( + + {/* Warning triangle */} + + + {/* Exclamation mark */} + + + + ); +}; + type ButtonProps = ButtonHTMLAttributes export const ButtonSubmit = ({ className, disabled, ...props }: ButtonProps & Required>) => { return } @@ -192,7 +215,7 @@ export const SelectedFiles = ( > {selections.map((selection, i) => { - const showSelectionText = selection.selectionStr && selectionIsOpened[i] + const showSelectionText = !!(selection.selectionStr && selectionIsOpened[i]) return (
{ @@ -222,7 +247,7 @@ export const SelectedFiles = ( {/* type of selection */} - {selection.selectionStr !== null ? 'Selection' : 'File'} + {selection.selectionStr !== null ? 'Selection' : 'File'} {/* X button */} {type === 'staging' && // hoveredIdx === i @@ -241,7 +266,7 @@ export const SelectedFiles = ( {/* selection text */} {showSelectionText &&
- +
}
diff --git a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx index 5995ea78..557d4dca 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/util/inputs.tsx @@ -286,6 +286,9 @@ const normalizeIndentation = (code: string): string => { } export const VoidCodeEditor = ({ initValue, language }: { initValue: string, language: string | undefined }) => { + + const MAX_HEIGHT = 200; + const divRef = useRef(null) const accessor = useAccessor() @@ -302,10 +305,11 @@ export const VoidCodeEditor = ({ initValue, language }: { initValue: string, lan container, { automaticLayout: true, - wordWrap: 'on', + wordWrap: 'off', scrollbar: { - vertical: 'hidden', + vertical: 'auto', horizontal: 'auto', + alwaysConsumeMouseWheel: false }, lineNumbers: 'off', folding: false, @@ -326,26 +330,35 @@ export const VoidCodeEditor = ({ initValue, language }: { initValue: string, lan } onCreateInstance={useCallback((editor: CodeEditorWidget) => { - const model = modelService.createModel(initValue, null) editor.setModel(model); model.setLanguage(language ?? 'plaintext') const container = editor.getDomNode() const parentNode = container?.parentElement - if (parentNode) - parentNode.style.height = `${editor.getScrollHeight() + 1}px` // the +1 is if there's a half pixel issue + if (parentNode) { + const height = Math.min(editor.getScrollHeight() + 1, MAX_HEIGHT); + parentNode.style.height = `${height}px`; + editor.layout(); + } - return [] + // Listen for content changes and update height + const disposable = editor.onDidContentSizeChange(() => { + if (parentNode) { + const height = Math.min(editor.getScrollHeight() + 1, MAX_HEIGHT); + parentNode.style.height = `${height}px`; + editor.layout(); + } + }); + + return [disposable] }, [modelService, initValue, language])} dispose={useCallback((editor: CodeEditorWidget) => { editor.dispose(); }, [])} - // ignored propsFn={useCallback(() => { return [] }, [])} - />
diff --git a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx index edb55f90..2ec2db72 100644 --- a/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx +++ b/src/vs/workbench/contrib/void/browser/react/src/void-settings-tsx/ModelDropdown.tsx @@ -8,6 +8,7 @@ import { FeatureName, featureNames, ModelSelection, modelSelectionsEqual, Provid import { useSettingsState, useRefreshModelState, useAccessor } from '../util/services.js' import { VoidSelectBox } from '../util/inputs.js' import { SelectBox } from '../../../../../../../base/browser/ui/selectBox/selectBox.js' +import { IconWarning } from '../sidebar-tsx/SidebarChat.js' const ModelSelectBox = ({ featureName }: { featureName: FeatureName }) => { @@ -42,10 +43,18 @@ const ModelSelectBox = ({ featureName }: { featureName: FeatureName }) => { } const DummySelectBox = () => { - return { }} - /> + + return
+ + Add a model +
+ // return { }} + // /> } export const ModelDropdown = ({ featureName }: { featureName: FeatureName }) => { From a435a59a2e51299a000d23f516d5736ce40756ca Mon Sep 17 00:00:00 2001 From: Andrew Pareles Date: Sat, 21 Dec 2024 21:37:55 -0800 Subject: [PATCH 11/90] inlineDiffEdits add support for ctrl+K --- .../parts/editor/editorGroupWatermark.ts | 7 +- .../void/browser/inlineDiffsService.ts | 248 ++++--- .../contrib/void/browser/media/void.css | 4 + .../contrib/void/browser/prompt/prompts.ts | 632 +++++++++--------- .../void/browser/quickEditStateService.ts | 10 - .../react/src/ctrl-k-tsx/CtrlKChat.tsx | 15 +- .../react/src/sidebar-tsx/SidebarChat.tsx | 6 +- .../contrib/void/browser/sidebarActions.ts | 4 +- .../contrib/void/browser/voidSettingsPane.ts | 6 +- 9 files changed, 452 insertions(+), 480 deletions(-) diff --git a/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts b/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts index 82f094e3..e320e456 100644 --- a/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts +++ b/src/vs/workbench/browser/parts/editor/editorGroupWatermark.ts @@ -25,6 +25,7 @@ import { IWindowOpenable } from '../../../../platform/window/common/window.js'; import { ILabelService, Verbosity } from '../../../../platform/label/common/label.js'; import { splitRecentLabel } from '../../../../base/common/labels.js'; import { IHostService } from '../../../services/host/browser/host.js'; +import { VOID_OPEN_SETTINGS_ACTION_ID } from '../../../contrib/void/browser/voidSettingsPane.js'; // import { IContextKeyService } from '../../../../platform/contextkey/common/contextkey.js'; registerColor('editorWatermark.foreground', { dark: transparent(editorForeground, 0.6), light: transparent(editorForeground, 0.68), hcDark: editorForeground, hcLight: editorForeground }, localize('editorLineHighlight', 'Foreground color for the labels in the editor watermark.')); @@ -278,17 +279,15 @@ export class EditorGroupWatermark extends Disposable { const keys3 = this.keybindingService.lookupKeybinding('workbench.action.openGlobalKeybindings'); const button3 = append(boxBelow, $('button')); - button3.textContent = 'Change Keybindings' + button3.textContent = 'Void Settings' const label3 = new KeybindingLabel(button3, OS, { renderUnboundKeybindings: true, ...defaultKeybindingLabelStyles }); if (keys3) label3.set(keys3); button3.onclick = () => { - this.commandService.executeCommand('workbench.action.openGlobalKeybindings') + this.commandService.executeCommand(VOID_OPEN_SETTINGS_ACTION_ID) } this.currentDisposables.add(label3); - - } }; diff --git a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts index e33c9991..50a51301 100644 --- a/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts +++ b/src/vs/workbench/contrib/void/browser/inlineDiffsService.ts @@ -11,9 +11,9 @@ import { ICodeEditor, IOverlayWidget, IViewZone } from '../../../../editor/brows // import { IUndoRedoService } from '../../../../platform/undoRedo/common/undoRedo.js'; import { ICodeEditorService } from '../../../../editor/browser/services/codeEditorService.js'; // import { throttle } from '../../../../base/common/decorators.js'; -import { writeFileWithDiffInstructions } from './prompt/prompts.js'; +import { inlineDiff_systemMessage } from './prompt/prompts.js'; import { ComputedDiff, findDiffs } from './helpers/findDiffs.js'; -import { EndOfLinePreference, ITextModel } from '../../../../editor/common/model.js'; +import { EndOfLinePreference, IModelDecorationOptions, ITextModel } from '../../../../editor/common/model.js'; import { IRange } from '../../../../editor/common/core/range.js'; import { registerColor } from '../../../../platform/theme/common/colorUtils.js'; import { Color, RGBA } from '../../../../base/common/color.js'; @@ -31,33 +31,24 @@ import { LLMFeatureSelection, ServiceSendLLMMessageParams } from '../../../../pl import { ILLMMessageService } from '../../../../platform/void/common/llmMessageService.js'; +const configOfBG = (color: Color) => { + return { dark: color, light: color, hcDark: color, hcLight: color, } +} // gets converted to --vscode-void-greenBG, see void.css const greenBG = new Color(new RGBA(155, 185, 85, .3)); // default is RGBA(155, 185, 85, .2) -registerColor('void.greenBG', { - dark: greenBG, - light: greenBG, hcDark: null, hcLight: null -}, '', true); +registerColor('void.greenBG', configOfBG(greenBG), '', true); const redBG = new Color(new RGBA(255, 0, 0, .3)); // default is RGBA(255, 0, 0, .2) -registerColor('void.redBG', { - dark: redBG, - light: redBG, hcDark: null, hcLight: null -}, '', true); +registerColor('void.redBG', configOfBG(redBG), '', true); const sweepBG = new Color(new RGBA(100, 100, 100, .2)); -registerColor('void.sweepBG', { - dark: sweepBG, - light: sweepBG, hcDark: null, hcLight: null -}, '', true); +registerColor('void.sweepBG', configOfBG(sweepBG), '', true); + +const highlightBG = new Color(new RGBA(100, 100, 100, .1)); +registerColor('void.highlightBG', configOfBG(highlightBG), '', true); const sweepIdxBG = new Color(new RGBA(100, 100, 100, .5)); -registerColor('void.sweepIdxBG', { - dark: sweepIdxBG, - light: sweepIdxBG, hcDark: null, hcLight: null -}, '', true); - - - +registerColor('void.sweepIdxBG', configOfBG(sweepIdxBG), '', true); export type Diff = { @@ -73,9 +64,11 @@ type DiffArea = { originalCode: string; startLine: number; endLine: number; + shouldHighlight: boolean; // should visually highlight this DiffArea _URI: URI; // typically we get the URI from model _diffOfId: Record; // diffid -> diff in this DiffArea + } & ({ _sweepState: { isStreaming: true; @@ -91,6 +84,7 @@ const diffAreaSnapshotKeys = [ 'originalCode', 'startLine', 'endLine', + 'shouldHighlight', ] as const satisfies (keyof DiffArea)[] type DiffAreaSnapshot = Pick @@ -120,9 +114,9 @@ export const IInlineDiffsService = createDecorator('inlineD class InlineDiffsService extends Disposable implements IInlineDiffsService { _serviceBrand: undefined; - // state of each document - removeStylesFnsOfUri: Record> = {} // functions that remove the styles of this uri + // URI <--> model + removeStylesFnsOfURI: Record> = {} // functions that remove the styles of this uri diffAreasOfURI: Record> = {} diffAreaOfId: Record = {}; @@ -131,16 +125,6 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { _diffareaidPool = 0 // each diffarea has an id _diffidPool = 0 // each diff has an id - /* - Picture of all the data structures: - () -modelid-> {originalFileStr, Set(diffareaid), state} - ^ | - \________________ diffareaid -> diffarea -> diff[] - ^ | - \____ diff - */ - - constructor( // @IHistoryService private readonly _historyService: IHistoryService, // history service is the history of pressing alt left/right @ICodeEditorService private readonly _editorService: ICodeEditorService, @@ -156,8 +140,8 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { if (!(model.uri.fsPath in this.diffAreasOfURI)) { this.diffAreasOfURI[model.uri.fsPath] = new Set(); } - if (!(model.uri.fsPath in this.removeStylesFnsOfUri)) { - this.removeStylesFnsOfUri[model.uri.fsPath] = new Set(); + if (!(model.uri.fsPath in this.removeStylesFnsOfURI)) { + this.removeStylesFnsOfURI[model.uri.fsPath] = new Set(); } // when the user types, realign diff areas and re-render them @@ -185,7 +169,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { const uri = editor.getModel()?.uri ?? null if (uri) this._refreshDiffsInURI(uri) - // called when the user switches tabs (typically there's only 1 editor on the screen, make sure you understand this) + // called when the user switches tabs (typically there's only 1 editor on the screen, it switches between models, make sure you understand this) this._register(editor.onDidChangeModel((e) => { if (e.oldModelUrl) this._refreshDiffsInURI(e.oldModelUrl) if (e.newModelUrl) this._refreshDiffsInURI(e.newModelUrl) @@ -202,51 +186,46 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { - - - - - - - - private _addSweepStylesToURI = (uri: URI, sweepLine: number, endLine: number) => { - - const decorationIds: (string | null)[] = [] - - const model = this._getModel(uri) + // highlight the region + private _addLineDecoration = (model: ITextModel | null, startLine: number, endLine: number, className: string, options?: Partial) => { if (model === null) return - - // sweepLine ... sweepLine - decorationIds.push( - model.changeDecorations(accessor => accessor.addDecoration( - { startLineNumber: sweepLine, startColumn: 1, endLineNumber: sweepLine, endColumn: Number.MAX_SAFE_INTEGER }, - { - className: 'void-sweepIdxBG', - description: 'void-sweepIdxBG', - isWholeLine: true - })) - ) - - // sweepLine+1 ... endLine - decorationIds.push( - model.changeDecorations(accessor => accessor.addDecoration( - { startLineNumber: sweepLine + 1, startColumn: 1, endLineNumber: endLine, endColumn: Number.MAX_SAFE_INTEGER }, - { - className: 'void-sweepBG', - description: 'void-sweepBG', - isWholeLine: true - })) - ) - const disposeSweepStyles = () => { - for (const id of decorationIds) { - if (id) model.changeDecorations(accessor => accessor.removeDecoration(id)) - } + const id = model.changeDecorations(accessor => accessor.addDecoration( + { startLineNumber: startLine, startColumn: 1, endLineNumber: endLine, endColumn: Number.MAX_SAFE_INTEGER }, + { + className: className, + description: className, + isWholeLine: true, + ...options + })) + const disposeHighlight = () => { + if (id) model.changeDecorations(accessor => accessor.removeDecoration(id)) } - return disposeSweepStyles + return disposeHighlight } + private _addDiffAreaStylesToURI = (uri: URI) => { + const model = this._getModel(uri) + + for (const diffareaid of this.diffAreasOfURI[uri.fsPath]) { + const diffArea = this.diffAreaOfId[diffareaid] + // add sweep styles to the diffArea + if (diffArea._sweepState.isStreaming) { + // sweepLine ... sweepLine + const fn1 = this._addLineDecoration(model, diffArea._sweepState.line, diffArea._sweepState.line, 'void-sweepIdxBG') + // sweepLine+1 ... endLine + const fn2 = this._addLineDecoration(model, diffArea._sweepState.line + 1, diffArea.endLine, 'void-sweepBG') + this.removeStylesFnsOfURI[uri.fsPath].add(() => { fn1?.(); fn2?.(); }) + } + // highlight the diffArea + if (diffArea.shouldHighlight) { + const fn = this._addLineDecoration(model, diffArea.startLine, diffArea.endLine, 'void-highlightBG') + this.removeStylesFnsOfURI[uri.fsPath].add(() => fn?.()); + } + } + } + private _addDiffStylesToEditor = (editor: ICodeEditor, diff: Diff) => { const { type, diffid } = diff @@ -254,57 +233,48 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { const disposeInThisEditorFns: (() => void)[] = [] // green decoration and minimap decoration - editor.changeDecorations(accessor => { - if (type === 'deletion') return; - - const greenRange = { startLineNumber: diff.startLine, startColumn: 1, endLineNumber: diff.endLine, endColumn: Number.MAX_SAFE_INTEGER, } // 1-indexed - const decorationId = accessor.addDecoration(greenRange, { - className: 'void-greenBG', // .monaco-editor .line-insert - description: 'Void added this code', - isWholeLine: true, - minimap: { - color: { id: 'minimapGutter.addedBackground' }, - position: 2 - }, - overviewRuler: { - color: { id: 'editorOverviewRuler.addedForeground' }, - position: 7 - } + if (type !== 'deletion') { + const fn = this._addLineDecoration(editor.getModel(), diff.startLine, diff.endLine, 'void-greenBG', { + minimap: { color: { id: 'minimapGutter.addedBackground' }, position: 2 }, + overviewRuler: { color: { id: 'editorOverviewRuler.addedForeground' }, position: 7 } }) - disposeInThisEditorFns.push(() => { editor.changeDecorations(accessor => { if (decorationId) accessor.removeDecoration(decorationId) }) }) - }) + disposeInThisEditorFns.push(() => { fn?.() }) + } + // red in a view zone - editor.changeViewZones(accessor => { - if (type === 'insertion') return; + if (type !== 'insertion') { + editor.changeViewZones(accessor => { - const domNode = document.createElement('div'); - domNode.className = 'void-redBG' + const domNode = document.createElement('div'); + domNode.className = 'void-redBG' - const renderOptions = RenderOptions.fromEditor(editor); - // applyFontInfo(domNode, renderOptions.fontInfo) + const renderOptions = RenderOptions.fromEditor(editor); + // applyFontInfo(domNode, renderOptions.fontInfo) - // Compute view-lines based on redText - const redText = diff.originalCode - const lines = redText.split('\n'); - const lineTokens = lines.map(line => LineTokens.createFromTextAndMetadata([{ text: line, metadata: 0 }], this._langService.languageIdCodec)); - const source = new LineSource(lineTokens, lines.map(() => null), false, false) - const result = renderLines(source, renderOptions, [], domNode); + // Compute view-lines based on redText + const redText = diff.originalCode + const lines = redText.split('\n'); + const lineTokens = lines.map(line => LineTokens.createFromTextAndMetadata([{ text: line, metadata: 0 }], this._langService.languageIdCodec)); + const source = new LineSource(lineTokens, lines.map(() => null), false, false) + const result = renderLines(source, renderOptions, [], domNode); - const viewZone: IViewZone = { - // afterLineNumber: computedDiff.startLine - 1, - afterLineNumber: type === 'edit' ? diff.endLine : diff.startLine - 1, - heightInLines: result.heightInLines, - minWidthInPx: result.minWidthInPx, - domNode: domNode, - marginDomNode: document.createElement('div'), // displayed to left - suppressMouseDown: true, - }; + const viewZone: IViewZone = { + // afterLineNumber: computedDiff.startLine - 1, + afterLineNumber: type === 'edit' ? diff.endLine : diff.startLine - 1, + heightInLines: result.heightInLines, + minWidthInPx: result.minWidthInPx, + domNode: domNode, + marginDomNode: document.createElement('div'), // displayed to left + suppressMouseDown: true, + }; - const zoneId = accessor.addZone(viewZone) - disposeInThisEditorFns.push(() => { editor.changeViewZones(accessor => { if (zoneId) accessor.removeZone(zoneId) }) }) + const zoneId = accessor.addZone(viewZone) + disposeInThisEditorFns.push(() => { editor.changeViewZones(accessor => { if (zoneId) accessor.removeZone(zoneId) }) }) + + }); + } - }); // Accept | Reject widget const buttonsWidget = new AcceptRejectWidget({ @@ -440,10 +410,10 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { const diffArea = this.diffAreaOfId[diffareaid] this._deleteDiffs(diffArea) } - for (const removeStyleFn of this.removeStylesFnsOfUri[uri.fsPath]) { + for (const removeStyleFn of this.removeStylesFnsOfURI[uri.fsPath]) { removeStyleFn() } - this.removeStylesFnsOfUri[uri.fsPath].clear() + this.removeStylesFnsOfURI[uri.fsPath].clear() } @@ -552,17 +522,15 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { for (let editor of editors) { const fn = this._addDiffStylesToEditor(editor, newDiff) - this.removeStylesFnsOfUri[uri.fsPath].add(() => fn()) + this.removeStylesFnsOfURI[uri.fsPath].add(() => fn()) } this.diffOfId[diffid] = newDiff diffArea._diffOfId[diffid] = newDiff } - if (diffArea._sweepState.isStreaming) { - const fn = this._addSweepStylesToURI(uri, diffArea._sweepState.line, diffArea.endLine) - this.removeStylesFnsOfUri[uri.fsPath].add(() => fn?.()) - } + // update styles on this DiffArea + this._addDiffAreaStylesToURI(uri) } @@ -674,6 +642,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService { originalCode: originalCode, startLine: beginLine, endLine: endLine, // starts out the same as the current file + shouldHighlight: false, _URI: uri, _sweepState: { isStreaming: true, @@ -710,7 +679,7 @@ Please finish writing the new file by applying the diff to the original file. Re const object: ServiceSendLLMMessageParams = { logging: { loggingName: 'streamChunk' }, messages: [ - { role: 'system', content: writeFileWithDiffInstructions, }, + { role: 'system', content: inlineDiff_systemMessage, }, // TODO include more context too { role: 'user', content: promptContent, } ], @@ -772,6 +741,29 @@ Please finish writing the new file by applying the diff to the original file. Re + addDiffArea({ uri, startLine, endLine, originalCode }: { uri: URI, startLine: number, endLine: number, originalCode: string }) { + const diffareaid = this._diffareaidPool++ + + const diffArea: DiffArea = { + diffareaid: diffareaid, + originalCode, + startLine, + endLine, + shouldHighlight: true, + _URI: uri, + _sweepState: { + isStreaming: false, + line: null, + }, + _diffOfId: {}, + } + + this.diffAreasOfURI[uri.fsPath].add(diffArea.diffareaid.toString()) + this.diffAreaOfId[diffArea.diffareaid] = diffArea + + this._refreshDiffsInURI(uri) + } + @@ -1002,9 +994,3 @@ class AcceptRejectWidget extends Widget implements IOverlayWidget { } - - - - - - diff --git a/src/vs/workbench/contrib/void/browser/media/void.css b/src/vs/workbench/contrib/void/browser/media/void.css index cf317680..00912fdb 100644 --- a/src/vs/workbench/contrib/void/browser/media/void.css +++ b/src/vs/workbench/contrib/void/browser/media/void.css @@ -11,6 +11,10 @@ background-color: var(--vscode-void-sweepBG); } +.void-highlightBG { + background-color: var(--vscode-void-highlightBG); +} + .void-greenBG { background-color: var(--vscode-void-greenBG); } diff --git a/src/vs/workbench/contrib/void/browser/prompt/prompts.ts b/src/vs/workbench/contrib/void/browser/prompt/prompts.ts index 803029c2..49493bbd 100644 --- a/src/vs/workbench/contrib/void/browser/prompt/prompts.ts +++ b/src/vs/workbench/contrib/void/browser/prompt/prompts.ts @@ -6,33 +6,7 @@ import { CodeSelection } from '../threadHistoryService.js'; -const stringifySelections = (selections: CodeSelection[]) => { - - return selections.map(({ fileURI, content, selectionStr }) => - `\ -File: ${fileURI.fsPath} -\`\`\` -${content // this was the enite file which is foolish - } -\`\`\`${selectionStr === null ? '' : ` -Selection: ${selectionStr}`} -`).join('\n') -} - - -export const generateCtrlLPrompt = (instructions: string, selections: CodeSelection[] | null) => { - let str = ''; - if (selections && selections.length > 0) { - str += stringifySelections(selections); - str += `Please edit the selected code following these instructions:\n` - } - str += `${instructions}`; - return str; -}; - - - -export const ctrlLSystem = `\ +export const chat_systemMessage = `\ You are a coding assistant. You are given a list of relevant files \`files\`, a selection that the user is making \`selection\`, and instructions to follow \`instructions\`. Please edit the selected file following the user's instructions (or, if appropriate, answer their question instead). @@ -119,301 +93,38 @@ Store Result: After computing fib(n), the result is stored in memo for future re ## END EXAMPLES\ ` -export const generateCtrlKPrompt = ({ selection, prefix, suffix, instructions, }: { selection: string, prefix: string, suffix: string, instructions: string, }) => `\ -Here is the user's original selection: + + +const stringifySelections = (selections: CodeSelection[]) => { + return selections.map(({ fileURI, content, selectionStr }) => + `\ +File: ${fileURI.fsPath} \`\`\` -${selection} -\`\`\` - -The user wants to apply the following instructions to the selection: -${instructions} - -Please rewrite the selection following the user's instructions. - -Instructions to follow: -1. Follow the user's instructions -2. You may ONLY CHANGE the selection, and nothing else in the file -3. Make sure all brackets in the new selection are balanced the same was as in the original selection -3. Be careful not to duplicate or remove variables, comments, or other syntax by mistake - -Complete the following: -\`\`\` -
${prefix}
-${suffix} -`; - - -export const generateDiffInstructions = ` -You are a coding assistant. You are given a list of relevant files \`files\`, a selection that the user is making \`selection\`, and instructions to follow \`instructions\`. - -Please edit the selected file following the user's instructions (or, if appropriate, answer their question instead). - -All changes made to files must be outputted in unified diff format. -Unified diff format instructions: -1. Each diff must begin with \`\`\`@@ ... @@\`\`\`. -2. Each line must start with a \`+\` or \`-\` or \` \` symbol. -3. Make diffs more than a few lines. -4. Make high-level diffs rather than many one-line diffs. - -Here's an example of unified diff format: - -\`\`\` -@@ ... @@ --def factorial(n): -- if n == 0: -- return 1 -- else: -- return n * factorial(n-1) -+def factorial(number): -+ if number == 0: -+ return 1 -+ else: -+ return number * factorial(number-1) -\`\`\` - -Please create high-level diffs where you group edits together if they are near each other, like in the above example. Another way to represent the above example is to make many small line edits. However, this is less preferred, because the edits are not high-level. The edits are close together and should be grouped: - -\`\`\` -@@ ... @@ # This is less preferred because edits are close together and should be grouped: --def factorial(n): -+def factorial(number): -- if n == 0: -+ if number == 0: - return 1 - else: -- return n * factorial(n-1) -+ return number * factorial(number-1) -\`\`\` - -# Example 1: - -FILES -selected file \`test.ts\`: -\`\`\` -x = 1 - -{{selection}} - -z = 3 -\`\`\` - -SELECTION -\`\`\`const y = 2\`\`\` - -INSTRUCTIONS -\`\`\`y = 3\`\`\` - -EXPECTED RESULT - -We should change the selection from \`\`\`y = 2\`\`\` to \`\`\`y = 3\`\`\`. -\`\`\` -@@ ... @@ --x = 1 -- --y = 2 -+x = 1 -+ -+y = 3 -\`\`\` - -# Example 2: - -FILES -selected file \`Sidebar.tsx\`: -\`\`\` -import React from 'react'; -import styles from './Sidebar.module.css'; - -interface SidebarProps { - items: { label: string; href: string }[]; - onItemSelect?: (label: string) => void; - onExtraButtonClick?: () => void; +${content // this was the enite file which is foolish + } +\`\`\`${selectionStr === null ? '' : ` +Selection: ${selectionStr}`} +`).join('\n') } -const Sidebar: React.FC = ({ items, onItemSelect, onExtraButtonClick }) => { - return ( -
-
    - {items.map((item, index) => ( -
  • - {{selection}} - className={styles.sidebarButton} - onClick={() => onItemSelect?.(item.label)} - > - {item.label} - -
  • - ))} -
- -
- ); + +export const chat_prompt = (instructions: string, selections: CodeSelection[] | null) => { + let str = ''; + if (selections && selections.length > 0) { + str += stringifySelections(selections); + str += `Please edit the selected code following these instructions:\n` + } + str += `${instructions}`; + return str; }; -export default Sidebar; -\`\`\` - -SELECTION -\`\`\` --
    -- {items.map((item, index) => ( --
  • -- --
  • -- ))} --
-- --
-+
-+
    -+ {items.map((item, index) => ( -+
  • -+
    onItemSelect?.(item.label)} -+ > -+ {item.label} -+
    -+
  • -+ ))} -+
-+
-+ Extra Action -+
-+
-\`\`\` -`; -export const searchDiffChunkInstructions = ` -You are a coding assistant that applies a diff to a file. You are given a diff \`diff\`, a list of files \`files\` to apply the diff to, and a selection \`selection\` that you are currently considering in the file. - -Determine whether you should modify ANY PART of the selection \`selection\` following the \`diff\`. Return \`true\` if you should modify any part of the selection, and \`false\` if you should not modify any part of it. - -# Example 1: - -FILES -selected file \`Sidebar.tsx\`: -\`\`\` -import React from 'react'; -import styles from './Sidebar.module.css'; - -interface SidebarProps { - items: { label: string; href: string }[]; - onItemSelect?: (label: string) => void; - onExtraButtonClick?: () => void; -} - -const Sidebar: React.FC = ({ items, onItemSelect, onExtraButtonClick }) => { - return ( -
-
    - {items.map((item, index) => ( -
  • - -
  • - ))} -
- -
- ); -}; - -export default Sidebar; -\`\`\` - -DIFF -\`\`\` -@@ ... @@ --
--
    -- {items.map((item, index) => ( --
  • -- --
  • -- ))} --
-- --
-+
-+
    -+ {items.map((item, index) => ( -+
  • -+
    onItemSelect?.(item.label)} -+ > -+ {item.label} -+
    -+
  • -+ ))} -+
-+
-+ Extra Action -+
-+
-\`\`\` - -SELECTION -\`\`\` -import React from 'react'; -import styles from './Sidebar.module.css'; - -interface SidebarProps { - items: { label: string; href: string }[]; - onItemSelect?: (label: string) => void; - onExtraButtonClick?: () => void; -} - -const Sidebar: React.FC = ({ items, onItemSelect, onExtraButtonClick }) => { - return ( -
-