Compare commits
62 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| ab54f6d097 | |||
| cc177b9cd4 | |||
| dd204978e5 | |||
| fb48c4e67e | |||
| 74fa5cb505 | |||
| fae03c3060 | |||
| 68722ee5c3 | |||
| 4a993a716b | |||
| 23d1d4169a | |||
| f688e1ffae | |||
| a443315c14 | |||
| eeacb2d3c9 | |||
| cdbdf3c5c7 | |||
| 825c40bfff | |||
| a3d3309b9d | |||
| 32bfe9a111 | |||
| a9adcad560 | |||
| 80f7511eee | |||
| 7fe8f5c47d | |||
| b31882565b | |||
| 6aaf425419 | |||
| b0d21dfdb1 | |||
| 2087948789 | |||
| 6feb713682 | |||
| 667dc8bd7e | |||
| bdb0c65346 | |||
| df14b80d8b | |||
| 86decf8ed9 | |||
| bd9b9a9058 | |||
| 83c1f3430a | |||
| 02de8937ac | |||
| 78f3819c33 | |||
| b9cea4906e | |||
| 4a4677b5e2 | |||
| 5dab1a6a77 | |||
| 9b01d5ba7c | |||
| dcb708758d | |||
| dd4548466a | |||
| cda489e3e0 | |||
| 13594ef06c | |||
| c2b8df06eb | |||
| 33809ec48b | |||
| b4820abc9e | |||
| 0e79dec0d7 | |||
| 659f01413f | |||
| 110534df30 | |||
| d3b61867f0 | |||
| 954e611fda | |||
| 198adaaf18 | |||
| 2df7fa9ebc | |||
| 312942b004 | |||
| 0a444f6ff8 | |||
| 0c10cb73f6 | |||
| 3a3bc24fef | |||
| 9543bf8eb3 | |||
| d85a316536 | |||
| 076e0add44 | |||
| 8a17c9246b | |||
| 1afb39b155 | |||
| f08fd04af5 | |||
| 2d80a29275 | |||
| d8e9b50890 |
@@ -8,7 +8,7 @@ There are a few ways to contribute:
|
||||
- 💡 Make suggestions in our [Discord](https://discord.gg/RSNjgaugJs).
|
||||
- ⭐️ If you want to build your AI tool into Void, feel free to get in touch! It's very easy to extend Void, and the UX you create will be much more natural than a VSCode Extension.
|
||||
|
||||
Most of Void's code lives in `src/vs/workbench/contrib/void/browser/` and `src/vs/platform/void/`.
|
||||
Void's code lives in `src/vs/workbench/contrib/void/browser/` and `src/vs/platform/void/`.
|
||||
|
||||
|
||||
|
||||
@@ -43,19 +43,19 @@ First, run `npm install -g node-gyp`. Then:
|
||||
|
||||
### Building Void
|
||||
|
||||
To build Void, open `void/` inside VSCode. Then:
|
||||
To build Void, open `void/` inside VSCode. Then open your terminal and run:
|
||||
|
||||
1. `npm install` to install all dependencies.
|
||||
2. `npm run watchreact` to build Void's browser dependencies like React.
|
||||
3. Build.
|
||||
3. Build Void.
|
||||
- Press <kbd>Cmd+Shift+B</kbd> (Mac).
|
||||
- Press <kbd>Ctrl+Shift+B</kbd> (Windows/Linux).
|
||||
- This step can take ~5 min. The build is done when you see two check marks.
|
||||
4. Run.
|
||||
4. Run Void.
|
||||
- Run `./scripts/code.sh` (Mac/Linux).
|
||||
- Run `./scripts/code.bat` (Windows).
|
||||
- This command should open up the built IDE. You can always press <kbd>Ctrl+R</kbd> (<kbd>Cmd+R</kbd>) inside the new window to see changes without re-building, or press or <kbd>Ctrl+Shift+P</kbd> in the new window and run "Reload Window".
|
||||
|
||||
- If you are actively developing Void, we strongly recommend adding the flags `--user-data-dir ./.tmp/user-data --extensions-dir ./.tmp/extensions` to the above run command (just append them at the end of the string). This will save all data and extensions to the `.tmp` folder. You can delete this folder to reset any IDE changes you made when testing.
|
||||
|
||||
#### Building Void from Terminal
|
||||
|
||||
@@ -75,6 +75,7 @@ Alternatively, if you want to build Void from the terminal, instead of pressing
|
||||
- Make sure you follow the prerequisite steps.
|
||||
- Make sure you have the same NodeJS version as `.nvmrc`.
|
||||
- Make sure your `npm run watchreact` is running if you change any React files, or else you'll need to re-build.
|
||||
- If you see missing styles, go to `src2/styles.css` and re-save the file.
|
||||
- If you get `"TypeError: Failed to fetch dynamically imported module: vscode-file://vscode-app/.../workbench.desktop.main.js", source: file:///.../bootstrap-window.js`, make sure all imports end with `.js`.
|
||||
- If you have any questions, feel free to [submit an issue](https://github.com/voideditor/void/issues/new). For building questions, you can also refer to VSCode's full [How to Contribute](https://github.com/microsoft/vscode/wiki/How-to-Contribute) page.
|
||||
|
||||
@@ -82,7 +83,16 @@ 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.
|
||||
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 outside of the void/ repo (see below). Be patient - compiling can take ~25 minutes.
|
||||
|
||||
```bash
|
||||
workspace/
|
||||
├── void/ # Your Void Fork
|
||||
├── VSCode-linux-x64/ # Build folder generated outside of void for Linux
|
||||
└── VSCode-darwin-arm64/ # Build folder generated outside of void for Mac
|
||||
|
||||
```
|
||||
|
||||
|
||||
### Mac
|
||||
- `npm run gulp vscode-darwin-arm64` - most common (Apple Silicon)
|
||||
|
||||
@@ -0,0 +1,26 @@
|
||||
Void is a fork of VS Code, which is licensed under the MIT License (below).
|
||||
Void's additions and modifications are licensed under the MIT License (see LICENSE.txt).
|
||||
|
||||
--------------------
|
||||
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2015 - present Microsoft Corporation
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
in the Software without restriction, including without limitation the rights
|
||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||
copies of the Software, and to permit persons to whom the Software is
|
||||
furnished to do so, subject to the following conditions:
|
||||
|
||||
The above copyright notice and this permission notice shall be included in all
|
||||
copies or substantial portions of the Software.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||
SOFTWARE.
|
||||
@@ -1,6 +1,6 @@
|
||||
MIT License
|
||||
|
||||
Copyright (c) 2015 - present Microsoft Corporation
|
||||
Copyright (c) 2025 Glass Devtools, Inc.
|
||||
|
||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||
of this software and associated documentation files (the "Software"), to deal
|
||||
|
||||
@@ -10,7 +10,8 @@ To build and run Void, follow the steps in [`CONTRIBUTING.md`](https://github.co
|
||||
|
||||
## Reference
|
||||
|
||||
Void is a fork of the of [vscode](https://github.com/microsoft/vscode) repository. For some useful links on VSCode, see [`VOID_USEFUL_LINKS.md`](https://github.com/voideditor/void/blob/main/VOID_USEFUL_LINKS.md).
|
||||
Void is a fork of the of [vscode](https://github.com/microsoft/vscode) repository.
|
||||
For some useful links on VSCode, see [`VOID_USEFUL_LINKS.md`](https://github.com/voideditor/void/blob/main/VOID_USEFUL_LINKS.md).
|
||||
|
||||
## Support
|
||||
Feel free to reach out in our [Discord](https://discord.gg/RSNjgaugJs) or contact us via email.
|
||||
Feel free to reach out in our [Discord](https://discord.gg/RSNjgaugJs) server or contact us via email.
|
||||
|
||||
@@ -1,41 +0,0 @@
|
||||
<!-- BEGIN MICROSOFT SECURITY.MD V0.0.9 BLOCK -->
|
||||
|
||||
## Security
|
||||
|
||||
Microsoft takes the security of our software products and services seriously, which includes all source code repositories managed through our GitHub organizations, which include [Microsoft](https://github.com/Microsoft), [Azure](https://github.com/Azure), [DotNet](https://github.com/dotnet), [AspNet](https://github.com/aspnet) and [Xamarin](https://github.com/xamarin).
|
||||
|
||||
If you believe you have found a security vulnerability in any Microsoft-owned repository that meets [Microsoft's definition of a security vulnerability](https://aka.ms/security.md/definition), please report it to us as described below.
|
||||
|
||||
## Reporting Security Issues
|
||||
|
||||
**Please do not report security vulnerabilities through public GitHub issues.**
|
||||
|
||||
Instead, please report them to the Microsoft Security Response Center (MSRC) at [https://msrc.microsoft.com/create-report](https://aka.ms/security.md/msrc/create-report).
|
||||
|
||||
If you prefer to submit without logging in, send email to [secure@microsoft.com](mailto:secure@microsoft.com). If possible, encrypt your message with our PGP key; please download it from the [Microsoft Security Response Center PGP Key page](https://aka.ms/security.md/msrc/pgp).
|
||||
|
||||
You should receive a response within 24 hours. If for some reason you do not, please follow up via email to ensure we received your original message. Additional information can be found at [microsoft.com/msrc](https://www.microsoft.com/msrc).
|
||||
|
||||
Please include the requested information listed below (as much as you can provide) to help us better understand the nature and scope of the possible issue:
|
||||
|
||||
* Type of issue (e.g. buffer overflow, SQL injection, cross-site scripting, etc.)
|
||||
* Full paths of source file(s) related to the manifestation of the issue
|
||||
* The location of the affected source code (tag/branch/commit or direct URL)
|
||||
* Any special configuration required to reproduce the issue
|
||||
* Step-by-step instructions to reproduce the issue
|
||||
* Proof-of-concept or exploit code (if possible)
|
||||
* Impact of the issue, including how an attacker might exploit the issue
|
||||
|
||||
This information will help us triage your report more quickly.
|
||||
|
||||
If you are reporting for a bug bounty, more complete reports can contribute to a higher bounty award. Please visit our [Microsoft Bug Bounty Program](https://aka.ms/security.md/msrc/bounty) page for more details about our active programs.
|
||||
|
||||
## Preferred Languages
|
||||
|
||||
We prefer all communications to be in English.
|
||||
|
||||
## Policy
|
||||
|
||||
Microsoft follows the principle of [Coordinated Vulnerability Disclosure](https://aka.ms/security.md/cvd).
|
||||
|
||||
<!-- END MICROSOFT SECURITY.MD BLOCK -->
|
||||
@@ -32,6 +32,6 @@ Void is no longer an extension, so these links are no longer required, but they
|
||||
|
||||
- [The Full VSCode Extension API](https://code.visualstudio.com/api/references/vscode-api) - look on the right side for organization. The [bottom](https://code.visualstudio.com/api/references/vscode-api#api-patterns) of the page is easy to miss but is useful - cancellation tokens, events, disposables.
|
||||
|
||||
- [Activation events](https://code.visualstudio.com/api/references/activation-events) you can define in `package.json` (not the most useful)
|
||||
- [Activation events](https://code.visualstudio.com/api/references/activation-events) you can define in `package.json` (not the most useful).
|
||||
|
||||
|
||||
|
||||
@@ -425,15 +425,15 @@ function packageTask(platform, arch, sourceFolderName, destinationFolderName, op
|
||||
'resources/win32/vue.ico',
|
||||
'resources/win32/xml.ico',
|
||||
'resources/win32/yaml.ico',
|
||||
'resources/win32/code_70x70.png',
|
||||
'resources/win32/code_150x150.png'
|
||||
'resources/win32/code_70x70.png', // <-- Void icon
|
||||
'resources/win32/code_150x150.png' // <-- Void icon
|
||||
], { base: '.' }));
|
||||
} else if (platform === 'linux') {
|
||||
all = es.merge(all, gulp.src('resources/linux/code.png', { base: '.' }));
|
||||
all = es.merge(all, gulp.src('resources/linux/code.png', { base: '.' })); // <-- Void icon
|
||||
} else if (platform === 'darwin') {
|
||||
const shortcut = gulp.src('resources/darwin/bin/code.sh')
|
||||
.pipe(replace('@@APPNAME@@', product.applicationName))
|
||||
.pipe(rename('bin/code'));
|
||||
.pipe(rename('bin/code')); // <-- Void icon
|
||||
|
||||
all = es.merge(all, shortcut);
|
||||
}
|
||||
|
||||
@@ -54,7 +54,7 @@ function darwinBundleDocumentType(extensions, icon, nameOrSuffix, utis) {
|
||||
role: 'Editor',
|
||||
ostypes: ['TEXT', 'utxt', 'TUTX', '****'],
|
||||
extensions,
|
||||
iconFile: 'resources/darwin/' + icon.toLowerCase() + '.icns',
|
||||
iconFile: 'resources/darwin/' + icon.toLowerCase() + '.icns', // <-- Void icon code.icns
|
||||
utis
|
||||
};
|
||||
}
|
||||
@@ -179,7 +179,7 @@ exports.config = {
|
||||
darwinForceDarkModeSupport: true,
|
||||
darwinCredits: darwinCreditsTemplate ? Buffer.from(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : undefined,
|
||||
linuxExecutableName: product.applicationName,
|
||||
winIcon: 'resources/win32/code.ico',
|
||||
winIcon: 'resources/win32/code.ico', // <-- Void icon
|
||||
token: process.env['GITHUB_TOKEN'],
|
||||
repo: product.electronRepository || undefined,
|
||||
validateChecksum: true,
|
||||
|
||||
@@ -68,7 +68,7 @@ function darwinBundleDocumentType(extensions: string[], icon: string, nameOrSuff
|
||||
role: 'Editor',
|
||||
ostypes: ['TEXT', 'utxt', 'TUTX', '****'],
|
||||
extensions,
|
||||
iconFile: 'resources/darwin/' + icon.toLowerCase() + '.icns',
|
||||
iconFile: 'resources/darwin/' + icon.toLowerCase() + '.icns', // <-- Void icon code.icns
|
||||
utis
|
||||
};
|
||||
}
|
||||
@@ -196,7 +196,7 @@ export const config = {
|
||||
darwinForceDarkModeSupport: true,
|
||||
darwinCredits: darwinCreditsTemplate ? Buffer.from(darwinCreditsTemplate({ commit: commit, date: new Date().toISOString() })) : undefined,
|
||||
linuxExecutableName: product.applicationName,
|
||||
winIcon: 'resources/win32/code.ico',
|
||||
winIcon: 'resources/win32/code.ico', // <-- Void icon
|
||||
token: process.env['GITHUB_TOKEN'],
|
||||
repo: product.electronRepository || undefined,
|
||||
validateChecksum: true,
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
? ('; LicenseFile: "' + RepoDir + '\licenses\LICENSE-' + Language + '.rtf"') \
|
||||
: '; LicenseFile: "' + RepoDir + '\' + RootLicenseFileName + '"'
|
||||
|
||||
|
||||
[Setup]
|
||||
AppId={#AppId}
|
||||
AppName={#NameLong}
|
||||
@@ -20,8 +21,10 @@ Compression=lzma
|
||||
SolidCompression=yes
|
||||
AppMutex={code:GetAppMutex}
|
||||
SetupMutex={#AppMutex}setup
|
||||
WizardImageFile="{#RepoDir}\resources\win32\inno-big-100.bmp,{#RepoDir}\resources\win32\inno-big-125.bmp,{#RepoDir}\resources\win32\inno-big-150.bmp,{#RepoDir}\resources\win32\inno-big-175.bmp,{#RepoDir}\resources\win32\inno-big-200.bmp,{#RepoDir}\resources\win32\inno-big-225.bmp,{#RepoDir}\resources\win32\inno-big-250.bmp"
|
||||
WizardSmallImageFile="{#RepoDir}\resources\win32\inno-small-100.bmp,{#RepoDir}\resources\win32\inno-small-125.bmp,{#RepoDir}\resources\win32\inno-small-150.bmp,{#RepoDir}\resources\win32\inno-small-175.bmp,{#RepoDir}\resources\win32\inno-small-200.bmp,{#RepoDir}\resources\win32\inno-small-225.bmp,{#RepoDir}\resources\win32\inno-small-250.bmp"
|
||||
; this is a Void icon comment. Old: WizardImageFile="{#RepoDir}\resources\win32\inno-big-100.bmp,{#RepoDir}\resources\win32\inno-big-125.bmp,{#RepoDir}\resources\win32\inno-big-150.bmp,{#RepoDir}\resources\win32\inno-big-175.bmp,{#RepoDir}\resources\win32\inno-big-200.bmp,{#RepoDir}\resources\win32\inno-big-225.bmp,{#RepoDir}\resources\win32\inno-big-250.bmp"
|
||||
; this is a Void icon comment. Old: WizardSmallImageFile="{#RepoDir}\resources\win32\inno-small-100.bmp,{#RepoDir}\resources\win32\inno-small-125.bmp,{#RepoDir}\resources\win32\inno-small-150.bmp,{#RepoDir}\resources\win32\inno-small-175.bmp,{#RepoDir}\resources\win32\inno-small-200.bmp,{#RepoDir}\resources\win32\inno-small-225.bmp,{#RepoDir}\resources\win32\inno-small-250.bmp"
|
||||
WizardImageFile="{#RepoDir}\resources\win32\inno-void.bmp"
|
||||
WizardSmallImageFile="{#RepoDir}\resources\win32\inno-void.bmp"
|
||||
SetupIconFile={#RepoDir}\resources\win32\code.ico
|
||||
UninstallDisplayIcon={app}\{#ExeBasename}.exe
|
||||
ChangesEnvironment=true
|
||||
|
||||
@@ -1,11 +1,11 @@
|
||||
{
|
||||
"name": "code-oss-dev",
|
||||
"name": "void-dev",
|
||||
"version": "1.94.0",
|
||||
"lockfileVersion": 3,
|
||||
"requires": true,
|
||||
"packages": {
|
||||
"": {
|
||||
"name": "code-oss-dev",
|
||||
"name": "void-dev",
|
||||
"version": "1.94.0",
|
||||
"hasInstallScript": true,
|
||||
"license": "MIT",
|
||||
@@ -17,6 +17,7 @@
|
||||
"@parcel/watcher": "2.1.0",
|
||||
"@rrweb/record": "^2.0.0-alpha.17",
|
||||
"@rrweb/types": "^2.0.0-alpha.17",
|
||||
"@todesktop/runtime": "^2.0.0",
|
||||
"@vscode/deviceid": "^0.1.1",
|
||||
"@vscode/iconv-lite-umd": "0.7.0",
|
||||
"@vscode/policy-watcher": "^1.1.4",
|
||||
@@ -1978,7 +1979,6 @@
|
||||
"version": "2.1.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.scandir/-/fs.scandir-2.1.5.tgz",
|
||||
"integrity": "sha512-vq24Bq3ym5HEQm2NKCr3yXDwjc7vTsEThRDnkp2DK9p1uqLR+DHurm/NOTo0KG7HYHU7eppKZj3MyqYuMBf62g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "2.0.5",
|
||||
"run-parallel": "^1.1.9"
|
||||
@@ -1991,7 +1991,6 @@
|
||||
"version": "2.0.5",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.stat/-/fs.stat-2.0.5.tgz",
|
||||
"integrity": "sha512-RkhPPp2zrqDAQA/2jNhnztcPAlv64XdhIp7a7454A5ovI7Bukxgt7MX7udwAu3zg1DcpPU0rz3VV1SeaqvY4+A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
@@ -2000,7 +1999,6 @@
|
||||
"version": "1.2.8",
|
||||
"resolved": "https://registry.npmjs.org/@nodelib/fs.walk/-/fs.walk-1.2.8.tgz",
|
||||
"integrity": "sha512-oGB+UxlgWcgQkgwo8GcEGwemoTFt3FIO9ababBmaGwXIoBKZ+GTy0pP185beGg7Llih/NSHSV2XAs1lnznocSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@nodelib/fs.scandir": "2.1.5",
|
||||
"fastq": "^1.6.0"
|
||||
@@ -2723,6 +2721,20 @@
|
||||
"node": ">=10"
|
||||
}
|
||||
},
|
||||
"node_modules/@todesktop/runtime": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@todesktop/runtime/-/runtime-2.0.0.tgz",
|
||||
"integrity": "sha512-0a2tmWpIc/HJE/873xRMZKQNggfrYhoKYIchfN+k8RqKdzTPwTWa5ztur7GdCHLHBUaiMBPNRzF3h4kwHd1NCw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"del": "^6.1.1",
|
||||
"electron-updater": "^6.3.9",
|
||||
"eventemitter2": "^6.4.9",
|
||||
"execa": "^5.0.0",
|
||||
"lodash.once": "^4.1.1",
|
||||
"semver": "^7.6.3"
|
||||
}
|
||||
},
|
||||
"node_modules/@tootallnate/once": {
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/@tootallnate/once/-/once-3.0.0.tgz",
|
||||
@@ -4504,6 +4516,19 @@
|
||||
"node": ">= 8.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/aggregate-error": {
|
||||
"version": "3.1.0",
|
||||
"resolved": "https://registry.npmjs.org/aggregate-error/-/aggregate-error-3.1.0.tgz",
|
||||
"integrity": "sha512-4I7Td01quW/RpocfNayFdFVk1qSuoh0E7JrbRJ16nH01HhKFQ88INq9Sd+nd72zqRySlr9BmDA8xlEJ6vJMrYA==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"clean-stack": "^2.0.0",
|
||||
"indent-string": "^4.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/ajv": {
|
||||
"version": "8.17.1",
|
||||
"resolved": "https://registry.npmjs.org/ajv/-/ajv-8.17.1.tgz",
|
||||
@@ -4700,8 +4725,7 @@
|
||||
"node_modules/argparse": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/argparse/-/argparse-2.0.1.tgz",
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q==",
|
||||
"dev": true
|
||||
"integrity": "sha512-8+9WqebbFzpX9OR+Wa6O29asIogeRMzcGtAINdpMHHyAg10f05aSFVBbcEqGf/PXw1EjAZ+q2/bEBg3DvurK3Q=="
|
||||
},
|
||||
"node_modules/arr-diff": {
|
||||
"version": "4.0.0",
|
||||
@@ -4867,7 +4891,6 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/array-union/-/array-union-2.1.0.tgz",
|
||||
"integrity": "sha512-HGyxoOTYUyCM6stUe6EJgnd4EoewAI7zMdfqO+kGjnlZmBDz/cR5pf8r/cR4Wq60sL/p0IkcjUEEPwS3GFrIyw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -5137,8 +5160,7 @@
|
||||
"node_modules/balanced-match": {
|
||||
"version": "1.0.2",
|
||||
"resolved": "https://registry.npmjs.org/balanced-match/-/balanced-match-1.0.2.tgz",
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-3oSeUO0TMV67hN1AmbXsK4yaqU7tjiHlbxRDZOpH0KW9+CeX4bRAaX0Anxt0tx2MrpRpWwQaPwIlISEJhYU5Pw=="
|
||||
},
|
||||
"node_modules/bare-events": {
|
||||
"version": "2.5.0",
|
||||
@@ -5342,7 +5364,6 @@
|
||||
"version": "1.1.11",
|
||||
"resolved": "https://registry.npmjs.org/brace-expansion/-/brace-expansion-1.1.11.tgz",
|
||||
"integrity": "sha512-iCuPHDFgrHX7H2vEI/5xpz07zSHB00TpugqhmYtVmMO6518mCuRMoOYFldEBl0g187ufozdaHgWKcYFb61qGiA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"balanced-match": "^1.0.0",
|
||||
"concat-map": "0.0.1"
|
||||
@@ -5455,6 +5476,19 @@
|
||||
"integrity": "sha512-E+XQCRwSbaaiChtv6k6Dwgc+bx+Bs6vuKJHHl5kox/BaKbhiXzqQOwK4cO22yElGp2OCmjwVhT3HmxgyPGnJfQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/builder-util-runtime": {
|
||||
"version": "9.2.10",
|
||||
"resolved": "https://registry.npmjs.org/builder-util-runtime/-/builder-util-runtime-9.2.10.tgz",
|
||||
"integrity": "sha512-6p/gfG1RJSQeIbz8TK5aPNkoztgY1q5TgmGFMAXcY8itsGW6Y2ld1ALsZ5UJn8rog7hKF3zHx5iQbNQ8uLcRlw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"debug": "^4.3.4",
|
||||
"sax": "^1.2.4"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12.0.0"
|
||||
}
|
||||
},
|
||||
"node_modules/builtin-modules": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/builtin-modules/-/builtin-modules-3.3.0.tgz",
|
||||
@@ -5874,6 +5908,15 @@
|
||||
"node": ">= 0.4"
|
||||
}
|
||||
},
|
||||
"node_modules/clean-stack": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/clean-stack/-/clean-stack-2.2.0.tgz",
|
||||
"integrity": "sha512-4diC9HaTE+KRAMWhDhrGOECgWZxoevMc5TlkObMqNSsVU62PYzXZ/SMTjzyGAFF1YusgxGcSWTEXBhp0CPwQ1A==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/cli-cursor": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/cli-cursor/-/cli-cursor-4.0.0.tgz",
|
||||
@@ -6215,8 +6258,7 @@
|
||||
"node_modules/concat-map": {
|
||||
"version": "0.0.1",
|
||||
"resolved": "https://registry.npmjs.org/concat-map/-/concat-map-0.0.1.tgz",
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-/Srv4dswyQNBfohGpz9o6Yb3Gz3SrUDqBH5rTuhGR7ahtlbYKnVxw2bCFMRljaA7EXHaXZ8wsHdodFvbkhKmqg=="
|
||||
},
|
||||
"node_modules/concat-stream": {
|
||||
"version": "1.6.2",
|
||||
@@ -6448,7 +6490,6 @@
|
||||
"version": "7.0.6",
|
||||
"resolved": "https://registry.npmjs.org/cross-spawn/-/cross-spawn-7.0.6.tgz",
|
||||
"integrity": "sha512-uV2QOWP2nWzsy2aMp8aRibhi9dlzF5Hgh5SHaB9OiTGEyDTiJJyx0uy51QXdyWbtAHNua4XJzUKca3OzKUd3vA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"path-key": "^3.1.0",
|
||||
"shebang-command": "^2.0.0",
|
||||
@@ -6963,6 +7004,80 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/del": {
|
||||
"version": "6.1.1",
|
||||
"resolved": "https://registry.npmjs.org/del/-/del-6.1.1.tgz",
|
||||
"integrity": "sha512-ua8BhapfP0JUJKC/zV9yHHDW/rDoDxP4Zhn3AkA6/xT6gY7jYXJiaeyBZznYVujhZZET+UgcbZiQ7sN3WqcImg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"globby": "^11.0.1",
|
||||
"graceful-fs": "^4.2.4",
|
||||
"is-glob": "^4.0.1",
|
||||
"is-path-cwd": "^2.2.0",
|
||||
"is-path-inside": "^3.0.2",
|
||||
"p-map": "^4.0.0",
|
||||
"rimraf": "^3.0.2",
|
||||
"slash": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/del/node_modules/glob": {
|
||||
"version": "7.2.3",
|
||||
"resolved": "https://registry.npmjs.org/glob/-/glob-7.2.3.tgz",
|
||||
"integrity": "sha512-nFR0zLpU2YCaRxwoCJvL6UvCH2JFyFVIvwTLsIf21AuHlMskA1hhTdk+LlYJtOlYt9v6dvszD2BGRqBL+iQK9Q==",
|
||||
"deprecated": "Glob versions prior to v9 are no longer supported",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"fs.realpath": "^1.0.0",
|
||||
"inflight": "^1.0.4",
|
||||
"inherits": "2",
|
||||
"minimatch": "^3.1.1",
|
||||
"once": "^1.3.0",
|
||||
"path-is-absolute": "^1.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": "*"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/del/node_modules/p-map": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/p-map/-/p-map-4.0.0.tgz",
|
||||
"integrity": "sha512-/bjOqmgETBYB5BoEeGVea8dmvHb2m9GLy1E9W43yeyfP6QQCZGFNa+XRceJEuDB6zqr+gKpIAmlLebMpykw/MQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"aggregate-error": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/del/node_modules/rimraf": {
|
||||
"version": "3.0.2",
|
||||
"resolved": "https://registry.npmjs.org/rimraf/-/rimraf-3.0.2.tgz",
|
||||
"integrity": "sha512-JZkJMZkAGFFPP2YqXZXPbMlMBgsxzE8ILs4lMIX/2o0L9UBw9O/Y3o6wFw/i9YLapcUJWwqbi3kdxIPdC62TIA==",
|
||||
"deprecated": "Rimraf versions prior to v4 are no longer supported",
|
||||
"license": "ISC",
|
||||
"dependencies": {
|
||||
"glob": "^7.1.3"
|
||||
},
|
||||
"bin": {
|
||||
"rimraf": "bin.js"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/isaacs"
|
||||
}
|
||||
},
|
||||
"node_modules/delayed-stream": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/delayed-stream/-/delayed-stream-1.0.0.tgz",
|
||||
@@ -7062,7 +7177,6 @@
|
||||
"version": "3.0.1",
|
||||
"resolved": "https://registry.npmjs.org/dir-glob/-/dir-glob-3.0.1.tgz",
|
||||
"integrity": "sha512-WkrWp9GR4KXfKGYzOLmTuGVi1UWFfws377n9cc55/tb6DuqyF6pcQ5AbiHEshaDpY9v6oaSr2XCDidGmMwdzIA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"path-type": "^4.0.0"
|
||||
},
|
||||
@@ -7320,6 +7434,36 @@
|
||||
"integrity": "sha512-ck3//9RC+6oss/1Bh9tiAVFy5vfSKbRHAFh7Z3/eTRkEqJeWgymloShB17Vg3Z4nmDNp35vAd1BZ6CMW4Wt6Iw==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/electron-updater": {
|
||||
"version": "6.3.9",
|
||||
"resolved": "https://registry.npmjs.org/electron-updater/-/electron-updater-6.3.9.tgz",
|
||||
"integrity": "sha512-2PJNONi+iBidkoC5D1nzT9XqsE8Q1X28Fn6xRQhO3YX8qRRyJ3mkV4F1aQsuRnYPqq6Hw+E51y27W75WgDoofw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"builder-util-runtime": "9.2.10",
|
||||
"fs-extra": "^10.1.0",
|
||||
"js-yaml": "^4.1.0",
|
||||
"lazy-val": "^1.0.5",
|
||||
"lodash.escaperegexp": "^4.1.2",
|
||||
"lodash.isequal": "^4.5.0",
|
||||
"semver": "^7.6.3",
|
||||
"tiny-typed-emitter": "^2.1.0"
|
||||
}
|
||||
},
|
||||
"node_modules/electron-updater/node_modules/fs-extra": {
|
||||
"version": "10.1.0",
|
||||
"resolved": "https://registry.npmjs.org/fs-extra/-/fs-extra-10.1.0.tgz",
|
||||
"integrity": "sha512-oRXApq54ETRj4eMiFzGnHWGy+zo5raudjuxN0b8H7s/RU2oW0Wvsx9O0ACRN/kRq9E8Vu/ReskGB5o3ji+FzHQ==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"graceful-fs": "^4.2.0",
|
||||
"jsonfile": "^6.0.1",
|
||||
"universalify": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=12"
|
||||
}
|
||||
},
|
||||
"node_modules/emoji-regex": {
|
||||
"version": "10.4.0",
|
||||
"resolved": "https://registry.npmjs.org/emoji-regex/-/emoji-regex-10.4.0.tgz",
|
||||
@@ -7974,6 +8118,12 @@
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/eventemitter2": {
|
||||
"version": "6.4.9",
|
||||
"resolved": "https://registry.npmjs.org/eventemitter2/-/eventemitter2-6.4.9.tgz",
|
||||
"integrity": "sha512-JEPTiaOt9f04oa6NOkc4aH+nVp5I3wEjpHbIPqfgCdD5v5bUzy7xQqwcVO2aDQgOWhI28da57HksMrzK9HlRxg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/events": {
|
||||
"version": "3.3.0",
|
||||
"resolved": "https://registry.npmjs.org/events/-/events-3.3.0.tgz",
|
||||
@@ -7983,6 +8133,59 @@
|
||||
"node": ">=0.8.x"
|
||||
}
|
||||
},
|
||||
"node_modules/execa": {
|
||||
"version": "5.1.1",
|
||||
"resolved": "https://registry.npmjs.org/execa/-/execa-5.1.1.tgz",
|
||||
"integrity": "sha512-8uSpZZocAZRBAPIEINJj3Lo9HyGitllczc27Eh5YYojjMFMn8yHMDMaUHE2Jqfq05D/wucwI4JGURyXt1vchyg==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"cross-spawn": "^7.0.3",
|
||||
"get-stream": "^6.0.0",
|
||||
"human-signals": "^2.1.0",
|
||||
"is-stream": "^2.0.0",
|
||||
"merge-stream": "^2.0.0",
|
||||
"npm-run-path": "^4.0.1",
|
||||
"onetime": "^5.1.2",
|
||||
"signal-exit": "^3.0.3",
|
||||
"strip-final-newline": "^2.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sindresorhus/execa?sponsor=1"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/get-stream": {
|
||||
"version": "6.0.1",
|
||||
"resolved": "https://registry.npmjs.org/get-stream/-/get-stream-6.0.1.tgz",
|
||||
"integrity": "sha512-ts6Wi+2j3jQjqi70w5AlN8DFnkSwC+MqmxEzdEALB2qXZYV3X/b1CTfgPLGJNMeAWxdPfU8FO1ms3NUfaHCPYg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=10"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/is-stream": {
|
||||
"version": "2.0.1",
|
||||
"resolved": "https://registry.npmjs.org/is-stream/-/is-stream-2.0.1.tgz",
|
||||
"integrity": "sha512-hFoiJiTl63nn+kstHGBtewWSKnQLpyb155KHheA1l39uvtO9nWIop1p3udqPcUd/xbF1VLMO4n7OI6p7RbngDg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
},
|
||||
"funding": {
|
||||
"url": "https://github.com/sponsors/sindresorhus"
|
||||
}
|
||||
},
|
||||
"node_modules/execa/node_modules/signal-exit": {
|
||||
"version": "3.0.7",
|
||||
"resolved": "https://registry.npmjs.org/signal-exit/-/signal-exit-3.0.7.tgz",
|
||||
"integrity": "sha512-wnD2ZE+l+SPC/uoS0vXeE9L1+0wuaMqKlfz9AMUo38JsyLSBWSFcHR1Rri62LZc12vLr1gb3jl7iwQhgwpAbGQ==",
|
||||
"license": "ISC"
|
||||
},
|
||||
"node_modules/exenv-es6": {
|
||||
"version": "1.1.1",
|
||||
"resolved": "https://registry.npmjs.org/exenv-es6/-/exenv-es6-1.1.1.tgz",
|
||||
@@ -8241,7 +8444,6 @@
|
||||
"version": "3.3.2",
|
||||
"resolved": "https://registry.npmjs.org/fast-glob/-/fast-glob-3.3.2.tgz",
|
||||
"integrity": "sha512-oX2ruAFQwf/Orj8m737Y5adxDQO0LAB7/S5MnxCdTNDd4p6BsyIVsv9JQsATbTSq8KHRpLwIHbVlUNatxd+1Ow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"@nodelib/fs.stat": "^2.0.2",
|
||||
"@nodelib/fs.walk": "^1.2.3",
|
||||
@@ -8306,7 +8508,6 @@
|
||||
"version": "1.17.1",
|
||||
"resolved": "https://registry.npmjs.org/fastq/-/fastq-1.17.1.tgz",
|
||||
"integrity": "sha512-sRVD3lWVIXWg6By68ZN7vho9a1pQcN/WBFaAAsDDFzlJjvoGx0P8z7V1t72grFJfJhu3YPZBuu25f7Kaw2jN1w==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"reusify": "^1.0.4"
|
||||
}
|
||||
@@ -9052,8 +9253,7 @@
|
||||
"node_modules/fs.realpath": {
|
||||
"version": "1.0.0",
|
||||
"resolved": "https://registry.npmjs.org/fs.realpath/-/fs.realpath-1.0.0.tgz",
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-OO0pH2lK6a0hZnAdau5ItzHPI6pUlvI7jMVnxUQRtw4owF2wk8lOSabtGDCTP4Ggrg2MbGnWO9X8K1t4+fGMDw=="
|
||||
},
|
||||
"node_modules/fsevents": {
|
||||
"version": "2.3.3",
|
||||
@@ -9256,7 +9456,6 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/glob-parent/-/glob-parent-5.1.2.tgz",
|
||||
"integrity": "sha512-AOIgSQCepiJYwP3ARnGx+5VnTu2HBYdzbGP45eLw1vr3zB3vZLeyed1sC9hnbcOc9/SrMyM5RPQrkGz4aS9Zow==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"is-glob": "^4.0.1"
|
||||
},
|
||||
@@ -9778,7 +9977,6 @@
|
||||
"version": "11.1.0",
|
||||
"resolved": "https://registry.npmjs.org/globby/-/globby-11.1.0.tgz",
|
||||
"integrity": "sha512-jhIXaOzy1sb8IyocaruWSn1TjmnBVs8Ayhcy83rmxNJ8q2uWKCAj3CnJY+KpGSXCueAPc0i05kVvVKtP1t9S3g==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"array-union": "^2.1.0",
|
||||
"dir-glob": "^3.0.1",
|
||||
@@ -12373,6 +12571,15 @@
|
||||
"node": ">= 14"
|
||||
}
|
||||
},
|
||||
"node_modules/human-signals": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/human-signals/-/human-signals-2.1.0.tgz",
|
||||
"integrity": "sha512-B4FFZ6q/T2jhhksgkbEW3HBvWIfDW85snkQgawt07S7J5QXTk6BkNV+0yAeZrM5QpMAdYlocGoljn0sJ/WQkFw==",
|
||||
"license": "Apache-2.0",
|
||||
"engines": {
|
||||
"node": ">=10.17.0"
|
||||
}
|
||||
},
|
||||
"node_modules/humanize-ms": {
|
||||
"version": "1.2.1",
|
||||
"resolved": "https://registry.npmjs.org/humanize-ms/-/humanize-ms-1.2.1.tgz",
|
||||
@@ -12514,7 +12721,6 @@
|
||||
"version": "5.3.2",
|
||||
"resolved": "https://registry.npmjs.org/ignore/-/ignore-5.3.2.tgz",
|
||||
"integrity": "sha512-hsBTNUqQTDwkWtcdYI2i06Y/nUBEsNEDJKjWdigLvegy8kDuJAS8uRlpkkcQpyEXL0Z/pjDy5HBmMjRCJ2gq+g==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 4"
|
||||
}
|
||||
@@ -12575,12 +12781,20 @@
|
||||
"node": ">=0.8.19"
|
||||
}
|
||||
},
|
||||
"node_modules/indent-string": {
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/indent-string/-/indent-string-4.0.0.tgz",
|
||||
"integrity": "sha512-EdDDZu4A2OyIK7Lr/2zG+w5jmbuk1DVBnEwREQvBzspBJkCEbRa8GxU1lghYcaGJCnRWibjDXlq779X1/y5xwg==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/inflight": {
|
||||
"version": "1.0.6",
|
||||
"resolved": "https://registry.npmjs.org/inflight/-/inflight-1.0.6.tgz",
|
||||
"integrity": "sha512-k92I/b08q4wvFscXCLvqfsHCrjrF7yiXsQuIVvVE7N82W3+aqpzuUdBbfhWcy/FZR3/4IgflMgKLOsvPDrGCJA==",
|
||||
"deprecated": "This module is not supported, and leaks memory. Do not use it. Check out lru-cache if you want a good and tested way to coalesce async requests by a key value, which is much more comprehensive and powerful.",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"once": "^1.3.0",
|
||||
"wrappy": "1"
|
||||
@@ -13323,11 +13537,19 @@
|
||||
"url": "https://github.com/sponsors/ljharb"
|
||||
}
|
||||
},
|
||||
"node_modules/is-path-cwd": {
|
||||
"version": "2.2.0",
|
||||
"resolved": "https://registry.npmjs.org/is-path-cwd/-/is-path-cwd-2.2.0.tgz",
|
||||
"integrity": "sha512-w942bTcih8fdJPJmQHFzkS76NEP8Kzzvmw92cXsazb8intwLqPibPPdXf4ANdKV3rYMuuQYGIWtvz9JilB3NFQ==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/is-path-inside": {
|
||||
"version": "3.0.3",
|
||||
"resolved": "https://registry.npmjs.org/is-path-inside/-/is-path-inside-3.0.3.tgz",
|
||||
"integrity": "sha512-Fd4gABb+ycGAmKou8eMftCupSir5lRxqf4aD/vd0cD2qc4HL07OjCeuHMr8Ro4CoMaeCKDB0/ECBOVWjTwUvPQ==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -13581,8 +13803,7 @@
|
||||
"node_modules/isexe": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/isexe/-/isexe-2.0.0.tgz",
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw==",
|
||||
"dev": true
|
||||
"integrity": "sha512-RHxMLp9lnKHGHRng9QFhRCMbYAcVpn69smSGcq3f36xjgVVWThj4qqLbTLlq7Ssj8B+fIQ1EuCEGI2lKsyQeIw=="
|
||||
},
|
||||
"node_modules/isobject": {
|
||||
"version": "3.0.1",
|
||||
@@ -13853,7 +14074,6 @@
|
||||
"version": "4.1.0",
|
||||
"resolved": "https://registry.npmjs.org/js-yaml/-/js-yaml-4.1.0.tgz",
|
||||
"integrity": "sha512-wpxZs9NoxZaJESJGIZTyDEaYpl0FKSA+FB9aJiyemKhMwkxQg63h4T1KJgUGHpTqPDNRcmmYLugrRjJlBtWvRA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"argparse": "^2.0.1"
|
||||
},
|
||||
@@ -14262,6 +14482,12 @@
|
||||
"node": ">= 0.10"
|
||||
}
|
||||
},
|
||||
"node_modules/lazy-val": {
|
||||
"version": "1.0.5",
|
||||
"resolved": "https://registry.npmjs.org/lazy-val/-/lazy-val-1.0.5.tgz",
|
||||
"integrity": "sha512-0/BnGCCfyUMkBpeDgWihanIAF9JmZhHBgUhEqzvf+adhNGLoP6TaiI5oF8oyb3I45P+PcnrqihSf01M0l0G5+Q==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lazy.js": {
|
||||
"version": "0.4.3",
|
||||
"resolved": "https://registry.npmjs.org/lazy.js/-/lazy.js-0.4.3.tgz",
|
||||
@@ -14506,12 +14732,24 @@
|
||||
"integrity": "sha512-H5ZhCF25riFd9uB5UCkVKo61m3S/xZk1x4wA6yp/L3RFP6Z/eHH1ymQcGLo7J3GMPfm0V/7m1tryHuGVxpqEBQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.escaperegexp": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.escaperegexp/-/lodash.escaperegexp-4.1.2.tgz",
|
||||
"integrity": "sha512-TM9YBvyC84ZxE3rgfefxUWiQKLilstD6k7PTGt6wfbtXF8ixIJLOL3VYyV/z+ZiPLsVxAsKAFVwWlWeb2Y8Yyw==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.get": {
|
||||
"version": "4.4.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.get/-/lodash.get-4.4.2.tgz",
|
||||
"integrity": "sha512-z+Uw/vLuy6gQe8cfaFWD7p0wVv8fJl3mbzXh33RS+0oW2wvUqiRXiQ69gLWSLpgB5/6sU+r6BlQR0MBILadqTQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.isequal": {
|
||||
"version": "4.5.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.isequal/-/lodash.isequal-4.5.0.tgz",
|
||||
"integrity": "sha512-pDo3lu8Jhfjqls6GkMgpahsF9kCyayhgykjyLMNFTKWrpVdAQtYyB4muAMWozBB4ig/dtWAmsMxLEI8wuz+DYQ==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.memoize": {
|
||||
"version": "4.1.2",
|
||||
"resolved": "https://registry.npmjs.org/lodash.memoize/-/lodash.memoize-4.1.2.tgz",
|
||||
@@ -14524,6 +14762,12 @@
|
||||
"integrity": "sha512-0KpjqXRVvrYyCsX1swR/XTK0va6VQkQM6MNo7PqW77ByjAhoARA8EfrP1N4+KlKj8YS0ZUCtRT/YUuhyYDujIQ==",
|
||||
"dev": true
|
||||
},
|
||||
"node_modules/lodash.once": {
|
||||
"version": "4.1.1",
|
||||
"resolved": "https://registry.npmjs.org/lodash.once/-/lodash.once-4.1.1.tgz",
|
||||
"integrity": "sha512-Sb487aTOCr9drQVL8pIxOzVhafOjZN9UU54hiN8PU3uAiSV7lx1yYNpbNmex2PK6dSJoNTSJUUswT651yww3Mg==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/lodash.some": {
|
||||
"version": "4.6.0",
|
||||
"resolved": "https://registry.npmjs.org/lodash.some/-/lodash.some-4.6.0.tgz",
|
||||
@@ -15042,14 +15286,12 @@
|
||||
"node_modules/merge-stream": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/merge-stream/-/merge-stream-2.0.0.tgz",
|
||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w==",
|
||||
"dev": true
|
||||
"integrity": "sha512-abv/qOcuPfk3URPfDzmZU1LKmuw8kT+0nIHvKrKgFrwifol/doWcdA4ZqsWQ8ENrFKkd67Mfpo/LovbIUsbt3w=="
|
||||
},
|
||||
"node_modules/merge2": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/merge2/-/merge2-1.4.1.tgz",
|
||||
"integrity": "sha512-8q7VEgMJW4J8tcfVPy8g09NcQwZdbwFEqhe/WZkoIzjn/3TGDwtOCYtXGxA3O8tPzpczCCDgv+P2P5y00ZJOOg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">= 8"
|
||||
}
|
||||
@@ -15101,7 +15343,6 @@
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/mimic-fn/-/mimic-fn-2.1.0.tgz",
|
||||
"integrity": "sha512-OqbOk5oEQeAZ8WXWydlu9HJjz9WVdEIvamMCcXmuqUYjTknH/sqsWvhQ3vgwKFRR1HpjvNBKQ37nbJgYzGqGcg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
@@ -15119,7 +15360,6 @@
|
||||
"version": "3.1.2",
|
||||
"resolved": "https://registry.npmjs.org/minimatch/-/minimatch-3.1.2.tgz",
|
||||
"integrity": "sha512-J7p63hRiAjw1NDEww1W7i37+ByIrOWO5XQQAzZ3VOcL0PNybwpfmV/N05zFAzwQ9USyEcX6t3UO+K5aqBQOIHw==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"brace-expansion": "^1.1.7"
|
||||
},
|
||||
@@ -16058,6 +16298,18 @@
|
||||
"which": "bin/which"
|
||||
}
|
||||
},
|
||||
"node_modules/npm-run-path": {
|
||||
"version": "4.0.1",
|
||||
"resolved": "https://registry.npmjs.org/npm-run-path/-/npm-run-path-4.0.1.tgz",
|
||||
"integrity": "sha512-S48WzZW777zhNIrn7gxOlISNAqi9ZC/uQFnRdbeIHhZhCA6UqpkOT8T1G7BvfdgP4Er8gF4sUbaS0i7QvIfCWw==",
|
||||
"license": "MIT",
|
||||
"dependencies": {
|
||||
"path-key": "^3.0.0"
|
||||
},
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
},
|
||||
"node_modules/nth-check": {
|
||||
"version": "2.1.1",
|
||||
"resolved": "https://registry.npmjs.org/nth-check/-/nth-check-2.1.1.tgz",
|
||||
@@ -16293,7 +16545,6 @@
|
||||
"version": "5.1.2",
|
||||
"resolved": "https://registry.npmjs.org/onetime/-/onetime-5.1.2.tgz",
|
||||
"integrity": "sha512-kbpaSSGJTWdAY5KPVeMOKXSrPtr8C8C7wodJbcsd51jRnmD+GZu8Y0VoU6Dm5Z4vWr0Ig/1NKuWRKf7j5aaYSg==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"mimic-fn": "^2.1.0"
|
||||
},
|
||||
@@ -16769,7 +17020,6 @@
|
||||
"version": "1.0.1",
|
||||
"resolved": "https://registry.npmjs.org/path-is-absolute/-/path-is-absolute-1.0.1.tgz",
|
||||
"integrity": "sha512-AVbw3UJ2e9bq64vSaS9Am0fje1Pa8pbGqTTsmXfaIiMpnr5DlDhfJOuLj9Sf95ZPVDAUerDfEk88MPmPe7UCQg==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
@@ -16784,7 +17034,6 @@
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/path-key/-/path-key-3.1.1.tgz",
|
||||
"integrity": "sha512-ojmeN0qd+y0jszEtoY48r0Peq5dwMEkIlCOu6Q5f41lfkswXuKtYrhgoTpLnyIcHm24Uhqx+5Tqm2InSwLhE6Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -16848,7 +17097,6 @@
|
||||
"version": "4.0.0",
|
||||
"resolved": "https://registry.npmjs.org/path-type/-/path-type-4.0.0.tgz",
|
||||
"integrity": "sha512-gDKb8aZMDeD/tZWs9P6+q0J9Mwkdl6xMV8TjnGP3qJVJ06bdMgkbBlLU8IdfOsIsFz2BW1rNVT3XuNEl8zPAvw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -18161,7 +18409,6 @@
|
||||
"version": "1.2.3",
|
||||
"resolved": "https://registry.npmjs.org/queue-microtask/-/queue-microtask-1.2.3.tgz",
|
||||
"integrity": "sha512-NuaNSa6flKT5JaSYQzJok04JzTL1CA6aGhv5rfLW3PgqA+M2ChpZQnAC8h8i4ZFkBS8X5RqkDBHA7r4hej3K9A==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -18945,7 +19192,6 @@
|
||||
"version": "1.0.4",
|
||||
"resolved": "https://registry.npmjs.org/reusify/-/reusify-1.0.4.tgz",
|
||||
"integrity": "sha512-U9nH88a3fc/ekCF1l0/UP1IosiuIjyTh7hBvXVMHYgVcfGvt897Xguj2UOLDeI5BG2m7/uwyaLVT6fbtCwTyzw==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"iojs": ">=1.0.0",
|
||||
"node": ">=0.10.0"
|
||||
@@ -19085,7 +19331,6 @@
|
||||
"version": "1.2.0",
|
||||
"resolved": "https://registry.npmjs.org/run-parallel/-/run-parallel-1.2.0.tgz",
|
||||
"integrity": "sha512-5l4VyZR86LZ/lDxZTR6jqL8AFE2S0IFLMP26AbjsLVADxHdhB/c0GUsH+y39UfCi3dzz8OlQuPmnaJOMoDHQBA==",
|
||||
"dev": true,
|
||||
"funding": [
|
||||
{
|
||||
"type": "github",
|
||||
@@ -19200,8 +19445,7 @@
|
||||
"node_modules/sax": {
|
||||
"version": "1.4.1",
|
||||
"resolved": "https://registry.npmjs.org/sax/-/sax-1.4.1.tgz",
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg==",
|
||||
"dev": true
|
||||
"integrity": "sha512-+aWOz7yVScEGoKNd4PA10LZ8sk0A/z5+nXQG5giUO5rprX9jgYsTdov9qCchZiPIZezbZH+jRut8nPodFAX4Jg=="
|
||||
},
|
||||
"node_modules/scheduler": {
|
||||
"version": "0.23.2",
|
||||
@@ -19448,7 +19692,6 @@
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-command/-/shebang-command-2.0.0.tgz",
|
||||
"integrity": "sha512-kHxr2zZpYtdmrN1qDjrrX/Z1rR1kG8Dx+gkpK1G4eXmvXswmcE1hTWBWYUzlraYw1/yZp6YuDY77YtvbN0dmDA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"shebang-regex": "^3.0.0"
|
||||
},
|
||||
@@ -19460,7 +19703,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/shebang-regex/-/shebang-regex-3.0.0.tgz",
|
||||
"integrity": "sha512-7++dFhtcx3353uBaq8DDR4NuxBetBzC7ZQOhmTQInHEd6bSrXdiEyzCvG07Z44UYdLShWUyXt5M/yhz8ekcb1A==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -19669,7 +19911,6 @@
|
||||
"version": "3.0.0",
|
||||
"resolved": "https://registry.npmjs.org/slash/-/slash-3.0.0.tgz",
|
||||
"integrity": "sha512-g9Q1haeby36OSStwb4ntCGGGaKsaVSjQ68fBxoQcutl5fS1vuY18H3wSt3jFyFtrkx+Kz0V1G85A4MyAdDMi2Q==",
|
||||
"dev": true,
|
||||
"engines": {
|
||||
"node": ">=8"
|
||||
}
|
||||
@@ -20458,6 +20699,15 @@
|
||||
"node": ">=0.10.0"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-final-newline": {
|
||||
"version": "2.0.0",
|
||||
"resolved": "https://registry.npmjs.org/strip-final-newline/-/strip-final-newline-2.0.0.tgz",
|
||||
"integrity": "sha512-BrpvfNAE3dcvq7ll3xVumzjKjZQ5tI1sEUIKr3Uoks0XUl45St3FlatVqef9prk4jRDzhW6WZg+3bk93y6pLjA==",
|
||||
"license": "MIT",
|
||||
"engines": {
|
||||
"node": ">=6"
|
||||
}
|
||||
},
|
||||
"node_modules/strip-json-comments": {
|
||||
"version": "3.1.1",
|
||||
"resolved": "https://registry.npmjs.org/strip-json-comments/-/strip-json-comments-3.1.1.tgz",
|
||||
@@ -21279,6 +21529,12 @@
|
||||
"node": ">=0.12"
|
||||
}
|
||||
},
|
||||
"node_modules/tiny-typed-emitter": {
|
||||
"version": "2.1.0",
|
||||
"resolved": "https://registry.npmjs.org/tiny-typed-emitter/-/tiny-typed-emitter-2.1.0.tgz",
|
||||
"integrity": "sha512-qVtvMxeXbVej0cQWKqVSSAHmKZEHAvxdF8HEUBFWts8h+xEo5m/lEiPakuyZ3BnCBjOD8i24kzNOiOLLgsSxhA==",
|
||||
"license": "MIT"
|
||||
},
|
||||
"node_modules/tinyexec": {
|
||||
"version": "0.3.1",
|
||||
"resolved": "https://registry.npmjs.org/tinyexec/-/tinyexec-0.3.1.tgz",
|
||||
@@ -22888,7 +23144,6 @@
|
||||
"version": "2.0.2",
|
||||
"resolved": "https://registry.npmjs.org/which/-/which-2.0.2.tgz",
|
||||
"integrity": "sha512-BLI3Tl1TW3Pvl70l3yq3Y64i+awpwXqsGBYWkkqMtnbXgrMD+yj7rhW0kuEDxzJaYXGjEW5ogapKNMEKNMjibA==",
|
||||
"dev": true,
|
||||
"dependencies": {
|
||||
"isexe": "^2.0.0"
|
||||
},
|
||||
|
||||
@@ -1,9 +1,12 @@
|
||||
{
|
||||
"name": "code-oss-dev",
|
||||
"name": "void-dev",
|
||||
"productName": "Void",
|
||||
"version": "1.94.0",
|
||||
"distro": "ffcc24343ac46468a625666e5b9e673971dd1a1f",
|
||||
"distro": "this is a commit number if we want to publish on npm",
|
||||
"homepage": "https://voideditor.com",
|
||||
"author": {
|
||||
"name": "Microsoft Corporation"
|
||||
"name": "Glass Devtools, Inc.",
|
||||
"email": "andrew@voideditor.com"
|
||||
},
|
||||
"license": "MIT",
|
||||
"main": "./out/main",
|
||||
@@ -81,6 +84,7 @@
|
||||
"@parcel/watcher": "2.1.0",
|
||||
"@rrweb/record": "^2.0.0-alpha.17",
|
||||
"@rrweb/types": "^2.0.0-alpha.17",
|
||||
"@todesktop/runtime": "^2.0.0",
|
||||
"@vscode/deviceid": "^0.1.1",
|
||||
"@vscode/iconv-lite-umd": "0.7.0",
|
||||
"@vscode/policy-watcher": "^1.1.4",
|
||||
|
||||
@@ -1,36 +1,35 @@
|
||||
{
|
||||
"nameShort": "Void",
|
||||
"nameLong": "Void",
|
||||
"applicationName": "code-oss",
|
||||
"dataFolderName": ".vscode-oss",
|
||||
"win32MutexName": "vscodeoss",
|
||||
"applicationName": "void",
|
||||
"dataFolderName": ".void-editor",
|
||||
"win32MutexName": "voideditor",
|
||||
"licenseName": "MIT",
|
||||
"licenseUrl": "https://github.com/microsoft/vscode/blob/main/LICENSE.txt",
|
||||
"serverLicenseUrl": "https://github.com/microsoft/vscode/blob/main/LICENSE.txt",
|
||||
"licenseUrl": "https://github.com/voideditor/void/blob/main/LICENSE.txt",
|
||||
"serverLicenseUrl": "https://github.com/voideditor/void/blob/main/LICENSE.txt",
|
||||
"serverGreeting": [],
|
||||
"serverLicense": [],
|
||||
"serverLicensePrompt": "",
|
||||
"serverApplicationName": "code-server-oss",
|
||||
"serverDataFolderName": ".vscode-server-oss",
|
||||
"tunnelApplicationName": "code-tunnel-oss",
|
||||
"win32DirName": "Microsoft Code OSS",
|
||||
"win32NameVersion": "Microsoft Code OSS",
|
||||
"win32RegValueName": "CodeOSS",
|
||||
"win32x64AppId": "{{D77B7E06-80BA-4137-BCF4-654B95CCEBC5}",
|
||||
"win32arm64AppId": "{{D1ACE434-89C5-48D1-88D3-E2991DF85475}",
|
||||
"win32x64UserAppId": "{{CC6B787D-37A0-49E8-AE24-8559A032BE0C}",
|
||||
"win32arm64UserAppId": "{{3AEBF0C8-F733-4AD4-BADE-FDB816D53D7B}",
|
||||
"win32AppUserModelId": "Microsoft.CodeOSS",
|
||||
"win32ShellNameShort": "C&ode - OSS",
|
||||
"win32TunnelServiceMutex": "vscodeoss-tunnelservice",
|
||||
"win32TunnelMutex": "vscodeoss-tunnel",
|
||||
"darwinBundleIdentifier": "com.visualstudio.code.oss",
|
||||
"linuxIconName": "code-oss",
|
||||
"serverApplicationName": "void-server",
|
||||
"serverDataFolderName": ".void-server",
|
||||
"tunnelApplicationName": "void-tunnel",
|
||||
"win32DirName": "Void",
|
||||
"win32NameVersion": "Void",
|
||||
"win32RegValueName": "VoidEditor",
|
||||
"win32x64AppId": "{{9D394D01-1728-45A7-B997-A6C82C5452C3}",
|
||||
"win32arm64AppId": "{{0668DD58-2BDE-4101-8CDA-40252DF8875D}",
|
||||
"win32x64UserAppId": "{{8BED5DC1-6C55-46E6-9FE6-18F7E6F7C7F1}",
|
||||
"win32arm64UserAppId": "{{F6C87466-BC82-4A8F-B0FF-18CA366BA4D8}",
|
||||
"win32AppUserModelId": "Void.Editor",
|
||||
"win32ShellNameShort": "V&oid",
|
||||
"win32TunnelServiceMutex": "void-tunnelservice",
|
||||
"win32TunnelMutex": "void-tunnel",
|
||||
"darwinBundleIdentifier": "com.voideditor.code",
|
||||
"linuxIconName": "void-editor",
|
||||
"licenseFileName": "LICENSE.txt",
|
||||
"reportIssueUrl": "https://github.com/microsoft/vscode/issues/new",
|
||||
"reportIssueUrl": "https://github.com/voideditor/void/issues/new",
|
||||
"nodejsRepository": "https://nodejs.org",
|
||||
"urlProtocol": "code-oss",
|
||||
"webviewContentExternalBaseUrlTemplate": "https://{{uuid}}.vscode-cdn.net/insider/ef65ac1ba57f57f2a3961bfe94aa20481caca4c6/out/vs/workbench/contrib/webview/browser/pre/",
|
||||
"urlProtocol": "void-editor",
|
||||
"extensionsGallery": {
|
||||
"serviceUrl": "https://open-vsx.org/vscode/gallery",
|
||||
"itemUrl": "https://open-vsx.org/vscode/item"
|
||||
|
||||
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 813 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 254 KiB |
|
Before Width: | Height: | Size: 2.7 KiB After Width: | Height: | Size: 254 KiB |
|
Before Width: | Height: | Size: 34 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 89 KiB After Width: | Height: | Size: 29 KiB |
|
Before Width: | Height: | Size: 395 B After Width: | Height: | Size: 5.9 KiB |
|
Before Width: | Height: | Size: 338 B After Width: | Height: | Size: 1.8 KiB |
|
After Width: | Height: | Size: 5.5 MiB |
@@ -159,7 +159,7 @@ export class InputBox extends Widget {
|
||||
this.scrollableElement = new ScrollableElement(this.element, { vertical: ScrollbarVisibility.Auto });
|
||||
|
||||
if (this.options.flexibleWidth) {
|
||||
this.input.setAttribute('wrap', 'off');
|
||||
this.input.setAttribute('wrap', 'on');
|
||||
this.mirror.style.whiteSpace = 'pre';
|
||||
this.mirror.style.wordWrap = 'initial';
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@
|
||||
import '../../platform/update/common/update.config.contribution.js';
|
||||
|
||||
import { app, dialog } from 'electron';
|
||||
import todesktop from '@todesktop/runtime'
|
||||
import { unlinkSync, promises } from 'fs';
|
||||
import { URI } from '../../base/common/uri.js';
|
||||
import { coalesce, distinct } from '../../base/common/arrays.js';
|
||||
@@ -94,6 +95,8 @@ class CodeMain {
|
||||
|
||||
private async startup(): Promise<void> {
|
||||
|
||||
todesktop.init();
|
||||
|
||||
// Set the error handler early enough so that we are not getting the
|
||||
// default electron error dialog popping up
|
||||
setUnexpectedErrorHandler(err => console.error(err));
|
||||
|
||||
@@ -7,7 +7,10 @@ import { IRange } from '../../../common/core/range.js';
|
||||
import { EditorOption } from '../../../common/config/editorOptions.js';
|
||||
|
||||
|
||||
// THIS FILE IS OLD!!!
|
||||
// THIS FILE IS OLD + UNUSED!!!
|
||||
|
||||
// SEE inlineDiffsService.ts INSTEAD.
|
||||
|
||||
export interface IInlineDiffService {
|
||||
readonly _serviceBrand: undefined;
|
||||
addDiff(editor: ICodeEditor, originalText: string, modifiedRange: IRange): void;
|
||||
|
||||
@@ -1,4 +1,7 @@
|
||||
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
// ---------- common ----------
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { EventLLMMessageOnTextParams, EventLLMMessageOnErrorParams, EventLLMMessageOnFinalMessageParams, ServiceSendLLMMessageParams, MainLLMMessageParams, MainLLMMessageAbortParams, ServiceModelListParams, EventModelListOnSuccessParams, EventModelListOnErrorParams, MainModelListParams, OllamaModelResponse, OpenaiCompatibleModelResponse, } from './llmMessageTypes.js';
|
||||
import { IChannel } from '../../../base/parts/ipc/common/ipc.js';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IRange } from '../../../editor/common/core/range'
|
||||
import { ProviderName, SettingsOfProvider } from './voidSettingsTypes.js'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from '../../instantiation/common/instantiation.js';
|
||||
import { ProxyChannel } from '../../../base/parts/ipc/common/ipc.js';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { createDecorator } from '../../instantiation/common/instantiation.js';
|
||||
import { InstantiationType, registerSingleton } from '../../instantiation/common/extensions.js';
|
||||
@@ -22,7 +22,10 @@ type RefreshableState = ({
|
||||
state: 'refreshing',
|
||||
timeoutId: NodeJS.Timeout | null, // the timeoutId of the most recent call to refreshModels
|
||||
} | {
|
||||
state: 'success',
|
||||
state: 'finished',
|
||||
timeoutId: null,
|
||||
} | {
|
||||
state: 'finished_invisible',
|
||||
timeoutId: null,
|
||||
})
|
||||
|
||||
@@ -82,7 +85,7 @@ export class RefreshModelService extends Disposable implements IRefreshModelServ
|
||||
for (const providerName of refreshableProviderNames) {
|
||||
|
||||
const { _enabled: enabled } = this.voidSettingsService.state.settingsOfProvider[providerName]
|
||||
this.refreshModels(providerName, !enabled)
|
||||
this.refreshModels(providerName, !enabled, { isPolling: true, isInternal: true })
|
||||
|
||||
// every time providerName.enabled changes, refresh models too, like a useEffect
|
||||
let relevantVals = () => refreshBasedOn[providerName].map(settingName => this.voidSettingsService.state.settingsOfProvider[providerName][settingName])
|
||||
@@ -98,7 +101,7 @@ export class RefreshModelService extends Disposable implements IRefreshModelServ
|
||||
// if it was just enabled, or there was a change and it wasn't to the enabled state, refresh
|
||||
if ((enabled && !prevEnabled) || (!enabled && !prevEnabled)) {
|
||||
// if user just clicked enable, refresh
|
||||
this.refreshModels(providerName, !enabled)
|
||||
this.refreshModels(providerName, !enabled, { isPolling: false, isInternal: true })
|
||||
}
|
||||
else {
|
||||
// else if user just clicked disable, don't refresh
|
||||
@@ -131,11 +134,16 @@ export class RefreshModelService extends Disposable implements IRefreshModelServ
|
||||
|
||||
|
||||
// start listening for models (and don't stop until success)
|
||||
async refreshModels(providerName: RefreshableProviderName, enableProviderOnSuccess?: boolean) {
|
||||
async refreshModels(providerName: RefreshableProviderName, enableProviderOnSuccess?: boolean, options?: { isPolling?: boolean, isInternal?: boolean }) {
|
||||
|
||||
const { isPolling, isInternal } = options ?? {}
|
||||
|
||||
console.log(`refreshModels, isInternal ${isInternal} isPolling ${isPolling}`)
|
||||
|
||||
this._clearProviderTimeout(providerName)
|
||||
|
||||
// start loading models
|
||||
this._setRefreshState(providerName, 'refreshing')
|
||||
if (!isInternal) this._setRefreshState(providerName, 'refreshing')
|
||||
|
||||
const fn = providerName === 'ollama' ? this.llmMessageService.ollamaList
|
||||
: providerName === 'openAICompatible' ? this.llmMessageService.openAICompatibleList
|
||||
@@ -153,15 +161,22 @@ export class RefreshModelService extends Disposable implements IRefreshModelServ
|
||||
this.voidSettingsService.setSettingOfProvider(providerName, '_enabled', true)
|
||||
}
|
||||
|
||||
this._setRefreshState(providerName, 'success')
|
||||
if (!isInternal) this._setRefreshState(providerName, 'finished')
|
||||
|
||||
},
|
||||
onError: ({ error }) => {
|
||||
// poll
|
||||
console.log('retrying list models:', providerName, error)
|
||||
const timeoutId = setTimeout(() => this.refreshModels(providerName, enableProviderOnSuccess), REFRESH_INTERVAL)
|
||||
this._setTimeoutId(providerName, timeoutId)
|
||||
}
|
||||
})
|
||||
|
||||
if (isInternal) this._setRefreshState(providerName, 'finished_invisible')
|
||||
|
||||
// check if we should poll
|
||||
// if it was originally called as `isPolling` and if the `autoRefreshModels` flag is enabled
|
||||
if (isPolling && this.voidSettingsService.state.featureFlagSettings.autoRefreshModels) {
|
||||
const timeoutId = setTimeout(() => this.refreshModels(providerName, enableProviderOnSuccess, options), REFRESH_INTERVAL)
|
||||
this._setTimeoutId(providerName, timeoutId)
|
||||
}
|
||||
}
|
||||
|
||||
_clearAllTimeouts() {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from '../../../base/common/event.js';
|
||||
import { Disposable } from '../../../base/common/lifecycle.js';
|
||||
@@ -222,7 +222,7 @@ class VoidSettingsService extends Disposable implements IVoidSettingsService {
|
||||
|
||||
setDefaultModels(providerName: ProviderName, newDefaultModelNames: string[]) {
|
||||
const { models } = this.state.settingsOfProvider[providerName]
|
||||
const newDefaultModels = modelInfoOfDefaultNames(newDefaultModelNames)
|
||||
const newDefaultModels = modelInfoOfDefaultNames(newDefaultModelNames, { isAutodetected: true, existingModels: models })
|
||||
const newModels = [
|
||||
...newDefaultModels,
|
||||
...models.filter(m => !m.isDefault), // keep any non-default models
|
||||
|
||||
@@ -1,8 +1,8 @@
|
||||
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
|
||||
@@ -11,12 +11,32 @@ export type VoidModelInfo = {
|
||||
modelName: string,
|
||||
isDefault: boolean, // whether or not it's a default for its provider
|
||||
isHidden: boolean, // whether or not the user is hiding it
|
||||
isAutodetected?: boolean, // whether the model was autodetected by polling
|
||||
}
|
||||
|
||||
type ModelInfoOfDefaultNamesOptions = { isAutodetected: true, existingModels: VoidModelInfo[] } // | { isOtherOption: true, ...otherOptions }
|
||||
export const modelInfoOfDefaultNames = (modelNames: string[], options?: ModelInfoOfDefaultNamesOptions): VoidModelInfo[] => {
|
||||
|
||||
export const modelInfoOfDefaultNames = (modelNames: string[]): VoidModelInfo[] => {
|
||||
const { isAutodetected, existingModels } = options ?? {}
|
||||
const isDefault = true
|
||||
const isHidden = modelNames.length >= 10 // hide all models if there are a ton of them, and make user enable them individually
|
||||
return modelNames.map((modelName, i) => ({ modelName, isDefault: true, isHidden }))
|
||||
|
||||
if (!existingModels) {
|
||||
|
||||
return modelNames.map((modelName, i) => ({ modelName, isDefault, isAutodetected, isHidden, }))
|
||||
|
||||
} else {
|
||||
// keep existing `isHidden` property
|
||||
|
||||
const existingModelsMap: Record<string, VoidModelInfo> = {}
|
||||
for (const em of existingModels) {
|
||||
existingModelsMap[em.modelName] = em
|
||||
}
|
||||
|
||||
return modelNames.map((modelName, i) => ({ modelName, isDefault, isAutodetected, isHidden: !!existingModelsMap[modelName]?.isHidden, }))
|
||||
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
// https://docs.anthropic.com/en/docs/about-claude/models
|
||||
@@ -121,11 +141,11 @@ export const defaultProviderSettings = {
|
||||
}
|
||||
} as const
|
||||
|
||||
|
||||
export type ProviderName = keyof typeof defaultProviderSettings
|
||||
export const providerNames = Object.keys(defaultProviderSettings) as ProviderName[]
|
||||
|
||||
|
||||
export const localProviderNames = ['ollama', 'openAICompatible'] satisfies ProviderName[] // all local names
|
||||
export const nonlocalProviderNames = providerNames.filter((name) => !(localProviderNames as string[]).includes(name)) // all non-local names
|
||||
|
||||
type CustomSettingName = UnionOfKeys<typeof defaultProviderSettings[ProviderName]>
|
||||
type CustomProviderSettings<providerName extends ProviderName> = {
|
||||
@@ -183,7 +203,7 @@ export const displayInfoOfProviderName = (providerName: ProviderName): DisplayIn
|
||||
}
|
||||
else if (providerName === 'openAICompatible') {
|
||||
return {
|
||||
title: 'OpenAI-Compatible',
|
||||
title: 'Other',
|
||||
}
|
||||
}
|
||||
else if (providerName === 'gemini') {
|
||||
@@ -222,7 +242,7 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName
|
||||
providerName === 'openRouter' ? 'Get your [API Key here](https://openrouter.ai/settings/keys).' :
|
||||
providerName === 'gemini' ? 'Get your [API Key here](https://aistudio.google.com/apikey).' :
|
||||
providerName === 'groq' ? 'Get your [API Key here](https://console.groq.com/keys).' :
|
||||
providerName === 'openAICompatible' ? undefined :
|
||||
providerName === 'openAICompatible' ? 'Add any OpenAI-Compatible endpoint.' :
|
||||
undefined,
|
||||
}
|
||||
}
|
||||
@@ -236,7 +256,7 @@ export const displayInfoOfSettingName = (providerName: ProviderName, settingName
|
||||
: providerName === 'openAICompatible' ? 'https://my-website.com/v1'
|
||||
: '(never)',
|
||||
|
||||
subTextMd: providerName === 'ollama' ? 'Read about Ollama [Endpoints here](https://github.com/ollama/ollama/blob/main/docs/faq.md#how-can-i-expose-ollama-on-my-network).' :
|
||||
subTextMd: providerName === 'ollama' ? 'Read about advanced [Endpoints here](https://github.com/ollama/ollama/blob/main/docs/faq.md#how-can-i-expose-ollama-on-my-network).' :
|
||||
undefined,
|
||||
}
|
||||
}
|
||||
@@ -359,7 +379,7 @@ export const featureNames = ['Ctrl+L', 'Ctrl+K', 'Autocomplete'] as const
|
||||
|
||||
|
||||
// the models of these can be refreshed (in theory all can, but not all should)
|
||||
export const refreshableProviderNames = ['ollama', 'openAICompatible'] satisfies ProviderName[]
|
||||
export const refreshableProviderNames = localProviderNames
|
||||
export type RefreshableProviderName = typeof refreshableProviderNames[number]
|
||||
|
||||
|
||||
@@ -385,7 +405,7 @@ type FeatureFlagDisplayInfo = {
|
||||
export const displayInfoOfFeatureFlag = (featureFlag: FeatureFlagName): FeatureFlagDisplayInfo => {
|
||||
if (featureFlag === 'autoRefreshModels') {
|
||||
return {
|
||||
description: `Automatically scan for and enable local models.`, // ${`refreshableProviderNames.map(providerName => titleOfProviderName(providerName)).join(', ')`}
|
||||
description: `Automatically detect local providers and models (${refreshableProviderNames.map(providerName => displayInfoOfProviderName(providerName).title).join(', ')}).`,
|
||||
}
|
||||
}
|
||||
throw new Error(`featureFlagInfo: Unknown feature flag: "${featureFlag}"`)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import Anthropic from '@anthropic-ai/sdk';
|
||||
import { _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Content, GoogleGenerativeAI, GoogleGenerativeAIFetchError } from '@google/generative-ai';
|
||||
import { _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
// // Greptile
|
||||
// // https://docs.greptile.com/api-reference/query
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import Groq from 'groq-sdk';
|
||||
import { _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Ollama } from 'ollama';
|
||||
import { _InternalModelListFnType, _InternalSendLLMMessageFnType, OllamaModelResponse } from '../../common/llmMessageTypes.js';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import OpenAI from 'openai';
|
||||
import { _InternalModelListFnType, _InternalSendLLMMessageFnType } from '../../common/llmMessageTypes.js';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { LLMMMessageParams, OnText, OnFinalMessage, OnError } from '../../common/llmMessageTypes.js';
|
||||
import { IMetricsService } from '../../common/metricsService.js';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
// registered in app.ts
|
||||
// code convention is to make a service responsible for this stuff, and not a channel, but having fewer files is simpler...
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from '../../../base/common/lifecycle.js';
|
||||
import { ITelemetryService } from '../../telemetry/common/telemetry.js';
|
||||
|
||||
@@ -170,6 +170,9 @@ export class EditorGroupWatermark extends Disposable {
|
||||
this.clear();
|
||||
const box = append(this.shortcuts, $('.watermark-box'));
|
||||
const boxBelow = append(this.shortcuts, $(''))
|
||||
boxBelow.style.display = 'flex'
|
||||
boxBelow.style.flex = 'row'
|
||||
boxBelow.style.justifyContent = 'center'
|
||||
|
||||
|
||||
const update = async () => {
|
||||
@@ -184,9 +187,13 @@ export class EditorGroupWatermark extends Disposable {
|
||||
// Void - if the workbench is empty, show open
|
||||
if (this.contextService.getWorkbenchState() === WorkbenchState.EMPTY) {
|
||||
|
||||
// Open Folder
|
||||
// Open a folder
|
||||
const button = h('button')
|
||||
button.root.textContent = 'Open Folder'
|
||||
button.root.classList.add('void-watermark-button')
|
||||
button.root.style.display = 'block'
|
||||
button.root.style.marginLeft = 'auto'
|
||||
button.root.style.marginRight = 'auto'
|
||||
button.root.textContent = 'Open a folder'
|
||||
button.root.onclick = () => {
|
||||
this.commandService.executeCommand(isMacintosh && isNative ? OpenFileFolderAction.ID : OpenFolderAction.ID)
|
||||
// if (this.contextKeyService.contextMatchesRules(ContextKeyExpr.and(WorkbenchStateContext.isEqualTo('workspace')))) {
|
||||
@@ -197,58 +204,66 @@ export class EditorGroupWatermark extends Disposable {
|
||||
}
|
||||
box.appendChild(button.root);
|
||||
|
||||
|
||||
// Recents
|
||||
const recentlyOpened = await this.workspacesService.getRecentlyOpened()
|
||||
.catch(() => ({ files: [], workspaces: [] })).then(w => w.workspaces);
|
||||
|
||||
|
||||
if (recentlyOpened.length !== 0) {
|
||||
|
||||
box.append(
|
||||
...recentlyOpened.map(w => {
|
||||
const span = $('div')
|
||||
span.textContent = 'Recent'
|
||||
span.style.fontWeight = '500'
|
||||
box.append(span)
|
||||
|
||||
let fullPath: string;
|
||||
let windowOpenable: IWindowOpenable;
|
||||
if (isRecentFolder(w)) {
|
||||
windowOpenable = { folderUri: w.folderUri };
|
||||
fullPath = w.label || this.labelService.getWorkspaceLabel(w.folderUri, { verbose: Verbosity.LONG });
|
||||
}
|
||||
else {
|
||||
return null
|
||||
// fullPath = w.label || this.labelService.getWorkspaceLabel(w.workspace, { verbose: Verbosity.LONG });
|
||||
// windowOpenable = { workspaceUri: w.workspace.configPath };
|
||||
}
|
||||
box.append(
|
||||
...recentlyOpened.map(w => {
|
||||
|
||||
let fullPath: string;
|
||||
let windowOpenable: IWindowOpenable;
|
||||
if (isRecentFolder(w)) {
|
||||
windowOpenable = { folderUri: w.folderUri };
|
||||
fullPath = w.label || this.labelService.getWorkspaceLabel(w.folderUri, { verbose: Verbosity.LONG });
|
||||
}
|
||||
else {
|
||||
return null
|
||||
// fullPath = w.label || this.labelService.getWorkspaceLabel(w.workspace, { verbose: Verbosity.LONG });
|
||||
// windowOpenable = { workspaceUri: w.workspace.configPath };
|
||||
}
|
||||
|
||||
|
||||
const { name, parentPath } = splitRecentLabel(fullPath);
|
||||
|
||||
const { name, parentPath } = splitRecentLabel(fullPath);
|
||||
const li = $('li');
|
||||
const link = $('span');
|
||||
link.classList.add('void-link')
|
||||
|
||||
const li = $('li');
|
||||
const link = $('button.button-link');
|
||||
|
||||
link.innerText = name;
|
||||
link.title = fullPath;
|
||||
link.setAttribute('aria-label', localize('welcomePage.openFolderWithPath', "Open folder {0} with path {1}", name, parentPath));
|
||||
link.addEventListener('click', e => {
|
||||
this.hostService.openWindow([windowOpenable], {
|
||||
forceNewWindow: e.ctrlKey || e.metaKey,
|
||||
remoteAuthority: w.remoteAuthority || null // local window if remoteAuthority is not set or can not be deducted from the openable
|
||||
link.innerText = name;
|
||||
link.title = fullPath;
|
||||
link.setAttribute('aria-label', localize('welcomePage.openFolderWithPath', "Open folder {0} with path {1}", name, parentPath));
|
||||
link.addEventListener('click', e => {
|
||||
this.hostService.openWindow([windowOpenable], {
|
||||
forceNewWindow: e.ctrlKey || e.metaKey,
|
||||
remoteAuthority: w.remoteAuthority || null // local window if remoteAuthority is not set or can not be deducted from the openable
|
||||
});
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
e.preventDefault();
|
||||
e.stopPropagation();
|
||||
});
|
||||
li.appendChild(link);
|
||||
li.appendChild(link);
|
||||
|
||||
const span = $('span');
|
||||
span.classList.add('path');
|
||||
span.classList.add('detail');
|
||||
span.innerText = parentPath;
|
||||
span.title = fullPath;
|
||||
li.appendChild(span);
|
||||
const span = $('span');
|
||||
span.style.paddingLeft = '4px';
|
||||
span.classList.add('path');
|
||||
span.classList.add('detail');
|
||||
span.innerText = parentPath;
|
||||
span.title = fullPath;
|
||||
li.appendChild(span);
|
||||
|
||||
|
||||
return li
|
||||
}).filter(v => !!v)
|
||||
)
|
||||
return li
|
||||
}).filter(v => !!v)
|
||||
)
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -280,6 +295,11 @@ export class EditorGroupWatermark extends Disposable {
|
||||
const keys3 = this.keybindingService.lookupKeybinding('workbench.action.openGlobalKeybindings');
|
||||
const button3 = append(boxBelow, $('button'));
|
||||
button3.textContent = 'Void Settings'
|
||||
button3.style.display = 'block'
|
||||
button3.style.marginLeft = 'auto'
|
||||
button3.style.marginRight = 'auto'
|
||||
button3.classList.add('void-settings-watermark-button')
|
||||
|
||||
const label3 = new KeybindingLabel(button3, OS, { renderUnboundKeybindings: true, ...defaultKeybindingLabelStyles });
|
||||
if (keys3)
|
||||
label3.set(keys3);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from '../../../../base/common/lifecycle.js';
|
||||
import { ILanguageFeaturesService } from '../../../../editor/common/services/languageFeatures.js';
|
||||
@@ -17,6 +17,7 @@ import { IEditorService } from '../../../services/editor/common/editorService.js
|
||||
import { isCodeEditor } from '../../../../editor/browser/editorBrowser.js';
|
||||
import { EditorResourceAccessor } from '../../../common/editor.js';
|
||||
import { IModelService } from '../../../../editor/common/services/model.js';
|
||||
import { extractCodeFromResult } from './helpers/extractCodeFromResult.js';
|
||||
|
||||
// The extension this was called from is here - https://github.com/voideditor/void/blob/autocomplete/extensions/void/src/extension/extension.ts
|
||||
|
||||
@@ -165,20 +166,6 @@ const postprocessResult = (result: string) => {
|
||||
|
||||
}
|
||||
|
||||
const extractCodeFromResult = (result: string) => {
|
||||
// Match either:
|
||||
// 1. ```language\n<code>```
|
||||
// 2. ```<code>```
|
||||
const match = result.match(/```(?:\w+\n)?([\s\S]*?)```|```([\s\S]*?)```/);
|
||||
|
||||
if (!match) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return whichever group matched (non-empty)
|
||||
return match[1] ?? match[2] ?? result;
|
||||
}
|
||||
|
||||
|
||||
// trims the end of the prefix to improve cache hit rate
|
||||
const removeLeftTabsAndTrimEnd = (s: string): string => {
|
||||
@@ -768,3 +755,5 @@ export class AutocompleteService extends Disposable implements IAutocompleteServ
|
||||
|
||||
|
||||
registerSingleton(IAutocompleteService, AutocompleteService, InstantiationType.Eager);
|
||||
|
||||
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from '../../../../../base/common/lifecycle.js';
|
||||
import { URI } from '../../../../../base/common/uri.js';
|
||||
import { generateUuid } from '../../../../../base/common/uuid.js';
|
||||
@@ -9,7 +14,6 @@ import { createDecorator } from '../../../../../platform/instantiation/common/in
|
||||
|
||||
// lets you add a "consistent" item to a Model (aka URI), instead of just to a single editor
|
||||
|
||||
|
||||
type AddItemInputs = { uri: URI; fn: (editor: ICodeEditor) => (() => void); }
|
||||
|
||||
export interface IConsistentItemService {
|
||||
@@ -56,6 +60,7 @@ export class ConsistentItemService extends Disposable {
|
||||
}
|
||||
|
||||
|
||||
// when editor switches tabs (models)
|
||||
const addTabSwitchListeners = (editor: ICodeEditor) => {
|
||||
this._register(
|
||||
editor.onDidChangeModel(e => {
|
||||
@@ -65,6 +70,7 @@ export class ConsistentItemService extends Disposable {
|
||||
)
|
||||
}
|
||||
|
||||
// when editor is disposed
|
||||
const addDisposeListener = (editor: ICodeEditor) => {
|
||||
this._register(editor.onDidDispose(() => {
|
||||
// anything on the editor has been disposed already
|
||||
@@ -176,3 +182,243 @@ export class ConsistentItemService extends Disposable {
|
||||
registerSingleton(IConsistentItemService, ConsistentItemService, InstantiationType.Eager);
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
// mostly generated by o1 (almost the same as above, but just for 1 editor)
|
||||
export interface IConsistentEditorItemService {
|
||||
readonly _serviceBrand: undefined;
|
||||
addToEditor(editor: ICodeEditor, fn: () => () => void): string;
|
||||
removeFromEditor(itemId: string): void;
|
||||
}
|
||||
export const IConsistentEditorItemService = createDecorator<IConsistentEditorItemService>('ConsistentEditorItemService');
|
||||
|
||||
|
||||
export class ConsistentEditorItemService extends Disposable {
|
||||
readonly _serviceBrand: undefined;
|
||||
|
||||
/**
|
||||
* For each editorId, we track the set of itemIds that have been "added" to that editor.
|
||||
* This does *not* necessarily mean they're currently mounted (the user may have switched models).
|
||||
*/
|
||||
private readonly itemIdsByEditorId: Record<string, Set<string>> = {};
|
||||
|
||||
/**
|
||||
* For each itemId, we store relevant info (the fn to call on the editor, the editorId, the uri, and the current dispose function).
|
||||
*/
|
||||
private readonly itemInfoById: Record<
|
||||
string,
|
||||
{
|
||||
editorId: string;
|
||||
uriFsPath: string;
|
||||
fn: (editor: ICodeEditor) => () => void;
|
||||
disposeFn?: () => void;
|
||||
}
|
||||
> = {};
|
||||
|
||||
constructor(
|
||||
@ICodeEditorService private readonly _editorService: ICodeEditorService,
|
||||
) {
|
||||
super();
|
||||
|
||||
//
|
||||
// Wire up listeners to watch for new editors, removed editors, etc.
|
||||
//
|
||||
|
||||
// Initialize any already-existing editors
|
||||
for (const editor of this._editorService.listCodeEditors()) {
|
||||
this._initializeEditor(editor);
|
||||
}
|
||||
|
||||
// When an editor is added, track it
|
||||
this._register(
|
||||
this._editorService.onCodeEditorAdd((editor) => {
|
||||
this._initializeEditor(editor);
|
||||
})
|
||||
);
|
||||
|
||||
// When an editor is removed, remove all items associated with that editor
|
||||
this._register(
|
||||
this._editorService.onCodeEditorRemove((editor) => {
|
||||
this._removeAllItemsFromEditor(editor);
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
/**
|
||||
* Sets up listeners on the provided editor so that:
|
||||
* - If the editor changes models, we remove items and re-mount only if the new model matches.
|
||||
* - If the editor is disposed, we do the needed cleanup.
|
||||
*/
|
||||
private _initializeEditor(editor: ICodeEditor) {
|
||||
const editorId = editor.getId();
|
||||
|
||||
//
|
||||
// Listen for model changes
|
||||
//
|
||||
this._register(
|
||||
editor.onDidChangeModel((e) => {
|
||||
this._removeAllItemsFromEditor(editor);
|
||||
if (!e.newModelUrl) {
|
||||
return;
|
||||
}
|
||||
// Re-mount any items that belong to this editor and match the new URI
|
||||
const itemsForEditor = this.itemIdsByEditorId[editorId];
|
||||
if (itemsForEditor) {
|
||||
for (const itemId of itemsForEditor) {
|
||||
const itemInfo = this.itemInfoById[itemId];
|
||||
if (itemInfo && itemInfo.uriFsPath === e.newModelUrl.fsPath) {
|
||||
this._mountItemOnEditor(editor, itemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
})
|
||||
);
|
||||
|
||||
//
|
||||
// When the editor is disposed, remove all items from it
|
||||
//
|
||||
this._register(
|
||||
editor.onDidDispose(() => {
|
||||
this._removeAllItemsFromEditor(editor);
|
||||
})
|
||||
);
|
||||
|
||||
//
|
||||
// If the editor already has a model (e.g. on initial load), try mounting items
|
||||
//
|
||||
const uri = editor.getModel()?.uri;
|
||||
if (!uri) {
|
||||
return;
|
||||
}
|
||||
|
||||
const itemsForEditor = this.itemIdsByEditorId[editorId];
|
||||
if (itemsForEditor) {
|
||||
for (const itemId of itemsForEditor) {
|
||||
const itemInfo = this.itemInfoById[itemId];
|
||||
if (itemInfo && itemInfo.uriFsPath === uri.fsPath) {
|
||||
this._mountItemOnEditor(editor, itemId);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Actually calls the item-creation function `fn(editor)` and saves the resulting disposeFn
|
||||
* so we can later clean it up.
|
||||
*/
|
||||
private _mountItemOnEditor(editor: ICodeEditor, itemId: string) {
|
||||
const info = this.itemInfoById[itemId];
|
||||
if (!info) {
|
||||
return;
|
||||
}
|
||||
const { fn } = info;
|
||||
const disposeFn = fn(editor);
|
||||
info.disposeFn = disposeFn;
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes a single item from an editor (calling its `disposeFn` if present).
|
||||
*/
|
||||
private _removeItemFromEditor(editor: ICodeEditor, itemId: string) {
|
||||
const info = this.itemInfoById[itemId];
|
||||
if (info?.disposeFn) {
|
||||
info.disposeFn();
|
||||
info.disposeFn = undefined;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Removes *all* items from the given editor. Typically called when the editor changes model or is disposed.
|
||||
*/
|
||||
private _removeAllItemsFromEditor(editor: ICodeEditor) {
|
||||
const editorId = editor.getId();
|
||||
const itemsForEditor = this.itemIdsByEditorId[editorId];
|
||||
if (!itemsForEditor) {
|
||||
return;
|
||||
}
|
||||
|
||||
for (const itemId of itemsForEditor) {
|
||||
this._removeItemFromEditor(editor, itemId);
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Public API: Adds an item to an *individual* editor (determined by editor ID),
|
||||
* but only when that editor is showing the same model (uri.fsPath).
|
||||
*/
|
||||
addToEditor(editor: ICodeEditor, fn: () => () => void): string {
|
||||
const uri = editor.getModel()?.uri
|
||||
if (!uri) {
|
||||
throw new Error('No URI on the provided editor or in AddItemInputs.');
|
||||
}
|
||||
|
||||
const editorId = editor.getId();
|
||||
|
||||
// Create an ID for this item
|
||||
const itemId = generateUuid();
|
||||
|
||||
// Record the info
|
||||
this.itemInfoById[itemId] = {
|
||||
editorId,
|
||||
uriFsPath: uri.fsPath,
|
||||
fn,
|
||||
};
|
||||
|
||||
// Add to the editor's known items
|
||||
if (!this.itemIdsByEditorId[editorId]) {
|
||||
this.itemIdsByEditorId[editorId] = new Set();
|
||||
}
|
||||
this.itemIdsByEditorId[editorId].add(itemId);
|
||||
|
||||
// If the editor's current URI matches, mount it now
|
||||
if (editor.getModel()?.uri.fsPath === uri.fsPath) {
|
||||
this._mountItemOnEditor(editor, itemId);
|
||||
}
|
||||
|
||||
return itemId;
|
||||
}
|
||||
|
||||
/**
|
||||
* Public API: Removes an item from the *specific* editor. We look up which editor
|
||||
* had this item and remove it from that editor.
|
||||
*/
|
||||
removeFromEditor(itemId: string): void {
|
||||
const info = this.itemInfoById[itemId];
|
||||
if (!info) {
|
||||
// Nothing to remove
|
||||
return;
|
||||
}
|
||||
|
||||
const { editorId } = info;
|
||||
|
||||
// Find the editor in question
|
||||
const editor = this._editorService.listCodeEditors().find(
|
||||
(ed) => ed.getId() === editorId
|
||||
);
|
||||
if (editor) {
|
||||
// Dispose on that editor
|
||||
this._removeItemFromEditor(editor, itemId);
|
||||
}
|
||||
|
||||
// Clean up references
|
||||
this.itemIdsByEditorId[editorId]?.delete(itemId);
|
||||
delete this.itemInfoById[itemId];
|
||||
}
|
||||
}
|
||||
|
||||
registerSingleton(IConsistentEditorItemService, ConsistentEditorItemService, InstantiationType.Eager);
|
||||
|
||||
|
||||
|
||||
@@ -0,0 +1,18 @@
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
export const extractCodeFromResult = (result: string) => {
|
||||
// Match either:
|
||||
// 1. ```language\n<code>```
|
||||
// 2. ```<code>```
|
||||
const match = result.match(/```(?:\w+\n)?([\s\S]*?)```|```([\s\S]*?)```/);
|
||||
|
||||
if (!match) {
|
||||
return result;
|
||||
}
|
||||
|
||||
// Return whichever group matched (non-empty)
|
||||
return match[1] ?? match[2] ?? result;
|
||||
}
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { diffLines } from '../react/out/diff/index.js'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { isMacintosh } from '../../../../../base/common/platform.js';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from '../../../../base/common/lifecycle.js';
|
||||
import { registerSingleton, InstantiationType } from '../../../../platform/instantiation/common/extensions.js';
|
||||
@@ -26,7 +26,7 @@ import { ILanguageService } from '../../../../editor/common/languages/language.j
|
||||
import * as dom from '../../../../base/browser/dom.js';
|
||||
import { Widget } from '../../../../base/browser/ui/widget.js';
|
||||
import { URI } from '../../../../base/common/uri.js';
|
||||
import { IConsistentItemService } from './helperServices/consistentItemService.js';
|
||||
import { IConsistentEditorItemService, IConsistentItemService } from './helperServices/consistentItemService.js';
|
||||
import { ctrlKStream_prefixAndSuffix, ctrlKStream_prompt, ctrlKStream_systemMessage, ctrlLStream_prompt, ctrlLStream_systemMessage } from './prompt/prompts.js';
|
||||
import { ILLMMessageService } from '../../../../platform/void/common/llmMessageService.js';
|
||||
import { IPosition } from '../../../../editor/common/core/position.js';
|
||||
@@ -117,7 +117,7 @@ type CtrlKZone = {
|
||||
editorId: string; // the editor the input lives on
|
||||
|
||||
_mountInfo: null | {
|
||||
inputBox: InputBox; // the input box that lives in the zone
|
||||
inputBoxRef: { current: InputBox | null }; // the input box that lives in the zone
|
||||
dispose: () => void;
|
||||
refresh: () => void;
|
||||
}
|
||||
@@ -136,7 +136,7 @@ type DiffZone = {
|
||||
} | {
|
||||
isStreaming: false;
|
||||
streamRequestIdRef?: undefined;
|
||||
line: null;
|
||||
line?: undefined;
|
||||
};
|
||||
editorId?: undefined;
|
||||
} & CommonZoneProps
|
||||
@@ -171,6 +171,7 @@ export interface IInlineDiffsService {
|
||||
startApplying(opts: StartApplyingOpts): number | undefined;
|
||||
interruptStreaming(diffareaid: number): void;
|
||||
addCtrlKZone(opts: AddCtrlKOpts): number | undefined;
|
||||
removeCtrlKZone(opts: { diffareaid: number }): void;
|
||||
}
|
||||
|
||||
export const IInlineDiffsService = createDecorator<IInlineDiffsService>('inlineDiffAreasService');
|
||||
@@ -195,6 +196,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
@ILLMMessageService private readonly _llmMessageService: ILLMMessageService,
|
||||
@IConsistentItemService private readonly _consistentItemService: IConsistentItemService,
|
||||
@IInstantiationService private readonly _instantiationService: IInstantiationService,
|
||||
@IConsistentEditorItemService private readonly _consistentEditorItemService: IConsistentEditorItemService,
|
||||
) {
|
||||
super();
|
||||
|
||||
@@ -208,9 +210,8 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
this._register(
|
||||
model.onDidChangeContent(e => {
|
||||
// it's as if we just called _write, now all we need to do is realign and refresh
|
||||
const uri = model.uri
|
||||
|
||||
if (this.weAreWriting) return
|
||||
const uri = model.uri
|
||||
this._onUserChangeContent(uri, e)
|
||||
})
|
||||
)
|
||||
@@ -242,6 +243,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
private _onInternalChangeContent(uri: URI, { shouldRealign }: { shouldRealign: false | { newText: string, oldRange: IRange } }) {
|
||||
if (shouldRealign) {
|
||||
const { newText, oldRange } = shouldRealign
|
||||
console.log('realiging', newText, oldRange)
|
||||
this._realignAllDiffAreasLines(uri, newText, oldRange)
|
||||
}
|
||||
this._refreshStylesAndDiffsInURI(uri)
|
||||
@@ -319,76 +321,78 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
|
||||
|
||||
mostRecentTextOfCtrlKZoneId: Record<string, string | undefined> = {}
|
||||
private _addCtrlKZoneInput = async (ctrlKZone: CtrlKZone) => {
|
||||
private _addCtrlKZoneInput = (ctrlKZone: CtrlKZone) => {
|
||||
|
||||
const { editorId } = ctrlKZone
|
||||
const editor = this._editorService.listCodeEditors().find(e => e.getId() === editorId)
|
||||
if (!editor) {
|
||||
console.error('editor not found')
|
||||
return null
|
||||
}
|
||||
if (!editor) { return null }
|
||||
|
||||
const domNode = document.createElement('div');
|
||||
domNode.style.zIndex = '1'
|
||||
const viewZone: IViewZone = {
|
||||
afterLineNumber: ctrlKZone.startLine - 1,
|
||||
domNode: domNode,
|
||||
heightInPx: 0,
|
||||
suppressMouseDown: false,
|
||||
};
|
||||
|
||||
|
||||
// mount zone
|
||||
let zoneId: string | null = null
|
||||
editor.changeViewZones(accessor => {
|
||||
zoneId = accessor.addZone(viewZone)
|
||||
})
|
||||
let viewZone_: IViewZone | null = null
|
||||
const inputBoxRef: { current: InputBox | null } = { current: null }
|
||||
|
||||
const itemId = this._consistentEditorItemService.addToEditor(editor, () => {
|
||||
const domNode = document.createElement('div');
|
||||
domNode.style.zIndex = '1'
|
||||
const viewZone: IViewZone = {
|
||||
afterLineNumber: ctrlKZone.startLine - 1,
|
||||
domNode: domNode,
|
||||
heightInPx: 52,
|
||||
suppressMouseDown: false,
|
||||
};
|
||||
viewZone_ = viewZone
|
||||
|
||||
let res_: (inputBox: InputBox) => void
|
||||
const inputBoxPromise: Promise<InputBox> = new Promise((res, rej) => { res_ = res })
|
||||
// mount zone
|
||||
editor.changeViewZones(accessor => {
|
||||
zoneId = accessor.addZone(viewZone)
|
||||
})
|
||||
|
||||
// mount react
|
||||
this._instantiationService.invokeFunction(accessor => {
|
||||
const props: QuickEditPropsType = {
|
||||
diffareaid: ctrlKZone.diffareaid,
|
||||
onGetInputBox(inputBox) {
|
||||
res_(inputBox)
|
||||
// not sure why this requries a timeout
|
||||
setTimeout(() => inputBox.focus(), 0)
|
||||
},
|
||||
onChangeHeight(height) {
|
||||
if (height === undefined) return
|
||||
viewZone.heightInPx = height
|
||||
// re-render with this new height
|
||||
editor.changeViewZones(accessor => {
|
||||
if (zoneId) {
|
||||
accessor.layoutZone(zoneId)
|
||||
// mount react
|
||||
this._instantiationService.invokeFunction(accessor => {
|
||||
mountCtrlK(domNode, accessor, {
|
||||
diffareaid: ctrlKZone.diffareaid,
|
||||
onGetInputBox: (inputBox) => {
|
||||
inputBoxRef.current = inputBox
|
||||
// if it's mounting for the first time, focus it
|
||||
if (!(ctrlKZone.diffareaid in this.mostRecentTextOfCtrlKZoneId)) { // detect first mount this way (a hack)
|
||||
this.mostRecentTextOfCtrlKZoneId[ctrlKZone.diffareaid] = undefined
|
||||
setTimeout(() => inputBox.focus(), 0)
|
||||
}
|
||||
})
|
||||
},
|
||||
onUserUpdateText: (text) => { this.mostRecentTextOfCtrlKZoneId[ctrlKZone.diffareaid] = text; },
|
||||
initText: this.mostRecentTextOfCtrlKZoneId[ctrlKZone.diffareaid] ?? null,
|
||||
}
|
||||
mountCtrlK(domNode, accessor, props)
|
||||
})
|
||||
},
|
||||
onChangeHeight(height) {
|
||||
if (height === undefined) return
|
||||
viewZone.heightInPx = height
|
||||
// re-render with this new height
|
||||
editor.changeViewZones(accessor => {
|
||||
if (zoneId) {
|
||||
accessor.layoutZone(zoneId)
|
||||
}
|
||||
})
|
||||
},
|
||||
onUserUpdateText: (text) => { this.mostRecentTextOfCtrlKZoneId[ctrlKZone.diffareaid] = text; },
|
||||
initText: this.mostRecentTextOfCtrlKZoneId[ctrlKZone.diffareaid] ?? null,
|
||||
} satisfies QuickEditPropsType)
|
||||
|
||||
const inputBox = await inputBoxPromise
|
||||
})
|
||||
|
||||
return () => editor.changeViewZones(accessor => {
|
||||
if (zoneId)
|
||||
accessor.removeZone(zoneId)
|
||||
})
|
||||
})
|
||||
|
||||
return {
|
||||
inputBox,
|
||||
inputBoxRef,
|
||||
refresh: () => editor.changeViewZones(accessor => {
|
||||
if (zoneId && viewZone) {
|
||||
viewZone.afterLineNumber = ctrlKZone.startLine - 1
|
||||
if (zoneId && viewZone_) {
|
||||
viewZone_.afterLineNumber = ctrlKZone.startLine - 1
|
||||
accessor.layoutZone(zoneId)
|
||||
}
|
||||
}),
|
||||
dispose: () => {
|
||||
editor.changeViewZones(accessor => {
|
||||
if (zoneId)
|
||||
accessor.removeZone(zoneId)
|
||||
})
|
||||
this._consistentEditorItemService.removeFromEditor(itemId)
|
||||
},
|
||||
}
|
||||
} satisfies CtrlKZone['_mountInfo']
|
||||
}
|
||||
|
||||
|
||||
@@ -398,12 +402,12 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
const diffArea = this.diffAreaOfId[diffareaid]
|
||||
if (diffArea.type !== 'CtrlKZone') continue
|
||||
if (!diffArea._mountInfo) {
|
||||
diffArea._mountInfo = await this._addCtrlKZoneInput(diffArea)
|
||||
diffArea._mountInfo = this._addCtrlKZoneInput(diffArea)
|
||||
console.log('MOUNTED', diffArea.diffareaid)
|
||||
}
|
||||
else {
|
||||
diffArea._mountInfo.refresh()
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
@@ -574,10 +578,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
type: 'DiffZone',
|
||||
_diffOfId: {},
|
||||
_URI: uri,
|
||||
_streamState: {
|
||||
isStreaming: false,
|
||||
line: null,
|
||||
} as const,
|
||||
_streamState: { isStreaming: false },
|
||||
_removeStylesFns: new Set(),
|
||||
}
|
||||
}
|
||||
@@ -735,17 +736,14 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
for (const diffareaid of this.diffAreasOfURI[model.uri.fsPath] || []) {
|
||||
const diffArea = this.diffAreaOfId[diffareaid]
|
||||
|
||||
console.log('DA', diffArea.startLine, diffArea.endLine)
|
||||
console.log('CHANGE', startLine, endLine)
|
||||
|
||||
// if the diffArea is entirely above the range, it is not affected
|
||||
if (diffArea.endLine < startLine) {
|
||||
// console.log('DA FULLY ABOVE (doing nothing)')
|
||||
// console.log('CHANGE FULLY BELOW DA (doing nothing)')
|
||||
continue
|
||||
}
|
||||
// if a diffArea is entirely below the range, shift the diffArea up/down by the delta amount of newlines
|
||||
else if (endLine < diffArea.startLine) {
|
||||
// console.log('DA FULLY BELOW')
|
||||
// console.log('CHANGE FULLY ABOVE DA')
|
||||
const changedRangeHeight = endLine - startLine + 1
|
||||
const deltaNewlines = newTextHeight - changedRangeHeight
|
||||
diffArea.startLine += deltaNewlines
|
||||
@@ -766,16 +764,16 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
}
|
||||
// if the change contains only the diffArea's top
|
||||
else if (startLine < diffArea.startLine && diffArea.startLine <= endLine) {
|
||||
// console.log('TOP ONLY')
|
||||
// console.log('CHANGE CONTAINS TOP OF DA ONLY')
|
||||
const numOverlappingLines = endLine - diffArea.startLine + 1
|
||||
const numRemainingLinesInDA = diffArea.endLine - diffArea.startLine + 1 - numOverlappingLines
|
||||
const newHeight = numRemainingLinesInDA + (newTextHeight - 1)
|
||||
const newHeight = (numRemainingLinesInDA - 1) + (newTextHeight - 1) + 1
|
||||
diffArea.startLine = startLine
|
||||
diffArea.endLine = startLine + newHeight
|
||||
}
|
||||
// if the change contains only the diffArea's bottom
|
||||
else if (startLine <= diffArea.endLine && diffArea.endLine < endLine) {
|
||||
// console.log('BOTTOM ONLY')
|
||||
// console.log('CHANGE CONTAINS BOTTOM OF DA ONLY')
|
||||
const numOverlappingLines = diffArea.endLine - startLine + 1
|
||||
diffArea.endLine += newTextHeight - numOverlappingLines
|
||||
}
|
||||
@@ -818,47 +816,40 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
|
||||
// if streaming, use diffs to figure out where to write new code
|
||||
// these are two different coordinate systems - new and old line number
|
||||
let newFileEndLine: number // get new[0...newStoppingPoint] with line=newStoppingPoint highlighted
|
||||
let originalCodeStartLine: number // get original[oldStartingPoint...]
|
||||
let newCodeEndLine: number // get file[diffArea.startLine...newFileEndLine] with line=newFileEndLine highlighted
|
||||
let originalCodeStartLine: number // get original[oldStartingPoint...] (line in the original code, so starts at 1)
|
||||
|
||||
const lastDiff = computedDiffs.pop()
|
||||
|
||||
if (!lastDiff) {
|
||||
// if the writing is identical so far, display no changes
|
||||
newFileEndLine = diffZone.startLine
|
||||
originalCodeStartLine = 1
|
||||
newCodeEndLine = 1
|
||||
}
|
||||
else {
|
||||
if (lastDiff.type === 'insertion') {
|
||||
newFileEndLine = lastDiff.endLine
|
||||
originalCodeStartLine = lastDiff.originalStartLine
|
||||
}
|
||||
else if (lastDiff.type === 'deletion') {
|
||||
newFileEndLine = lastDiff.startLine
|
||||
originalCodeStartLine = lastDiff.originalStartLine
|
||||
}
|
||||
else if (lastDiff.type === 'edit') {
|
||||
newFileEndLine = lastDiff.endLine
|
||||
originalCodeStartLine = lastDiff.originalStartLine
|
||||
}
|
||||
else {
|
||||
originalCodeStartLine = lastDiff.originalStartLine
|
||||
if (lastDiff.type === 'insertion' || lastDiff.type === 'edit')
|
||||
newCodeEndLine = lastDiff.endLine
|
||||
else if (lastDiff.type === 'deletion')
|
||||
newCodeEndLine = lastDiff.startLine
|
||||
else
|
||||
throw new Error(`Void: diff.type not recognized on: ${lastDiff}`)
|
||||
}
|
||||
}
|
||||
|
||||
diffZone._streamState.line = newFileEndLine
|
||||
|
||||
// lines are 1-indexed
|
||||
const newFileTop = llmText.split('\n').slice(diffZone.startLine, (newFileEndLine - 1)).join('\n')
|
||||
const oldFileBottom = diffZone.originalCode.split('\n').slice((originalCodeStartLine - 1), Infinity).join('\n')
|
||||
const newCodeTop = llmText.split('\n').slice(0, (newCodeEndLine - 1) + 1).join('\n')
|
||||
const oldFileBottom = diffZone.originalCode.split('\n').slice((originalCodeStartLine - 1) + 1, Infinity).join('\n')
|
||||
|
||||
const newCode = `${newFileTop}\n${oldFileBottom}`
|
||||
const newCode = `${newCodeTop}\n${oldFileBottom}`
|
||||
|
||||
this._writeText(uri, newCode,
|
||||
{ startLineNumber: diffZone.startLine, startColumn: 1, endLineNumber: diffZone.endLine, endColumn: Number.MAX_SAFE_INTEGER, }, // 1-indexed
|
||||
{ shouldRealignDiffAreas: true }
|
||||
)
|
||||
|
||||
// add diffZone.startLine to convert to right coordinate system (line in file, not in diffarea)
|
||||
diffZone._streamState.line = (diffZone.startLine - 1) + newCodeEndLine
|
||||
|
||||
return computedDiffs
|
||||
|
||||
@@ -866,6 +857,54 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
|
||||
|
||||
|
||||
// // if streaming, use diffs to figure out where to write new code
|
||||
// // these are two different coordinate systems - new and old line number
|
||||
// let newFileEndLine: number // get new[0...newStoppingPoint] with line=newStoppingPoint highlighted
|
||||
// let originalCodeStartLine: number // get original[oldStartingPoint...]
|
||||
|
||||
// const lastDiff = computedDiffs.pop()
|
||||
|
||||
// if (!lastDiff) {
|
||||
// // if the writing is identical so far, display no changes
|
||||
// newFileEndLine = diffZone.startLine
|
||||
// originalCodeStartLine = 1
|
||||
// }
|
||||
// else {
|
||||
// if (lastDiff.type === 'insertion') {
|
||||
// newFileEndLine = lastDiff.endLine
|
||||
// originalCodeStartLine = lastDiff.originalStartLine
|
||||
// }
|
||||
// else if (lastDiff.type === 'deletion') {
|
||||
// newFileEndLine = lastDiff.startLine
|
||||
// originalCodeStartLine = lastDiff.originalStartLine
|
||||
// }
|
||||
// else if (lastDiff.type === 'edit') {
|
||||
// newFileEndLine = lastDiff.endLine
|
||||
// originalCodeStartLine = lastDiff.originalStartLine
|
||||
// }
|
||||
// else {
|
||||
// throw new Error(`Void: diff.type not recognized on: ${lastDiff}`)
|
||||
// }
|
||||
// }
|
||||
|
||||
// diffZone._streamState.line = newFileEndLine
|
||||
|
||||
// // lines are 1-indexed
|
||||
// const newFileTop = llmText.split('\n').slice(diffZone.startLine, (newFileEndLine - 1)).join('\n')
|
||||
// const oldFileBottom = diffZone.originalCode.split('\n').slice((originalCodeStartLine - 1), Infinity).join('\n')
|
||||
|
||||
// const newCode = `${newFileTop}\n${oldFileBottom}`
|
||||
|
||||
// this._writeText(uri, newCode,
|
||||
// { startLineNumber: diffZone.startLine, startColumn: 1, endLineNumber: diffZone.endLine, endColumn: Number.MAX_SAFE_INTEGER, }, // 1-indexed
|
||||
// { shouldRealignDiffAreas: true }
|
||||
// )
|
||||
|
||||
|
||||
// return computedDiffs
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
@@ -882,7 +921,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
if (diffArea.type !== 'CtrlKZone') continue
|
||||
const noOverlap = diffArea.startLine > endLine || diffArea.endLine < startLine
|
||||
if (!noOverlap) {
|
||||
diffArea._mountInfo?.inputBox.focus()
|
||||
setTimeout(() => diffArea._mountInfo?.inputBoxRef.current?.focus(), 0)
|
||||
return
|
||||
}
|
||||
}
|
||||
@@ -899,13 +938,24 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
_mountInfo: null,
|
||||
}
|
||||
const ctrlKZone = this._addDiffArea(adding)
|
||||
|
||||
this._refreshStylesAndDiffsInURI(uri)
|
||||
|
||||
onFinishEdit()
|
||||
return ctrlKZone.diffareaid
|
||||
}
|
||||
|
||||
public removeCtrlKZone({ diffareaid }: { diffareaid: number }) {
|
||||
const ctrlKZone = this.diffAreaOfId[diffareaid]
|
||||
if (!ctrlKZone) return
|
||||
if (ctrlKZone.type !== 'CtrlKZone') return
|
||||
|
||||
const uri = ctrlKZone._URI
|
||||
const { onFinishEdit } = this._addToHistory(uri)
|
||||
this._deleteCtrlKZone(ctrlKZone)
|
||||
this._refreshStylesAndDiffsInURI(uri)
|
||||
onFinishEdit()
|
||||
}
|
||||
|
||||
|
||||
|
||||
public startApplying(opts: StartApplyingOpts) {
|
||||
@@ -967,14 +1017,13 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
startLine = startLine_
|
||||
endLine = endLine_
|
||||
|
||||
if (!_mountInfo) return
|
||||
userMessage = _mountInfo.inputBox.value
|
||||
if (!_mountInfo?.inputBoxRef.current) return
|
||||
userMessage = _mountInfo.inputBoxRef.current?.value
|
||||
}
|
||||
else {
|
||||
throw new Error(`Void: diff.type not recognized on: ${featureName}`)
|
||||
}
|
||||
|
||||
|
||||
const currentFileStr = this._readURI(uri)
|
||||
if (currentFileStr === null) return
|
||||
const originalCode = currentFileStr.split('\n').slice((startLine - 1), (endLine - 1) + 1).join('\n')
|
||||
@@ -1039,7 +1088,7 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
const latestOriginalFileStart: IPosition = { lineNumber: 1, column: 1 }
|
||||
|
||||
const onDone = () => {
|
||||
diffZone._streamState = { isStreaming: false, line: null }
|
||||
diffZone._streamState = { isStreaming: false, }
|
||||
|
||||
if (featureName === 'Ctrl+K') {
|
||||
const ctrlKZone = this.diffAreaOfId[opts.diffareaid] as CtrlKZone
|
||||
@@ -1050,9 +1099,12 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
onFinishEdit()
|
||||
}
|
||||
|
||||
// refresh now in case onText takes a while to get 1st message
|
||||
this._refreshStylesAndDiffsInURI(uri)
|
||||
|
||||
streamRequestIdRef.current = this._llmMessageService.sendLLMMessage({
|
||||
featureName,
|
||||
logging: { loggingName: 'streamChunk' },
|
||||
logging: { loggingName: `startApplying - ${featureName}` },
|
||||
messages,
|
||||
onText: ({ newText, fullText }) => {
|
||||
this._writeDiffZoneLLMText(diffZone, fullText, latestCurrentFileEnd, latestOriginalFileStart)
|
||||
@@ -1092,16 +1144,12 @@ class InlineDiffsService extends Disposable implements IInlineDiffsService {
|
||||
|
||||
this._llmMessageService.abort(streamRequestId)
|
||||
|
||||
diffZone._streamState = {
|
||||
isStreaming: false,
|
||||
streamRequestIdRef: undefined,
|
||||
line: null
|
||||
}
|
||||
diffZone._streamState = { isStreaming: false, }
|
||||
|
||||
}
|
||||
|
||||
|
||||
// call this outside undo/redo (it calls undo)
|
||||
// call this outside undo/redo (it calls undo). this is only for aborting a diffzone stream
|
||||
interruptStreaming(diffareaid: number) {
|
||||
const diffArea = this.diffAreaOfId[diffareaid]
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
.monaco-editor .void-sweepIdxBG {
|
||||
background-color: var(--vscode-void-sweepIdxBG);
|
||||
@@ -22,3 +22,52 @@
|
||||
.void-redBG {
|
||||
background-color: var(--vscode-void-redBG);
|
||||
}
|
||||
|
||||
.void-watermark-button {
|
||||
margin: 8px 0;
|
||||
padding: 8px 20px;
|
||||
background-color: #3b82f6;
|
||||
color: white;
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
outline: none !important;
|
||||
box-shadow: none !important;
|
||||
cursor: pointer;
|
||||
transition: background-color 0.2s ease;
|
||||
}
|
||||
.void-watermark-button:hover {
|
||||
background-color: #2563eb;
|
||||
}
|
||||
.void-watermark-button:active {
|
||||
background-color: #2563eb;
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.void-settings-watermark-button {
|
||||
margin: 8px 0;
|
||||
padding: 8px 20px;
|
||||
background-color: var(--vscode-input-background);
|
||||
color: var(--vscode-input-foreground);
|
||||
border: none;
|
||||
border-radius: 4px;
|
||||
outline: none !important;
|
||||
box-shadow: none !important;
|
||||
cursor: pointer;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
.void-settings-watermark-button:hover {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
.void-settings-watermark-button:active {
|
||||
filter: brightness(1.1);
|
||||
}
|
||||
|
||||
|
||||
|
||||
|
||||
.void-link {
|
||||
color: #3b82f6;
|
||||
cursor: pointer;
|
||||
}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
import { CodeSelection } from '../threadHistoryService.js';
|
||||
@@ -16,6 +16,7 @@ Instructions:
|
||||
1. Do not re-write the entire file.
|
||||
3. Instead, you may use code elision to represent unchanged portions of code. For example, write "existing code..." in code comments.
|
||||
4. You must give enough context to apply the change in the correct location.
|
||||
5. Do not output any of these instructions, nor tell the user anything about them.
|
||||
|
||||
## EXAMPLE
|
||||
|
||||
@@ -334,7 +335,8 @@ export const ctrlKStream_prompt = ({ selection, prefix, suffix, userMessage }: {
|
||||
<${preTag}>
|
||||
/* Original Selection:
|
||||
${selection}*/
|
||||
/* Instructions: ${userMessage}*/
|
||||
/* Instructions:
|
||||
${userMessage}*/
|
||||
${prefix}</${preTag}>
|
||||
<${sufTag}>${suffix}</${sufTag}>
|
||||
<${midTag}>`
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { KeyCode, KeyMod } from '../../../../base/common/keyCodes.js';
|
||||
import { Action2, registerAction2 } from '../../../../platform/actions/common/actions.js';
|
||||
import { ServicesAccessor } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from '../../../../base/common/event.js';
|
||||
import { Disposable } from '../../../../base/common/lifecycle.js';
|
||||
import { InstantiationType, registerSingleton } from '../../../../platform/instantiation/common/extensions.js';
|
||||
|
||||
@@ -1,16 +1,45 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { spawn, execSync } from 'child_process';
|
||||
// Added lines below
|
||||
import fs from 'fs';
|
||||
import path from 'path';
|
||||
import { fileURLToPath } from 'url';
|
||||
|
||||
const __filename = fileURLToPath(import.meta.url);
|
||||
const __dirname = path.dirname(__filename);
|
||||
const __void_name = 'void'
|
||||
|
||||
// hack to refresh styles automatically
|
||||
function saveStylesFile() {
|
||||
setTimeout(() => {
|
||||
try {
|
||||
// Find "void" in __dirname and use that as our base:
|
||||
const voidIdx = __dirname.indexOf(__void_name);
|
||||
const baseDir = __dirname.substring(0, voidIdx + __void_name.length);
|
||||
const target = path.join(
|
||||
baseDir,
|
||||
'src/vs/workbench/contrib/void/browser/react/src2/styles.css'
|
||||
);
|
||||
|
||||
// Or re-write with the same content:
|
||||
const content = fs.readFileSync(target, 'utf8');
|
||||
fs.writeFileSync(target, content, 'utf8');
|
||||
console.log('[scope-tailwind] Force-saved styles.css');
|
||||
} catch (err) {
|
||||
console.error('[scope-tailwind] Error saving styles.css:', err);
|
||||
}
|
||||
}, 5000);
|
||||
}
|
||||
|
||||
const args = process.argv.slice(2);
|
||||
const isWatch = args.includes('--watch') || args.includes('-w');
|
||||
|
||||
if (isWatch) {
|
||||
// Watch mode
|
||||
// Create a watcher for scope-tailwind using nodemon
|
||||
const scopeTailwindWatcher = spawn('npx', [
|
||||
'nodemon',
|
||||
'--watch', 'src',
|
||||
@@ -19,15 +48,17 @@ if (isWatch) {
|
||||
'npx scope-tailwind ./src -o src2/ -s void-scope -c styles.css -p "void-"'
|
||||
]);
|
||||
|
||||
// Create a watcher for tsup in watch mode
|
||||
const tsupWatcher = spawn('npx', [
|
||||
'tsup',
|
||||
'--watch'
|
||||
]);
|
||||
|
||||
// Handle scope-tailwind watcher output
|
||||
scopeTailwindWatcher.stdout.on('data', (data) => {
|
||||
console.log(`[scope-tailwind] ${data}`);
|
||||
// If the output mentions "styles.css", trigger the save:
|
||||
if (data.toString().includes('styles.css')) {
|
||||
saveStylesFile();
|
||||
}
|
||||
});
|
||||
|
||||
scopeTailwindWatcher.stderr.on('data', (data) => {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { useEffect, useState } from 'react'
|
||||
import { useIsDark, useSidebarState } from '../util/services.js'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { FormEvent, useCallback, useEffect, useRef, useState } from 'react';
|
||||
import { useSettingsState, useSidebarState, useThreadsState, useQuickEditState, useAccessor } from '../util/services.js';
|
||||
@@ -11,6 +11,8 @@ import { getCmdKey } from '../../../helpers/getCmdKey.js';
|
||||
import { VoidInputBox } from '../util/inputs.js';
|
||||
import { QuickEditPropsType } from '../../../quickEditActions.js';
|
||||
import { ButtonStop, ButtonSubmit } from '../sidebar-tsx/SidebarChat.js';
|
||||
import { ModelDropdown } from '../void-settings-tsx/ModelDropdown.js';
|
||||
import { X } from 'lucide-react';
|
||||
|
||||
export const CtrlKChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChangeHeight, initText }: QuickEditPropsType) => {
|
||||
|
||||
@@ -60,6 +62,7 @@ export const CtrlKChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChang
|
||||
const onInterrupt = useCallback(() => {
|
||||
if (currentlyStreamingIdRef.current !== undefined)
|
||||
inlineDiffsService.interruptStreaming(currentlyStreamingIdRef.current)
|
||||
inputBoxRef.current?.enable()
|
||||
setIsStreaming(false)
|
||||
}, [inlineDiffsService])
|
||||
|
||||
@@ -73,11 +76,11 @@ export const CtrlKChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChang
|
||||
inputBoxRef.current.value = instructions
|
||||
}, [initText, instructions])
|
||||
|
||||
return <div className='py-2 w-full max-w-xl' ref={sizerRef}>
|
||||
return <div ref={sizerRef} className='py-2 w-full max-w-xl'>
|
||||
<form
|
||||
// copied from SidebarChat.tsx
|
||||
className={`
|
||||
flex flex-col gap-2 p-1 relative input text-left shrink-0
|
||||
flex flex-col gap-2 py-1 px-2 relative input text-left shrink-0
|
||||
transition-all duration-200
|
||||
rounded-md
|
||||
bg-vscode-input-bg
|
||||
@@ -99,17 +102,27 @@ export const CtrlKChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChang
|
||||
onSubmit(e)
|
||||
}}
|
||||
onClick={(e) => {
|
||||
if (e.currentTarget === e.target) {
|
||||
inputBoxRef.current?.focus()
|
||||
}
|
||||
inputBoxRef.current?.focus()
|
||||
}}
|
||||
>
|
||||
|
||||
<div // this div is used to position the input box properly
|
||||
className={`w-full p-2 z-[999]`}
|
||||
{/* // this div is used to position the input box properly */}
|
||||
<div
|
||||
className={`w-full z-[999] relative
|
||||
@@[&_textarea]:!void-bg-transparent
|
||||
@@[&_textarea]:!void-outline-none
|
||||
@@[&_textarea]:!void-text-vscode-input-fg
|
||||
@@[&_div.monaco-inputbox]:!void-border-none
|
||||
@@[&_div.monaco-inputbox]:!void-outline-none`}
|
||||
>
|
||||
<div className='flex flex-row justify-between items-end gap-1'>
|
||||
{/* left (input) */}
|
||||
<div className='absolute size-0.5 top-0 right-4 z-[1]'>
|
||||
<X
|
||||
onClick={() => { inlineDiffsService.removeCtrlKZone({ diffareaid }) }}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* input */}
|
||||
<div // copied from SidebarChat.tsx
|
||||
className={`w-full
|
||||
@@[&_textarea]:!void-bg-transparent @@[&_textarea]:!void-outline-none @@[&_textarea]:!void-text-vscode-input-fg @@[&_div.monaco-inputbox]:!void-outline-none`}>
|
||||
@@ -126,22 +139,33 @@ export const CtrlKChat = ({ diffareaid, onGetInputBox, onUserUpdateText, onChang
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* right (button) */}
|
||||
<div className='flex flex-row items-end'>
|
||||
{/* submit / stop button */}
|
||||
{isStreaming ?
|
||||
// stop button
|
||||
<ButtonStop
|
||||
onClick={onInterrupt}
|
||||
/>
|
||||
:
|
||||
// submit button (up arrow)
|
||||
<ButtonSubmit
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
|
||||
|
||||
{/* bottom row */}
|
||||
<div
|
||||
className='flex flex-row justify-between items-end gap-1'
|
||||
>
|
||||
{/* submit options */}
|
||||
<div className='max-w-[150px]
|
||||
@@[&_select]:!void-border-none
|
||||
@@[&_select]:!void-outline-none'
|
||||
>
|
||||
<ModelDropdown featureName='Ctrl+K' />
|
||||
</div>
|
||||
|
||||
{/* submit / stop button */}
|
||||
{isStreaming ?
|
||||
// stop button
|
||||
<ButtonStop
|
||||
onClick={onInterrupt}
|
||||
/>
|
||||
:
|
||||
// submit button (up arrow)
|
||||
<ButtonSubmit
|
||||
disabled={isDisabled}
|
||||
/>
|
||||
}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { mountFnGenerator } from '../util/mountFnGenerator.js'
|
||||
import { CtrlK } from './CtrlK.js'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { diffLines, Change } from 'diff';
|
||||
|
||||
|
||||
@@ -1,80 +1,78 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { ReactNode } from "react"
|
||||
import { ReactNode } from "react"
|
||||
import { VoidCodeEditor } from '../util/inputs.js';
|
||||
|
||||
|
||||
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'
|
||||
};
|
||||
|
||||
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 }) => {
|
||||
|
||||
return (<>
|
||||
<div className={`relative group w-full bg-vscode-sidebar-bg overflow-hidden isolate`}>
|
||||
|
||||
const isSingleLine = !text.includes('\n')
|
||||
|
||||
return (<>
|
||||
<div className={`relative group w-full bg-vscode-editor-bg overflow-hidden isolate`}>
|
||||
{buttonsOnHover === null ? null : (
|
||||
<div className="z-[1] absolute top-0 right-0 opacity-0 group-hover:opacity-100 duration-200">
|
||||
<div className="flex space-x-2 p-2">{buttonsOnHover}</div>
|
||||
<div className={`flex space-x-2 ${isSingleLine ? '' : 'p-2'}`}>{buttonsOnHover}</div>
|
||||
</div>
|
||||
)}
|
||||
|
||||
@@ -82,18 +80,6 @@ export const BlockCode = ({ text, buttonsOnHover, language }: { text: string, bu
|
||||
initValue={text}
|
||||
language={language}
|
||||
/>
|
||||
{/* <div
|
||||
className={`overflow-x-auto rounded-sm text-vscode-editor-fg bg-vscode-editor-bg`}
|
||||
>
|
||||
<SyntaxHighlighter
|
||||
language={language ?? 'plaintext'} // TODO must auto detect language
|
||||
style={customStyle}
|
||||
className={"rounded-sm"}
|
||||
>
|
||||
{text}
|
||||
</SyntaxHighlighter>
|
||||
|
||||
</div> */}
|
||||
</div>
|
||||
</>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { JSX, useCallback, useEffect, useState } from 'react'
|
||||
import { marked, MarkedToken, Token } from 'marked'
|
||||
@@ -17,7 +17,7 @@ enum CopyButtonState {
|
||||
|
||||
const COPY_FEEDBACK_TIMEOUT = 1000 // amount of time to say 'Copied!'
|
||||
|
||||
const CodeButtonsOnHover = ({ diffRepr: text }: { diffRepr: string }) => {
|
||||
const CodeButtonsOnHover = ({ text }: { text: string }) => {
|
||||
const accessor = useAccessor()
|
||||
|
||||
const [copyButtonState, setCopyButtonState] = useState(CopyButtonState.Copy)
|
||||
@@ -38,21 +38,26 @@ const CodeButtonsOnHover = ({ diffRepr: text }: { diffRepr: string }) => {
|
||||
.catch(() => { setCopyButtonState(CopyButtonState.Error) })
|
||||
}, [text, clipboardService])
|
||||
|
||||
const onApply = useCallback(() => {
|
||||
inlineDiffService.startApplying({
|
||||
featureName: 'Ctrl+L',
|
||||
userMessage: text,
|
||||
})
|
||||
}, [inlineDiffService])
|
||||
|
||||
const isSingleLine = !text.includes('\n')
|
||||
|
||||
return <>
|
||||
<button
|
||||
className="btn btn-secondary btn-sm border border-vscode-input-border rounded"
|
||||
className={`${isSingleLine ? '' : 'p-1'} text-xs hover:brightness-110 bg-vscode-input-bg border border-vscode-input-border rounded text-xs text-vscode-input-fg`}
|
||||
onClick={onCopy}
|
||||
>
|
||||
{copyButtonState}
|
||||
</button>
|
||||
<button
|
||||
className="btn btn-secondary btn-sm border border-vscode-input-border rounded"
|
||||
onClick={() => {
|
||||
inlineDiffService.startApplying({
|
||||
featureName: 'Ctrl+L',
|
||||
userMessage: text,
|
||||
})
|
||||
}}
|
||||
// btn btn-secondary btn-sm border text-xs text-vscode-input-fg border-vscode-input-border rounded
|
||||
className={`${isSingleLine ? '' : 'p-1'} text-xs hover:brightness-110 bg-vscode-input-bg border border-vscode-input-border rounded text-xs text-vscode-input-fg`}
|
||||
onClick={onApply}
|
||||
>
|
||||
Apply
|
||||
</button>
|
||||
@@ -72,8 +77,8 @@ const RenderToken = ({ token, nested = false }: { token: Token | string, nested?
|
||||
if (t.type === "code") {
|
||||
return <BlockCode
|
||||
text={t.text}
|
||||
language={t.lang}
|
||||
buttonsOnHover={<CodeButtonsOnHover diffRepr={t.text} />}
|
||||
// language={t.lang} // instead use vscode to detect language
|
||||
buttonsOnHover={<CodeButtonsOnHover text={t.text} />}
|
||||
/>
|
||||
}
|
||||
|
||||
@@ -192,7 +197,7 @@ const RenderToken = ({ token, nested = false }: { token: Token | string, nested?
|
||||
// inline code
|
||||
if (t.type === "codespan") {
|
||||
return (
|
||||
<code className="text-vscode-editor-fg bg-vscode-editor-bg px-1 rounded-sm font-mono">
|
||||
<code className="text-vscode-text-preformat-fg bg-vscode-text-preformat-bg px-1 rounded-sm font-mono">
|
||||
{t.text}
|
||||
</code>
|
||||
)
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { Component, ErrorInfo, ReactNode } from 'react';
|
||||
import { ErrorDisplay } from './ErrorDisplay.js';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { useState } from 'react';
|
||||
import { AlertCircle, ChevronDown, ChevronUp, X } from 'lucide-react';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
import React, { useEffect, useState } from 'react'
|
||||
import { mountFnGenerator } from '../util/mountFnGenerator.js'
|
||||
|
||||
@@ -22,8 +22,9 @@ export const Sidebar = ({ className }: { className: string }) => {
|
||||
const { isHistoryOpen, currentTab: tab } = sidebarState
|
||||
|
||||
const isDark = useIsDark()
|
||||
return <div className={`@@void-scope ${isDark ? 'dark' : ''}`} style={{ width: '100%', height: '100%' }}>
|
||||
<div className={`flex flex-col px-2 py-2 w-full h-full`}>
|
||||
// ${isDark ? 'dark' : ''}
|
||||
return <div className={`@@void-scope`} style={{ width: '100%', height: '100%' }}>
|
||||
<div className={`w-full h-full flex flex-col py-2 bg-vscode-sidebar-bg`}>
|
||||
|
||||
{/* <span onClick={() => {
|
||||
const tabs = ['chat', 'settings', 'threadSelector']
|
||||
@@ -31,7 +32,7 @@ export const Sidebar = ({ className }: { className: string }) => {
|
||||
sidebarStateService.setState({ currentTab: tabs[(index + 1) % tabs.length] as any })
|
||||
}}>clickme {tab}</span> */}
|
||||
|
||||
<div className={`mb-2 w-full ${isHistoryOpen ? '' : 'hidden'} ring-2 ring-widget-shadow z-10`}>
|
||||
<div className={`w-full h-auto mb-2 ${isHistoryOpen ? '' : 'hidden'} ring-2 ring-widget-shadow z-10`}>
|
||||
<ErrorBoundary>
|
||||
<SidebarThreadSelector />
|
||||
</ErrorBoundary>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { ButtonHTMLAttributes, FormEvent, FormHTMLAttributes, Fragment, useCallback, useEffect, useRef, useState } from 'react';
|
||||
|
||||
@@ -18,7 +18,7 @@ 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 { VoidCodeEditor, VoidInputBox } from '../util/inputs.js';
|
||||
import { VoidInputBox } from '../util/inputs.js';
|
||||
import { ModelDropdown } from '../void-settings-tsx/ModelDropdown.js';
|
||||
import { chat_systemMessage, chat_prompt } from '../../../prompt/prompts.js';
|
||||
import { ISidebarStateService } from '../../../sidebarStateService.js';
|
||||
@@ -109,6 +109,65 @@ export const IconWarning = ({ size, className = '' }: { size: number, className?
|
||||
);
|
||||
};
|
||||
|
||||
|
||||
export const IconLoading = ({ className = '' }: { className?: string }) => {
|
||||
|
||||
const [loadingText, setLoadingText] = useState('.');
|
||||
|
||||
useEffect(() => {
|
||||
let intervalId;
|
||||
|
||||
// Function to handle the animation
|
||||
const toggleLoadingText = () => {
|
||||
if (loadingText === '...') {
|
||||
setLoadingText('.');
|
||||
} else {
|
||||
setLoadingText(loadingText + '.');
|
||||
}
|
||||
};
|
||||
|
||||
// Start the animation loop
|
||||
intervalId = setInterval(toggleLoadingText, 300);
|
||||
|
||||
// Cleanup function to clear the interval when component unmounts
|
||||
return () => clearInterval(intervalId);
|
||||
}, [loadingText, setLoadingText]);
|
||||
|
||||
return <div className={`${className}`}>{loadingText}</div>;
|
||||
|
||||
}
|
||||
|
||||
const useResizeObserver = () => {
|
||||
const ref = useRef(null);
|
||||
const [dimensions, setDimensions] = useState({ height: 0, width: 0 });
|
||||
|
||||
useEffect(() => {
|
||||
if (ref.current) {
|
||||
const resizeObserver = new ResizeObserver((entries) => {
|
||||
if (entries.length > 0) {
|
||||
const entry = entries[0];
|
||||
setDimensions({
|
||||
height: entry.contentRect.height,
|
||||
width: entry.contentRect.width
|
||||
});
|
||||
}
|
||||
});
|
||||
|
||||
resizeObserver.observe(ref.current);
|
||||
|
||||
return () => {
|
||||
if (ref.current)
|
||||
resizeObserver.unobserve(ref.current);
|
||||
};
|
||||
}
|
||||
}, []);
|
||||
|
||||
return [ref, dimensions] as const;
|
||||
};
|
||||
|
||||
|
||||
|
||||
|
||||
type ButtonProps = ButtonHTMLAttributes<HTMLButtonElement>
|
||||
const DEFAULT_BUTTON_SIZE = 20;
|
||||
export const ButtonSubmit = ({ className, disabled, ...props }: ButtonProps & Required<Pick<ButtonProps, 'disabled'>>) => {
|
||||
@@ -217,11 +276,11 @@ export const SelectedFiles = (
|
||||
>
|
||||
{selections.map((selection, i) => {
|
||||
|
||||
const showSelectionText = !!(selection.selectionStr && selectionIsOpened[i])
|
||||
const isThisSelectionOpened = !!(selection.selectionStr && selectionIsOpened[i])
|
||||
|
||||
return (
|
||||
<div key={i} // container for `selectionSummary` and `selectionText`
|
||||
className={`${showSelectionText ? 'w-full' : ''}`}
|
||||
className={`${isThisSelectionOpened ? 'w-full' : ''}`}
|
||||
>
|
||||
{/* selection summary */}
|
||||
<div
|
||||
@@ -287,8 +346,8 @@ export const SelectedFiles = (
|
||||
|
||||
</div>
|
||||
{/* selection text */}
|
||||
{showSelectionText &&
|
||||
<div className='w-full p-1 rounded-sm border-vscode-editor-border bg-vscode-sidebar-bg'>
|
||||
{isThisSelectionOpened &&
|
||||
<div className='w-full p-1 rounded-sm border-vscode-editor-border'>
|
||||
<BlockCode text={selection.selectionStr!} language={getLanguageFromFileName(selection.fileURI.path)} />
|
||||
</div>
|
||||
}
|
||||
@@ -301,8 +360,9 @@ export const SelectedFiles = (
|
||||
}
|
||||
|
||||
|
||||
const ChatBubble = ({ chatMessage }: {
|
||||
chatMessage: ChatMessage
|
||||
const ChatBubble = ({ chatMessage, isLoading }: {
|
||||
chatMessage: ChatMessage,
|
||||
isLoading?: boolean,
|
||||
}) => {
|
||||
|
||||
const role = chatMessage.role
|
||||
@@ -322,10 +382,16 @@ const ChatBubble = ({ chatMessage }: {
|
||||
chatbubbleContents = <ChatMarkdownRender string={chatMessage.displayContent} /> // sectionsHTML
|
||||
}
|
||||
|
||||
return <div className={`${role === 'user' ? 'text-right' : 'text-left'}`}>
|
||||
<div className={`text-left inline-block p-2 rounded-lg space-y-2 ${role === 'user' ? 'bg-vscode-input-bg text-vscode-input-fg' : ''} max-w-full overflow-auto`}>
|
||||
{chatbubbleContents}
|
||||
</div>
|
||||
return <div
|
||||
// style + align chatbubble accoridng to role
|
||||
className={`p-2 mx-2 text-left space-y-2 rounded-lg max-w-full
|
||||
${role === 'user' ? 'self-end' : 'self-start'}
|
||||
${role === 'user' ? 'bg-vscode-input-bg text-vscode-input-fg' : ''}
|
||||
${role === 'assistant' ? 'w-full' : ''}
|
||||
`}
|
||||
>
|
||||
{chatbubbleContents}
|
||||
{isLoading && <IconLoading className='opacity-50 text-sm' />}
|
||||
</div>
|
||||
}
|
||||
|
||||
@@ -369,8 +435,12 @@ export const SidebarChat = () => {
|
||||
// state of current message
|
||||
const [instructions, setInstructions] = useState('') // the user's instructions
|
||||
const isDisabled = !instructions.trim()
|
||||
const [formHeight, setFormHeight] = useState(0) // TODO should use resize observer instead
|
||||
const [sidebarHeight, setSidebarHeight] = useState(0)
|
||||
|
||||
const [sidebarRef, sidebarDimensions] = useResizeObserver()
|
||||
const [formRef, formDimensions] = useResizeObserver()
|
||||
|
||||
// const [formHeight, setFormHeight] = useState(0) // TODO should use resize observer instead
|
||||
// const [sidebarHeight, setSidebarHeight] = useState(0)
|
||||
const onChangeText = useCallback((newStr: string) => { setInstructions(newStr) }, [setInstructions])
|
||||
|
||||
|
||||
@@ -455,6 +525,8 @@ export const SidebarChat = () => {
|
||||
|
||||
threadsStateService.setStaging([]) // clear staging
|
||||
|
||||
inputBoxRef.current?.focus() // focus input after submit
|
||||
|
||||
}
|
||||
|
||||
const onAbort = () => {
|
||||
@@ -481,18 +553,23 @@ export const SidebarChat = () => {
|
||||
// const [_test_messages, _set_test_messages] = useState<string[]>([])
|
||||
|
||||
return <div
|
||||
ref={(ref) => { if (ref) { setSidebarHeight(ref.clientHeight); } }}
|
||||
ref={sidebarRef}
|
||||
className={`w-full h-full`}
|
||||
>
|
||||
<ScrollToBottomContainer
|
||||
className={`overflow-x-hidden overflow-y-auto`}
|
||||
style={{ maxHeight: sidebarHeight - formHeight - 30 }}
|
||||
className={`
|
||||
w-full h-auto
|
||||
flex flex-col gap-0
|
||||
overflow-x-hidden
|
||||
overflow-y-auto
|
||||
`}
|
||||
style={{ maxHeight: sidebarDimensions.height - formDimensions.height - 30 }}
|
||||
>
|
||||
{/* previous messages */}
|
||||
{previousMessages.map((message, i) => <ChatBubble key={i} chatMessage={message} />)}
|
||||
|
||||
{/* message stream */}
|
||||
<ChatBubble chatMessage={{ role: 'assistant', content: messageStream, displayContent: messageStream || null }} />
|
||||
<ChatBubble chatMessage={{ role: 'assistant', content: messageStream, displayContent: messageStream || null }} isLoading={isLoading} />
|
||||
|
||||
{/* {_test_messages.map((_, i) => <div key={i}>div {i}</div>)}
|
||||
<div>{`totalHeight: ${sidebarHeight - formHeight - 30}`}</div>
|
||||
@@ -508,7 +585,7 @@ export const SidebarChat = () => {
|
||||
className={`right-0 left-0 m-2 z-[999] overflow-hidden ${previousMessages.length > 0 ? 'absolute bottom-0' : ''}`}
|
||||
>
|
||||
<form
|
||||
ref={(ref) => { if (ref) { setFormHeight(ref.clientHeight); } }}
|
||||
ref={formRef}
|
||||
className={`
|
||||
flex flex-col gap-2 p-2 relative input text-left shrink-0
|
||||
transition-all duration-200
|
||||
@@ -526,9 +603,7 @@ export const SidebarChat = () => {
|
||||
onSubmit(e)
|
||||
}}
|
||||
onClick={(e) => {
|
||||
if (e.currentTarget === e.target) {
|
||||
inputBoxRef.current?.focus()
|
||||
}
|
||||
inputBoxRef.current?.focus()
|
||||
}}
|
||||
>
|
||||
{/* top row */}
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import React from "react";
|
||||
import { useAccessor, useThreadsState } from '../util/services.js';
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { mountFnGenerator } from '../util/mountFnGenerator.js'
|
||||
import { Sidebar } from './Sidebar.js'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
@tailwind base;
|
||||
@tailwind components;
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { useCallback, useEffect, useRef } from 'react';
|
||||
import { IInputBoxStyles, InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js';
|
||||
@@ -66,6 +66,7 @@ export const VoidInputBox = ({ onChangeText, onCreateInstance, inputBoxRef, plac
|
||||
{
|
||||
inputBoxStyles: {
|
||||
...defaultInputBoxStyles,
|
||||
inputForeground: "var(--vscode-foreground)",
|
||||
// inputBackground: 'transparent',
|
||||
// inputBorder: 'none',
|
||||
...styles,
|
||||
@@ -74,7 +75,7 @@ export const VoidInputBox = ({ onChangeText, onCreateInstance, inputBoxRef, plac
|
||||
tooltip: '',
|
||||
flexibleHeight: multiline,
|
||||
flexibleMaxHeight: 500,
|
||||
flexibleWidth: true,
|
||||
flexibleWidth: false,
|
||||
}
|
||||
] as const, [contextViewProvider, placeholder, multiline])}
|
||||
dispose={useCallback((instance: InputBox) => {
|
||||
@@ -294,12 +295,13 @@ export const VoidCodeEditor = ({ initValue, language }: { initValue: string, lan
|
||||
const accessor = useAccessor()
|
||||
const instantiationService = accessor.get('IInstantiationService')
|
||||
const modelService = accessor.get('IModelService')
|
||||
const languageDetectionService = accessor.get('ILanguageDetectionService')
|
||||
|
||||
initValue = normalizeIndentation(initValue)
|
||||
|
||||
return <div ref={divRef}>
|
||||
<WidgetComponent
|
||||
className='relative z-0 text-sm'
|
||||
className='relative z-0 text-sm bg-vscode-editor-bg'
|
||||
ctor={useCallback((container) =>
|
||||
instantiationService.createInstance(
|
||||
CodeEditorWidget,
|
||||
@@ -349,33 +351,36 @@ export const VoidCodeEditor = ({ initValue, language }: { initValue: string, lan
|
||||
}
|
||||
|
||||
onCreateInstance={useCallback((editor: CodeEditorWidget) => {
|
||||
const model = modelService.createModel(initValue, null)
|
||||
const model = modelService.createModel(
|
||||
initValue,
|
||||
language ? {
|
||||
languageId: language,
|
||||
onDidChange: () => ({
|
||||
dispose: () => { }
|
||||
})
|
||||
} : null
|
||||
);
|
||||
editor.setModel(model);
|
||||
model.setLanguage(language ?? 'plaintext')
|
||||
|
||||
const container = editor.getDomNode()
|
||||
const parentNode = container?.parentElement
|
||||
if (parentNode) {
|
||||
const height = Math.min(editor.getScrollHeight() + 1, MAX_HEIGHT);
|
||||
parentNode.style.height = `${height}px`;
|
||||
editor.layout();
|
||||
}
|
||||
|
||||
// Listen for content changes and update height
|
||||
const disposable = editor.onDidContentSizeChange(() => {
|
||||
const resize = () => {
|
||||
if (parentNode) {
|
||||
const height = Math.min(editor.getScrollHeight() + 1, MAX_HEIGHT);
|
||||
parentNode.style.height = `${height}px`;
|
||||
editor.layout();
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
resize()
|
||||
const disposable = editor.onDidContentSizeChange(() => { resize() });
|
||||
|
||||
return [disposable]
|
||||
}, [modelService, initValue, language])}
|
||||
|
||||
dispose={useCallback((editor: CodeEditorWidget) => {
|
||||
editor.dispose();
|
||||
}, [])}
|
||||
}, [modelService, languageDetectionService])}
|
||||
|
||||
propsFn={useCallback(() => { return [] }, [])}
|
||||
/>
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { useEffect, useState } from 'react';
|
||||
import * as ReactDOM from 'react-dom/client'
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { useState, useEffect } from 'react'
|
||||
import { ThreadsState } from '../../../threadHistoryService.js'
|
||||
@@ -39,6 +39,7 @@ import { INotificationService } from '../../../../../../../platform/notification
|
||||
import { IAccessibilityService } from '../../../../../../../platform/accessibility/common/accessibility.js'
|
||||
import { ILanguageConfigurationService } from '../../../../../../../editor/common/languages/languageConfigurationRegistry.js'
|
||||
import { ILanguageFeaturesService } from '../../../../../../../editor/common/services/languageFeatures.js'
|
||||
import { ILanguageDetectionService } from '../../../../../../services/languageDetection/common/languageDetectionWorkerService.js'
|
||||
|
||||
|
||||
|
||||
@@ -145,6 +146,7 @@ export const _registerServices = (accessor: ServicesAccessor) => {
|
||||
}
|
||||
|
||||
|
||||
|
||||
const getReactAccessor = (accessor: ServicesAccessor) => {
|
||||
const reactAccessor = {
|
||||
IModelService: accessor.get(IModelService),
|
||||
@@ -169,6 +171,7 @@ const getReactAccessor = (accessor: ServicesAccessor) => {
|
||||
INotificationService: accessor.get(INotificationService),
|
||||
IAccessibilityService: accessor.get(IAccessibilityService),
|
||||
ILanguageConfigurationService: accessor.get(ILanguageConfigurationService),
|
||||
ILanguageDetectionService: accessor.get(ILanguageDetectionService),
|
||||
ILanguageFeaturesService: accessor.get(ILanguageFeaturesService),
|
||||
|
||||
} as const
|
||||
|
||||
@@ -1,26 +1,38 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { useCallback, useEffect, useRef, useState } from 'react'
|
||||
import { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { FeatureName, featureNames, ModelSelection, modelSelectionsEqual, ProviderName, providerNames } from '../../../../../../../platform/void/common/voidSettingsTypes.js'
|
||||
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'
|
||||
import { VOID_OPEN_SETTINGS_ACTION_ID } from '../../../voidSettingsPane.js'
|
||||
import { ModelOption } from '../../../../../../../platform/void/common/voidSettingsService.js'
|
||||
|
||||
const ModelSelectBox = ({ featureName }: { featureName: FeatureName }) => {
|
||||
|
||||
|
||||
const optionsEqual = (m1: ModelOption[], m2: ModelOption[]) => {
|
||||
if (m1.length !== m2.length) return false
|
||||
for (let i = 0; i < m1.length; i++) {
|
||||
if (!modelSelectionsEqual(m1[i].value, m2[i].value)) return false
|
||||
}
|
||||
return true
|
||||
}
|
||||
|
||||
|
||||
|
||||
const ModelSelectBox = ({ options, featureName }: { options: ModelOption[], featureName: FeatureName }) => {
|
||||
const accessor = useAccessor()
|
||||
|
||||
const voidSettingsService = accessor.get('IVoidSettingsService')
|
||||
const settingsState = useSettingsState()
|
||||
|
||||
let weChangedText = false
|
||||
|
||||
return <VoidSelectBox
|
||||
options={settingsState._modelOptions}
|
||||
options={options}
|
||||
onChangeSelection={useCallback((newVal: ModelSelection) => {
|
||||
if (weChangedText) return
|
||||
voidSettingsService.setModelSelectionOfFeature(featureName, newVal)
|
||||
@@ -42,6 +54,23 @@ const ModelSelectBox = ({ featureName }: { featureName: FeatureName }) => {
|
||||
/>
|
||||
}
|
||||
|
||||
const MemoizedModelSelectBox = ({ featureName }: { featureName: FeatureName }) => {
|
||||
const settingsState = useSettingsState()
|
||||
const oldOptionsRef = useRef<ModelOption[]>([])
|
||||
const [memoizedOptions, setMemoizedOptions] = useState(oldOptionsRef.current)
|
||||
useEffect(() => {
|
||||
const oldOptions = oldOptionsRef.current
|
||||
const newOptions = settingsState._modelOptions
|
||||
if (!optionsEqual(oldOptions, newOptions)) {
|
||||
setMemoizedOptions(newOptions)
|
||||
}
|
||||
oldOptionsRef.current = newOptions
|
||||
}, [settingsState._modelOptions])
|
||||
|
||||
return <ModelSelectBox featureName={featureName} options={memoizedOptions} />
|
||||
|
||||
}
|
||||
|
||||
const DummySelectBox = () => {
|
||||
|
||||
const accessor = useAccessor()
|
||||
@@ -76,6 +105,6 @@ const DummySelectBox = () => {
|
||||
export const ModelDropdown = ({ featureName }: { featureName: FeatureName }) => {
|
||||
const settingsState = useSettingsState()
|
||||
return <>
|
||||
{settingsState._modelOptions.length === 0 ? <DummySelectBox /> : <ModelSelectBox featureName={featureName} />}
|
||||
{settingsState._modelOptions.length === 0 ? <DummySelectBox /> : <MemoizedModelSelectBox featureName={featureName} />}
|
||||
</>
|
||||
}
|
||||
|
||||
@@ -1,6 +1,11 @@
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import React, { useCallback, useEffect, useMemo, useRef, useState } from 'react'
|
||||
import { InputBox } from '../../../../../../../base/browser/ui/inputbox/inputBox.js'
|
||||
import { ProviderName, SettingName, displayInfoOfSettingName, providerNames, VoidModelInfo, featureFlagNames, displayInfoOfFeatureFlag, customSettingNamesOfProvider, RefreshableProviderName, refreshableProviderNames, displayInfoOfProviderName, defaultProviderSettings } from '../../../../../../../platform/void/common/voidSettingsTypes.js'
|
||||
import { ProviderName, SettingName, displayInfoOfSettingName, providerNames, VoidModelInfo, featureFlagNames, displayInfoOfFeatureFlag, customSettingNamesOfProvider, RefreshableProviderName, refreshableProviderNames, displayInfoOfProviderName, defaultProviderSettings, nonlocalProviderNames, localProviderNames } from '../../../../../../../platform/void/common/voidSettingsTypes.js'
|
||||
import ErrorBoundary from '../sidebar-tsx/ErrorBoundary.js'
|
||||
import { VoidCheckBox, VoidInputBox, VoidSelectBox, VoidSwitch } from '../util/inputs.js'
|
||||
import { useAccessor, useIsDark, useRefreshModelListener, useRefreshModelState, useSettingsState } from '../util/services.js'
|
||||
@@ -9,7 +14,7 @@ import { ChatMarkdownRender } from '../markdown/ChatMarkdownRender.js'
|
||||
|
||||
const SubtleButton = ({ onClick, text, icon, disabled }: { onClick: () => void, text: string, icon: React.ReactNode, disabled: boolean }) => {
|
||||
|
||||
return <div className='flex items-center py-1 px-3 rounded-sm overflow-hidden gap-2 hover:bg-black/10 dark:hover:bg-gray-200/10'>
|
||||
return <div className='flex items-center px-3 rounded-sm overflow-hidden gap-2 hover:bg-black/10 dark:hover:bg-gray-300/10'>
|
||||
<button className='flex items-center' disabled={disabled} onClick={onClick}>
|
||||
{icon}
|
||||
</button>
|
||||
@@ -19,24 +24,24 @@ const SubtleButton = ({ onClick, text, icon, disabled }: { onClick: () => void,
|
||||
</div>
|
||||
}
|
||||
|
||||
|
||||
// models
|
||||
const RefreshModelButton = ({ providerName }: { providerName: RefreshableProviderName }) => {
|
||||
|
||||
const refreshModelState = useRefreshModelState()
|
||||
|
||||
const accessor = useAccessor()
|
||||
const refreshModelService = accessor.get('IRefreshModelService')
|
||||
|
||||
const [justFinished, setJustSucceeded] = useState(false)
|
||||
const [justFinished, setJustFinished] = useState(false)
|
||||
|
||||
useRefreshModelListener(
|
||||
useCallback((providerName2, refreshModelState) => {
|
||||
if (providerName2 !== providerName) return
|
||||
const { state } = refreshModelState[providerName]
|
||||
if (state !== 'success') return
|
||||
// now we know we just entered 'success' state for this providerName
|
||||
setJustSucceeded(true)
|
||||
const tid = setTimeout(() => { setJustSucceeded(false) }, 2000)
|
||||
if (state !== 'finished') return
|
||||
// now we know we just entered 'finished' state for this providerName
|
||||
setJustFinished(true)
|
||||
const tid = setTimeout(() => { setJustFinished(false) }, 2000)
|
||||
return () => clearTimeout(tid)
|
||||
}, [providerName])
|
||||
)
|
||||
@@ -59,7 +64,9 @@ const RefreshableModels = () => {
|
||||
|
||||
const buttons = refreshableProviderNames.map(providerName => {
|
||||
if (!settingsState.settingsOfProvider[providerName]._enabled) return null
|
||||
return <RefreshModelButton key={providerName} providerName={providerName} />
|
||||
return <div key={providerName} className='pb-4' >
|
||||
<RefreshModelButton providerName={providerName} />
|
||||
</div>
|
||||
})
|
||||
|
||||
return <>
|
||||
@@ -87,17 +94,9 @@ const AddModelMenu = ({ onSubmit }: { onSubmit: () => void }) => {
|
||||
|
||||
return <>
|
||||
<div className='flex items-center gap-4'>
|
||||
{/* model */}
|
||||
<div className='max-w-40 w-full'>
|
||||
<VoidInputBox
|
||||
placeholder='Model Name'
|
||||
onChangeText={useCallback((modelName) => { modelNameRef.current = modelName }, [])}
|
||||
multiline={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* provider */}
|
||||
<div className='max-w-40 w-full'>
|
||||
<div className='max-w-40 w-full border border-vscode-editorwidget-border'>
|
||||
<VoidSelectBox
|
||||
onCreateInstance={useCallback(() => { providerNameRef.current = providerOptions[0].value }, [providerOptions])} // initialize state
|
||||
onChangeSelection={useCallback((providerName: ProviderName) => { providerNameRef.current = providerName }, [])}
|
||||
@@ -105,6 +104,15 @@ const AddModelMenu = ({ onSubmit }: { onSubmit: () => void }) => {
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* model */}
|
||||
<div className='max-w-40 w-full border border-vscode-editorwidget-border'>
|
||||
<VoidInputBox
|
||||
placeholder='Model Name'
|
||||
onChangeText={useCallback((modelName) => { modelNameRef.current = modelName }, [])}
|
||||
multiline={false}
|
||||
/>
|
||||
</div>
|
||||
|
||||
{/* button */}
|
||||
<div className='max-w-40'>
|
||||
<button
|
||||
@@ -147,7 +155,7 @@ const AddModelMenu = ({ onSubmit }: { onSubmit: () => void }) => {
|
||||
const AddModelMenuFull = () => {
|
||||
const [open, setOpen] = useState(false)
|
||||
|
||||
return <div className='hover:bg-black/10 dark:hover:bg-gray-200/10 py-1 px-3 rounded-sm overflow-hidden '>
|
||||
return <div className='hover:bg-black/10 dark:hover:bg-gray-300/10 py-1 my-4 pb-1 px-3 rounded-sm overflow-hidden '>
|
||||
{open ?
|
||||
<AddModelMenu onSubmit={() => { setOpen(false) }} />
|
||||
: <button
|
||||
@@ -180,19 +188,23 @@ export const ModelDump = () => {
|
||||
})
|
||||
|
||||
return <div className=''>
|
||||
{modelDump.map(m => {
|
||||
const { isHidden, isDefault, modelName, providerName, providerEnabled } = m
|
||||
{modelDump.map((m, i) => {
|
||||
const { isHidden, isDefault, isAutodetected, modelName, providerName, providerEnabled } = m
|
||||
|
||||
const isNewProviderName = (i > 0 ? modelDump[i - 1] : undefined)?.providerName !== providerName
|
||||
|
||||
const disabled = !providerEnabled
|
||||
|
||||
return <div key={`${modelName}${providerName}`} className='flex items-center justify-between gap-4 hover:bg-black/10 dark:hover:bg-gray-200/10 py-1 px-3 rounded-sm overflow-hidden cursor-default'>
|
||||
return <div key={`${modelName}${providerName}`} className={`flex items-center justify-between gap-4 hover:bg-black/10 dark:hover:bg-gray-300/10 py-1 px-3 rounded-sm overflow-hidden cursor-default truncate ${isNewProviderName ? 'mt-4' : ''}`}>
|
||||
{/* left part is width:full */}
|
||||
<div className={`w-full flex items-center gap-4`}>
|
||||
<span>{`${modelName} (${providerName})`}</span>
|
||||
<span className='min-w-40'>{isNewProviderName ? displayInfoOfProviderName(providerName).title : ''}</span>
|
||||
<span>{modelName}</span>
|
||||
{/* <span>{`${modelName} (${providerName})`}</span> */}
|
||||
</div>
|
||||
{/* right part is anything that fits */}
|
||||
<div className='w-fit flex items-center gap-4'>
|
||||
<span className='opacity-50 whitespace-nowrap'>{isDefault ? '' : '(custom model)'}</span>
|
||||
<span className='opacity-50'>{isAutodetected ? '(detected locally)' : isDefault ? '' : '(custom model)'}</span>
|
||||
|
||||
<VoidSwitch
|
||||
value={disabled ? false : !isHidden}
|
||||
@@ -217,7 +229,7 @@ export const ModelDump = () => {
|
||||
const ProviderSetting = ({ providerName, settingName }: { providerName: ProviderName, settingName: SettingName }) => {
|
||||
|
||||
|
||||
const { title: providerTitle, } = displayInfoOfProviderName(providerName)
|
||||
// const { title: providerTitle, } = displayInfoOfProviderName(providerName)
|
||||
|
||||
const { title: settingTitle, placeholder, subTextMd } = displayInfoOfSettingName(providerName, settingName)
|
||||
|
||||
@@ -229,7 +241,8 @@ const ProviderSetting = ({ providerName, settingName }: { providerName: Provider
|
||||
return <ErrorBoundary>
|
||||
<div className='my-1'>
|
||||
<VoidInputBox
|
||||
placeholder={`${providerTitle} ${settingTitle} (${placeholder}).`}
|
||||
// placeholder={`${providerTitle} ${settingTitle} (${placeholder}).`}
|
||||
placeholder={`${settingTitle} (${placeholder}).`}
|
||||
onChangeText={useCallback((newVal) => {
|
||||
if (weChangedTextRef) return
|
||||
voidSettingsService.setSettingOfProvider(providerName, settingName, newVal)
|
||||
@@ -313,7 +326,7 @@ const SettingsForProvider = ({ providerName }: { providerName: ProviderName }) =
|
||||
}
|
||||
|
||||
|
||||
export const VoidProviderSettings = () => {
|
||||
export const VoidProviderSettings = ({ providerNames }: { providerNames: ProviderName[] }) => {
|
||||
return <>
|
||||
{providerNames.map(providerName =>
|
||||
<SettingsForProvider key={providerName} providerName={providerName} />
|
||||
@@ -346,7 +359,6 @@ export const VoidProviderSettings = () => {
|
||||
// }
|
||||
export const VoidFeatureFlagSettings = () => {
|
||||
|
||||
|
||||
const accessor = useAccessor()
|
||||
const voidSettingsService = accessor.get('IVoidSettingsService')
|
||||
|
||||
@@ -354,10 +366,11 @@ export const VoidFeatureFlagSettings = () => {
|
||||
|
||||
return featureFlagNames.map((flagName) => {
|
||||
|
||||
// right now this is just `enabled_autoRefreshModels`
|
||||
const enabled = voidSettingsState.featureFlagSettings[flagName]
|
||||
const { description } = displayInfoOfFeatureFlag(flagName)
|
||||
|
||||
return <SubtleButton
|
||||
return <SubtleButton key={flagName}
|
||||
onClick={() => { voidSettingsService.setFeatureFlag(flagName, !enabled) }}
|
||||
text={description}
|
||||
icon={enabled ? <Check className='stroke-green-500 size-3' /> : <X className='stroke-red-500 size-3' />}
|
||||
@@ -391,9 +404,9 @@ export const Settings = () => {
|
||||
<button className={`text-left p-1 px-3 my-0.5 rounded-sm overflow-hidden ${tab === 'models' ? 'bg-black/10 dark:bg-gray-200/10' : ''} hover:bg-black/10 hover:dark:bg-gray-200/10 active:bg-black/10 active:dark:bg-gray-200/10 `}
|
||||
onClick={() => { setTab('models') }}
|
||||
>Models</button>
|
||||
<button className={`text-left p-1 px-3 my-0.5 rounded-sm overflow-hidden ${tab === 'features' ? 'bg-black/10 dark:bg-gray-200/10' : ''} hover:bg-black/10 hover:dark:bg-gray-200/10 active:bg-black/10 active:dark:bg-gray-200/10 `}
|
||||
{/* <button className={`text-left p-1 px-3 my-0.5 rounded-sm overflow-hidden ${tab === 'features' ? 'bg-black/10 dark:bg-gray-200/10' : ''} hover:bg-black/10 hover:dark:bg-gray-200/10 active:bg-black/10 active:dark:bg-gray-200/10 `}
|
||||
onClick={() => { setTab('features') }}
|
||||
>Features</button>
|
||||
>Features</button> */}
|
||||
</div>
|
||||
|
||||
{/* separator */}
|
||||
@@ -404,14 +417,32 @@ export const Settings = () => {
|
||||
<div className='w-full overflow-y-auto'>
|
||||
|
||||
<div className={`${tab !== 'models' ? 'hidden' : ''}`}>
|
||||
<h2 className={`text-3xl mb-2`}>Providers</h2>
|
||||
<h2 className={`text-3xl mb-2`}>Local Providers</h2>
|
||||
{/* <h3 className={`text-md opacity-50 mb-2`}>{`Keep your data private by hosting AI locally on your computer.`}</h3> */}
|
||||
{/* <h3 className={`text-md opacity-50 mb-2`}>{`Instructions:`}</h3> */}
|
||||
<h3 className={`text-md mb-2`}>{`Void can access any model that you host locally. We automatically detect your local models by default.`}</h3>
|
||||
<div className='pl-4 select-text opacity-50'>
|
||||
<h4 className={`text-xs mb-2`}><ChatMarkdownRender string={`1. Download [Ollama](https://ollama.com/download).`} /></h4>
|
||||
<h4 className={`text-xs mb-2`}><ChatMarkdownRender string={`2. Open your terminal.`} /></h4>
|
||||
<h4 className={`text-xs mb-2`}><ChatMarkdownRender string={`3. Run \`ollama run llama3.1\`. This installs Meta's llama model which is competitive with GPT-series models. It requires 5GB of memory.`} /></h4>
|
||||
<h4 className={`text-xs mb-2`}><ChatMarkdownRender string={`4. Run \`ollama run qwen2.5-coder:1.5b\`. This is a faster autocomplete model and requires 1GB of memory.`} /></h4>
|
||||
{/* TODO we should create UI for downloading models without user going into terminal */}
|
||||
</div>
|
||||
|
||||
<ErrorBoundary>
|
||||
<VoidFeatureFlagSettings />
|
||||
<VoidProviderSettings />
|
||||
<VoidProviderSettings providerNames={localProviderNames} />
|
||||
</ErrorBoundary>
|
||||
|
||||
<h2 className={`text-3xl mb-2 mt-4`}>Models</h2>
|
||||
<h2 className={`text-3xl mb-2 mt-16`}>More Providers</h2>
|
||||
<h3 className={`text-md mb-2`}>{`Void can also access models like ChatGPT and Claude. We recommend using Anthropic or OpenAI.`}</h3>
|
||||
{/* <h3 className={`text-md opacity-50 mb-2`}>{`Access models like ChatGPT and Claude. We recommend using Anthropic or OpenAI as providers, or Groq as a faster alternative.`}</h3> */}
|
||||
<ErrorBoundary>
|
||||
<VoidProviderSettings providerNames={nonlocalProviderNames} />
|
||||
</ErrorBoundary>
|
||||
|
||||
<h2 className={`text-3xl mb-2 mt-16`}>Models</h2>
|
||||
<ErrorBoundary>
|
||||
<VoidFeatureFlagSettings />
|
||||
<RefreshableModels />
|
||||
<ModelDump />
|
||||
<AddModelMenuFull />
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { mountFnGenerator } from '../util/mountFnGenerator.js'
|
||||
import { Settings } from './Settings.js'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
/** @type {import('tailwindcss').Config} */
|
||||
module.exports = {
|
||||
@@ -89,7 +89,7 @@ module.exports = {
|
||||
"sidebar-bg": "var(--vscode-sideBar-background)",
|
||||
"sidebar-fg": "var(--vscode-sideBar-foreground)",
|
||||
"sidebar-border": "var(--vscode-sideBar-border)",
|
||||
"sidebar-drop-backdrop": "var(--vscode-sideBar-dropBackground)",
|
||||
"sidebar-drop-bg": "var(--vscode-sideBar-dropBackground)",
|
||||
"sidebar-title-fg": "var(--vscode-sideBarTitle-foreground)",
|
||||
"sidebar-header-bg": "var(--vscode-sideBarSectionHeader-background)",
|
||||
"sidebar-header-fg": "var(--vscode-sideBarSectionHeader-foreground)",
|
||||
@@ -103,6 +103,10 @@ module.exports = {
|
||||
|
||||
// other colors (these are partially complete)
|
||||
|
||||
// text formatting
|
||||
"text-preformat-bg": "var(--vscode-textPreformat-background)",
|
||||
"text-preformat-fg": "var(--vscode-textPreformat-foreground)",
|
||||
|
||||
// editor colors
|
||||
"editor-bg": "var(--vscode-editor-background)",
|
||||
"editor-fg": "var(--vscode-editor-foreground)",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
{
|
||||
"compilerOptions": {
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { defineConfig } from 'tsup'
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { KeyCode, KeyMod } from '../../../../base/common/keyCodes.js';
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Registry } from '../../../../platform/registry/common/platform.js';
|
||||
import {
|
||||
|
||||
@@ -1,3 +1,8 @@
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Emitter, Event } from '../../../../base/common/event.js';
|
||||
import { Disposable } from '../../../../base/common/lifecycle.js';
|
||||
import { ICommandService } from '../../../../platform/commands/common/commands.js';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { Disposable } from '../../../../base/common/lifecycle.js';
|
||||
import { registerSingleton, InstantiationType } from '../../../../platform/instantiation/common/extensions.js';
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
|
||||
// register inline diffs
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
/*---------------------------------------------------------------------------------------------
|
||||
* Copyright (c) Glass Devtools, Inc. All rights reserved.
|
||||
* Void Editor additions licensed under the AGPL 3.0 License.
|
||||
*--------------------------------------------------------------------------------------------*/
|
||||
/*------------------------------------------------------------------------------------------
|
||||
* Copyright (c) 2025 Glass Devtools, Inc. All rights reserved.
|
||||
* Licensed under the MIT License. See LICENSE.txt in the project root for more information.
|
||||
*-----------------------------------------------------------------------------------------*/
|
||||
|
||||
import { IInstantiationService } from '../../../../platform/instantiation/common/instantiation.js';
|
||||
import { EditorInput } from '../../../common/editor/editorInput.js';
|
||||
|
||||
|
Before Width: | Height: | Size: 23 KiB |
@@ -0,0 +1,8 @@
|
||||
{
|
||||
"id": "2501027uxm8l3",
|
||||
"icon": "./resources/darwin/code.icns",
|
||||
"appPath": ".",
|
||||
"schemaVersion": 1,
|
||||
"nodeVersion": "20.16.0",
|
||||
"uploadSizeLimit": 600
|
||||
}
|
||||