Compare commits
176 commits
Author | SHA1 | Date | |
---|---|---|---|
0032dbf0f3 | |||
e7f0bb793a | |||
532292068f | |||
dd2104065c | |||
8389c66814 | |||
803b25d7fb | |||
b3ce6d62a7 | |||
f28cf77347 | |||
c524bbf899 | |||
a9c8a3a0d9 | |||
570eeac755 | |||
5efc28ae18 | |||
91747319aa | |||
8a7ca04168 | |||
5e4f2d5dfb | |||
4722613b4c | |||
53f4d1d330 | |||
270ac9e113 | |||
a4db054b59 | |||
bd47cb201f | |||
520167414a | |||
2d0ad8be44 | |||
9913ceb67e | |||
d5359e5816 | |||
8336d2bcc5 | |||
281ce0ed4e | |||
dcede7eb43 | |||
137977f691 | |||
ab20a57e9e | |||
1725b189a4 | |||
68b60e2c77 | |||
f7ea73ae45 | |||
3ceb61f2dd | |||
c7e33ea8de | |||
12e5ffdea1 | |||
54cd514249 | |||
a8f97172d6 | |||
b485c1e48c | |||
ee5a2463b9 | |||
9676b70821 | |||
9023026478 | |||
8bb4e8bef1 | |||
9541bb9752 | |||
2c500d40a5 | |||
e737058cb5 | |||
f53b0e3283 | |||
3de2f92bf8 | |||
dec12a8041 | |||
ac90dab503 | |||
9830b7ebc9 | |||
efa2f127a9 | |||
78c4751c53 | |||
1f79f484e5 | |||
6c14ad7113 | |||
ab5948a51b | |||
a950c932f5 | |||
46069b9a22 | |||
0a5a765eaf | |||
da38433eb3 | |||
7c1aa36d82 | |||
ceea101170 | |||
6dacf97583 | |||
b497f04e40 | |||
13266d112c | |||
74f1ceb880 | |||
af9ebee500 | |||
cc062b533e | |||
612841724c | |||
0cbce88d10 | |||
1ce31d786d | |||
8880f22840 | |||
94fe15409a | |||
868c37c567 | |||
e33c96d658 | |||
f02f50c1a7 | |||
9faa421ad9 | |||
009db1cb0f | |||
5c682f6bfa | |||
cc7d1393d6 | |||
7ee7e2f3d1 | |||
f138a2a4ba | |||
7c14ca2944 | |||
7c0fb4412d | |||
cb4ecb9ff6 | |||
7da3af7cd0 | |||
09ec2d79cc | |||
2f8bc57fe1 | |||
b2d4355488 | |||
1382aed48c | |||
404a554654 | |||
206cc1e437 | |||
c6f3a8202b | |||
4f9c324af1 | |||
a9b55ec830 | |||
08a04aff2c | |||
fbeb7985e4 | |||
c6af369b1c | |||
2ab3570d08 | |||
d4a1b69172 | |||
91ee38e922 | |||
05ff125c1d | |||
03a86defb9 | |||
a1c952e019 | |||
5399fbe2a9 | |||
f1bbe84c71 | |||
d80230cba5 | |||
e2406b406c | |||
e177001020 | |||
f57d78f8c3 | |||
683aa7fad1 | |||
c31a78d547 | |||
16fb4b57b7 | |||
88df5b1426 | |||
6b8b82e710 | |||
f26be52940 | |||
0982b3488d | |||
0b22a4538b | |||
ec66112700 | |||
8e9968b6f5 | |||
2730b88c18 | |||
efdde4aad2 | |||
2694b9e1c1 | |||
aaa8885081 | |||
353151c4c5 | |||
009c5fa5ed | |||
2e6db5ccd3 | |||
26c4b26ae8 | |||
63d45b87b5 | |||
9ed15e49cf | |||
df15261196 | |||
dcce9a8b28 | |||
993930fa99 | |||
ecf01829cf | |||
87d30dfaa2 | |||
4990cb42f6 | |||
3a5daab063 | |||
0edcce333b | |||
9135cc6dd6 | |||
14c909d50e | |||
aace0d316f | |||
9d05a4c3d7 | |||
a3143dbc0c | |||
adb8797051 | |||
ff75518aa8 | |||
694acfc1d3 | |||
6879cbf0e5 | |||
77e72ea98d | |||
8a988d5bfe | |||
c652e1f05c | |||
91e8857ea9 | |||
990563d70a | |||
0636ba09f6 | |||
f9317ebe29 | |||
66d76b99a4 | |||
a32068ce23 | |||
93d8deeec8 | |||
6a67748355 | |||
27160d6778 | |||
0ed6adff8d | |||
17dca6d419 | |||
d3de75f950 | |||
f067ca647c | |||
c9a3388c57 | |||
7ab0657fd4 | |||
e6be5d7995 | |||
e45872a98b | |||
24da7b413a | |||
fbdeb371f7 | |||
7120d095d1 | |||
9994416282 | |||
5fa4ff72d1 | |||
5eca261831 | |||
768b8b29ff | |||
aeeb2ab946 | |||
28527cddb4 | |||
f704b6c936 |
282 changed files with 8016 additions and 2704 deletions
2
.github/FUNDING.yml
vendored
Normal file
2
.github/FUNDING.yml
vendored
Normal file
|
@ -0,0 +1,2 @@
|
||||||
|
patreon: falsepattern
|
||||||
|
ko_fi: falsepattern
|
3
.gitignore
vendored
3
.gitignore
vendored
|
@ -60,4 +60,5 @@ gradle-app.setting
|
||||||
.intellijPlatform
|
.intellijPlatform
|
||||||
jbr
|
jbr
|
||||||
secrets
|
secrets
|
||||||
!**/src/**/build/
|
!**/src/**/build/
|
||||||
|
.kotlin
|
316
CHANGELOG.md
316
CHANGELOG.md
|
@ -17,6 +17,310 @@ Changelog structure reference:
|
||||||
|
|
||||||
## [Unreleased]
|
## [Unreleased]
|
||||||
|
|
||||||
|
## [25.2.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Debugger
|
||||||
|
- Notify the user if zig run / zig test debugging starts, but a build.zig is present
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- Line marker task suggestions for main/test now defer to Zig Build if build.zig file is detected.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Debugger
|
||||||
|
- Compilation failures did not open the terminal properly and suppressed the error message
|
||||||
|
|
||||||
|
## [25.1.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- IDEA 2025.1 support
|
||||||
|
|
||||||
|
- LSP
|
||||||
|
- Configurable inlay hints file size limit to reduce IDE lag
|
||||||
|
|
||||||
|
## [25.0.2]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- ZLS settings not scrollable in the language server list
|
||||||
|
|
||||||
|
## [25.0.1]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- Zig.iml file created in every project
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- BREAKING MAJOR UPDATE: Fully reworked toolchain and language server management
|
||||||
|
The configuration menu is now very similar to the intellij java toolchain management,
|
||||||
|
with proper toolchain selection, detection, downloading, etc. This change will require
|
||||||
|
you to re-configure your toolchains!
|
||||||
|
- Zig external library root is now no longer shown if zig is not configured
|
||||||
|
|
||||||
|
## [24.0.1]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Project, Debugging
|
||||||
|
- TTY support for zig processes
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- "Emulate terminal" and "colored output" config options have been removed from zig run/test/build tasks, as they are no longer required for ZigBrains to work.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Debugger
|
||||||
|
- Build errors didn't get shown in the console
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- File path browse buttons in zig run configurations didn't work
|
||||||
|
- Occasional GUI deadlocks
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- IPC wrapper wasn't passing exit code
|
||||||
|
|
||||||
|
## [23.1.2]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- LSP
|
||||||
|
- IDE warning when renaming symbols
|
||||||
|
|
||||||
|
## [23.1.1]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- New project creation creates a blank ZLS config
|
||||||
|
|
||||||
|
## [23.1.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- Support running file main/tests with hotkey (default: ctrl+shift+f10)
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Direnv
|
||||||
|
- Centralized all direnv toggling into a single project-level option
|
||||||
|
|
||||||
|
## [23.0.2]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- Documentation comment after regular comment was being highlighted as regular comment
|
||||||
|
|
||||||
|
## [23.0.1]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- mkfifo/bash for zig progress visualization is now detected more reliably (fixes error on macOS)
|
||||||
|
- Deadlock when launching zig build tasks
|
||||||
|
|
||||||
|
## [23.0.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- Zig std.Progress visualization in the zig tool window (Linux/macOS only)
|
||||||
|
|
||||||
|
### Removed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- Executable / Library new project templates temporarily removed until zig stabilizes
|
||||||
|
|
||||||
|
## [22.0.1]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- LSP
|
||||||
|
- Changing ZLS configs would not restart ZLS
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- Occasional "AWT events are not allowed inside write action" error coming from LSP
|
||||||
|
- IllegalStateException coming from the standard library handler
|
||||||
|
|
||||||
|
## [22.0.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- LSP
|
||||||
|
- Error/Warning banner at the top of the editor when ZLS is misconfigured/not running
|
||||||
|
- ZLS version indicator in the zig settings
|
||||||
|
|
||||||
|
- Toolchain
|
||||||
|
- More descriptive error messages when toolchain detection fails
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- !!BREAKING CHANGE!! Changed file format of zig tasks to store command line arguments as strings instead of string lists.
|
||||||
|
This (and newer) versions of the plugin will automatically upgrade tasks from 21.1.0 and before.
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Debugging
|
||||||
|
- Breakpoints could not be placed inside zig code in Android Studio
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- Zig run/debug configuration command line arguments would lose quotes around arguments
|
||||||
|
|
||||||
|
## [21.1.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Zon
|
||||||
|
- ZLS integration
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Zon
|
||||||
|
- Fully refactored the parser for parity with the zig parser
|
||||||
|
|
||||||
|
## [21.0.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- Changing the zig standard library path in the project settings now properly updates the dependency
|
||||||
|
- ZLS
|
||||||
|
- All of the config options are now exposed in the GUI
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- New project panel is now much more compact
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- `zig env` failure causes an IDE error
|
||||||
|
- A local toolchain disappearing (std directory or zig exe deleted) is now handled properly
|
||||||
|
|
||||||
|
## [20.3.0]
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- Improved default colors
|
||||||
|
|
||||||
|
## [20.2.2]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Debugging
|
||||||
|
- `zig build run` would run the process twice, one without, one with debugging
|
||||||
|
|
||||||
|
## [20.2.1]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- Lexer error when a zig file has a comment or multiline string at the end of file without trailing newline
|
||||||
|
|
||||||
|
## [20.2.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- Live template support
|
||||||
|
|
||||||
|
## [20.1.3]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- `.zig-cache` directory added to autogenerated gitignore in the project generator
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- Zig Build tool window crashes when opening remote projects
|
||||||
|
|
||||||
|
## [20.1.2]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- Source file path highlighter made the terminal lag with some files
|
||||||
|
- Non-terminating rule in lexer could make the editor hang
|
||||||
|
|
||||||
|
## [20.1.1]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- Unterminated string at the end of the file soft-locks the editor
|
||||||
|
- Trailing commas in for loop parameters don't get parsed correctly
|
||||||
|
|
||||||
|
## [20.1.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- String, character literal, and `@"identifier"` quote matching
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Zon
|
||||||
|
- Broken string quote handling
|
||||||
|
|
||||||
|
## [20.0.4]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Renamed Zig new file task to "Zig File" and moved to the file creation group
|
||||||
|
|
||||||
|
## [20.0.3]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- "Save all documents" hanging when trying to run a zig file
|
||||||
|
|
||||||
|
## [20.0.2]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- Escape sequence highlighting in char literals
|
||||||
|
|
||||||
|
### Changed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- Direnv now only runs automatically in trusted projects
|
||||||
|
- Toolchain autodetection is now done in the background on project load
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- Unicode characters in char literals triggered an error
|
||||||
|
|
||||||
|
## [20.0.1]
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Project
|
||||||
|
- IDE freezes when opening a zig project / doing zig init
|
||||||
|
- Test tasks don't work and try to run the file as an executable
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- Struct fields being styled as static fields instead of instance fields
|
||||||
|
|
||||||
|
## [20.0.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
||||||
- Debugging
|
- Debugging
|
||||||
|
@ -30,6 +334,18 @@ Changelog structure reference:
|
||||||
|
|
||||||
- Most of the internals have been rewritten to be fully asynchronous, so freezes should happen way less
|
- Most of the internals have been rewritten to be fully asynchronous, so freezes should happen way less
|
||||||
|
|
||||||
|
## [19.3.0]
|
||||||
|
|
||||||
|
### Added
|
||||||
|
|
||||||
|
- Toolchains, Run Configurations
|
||||||
|
- [Direnv](https://github.com/direnv/direnv) support
|
||||||
|
|
||||||
|
### Fixed
|
||||||
|
|
||||||
|
- Zig
|
||||||
|
- Missing description for string conversion intentions
|
||||||
|
|
||||||
## [19.2.0]
|
## [19.2.0]
|
||||||
|
|
||||||
### Added
|
### Added
|
||||||
|
|
10
LICENSE
10
LICENSE
|
@ -1,5 +1,5 @@
|
||||||
ZigBrains
|
ZigBrains
|
||||||
Copyright (C) 2023-2024 FalsePattern
|
Copyright (C) 2023-2025 FalsePattern
|
||||||
All Rights Reserved
|
All Rights Reserved
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included
|
The above copyright notice and this permission notice shall be included
|
||||||
|
@ -25,6 +25,11 @@ which are the property of the Zig Software Foundation.
|
||||||
(https://github.com/ziglang/logo)
|
(https://github.com/ziglang/logo)
|
||||||
These art assets are licensed under Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0).
|
These art assets are licensed under Creative Commons Attribution-ShareAlike 4.0 International (CC BY-SA 4.0).
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
The art assets inside src/art/zls, and all copies of them, are derived from the Zig Language Server,
|
||||||
|
which are the property of the zigtools organization.
|
||||||
|
(https://github.com/zigtools/zls)
|
||||||
|
These art assets are licensed under MIT license.
|
||||||
|
--------------------------------
|
||||||
Parts of the codebase are based on the intellij-zig plugin,
|
Parts of the codebase are based on the intellij-zig plugin,
|
||||||
developed by HTGAzureX1212 (https://github.com/HTGAzureX1212), licensed under the Apache 2.0 license.
|
developed by HTGAzureX1212 (https://github.com/HTGAzureX1212), licensed under the Apache 2.0 license.
|
||||||
--------------------------------
|
--------------------------------
|
||||||
|
@ -37,4 +42,5 @@ All of the licenses listed here are available in the following files, bundled wi
|
||||||
- licenses/CC_BY_SA_4.0.LICENSE
|
- licenses/CC_BY_SA_4.0.LICENSE
|
||||||
- licenses/GPL3.LICENSE
|
- licenses/GPL3.LICENSE
|
||||||
- licenses/INTELLIJ-RUST.LICENSE
|
- licenses/INTELLIJ-RUST.LICENSE
|
||||||
- licenses/LGPL3.LICENSE
|
- licenses/LGPL3.LICENSE
|
||||||
|
- licenses/ZLS.LICENSE
|
|
@ -15,6 +15,7 @@ through the built-in plugin browser:
|
||||||
1. Go to `Settings -> Plugins`
|
1. Go to `Settings -> Plugins`
|
||||||
2. To the right of the `Installed` button at the top, click on the `...` dropdown menu, then select `Manage Plugin Repositories...`
|
2. To the right of the `Installed` button at the top, click on the `...` dropdown menu, then select `Manage Plugin Repositories...`
|
||||||
3. Click the add button, and then enter the ZigBrains updater URL, based on your IDE version:
|
3. Click the add button, and then enter the ZigBrains updater URL, based on your IDE version:
|
||||||
|
- `2025.1.*` or newer: https://falsepattern.com/zigbrains/updatePlugins-251.xml
|
||||||
- `2024.3.*`: https://falsepattern.com/zigbrains/updatePlugins-243.xml
|
- `2024.3.*`: https://falsepattern.com/zigbrains/updatePlugins-243.xml
|
||||||
- `2024.2.*`: https://falsepattern.com/zigbrains/updatePlugins-242.xml
|
- `2024.2.*`: https://falsepattern.com/zigbrains/updatePlugins-242.xml
|
||||||
- `2024.1.*`: https://falsepattern.com/zigbrains/updatePlugins-241.xml
|
- `2024.1.*`: https://falsepattern.com/zigbrains/updatePlugins-241.xml
|
||||||
|
@ -38,6 +39,7 @@ and might as well utilize the full semver string for extra information.
|
||||||
## Supporters
|
## Supporters
|
||||||
|
|
||||||
- ### [Techatrix](https://github.com/Techatrix)
|
- ### [Techatrix](https://github.com/Techatrix)
|
||||||
|
- ### [nuxusr](https://github.com/nuxusr)
|
||||||
- gree7
|
- gree7
|
||||||
- xceno
|
- xceno
|
||||||
- AnErrupTion
|
- AnErrupTion
|
||||||
|
@ -70,11 +72,7 @@ excellent example on how to write debugger support that doesn't depend on CLion.
|
||||||
<!-- Plugin description -->
|
<!-- Plugin description -->
|
||||||
Adds support for the Zig Language, utilizing the ZLS language server for advanced coding assistance.
|
Adds support for the Zig Language, utilizing the ZLS language server for advanced coding assistance.
|
||||||
|
|
||||||
## Quick setup guide for Zig and ZLS
|
Before you can properly use the plugin, you need to select or download the Zig toolchain and language server in `Settings` -> `Languages & Frameworks` -> `Zig`.
|
||||||
|
|
||||||
1. Download the latest version of Zig from https://ziglang.org/download
|
|
||||||
2. Download and compile the ZLS language server, available at https://github.com/zigtools/zls
|
|
||||||
3. Go to `Settings` -> `Languages & Frameworks` -> `Zig`, and point the `Toolchain Location` and `ZLS path` to the correct places
|
|
||||||
|
|
||||||
## Debugging
|
## Debugging
|
||||||
|
|
||||||
|
@ -88,6 +86,7 @@ Debugging Zig code is supported in any native debugging capable IDE. The followi
|
||||||
- RustRover (including the non-commercial free version too)
|
- RustRover (including the non-commercial free version too)
|
||||||
- GoLand
|
- GoLand
|
||||||
- PyCharm Professional
|
- PyCharm Professional
|
||||||
|
- Android Studio
|
||||||
|
|
||||||
Additionally, in CLion, the plugin uses the C++ Toolchains for sourcing the debugger (this can be toggled off in the settings).
|
Additionally, in CLion, the plugin uses the C++ Toolchains for sourcing the debugger (this can be toggled off in the settings).
|
||||||
|
|
||||||
|
|
|
@ -6,15 +6,15 @@ import org.jetbrains.kotlin.gradle.dsl.KotlinJvmProjectExtension
|
||||||
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
|
import org.jetbrains.kotlin.gradle.tasks.KotlinCompilationTask
|
||||||
|
|
||||||
plugins {
|
plugins {
|
||||||
kotlin("jvm") version "1.9.24" apply false
|
kotlin("jvm") version "2.1.10" apply false
|
||||||
kotlin("plugin.serialization") version "1.9.24" apply false
|
kotlin("plugin.serialization") version "2.1.10" apply false
|
||||||
id("org.jetbrains.intellij.platform") version "2.1.0"
|
id("org.jetbrains.intellij.platform") version "2.5.0"
|
||||||
id("org.jetbrains.changelog") version "2.2.1"
|
id("org.jetbrains.changelog") version "2.2.1"
|
||||||
id("org.jetbrains.grammarkit") version "2022.3.2.2" apply false
|
id("org.jetbrains.grammarkit") version "2022.3.2.2" apply false
|
||||||
idea
|
idea
|
||||||
`maven-publish`
|
`maven-publish`
|
||||||
}
|
}
|
||||||
val publishVersions = listOf("241", "242", "243")
|
val publishVersions = listOf("241", "242", "243", "251")
|
||||||
val pluginVersionFull get() = "$pluginVersion-$pluginSinceBuild"
|
val pluginVersionFull get() = "$pluginVersion-$pluginSinceBuild"
|
||||||
val pluginVersion: String by project
|
val pluginVersion: String by project
|
||||||
val pluginSinceBuild: String by project
|
val pluginSinceBuild: String by project
|
||||||
|
@ -23,7 +23,10 @@ val javaVersion = property("javaVersion").toString().toInt()
|
||||||
val lsp4ijVersion: String by project
|
val lsp4ijVersion: String by project
|
||||||
val runIdeTarget: String by project
|
val runIdeTarget: String by project
|
||||||
val lsp4ijNightly = property("lsp4ijNightly").toString().toBoolean()
|
val lsp4ijNightly = property("lsp4ijNightly").toString().toBoolean()
|
||||||
|
val useInstaller = property("useInstaller").toString().toBoolean()
|
||||||
val lsp4ijPluginString = "com.redhat.devtools.lsp4ij:$lsp4ijVersion${if (lsp4ijNightly) "@nightly" else ""}"
|
val lsp4ijPluginString = "com.redhat.devtools.lsp4ij:$lsp4ijVersion${if (lsp4ijNightly) "@nightly" else ""}"
|
||||||
|
val ideaCommunityVersion: String by project
|
||||||
|
val clionVersion: String by project
|
||||||
|
|
||||||
group = "com.falsepattern"
|
group = "com.falsepattern"
|
||||||
version = pluginVersionFull
|
version = pluginVersionFull
|
||||||
|
@ -57,7 +60,6 @@ tasks {
|
||||||
allprojects {
|
allprojects {
|
||||||
idea {
|
idea {
|
||||||
module {
|
module {
|
||||||
isDownloadJavadoc = false
|
|
||||||
isDownloadSources = true
|
isDownloadSources = true
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -88,11 +90,7 @@ allprojects {
|
||||||
|
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
defaultRepositories()
|
defaultRepositories()
|
||||||
}
|
snapshots()
|
||||||
}
|
|
||||||
dependencies {
|
|
||||||
intellijPlatform {
|
|
||||||
instrumentationTools()
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -100,8 +98,8 @@ allprojects {
|
||||||
dependencies {
|
dependencies {
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
when(runIdeTarget) {
|
when(runIdeTarget) {
|
||||||
"ideaCommunity" -> create(IntelliJPlatformType.IntellijIdeaCommunity, providers.gradleProperty("ideaCommunityVersion"))
|
"ideaCommunity" -> create(IntelliJPlatformType.IntellijIdeaCommunity, ideaCommunityVersion, useInstaller = useInstaller)
|
||||||
"clion" -> create(IntelliJPlatformType.CLion, providers.gradleProperty("clionVersion"))
|
"clion" -> create(IntelliJPlatformType.CLion, clionVersion, useInstaller = useInstaller)
|
||||||
}
|
}
|
||||||
|
|
||||||
pluginVerifier()
|
pluginVerifier()
|
||||||
|
@ -109,13 +107,14 @@ dependencies {
|
||||||
plugin(lsp4ijPluginString)
|
plugin(lsp4ijPluginString)
|
||||||
}
|
}
|
||||||
|
|
||||||
implementation(project(":core"))
|
runtimeOnly(project(":core"))
|
||||||
implementation(project(":cidr"))
|
runtimeOnly(project(":cidr"))
|
||||||
|
runtimeOnly(project(":lsp"))
|
||||||
}
|
}
|
||||||
|
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
pluginConfiguration {
|
pluginConfiguration {
|
||||||
version = providers.gradleProperty("pluginVersion")
|
version = pluginVersionFull
|
||||||
|
|
||||||
description = providers.fileContents(layout.projectDirectory.file("README.md")).asText.map {
|
description = providers.fileContents(layout.projectDirectory.file("README.md")).asText.map {
|
||||||
val start = "<!-- Plugin description -->"
|
val start = "<!-- Plugin description -->"
|
||||||
|
@ -131,7 +130,7 @@ intellijPlatform {
|
||||||
|
|
||||||
val changelog = project.changelog
|
val changelog = project.changelog
|
||||||
|
|
||||||
changeNotes = providers.gradleProperty("pluginVersion").map { pluginVersion ->
|
changeNotes = provider { pluginVersion }.map { pluginVersion ->
|
||||||
with(changelog) {
|
with(changelog) {
|
||||||
renderItem(
|
renderItem(
|
||||||
(getOrNull(pluginVersion) ?: getUnreleased())
|
(getOrNull(pluginVersion) ?: getUnreleased())
|
||||||
|
@ -146,6 +145,8 @@ intellijPlatform {
|
||||||
sinceBuild = pluginSinceBuild
|
sinceBuild = pluginSinceBuild
|
||||||
if (pluginUntilBuild.isNotBlank()) {
|
if (pluginUntilBuild.isNotBlank()) {
|
||||||
untilBuild = pluginUntilBuild
|
untilBuild = pluginUntilBuild
|
||||||
|
} else {
|
||||||
|
untilBuild = provider { null }
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -156,11 +157,6 @@ intellijPlatform {
|
||||||
password = providers.environmentVariable("PRIVATE_KEY_PASSWORD")
|
password = providers.environmentVariable("PRIVATE_KEY_PASSWORD")
|
||||||
}
|
}
|
||||||
|
|
||||||
publishing {
|
|
||||||
token = providers.environmentVariable("PUBLISH_TOKEN")
|
|
||||||
channels = providers.gradleProperty("pluginVersion").map { listOf(it.substringAfter('-', "").substringBefore('.').ifEmpty { "default" }) }
|
|
||||||
}
|
|
||||||
|
|
||||||
pluginVerification {
|
pluginVerification {
|
||||||
ides {
|
ides {
|
||||||
select {
|
select {
|
||||||
|
@ -196,6 +192,9 @@ tasks {
|
||||||
inputArchiveFile = signPlugin.map { it.signedArchiveFile }.get()
|
inputArchiveFile = signPlugin.map { it.signedArchiveFile }.get()
|
||||||
dependsOn(signPlugin)
|
dependsOn(signPlugin)
|
||||||
}
|
}
|
||||||
|
publishPlugin {
|
||||||
|
enabled = false
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -206,6 +205,7 @@ publishVersions.forEach {
|
||||||
archiveFile = distFile(it)
|
archiveFile = distFile(it)
|
||||||
token = providers.environmentVariable("IJ_PUBLISH_TOKEN")
|
token = providers.environmentVariable("IJ_PUBLISH_TOKEN")
|
||||||
channels = if (pluginVersion.contains("-")) listOf("nightly") else listOf("default")
|
channels = if (pluginVersion.contains("-")) listOf("nightly") else listOf("default")
|
||||||
|
setDependsOn(dependsOn.filter { if (it is TaskProvider<*>) it.name != "signPlugin" && it.name != "buildPlugin" else true })
|
||||||
}
|
}
|
||||||
tasks.named("publish").configure {
|
tasks.named("publish").configure {
|
||||||
dependsOn("jbpublish-$it")
|
dependsOn("jbpublish-$it")
|
||||||
|
|
28
build.sh
28
build.sh
|
@ -1,23 +1,29 @@
|
||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
#
|
#
|
||||||
# Copyright 2023-2024 FalsePattern
|
# This file is part of ZigBrains.
|
||||||
#
|
#
|
||||||
# Licensed under the Apache License, Version 2.0 (the "License");
|
# Copyright (C) 2023-2025 FalsePattern
|
||||||
# you may not use this file except in compliance with the License.
|
# All Rights Reserved
|
||||||
# You may obtain a copy of the License at
|
|
||||||
#
|
#
|
||||||
# http://www.apache.org/licenses/LICENSE-2.0
|
# The above copyright notice and this permission notice shall be included
|
||||||
|
# in all copies or substantial portions of the Software.
|
||||||
#
|
#
|
||||||
# Unless required by applicable law or agreed to in writing, software
|
# ZigBrains is free software: you can redistribute it and/or modify
|
||||||
# distributed under the License is distributed on an "AS IS" BASIS,
|
# it under the terms of the GNU Lesser General Public License as published by
|
||||||
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
# the Free Software Foundation, only version 3 of the License.
|
||||||
# See the License for the specific language governing permissions and
|
#
|
||||||
# limitations under the License.
|
# ZigBrains is distributed in the hope that it will be useful,
|
||||||
|
# but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
# GNU Lesser General Public License for more details.
|
||||||
|
#
|
||||||
|
# You should have received a copy of the GNU Lesser General Public License
|
||||||
|
# along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||||
#
|
#
|
||||||
|
|
||||||
set -e
|
set -e
|
||||||
|
|
||||||
declare -a branches=("master" "242" "241")
|
declare -a branches=("master" "243" "242" "241")
|
||||||
|
|
||||||
DEFAULT_BRANCH="${branches[0]}"
|
DEFAULT_BRANCH="${branches[0]}"
|
||||||
|
|
||||||
|
|
|
@ -7,12 +7,15 @@ plugins {
|
||||||
}
|
}
|
||||||
val lsp4jVersion: String by project
|
val lsp4jVersion: String by project
|
||||||
val clionVersion: String by project
|
val clionVersion: String by project
|
||||||
|
val useInstaller = property("useInstaller").toString().toBoolean()
|
||||||
|
|
||||||
val genOutputDir = layout.buildDirectory.dir("generated-resources")
|
val genOutputDir = layout.buildDirectory.dir("generated-resources")
|
||||||
sourceSets["main"].resources.srcDir(genOutputDir)
|
sourceSets["main"].resources.srcDir(genOutputDir)
|
||||||
|
|
||||||
tasks {
|
tasks {
|
||||||
register<Download>("downloadProps") {
|
register<Download>("downloadProps") {
|
||||||
|
onlyIfModified(true)
|
||||||
|
useETag(true)
|
||||||
src("https://falsepattern.com/zigbrains/msvc.properties")
|
src("https://falsepattern.com/zigbrains/msvc.properties")
|
||||||
dest(genOutputDir.map { it.file("msvc.properties") })
|
dest(genOutputDir.map { it.file("msvc.properties") })
|
||||||
}
|
}
|
||||||
|
@ -23,10 +26,12 @@ tasks {
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
create(IntelliJPlatformType.CLion, providers.gradleProperty("clionVersion"))
|
create(IntelliJPlatformType.CLion, clionVersion, useInstaller = useInstaller)
|
||||||
bundledPlugins("com.intellij.clion", "com.intellij.cidr.base", "com.intellij.nativeDebug")
|
bundledPlugins("com.intellij.clion", "com.intellij.cidr.base", "com.intellij.nativeDebug")
|
||||||
}
|
}
|
||||||
implementation(project(":core"))
|
implementation(project(":core")) {
|
||||||
|
isTransitive = false
|
||||||
|
}
|
||||||
implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.debug:$lsp4jVersion") {
|
implementation("org.eclipse.lsp4j:org.eclipse.lsp4j.debug:$lsp4jVersion") {
|
||||||
exclude("org.eclipse.lsp4j", "org.eclipse.lsp4j")
|
exclude("org.eclipse.lsp4j", "org.eclipse.lsp4j")
|
||||||
exclude("org.eclipse.lsp4j", "org.eclipse.lsp4j.jsonrpc")
|
exclude("org.eclipse.lsp4j", "org.eclipse.lsp4j.jsonrpc")
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -24,7 +24,6 @@ package com.falsepattern.zigbrains.clion
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.debugger.ZigDebuggerDriverConfigurationProvider
|
import com.falsepattern.zigbrains.debugger.ZigDebuggerDriverConfigurationProvider
|
||||||
import com.falsepattern.zigbrains.debugger.settings.ZigDebuggerSettings
|
import com.falsepattern.zigbrains.debugger.settings.ZigDebuggerSettings
|
||||||
import com.intellij.openapi.diagnostic.Logger
|
|
||||||
import com.intellij.openapi.diagnostic.logger
|
import com.intellij.openapi.diagnostic.logger
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.util.SystemInfo
|
import com.intellij.openapi.util.SystemInfo
|
||||||
|
@ -58,8 +57,9 @@ class ZigClionDebuggerDriverConfigurationProvider: ZigDebuggerDriverConfiguratio
|
||||||
}
|
}
|
||||||
return when(toolchain.debuggerKind) {
|
return when(toolchain.debuggerKind) {
|
||||||
CPPDebugger.Kind.BUNDLED_GDB,
|
CPPDebugger.Kind.BUNDLED_GDB,
|
||||||
CPPDebugger.Kind.CUSTOM_GDB -> CLionGDBDriverConfiguration(project, toolchain)
|
CPPDebugger.Kind.CUSTOM_GDB -> CLionGDBDriverConfiguration(project, toolchain, isEmulateTerminal = emulateTerminal)
|
||||||
CPPDebugger.Kind.BUNDLED_LLDB -> CLionLLDBDriverConfiguration(project, toolchain)
|
CPPDebugger.Kind.BUNDLED_LLDB,
|
||||||
|
CPPDebugger.Kind.CUSTOM_LLDB -> CLionLLDBDriverConfiguration(project, toolchain, isEmulateTerminal = emulateTerminal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -27,6 +27,7 @@ import com.falsepattern.zigbrains.debugger.toolchain.*
|
||||||
import com.falsepattern.zigbrains.debugger.win.MSVCDriverConfiguration
|
import com.falsepattern.zigbrains.debugger.win.MSVCDriverConfiguration
|
||||||
import com.falsepattern.zigbrains.shared.coroutine.withEDTContext
|
import com.falsepattern.zigbrains.shared.coroutine.withEDTContext
|
||||||
import com.falsepattern.zigbrains.zig.ZigLanguage
|
import com.falsepattern.zigbrains.zig.ZigLanguage
|
||||||
|
import com.intellij.openapi.application.ModalityState
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.ui.DoNotAskOption
|
import com.intellij.openapi.ui.DoNotAskOption
|
||||||
import com.intellij.openapi.ui.MessageDialogBuilder
|
import com.intellij.openapi.ui.MessageDialogBuilder
|
||||||
|
@ -85,7 +86,7 @@ private suspend fun availabilityCheck(project: Project, kind: DebuggerKind): Boo
|
||||||
}
|
}
|
||||||
|
|
||||||
if (downloadDebugger) {
|
if (downloadDebugger) {
|
||||||
val result = withEDTContext {
|
val result = withEDTContext(ModalityState.any()) {
|
||||||
service.downloadDebugger(project, kind)
|
service.downloadDebugger(project, kind)
|
||||||
}
|
}
|
||||||
if (result is ZigDebuggerToolchainService.DownloadResult.Ok) {
|
if (result is ZigDebuggerToolchainService.DownloadResult.Ok) {
|
||||||
|
@ -104,7 +105,7 @@ private suspend fun showDialog(project: Project, message: String, action: String
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return withEDTContext {
|
return withEDTContext(ModalityState.any()) {
|
||||||
MessageDialogBuilder
|
MessageDialogBuilder
|
||||||
.okCancel(ZigDebugBundle.message("debugger.run.unavailable"), message)
|
.okCancel(ZigDebugBundle.message("debugger.run.unavailable"), message)
|
||||||
.yesText(action)
|
.yesText(action)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -22,9 +22,10 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.debugger
|
package com.falsepattern.zigbrains.debugger
|
||||||
|
|
||||||
|
import com.intellij.execution.filters.Filter
|
||||||
import com.intellij.execution.filters.TextConsoleBuilder
|
import com.intellij.execution.filters.TextConsoleBuilder
|
||||||
import com.intellij.xdebugger.XDebugSession
|
import com.intellij.xdebugger.XDebugSession
|
||||||
import com.jetbrains.cidr.execution.RunParameters
|
import com.jetbrains.cidr.execution.RunParameters
|
||||||
import com.jetbrains.cidr.execution.debugger.CidrLocalDebugProcess
|
import com.jetbrains.cidr.execution.debugger.CidrLocalDebugProcess
|
||||||
|
|
||||||
class ZigLocalDebugProcess(parameters: RunParameters, session: XDebugSession, consoleBuilder: TextConsoleBuilder) : CidrLocalDebugProcess(parameters, session, consoleBuilder)
|
class ZigLocalDebugProcess(parameters: RunParameters, session: XDebugSession, consoleBuilder: TextConsoleBuilder) : CidrLocalDebugProcess(parameters, session, consoleBuilder, { Filter.EMPTY_ARRAY }, true)
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -26,11 +26,7 @@ import com.falsepattern.zigbrains.project.run.ZigProcessHandler
|
||||||
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
||||||
import com.intellij.execution.ExecutionException
|
import com.intellij.execution.ExecutionException
|
||||||
import com.intellij.execution.configurations.PtyCommandLine
|
import com.intellij.execution.configurations.PtyCommandLine
|
||||||
import com.intellij.execution.process.BaseProcessHandler
|
import com.intellij.execution.process.*
|
||||||
import com.intellij.execution.process.ProcessAdapter
|
|
||||||
import com.intellij.execution.process.ProcessEvent
|
|
||||||
import com.intellij.execution.process.ProcessListener
|
|
||||||
import com.intellij.execution.process.ProcessOutputType
|
|
||||||
import com.intellij.openapi.util.Key
|
import com.intellij.openapi.util.Key
|
||||||
import com.intellij.openapi.util.KeyWithDefaultValue
|
import com.intellij.openapi.util.KeyWithDefaultValue
|
||||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||||
|
@ -45,9 +41,12 @@ import com.jetbrains.cidr.execution.debugger.memory.AddressRange
|
||||||
import com.jetbrains.cidr.system.HostMachine
|
import com.jetbrains.cidr.system.HostMachine
|
||||||
import com.jetbrains.cidr.system.LocalHost
|
import com.jetbrains.cidr.system.LocalHost
|
||||||
import io.ktor.util.*
|
import io.ktor.util.*
|
||||||
import kotlinx.coroutines.*
|
import kotlinx.coroutines.Job
|
||||||
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.future.asCompletableFuture
|
import kotlinx.coroutines.future.asCompletableFuture
|
||||||
import kotlinx.coroutines.future.asDeferred
|
import kotlinx.coroutines.future.asDeferred
|
||||||
|
import kotlinx.coroutines.launch
|
||||||
|
import kotlinx.coroutines.runBlocking
|
||||||
import org.eclipse.lsp4j.debug.*
|
import org.eclipse.lsp4j.debug.*
|
||||||
import org.eclipse.lsp4j.debug.services.IDebugProtocolClient
|
import org.eclipse.lsp4j.debug.services.IDebugProtocolClient
|
||||||
import org.eclipse.lsp4j.debug.services.IDebugProtocolServer
|
import org.eclipse.lsp4j.debug.services.IDebugProtocolServer
|
||||||
|
@ -58,8 +57,7 @@ import java.io.ByteArrayOutputStream
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.io.OutputStream
|
import java.io.OutputStream
|
||||||
import java.io.PipedOutputStream
|
import java.io.PipedOutputStream
|
||||||
import java.lang.Exception
|
import java.util.*
|
||||||
import java.util.TreeMap
|
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.concurrent.Executors
|
import java.util.concurrent.Executors
|
||||||
import kotlin.math.min
|
import kotlin.math.min
|
||||||
|
@ -213,7 +211,7 @@ abstract class DAPDriver<Server : IDebugProtocolServer, Client : IDebugProtocolC
|
||||||
val cli = installer.install()
|
val cli = installer.install()
|
||||||
val args = HashMap<String, Any>()
|
val args = HashMap<String, Any>()
|
||||||
args["program"] = Util.toWinPath(cli.exePath)
|
args["program"] = Util.toWinPath(cli.exePath)
|
||||||
args["cmd"] = cli.workDirectory.toString()
|
args["cmd"] = cli.workingDirectory.toString()
|
||||||
args["name"] = "CPP Debug"
|
args["name"] = "CPP Debug"
|
||||||
args["type"] = "cppvsdbg"
|
args["type"] = "cppvsdbg"
|
||||||
args["request"] = "launch"
|
args["request"] = "launch"
|
||||||
|
@ -953,7 +951,7 @@ abstract class DAPDriver<Server : IDebugProtocolServer, Client : IDebugProtocolC
|
||||||
|
|
||||||
fun runInTerminalAsync(args: RunInTerminalRequestArguments): RunInTerminalResponse {
|
fun runInTerminalAsync(args: RunInTerminalRequestArguments): RunInTerminalResponse {
|
||||||
val cli = PtyCommandLine(args.args.toList())
|
val cli = PtyCommandLine(args.args.toList())
|
||||||
cli.charset = Charsets.UTF_8
|
cli.withCharset(Charsets.UTF_8)
|
||||||
val cwd = args.cwd?.ifBlank { null }?.toNioPathOrNull()
|
val cwd = args.cwd?.ifBlank { null }?.toNioPathOrNull()
|
||||||
if (cwd != null) {
|
if (cwd != null) {
|
||||||
cli.withWorkingDirectory(cwd)
|
cli.withWorkingDirectory(cwd)
|
||||||
|
|
|
@ -1,17 +1,23 @@
|
||||||
/*
|
/*
|
||||||
* Copyright 2023-2024 FalsePattern
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Licensed under the Apache License, Version 2.0 (the "License");
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* you may not use this file except in compliance with the License.
|
* All Rights Reserved
|
||||||
* You may obtain a copy of the License at
|
|
||||||
*
|
*
|
||||||
* http://www.apache.org/licenses/LICENSE-2.0
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
*
|
*
|
||||||
* Unless required by applicable law or agreed to in writing, software
|
* ZigBrains is free software: you can redistribute it and/or modify
|
||||||
* distributed under the License is distributed on an "AS IS" BASIS,
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
* the Free Software Foundation, only version 3 of the License.
|
||||||
* See the License for the specific language governing permissions and
|
*
|
||||||
* limitations under the License.
|
* ZigBrains is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
package com.falsepattern.zigbrains.debugger.dap
|
package com.falsepattern.zigbrains.debugger.dap
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -33,7 +33,7 @@ class ZigConfigTypeBinary: ConfigurationTypeBase(
|
||||||
IDENTIFIER,
|
IDENTIFIER,
|
||||||
ZigDebugBundle.message("configuration.binary.name"),
|
ZigDebugBundle.message("configuration.binary.name"),
|
||||||
ZigDebugBundle.message("configuration.binary.description"),
|
ZigDebugBundle.message("configuration.binary.description"),
|
||||||
Icons.ZIG
|
Icons.Zig
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
addFactory(ConfigFactoryBinary(this))
|
addFactory(ConfigFactoryBinary(this))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -39,7 +39,7 @@ class ZigExecConfigBinary(project: Project, factory: ConfigurationFactory) : Zig
|
||||||
get() = ZigDebugBundle.message("configuration.binary.suggested-name")
|
get() = ZigDebugBundle.message("configuration.binary.suggested-name")
|
||||||
|
|
||||||
override suspend fun buildCommandLineArgs(debug: Boolean): List<String> {
|
override suspend fun buildCommandLineArgs(debug: Boolean): List<String> {
|
||||||
return args.args
|
return args.argsSplit()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getConfigurables(): List<ZigConfigurable<*>> {
|
override fun getConfigurables(): List<ZigConfigurable<*>> {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -24,14 +24,14 @@ package com.falsepattern.zigbrains.debugger.execution.binary
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.debugger.ZigDebugBundle
|
import com.falsepattern.zigbrains.debugger.ZigDebugBundle
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.intellij.execution.ExecutionException
|
import com.intellij.execution.ExecutionException
|
||||||
import com.intellij.execution.configurations.GeneralCommandLine
|
import com.intellij.execution.configurations.GeneralCommandLine
|
||||||
import com.intellij.execution.runners.ExecutionEnvironment
|
import com.intellij.execution.runners.ExecutionEnvironment
|
||||||
import kotlin.io.path.pathString
|
import kotlin.io.path.pathString
|
||||||
|
|
||||||
class ZigProfileStateBinary(environment: ExecutionEnvironment, configuration: ZigExecConfigBinary) : ZigProfileState<ZigExecConfigBinary>(environment, configuration) {
|
class ZigProfileStateBinary(environment: ExecutionEnvironment, configuration: ZigExecConfigBinary) : ZigProfileState<ZigExecConfigBinary>(environment, configuration) {
|
||||||
override suspend fun getCommandLine(toolchain: AbstractZigToolchain, debug: Boolean): GeneralCommandLine {
|
override suspend fun getCommandLine(toolchain: ZigToolchain, debug: Boolean): GeneralCommandLine {
|
||||||
val cli = GeneralCommandLine()
|
val cli = GeneralCommandLine()
|
||||||
val cfg = configuration
|
val cfg = configuration
|
||||||
cfg.workingDirectory.path?.let { cli.withWorkingDirectory(it) }
|
cfg.workingDirectory.path?.let { cli.withWorkingDirectory(it) }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
package com.falsepattern.zigbrains.debugger.runner.base
|
package com.falsepattern.zigbrains.debugger.runner.base
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.run.ZigProcessHandler
|
import com.falsepattern.zigbrains.project.run.ZigProcessHandler
|
||||||
|
import com.falsepattern.zigbrains.shared.cli.startIPCAwareProcess
|
||||||
import com.intellij.execution.ExecutionException
|
import com.intellij.execution.ExecutionException
|
||||||
import com.intellij.execution.configurations.GeneralCommandLine
|
import com.intellij.execution.configurations.GeneralCommandLine
|
||||||
import com.intellij.execution.process.ProcessEvent
|
import com.intellij.execution.process.ProcessEvent
|
||||||
|
@ -30,6 +31,7 @@ import com.intellij.execution.process.ProcessHandler
|
||||||
import com.intellij.execution.process.ProcessListener
|
import com.intellij.execution.process.ProcessListener
|
||||||
import com.intellij.execution.ui.ConsoleView
|
import com.intellij.execution.ui.ConsoleView
|
||||||
import com.intellij.execution.ui.ConsoleViewContentType
|
import com.intellij.execution.ui.ConsoleViewContentType
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.platform.util.progress.withProgressText
|
import com.intellij.platform.util.progress.withProgressText
|
||||||
import com.intellij.util.io.awaitExit
|
import com.intellij.util.io.awaitExit
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
@ -39,17 +41,17 @@ import kotlinx.coroutines.withContext
|
||||||
class PreLaunchProcessListener(val console: ConsoleView) : ProcessListener {
|
class PreLaunchProcessListener(val console: ConsoleView) : ProcessListener {
|
||||||
var isBuildFailed: Boolean = false
|
var isBuildFailed: Boolean = false
|
||||||
private set
|
private set
|
||||||
lateinit var processHandler: ProcessHandler
|
lateinit var processHandler: ZigProcessHandler.IPCAware
|
||||||
private set
|
private set
|
||||||
|
|
||||||
@Throws(ExecutionException::class)
|
@Throws(ExecutionException::class)
|
||||||
suspend fun executeCommandLineWithHook(commandLine: GeneralCommandLine): Boolean {
|
suspend fun executeCommandLineWithHook(project: Project, commandLine: GeneralCommandLine): Boolean {
|
||||||
return withProgressText(commandLine.commandLineString) {
|
return withProgressText(commandLine.commandLineString) {
|
||||||
val processHandler = ZigProcessHandler(commandLine)
|
val processHandler = commandLine.startIPCAwareProcess(project)
|
||||||
this@PreLaunchProcessListener.processHandler = processHandler
|
this@PreLaunchProcessListener.processHandler = processHandler
|
||||||
hook(processHandler)
|
hook(processHandler)
|
||||||
processHandler.startNotify()
|
processHandler.startNotify()
|
||||||
withContext(Dispatchers.Default) {
|
withContext(Dispatchers.IO) {
|
||||||
processHandler.process.awaitExit()
|
processHandler.process.awaitExit()
|
||||||
}
|
}
|
||||||
runInterruptible {
|
runInterruptible {
|
||||||
|
@ -66,10 +68,6 @@ class PreLaunchProcessListener(val console: ConsoleView) : ProcessListener {
|
||||||
|
|
||||||
override fun processTerminated(event: ProcessEvent) {
|
override fun processTerminated(event: ProcessEvent) {
|
||||||
if (event.exitCode != 0) {
|
if (event.exitCode != 0) {
|
||||||
console.print(
|
|
||||||
"Process finished with exit code " + event.exitCode,
|
|
||||||
ConsoleViewContentType.NORMAL_OUTPUT
|
|
||||||
)
|
|
||||||
isBuildFailed = true
|
isBuildFailed = true
|
||||||
} else {
|
} else {
|
||||||
isBuildFailed = false
|
isBuildFailed = false
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -23,9 +23,10 @@
|
||||||
package com.falsepattern.zigbrains.debugger.runner.base
|
package com.falsepattern.zigbrains.debugger.runner.base
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
||||||
import com.intellij.execution.configurations.GeneralCommandLine
|
import com.intellij.execution.configurations.GeneralCommandLine
|
||||||
|
import com.intellij.execution.configurations.PtyCommandLine
|
||||||
import com.jetbrains.cidr.execution.Installer
|
import com.jetbrains.cidr.execution.Installer
|
||||||
import kotlinx.coroutines.async
|
import kotlinx.coroutines.async
|
||||||
import kotlinx.coroutines.future.asCompletableFuture
|
import kotlinx.coroutines.future.asCompletableFuture
|
||||||
|
@ -33,13 +34,13 @@ import java.io.File
|
||||||
|
|
||||||
class ZigDebugEmitBinaryInstaller<ProfileState: ZigProfileState<*>>(
|
class ZigDebugEmitBinaryInstaller<ProfileState: ZigProfileState<*>>(
|
||||||
private val profileState: ProfileState,
|
private val profileState: ProfileState,
|
||||||
private val toolchain: AbstractZigToolchain,
|
private val toolchain: ZigToolchain,
|
||||||
private val executableFile: File,
|
private val executableFile: File,
|
||||||
private val exeArgs: List<String>
|
private val exeArgs: List<String>
|
||||||
): Installer {
|
): Installer {
|
||||||
override fun install(): GeneralCommandLine {
|
override fun install(): GeneralCommandLine {
|
||||||
val cfg = profileState.configuration
|
val cfg = profileState.configuration
|
||||||
val cli = GeneralCommandLine().withExePath(executableFile.absolutePath)
|
val cli = PtyCommandLine().withConsoleMode(false).withExePath(executableFile.absolutePath)
|
||||||
cfg.workingDirectory.path?.let { x -> cli.withWorkingDirectory(x) }
|
cfg.workingDirectory.path?.let { x -> cli.withWorkingDirectory(x) }
|
||||||
cli.addParameters(exeArgs)
|
cli.addParameters(exeArgs)
|
||||||
cli.withCharset(Charsets.UTF_8)
|
cli.withCharset(Charsets.UTF_8)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -23,7 +23,7 @@
|
||||||
package com.falsepattern.zigbrains.debugger.runner.base
|
package com.falsepattern.zigbrains.debugger.runner.base
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.intellij.util.system.CpuArch
|
import com.intellij.util.system.CpuArch
|
||||||
import com.jetbrains.cidr.ArchitectureType
|
import com.jetbrains.cidr.ArchitectureType
|
||||||
import com.jetbrains.cidr.execution.RunParameters
|
import com.jetbrains.cidr.execution.RunParameters
|
||||||
|
@ -31,7 +31,7 @@ import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
||||||
|
|
||||||
abstract class ZigDebugParametersBase<ProfileState: ZigProfileState<*>>(
|
abstract class ZigDebugParametersBase<ProfileState: ZigProfileState<*>>(
|
||||||
private val driverConfiguration: DebuggerDriverConfiguration,
|
private val driverConfiguration: DebuggerDriverConfiguration,
|
||||||
protected val toolchain: AbstractZigToolchain,
|
protected val toolchain: ZigToolchain,
|
||||||
protected val profileState: ProfileState
|
protected val profileState: ProfileState
|
||||||
): RunParameters() {
|
): RunParameters() {
|
||||||
override fun getDebuggerDriverConfiguration(): DebuggerDriverConfiguration {
|
override fun getDebuggerDriverConfiguration(): DebuggerDriverConfiguration {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -24,9 +24,10 @@ package com.falsepattern.zigbrains.debugger.runner.base
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.debugger.ZigDebugBundle
|
import com.falsepattern.zigbrains.debugger.ZigDebugBundle
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.intellij.execution.ExecutionException
|
import com.intellij.execution.ExecutionException
|
||||||
import com.intellij.openapi.util.io.FileUtil
|
import com.intellij.openapi.util.io.FileUtil
|
||||||
|
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||||
import com.intellij.platform.util.progress.withProgressText
|
import com.intellij.platform.util.progress.withProgressText
|
||||||
import com.intellij.util.containers.orNull
|
import com.intellij.util.containers.orNull
|
||||||
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
||||||
|
@ -36,10 +37,11 @@ import java.io.File
|
||||||
import java.nio.file.Files
|
import java.nio.file.Files
|
||||||
import kotlin.io.path.absolutePathString
|
import kotlin.io.path.absolutePathString
|
||||||
import kotlin.io.path.isExecutable
|
import kotlin.io.path.isExecutable
|
||||||
|
import kotlin.io.path.pathString
|
||||||
|
|
||||||
abstract class ZigDebugParametersEmitBinaryBase<ProfileState: ZigProfileState<*>>(
|
abstract class ZigDebugParametersEmitBinaryBase<ProfileState: ZigProfileState<*>>(
|
||||||
driverConfiguration: DebuggerDriverConfiguration,
|
driverConfiguration: DebuggerDriverConfiguration,
|
||||||
toolchain: AbstractZigToolchain,
|
toolchain: ZigToolchain,
|
||||||
profileState: ProfileState,
|
profileState: ProfileState,
|
||||||
) : ZigDebugParametersBase<ProfileState>(driverConfiguration, toolchain, profileState), PreLaunchAware {
|
) : ZigDebugParametersBase<ProfileState>(driverConfiguration, toolchain, profileState), PreLaunchAware {
|
||||||
@Volatile
|
@Volatile
|
||||||
|
@ -49,13 +51,14 @@ abstract class ZigDebugParametersEmitBinaryBase<ProfileState: ZigProfileState<*>
|
||||||
@Throws(ExecutionException::class)
|
@Throws(ExecutionException::class)
|
||||||
private suspend fun compileExe(listener: PreLaunchProcessListener): File {
|
private suspend fun compileExe(listener: PreLaunchProcessListener): File {
|
||||||
val commandLine = profileState.getCommandLine(toolchain, true)
|
val commandLine = profileState.getCommandLine(toolchain, true)
|
||||||
|
val cliString = commandLine.getCommandLineString(commandLine.exePath.toNioPathOrNull()?.fileName?.pathString)
|
||||||
val tmpDir = FileUtil.createTempDirectory("zigbrains_debug", "", true).toPath()
|
val tmpDir = FileUtil.createTempDirectory("zigbrains_debug", "", true).toPath()
|
||||||
|
|
||||||
val exe = tmpDir.resolve("executable")
|
val exe = tmpDir.resolve("executable")
|
||||||
commandLine.addParameters("-femit-bin=${exe.absolutePathString()}")
|
commandLine.addParameters("-femit-bin=${exe.absolutePathString()}")
|
||||||
|
|
||||||
if (listener.executeCommandLineWithHook(commandLine))
|
if (listener.executeCommandLineWithHook(profileState.environment.project, commandLine))
|
||||||
throw ExecutionException(ZigDebugBundle.message("debug.base.compile.failed.generic"))
|
throw ExecutionException(ZigDebugBundle.message("debug.base.compile.failed.generic", cliString))
|
||||||
|
|
||||||
return withContext(Dispatchers.IO) {
|
return withContext(Dispatchers.IO) {
|
||||||
Files.list(tmpDir).use { stream ->
|
Files.list(tmpDir).use { stream ->
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -24,9 +24,10 @@ package com.falsepattern.zigbrains.debugger.runner.base
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.debugbridge.ZigDebuggerDriverConfigurationProviderBase
|
import com.falsepattern.zigbrains.debugbridge.ZigDebuggerDriverConfigurationProviderBase
|
||||||
import com.falsepattern.zigbrains.debugger.ZigLocalDebugProcess
|
import com.falsepattern.zigbrains.debugger.ZigLocalDebugProcess
|
||||||
|
import com.falsepattern.zigbrains.debugger.runner.build.ZigDebugRunnerBuild
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
import com.falsepattern.zigbrains.project.run.ZigProgramRunner
|
import com.falsepattern.zigbrains.project.run.ZigProgramRunner
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.falsepattern.zigbrains.shared.coroutine.runInterruptibleEDT
|
import com.falsepattern.zigbrains.shared.coroutine.runInterruptibleEDT
|
||||||
import com.falsepattern.zigbrains.shared.coroutine.withEDTContext
|
import com.falsepattern.zigbrains.shared.coroutine.withEDTContext
|
||||||
import com.intellij.execution.DefaultExecutionResult
|
import com.intellij.execution.DefaultExecutionResult
|
||||||
|
@ -40,6 +41,8 @@ import com.intellij.execution.runners.RunContentBuilder
|
||||||
import com.intellij.execution.ui.ConsoleView
|
import com.intellij.execution.ui.ConsoleView
|
||||||
import com.intellij.execution.ui.ConsoleViewContentType
|
import com.intellij.execution.ui.ConsoleViewContentType
|
||||||
import com.intellij.execution.ui.RunContentDescriptor
|
import com.intellij.execution.ui.RunContentDescriptor
|
||||||
|
import com.intellij.openapi.application.ModalityState
|
||||||
|
import com.intellij.openapi.project.guessProjectDir
|
||||||
import com.intellij.platform.util.progress.reportProgress
|
import com.intellij.platform.util.progress.reportProgress
|
||||||
import com.intellij.xdebugger.XDebugProcess
|
import com.intellij.xdebugger.XDebugProcess
|
||||||
import com.intellij.xdebugger.XDebugProcessStarter
|
import com.intellij.xdebugger.XDebugProcessStarter
|
||||||
|
@ -51,13 +54,13 @@ abstract class ZigDebugRunnerBase<ProfileState : ZigProfileState<*>> : ZigProgra
|
||||||
@Throws(ExecutionException::class)
|
@Throws(ExecutionException::class)
|
||||||
override suspend fun execute(
|
override suspend fun execute(
|
||||||
state: ProfileState,
|
state: ProfileState,
|
||||||
toolchain: AbstractZigToolchain,
|
toolchain: ZigToolchain,
|
||||||
environment: ExecutionEnvironment
|
environment: ExecutionEnvironment
|
||||||
): RunContentDescriptor? {
|
): RunContentDescriptor? {
|
||||||
val project = environment.project
|
val project = environment.project
|
||||||
val driverProviders = ZigDebuggerDriverConfigurationProviderBase.EXTENSION_POINT_NAME.extensionList
|
val driverProviders = ZigDebuggerDriverConfigurationProviderBase.EXTENSION_POINT_NAME.extensionList
|
||||||
for (provider in driverProviders) {
|
for (provider in driverProviders) {
|
||||||
val driver = provider.getDebuggerConfiguration(project, isElevated = false, emulateTerminal = false, DebuggerDriverConfiguration::class.java) ?: continue
|
val driver = provider.getDebuggerConfiguration(project, isElevated = false, emulateTerminal = true, DebuggerDriverConfiguration::class.java) ?: continue
|
||||||
return executeWithDriver(state, toolchain, environment, driver) ?: continue
|
return executeWithDriver(state, toolchain, environment, driver) ?: continue
|
||||||
}
|
}
|
||||||
return null
|
return null
|
||||||
|
@ -66,7 +69,7 @@ abstract class ZigDebugRunnerBase<ProfileState : ZigProfileState<*>> : ZigProgra
|
||||||
@Throws(ExecutionException::class)
|
@Throws(ExecutionException::class)
|
||||||
private suspend fun executeWithDriver(
|
private suspend fun executeWithDriver(
|
||||||
state: ProfileState,
|
state: ProfileState,
|
||||||
toolchain: AbstractZigToolchain,
|
toolchain: ZigToolchain,
|
||||||
environment: ExecutionEnvironment,
|
environment: ExecutionEnvironment,
|
||||||
debuggerDriver: DebuggerDriverConfiguration
|
debuggerDriver: DebuggerDriverConfiguration
|
||||||
): RunContentDescriptor? {
|
): RunContentDescriptor? {
|
||||||
|
@ -81,22 +84,25 @@ abstract class ZigDebugRunnerBase<ProfileState : ZigProfileState<*>> : ZigProgra
|
||||||
}
|
}
|
||||||
} catch (e: ExecutionException) {
|
} catch (e: ExecutionException) {
|
||||||
console.print("\n", ConsoleViewContentType.ERROR_OUTPUT)
|
console.print("\n", ConsoleViewContentType.ERROR_OUTPUT)
|
||||||
e.message?.let { listener.console.print(it, ConsoleViewContentType.SYSTEM_OUTPUT) }
|
e.message?.let { listener.console.print(it, ConsoleViewContentType.ERROR_OUTPUT) }
|
||||||
|
if (this !is ZigDebugRunnerBuild && environment.project.guessProjectDir()?.children?.any { it.name == "build.zig" } == true) {
|
||||||
|
console.print("\n Warning: build.zig file detected in project.\n Did you want to use a Zig Build task instead?", ConsoleViewContentType.ERROR_OUTPUT)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
if (listener.isBuildFailed) {
|
if (listener.isBuildFailed) {
|
||||||
val executionResult = DefaultExecutionResult(console, listener.processHandler)
|
val executionResult = DefaultExecutionResult(console, listener.processHandler.unwrap())
|
||||||
return@reportProgress withEDTContext {
|
return@reportProgress withEDTContext(ModalityState.any()) {
|
||||||
val runContentBuilder = RunContentBuilder(executionResult, environment)
|
val runContentBuilder = RunContentBuilder(executionResult, environment)
|
||||||
runContentBuilder.showRunContent(null)
|
runContentBuilder.showRunContent(null)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return@reportProgress runInterruptibleEDT {
|
return@reportProgress runInterruptibleEDT(ModalityState.any()) {
|
||||||
val debuggerManager = XDebuggerManager.getInstance(environment.project)
|
val debuggerManager = XDebuggerManager.getInstance(environment.project)
|
||||||
debuggerManager.startSession(environment, object: XDebugProcessStarter() {
|
debuggerManager.startSession(environment, object: XDebugProcessStarter() {
|
||||||
override fun start(session: XDebugSession): XDebugProcess {
|
override fun start(session: XDebugSession): XDebugProcess {
|
||||||
val project = session.project
|
val project = session.project
|
||||||
val textConsoleBuilder = SharedConsoleBuilder(console)
|
val textConsoleBuilder = state.consoleBuilder
|
||||||
val debugProcess = ZigLocalDebugProcess(runParameters, session, textConsoleBuilder)
|
val debugProcess = ZigLocalDebugProcess(runParameters, session, textConsoleBuilder)
|
||||||
ProcessTerminatedListener.attach(debugProcess.processHandler, project)
|
ProcessTerminatedListener.attach(debugProcess.processHandler, project)
|
||||||
debugProcess.start()
|
debugProcess.start()
|
||||||
|
@ -111,7 +117,7 @@ abstract class ZigDebugRunnerBase<ProfileState : ZigProfileState<*>> : ZigProgra
|
||||||
protected abstract fun getDebugParameters(
|
protected abstract fun getDebugParameters(
|
||||||
state: ProfileState,
|
state: ProfileState,
|
||||||
debuggerDriver: DebuggerDriverConfiguration,
|
debuggerDriver: DebuggerDriverConfiguration,
|
||||||
toolchain: AbstractZigToolchain
|
toolchain: ZigToolchain
|
||||||
): ZigDebugParametersBase<ProfileState>
|
): ZigDebugParametersBase<ProfileState>
|
||||||
|
|
||||||
private class SharedConsoleBuilder(private val console: ConsoleView) : TextConsoleBuilder() {
|
private class SharedConsoleBuilder(private val console: ConsoleView) : TextConsoleBuilder() {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -26,16 +26,16 @@ import com.falsepattern.zigbrains.debugger.ZigDebugBundle
|
||||||
import com.falsepattern.zigbrains.debugger.execution.binary.ZigProfileStateBinary
|
import com.falsepattern.zigbrains.debugger.execution.binary.ZigProfileStateBinary
|
||||||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugEmitBinaryInstaller
|
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugEmitBinaryInstaller
|
||||||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugParametersBase
|
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugParametersBase
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.intellij.execution.ExecutionException
|
import com.intellij.execution.ExecutionException
|
||||||
import com.jetbrains.cidr.execution.Installer
|
import com.jetbrains.cidr.execution.Installer
|
||||||
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
||||||
|
|
||||||
|
|
||||||
class ZigDebugParametersBinary @Throws(ExecutionException::class) constructor(driverConfiguration: DebuggerDriverConfiguration, toolchain: AbstractZigToolchain, profileState: ZigProfileStateBinary) :
|
class ZigDebugParametersBinary @Throws(ExecutionException::class) constructor(driverConfiguration: DebuggerDriverConfiguration, toolchain: ZigToolchain, profileState: ZigProfileStateBinary) :
|
||||||
ZigDebugParametersBase<ZigProfileStateBinary>(driverConfiguration, toolchain, profileState) {
|
ZigDebugParametersBase<ZigProfileStateBinary>(driverConfiguration, toolchain, profileState) {
|
||||||
private val executableFile = profileState.configuration.exePath.path?.toFile() ?: throw ExecutionException(ZigDebugBundle.message("exception.missing-exe-path"))
|
private val executableFile = profileState.configuration.exePath.path?.toFile() ?: throw ExecutionException(ZigDebugBundle.message("exception.missing-exe-path"))
|
||||||
override fun getInstaller(): Installer {
|
override fun getInstaller(): Installer {
|
||||||
return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.args.args)
|
return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.args.argsSplit())
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -27,8 +27,8 @@ import com.falsepattern.zigbrains.debugger.execution.binary.ZigProfileStateBinar
|
||||||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugParametersBase
|
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugParametersBase
|
||||||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugRunnerBase
|
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugRunnerBase
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.falsepattern.zigbrains.project.toolchain.LocalZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.local.LocalZigToolchain
|
||||||
import com.intellij.execution.configurations.RunProfile
|
import com.intellij.execution.configurations.RunProfile
|
||||||
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class ZigDebugRunnerBinary: ZigDebugRunnerBase<ZigProfileStateBinary>() {
|
||||||
override fun getDebugParameters(
|
override fun getDebugParameters(
|
||||||
state: ZigProfileStateBinary,
|
state: ZigProfileStateBinary,
|
||||||
debuggerDriver: DebuggerDriverConfiguration,
|
debuggerDriver: DebuggerDriverConfiguration,
|
||||||
toolchain: AbstractZigToolchain
|
toolchain: ZigToolchain
|
||||||
): ZigDebugParametersBase<ZigProfileStateBinary> {
|
): ZigDebugParametersBase<ZigProfileStateBinary> {
|
||||||
return ZigDebugParametersBinary(debuggerDriver, LocalZigToolchain.ensureLocal(toolchain), state)
|
return ZigDebugParametersBinary(debuggerDriver, LocalZigToolchain.ensureLocal(toolchain), state)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -28,7 +28,7 @@ import com.falsepattern.zigbrains.debugger.runner.base.PreLaunchProcessListener
|
||||||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugEmitBinaryInstaller
|
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugEmitBinaryInstaller
|
||||||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugParametersBase
|
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugParametersBase
|
||||||
import com.falsepattern.zigbrains.project.execution.build.ZigProfileStateBuild
|
import com.falsepattern.zigbrains.project.execution.build.ZigProfileStateBuild
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.intellij.execution.ExecutionException
|
import com.intellij.execution.ExecutionException
|
||||||
import com.intellij.openapi.util.SystemInfo
|
import com.intellij.openapi.util.SystemInfo
|
||||||
import com.intellij.platform.util.progress.withProgressText
|
import com.intellij.platform.util.progress.withProgressText
|
||||||
|
@ -43,18 +43,17 @@ import java.nio.file.Path
|
||||||
import java.util.stream.Stream
|
import java.util.stream.Stream
|
||||||
import kotlin.io.path.isExecutable
|
import kotlin.io.path.isExecutable
|
||||||
import kotlin.io.path.isRegularFile
|
import kotlin.io.path.isRegularFile
|
||||||
import kotlin.io.path.notExists
|
|
||||||
|
|
||||||
class ZigDebugParametersBuild(
|
class ZigDebugParametersBuild(
|
||||||
driverConfiguration: DebuggerDriverConfiguration,
|
driverConfiguration: DebuggerDriverConfiguration,
|
||||||
toolchain: AbstractZigToolchain,
|
toolchain: ZigToolchain,
|
||||||
profileState: ZigProfileStateBuild
|
profileState: ZigProfileStateBuild
|
||||||
) : ZigDebugParametersBase<ZigProfileStateBuild>(driverConfiguration, toolchain, profileState), PreLaunchAware {
|
) : ZigDebugParametersBase<ZigProfileStateBuild>(driverConfiguration, toolchain, profileState), PreLaunchAware {
|
||||||
@Volatile
|
@Volatile
|
||||||
private lateinit var executableFile: File
|
private lateinit var executableFile: File
|
||||||
|
|
||||||
override fun getInstaller(): Installer {
|
override fun getInstaller(): Installer {
|
||||||
return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.exeArgs.args)
|
return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.exeArgs.argsSplit())
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(ExecutionException::class)
|
@Throws(ExecutionException::class)
|
||||||
|
@ -62,8 +61,8 @@ class ZigDebugParametersBuild(
|
||||||
withProgressText("Building zig project") {
|
withProgressText("Building zig project") {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
val commandLine = profileState.getCommandLine(toolchain, true)
|
val commandLine = profileState.getCommandLine(toolchain, true)
|
||||||
if (listener.executeCommandLineWithHook(commandLine))
|
if (listener.executeCommandLineWithHook(profileState.environment.project, commandLine))
|
||||||
throw ExecutionException(ZigDebugBundle.message("debug.build.compile.failed.generic"))
|
return@withContext
|
||||||
val cfg = profileState.configuration
|
val cfg = profileState.configuration
|
||||||
val workingDir = cfg.workingDirectory.path
|
val workingDir = cfg.workingDirectory.path
|
||||||
val exe = profileState.configuration.exePath.path ?: run {
|
val exe = profileState.configuration.exePath.path ?: run {
|
||||||
|
@ -73,7 +72,7 @@ class ZigDebugParametersBuild(
|
||||||
fail("debug.build.compile.failed.no-workdir")
|
fail("debug.build.compile.failed.no-workdir")
|
||||||
}
|
}
|
||||||
val expectedOutputDir = workingDir.resolve(Path.of("zig-out", "bin"))
|
val expectedOutputDir = workingDir.resolve(Path.of("zig-out", "bin"))
|
||||||
if (expectedOutputDir.notExists()) {
|
if (!expectedOutputDir.toFile().exists()) {
|
||||||
fail("debug.build.compile.failed.autodetect")
|
fail("debug.build.compile.failed.autodetect")
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -82,7 +81,7 @@ class ZigDebugParametersBuild(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (exe.notExists())
|
if (!exe.toFile().exists())
|
||||||
fail("debug.build.compile.failed.no-file", exe)
|
fail("debug.build.compile.failed.no-file", exe)
|
||||||
else if (!exe.isExecutable())
|
else if (!exe.isExecutable())
|
||||||
fail("debug.build.compile.failed.non-exec-file", exe)
|
fail("debug.build.compile.failed.non-exec-file", exe)
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -27,8 +27,8 @@ import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugRunnerBase
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
import com.falsepattern.zigbrains.project.execution.build.ZigExecConfigBuild
|
import com.falsepattern.zigbrains.project.execution.build.ZigExecConfigBuild
|
||||||
import com.falsepattern.zigbrains.project.execution.build.ZigProfileStateBuild
|
import com.falsepattern.zigbrains.project.execution.build.ZigProfileStateBuild
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.falsepattern.zigbrains.project.toolchain.LocalZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.local.LocalZigToolchain
|
||||||
import com.intellij.execution.configurations.RunProfile
|
import com.intellij.execution.configurations.RunProfile
|
||||||
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class ZigDebugRunnerBuild: ZigDebugRunnerBase<ZigProfileStateBuild>() {
|
||||||
override fun getDebugParameters(
|
override fun getDebugParameters(
|
||||||
state: ZigProfileStateBuild,
|
state: ZigProfileStateBuild,
|
||||||
debuggerDriver: DebuggerDriverConfiguration,
|
debuggerDriver: DebuggerDriverConfiguration,
|
||||||
toolchain: AbstractZigToolchain
|
toolchain: ZigToolchain
|
||||||
): ZigDebugParametersBase<ZigProfileStateBuild> {
|
): ZigDebugParametersBase<ZigProfileStateBuild> {
|
||||||
return ZigDebugParametersBuild(debuggerDriver, LocalZigToolchain.ensureLocal(toolchain), state)
|
return ZigDebugParametersBuild(debuggerDriver, LocalZigToolchain.ensureLocal(toolchain), state)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -25,13 +25,13 @@ package com.falsepattern.zigbrains.debugger.runner.run
|
||||||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugEmitBinaryInstaller
|
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugEmitBinaryInstaller
|
||||||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugParametersEmitBinaryBase
|
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugParametersEmitBinaryBase
|
||||||
import com.falsepattern.zigbrains.project.execution.run.ZigProfileStateRun
|
import com.falsepattern.zigbrains.project.execution.run.ZigProfileStateRun
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.jetbrains.cidr.execution.Installer
|
import com.jetbrains.cidr.execution.Installer
|
||||||
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
||||||
|
|
||||||
class ZigDebugParametersRun(driverConfiguration: DebuggerDriverConfiguration, toolchain: AbstractZigToolchain, profileState: ZigProfileStateRun) :
|
class ZigDebugParametersRun(driverConfiguration: DebuggerDriverConfiguration, toolchain: ZigToolchain, profileState: ZigProfileStateRun) :
|
||||||
ZigDebugParametersEmitBinaryBase<ZigProfileStateRun>(driverConfiguration, toolchain, profileState) {
|
ZigDebugParametersEmitBinaryBase<ZigProfileStateRun>(driverConfiguration, toolchain, profileState) {
|
||||||
override fun getInstaller(): Installer {
|
override fun getInstaller(): Installer {
|
||||||
return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.exeArgs.args)
|
return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, profileState.configuration.exeArgs.argsSplit())
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -27,8 +27,8 @@ import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugRunnerBase
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
import com.falsepattern.zigbrains.project.execution.run.ZigExecConfigRun
|
import com.falsepattern.zigbrains.project.execution.run.ZigExecConfigRun
|
||||||
import com.falsepattern.zigbrains.project.execution.run.ZigProfileStateRun
|
import com.falsepattern.zigbrains.project.execution.run.ZigProfileStateRun
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.falsepattern.zigbrains.project.toolchain.LocalZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.local.LocalZigToolchain
|
||||||
import com.intellij.execution.configurations.RunProfile
|
import com.intellij.execution.configurations.RunProfile
|
||||||
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class ZigDebugRunnerRun: ZigDebugRunnerBase<ZigProfileStateRun>() {
|
||||||
override fun getDebugParameters(
|
override fun getDebugParameters(
|
||||||
state: ZigProfileStateRun,
|
state: ZigProfileStateRun,
|
||||||
debuggerDriver: DebuggerDriverConfiguration,
|
debuggerDriver: DebuggerDriverConfiguration,
|
||||||
toolchain: AbstractZigToolchain
|
toolchain: ZigToolchain
|
||||||
): ZigDebugParametersBase<ZigProfileStateRun> {
|
): ZigDebugParametersBase<ZigProfileStateRun> {
|
||||||
return ZigDebugParametersRun(debuggerDriver, LocalZigToolchain.ensureLocal(toolchain), state)
|
return ZigDebugParametersRun(debuggerDriver, LocalZigToolchain.ensureLocal(toolchain), state)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -25,11 +25,11 @@ package com.falsepattern.zigbrains.debugger.runner.test
|
||||||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugEmitBinaryInstaller
|
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugEmitBinaryInstaller
|
||||||
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugParametersEmitBinaryBase
|
import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugParametersEmitBinaryBase
|
||||||
import com.falsepattern.zigbrains.project.execution.test.ZigProfileStateTest
|
import com.falsepattern.zigbrains.project.execution.test.ZigProfileStateTest
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.jetbrains.cidr.execution.Installer
|
import com.jetbrains.cidr.execution.Installer
|
||||||
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
||||||
|
|
||||||
class ZigDebugParametersTest(driverConfiguration: DebuggerDriverConfiguration, toolchain: AbstractZigToolchain, profileState: ZigProfileStateTest) :
|
class ZigDebugParametersTest(driverConfiguration: DebuggerDriverConfiguration, toolchain: ZigToolchain, profileState: ZigProfileStateTest) :
|
||||||
ZigDebugParametersEmitBinaryBase<ZigProfileStateTest>(driverConfiguration, toolchain, profileState) {
|
ZigDebugParametersEmitBinaryBase<ZigProfileStateTest>(driverConfiguration, toolchain, profileState) {
|
||||||
override fun getInstaller(): Installer {
|
override fun getInstaller(): Installer {
|
||||||
return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, listOf())
|
return ZigDebugEmitBinaryInstaller(profileState, toolchain, executableFile, listOf())
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -27,8 +27,8 @@ import com.falsepattern.zigbrains.debugger.runner.base.ZigDebugRunnerBase
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
import com.falsepattern.zigbrains.project.execution.test.ZigExecConfigTest
|
import com.falsepattern.zigbrains.project.execution.test.ZigExecConfigTest
|
||||||
import com.falsepattern.zigbrains.project.execution.test.ZigProfileStateTest
|
import com.falsepattern.zigbrains.project.execution.test.ZigProfileStateTest
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
import com.falsepattern.zigbrains.project.toolchain.LocalZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.local.LocalZigToolchain
|
||||||
import com.intellij.execution.configurations.RunProfile
|
import com.intellij.execution.configurations.RunProfile
|
||||||
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
import com.jetbrains.cidr.execution.debugger.backend.DebuggerDriverConfiguration
|
||||||
|
|
||||||
|
@ -36,7 +36,7 @@ class ZigDebugRunnerTest: ZigDebugRunnerBase<ZigProfileStateTest>() {
|
||||||
override fun getDebugParameters(
|
override fun getDebugParameters(
|
||||||
state: ZigProfileStateTest,
|
state: ZigProfileStateTest,
|
||||||
debuggerDriver: DebuggerDriverConfiguration,
|
debuggerDriver: DebuggerDriverConfiguration,
|
||||||
toolchain: AbstractZigToolchain
|
toolchain: ZigToolchain
|
||||||
): ZigDebugParametersBase<ZigProfileStateTest> {
|
): ZigDebugParametersBase<ZigProfileStateTest> {
|
||||||
return ZigDebugParametersTest(debuggerDriver, LocalZigToolchain.ensureLocal(toolchain), state)
|
return ZigDebugParametersTest(debuggerDriver, LocalZigToolchain.ensureLocal(toolchain), state)
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -29,6 +29,7 @@ import com.intellij.openapi.options.SimpleConfigurable
|
||||||
import com.intellij.util.xmlb.XmlSerializerUtil
|
import com.intellij.util.xmlb.XmlSerializerUtil
|
||||||
import com.intellij.xdebugger.settings.DebuggerSettingsCategory
|
import com.intellij.xdebugger.settings.DebuggerSettingsCategory
|
||||||
import com.intellij.xdebugger.settings.XDebuggerSettings
|
import com.intellij.xdebugger.settings.XDebuggerSettings
|
||||||
|
import java.util.function.Supplier
|
||||||
|
|
||||||
class ZigDebuggerSettings: XDebuggerSettings<ZigDebuggerSettings>("Zig") {
|
class ZigDebuggerSettings: XDebuggerSettings<ZigDebuggerSettings>("Zig") {
|
||||||
var debuggerKind = DebuggerKind.default
|
var debuggerKind = DebuggerKind.default
|
||||||
|
@ -58,9 +59,10 @@ class ZigDebuggerSettings: XDebuggerSettings<ZigDebuggerSettings>("Zig") {
|
||||||
GENERAL_SETTINGS_ID,
|
GENERAL_SETTINGS_ID,
|
||||||
ZigDebugBundle.message("settings.debugger.title"),
|
ZigDebugBundle.message("settings.debugger.title"),
|
||||||
ZigDebuggerGeneralSettingsConfigurableUi::class.java,
|
ZigDebuggerGeneralSettingsConfigurableUi::class.java,
|
||||||
) {
|
Supplier {
|
||||||
instance
|
instance
|
||||||
}
|
}
|
||||||
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
companion object {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -31,6 +31,7 @@ import com.falsepattern.zigbrains.shared.coroutine.launchWithEDT
|
||||||
import com.falsepattern.zigbrains.shared.coroutine.runModalOrBlocking
|
import com.falsepattern.zigbrains.shared.coroutine.runModalOrBlocking
|
||||||
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
||||||
import com.intellij.ide.plugins.PluginManager
|
import com.intellij.ide.plugins.PluginManager
|
||||||
|
import com.intellij.openapi.application.ModalityState
|
||||||
import com.intellij.openapi.extensions.PluginId
|
import com.intellij.openapi.extensions.PluginId
|
||||||
import com.intellij.openapi.observable.util.whenItemSelected
|
import com.intellij.openapi.observable.util.whenItemSelected
|
||||||
import com.intellij.openapi.ui.ComboBox
|
import com.intellij.openapi.ui.ComboBox
|
||||||
|
@ -88,7 +89,7 @@ class ZigDebuggerToolchainConfigurableUi : ZigDebuggerUiComponent {
|
||||||
row(ZigDebugBundle.message("settings.debugger.toolchain.debugger.label")) {
|
row(ZigDebugBundle.message("settings.debugger.toolchain.debugger.label")) {
|
||||||
comment = cell(debuggerKindComboBox)
|
comment = cell(debuggerKindComboBox)
|
||||||
.comment("", DEFAULT_COMMENT_WIDTH) {
|
.comment("", DEFAULT_COMMENT_WIDTH) {
|
||||||
zigCoroutineScope.launchWithEDT {
|
zigCoroutineScope.launchWithEDT(ModalityState.defaultModalityState()) {
|
||||||
withModalProgress(ModalTaskOwner.component(debuggerKindComboBox), "Downloading debugger", TaskCancellation.cancellable()) {
|
withModalProgress(ModalTaskOwner.component(debuggerKindComboBox), "Downloading debugger", TaskCancellation.cancellable()) {
|
||||||
downloadDebugger()
|
downloadDebugger()
|
||||||
}
|
}
|
||||||
|
@ -96,7 +97,7 @@ class ZigDebuggerToolchainConfigurableUi : ZigDebuggerUiComponent {
|
||||||
}
|
}
|
||||||
.applyToComponent {
|
.applyToComponent {
|
||||||
whenItemSelected(null) {
|
whenItemSelected(null) {
|
||||||
zigCoroutineScope.launchWithEDT {
|
zigCoroutineScope.launchWithEDT(ModalityState.defaultModalityState()) {
|
||||||
this@ZigDebuggerToolchainConfigurableUi.update()
|
this@ZigDebuggerToolchainConfigurableUi.update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -111,7 +112,7 @@ class ZigDebuggerToolchainConfigurableUi : ZigDebuggerUiComponent {
|
||||||
cell(useClion)
|
cell(useClion)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
zigCoroutineScope.launchWithEDT {
|
zigCoroutineScope.launchWithEDT(ModalityState.defaultModalityState()) {
|
||||||
update()
|
update()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -27,10 +27,8 @@ import com.falsepattern.zigbrains.debugger.settings.MSVCDownloadPermission
|
||||||
import com.falsepattern.zigbrains.debugger.settings.ZigDebuggerSettings
|
import com.falsepattern.zigbrains.debugger.settings.ZigDebuggerSettings
|
||||||
import com.falsepattern.zigbrains.debugger.toolchain.ZigDebuggerToolchainService.Companion.downloadPath
|
import com.falsepattern.zigbrains.debugger.toolchain.ZigDebuggerToolchainService.Companion.downloadPath
|
||||||
import com.falsepattern.zigbrains.shared.coroutine.withCurrentEDTModalityContext
|
import com.falsepattern.zigbrains.shared.coroutine.withCurrentEDTModalityContext
|
||||||
import com.falsepattern.zigbrains.shared.coroutine.withEDTContext
|
|
||||||
import com.intellij.notification.Notification
|
import com.intellij.notification.Notification
|
||||||
import com.intellij.notification.NotificationType
|
import com.intellij.notification.NotificationType
|
||||||
import com.intellij.openapi.application.ModalityState
|
|
||||||
import com.intellij.openapi.progress.coroutineToIndicator
|
import com.intellij.openapi.progress.coroutineToIndicator
|
||||||
import com.intellij.openapi.ui.DialogBuilder
|
import com.intellij.openapi.ui.DialogBuilder
|
||||||
import com.intellij.platform.util.progress.withProgressText
|
import com.intellij.platform.util.progress.withProgressText
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -23,6 +23,7 @@
|
||||||
package com.falsepattern.zigbrains.debugger.toolchain
|
package com.falsepattern.zigbrains.debugger.toolchain
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.debugger.ZigDebugBundle
|
import com.falsepattern.zigbrains.debugger.ZigDebugBundle
|
||||||
|
import com.falsepattern.zigbrains.shared.Unarchiver
|
||||||
import com.intellij.notification.Notification
|
import com.intellij.notification.Notification
|
||||||
import com.intellij.notification.NotificationType
|
import com.intellij.notification.NotificationType
|
||||||
import com.intellij.openapi.application.PathManager
|
import com.intellij.openapi.application.PathManager
|
||||||
|
@ -34,28 +35,25 @@ import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.ui.DialogBuilder
|
import com.intellij.openapi.ui.DialogBuilder
|
||||||
import com.intellij.openapi.util.SystemInfo
|
import com.intellij.openapi.util.SystemInfo
|
||||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||||
|
import com.intellij.platform.util.progress.reportSequentialProgress
|
||||||
import com.intellij.ui.BrowserHyperlinkListener
|
import com.intellij.ui.BrowserHyperlinkListener
|
||||||
import com.intellij.ui.HyperlinkLabel
|
import com.intellij.ui.HyperlinkLabel
|
||||||
import com.intellij.ui.components.JBPanel
|
import com.intellij.ui.components.JBPanel
|
||||||
import com.intellij.util.application
|
import com.intellij.util.application
|
||||||
import com.intellij.util.concurrency.annotations.RequiresEdt
|
import com.intellij.util.concurrency.annotations.RequiresEdt
|
||||||
import com.intellij.util.download.DownloadableFileService
|
import com.intellij.util.download.DownloadableFileService
|
||||||
import com.intellij.util.io.Decompressor
|
|
||||||
import com.intellij.util.system.CpuArch
|
import com.intellij.util.system.CpuArch
|
||||||
import com.intellij.util.system.OS
|
import com.intellij.util.system.OS
|
||||||
import com.jetbrains.cidr.execution.debugger.CidrDebuggerPathManager
|
import com.jetbrains.cidr.execution.debugger.CidrDebuggerPathManager
|
||||||
import com.jetbrains.cidr.execution.debugger.backend.bin.UrlProvider
|
import com.jetbrains.cidr.execution.debugger.backend.bin.UrlProvider
|
||||||
import com.jetbrains.cidr.execution.debugger.backend.lldb.LLDBDriverConfiguration
|
import com.jetbrains.cidr.execution.debugger.backend.lldb.LLDBDriverConfiguration
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
import kotlinx.coroutines.runInterruptible
|
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import java.io.File
|
|
||||||
import java.io.IOException
|
import java.io.IOException
|
||||||
import java.net.URL
|
import java.net.URL
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import java.util.*
|
import java.util.*
|
||||||
import kotlin.io.path.name
|
import kotlin.io.path.name
|
||||||
import kotlin.io.path.notExists
|
|
||||||
|
|
||||||
@Service
|
@Service
|
||||||
class ZigDebuggerToolchainService {
|
class ZigDebuggerToolchainService {
|
||||||
|
@ -80,7 +78,7 @@ class ZigDebuggerToolchainService {
|
||||||
val lldbPath = lldbPath()
|
val lldbPath = lldbPath()
|
||||||
val frameworkFile = lldbPath.resolve(frameworkPath)
|
val frameworkFile = lldbPath.resolve(frameworkPath)
|
||||||
val frontendFile = lldbPath.resolve(frontendPath)
|
val frontendFile = lldbPath.resolve(frontendPath)
|
||||||
if (frameworkFile.notExists() || frontendFile.notExists()) return DebuggerAvailability.NeedToDownload
|
if (!frameworkFile.toFile().exists() || !frontendFile.toFile().exists()) return DebuggerAvailability.NeedToDownload
|
||||||
|
|
||||||
val versions = loadDebuggerVersions(DebuggerKind.LLDB)
|
val versions = loadDebuggerVersions(DebuggerKind.LLDB)
|
||||||
val (lldbFrameworkUrl, lldbFrontendUrl) = lldbUrls() ?: return DebuggerAvailability.Unavailable
|
val (lldbFrameworkUrl, lldbFrontendUrl) = lldbUrls() ?: return DebuggerAvailability.Unavailable
|
||||||
|
@ -105,7 +103,7 @@ class ZigDebuggerToolchainService {
|
||||||
}
|
}
|
||||||
|
|
||||||
val gdbFile = gdbPath().resolve(gdbBinaryPath)
|
val gdbFile = gdbPath().resolve(gdbBinaryPath)
|
||||||
if (gdbFile.notExists()) return DebuggerAvailability.NeedToDownload
|
if (!gdbFile.toFile().exists()) return DebuggerAvailability.NeedToDownload
|
||||||
|
|
||||||
val versions = loadDebuggerVersions(DebuggerKind.GDB)
|
val versions = loadDebuggerVersions(DebuggerKind.GDB)
|
||||||
val gdbUrl = gdbUrl() ?: return DebuggerAvailability.Unavailable
|
val gdbUrl = gdbUrl() ?: return DebuggerAvailability.Unavailable
|
||||||
|
@ -123,7 +121,7 @@ class ZigDebuggerToolchainService {
|
||||||
val msvcBinaryPath = "vsdbg.exe"
|
val msvcBinaryPath = "vsdbg.exe"
|
||||||
|
|
||||||
val msvcFile = msvcPath().resolve(msvcBinaryPath)
|
val msvcFile = msvcPath().resolve(msvcBinaryPath)
|
||||||
if (msvcFile.notExists()) return DebuggerAvailability.NeedToDownload
|
if (!msvcFile.toFile().exists()) return DebuggerAvailability.NeedToDownload
|
||||||
|
|
||||||
val msvcUrl = msvcUrl() ?: return DebuggerAvailability.Binaries(MSVCBinaries(msvcFile))
|
val msvcUrl = msvcUrl() ?: return DebuggerAvailability.Binaries(MSVCBinaries(msvcFile))
|
||||||
|
|
||||||
|
@ -170,7 +168,9 @@ class ZigDebuggerToolchainService {
|
||||||
}
|
}
|
||||||
|
|
||||||
try {
|
try {
|
||||||
downloadAndUnArchive(baseDir, downloadableBinaries)
|
withContext(Dispatchers.IO) {
|
||||||
|
downloadAndUnArchive(baseDir, downloadableBinaries)
|
||||||
|
}
|
||||||
return DownloadResult.Ok(baseDir)
|
return DownloadResult.Ok(baseDir)
|
||||||
} catch (e: IOException) {
|
} catch (e: IOException) {
|
||||||
//TODO logging
|
//TODO logging
|
||||||
|
@ -209,34 +209,40 @@ class ZigDebuggerToolchainService {
|
||||||
@Throws(IOException::class)
|
@Throws(IOException::class)
|
||||||
@RequiresEdt
|
@RequiresEdt
|
||||||
private suspend fun downloadAndUnArchive(baseDir: Path, binariesToDownload: List<DownloadableDebuggerBinary>) {
|
private suspend fun downloadAndUnArchive(baseDir: Path, binariesToDownload: List<DownloadableDebuggerBinary>) {
|
||||||
val service = DownloadableFileService.getInstance()
|
reportSequentialProgress { reporter ->
|
||||||
|
val service = DownloadableFileService.getInstance()
|
||||||
|
|
||||||
val downloadDir = baseDir.toFile()
|
val downloadDir = baseDir.toFile()
|
||||||
downloadDir.deleteRecursively()
|
downloadDir.deleteRecursively()
|
||||||
|
|
||||||
val descriptions = binariesToDownload.map {
|
val descriptions = binariesToDownload.map {
|
||||||
service.createFileDescription(it.url, fileName(it.url))
|
service.createFileDescription(it.url, fileName(it.url))
|
||||||
}
|
|
||||||
|
|
||||||
val downloader = service.createDownloader(descriptions, "Debugger downloading")
|
|
||||||
val downloadDirectory = downloadPath().toFile()
|
|
||||||
val downloadResults = withContext(Dispatchers.IO) {
|
|
||||||
coroutineToIndicator {
|
|
||||||
downloader.download(downloadDirectory)
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
val versions = Properties()
|
|
||||||
for (result in downloadResults) {
|
|
||||||
val downloadUrl = result.second.downloadUrl
|
|
||||||
val binaryToDownload = binariesToDownload.first { it.url == downloadUrl }
|
|
||||||
val propertyName = binaryToDownload.propertyName
|
|
||||||
val archiveFile = result.first
|
|
||||||
Unarchiver.unarchive(archiveFile, downloadDir, binaryToDownload.prefix)
|
|
||||||
archiveFile.delete()
|
|
||||||
versions[propertyName] = binaryToDownload.version
|
|
||||||
}
|
|
||||||
|
|
||||||
saveVersionsFile(baseDir, versions)
|
val downloader = service.createDownloader(descriptions, "Debugger downloading")
|
||||||
|
val downloadDirectory = downloadPath().toFile()
|
||||||
|
val downloadResults = reporter.sizedStep(100) {
|
||||||
|
coroutineToIndicator {
|
||||||
|
downloader.download(downloadDirectory)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
val versions = Properties()
|
||||||
|
for (result in downloadResults) {
|
||||||
|
val downloadUrl = result.second.downloadUrl
|
||||||
|
val binaryToDownload = binariesToDownload.first { it.url == downloadUrl }
|
||||||
|
val propertyName = binaryToDownload.propertyName
|
||||||
|
val archiveFile = result.first
|
||||||
|
reporter.indeterminateStep {
|
||||||
|
coroutineToIndicator {
|
||||||
|
Unarchiver.unarchive(archiveFile.toPath(), baseDir, binaryToDownload.prefix)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
archiveFile.delete()
|
||||||
|
versions[propertyName] = binaryToDownload.version
|
||||||
|
}
|
||||||
|
|
||||||
|
saveVersionsFile(baseDir, versions)
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun lldbUrls(): Pair<URL, URL>? {
|
private fun lldbUrls(): Pair<URL, URL>? {
|
||||||
|
@ -331,38 +337,6 @@ class ZigDebuggerToolchainService {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private enum class Unarchiver {
|
|
||||||
ZIP {
|
|
||||||
override val extension = "zip"
|
|
||||||
override fun createDecompressor(file: File) = Decompressor.Zip(file)
|
|
||||||
},
|
|
||||||
TAR {
|
|
||||||
override val extension = "tar.gz"
|
|
||||||
override fun createDecompressor(file: File) = Decompressor.Tar(file)
|
|
||||||
},
|
|
||||||
VSIX {
|
|
||||||
override val extension = "vsix"
|
|
||||||
override fun createDecompressor(file: File) = Decompressor.Zip(file)
|
|
||||||
};
|
|
||||||
|
|
||||||
protected abstract val extension: String
|
|
||||||
protected abstract fun createDecompressor(file: File): Decompressor
|
|
||||||
|
|
||||||
companion object {
|
|
||||||
@Throws(IOException::class)
|
|
||||||
suspend fun unarchive(archivePath: File, dst: File, prefix: String? = null) {
|
|
||||||
runInterruptible {
|
|
||||||
val unarchiver = entries.find { archivePath.name.endsWith(it.extension) } ?: error("Unexpected archive type: $archivePath")
|
|
||||||
val dec = unarchiver.createDecompressor(archivePath)
|
|
||||||
if (prefix != null) {
|
|
||||||
dec.removePrefixPath(prefix)
|
|
||||||
}
|
|
||||||
dec.extract(dst)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
sealed class DownloadResult {
|
sealed class DownloadResult {
|
||||||
class Ok(val baseDir: Path): DownloadResult()
|
class Ok(val baseDir: Path): DownloadResult()
|
||||||
data object NoUrls: DownloadResult()
|
data object NoUrls: DownloadResult()
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -40,7 +40,7 @@ abstract class MSVCDriverConfiguration: DAPDebuggerDriverConfiguration() {
|
||||||
override fun createDriverCommandLine(driver: DebuggerDriver, arch: ArchitectureType): GeneralCommandLine {
|
override fun createDriverCommandLine(driver: DebuggerDriver, arch: ArchitectureType): GeneralCommandLine {
|
||||||
val path = debuggerExecutable
|
val path = debuggerExecutable
|
||||||
val cli = GeneralCommandLine()
|
val cli = GeneralCommandLine()
|
||||||
cli.exePath = path.pathString
|
cli.withExePath(path.pathString)
|
||||||
cli.addParameters("--interpreter=vscode", "--extconfigdir=%USERPROFILE%\\.cppvsdbg\\extensions")
|
cli.addParameters("--interpreter=vscode", "--extconfigdir=%USERPROFILE%\\.cppvsdbg\\extensions")
|
||||||
cli.withWorkingDirectory(path.parent)
|
cli.withWorkingDirectory(path.parent)
|
||||||
return cli
|
return cli
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -38,9 +38,9 @@ import org.eclipse.lsp4j.jsonrpc.MessageConsumer
|
||||||
import org.eclipse.lsp4j.jsonrpc.debug.messages.DebugResponseMessage
|
import org.eclipse.lsp4j.jsonrpc.debug.messages.DebugResponseMessage
|
||||||
import org.eclipse.lsp4j.jsonrpc.messages.Message
|
import org.eclipse.lsp4j.jsonrpc.messages.Message
|
||||||
import org.eclipse.lsp4j.jsonrpc.services.JsonRequest
|
import org.eclipse.lsp4j.jsonrpc.services.JsonRequest
|
||||||
import java.lang.RuntimeException
|
import java.io.InputStream
|
||||||
import java.security.MessageDigest
|
import java.security.MessageDigest
|
||||||
import java.util.Base64
|
import java.util.*
|
||||||
import java.util.concurrent.CompletableFuture
|
import java.util.concurrent.CompletableFuture
|
||||||
import java.util.zip.Inflater
|
import java.util.zip.Inflater
|
||||||
|
|
||||||
|
@ -73,7 +73,7 @@ class WinDAPDriver(handler: Handler) : DAPDriver<IDebugProtocolServer, WinDAPDri
|
||||||
handshakeFinished.acquire()
|
handshakeFinished.acquire()
|
||||||
}
|
}
|
||||||
|
|
||||||
inner class WinDAPDebuggerClient: DAPDriver<IDebugProtocolServer, WinDAPDriver.WinDAPDebuggerClient>.DAPDebuggerClient() {
|
inner class WinDAPDebuggerClient: DAPDriver<IDebugProtocolServer, WinDAPDebuggerClient>.DAPDebuggerClient() {
|
||||||
override fun output(args: OutputEventArguments) {
|
override fun output(args: OutputEventArguments) {
|
||||||
if ("telemetry" == args.category)
|
if ("telemetry" == args.category)
|
||||||
return
|
return
|
||||||
|
@ -92,7 +92,7 @@ class WinDAPDriver(handler: Handler) : DAPDriver<IDebugProtocolServer, WinDAPDri
|
||||||
val hasher = MessageDigest.getInstance("SHA-256")
|
val hasher = MessageDigest.getInstance("SHA-256")
|
||||||
hasher.update(handshake.value.encodeToByteArray())
|
hasher.update(handshake.value.encodeToByteArray())
|
||||||
val inflater = Inflater(true)
|
val inflater = Inflater(true)
|
||||||
val coconut = DAPDebuggerClient::class.java.getResourceAsStream("/coconut.jpg").use { it.readAllBytes() } ?: throw RuntimeException("No coconut")
|
val coconut = DAPDebuggerClient::class.java.getResourceAsStream("/coconut.jpg")?.use(InputStream::readAllBytes) ?: throw RuntimeException("No coconut")
|
||||||
inflater.setInput(coconut, coconut.size - 80, 77)
|
inflater.setInput(coconut, coconut.size - 80, 77)
|
||||||
inflater.finished()
|
inflater.finished()
|
||||||
val b = ByteArray(1)
|
val b = ByteArray(1)
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<idea-plugin package="com.falsepattern.zigbrains.debugger">
|
<idea-plugin package="com.falsepattern.zigbrains.debugger">
|
||||||
<depends>com.intellij.nativeDebug</depends>
|
<depends>com.intellij.modules.cidr.debugger</depends>
|
||||||
|
|
||||||
<extensions defaultExtensionNs="com.intellij">
|
<extensions defaultExtensionNs="com.intellij">
|
||||||
<configurationType
|
<configurationType
|
||||||
|
|
|
@ -1,13 +1,7 @@
|
||||||
dialog.title.download.debugger=Download Debugger
|
|
||||||
notification.nativedebug.title=Zig native debugger
|
|
||||||
notification.nativedebug.text=You need to install the "Native Debugging Support" plugin for Zig debugging in this IDE!
|
|
||||||
notification.nativedebug.market=Install from Marketplace
|
|
||||||
notification.nativedebug.browser=Open in Browser
|
|
||||||
notification.title.debugger=Debugger
|
notification.title.debugger=Debugger
|
||||||
notification.content.debugger.successfully.downloaded=Debugger successfully downloaded
|
notification.content.debugger.successfully.downloaded=Debugger successfully downloaded
|
||||||
notification.content.debugger.downloading.failed=Debugger downloading failed
|
notification.content.debugger.downloading.failed=Debugger downloading failed
|
||||||
notification.content.debugger.metadata.downloading.failed=Debugger metadata downloading failed, switching to fallback
|
notification.content.debugger.metadata.downloading.failed=Debugger metadata downloading failed, switching to fallback
|
||||||
notification.content.debugger.metadata.fallback.fetch.failed=Debugger fallback metadata fetch failed
|
|
||||||
notification.content.debugger.metadata.fallback.parse.failed=Debugger fallback metadata parse failed
|
notification.content.debugger.metadata.fallback.parse.failed=Debugger fallback metadata parse failed
|
||||||
settings.debugger.toolchain.download.debugger.automatically.checkbox=Download and update the debugger automatically
|
settings.debugger.toolchain.download.debugger.automatically.checkbox=Download and update the debugger automatically
|
||||||
settings.debugger.title=Zig
|
settings.debugger.title=Zig
|
||||||
|
@ -15,14 +9,13 @@ settings.debugger.toolchain.debugger.label=Debugger:
|
||||||
settings.debugger.toolchain.download.comment=Need to be <a>downloaded</a>
|
settings.debugger.toolchain.download.comment=Need to be <a>downloaded</a>
|
||||||
settings.debugger.toolchain.update.comment=Need to be <a>updated</a>
|
settings.debugger.toolchain.update.comment=Need to be <a>updated</a>
|
||||||
settings.debugger.toolchain.use.clion.toolchains=Use Clion toolchains instead
|
settings.debugger.toolchain.use.clion.toolchains=Use Clion toolchains instead
|
||||||
notification.content.debugger.need.download=You need to download/update the debugger before you can run debugging! (Settings | Build, Execution, Deployment | Debugging -> Zig)
|
|
||||||
debugger.run.unavailable=Unable to Run Debugger
|
debugger.run.unavailable=Unable to Run Debugger
|
||||||
debugger.run.unavailable.reason.download=Debugger is not downloaded yet
|
debugger.run.unavailable.reason.download=Debugger is not downloaded yet
|
||||||
debugger.run.unavailable.reason.download.button=Download
|
debugger.run.unavailable.reason.download.button=Download
|
||||||
debugger.run.unavailable.reason.update=Debugger is outdated
|
debugger.run.unavailable.reason.update=Debugger is outdated
|
||||||
debugger.run.unavailable.reason.update.button=Update
|
debugger.run.unavailable.reason.update.button=Update
|
||||||
debug.build.compile.failed.boilerplate={0}\nPlease edit this intellij build configuration and specify the path of the executable created by "zig build" directly!
|
debug.build.compile.failed.boilerplate={0}\nPlease edit this intellij build configuration and specify the path of the executable created by "zig build" directly!
|
||||||
debug.base.compile.failed.generic=Failed to compile executable
|
debug.base.compile.failed.generic=Failed to compile executable with command: {0}
|
||||||
debug.base.compile.failed.no-exe=Failed to find compiled binary
|
debug.base.compile.failed.no-exe=Failed to find compiled binary
|
||||||
debug.build.compile.failed.multiple-exe=Multiple compiled binaries found
|
debug.build.compile.failed.multiple-exe=Multiple compiled binaries found
|
||||||
debug.build.compile.failed.no-workdir=Cannot find working directory to run debugged executable
|
debug.build.compile.failed.no-workdir=Cannot find working directory to run debugged executable
|
||||||
|
|
|
@ -7,16 +7,17 @@ plugins {
|
||||||
kotlin("plugin.serialization")
|
kotlin("plugin.serialization")
|
||||||
}
|
}
|
||||||
|
|
||||||
val lsp4ijVersion: String by project
|
val ideaCommunityVersion: String by project
|
||||||
val lsp4jVersion: String by project
|
val useInstaller = property("useInstaller").toString().toBoolean()
|
||||||
|
val serializationVersion: String by project
|
||||||
|
|
||||||
dependencies {
|
dependencies {
|
||||||
intellijPlatform {
|
intellijPlatform {
|
||||||
create(IntelliJPlatformType.IntellijIdeaCommunity, providers.gradleProperty("ideaCommunityVersion"))
|
create(IntelliJPlatformType.IntellijIdeaCommunity, ideaCommunityVersion, useInstaller = useInstaller)
|
||||||
|
}
|
||||||
|
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core-jvm:$serializationVersion") {
|
||||||
|
isTransitive = false
|
||||||
}
|
}
|
||||||
compileOnly("com.redhat.devtools.intellij:lsp4ij:$lsp4ijVersion")
|
|
||||||
compileOnly("org.eclipse.lsp4j:org.eclipse.lsp4j:$lsp4jVersion")
|
|
||||||
compileOnly("org.jetbrains.kotlinx:kotlinx-serialization-core:1.6.3")
|
|
||||||
}
|
}
|
||||||
|
|
||||||
//region grammars
|
//region grammars
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -165,6 +165,8 @@
|
||||||
|
|
||||||
STRING_LITERAL_SINGLE='quoted string literal'
|
STRING_LITERAL_SINGLE='quoted string literal'
|
||||||
STRING_LITERAL_MULTI='multiline string literal'
|
STRING_LITERAL_MULTI='multiline string literal'
|
||||||
|
BAD_SQUOT='unterminated character literal'
|
||||||
|
BAD_DQUOT='unterminated string'
|
||||||
|
|
||||||
IDENTIFIER='identifier'
|
IDENTIFIER='identifier'
|
||||||
BUILTINIDENTIFIER='builtin identifier'
|
BUILTINIDENTIFIER='builtin identifier'
|
||||||
|
@ -178,11 +180,11 @@
|
||||||
Root ::= CONTAINER_DOC_COMMENT? ContainerMembers?
|
Root ::= CONTAINER_DOC_COMMENT? ContainerMembers?
|
||||||
|
|
||||||
// *** Top level ***
|
// *** Top level ***
|
||||||
ContainerMembers ::= ContainerDeclarations? (ContainerField COMMA)* (ContainerField | ContainerDeclarations)?
|
ContainerMembers ::= ContainerDeclaration* (ContainerField COMMA)* (ContainerField | ContainerDeclaration*)
|
||||||
|
|
||||||
ContainerDeclarations ::= (TestDecl | ComptimeDecl | DOC_COMMENT? KEYWORD_PUB? Decl)+
|
ContainerDeclaration ::= TestDecl | ComptimeDecl | DOC_COMMENT? KEYWORD_PUB? Decl
|
||||||
|
|
||||||
TestDecl ::= DOC_COMMENT? KEYWORD_TEST (STRING_LITERAL_SINGLE | IDENTIFIER)? Block {pin=2}
|
TestDecl ::= KEYWORD_TEST (STRING_LITERAL_SINGLE | IDENTIFIER)? Block {pin=1}
|
||||||
|
|
||||||
ComptimeDecl ::= KEYWORD_COMPTIME Block
|
ComptimeDecl ::= KEYWORD_COMPTIME Block
|
||||||
|
|
||||||
|
@ -203,6 +205,7 @@ ContainerField ::= DOC_COMMENT? KEYWORD_COMPTIME? !KEYWORD_FN (IDENTIFIER COLON)
|
||||||
Statement
|
Statement
|
||||||
::= KEYWORD_COMPTIME ComptimeStatement
|
::= KEYWORD_COMPTIME ComptimeStatement
|
||||||
| KEYWORD_NOSUSPEND BlockExprStatement
|
| KEYWORD_NOSUSPEND BlockExprStatement
|
||||||
|
| KEYWORD_SUSPEND BlockExprStatement
|
||||||
| KEYWORD_DEFER BlockExprStatement
|
| KEYWORD_DEFER BlockExprStatement
|
||||||
| KEYWORD_ERRDEFER Payload? BlockExprStatement
|
| KEYWORD_ERRDEFER Payload? BlockExprStatement
|
||||||
| IfStatement
|
| IfStatement
|
||||||
|
@ -413,14 +416,21 @@ WhilePrefix ::= KEYWORD_WHILE ZB_WhilePrefix_Operand PtrPayload? WhileContinueEx
|
||||||
|
|
||||||
private ZB_WhilePrefix_Operand ::= LPAREN Expr RPAREN {pin=1}
|
private ZB_WhilePrefix_Operand ::= LPAREN Expr RPAREN {pin=1}
|
||||||
|
|
||||||
ForRange ::= Expr DOT2 Expr?
|
ForPrefix ::= KEYWORD_FOR LPAREN ZB_ForParams RPAREN ForPayload {pin=1}
|
||||||
ForOperand ::= ForRange | Expr {recoverWhile="ZB_ForOperand_Recover"}
|
|
||||||
|
|
||||||
private ZB_ForOperand_Recover ::= !(COMMA | RPAREN)
|
private ZB_ForParams ::= ForInput (COMMA ForInput)* COMMA? {recoverWhile="ZB_ForParams_Recover"}
|
||||||
|
|
||||||
ForPrefix ::= KEYWORD_FOR ZB_ForPrefix_Operands PtrIndexPayload {pin=1}
|
private ZB_ForParams_Recover ::= !(RPAREN)
|
||||||
|
|
||||||
private ZB_ForPrefix_Operands ::= LPAREN (ForOperand COMMA)* ForOperand RPAREN {pin=1}
|
ForInput ::= Expr (DOT2 Expr?)? {recoverWhile="ZB_ForInput_Recover"}
|
||||||
|
|
||||||
|
private ZB_ForInput_Recover ::= !(COMMA | RPAREN)
|
||||||
|
|
||||||
|
ForPayload ::= PIPE ZB_ForPayload_Item (COMMA ZB_ForPayload_Item)* PIPE {pin=1}
|
||||||
|
|
||||||
|
private ZB_ForPayload_Item ::= ASTERISK? IDENTIFIER {recoverWhile="ZB_ForPayload_Recover"}
|
||||||
|
|
||||||
|
private ZB_ForPayload_Recover ::= !(COMMA | PIPE)
|
||||||
|
|
||||||
// Payloads
|
// Payloads
|
||||||
Payload ::= PIPE IDENTIFIER PIPE
|
Payload ::= PIPE IDENTIFIER PIPE
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -34,9 +34,12 @@ import static com.falsepattern.zigbrains.zig.psi.ZigTypes.*;
|
||||||
%implements FlexLexer
|
%implements FlexLexer
|
||||||
%function advance
|
%function advance
|
||||||
%type IElementType
|
%type IElementType
|
||||||
|
%unicode
|
||||||
|
|
||||||
CRLF=\R
|
WHITE_SPACE=\s+
|
||||||
WHITE_SPACE=[\s]+
|
|
||||||
|
// visual studio parity
|
||||||
|
LF=\r\n?|[\n\u0085\u2028\u2029]
|
||||||
|
|
||||||
bin=[01]
|
bin=[01]
|
||||||
bin_="_"? {bin}
|
bin_="_"? {bin}
|
||||||
|
@ -52,55 +55,14 @@ oct_int={oct} {oct_}*
|
||||||
dec_int={dec} {dec_}*
|
dec_int={dec} {dec_}*
|
||||||
hex_int={hex} {hex_}*
|
hex_int={hex} {hex_}*
|
||||||
|
|
||||||
ox80_oxBF=[\200-\277]
|
char_char= \\ .
|
||||||
oxF4=\364
|
| [^\'\r\n\u0085\u2028\u2029]
|
||||||
ox80_ox8F=[\200-\217]
|
|
||||||
oxF1_oxF3=[\361-\363]
|
|
||||||
oxF0=\360
|
|
||||||
ox90_0xBF=[\220-\277]
|
|
||||||
oxEE_oxEF=[\356-\357]
|
|
||||||
oxED=\355
|
|
||||||
ox80_ox9F=[\200-\237]
|
|
||||||
oxE1_oxEC=[\341-\354]
|
|
||||||
oxE0=\340
|
|
||||||
oxA0_oxBF=[\240-\277]
|
|
||||||
oxC2_oxDF=[\302-\337]
|
|
||||||
|
|
||||||
// From https://lemire.me/blog/2018/05/09/how-quickly-can-you-check-that-a-string-is-valid-unicode-utf-8/
|
|
||||||
// First Byte Second Byte Third Byte Fourth Byte
|
|
||||||
// [0x00,0x7F]
|
|
||||||
// [0xC2,0xDF] [0x80,0xBF]
|
|
||||||
// 0xE0 [0xA0,0xBF] [0x80,0xBF]
|
|
||||||
// [0xE1,0xEC] [0x80,0xBF] [0x80,0xBF]
|
|
||||||
// 0xED [0x80,0x9F] [0x80,0xBF]
|
|
||||||
// [0xEE,0xEF] [0x80,0xBF] [0x80,0xBF]
|
|
||||||
// 0xF0 [0x90,0xBF] [0x80,0xBF] [0x80,0xBF]
|
|
||||||
// [0xF1,0xF3] [0x80,0xBF] [0x80,0xBF] [0x80,0xBF]
|
|
||||||
// 0xF4 [0x80,0x8F] [0x80,0xBF] [0x80,0xBF]
|
|
||||||
|
|
||||||
mb_utf8_literal= {oxF4} {ox80_ox8F} {ox80_oxBF} {ox80_oxBF}
|
|
||||||
| {oxF1_oxF3} {ox80_oxBF} {ox80_oxBF} {ox80_oxBF}
|
|
||||||
| {oxF0} {ox90_0xBF} {ox80_oxBF} {ox80_oxBF}
|
|
||||||
| {oxEE_oxEF} {ox80_oxBF} {ox80_oxBF}
|
|
||||||
| {oxED} {ox80_ox9F} {ox80_oxBF}
|
|
||||||
| {oxE1_oxEC} {ox80_oxBF} {ox80_oxBF}
|
|
||||||
| {oxE0} {oxA0_oxBF} {ox80_oxBF}
|
|
||||||
| {oxC2_oxDF} {ox80_oxBF}
|
|
||||||
|
|
||||||
ascii_char_not_nl_slash_squote=[\000-\011\013-\046\050-\133\135-\177]
|
|
||||||
|
|
||||||
char_escape= "\\x" {hex} {hex}
|
|
||||||
| "\\u{" {hex}+ "}"
|
|
||||||
| "\\" [nr\\t'\"]
|
|
||||||
char_char= {mb_utf8_literal}
|
|
||||||
| {char_escape}
|
|
||||||
| {ascii_char_not_nl_slash_squote}
|
|
||||||
|
|
||||||
string_char= \\ .
|
string_char= \\ .
|
||||||
| [^\"\n]
|
| [^\"\r\n\u0085\u2028\u2029]
|
||||||
|
|
||||||
all_nl_wrap=[^\n]* [ \n]*
|
nl_wrap={LF} (\s|{LF})*
|
||||||
all_nl_nowrap=[^\n]* \n
|
all_no_nl=[^\r\n\u0085\u2028\u2029]+
|
||||||
|
|
||||||
|
|
||||||
FLOAT= "0x" {hex_int} "." {hex_int} ([pP] [-+]? {dec_int})?
|
FLOAT= "0x" {hex_int} "." {hex_int} ([pP] [-+]? {dec_int})?
|
||||||
|
@ -121,26 +83,38 @@ BUILTINIDENTIFIER="@"[A-Za-z_][A-Za-z0-9_]*
|
||||||
%state CHAR_LIT
|
%state CHAR_LIT
|
||||||
|
|
||||||
%state ID_QUOT
|
%state ID_QUOT
|
||||||
%state UNT_QUOT
|
%state UNT_SQUOT
|
||||||
|
%state UNT_DQUOT
|
||||||
|
|
||||||
%state CDOC_CMT
|
%state CMT_LINE
|
||||||
%state DOC_CMT
|
%state CMT_DOC
|
||||||
%state LINE_CMT
|
%state CMT_CDOC
|
||||||
%%
|
%%
|
||||||
|
|
||||||
//Comments
|
//Comments
|
||||||
|
|
||||||
<YYINITIAL> "//!" { yybegin(CDOC_CMT); }
|
<YYINITIAL> "//!" { yybegin(CMT_CDOC); }
|
||||||
<CDOC_CMT> {all_nl_wrap} "//!" { }
|
<YYINITIAL> "////" { yybegin(CMT_LINE); }
|
||||||
<CDOC_CMT> {all_nl_nowrap} { yybegin(YYINITIAL); return CONTAINER_DOC_COMMENT; }
|
<YYINITIAL> "///" { yybegin(CMT_DOC); }
|
||||||
|
<YYINITIAL> "//" { yybegin(CMT_LINE); }
|
||||||
|
|
||||||
<YYINITIAL> "///" { yybegin(DOC_CMT); }
|
<CMT_LINE> {all_no_nl} { }
|
||||||
<DOC_CMT> {all_nl_wrap} "///" { }
|
<CMT_LINE> {nl_wrap} "////" { }
|
||||||
<DOC_CMT> {all_nl_nowrap} { yybegin(YYINITIAL); return DOC_COMMENT; }
|
<CMT_LINE> {nl_wrap} "///" { yypushback(yylength()); yybegin(YYINITIAL); return LINE_COMMENT; }
|
||||||
|
<CMT_LINE> {nl_wrap} "//" { }
|
||||||
|
<CMT_LINE> {LF} { yybegin(YYINITIAL); return LINE_COMMENT; }
|
||||||
|
<CMT_LINE> <<EOF>> { yybegin(YYINITIAL); return LINE_COMMENT; }
|
||||||
|
|
||||||
<YYINITIAL> "//" { yybegin(LINE_CMT); }
|
<CMT_DOC> {all_no_nl} { }
|
||||||
<LINE_CMT> {all_nl_wrap} "//" { }
|
<CMT_DOC> {nl_wrap} "////" { yypushback(yylength()); yybegin(YYINITIAL); return DOC_COMMENT; }
|
||||||
<LINE_CMT> {all_nl_nowrap} { yybegin(YYINITIAL); return LINE_COMMENT; }
|
<CMT_DOC> {nl_wrap} "///" { }
|
||||||
|
<CMT_DOC> {LF} { yybegin(YYINITIAL); return DOC_COMMENT; }
|
||||||
|
<CMT_DOC> <<EOF>> { yybegin(YYINITIAL); return DOC_COMMENT; }
|
||||||
|
|
||||||
|
<CMT_CDOC> {all_no_nl} { }
|
||||||
|
<CMT_CDOC> {nl_wrap} "//!" { }
|
||||||
|
<CMT_CDOC> {LF} { yybegin(YYINITIAL); return CONTAINER_DOC_COMMENT; }
|
||||||
|
<CMT_CDOC> <<EOF>> { yybegin(YYINITIAL); return CONTAINER_DOC_COMMENT; }
|
||||||
|
|
||||||
//Symbols
|
//Symbols
|
||||||
<YYINITIAL> "&" { return AMPERSAND; }
|
<YYINITIAL> "&" { return AMPERSAND; }
|
||||||
|
@ -260,28 +234,49 @@ BUILTINIDENTIFIER="@"[A-Za-z_][A-Za-z0-9_]*
|
||||||
<YYINITIAL> "volatile" { return KEYWORD_VOLATILE; }
|
<YYINITIAL> "volatile" { return KEYWORD_VOLATILE; }
|
||||||
<YYINITIAL> "while" { return KEYWORD_WHILE; }
|
<YYINITIAL> "while" { return KEYWORD_WHILE; }
|
||||||
|
|
||||||
|
//Strings
|
||||||
|
|
||||||
<YYINITIAL> "'" { yybegin(CHAR_LIT); }
|
<YYINITIAL> "'" { yybegin(CHAR_LIT); }
|
||||||
<CHAR_LIT> {char_char}"'" { yybegin(YYINITIAL); return CHAR_LITERAL; }
|
<CHAR_LIT> {char_char}*"'" { yybegin(YYINITIAL); return CHAR_LITERAL; }
|
||||||
<CHAR_LIT> [^] { yypushback(1); yybegin(UNT_QUOT); }
|
<CHAR_LIT> <<EOF>> { yybegin(YYINITIAL); return BAD_SQUOT; }
|
||||||
|
<CHAR_LIT> [^] { yypushback(1); yybegin(UNT_SQUOT); }
|
||||||
|
|
||||||
|
<YYINITIAL> "\"" { yybegin(STR_LIT); }
|
||||||
|
<STR_LIT> {string_char}*"\"" { yybegin(YYINITIAL); return STRING_LITERAL_SINGLE; }
|
||||||
|
<STR_LIT> <<EOF>> { yybegin(YYINITIAL); return BAD_DQUOT; }
|
||||||
|
<STR_LIT> [^] { yypushback(1); yybegin(UNT_DQUOT); }
|
||||||
|
|
||||||
|
<YYINITIAL> "\\\\" { yybegin(STR_MULT_LINE); }
|
||||||
|
<STR_MULT_LINE> {all_no_nl} { }
|
||||||
|
<STR_MULT_LINE> {nl_wrap} "\\\\" { }
|
||||||
|
<STR_MULT_LINE> {LF} { yybegin(YYINITIAL); return STRING_LITERAL_MULTI; }
|
||||||
|
<STR_MULT_LINE> <<EOF>> { yybegin(YYINITIAL); return STRING_LITERAL_MULTI; }
|
||||||
|
|
||||||
|
//Numbers
|
||||||
|
|
||||||
<YYINITIAL> {FLOAT} { return FLOAT; }
|
<YYINITIAL> {FLOAT} { return FLOAT; }
|
||||||
<YYINITIAL> {INTEGER} { return INTEGER; }
|
<YYINITIAL> {INTEGER} { return INTEGER; }
|
||||||
|
|
||||||
<YYINITIAL> "\"" { yybegin(STR_LIT); }
|
//Identifiers
|
||||||
<STR_LIT> {string_char}*"\"" { yybegin(YYINITIAL); return STRING_LITERAL_SINGLE; }
|
|
||||||
<STR_LIT> [^] { yypushback(1); yybegin(UNT_QUOT); }
|
|
||||||
<YYINITIAL> "\\\\" { yybegin(STR_MULT_LINE); }
|
|
||||||
<STR_MULT_LINE> {all_nl_wrap} "\\\\" { }
|
|
||||||
<STR_MULT_LINE> {all_nl_nowrap} { yybegin(YYINITIAL); return STRING_LITERAL_MULTI; }
|
|
||||||
|
|
||||||
<YYINITIAL> {IDENTIFIER_PLAIN} { return IDENTIFIER; }
|
<YYINITIAL> {IDENTIFIER_PLAIN} { return IDENTIFIER; }
|
||||||
<YYINITIAL> "@\"" { yybegin(ID_QUOT); }
|
<YYINITIAL> "@\"" { yybegin(ID_QUOT); }
|
||||||
<ID_QUOT> {string_char}*"\"" { yybegin(YYINITIAL); return IDENTIFIER; }
|
<ID_QUOT> {string_char}*"\"" { yybegin(YYINITIAL); return IDENTIFIER; }
|
||||||
<ID_QUOT> [^] { yypushback(1); yybegin(UNT_QUOT); }
|
<ID_QUOT> <<EOF>> { yybegin(YYINITIAL); return BAD_DQUOT; }
|
||||||
|
<ID_QUOT> [^] { yypushback(1); yybegin(UNT_DQUOT); }
|
||||||
|
|
||||||
<YYINITIAL> {BUILTINIDENTIFIER} { return BUILTINIDENTIFIER; }
|
<YYINITIAL> {BUILTINIDENTIFIER} { return BUILTINIDENTIFIER; }
|
||||||
|
|
||||||
<UNT_QUOT> [^\n]*{CRLF} { yybegin(YYINITIAL); return BAD_CHARACTER; }
|
//Error handling
|
||||||
|
|
||||||
|
<UNT_SQUOT> <<EOF>> { yybegin(YYINITIAL); return BAD_SQUOT; }
|
||||||
|
<UNT_SQUOT> {LF} { yybegin(YYINITIAL); return BAD_SQUOT; }
|
||||||
|
<UNT_SQUOT> {all_no_nl} { }
|
||||||
|
<UNT_DQUOT> <<EOF>> { yybegin(YYINITIAL); return BAD_DQUOT; }
|
||||||
|
<UNT_DQUOT> {LF} { yybegin(YYINITIAL); return BAD_DQUOT; }
|
||||||
|
<UNT_DQUOT> {all_no_nl} { }
|
||||||
|
|
||||||
|
//Misc
|
||||||
|
|
||||||
<YYINITIAL> {WHITE_SPACE} { return WHITE_SPACE; }
|
<YYINITIAL> {WHITE_SPACE} { return WHITE_SPACE; }
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -40,17 +40,21 @@ import static com.intellij.psi.StringEscapesTokenTypes.*;
|
||||||
hex=[0-9a-fA-F]
|
hex=[0-9a-fA-F]
|
||||||
|
|
||||||
char_escape_unicode= "\\x" {hex} {hex} | "\\u{" {hex}+ "}"
|
char_escape_unicode= "\\x" {hex} {hex} | "\\u{" {hex}+ "}"
|
||||||
char_escape_unicode_invalid= "\\x" | "\\u"
|
char_escape_unicode_invalid= "\\x" .? .? | "\\u" ("{" [^}]* "}"?)?
|
||||||
|
|
||||||
char_escape_single_valid= "\\" [nr\\t'\"]
|
char_escape_single_valid= "\\" [nr\\t'\"]
|
||||||
char_escape_single_invalid= "\\" [^nr\\t'\"]
|
char_escape_single_invalid= "\\" [^nr\\t'\"]
|
||||||
|
|
||||||
%state STR
|
%state STR
|
||||||
|
%state CHAR
|
||||||
|
%state CHAR_END
|
||||||
|
%state CHAR_FINISH
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
|
||||||
<YYINITIAL> {
|
<YYINITIAL> {
|
||||||
"\"" { yybegin(STR); return STRING_LITERAL_SINGLE; }
|
"\"" { yybegin(STR); return STRING_LITERAL_SINGLE; }
|
||||||
|
"'" { yybegin(CHAR); return CHAR_LITERAL; }
|
||||||
[^] { return STRING_LITERAL_SINGLE; }
|
[^] { return STRING_LITERAL_SINGLE; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -61,3 +65,20 @@ char_escape_single_invalid= "\\" [^nr\\t'\"]
|
||||||
{char_escape_single_invalid} { return INVALID_CHARACTER_ESCAPE_TOKEN; }
|
{char_escape_single_invalid} { return INVALID_CHARACTER_ESCAPE_TOKEN; }
|
||||||
[^] { return STRING_LITERAL_SINGLE; }
|
[^] { return STRING_LITERAL_SINGLE; }
|
||||||
}
|
}
|
||||||
|
|
||||||
|
<CHAR> {
|
||||||
|
{char_escape_unicode} { yybegin(CHAR_END); return VALID_STRING_ESCAPE_TOKEN; }
|
||||||
|
{char_escape_unicode_invalid} { yybegin(CHAR_END); return INVALID_UNICODE_ESCAPE_TOKEN; }
|
||||||
|
{char_escape_single_valid} { yybegin(CHAR_END); return VALID_STRING_ESCAPE_TOKEN; }
|
||||||
|
{char_escape_single_invalid} { yybegin(CHAR_END); return INVALID_CHARACTER_ESCAPE_TOKEN; }
|
||||||
|
[^] { yybegin(CHAR_END); return CHAR_LITERAL; }
|
||||||
|
}
|
||||||
|
|
||||||
|
<CHAR_END> {
|
||||||
|
"'" { yybegin(CHAR_FINISH); return CHAR_LITERAL; }
|
||||||
|
[^] { return BAD_CHARACTER; }
|
||||||
|
}
|
||||||
|
|
||||||
|
<CHAR_FINISH> {
|
||||||
|
[^] { return BAD_CHARACTER; }
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -34,46 +34,57 @@
|
||||||
elementTypeClass="com.falsepattern.zigbrains.zon.parser.ZonElementType"
|
elementTypeClass="com.falsepattern.zigbrains.zon.parser.ZonElementType"
|
||||||
tokenTypeClass="com.falsepattern.zigbrains.zon.parser.ZonTokenType"
|
tokenTypeClass="com.falsepattern.zigbrains.zon.parser.ZonTokenType"
|
||||||
tokens=[
|
tokens=[
|
||||||
|
LINE_COMMENT='comment'
|
||||||
DOT='.'
|
DOT='.'
|
||||||
|
EQUAL='='
|
||||||
LBRACE='{'
|
LBRACE='{'
|
||||||
RBRACE='}'
|
RBRACE='}'
|
||||||
EQ='='
|
|
||||||
COMMA=','
|
COMMA=','
|
||||||
COMMENT='comment'
|
KEYWORD_FALSE='false'
|
||||||
ID='identifier'
|
KEYWORD_TRUE='true'
|
||||||
STRING_LITERAL_SINGLE='string'
|
KEYWORD_NULL='null'
|
||||||
LINE_STRING='multiline string'
|
NUM_NAN='nan'
|
||||||
BAD_STRING='unterminated string'
|
NUM_INF='inf'
|
||||||
BOOL_TRUE='true'
|
CHAR_LITERAL='char literal'
|
||||||
BOOL_FALSE='false'
|
STRING_LITERAL_SINGLE='string literal'
|
||||||
|
STRING_LITERAL_MULTI='multiline string literal'
|
||||||
|
FLOAT='float'
|
||||||
|
INTEGER='integer'
|
||||||
|
IDENTIFIER='identifier'
|
||||||
|
BAD_SQUOT='unterminated quote'
|
||||||
|
BAD_DQUOT='unterminated double quote'
|
||||||
]
|
]
|
||||||
|
|
||||||
//Mixins
|
|
||||||
mixin("entry")="com.falsepattern.zigbrains.zon.psi.impl.mixins.ZonEntryMixinImpl"
|
|
||||||
implements("entry")="com.falsepattern.zigbrains.zon.psi.mixins.ZonEntryMixin"
|
|
||||||
|
|
||||||
mixin("identifier")="com.falsepattern.zigbrains.zon.psi.impl.mixins.ZonIdentifierMixinImpl"
|
|
||||||
implements("identifier")="com.falsepattern.zigbrains.zon.psi.mixins.ZonIdentifierMixin"
|
|
||||||
}
|
}
|
||||||
|
|
||||||
zonFile ::= entry
|
Root ::= Expr
|
||||||
|
|
||||||
entry ::= DOT LBRACE (list | struct | ()) RBRACE
|
Expr
|
||||||
|
::= CHAR_LITERAL
|
||||||
|
| StringLiteral
|
||||||
|
| DOT IDENTIFIER
|
||||||
|
| DOT InitList
|
||||||
|
| Bool
|
||||||
|
| Number
|
||||||
|
| KEYWORD_NULL
|
||||||
|
|
||||||
struct ::= (property | property_placeholder) (COMMA (property_placeholder? property property_placeholder? | property_placeholder))* COMMA?
|
|
||||||
|
|
||||||
list ::= value (COMMA value)* COMMA?
|
InitList
|
||||||
|
::= LBRACE ZB_InitList_Body RBRACE {pin=1}
|
||||||
|
|
||||||
property ::= DOT identifier EQ value
|
private ZB_InitList_Body
|
||||||
|
::= FieldInit (COMMA ZB_InitList_FieldInit)* COMMA?
|
||||||
|
| Expr (COMMA ZB_InitList_Expr)* COMMA?
|
||||||
|
| ()
|
||||||
|
|
||||||
identifier ::= ID
|
private ZB_InitList_FieldInit ::= FieldInit {recoverWhile="ZB_InitList_Recover"}
|
||||||
|
private ZB_InitList_Expr ::= Expr {recoverWhile="ZB_InitList_Recover"}
|
||||||
|
|
||||||
property_placeholder ::= DOT? INTELLIJ_COMPLETION_DUMMY
|
private ZB_InitList_Recover ::= !(COMMA | RBRACE)
|
||||||
|
|
||||||
private value ::= entry | boolean | STRING_LITERAL | value_placeholder
|
FieldInit ::= DOT IDENTIFIER EQUAL Expr
|
||||||
|
|
||||||
value_placeholder ::= INTELLIJ_COMPLETION_DUMMY
|
Bool ::= KEYWORD_TRUE | KEYWORD_FALSE
|
||||||
|
|
||||||
boolean ::= BOOL_TRUE | BOOL_FALSE
|
Number ::= FLOAT | INTEGER | NUM_NAN | NUM_INF
|
||||||
|
|
||||||
STRING_LITERAL ::= STRING_LITERAL_SINGLE | LINE_STRING+
|
StringLiteral ::= STRING_LITERAL_SINGLE | STRING_LITERAL_MULTI
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -36,54 +36,124 @@ import static com.falsepattern.zigbrains.zon.psi.ZonTypes.*;
|
||||||
%type IElementType
|
%type IElementType
|
||||||
%unicode
|
%unicode
|
||||||
|
|
||||||
CRLF=\R
|
WHITE_SPACE=\s+
|
||||||
WHITE_SPACE=[\s]+
|
|
||||||
LINE_COMMENT="//" [^\n]* | "////" [^\n]*
|
|
||||||
COMMENT="///".*
|
|
||||||
|
|
||||||
ID=[A-Za-z_][A-Za-z0-9_]*
|
// visual studio parity
|
||||||
|
LF=\r\n?|[\n\u0085\u2028\u2029]
|
||||||
|
|
||||||
|
bin=[01]
|
||||||
|
bin_="_"? {bin}
|
||||||
|
oct=[0-7]
|
||||||
|
oct_="_"? {oct}
|
||||||
hex=[0-9a-fA-F]
|
hex=[0-9a-fA-F]
|
||||||
char_escape
|
hex_="_"? {hex}
|
||||||
= "\\x" {hex} {hex}
|
dec=[0-9]
|
||||||
| "\\u{" {hex}+ "}"
|
dec_="_"? {dec}
|
||||||
| "\\" [nr\\t'\"]
|
|
||||||
|
|
||||||
string_char
|
bin_int={bin} {bin_}*
|
||||||
= {char_escape}
|
oct_int={oct} {oct_}*
|
||||||
| [^\\\"\n]
|
dec_int={dec} {dec_}*
|
||||||
|
hex_int={hex} {hex_}*
|
||||||
|
|
||||||
LINE_STRING=("\\\\" [^\n]* [ \n]*)+
|
char_char= \\ .
|
||||||
|
| [^\'\r\n\u0085\u2028\u2029]
|
||||||
|
|
||||||
%state STRING_LITERAL
|
string_char= \\ .
|
||||||
%state ID_STRING
|
| [^\"\r\n\u0085\u2028\u2029]
|
||||||
%state UNCLOSED_STRING
|
|
||||||
|
nl_wrap={LF} (\s|{LF})*
|
||||||
|
all_no_nl=[^\r\n\u0085\u2028\u2029]+
|
||||||
|
|
||||||
|
|
||||||
|
FLOAT= "0x" {hex_int} "." {hex_int} ([pP] [-+]? {dec_int})?
|
||||||
|
| {dec_int} "." {dec_int} ([eE] [-+]? {dec_int})?
|
||||||
|
| "0x" {hex_int} [pP] [-+]? {dec_int}
|
||||||
|
| {dec_int} [eE] [-+]? {dec_int}
|
||||||
|
|
||||||
|
INTEGER= "0b" {bin_int}
|
||||||
|
| "0o" {oct_int}
|
||||||
|
| "0x" {hex_int}
|
||||||
|
| {dec_int}
|
||||||
|
|
||||||
|
IDENTIFIER_PLAIN=[A-Za-z_][A-Za-z0-9_]*
|
||||||
|
|
||||||
|
%state STR_LIT
|
||||||
|
%state STR_MULT_LINE
|
||||||
|
%state CHAR_LIT
|
||||||
|
|
||||||
|
%state ID_QUOT
|
||||||
|
%state UNT_SQUOT
|
||||||
|
%state UNT_DQUOT
|
||||||
|
|
||||||
|
%state CMT_LINE
|
||||||
%%
|
%%
|
||||||
|
|
||||||
|
//Comments
|
||||||
|
|
||||||
|
<YYINITIAL> "//" { yybegin(CMT_LINE); }
|
||||||
|
<CMT_LINE> {all_no_nl} { }
|
||||||
|
<CMT_LINE> {nl_wrap} "//" { }
|
||||||
|
<CMT_LINE> \R { yybegin(YYINITIAL); return LINE_COMMENT; }
|
||||||
|
<CMT_LINE> <<EOF>> { yybegin(YYINITIAL); return LINE_COMMENT; }
|
||||||
|
|
||||||
|
//Symbols
|
||||||
|
|
||||||
<YYINITIAL> {WHITE_SPACE} { return WHITE_SPACE; }
|
|
||||||
<YYINITIAL> "." { return DOT; }
|
<YYINITIAL> "." { return DOT; }
|
||||||
<YYINITIAL> "IntellijIdeaRulezzz" { return INTELLIJ_COMPLETION_DUMMY; }
|
<YYINITIAL> "=" { return EQUAL; }
|
||||||
<YYINITIAL> "{" { return LBRACE; }
|
<YYINITIAL> "{" { return LBRACE; }
|
||||||
<YYINITIAL> "}" { return RBRACE; }
|
<YYINITIAL> "}" { return RBRACE; }
|
||||||
<YYINITIAL> "=" { return EQ; }
|
|
||||||
<YYINITIAL> "," { return COMMA; }
|
<YYINITIAL> "," { return COMMA; }
|
||||||
<YYINITIAL> "true" { return BOOL_TRUE; }
|
|
||||||
<YYINITIAL> "false" { return BOOL_FALSE; }
|
|
||||||
<YYINITIAL> {COMMENT} { return COMMENT; }
|
|
||||||
<YYINITIAL> {LINE_COMMENT} { return COMMENT; }
|
|
||||||
|
|
||||||
<YYINITIAL> {ID} { return ID; }
|
//Keywords
|
||||||
<YYINITIAL> "@\"" { yybegin(ID_STRING); }
|
|
||||||
<ID_STRING> {string_char}*"\"" { yybegin(YYINITIAL); return ID; }
|
|
||||||
<ID_STRING> [^] { yypushback(1); yybegin(UNCLOSED_STRING); }
|
|
||||||
|
|
||||||
<YYINITIAL> "\"" { yybegin(STRING_LITERAL); }
|
<YYINITIAL> "false" { return KEYWORD_FALSE; }
|
||||||
<STRING_LITERAL> {string_char}*"\"" { yybegin(YYINITIAL); return STRING_LITERAL_SINGLE; }
|
<YYINITIAL> "true" { return KEYWORD_TRUE; }
|
||||||
<STRING_LITERAL> [^] { yypushback(1); yybegin(UNCLOSED_STRING); }
|
<YYINITIAL> "null" { return KEYWORD_NULL; }
|
||||||
|
<YYINITIAL> "nan" { return NUM_NAN; }
|
||||||
|
<YYINITIAL> "inf" { return NUM_INF; }
|
||||||
|
|
||||||
<UNCLOSED_STRING>[^\n]*{CRLF} { yybegin(YYINITIAL); return BAD_STRING; }
|
//Strings
|
||||||
|
|
||||||
<YYINITIAL> {LINE_STRING} { return LINE_STRING; }
|
<YYINITIAL> "'" { yybegin(CHAR_LIT); }
|
||||||
|
<CHAR_LIT> {char_char}*"'" { yybegin(YYINITIAL); return CHAR_LITERAL; }
|
||||||
|
<CHAR_LIT> <<EOF>> { yybegin(YYINITIAL); return BAD_SQUOT; }
|
||||||
|
<CHAR_LIT> [^] { yypushback(1); yybegin(UNT_SQUOT); }
|
||||||
|
|
||||||
|
<YYINITIAL> "\"" { yybegin(STR_LIT); }
|
||||||
|
<STR_LIT> {string_char}*"\"" { yybegin(YYINITIAL); return STRING_LITERAL_SINGLE; }
|
||||||
|
<STR_LIT> <<EOF>> { yybegin(YYINITIAL); return BAD_DQUOT; }
|
||||||
|
<STR_LIT> [^] { yypushback(1); yybegin(UNT_DQUOT); }
|
||||||
|
|
||||||
|
<YYINITIAL> "\\\\" { yybegin(STR_MULT_LINE); }
|
||||||
|
<STR_MULT_LINE> {all_no_nl} { }
|
||||||
|
<STR_MULT_LINE> {nl_wrap} "\\\\" { }
|
||||||
|
<STR_MULT_LINE> {LF} { yybegin(YYINITIAL); return STRING_LITERAL_MULTI; }
|
||||||
|
<STR_MULT_LINE> <<EOF>> { yybegin(YYINITIAL); return STRING_LITERAL_MULTI; }
|
||||||
|
|
||||||
|
//Numbers
|
||||||
|
|
||||||
|
<YYINITIAL> {FLOAT} { return FLOAT; }
|
||||||
|
<YYINITIAL> {INTEGER} { return INTEGER; }
|
||||||
|
|
||||||
|
//Identifiers
|
||||||
|
|
||||||
|
<YYINITIAL> {IDENTIFIER_PLAIN} { return IDENTIFIER; }
|
||||||
|
<YYINITIAL> "@\"" { yybegin(ID_QUOT); }
|
||||||
|
<ID_QUOT> {string_char}*"\"" { yybegin(YYINITIAL); return IDENTIFIER; }
|
||||||
|
<ID_QUOT> <<EOF>> { yybegin(YYINITIAL); return BAD_DQUOT; }
|
||||||
|
<ID_QUOT> [^] { yypushback(1); yybegin(UNT_DQUOT); }
|
||||||
|
|
||||||
|
//Error handling
|
||||||
|
|
||||||
|
<UNT_SQUOT> <<EOF>> { yybegin(YYINITIAL); return BAD_SQUOT; }
|
||||||
|
<UNT_SQUOT> {LF} { yybegin(YYINITIAL); return BAD_SQUOT; }
|
||||||
|
<UNT_SQUOT> {all_no_nl} { }
|
||||||
|
<UNT_DQUOT> <<EOF>> { yybegin(YYINITIAL); return BAD_DQUOT; }
|
||||||
|
<UNT_DQUOT> {LF} { yybegin(YYINITIAL); return BAD_DQUOT; }
|
||||||
|
<UNT_DQUOT> {all_no_nl} { }
|
||||||
|
|
||||||
|
//Misc
|
||||||
|
|
||||||
|
<YYINITIAL> {WHITE_SPACE} { return WHITE_SPACE; }
|
||||||
|
|
||||||
[^] { return BAD_CHARACTER; }
|
[^] { return BAD_CHARACTER; }
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -27,6 +27,8 @@ import org.jetbrains.annotations.NonNls
|
||||||
|
|
||||||
@NonNls
|
@NonNls
|
||||||
object Icons {
|
object Icons {
|
||||||
val ZIG = IconLoader.getIcon("/icons/zig.svg", Icons::class.java)
|
@JvmField
|
||||||
val ZON = IconLoader.getIcon("/icons/zon.svg", Icons::class.java)
|
val Zig = IconLoader.getIcon("/icons/zig.svg", Icons::class.java)
|
||||||
|
@JvmField
|
||||||
|
val Zon = IconLoader.getIcon("/icons/zon.svg", Icons::class.java)
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -25,26 +25,57 @@ package com.falsepattern.zigbrains.direnv
|
||||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||||
import com.intellij.execution.configurations.GeneralCommandLine
|
import com.intellij.execution.configurations.GeneralCommandLine
|
||||||
import com.intellij.execution.configurations.PathEnvironmentVariableUtil
|
import com.intellij.execution.configurations.PathEnvironmentVariableUtil
|
||||||
|
import com.intellij.ide.impl.isTrusted
|
||||||
import com.intellij.notification.Notification
|
import com.intellij.notification.Notification
|
||||||
import com.intellij.notification.NotificationType
|
import com.intellij.notification.NotificationType
|
||||||
import com.intellij.notification.Notifications
|
import com.intellij.notification.Notifications
|
||||||
|
import com.intellij.openapi.components.*
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.project.guessProjectDir
|
import com.intellij.openapi.project.guessProjectDir
|
||||||
|
import com.intellij.openapi.util.Key
|
||||||
|
import com.intellij.openapi.util.UserDataHolder
|
||||||
|
import com.intellij.openapi.vfs.toNioPathOrNull
|
||||||
import com.intellij.platform.util.progress.withProgressText
|
import com.intellij.platform.util.progress.withProgressText
|
||||||
import com.intellij.util.io.awaitExit
|
import com.intellij.util.io.awaitExit
|
||||||
|
import com.intellij.util.xmlb.annotations.Attribute
|
||||||
import kotlinx.coroutines.Dispatchers
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.sync.Mutex
|
||||||
import kotlinx.coroutines.sync.withLock
|
import kotlinx.coroutines.sync.withLock
|
||||||
import kotlinx.coroutines.withContext
|
import kotlinx.coroutines.withContext
|
||||||
import kotlinx.serialization.json.Json
|
import kotlinx.serialization.json.Json
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
import kotlin.io.path.isRegularFile
|
||||||
|
|
||||||
object DirenvCmd {
|
@Service(Service.Level.PROJECT)
|
||||||
suspend fun importDirenv(project: Project): Env {
|
@State(
|
||||||
if (!direnvInstalled())
|
name = "Direnv",
|
||||||
return emptyEnv
|
storages = [Storage("zigbrains.xml")]
|
||||||
val workDir = project.guessProjectDir()?.toNioPath() ?: return emptyEnv
|
)
|
||||||
|
class DirenvService(val project: Project): SerializablePersistentStateComponent<DirenvService.State>(State()), IDirenvService {
|
||||||
|
private val mutex = Mutex()
|
||||||
|
|
||||||
val runOutput = run(project, workDir, "export", "json")
|
override val isInstalled: Boolean by lazy {
|
||||||
|
// Using the builtin stuff here instead of Env because it should only scan for direnv on the process path
|
||||||
|
PathEnvironmentVariableUtil.findExecutableInPathOnAnyOS("direnv") != null
|
||||||
|
}
|
||||||
|
|
||||||
|
var isEnabledRaw: DirenvState
|
||||||
|
get() = state.enabled
|
||||||
|
set(value) {
|
||||||
|
updateState {
|
||||||
|
it.copy(enabled = value)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override val isEnabled: DirenvState
|
||||||
|
get() = isEnabledRaw
|
||||||
|
|
||||||
|
override suspend fun import(): Env {
|
||||||
|
if (!isInstalled || !project.isTrusted() || project.isDefault)
|
||||||
|
return Env.empty
|
||||||
|
val workDir = project.guessProjectDir()?.toNioPath() ?: return Env.empty
|
||||||
|
|
||||||
|
val runOutput = run(workDir, "export", "json")
|
||||||
if (runOutput.error) {
|
if (runOutput.error) {
|
||||||
if (runOutput.output.contains("is blocked")) {
|
if (runOutput.output.contains("is blocked")) {
|
||||||
Notifications.Bus.notify(Notification(
|
Notifications.Bus.notify(Notification(
|
||||||
|
@ -53,7 +84,7 @@ object DirenvCmd {
|
||||||
ZigBrainsBundle.message("notification.content.direnv-blocked"),
|
ZigBrainsBundle.message("notification.content.direnv-blocked"),
|
||||||
NotificationType.ERROR
|
NotificationType.ERROR
|
||||||
))
|
))
|
||||||
return emptyEnv
|
return Env.empty
|
||||||
} else {
|
} else {
|
||||||
Notifications.Bus.notify(Notification(
|
Notifications.Bus.notify(Notification(
|
||||||
GROUP_DISPLAY_ID,
|
GROUP_DISPLAY_ID,
|
||||||
|
@ -61,22 +92,22 @@ object DirenvCmd {
|
||||||
ZigBrainsBundle.message("notification.content.direnv-error", runOutput.output),
|
ZigBrainsBundle.message("notification.content.direnv-error", runOutput.output),
|
||||||
NotificationType.ERROR
|
NotificationType.ERROR
|
||||||
))
|
))
|
||||||
return emptyEnv
|
return Env.empty
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if (runOutput.output.isBlank()) {
|
return if (runOutput.output.isBlank()) {
|
||||||
return emptyEnv
|
Env.empty
|
||||||
} else {
|
} else {
|
||||||
return Env(Json.decodeFromString<Map<String, String>>(runOutput.output))
|
Env(Json.decodeFromString<Map<String, String>>(runOutput.output))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private suspend fun run(project: Project, workDir: Path, vararg args: String): DirenvOutput {
|
private suspend fun run(workDir: Path, vararg args: String): DirenvOutput {
|
||||||
val cli = GeneralCommandLine("direnv", *args).withWorkingDirectory(workDir)
|
val cli = GeneralCommandLine("direnv", *args).withWorkingDirectory(workDir)
|
||||||
|
|
||||||
val (process, exitCode) = withProgressText("Running ${cli.commandLineString}") {
|
val (process, exitCode) = withProgressText("Running ${cli.commandLineString}") {
|
||||||
withContext(Dispatchers.IO) {
|
withContext(Dispatchers.IO) {
|
||||||
project.direnvService.mutex.withLock {
|
mutex.withLock {
|
||||||
val process = cli.createProcess()
|
val process = cli.createProcess()
|
||||||
val exitCode = process.awaitExit()
|
val exitCode = process.awaitExit()
|
||||||
process to exitCode
|
process to exitCode
|
||||||
|
@ -93,14 +124,39 @@ object DirenvCmd {
|
||||||
return DirenvOutput(stdOut, false)
|
return DirenvOutput(stdOut, false)
|
||||||
}
|
}
|
||||||
|
|
||||||
private const val GROUP_DISPLAY_ID = "zigbrains-direnv"
|
fun hasDotEnv(): Boolean {
|
||||||
fun direnvInstalled() =
|
if (!isInstalled)
|
||||||
// Using the builtin stuff here instead of Env because it should only scan for direnv on the process path
|
return false
|
||||||
PathEnvironmentVariableUtil.findExecutableInPathOnAnyOS("direnv") != null
|
val projectDir = project.guessProjectDir()?.toNioPathOrNull() ?: return false
|
||||||
|
return envFiles.any { projectDir.resolve(it).isRegularFile() }
|
||||||
|
}
|
||||||
|
|
||||||
|
data class State(
|
||||||
|
@JvmField
|
||||||
|
@Attribute
|
||||||
|
var enabled: DirenvState = DirenvState.Auto
|
||||||
|
)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
private const val GROUP_DISPLAY_ID = "zigbrains-direnv"
|
||||||
|
fun getInstance(project: Project): IDirenvService = project.service<DirenvService>()
|
||||||
|
|
||||||
|
private val STATE_KEY = Key.create<DirenvState>("DIRENV_STATE")
|
||||||
|
|
||||||
|
fun getStateFor(data: UserDataHolder?, project: Project?): DirenvState {
|
||||||
|
return data?.getUserData(STATE_KEY) ?: project?.let { getInstance(project).isEnabled } ?: DirenvState.Disabled
|
||||||
|
}
|
||||||
|
|
||||||
|
fun setStateFor(data: UserDataHolder, state: DirenvState) {
|
||||||
|
data.putUserData(STATE_KEY, state)
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
suspend fun Project?.getDirenv(): Env {
|
sealed interface IDirenvService {
|
||||||
if (this == null)
|
val isInstalled: Boolean
|
||||||
return emptyEnv
|
val isEnabled: DirenvState
|
||||||
return DirenvCmd.importDirenv(this)
|
suspend fun import(): Env
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private val envFiles = listOf(".envrc", ".env")
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -22,14 +22,19 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.direnv
|
package com.falsepattern.zigbrains.direnv
|
||||||
|
|
||||||
import com.intellij.openapi.components.Service
|
|
||||||
import com.intellij.openapi.components.service
|
import com.intellij.openapi.components.service
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import kotlinx.coroutines.sync.Mutex
|
|
||||||
|
|
||||||
@Service(Service.Level.PROJECT)
|
enum class DirenvState {
|
||||||
class DirenvProjectService {
|
Auto,
|
||||||
val mutex = Mutex()
|
Enabled,
|
||||||
}
|
Disabled;
|
||||||
|
|
||||||
val Project.direnvService get() = service<DirenvProjectService>()
|
fun isEnabled(project: Project?): Boolean {
|
||||||
|
return when(this) {
|
||||||
|
Enabled -> true
|
||||||
|
Disabled -> false
|
||||||
|
Auto -> project?.service<DirenvService>()?.hasDotEnv() == true
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -25,31 +25,38 @@ package com.falsepattern.zigbrains.direnv
|
||||||
import com.intellij.openapi.util.SystemInfo
|
import com.intellij.openapi.util.SystemInfo
|
||||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||||
import com.intellij.util.EnvironmentUtil
|
import com.intellij.util.EnvironmentUtil
|
||||||
|
import kotlinx.coroutines.Dispatchers
|
||||||
|
import kotlinx.coroutines.flow.flow
|
||||||
|
import kotlinx.coroutines.flow.flowOn
|
||||||
import org.jetbrains.annotations.NonNls
|
import org.jetbrains.annotations.NonNls
|
||||||
import java.io.File
|
import java.io.File
|
||||||
import java.nio.file.Path
|
import kotlin.io.path.absolute
|
||||||
import kotlin.io.path.*
|
import kotlin.io.path.isDirectory
|
||||||
|
import kotlin.io.path.isExecutable
|
||||||
|
import kotlin.io.path.isRegularFile
|
||||||
|
|
||||||
|
@JvmRecord
|
||||||
data class Env(val env: Map<String, String>) {
|
data class Env(val env: Map<String, String>) {
|
||||||
private val path get() = getVariable("PATH")?.split(File.pathSeparatorChar)
|
private val path get() = getVariable("PATH")?.split(File.pathSeparatorChar)
|
||||||
|
|
||||||
private fun getVariable(name: @NonNls String) =
|
private fun getVariable(name: @NonNls String) =
|
||||||
env.getOrElse(name) { EnvironmentUtil.getValue(name) }
|
env.getOrElse(name) { EnvironmentUtil.getValue(name) }
|
||||||
|
|
||||||
fun findExecutableOnPATH(exe: @NonNls String): Path? {
|
fun findAllExecutablesOnPATH(exe: @NonNls String) = flow {
|
||||||
val exeName = if (SystemInfo.isWindows) "$exe.exe" else exe
|
val exeName = if (SystemInfo.isWindows) "$exe.exe" else exe
|
||||||
val paths = path ?: return null
|
val paths = path ?: return@flow
|
||||||
for (dir in paths) {
|
for (dir in paths) {
|
||||||
val path = dir.toNioPathOrNull()?.absolute() ?: continue
|
val path = dir.toNioPathOrNull()?.absolute() ?: continue
|
||||||
if (path.notExists() || !path.isDirectory())
|
if (!path.toFile().exists() || !path.isDirectory())
|
||||||
continue
|
continue
|
||||||
val exePath = path.resolve(exeName).absolute()
|
val exePath = path.resolve(exeName).absolute()
|
||||||
if (!exePath.isRegularFile() || !exePath.isExecutable())
|
if (!exePath.isRegularFile() || !exePath.isExecutable())
|
||||||
continue
|
continue
|
||||||
return exePath
|
emit(exePath)
|
||||||
}
|
}
|
||||||
return null
|
}.flowOn(Dispatchers.IO)
|
||||||
|
|
||||||
|
companion object {
|
||||||
|
val empty = Env(emptyMap())
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val emptyEnv = Env(emptyMap())
|
|
|
@ -0,0 +1,101 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* ZigBrains is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, only version 3 of the License.
|
||||||
|
*
|
||||||
|
* ZigBrains is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.falsepattern.zigbrains.direnv.ui
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||||
|
import com.falsepattern.zigbrains.direnv.DirenvService
|
||||||
|
import com.falsepattern.zigbrains.direnv.DirenvState
|
||||||
|
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider
|
||||||
|
import com.falsepattern.zigbrains.project.settings.ZigProjectConfigurationProvider.Companion.PROJECT_KEY
|
||||||
|
import com.falsepattern.zigbrains.shared.SubConfigurable
|
||||||
|
import com.intellij.openapi.components.service
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.openapi.ui.ComboBox
|
||||||
|
import com.intellij.ui.dsl.builder.Panel
|
||||||
|
import java.awt.event.ItemEvent
|
||||||
|
|
||||||
|
abstract class DirenvEditor<T>(private val sharedState: ZigProjectConfigurationProvider.IUserDataBridge?): SubConfigurable<T> {
|
||||||
|
private var cb: ComboBox<DirenvState>? = null
|
||||||
|
override fun attach(panel: Panel): Unit = with(panel) {
|
||||||
|
row(ZigBrainsBundle.message("settings.direnv.enable.label")) {
|
||||||
|
comboBox(DirenvState.entries).component.let {
|
||||||
|
cb = it
|
||||||
|
if (sharedState != null) {
|
||||||
|
it.addItemListener { e ->
|
||||||
|
if (e.stateChange != ItemEvent.SELECTED)
|
||||||
|
return@addItemListener
|
||||||
|
val item = e.item
|
||||||
|
if (item !is DirenvState)
|
||||||
|
return@addItemListener
|
||||||
|
DirenvService.setStateFor(sharedState, item)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun isModified(context: T): Boolean {
|
||||||
|
return isEnabled(context) != cb?.selectedItem as DirenvState
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun apply(context: T) {
|
||||||
|
setEnabled(context, cb?.selectedItem as DirenvState)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun reset(context: T?) {
|
||||||
|
if (context == null) {
|
||||||
|
cb?.selectedItem = DirenvState.Auto
|
||||||
|
return
|
||||||
|
}
|
||||||
|
cb?.selectedItem = isEnabled(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun dispose() {
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract fun isEnabled(context: T): DirenvState
|
||||||
|
abstract fun setEnabled(context: T, value: DirenvState)
|
||||||
|
|
||||||
|
class ForProject(sharedState: ZigProjectConfigurationProvider.IUserDataBridge) : DirenvEditor<Project>(sharedState) {
|
||||||
|
override fun isEnabled(context: Project): DirenvState {
|
||||||
|
return DirenvService.getInstance(context).isEnabled
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun setEnabled(context: Project, value: DirenvState) {
|
||||||
|
context.service<DirenvService>().isEnabledRaw = value
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class Provider: ZigProjectConfigurationProvider {
|
||||||
|
override fun create(sharedState: ZigProjectConfigurationProvider.IUserDataBridge): SubConfigurable<Project>? {
|
||||||
|
if (sharedState.getUserData(PROJECT_KEY)?.isDefault != false) {
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
DirenvService.setStateFor(sharedState, DirenvState.Auto)
|
||||||
|
return ForProject(sharedState)
|
||||||
|
}
|
||||||
|
|
||||||
|
override val index: Int
|
||||||
|
get() = 100
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,76 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of ZigBrains.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
|
||||||
* All Rights Reserved
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* ZigBrains is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, only version 3 of the License.
|
|
||||||
*
|
|
||||||
* ZigBrains is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.lsp
|
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.lsp.settings.zlsSettings
|
|
||||||
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
|
||||||
import com.intellij.openapi.components.service
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.util.Key
|
|
||||||
import com.intellij.platform.ide.progress.ModalTaskOwner
|
|
||||||
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
|
|
||||||
import com.intellij.util.application
|
|
||||||
import com.redhat.devtools.lsp4ij.LanguageServerEnablementSupport
|
|
||||||
import com.redhat.devtools.lsp4ij.LanguageServerFactory
|
|
||||||
import com.redhat.devtools.lsp4ij.LanguageServerManager
|
|
||||||
import com.redhat.devtools.lsp4ij.ServerStatus
|
|
||||||
import com.redhat.devtools.lsp4ij.server.StreamConnectionProvider
|
|
||||||
import kotlinx.coroutines.launch
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
|
|
||||||
class ZigLanguageServerFactory: LanguageServerFactory, LanguageServerEnablementSupport {
|
|
||||||
override fun createConnectionProvider(project: Project): StreamConnectionProvider {
|
|
||||||
return if (application.isDispatchThread) {
|
|
||||||
runWithModalProgressBlocking(ModalTaskOwner.project(project), ZLSBundle.message("progress.title.create-connection-provider")) {
|
|
||||||
ZLSStreamConnectionProvider.create(project)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
runBlocking {
|
|
||||||
ZLSStreamConnectionProvider.create(project)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isEnabled(project: Project): Boolean {
|
|
||||||
return (project.getUserData(ENABLED_KEY) ?: true) && project.zlsSettings.validate()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun setEnabled(enabled: Boolean, project: Project) {
|
|
||||||
project.putUserData(ENABLED_KEY, enabled)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class ZLSStarter: LanguageServerStarter {
|
|
||||||
override fun startLSP(project: Project, restart: Boolean) {
|
|
||||||
project.zigCoroutineScope.launch {
|
|
||||||
val manager = project.service<LanguageServerManager>()
|
|
||||||
val status = manager.getServerStatus("ZigBrains")
|
|
||||||
if ((status == ServerStatus.started || status == ServerStatus.starting) && !restart)
|
|
||||||
return@launch
|
|
||||||
manager.start("ZigBrains")
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
}
|
|
||||||
|
|
||||||
private val ENABLED_KEY = Key.create<Boolean>("ZLS_ENABLED")
|
|
|
@ -1,39 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of ZigBrains.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
|
||||||
* All Rights Reserved
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* ZigBrains is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, only version 3 of the License.
|
|
||||||
*
|
|
||||||
* ZigBrains is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
@file:Suppress("HardCodedStringLiteral")
|
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.lsp.config
|
|
||||||
|
|
||||||
import kotlinx.serialization.SerialName
|
|
||||||
import kotlinx.serialization.Serializable
|
|
||||||
import org.jetbrains.annotations.NonNls
|
|
||||||
|
|
||||||
@Serializable
|
|
||||||
data class ZLSConfig(
|
|
||||||
@SerialName("zig_exe_path") val zigExePath: @NonNls String? = null,
|
|
||||||
@SerialName("zig_lib_path") val zigLibPath: @NonNls String? = null,
|
|
||||||
@SerialName("enable_build_on_save") val buildOnSave: Boolean? = null,
|
|
||||||
@SerialName("build_on_save_step") val buildOnSaveStep: @NonNls String? = null,
|
|
||||||
@SerialName("dangerous_comptime_experiments_do_not_enable") val comptimeInterpreter: Boolean? = null,
|
|
||||||
@SerialName("highlight_global_var_declarations") val globalVarDeclarations: Boolean? = null
|
|
||||||
)
|
|
|
@ -1,120 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of ZigBrains.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
|
||||||
* All Rights Reserved
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* ZigBrains is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, only version 3 of the License.
|
|
||||||
*
|
|
||||||
* ZigBrains is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.lsp.settings
|
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.direnv.emptyEnv
|
|
||||||
import com.falsepattern.zigbrains.direnv.getDirenv
|
|
||||||
import com.falsepattern.zigbrains.lsp.ZLSBundle
|
|
||||||
import com.intellij.openapi.components.*
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
|
||||||
import com.intellij.platform.ide.progress.ModalTaskOwner
|
|
||||||
import com.intellij.platform.ide.progress.runWithModalProgressBlocking
|
|
||||||
import com.intellij.util.application
|
|
||||||
import kotlinx.coroutines.runBlocking
|
|
||||||
import java.nio.file.Path
|
|
||||||
import java.util.concurrent.locks.ReentrantLock
|
|
||||||
import kotlin.concurrent.withLock
|
|
||||||
import kotlin.io.path.isExecutable
|
|
||||||
import kotlin.io.path.isRegularFile
|
|
||||||
import kotlin.io.path.notExists
|
|
||||||
|
|
||||||
@Service(Service.Level.PROJECT)
|
|
||||||
@State(
|
|
||||||
name = "ZLSSettings",
|
|
||||||
storages = [Storage(value = "zigbrains.xml")]
|
|
||||||
)
|
|
||||||
class ZLSProjectSettingsService(val project: Project): PersistentStateComponent<ZLSSettings> {
|
|
||||||
@Volatile
|
|
||||||
private var state = ZLSSettings()
|
|
||||||
@Volatile
|
|
||||||
private var dirty = true
|
|
||||||
@Volatile
|
|
||||||
private var valid = false
|
|
||||||
|
|
||||||
private val mutex = ReentrantLock()
|
|
||||||
override fun getState(): ZLSSettings {
|
|
||||||
return state.copy()
|
|
||||||
}
|
|
||||||
|
|
||||||
fun setState(value: ZLSSettings) {
|
|
||||||
mutex.withLock {
|
|
||||||
this.state = value
|
|
||||||
dirty = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun loadState(state: ZLSSettings) {
|
|
||||||
mutex.withLock {
|
|
||||||
this.state = state
|
|
||||||
dirty = true
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun isModified(otherData: ZLSSettings): Boolean {
|
|
||||||
return state != otherData
|
|
||||||
}
|
|
||||||
|
|
||||||
fun validate(): Boolean {
|
|
||||||
mutex.withLock {
|
|
||||||
if (dirty) {
|
|
||||||
val state = this.state
|
|
||||||
valid = if (application.isDispatchThread) {
|
|
||||||
runWithModalProgressBlocking(ModalTaskOwner.project(project), ZLSBundle.message("progress.title.validate")) {
|
|
||||||
doValidate(project, state)
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
runBlocking {
|
|
||||||
doValidate(project, state)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
dirty = false
|
|
||||||
}
|
|
||||||
return valid
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun doValidate(project: Project, state: ZLSSettings): Boolean {
|
|
||||||
val zlsPath: Path = state.zlsPath.let { zlsPath ->
|
|
||||||
if (zlsPath.isEmpty()) {
|
|
||||||
val env = if (state.direnv) project.getDirenv() else emptyEnv
|
|
||||||
env.findExecutableOnPATH("zls") ?: run {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
} else {
|
|
||||||
zlsPath.toNioPathOrNull() ?: run {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
if (zlsPath.notExists()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
if (!zlsPath.isRegularFile() || !zlsPath.isExecutable()) {
|
|
||||||
return false
|
|
||||||
}
|
|
||||||
return true
|
|
||||||
}
|
|
||||||
|
|
||||||
val Project.zlsSettings get() = service<ZLSProjectSettingsService>()
|
|
|
@ -1,59 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of ZigBrains.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
|
||||||
* All Rights Reserved
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* ZigBrains is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, only version 3 of the License.
|
|
||||||
*
|
|
||||||
* ZigBrains is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.lsp.settings
|
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.lsp.startLSP
|
|
||||||
import com.falsepattern.zigbrains.shared.SubConfigurable
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.util.Disposer
|
|
||||||
import com.intellij.ui.dsl.builder.Panel
|
|
||||||
|
|
||||||
class ZLSSettingsConfigurable(private val project: Project): SubConfigurable {
|
|
||||||
private var appSettingsComponent: ZLSSettingsPanel? = null
|
|
||||||
override fun createComponent(panel: Panel) {
|
|
||||||
appSettingsComponent = ZLSSettingsPanel(project).apply { attach(panel) }.also { Disposer.register(this, it) }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun isModified(): Boolean {
|
|
||||||
val data = appSettingsComponent?.data ?: return false
|
|
||||||
return project.zlsSettings.state != data
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun apply() {
|
|
||||||
val data = appSettingsComponent?.data ?: return
|
|
||||||
val settings = project.zlsSettings
|
|
||||||
val reloadZLS = settings.isModified(data)
|
|
||||||
settings.state = data
|
|
||||||
if (reloadZLS) {
|
|
||||||
startLSP(project, true)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun reset() {
|
|
||||||
appSettingsComponent?.data = project.zlsSettings.state
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dispose() {
|
|
||||||
appSettingsComponent = null
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,138 +0,0 @@
|
||||||
/*
|
|
||||||
* This file is part of ZigBrains.
|
|
||||||
*
|
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
|
||||||
* All Rights Reserved
|
|
||||||
*
|
|
||||||
* The above copyright notice and this permission notice shall be included
|
|
||||||
* in all copies or substantial portions of the Software.
|
|
||||||
*
|
|
||||||
* ZigBrains is free software: you can redistribute it and/or modify
|
|
||||||
* it under the terms of the GNU Lesser General Public License as published by
|
|
||||||
* the Free Software Foundation, only version 3 of the License.
|
|
||||||
*
|
|
||||||
* ZigBrains is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU Lesser General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU Lesser General Public License
|
|
||||||
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
|
||||||
*/
|
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.lsp.settings
|
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.direnv.DirenvCmd
|
|
||||||
import com.falsepattern.zigbrains.direnv.Env
|
|
||||||
import com.falsepattern.zigbrains.direnv.emptyEnv
|
|
||||||
import com.falsepattern.zigbrains.direnv.getDirenv
|
|
||||||
import com.falsepattern.zigbrains.lsp.ZLSBundle
|
|
||||||
import com.falsepattern.zigbrains.shared.coroutine.launchWithEDT
|
|
||||||
import com.falsepattern.zigbrains.shared.zigCoroutineScope
|
|
||||||
import com.intellij.openapi.Disposable
|
|
||||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.util.Disposer
|
|
||||||
import com.intellij.platform.ide.progress.ModalTaskOwner
|
|
||||||
import com.intellij.platform.ide.progress.TaskCancellation
|
|
||||||
import com.intellij.platform.ide.progress.withModalProgress
|
|
||||||
import com.intellij.ui.components.JBCheckBox
|
|
||||||
import com.intellij.ui.components.fields.ExtendableTextField
|
|
||||||
import com.intellij.ui.components.textFieldWithBrowseButton
|
|
||||||
import com.intellij.ui.dsl.builder.AlignX
|
|
||||||
import com.intellij.ui.dsl.builder.Panel
|
|
||||||
import kotlin.io.path.pathString
|
|
||||||
|
|
||||||
class ZLSSettingsPanel(private val project: Project?) : Disposable {
|
|
||||||
private val zlsPath = textFieldWithBrowseButton(
|
|
||||||
project,
|
|
||||||
ZLSBundle.message("settings.zls-path.browse.title"),
|
|
||||||
FileChooserDescriptorFactory.createSingleFileDescriptor(),
|
|
||||||
).also { Disposer.register(this, it) }
|
|
||||||
private val zlsConfigPath = textFieldWithBrowseButton(
|
|
||||||
project,
|
|
||||||
ZLSBundle.message("settings.zls-config-path.browse.title"),
|
|
||||||
FileChooserDescriptorFactory.createSingleFileDescriptor()
|
|
||||||
).also { Disposer.register(this, it) }
|
|
||||||
|
|
||||||
private val buildOnSave = JBCheckBox().apply { toolTipText = ZLSBundle.message("settings.build-on-save.tooltip") }
|
|
||||||
private val buildOnSaveStep = ExtendableTextField().apply { toolTipText = ZLSBundle.message("settings.build-on-save-step.tooltip") }
|
|
||||||
private val globalVarDeclarations = JBCheckBox()
|
|
||||||
private val comptimeInterpreter = JBCheckBox()
|
|
||||||
private val inlayHints = JBCheckBox()
|
|
||||||
private val inlayHintsCompact = JBCheckBox().apply { toolTipText = ZLSBundle.message("settings.inlay-hints-compact.tooltip") }
|
|
||||||
|
|
||||||
private val messageTrace = JBCheckBox()
|
|
||||||
private val debug = JBCheckBox()
|
|
||||||
private val direnv = JBCheckBox(ZLSBundle.message("settings.zls-path.use-direnv.label"))
|
|
||||||
|
|
||||||
fun attach(panel: Panel) = with(panel) {
|
|
||||||
group(ZLSBundle.message("settings.group.title")) {
|
|
||||||
row(ZLSBundle.message("settings.zls-path.label")) {
|
|
||||||
cell(zlsPath).resizableColumn().align(AlignX.FILL)
|
|
||||||
if (DirenvCmd.direnvInstalled() && project != null && !project.isDefault) {
|
|
||||||
cell(direnv)
|
|
||||||
}
|
|
||||||
button(ZLSBundle.message("settings.zls-path.autodetect.label")) {
|
|
||||||
project.zigCoroutineScope.launchWithEDT {
|
|
||||||
withModalProgress(ModalTaskOwner.component(zlsPath), "Detecting ZLS...", TaskCancellation.cancellable()) {
|
|
||||||
autodetect()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
row(ZLSBundle.message("settings.zls-config-path.label")) { cell(zlsConfigPath).align(AlignX.FILL) }
|
|
||||||
row(ZLSBundle.message("settings.inlay-hints.label")) { cell(inlayHints) }
|
|
||||||
row(ZLSBundle.message("settings.inlay-hints-compact.label")) { cell(inlayHintsCompact) }
|
|
||||||
row(ZLSBundle.message("settings.build-on-save.label")) { cell(buildOnSave) }
|
|
||||||
row(ZLSBundle.message("settings.build-on-save-step.label")) { cell(buildOnSaveStep).resizableColumn().align(AlignX.FILL) }
|
|
||||||
row(ZLSBundle.message("settings.global-var-declarations.label")) { cell(globalVarDeclarations) }
|
|
||||||
row(ZLSBundle.message("settings.comptime-interpreter.label")) { cell(comptimeInterpreter) }
|
|
||||||
}
|
|
||||||
group(ZLSBundle.message("dev-settings.group.title")) {
|
|
||||||
row(ZLSBundle.message("dev-settings.debug.label")) { cell(debug) }
|
|
||||||
row(ZLSBundle.message("dev-settings.message-trace.label")) { cell(messageTrace) }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
var data
|
|
||||||
get() = ZLSSettings(
|
|
||||||
direnv.isSelected,
|
|
||||||
zlsPath.text,
|
|
||||||
zlsConfigPath.text,
|
|
||||||
debug.isSelected,
|
|
||||||
messageTrace.isSelected,
|
|
||||||
buildOnSave.isSelected,
|
|
||||||
buildOnSaveStep.text,
|
|
||||||
globalVarDeclarations.isSelected,
|
|
||||||
comptimeInterpreter.isSelected,
|
|
||||||
inlayHints.isSelected,
|
|
||||||
inlayHintsCompact.isSelected
|
|
||||||
)
|
|
||||||
set(value) {
|
|
||||||
direnv.isSelected = value.direnv
|
|
||||||
zlsPath.text = value.zlsPath
|
|
||||||
zlsConfigPath.text = value.zlsConfigPath
|
|
||||||
debug.isSelected = value.debug
|
|
||||||
messageTrace.isSelected = value.messageTrace
|
|
||||||
buildOnSave.isSelected = value.buildOnSave
|
|
||||||
buildOnSaveStep.text = value.buildOnSaveStep
|
|
||||||
globalVarDeclarations.isSelected = value.globalVarDeclarations
|
|
||||||
comptimeInterpreter.isSelected = value.comptimeInterpreter
|
|
||||||
inlayHints.isSelected = value.inlayHints
|
|
||||||
inlayHintsCompact.isSelected = value.inlayHintsCompact
|
|
||||||
}
|
|
||||||
|
|
||||||
suspend fun autodetect() {
|
|
||||||
getDirenv().findExecutableOnPATH("zls")?.let { zlsPath.text = it.pathString }
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun dispose() {
|
|
||||||
}
|
|
||||||
|
|
||||||
private suspend fun getDirenv(): Env {
|
|
||||||
if (!direnv.isSelected)
|
|
||||||
return emptyEnv
|
|
||||||
return project.getDirenv()
|
|
||||||
}
|
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -31,7 +31,7 @@ import com.intellij.psi.PsiDirectory
|
||||||
class ZigNewFileAction: CreateFileFromTemplateAction() {
|
class ZigNewFileAction: CreateFileFromTemplateAction() {
|
||||||
override fun buildDialog(project: Project, directory: PsiDirectory, builder: CreateFileFromTemplateDialog.Builder) {
|
override fun buildDialog(project: Project, directory: PsiDirectory, builder: CreateFileFromTemplateDialog.Builder) {
|
||||||
builder.setTitle("Zig File")
|
builder.setTitle("Zig File")
|
||||||
.addKind("Empty file", Icons.ZIG, "blank_zig_file")
|
.addKind("Empty file", Icons.Zig, "blank_zig_file")
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getActionName(directory: PsiDirectory?, newName: String, templateName: String?): String {
|
override fun getActionName(directory: PsiDirectory?, newName: String, templateName: String?): String {
|
||||||
|
|
|
@ -0,0 +1,90 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* ZigBrains is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, only version 3 of the License.
|
||||||
|
*
|
||||||
|
* ZigBrains is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.falsepattern.zigbrains.project.actions
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.project.execution.base.ZigExecConfig
|
||||||
|
import com.falsepattern.zigbrains.project.execution.run.ZigConfigProducerRun
|
||||||
|
import com.falsepattern.zigbrains.project.execution.run.ZigExecConfigRun
|
||||||
|
import com.falsepattern.zigbrains.project.execution.test.ZigConfigProducerTest
|
||||||
|
import com.falsepattern.zigbrains.project.execution.test.ZigExecConfigTest
|
||||||
|
import com.intellij.execution.ExecutionManager
|
||||||
|
import com.intellij.execution.actions.ConfigurationContext
|
||||||
|
import com.intellij.execution.actions.RunConfigurationProducer
|
||||||
|
import com.intellij.execution.executors.DefaultRunExecutor
|
||||||
|
import com.intellij.execution.runners.ExecutionEnvironmentBuilder
|
||||||
|
import com.intellij.openapi.actionSystem.ActionUpdateThread
|
||||||
|
import com.intellij.openapi.actionSystem.AnActionEvent
|
||||||
|
import com.intellij.openapi.actionSystem.CommonDataKeys
|
||||||
|
import com.intellij.openapi.project.DumbAwareAction
|
||||||
|
|
||||||
|
class ZigRunFileAction: DumbAwareAction() {
|
||||||
|
override fun actionPerformed(e: AnActionEvent) {
|
||||||
|
val file = e.getData(CommonDataKeys.PSI_FILE) ?: return
|
||||||
|
val config = getConfig(e) ?: return
|
||||||
|
val project = file.project
|
||||||
|
val builder = ExecutionEnvironmentBuilder.createOrNull(DefaultRunExecutor.getRunExecutorInstance(), config) ?: return
|
||||||
|
ExecutionManager.getInstance(project).restartRunProfile(builder.build())
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getConfig(e: AnActionEvent): ZigExecConfig<*>? {
|
||||||
|
val context = ConfigurationContext.getFromContext(e.dataContext, e.place)
|
||||||
|
return getRunConfiguration(context) ?: getTestConfiguration(context)
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun update(e: AnActionEvent) {
|
||||||
|
e.presentation.isEnabledAndVisible = getConfig(e) != null
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun getRunConfiguration(context: ConfigurationContext): ZigExecConfigRun? {
|
||||||
|
try {
|
||||||
|
val configProducer = RunConfigurationProducer.getInstance(ZigConfigProducerRun::class.java)
|
||||||
|
val settings = configProducer.findExistingConfiguration(context)
|
||||||
|
if (settings != null) {
|
||||||
|
return settings.configuration as? ZigExecConfigRun
|
||||||
|
}
|
||||||
|
val fromContext = configProducer.createConfigurationFromContext(context)
|
||||||
|
if (fromContext != null) {
|
||||||
|
return fromContext.configuration as? ZigExecConfigRun
|
||||||
|
}
|
||||||
|
} catch (_: NullPointerException) {}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
private fun getTestConfiguration(context: ConfigurationContext): ZigExecConfigTest? {
|
||||||
|
try {
|
||||||
|
val configProducer = RunConfigurationProducer.getInstance(ZigConfigProducerTest::class.java)
|
||||||
|
val settings = configProducer.findExistingConfiguration(context)
|
||||||
|
if (settings != null) {
|
||||||
|
return settings.configuration as? ZigExecConfigTest
|
||||||
|
}
|
||||||
|
val fromContext = configProducer.createConfigurationFromContext(context)
|
||||||
|
if (fromContext != null) {
|
||||||
|
return fromContext.configuration as? ZigExecConfigTest
|
||||||
|
}
|
||||||
|
} catch (_: NullPointerException) {}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getActionUpdateThread(): ActionUpdateThread {
|
||||||
|
return ActionUpdateThread.BGT
|
||||||
|
}
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -27,25 +27,23 @@ import com.intellij.execution.filters.Filter.ResultItem
|
||||||
import com.intellij.execution.filters.OpenFileHyperlinkInfo
|
import com.intellij.execution.filters.OpenFileHyperlinkInfo
|
||||||
import com.intellij.openapi.project.Project
|
import com.intellij.openapi.project.Project
|
||||||
import com.intellij.openapi.project.guessProjectDir
|
import com.intellij.openapi.project.guessProjectDir
|
||||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
|
||||||
import com.intellij.openapi.vfs.refreshAndFindVirtualFile
|
import com.intellij.openapi.vfs.refreshAndFindVirtualFile
|
||||||
import com.intellij.openapi.vfs.toNioPathOrNull
|
import com.intellij.openapi.vfs.toNioPathOrNull
|
||||||
|
import java.io.File
|
||||||
import java.nio.file.InvalidPathException
|
import java.nio.file.InvalidPathException
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
import kotlin.io.path.isRegularFile
|
|
||||||
import kotlin.io.path.notExists
|
|
||||||
import kotlin.math.max
|
import kotlin.math.max
|
||||||
|
|
||||||
|
|
||||||
class ZigSourceFileFilter(private val project: Project): Filter {
|
class ZigSourceFileFilter(private val project: Project): Filter {
|
||||||
|
private val projectPath = runCatching { project.guessProjectDir()?.toNioPathOrNull()?.toFile() }.getOrNull()
|
||||||
override fun applyFilter(line: String, entireLength: Int): Filter.Result? {
|
override fun applyFilter(line: String, entireLength: Int): Filter.Result? {
|
||||||
val lineStart = entireLength - line.length
|
val lineStart = entireLength - line.length
|
||||||
val projectPath = project.guessProjectDir()?.toNioPathOrNull()
|
|
||||||
val results = ArrayList<ResultItem>()
|
val results = ArrayList<ResultItem>()
|
||||||
val matcher = LEN_REGEX.findAll(line)
|
val matcher = LEN_REGEX.findAll(line)
|
||||||
for (match in matcher) {
|
for (match in matcher) {
|
||||||
val start = match.range.first
|
val start = match.range.first
|
||||||
val pair = findLongestParsablePathFromOffset(line, start, projectPath)
|
val pair = findLongestParsablePathFromOffset(line, start)
|
||||||
val path = pair?.first ?: return null
|
val path = pair?.first ?: return null
|
||||||
val file = path.refreshAndFindVirtualFile() ?: return null
|
val file = path.refreshAndFindVirtualFile() ?: return null
|
||||||
val lineNumber = max(match.groups[1]!!.value.toInt() - 1, 0)
|
val lineNumber = max(match.groups[1]!!.value.toInt() - 1, 0)
|
||||||
|
@ -55,25 +53,29 @@ class ZigSourceFileFilter(private val project: Project): Filter {
|
||||||
return Filter.Result(results)
|
return Filter.Result(results)
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun findLongestParsablePathFromOffset(line: String, end: Int, projectPath: Path?): Pair<Path, Int>? {
|
private fun findLongestParsablePathFromOffset(line: String, end: Int): Pair<Path, Int>? {
|
||||||
var longestStart = -1
|
var longestStart = -1
|
||||||
var longest: Path? = null
|
var longest: File? = null
|
||||||
for (i in end - 1 downTo 0) {
|
for (i in end - 1 downTo 0) {
|
||||||
try {
|
try {
|
||||||
val pathStr = line.substring(i, end)
|
val pathStr = line.substring(i, end)
|
||||||
var path: Path = pathStr.toNioPathOrNull() ?: continue
|
var file = File(pathStr)
|
||||||
if ((path.notExists() || !path.isRegularFile()) && projectPath != null) {
|
if (!file.isFile) {
|
||||||
path = projectPath.resolve(pathStr)
|
if (projectPath == null) {
|
||||||
if (path.notExists() || !path.isRegularFile())
|
|
||||||
continue
|
continue
|
||||||
|
}
|
||||||
|
file = projectPath.resolve(pathStr)
|
||||||
|
if (!file.isFile) {
|
||||||
|
continue
|
||||||
|
}
|
||||||
}
|
}
|
||||||
longest = path
|
longest = file
|
||||||
longestStart = i
|
longestStart = i
|
||||||
} catch (ignored: InvalidPathException) {
|
} catch (ignored: InvalidPathException) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
longest ?: return null
|
longest ?: return null
|
||||||
return Pair(longest, longestStart)
|
return Pair(longest.toPath(), longestStart)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -20,20 +20,18 @@
|
||||||
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||||
*/
|
*/
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.lsp.settings
|
package com.falsepattern.zigbrains.project.execution
|
||||||
|
|
||||||
import org.jetbrains.annotations.NonNls
|
import com.intellij.execution.filters.TextConsoleBuilderImpl
|
||||||
|
import com.intellij.execution.ui.ConsoleView
|
||||||
|
import com.intellij.openapi.project.Project
|
||||||
|
import com.intellij.terminal.TerminalExecutionConsole
|
||||||
|
|
||||||
data class ZLSSettings(
|
class ZigConsoleBuilder(private val project: Project, private val emulateTerminal: Boolean = false): TextConsoleBuilderImpl(project) {
|
||||||
var direnv: Boolean = true,
|
override fun createConsole(): ConsoleView {
|
||||||
var zlsPath: @NonNls String = "",
|
return if (emulateTerminal)
|
||||||
var zlsConfigPath: @NonNls String = "",
|
TerminalExecutionConsole(project, null)
|
||||||
var debug: Boolean = false,
|
else
|
||||||
var messageTrace: Boolean = false,
|
super.createConsole()
|
||||||
var buildOnSave: Boolean = false,
|
}
|
||||||
var buildOnSaveStep: @NonNls String = "install",
|
}
|
||||||
var globalVarDeclarations: Boolean = false,
|
|
||||||
var comptimeInterpreter: Boolean = false,
|
|
||||||
var inlayHints: Boolean = true,
|
|
||||||
var inlayHintsCompact: Boolean = true
|
|
||||||
)
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -24,20 +24,17 @@ package com.falsepattern.zigbrains.project.execution.base
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigConfigurable.ZigConfigModule
|
import com.falsepattern.zigbrains.project.execution.base.ZigConfigurable.ZigConfigModule
|
||||||
import com.falsepattern.zigbrains.project.settings.zigProjectSettings
|
|
||||||
import com.falsepattern.zigbrains.shared.cli.translateCommandline
|
import com.falsepattern.zigbrains.shared.cli.translateCommandline
|
||||||
import com.falsepattern.zigbrains.shared.element.*
|
import com.falsepattern.zigbrains.shared.element.*
|
||||||
import com.intellij.openapi.Disposable
|
import com.intellij.openapi.Disposable
|
||||||
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
import com.intellij.openapi.fileChooser.FileChooserDescriptorFactory
|
||||||
import com.intellij.openapi.options.SettingsEditor
|
import com.intellij.openapi.options.SettingsEditor
|
||||||
import com.intellij.openapi.project.Project
|
|
||||||
import com.intellij.openapi.ui.ComboBox
|
import com.intellij.openapi.ui.ComboBox
|
||||||
import com.intellij.openapi.ui.TextBrowseFolderListener
|
|
||||||
import com.intellij.openapi.ui.TextFieldWithBrowseButton
|
|
||||||
import com.intellij.openapi.util.Disposer
|
import com.intellij.openapi.util.Disposer
|
||||||
import com.intellij.openapi.util.io.toNioPathOrNull
|
import com.intellij.openapi.util.io.toNioPathOrNull
|
||||||
import com.intellij.ui.components.JBCheckBox
|
import com.intellij.ui.components.JBCheckBox
|
||||||
import com.intellij.ui.components.JBTextField
|
import com.intellij.ui.components.JBTextField
|
||||||
|
import com.intellij.ui.components.textFieldWithBrowseButton
|
||||||
import com.intellij.ui.dsl.builder.AlignX
|
import com.intellij.ui.dsl.builder.AlignX
|
||||||
import com.intellij.ui.dsl.builder.Panel
|
import com.intellij.ui.dsl.builder.Panel
|
||||||
import com.intellij.ui.dsl.builder.panel
|
import com.intellij.ui.dsl.builder.panel
|
||||||
|
@ -161,12 +158,10 @@ class WorkDirectoryConfigurable(@Transient override val serializedName: String)
|
||||||
}
|
}
|
||||||
|
|
||||||
class WorkDirectoryConfigModule(private val serializedName: String) : PathConfigModule<WorkDirectoryConfigurable>() {
|
class WorkDirectoryConfigModule(private val serializedName: String) : PathConfigModule<WorkDirectoryConfigurable>() {
|
||||||
private val field = TextFieldWithBrowseButton(
|
private val field = textFieldWithBrowseButton(
|
||||||
TextBrowseFolderListener(
|
null,
|
||||||
FileChooserDescriptorFactory.createSingleFolderDescriptor().withTitle(ZigBrainsBundle.message("dialog.title.working-directory"))
|
FileChooserDescriptorFactory.createSingleFolderDescriptor().withTitle(ZigBrainsBundle.message("dialog.title.working-directory"))
|
||||||
),
|
).also { Disposer.register(this, it) }
|
||||||
this
|
|
||||||
)
|
|
||||||
|
|
||||||
override var stringValue by field::text
|
override var stringValue by field::text
|
||||||
|
|
||||||
|
@ -201,9 +196,9 @@ class FilePathConfigurable(
|
||||||
}
|
}
|
||||||
|
|
||||||
class FilePathConfigModule(private val serializedName: String, @Nls private val label: String) : PathConfigModule<FilePathConfigurable>() {
|
class FilePathConfigModule(private val serializedName: String, @Nls private val label: String) : PathConfigModule<FilePathConfigurable>() {
|
||||||
private val field = TextFieldWithBrowseButton(
|
private val field = textFieldWithBrowseButton(
|
||||||
TextBrowseFolderListener(FileChooserDescriptorFactory.createSingleFileDescriptor()),
|
null,
|
||||||
this
|
FileChooserDescriptorFactory.createSingleFileNoJarsDescriptor(),
|
||||||
)
|
)
|
||||||
|
|
||||||
override var stringValue by field::text
|
override var stringValue by field::text
|
||||||
|
@ -224,7 +219,7 @@ class FilePathConfigurable(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class CheckboxConfigurable(
|
open class CheckboxConfigurable(
|
||||||
@Transient private val serializedName: String,
|
@Transient private val serializedName: String,
|
||||||
@Transient @Nls private val label: String,
|
@Transient @Nls private val label: String,
|
||||||
var value: Boolean
|
var value: Boolean
|
||||||
|
@ -274,11 +269,6 @@ class CheckboxConfigurable(
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
fun ColoredConfigurable(serializedName: String) = CheckboxConfigurable(serializedName, ZigBrainsBundle.message("exec.option.label.colored-terminal"), true)
|
|
||||||
|
|
||||||
fun DirenvConfigurable(serializedName: String, project: Project) =
|
|
||||||
CheckboxConfigurable(serializedName, ZigBrainsBundle.message("exec.option.label.direnv"), project.zigProjectSettings.state.direnv)
|
|
||||||
|
|
||||||
class OptimizationConfigurable(
|
class OptimizationConfigurable(
|
||||||
@Transient private val serializedName: String,
|
@Transient private val serializedName: String,
|
||||||
var level: OptimizationLevel = OptimizationLevel.Debug,
|
var level: OptimizationLevel = OptimizationLevel.Debug,
|
||||||
|
@ -340,14 +330,18 @@ class ArgsConfigurable(
|
||||||
@Transient private val serializedName: String,
|
@Transient private val serializedName: String,
|
||||||
@Transient @Nls private val guiName: String
|
@Transient @Nls private val guiName: String
|
||||||
) : ZigConfigurable<ArgsConfigurable>, Cloneable {
|
) : ZigConfigurable<ArgsConfigurable>, Cloneable {
|
||||||
var args: List<String> = emptyList()
|
var args: String = ""
|
||||||
|
|
||||||
override fun readExternal(element: Element) {
|
override fun readExternal(element: Element) {
|
||||||
args = element.readStrings(serializedName) ?: return
|
args = element.readString(serializedName) ?: element.readStrings(serializedName)?.joinToString(separator = " ") { if (it.contains(' ')) "\"$it\"" else it } ?: ""
|
||||||
|
}
|
||||||
|
|
||||||
|
fun argsSplit(): List<String> {
|
||||||
|
return translateCommandline(args)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun writeExternal(element: Element) {
|
override fun writeExternal(element: Element) {
|
||||||
element.writeStrings(serializedName, args)
|
element.writeString(serializedName, args)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun createEditor(): ZigConfigModule<ArgsConfigurable> {
|
override fun createEditor(): ZigConfigModule<ArgsConfigurable> {
|
||||||
|
@ -369,12 +363,12 @@ class ArgsConfigurable(
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun apply(configurable: ArgsConfigurable): Boolean {
|
override fun apply(configurable: ArgsConfigurable): Boolean {
|
||||||
configurable.args = translateCommandline(argsField.text)
|
configurable.args = argsField.text ?: ""
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun reset(configurable: ArgsConfigurable) {
|
override fun reset(configurable: ArgsConfigurable) {
|
||||||
argsField.text = configurable.args.joinToString(separator = " ")
|
argsField.text = configurable.args
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun construct(p: Panel): Unit = with(p) {
|
override fun construct(p: Panel): Unit = with(p) {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -41,7 +41,7 @@ abstract class ZigConfigProducer<T: ZigExecConfig<T>>: LazyRunConfigurationProdu
|
||||||
val psiFile = element.containingFile as? ZigFile ?: return false
|
val psiFile = element.containingFile as? ZigFile ?: return false
|
||||||
val theFile = psiFile.virtualFile ?: return false
|
val theFile = psiFile.virtualFile ?: return false
|
||||||
val filePath = theFile.toNioPathOrNull() ?: return false
|
val filePath = theFile.toNioPathOrNull() ?: return false
|
||||||
return setupConfigurationFromContext(configuration, element, filePath, theFile)
|
return setupConfigurationFromContext(configuration, element, psiFile, filePath, theFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isConfigurationFromContext(configuration: T, context: ConfigurationContext): Boolean {
|
override fun isConfigurationFromContext(configuration: T, context: ConfigurationContext): Boolean {
|
||||||
|
@ -49,7 +49,7 @@ abstract class ZigConfigProducer<T: ZigExecConfig<T>>: LazyRunConfigurationProdu
|
||||||
val psiFile = element.containingFile as? ZigFile ?: return false
|
val psiFile = element.containingFile as? ZigFile ?: return false
|
||||||
val theFile = psiFile.virtualFile ?: return false
|
val theFile = psiFile.virtualFile ?: return false
|
||||||
val filePath = theFile.toNioPathOrNull() ?: return false
|
val filePath = theFile.toNioPathOrNull() ?: return false
|
||||||
return isConfigurationFromContext(configuration, element, filePath, theFile)
|
return isConfigurationFromContext(configuration, element, psiFile, filePath, theFile)
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
|
@ -78,7 +78,7 @@ abstract class ZigConfigProducer<T: ZigExecConfig<T>>: LazyRunConfigurationProdu
|
||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
protected abstract fun setupConfigurationFromContext(configuration: T, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean
|
protected abstract fun setupConfigurationFromContext(configuration: T, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean
|
||||||
protected abstract fun isConfigurationFromContext(configuration: T, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean
|
protected abstract fun isConfigurationFromContext(configuration: T, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean
|
||||||
abstract override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean
|
abstract override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -22,9 +22,7 @@
|
||||||
|
|
||||||
package com.falsepattern.zigbrains.project.execution.base
|
package com.falsepattern.zigbrains.project.execution.base
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
import com.falsepattern.zigbrains.direnv.DirenvService
|
||||||
import com.falsepattern.zigbrains.direnv.DirenvCmd
|
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
|
||||||
import com.intellij.execution.ExecutionException
|
import com.intellij.execution.ExecutionException
|
||||||
import com.intellij.execution.Executor
|
import com.intellij.execution.Executor
|
||||||
import com.intellij.execution.configurations.ConfigurationFactory
|
import com.intellij.execution.configurations.ConfigurationFactory
|
||||||
|
@ -43,10 +41,6 @@ import org.jetbrains.annotations.Nls
|
||||||
abstract class ZigExecConfig<T: ZigExecConfig<T>>(project: Project, factory: ConfigurationFactory, @Nls name: String): LocatableConfigurationBase<ZigProfileState<T>>(project, factory, name) {
|
abstract class ZigExecConfig<T: ZigExecConfig<T>>(project: Project, factory: ConfigurationFactory, @Nls name: String): LocatableConfigurationBase<ZigProfileState<T>>(project, factory, name) {
|
||||||
var workingDirectory = WorkDirectoryConfigurable("workingDirectory").apply { path = project.guessProjectDir()?.toNioPathOrNull() }
|
var workingDirectory = WorkDirectoryConfigurable("workingDirectory").apply { path = project.guessProjectDir()?.toNioPathOrNull() }
|
||||||
private set
|
private set
|
||||||
var pty = CheckboxConfigurable("pty", ZigBrainsBundle.message("exec.option.label.emulate-terminal"), false)
|
|
||||||
private set
|
|
||||||
var direnv = DirenvConfigurable("direnv", project)
|
|
||||||
private set
|
|
||||||
|
|
||||||
abstract val suggestedName: @ActionText String
|
abstract val suggestedName: @ActionText String
|
||||||
@Throws(ExecutionException::class)
|
@Throws(ExecutionException::class)
|
||||||
|
@ -69,24 +63,19 @@ abstract class ZigExecConfig<T: ZigExecConfig<T>>(project: Project, factory: Con
|
||||||
|
|
||||||
|
|
||||||
suspend fun patchCommandLine(commandLine: GeneralCommandLine): GeneralCommandLine {
|
suspend fun patchCommandLine(commandLine: GeneralCommandLine): GeneralCommandLine {
|
||||||
if (direnv.value) {
|
val direnv = DirenvService.getInstance(project)
|
||||||
commandLine.withEnvironment(DirenvCmd.importDirenv(project).env)
|
if (direnv.isEnabled.isEnabled(project)) {
|
||||||
|
commandLine.withEnvironment(direnv.import().env)
|
||||||
}
|
}
|
||||||
return commandLine
|
return commandLine
|
||||||
}
|
}
|
||||||
|
|
||||||
fun emulateTerminal(): Boolean {
|
|
||||||
return pty.value
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun clone(): T {
|
override fun clone(): T {
|
||||||
val myClone = super.clone() as ZigExecConfig<*>
|
val myClone = super.clone() as ZigExecConfig<*>
|
||||||
myClone.workingDirectory = workingDirectory.clone()
|
myClone.workingDirectory = workingDirectory.clone()
|
||||||
myClone.pty = pty.clone()
|
|
||||||
myClone.direnv = direnv.clone()
|
|
||||||
@Suppress("UNCHECKED_CAST")
|
@Suppress("UNCHECKED_CAST")
|
||||||
return myClone as T
|
return myClone as T
|
||||||
}
|
}
|
||||||
|
|
||||||
open fun getConfigurables(): List<ZigConfigurable<*>> = listOf(workingDirectory, pty, direnv)
|
open fun getConfigurables(): List<ZigConfigurable<*>> = listOf(workingDirectory)
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -23,18 +23,16 @@
|
||||||
package com.falsepattern.zigbrains.project.execution.base
|
package com.falsepattern.zigbrains.project.execution.base
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||||
import com.falsepattern.zigbrains.project.run.ZigProcessHandler
|
import com.falsepattern.zigbrains.project.execution.ZigConsoleBuilder
|
||||||
import com.falsepattern.zigbrains.project.settings.zigProjectSettings
|
import com.falsepattern.zigbrains.project.toolchain.ZigToolchainService
|
||||||
import com.falsepattern.zigbrains.project.toolchain.AbstractZigToolchain
|
import com.falsepattern.zigbrains.project.toolchain.base.ZigToolchain
|
||||||
|
import com.falsepattern.zigbrains.shared.cli.startIPCAwareProcess
|
||||||
import com.falsepattern.zigbrains.shared.coroutine.runModalOrBlocking
|
import com.falsepattern.zigbrains.shared.coroutine.runModalOrBlocking
|
||||||
import com.intellij.build.BuildTextConsoleView
|
|
||||||
import com.intellij.execution.DefaultExecutionResult
|
|
||||||
import com.intellij.execution.ExecutionException
|
import com.intellij.execution.ExecutionException
|
||||||
import com.intellij.execution.configurations.CommandLineState
|
import com.intellij.execution.configurations.CommandLineState
|
||||||
import com.intellij.execution.configurations.GeneralCommandLine
|
import com.intellij.execution.configurations.GeneralCommandLine
|
||||||
import com.intellij.execution.configurations.PtyCommandLine
|
import com.intellij.execution.configurations.PtyCommandLine
|
||||||
import com.intellij.execution.process.ProcessHandler
|
import com.intellij.execution.process.ProcessHandler
|
||||||
import com.intellij.execution.process.ProcessTerminatedListener
|
|
||||||
import com.intellij.execution.runners.ExecutionEnvironment
|
import com.intellij.execution.runners.ExecutionEnvironment
|
||||||
import com.intellij.platform.ide.progress.ModalTaskOwner
|
import com.intellij.platform.ide.progress.ModalTaskOwner
|
||||||
import kotlin.io.path.pathString
|
import kotlin.io.path.pathString
|
||||||
|
@ -44,6 +42,10 @@ abstract class ZigProfileState<T: ZigExecConfig<T>> (
|
||||||
val configuration: T
|
val configuration: T
|
||||||
): CommandLineState(environment) {
|
): CommandLineState(environment) {
|
||||||
|
|
||||||
|
init {
|
||||||
|
consoleBuilder = ZigConsoleBuilder(environment.project, true)
|
||||||
|
}
|
||||||
|
|
||||||
@Throws(ExecutionException::class)
|
@Throws(ExecutionException::class)
|
||||||
override fun startProcess(): ProcessHandler {
|
override fun startProcess(): ProcessHandler {
|
||||||
return runModalOrBlocking({ModalTaskOwner.project(environment.project)}, {"ZigProfileState.startProcess"}) {
|
return runModalOrBlocking({ModalTaskOwner.project(environment.project)}, {"ZigProfileState.startProcess"}) {
|
||||||
|
@ -53,37 +55,20 @@ abstract class ZigProfileState<T: ZigExecConfig<T>> (
|
||||||
|
|
||||||
@Throws(ExecutionException::class)
|
@Throws(ExecutionException::class)
|
||||||
suspend fun startProcessSuspend(): ProcessHandler {
|
suspend fun startProcessSuspend(): ProcessHandler {
|
||||||
val toolchain = environment.project.zigProjectSettings.state.toolchain ?: throw ExecutionException(ZigBrainsBundle.message("exception.zig-profile-state.start-process.no-toolchain"))
|
val toolchain = ZigToolchainService.getInstance(environment.project).toolchain ?: throw ExecutionException(ZigBrainsBundle.message("exception.zig-profile-state.start-process.no-toolchain"))
|
||||||
return ZigProcessHandler(getCommandLine(toolchain, false))
|
return getCommandLine(toolchain, false).startIPCAwareProcess(environment.project, emulateTerminal = true)
|
||||||
}
|
}
|
||||||
|
|
||||||
@Throws(ExecutionException::class)
|
@Throws(ExecutionException::class)
|
||||||
open suspend fun getCommandLine(toolchain: AbstractZigToolchain, debug: Boolean): GeneralCommandLine {
|
open suspend fun getCommandLine(toolchain: ZigToolchain, debug: Boolean): GeneralCommandLine {
|
||||||
val workingDir = configuration.workingDirectory
|
val workingDir = configuration.workingDirectory
|
||||||
val zigExePath = toolchain.zig.path()
|
val zigExePath = toolchain.zig.path()
|
||||||
|
|
||||||
// TODO remove this check once JetBrains implements colored terminal in the debugger
|
val cli = PtyCommandLine().withConsoleMode(false)
|
||||||
// https://youtrack.jetbrains.com/issue/CPP-11622/ANSI-color-codes-not-honored-in-Debug-Run-Configuration-output-window
|
cli.withExePath(zigExePath.pathString)
|
||||||
val cli = if (configuration.emulateTerminal() && !debug) PtyCommandLine() else GeneralCommandLine()
|
|
||||||
cli.exePath = zigExePath.pathString
|
|
||||||
workingDir.path?.let { cli.withWorkingDirectory(it) }
|
workingDir.path?.let { cli.withWorkingDirectory(it) }
|
||||||
cli.charset = Charsets.UTF_8
|
cli.withCharset(Charsets.UTF_8)
|
||||||
cli.addParameters(configuration.buildCommandLineArgs(debug))
|
cli.addParameters(configuration.buildCommandLineArgs(debug))
|
||||||
return configuration.patchCommandLine(cli)
|
return configuration.patchCommandLine(cli)
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(ExecutionException::class)
|
|
||||||
fun executeCommandLine(commandLine: GeneralCommandLine, environment: ExecutionEnvironment): DefaultExecutionResult {
|
|
||||||
val handler = startProcess(commandLine)
|
|
||||||
val console = BuildTextConsoleView(environment.project, false, emptyList())
|
|
||||||
console.attachToProcess(handler)
|
|
||||||
return DefaultExecutionResult(console, handler)
|
|
||||||
}
|
|
||||||
|
|
||||||
@Throws(ExecutionException::class)
|
|
||||||
fun startProcess(commandLine: GeneralCommandLine): ProcessHandler {
|
|
||||||
val handler = ZigProcessHandler(commandLine)
|
|
||||||
ProcessTerminatedListener.attach(handler)
|
|
||||||
return handler
|
|
||||||
}
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -34,9 +34,9 @@ abstract class ZigTopLevelLineMarker: RunLineMarkerContributor() {
|
||||||
private fun getParentIfTopLevel(element: PsiElement): PsiElement? {
|
private fun getParentIfTopLevel(element: PsiElement): PsiElement? {
|
||||||
var parent = getDeclaration(element)
|
var parent = getDeclaration(element)
|
||||||
|
|
||||||
var nestingLevel = 0;
|
var nestingLevel = 0
|
||||||
while (parent != null && parent !is PsiFile) {
|
while (parent != null && parent !is PsiFile) {
|
||||||
if (parent.elementType == ZigTypes.CONTAINER_DECLARATIONS) {
|
if (parent.elementType == ZigTypes.CONTAINER_DECLARATION) {
|
||||||
if (nestingLevel != 0)
|
if (nestingLevel != 0)
|
||||||
return null
|
return null
|
||||||
nestingLevel++
|
nestingLevel++
|
||||||
|
@ -54,7 +54,7 @@ abstract class ZigTopLevelLineMarker: RunLineMarkerContributor() {
|
||||||
|
|
||||||
override fun getInfo(element: PsiElement): Info? {
|
override fun getInfo(element: PsiElement): Info? {
|
||||||
if (!elementMatches(element))
|
if (!elementMatches(element))
|
||||||
return null;
|
return null
|
||||||
val actions = ExecutorAction.getActions(0)
|
val actions = ExecutorAction.getActions(0)
|
||||||
return Info(getIcon(element), actions, null)
|
return Info(getIcon(element), actions, null)
|
||||||
}
|
}
|
||||||
|
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* This file is part of ZigBrains.
|
||||||
|
*
|
||||||
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
|
* All Rights Reserved
|
||||||
|
*
|
||||||
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
* in all copies or substantial portions of the Software.
|
||||||
|
*
|
||||||
|
* ZigBrains is free software: you can redistribute it and/or modify
|
||||||
|
* it under the terms of the GNU Lesser General Public License as published by
|
||||||
|
* the Free Software Foundation, only version 3 of the License.
|
||||||
|
*
|
||||||
|
* ZigBrains is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU Lesser General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU Lesser General Public License
|
||||||
|
* along with ZigBrains. If not, see <https://www.gnu.org/licenses/>.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package com.falsepattern.zigbrains.project.execution.base
|
||||||
|
|
||||||
|
import com.falsepattern.zigbrains.zig.psi.ZigContainerMembers
|
||||||
|
import com.falsepattern.zigbrains.zig.psi.ZigFile
|
||||||
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
import com.intellij.openapi.vfs.isFile
|
||||||
|
import com.intellij.psi.util.childrenOfType
|
||||||
|
|
||||||
|
fun ZigFile.hasMainFunction(): Boolean {
|
||||||
|
val members = childrenOfType<ZigContainerMembers>().firstOrNull() ?: return false
|
||||||
|
return members.containerDeclarationList.any { it.decl?.fnProto?.identifier?.textMatches("main") == true }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun ZigFile.hasTests(): Boolean {
|
||||||
|
val members = childrenOfType<ZigContainerMembers>().firstOrNull() ?: return false
|
||||||
|
return members.containerDeclarationList.any { it.testDecl != null }
|
||||||
|
}
|
||||||
|
|
||||||
|
fun VirtualFile.findBuildZig(): VirtualFile? {
|
||||||
|
var parent = this.parent
|
||||||
|
while (parent != null) {
|
||||||
|
parent.children.forEach {
|
||||||
|
if (it.isFile && it.name == "build.zig") {
|
||||||
|
return it
|
||||||
|
}
|
||||||
|
}
|
||||||
|
parent = parent.parent
|
||||||
|
}
|
||||||
|
return null
|
||||||
|
}
|
||||||
|
|
||||||
|
fun VirtualFile.isBuildZig(): Boolean {
|
||||||
|
return name == "build.zig"
|
||||||
|
}
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -24,11 +24,16 @@ package com.falsepattern.zigbrains.project.execution.build
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
|
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
|
||||||
|
import com.falsepattern.zigbrains.project.execution.base.findBuildZig
|
||||||
|
import com.falsepattern.zigbrains.project.execution.base.isBuildZig
|
||||||
import com.falsepattern.zigbrains.project.execution.firstConfigFactory
|
import com.falsepattern.zigbrains.project.execution.firstConfigFactory
|
||||||
|
import com.falsepattern.zigbrains.zig.psi.ZigFile
|
||||||
|
import com.falsepattern.zigbrains.zig.psi.ZigTypes
|
||||||
import com.intellij.execution.actions.ConfigurationFromContext
|
import com.intellij.execution.actions.ConfigurationFromContext
|
||||||
import com.intellij.execution.configurations.ConfigurationFactory
|
import com.intellij.execution.configurations.ConfigurationFactory
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
import com.intellij.psi.PsiElement
|
import com.intellij.psi.PsiElement
|
||||||
|
import com.intellij.psi.util.elementType
|
||||||
import java.nio.file.Path
|
import java.nio.file.Path
|
||||||
|
|
||||||
class ZigConfigProducerBuild: ZigConfigProducer<ZigExecConfigBuild>() {
|
class ZigConfigProducerBuild: ZigConfigProducer<ZigExecConfigBuild>() {
|
||||||
|
@ -36,21 +41,43 @@ class ZigConfigProducerBuild: ZigConfigProducer<ZigExecConfigBuild>() {
|
||||||
return firstConfigFactory<ZigConfigTypeBuild>()
|
return firstConfigFactory<ZigConfigTypeBuild>()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setupConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean {
|
override fun setupConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||||
if (LINE_MARKER.elementMatches(element)) {
|
if (theFile.isBuildZig()) {
|
||||||
configuration.name = ZigBrainsBundle.message("configuration.build.marker-name")
|
configuration.name = ZigBrainsBundle.message("configuration.build.marker-run")
|
||||||
|
configuration.buildSteps.args = "run"
|
||||||
|
configuration.debugBuildSteps.args = "install"
|
||||||
|
return true
|
||||||
|
}
|
||||||
|
val buildZig = theFile.findBuildZig() ?: return false
|
||||||
|
configuration.workingDirectory.path = buildZig.parent.toNioPath()
|
||||||
|
if (element.elementType == ZigTypes.KEYWORD_TEST) {
|
||||||
|
configuration.name = ZigBrainsBundle.message("configuration.build.marker-test")
|
||||||
|
configuration.buildSteps.args = "test"
|
||||||
|
configuration.debugBuildSteps.args = "install_test"
|
||||||
|
return true
|
||||||
|
} else {
|
||||||
|
configuration.name = ZigBrainsBundle.message("configuration.build.marker-run")
|
||||||
|
configuration.buildSteps.args = "run"
|
||||||
|
configuration.debugBuildSteps.args = "install"
|
||||||
return true
|
return true
|
||||||
}
|
}
|
||||||
return false
|
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean {
|
override fun isConfigurationFromContext(configuration: ZigExecConfigBuild, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||||
return filePath.parent == (configuration.workingDirectory.path ?: return false)
|
val dir = configuration.workingDirectory.path ?: return false
|
||||||
|
if (theFile.isBuildZig()) {
|
||||||
|
return filePath.parent == dir
|
||||||
|
} else {
|
||||||
|
if (element.elementType == ZigTypes.KEYWORD_TEST) {
|
||||||
|
if (configuration.buildSteps.args != "test")
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
val buildZig = theFile.findBuildZig() ?: return false
|
||||||
|
return buildZig.parent.toNioPath() == dir
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
|
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
|
||||||
return self.configurationType is ZigConfigTypeBuild
|
return self.configurationType is ZigConfigTypeBuild
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val LINE_MARKER = ZigLineMarkerBuild()
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -33,7 +33,7 @@ class ZigConfigTypeBuild : ConfigurationTypeBase(
|
||||||
IDENTIFIER,
|
IDENTIFIER,
|
||||||
ZigBrainsBundle.message("configuration.build.name"),
|
ZigBrainsBundle.message("configuration.build.name"),
|
||||||
ZigBrainsBundle.message("configuration.build.description"),
|
ZigBrainsBundle.message("configuration.build.description"),
|
||||||
Icons.ZIG
|
Icons.Zig
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
addFactory(ConfigFactoryRun(this))
|
addFactory(ConfigFactoryRun(this))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -25,7 +25,6 @@ package com.falsepattern.zigbrains.project.execution.build
|
||||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||||
import com.falsepattern.zigbrains.project.execution.base.*
|
import com.falsepattern.zigbrains.project.execution.base.*
|
||||||
import com.falsepattern.zigbrains.shared.ZBFeatures
|
import com.falsepattern.zigbrains.shared.ZBFeatures
|
||||||
import com.falsepattern.zigbrains.shared.cli.coloredCliFlags
|
|
||||||
import com.intellij.execution.ExecutionException
|
import com.intellij.execution.ExecutionException
|
||||||
import com.intellij.execution.Executor
|
import com.intellij.execution.Executor
|
||||||
import com.intellij.execution.configurations.ConfigurationFactory
|
import com.intellij.execution.configurations.ConfigurationFactory
|
||||||
|
@ -37,7 +36,9 @@ class ZigExecConfigBuild(project: Project, factory: ConfigurationFactory): ZigEx
|
||||||
private set
|
private set
|
||||||
var extraArgs = ArgsConfigurable("compilerArgs", ZigBrainsBundle.message("exec.option.label.build.args"))
|
var extraArgs = ArgsConfigurable("compilerArgs", ZigBrainsBundle.message("exec.option.label.build.args"))
|
||||||
private set
|
private set
|
||||||
var colored = ColoredConfigurable("colored")
|
var debugBuildSteps = ArgsConfigurable("debugBuildSteps", ZigBrainsBundle.message("exec.option.label.build.steps-debug"))
|
||||||
|
private set
|
||||||
|
var debugExtraArgs = ArgsConfigurable("debugCompilerArgs", ZigBrainsBundle.message("exec.option.label.build.args-debug"))
|
||||||
private set
|
private set
|
||||||
var exePath = FilePathConfigurable("exePath", ZigBrainsBundle.message("exec.option.label.build.exe-path-debug"))
|
var exePath = FilePathConfigurable("exePath", ZigBrainsBundle.message("exec.option.label.build.exe-path-debug"))
|
||||||
private set
|
private set
|
||||||
|
@ -48,22 +49,9 @@ class ZigExecConfigBuild(project: Project, factory: ConfigurationFactory): ZigEx
|
||||||
override suspend fun buildCommandLineArgs(debug: Boolean): List<String> {
|
override suspend fun buildCommandLineArgs(debug: Boolean): List<String> {
|
||||||
val result = ArrayList<String>()
|
val result = ArrayList<String>()
|
||||||
result.add("build")
|
result.add("build")
|
||||||
val steps = buildSteps.args
|
val steps = if (debug) debugBuildSteps.argsSplit() else buildSteps.argsSplit()
|
||||||
if (debug) {
|
|
||||||
val truncatedSteps = ArrayList<String>()
|
|
||||||
for (step in steps) {
|
|
||||||
if (step == "run")
|
|
||||||
continue
|
|
||||||
|
|
||||||
if (step == "test")
|
|
||||||
throw ExecutionException(ZigBrainsBundle.message("exception.zig-build.debug.test-not-supported"))
|
|
||||||
|
|
||||||
truncatedSteps.add(step)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
result.addAll(steps)
|
result.addAll(steps)
|
||||||
result.addAll(coloredCliFlags(colored.value, debug))
|
result.addAll(if (debug) debugExtraArgs.argsSplit() else extraArgs.argsSplit())
|
||||||
result.addAll(extraArgs.args)
|
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -74,18 +62,17 @@ class ZigExecConfigBuild(project: Project, factory: ConfigurationFactory): ZigEx
|
||||||
val clone = super.clone()
|
val clone = super.clone()
|
||||||
clone.buildSteps = buildSteps.clone()
|
clone.buildSteps = buildSteps.clone()
|
||||||
clone.exeArgs = exeArgs.clone()
|
clone.exeArgs = exeArgs.clone()
|
||||||
clone.colored = colored.clone()
|
|
||||||
clone.exePath = exePath.clone()
|
clone.exePath = exePath.clone()
|
||||||
clone.exeArgs = exeArgs.clone()
|
clone.exeArgs = exeArgs.clone()
|
||||||
return clone
|
return clone
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getConfigurables(): List<ZigConfigurable<*>> {
|
override fun getConfigurables(): List<ZigConfigurable<*>> {
|
||||||
val baseCfg = super.getConfigurables() + listOf(buildSteps, extraArgs, colored)
|
val baseCfg = super.getConfigurables() + listOf(buildSteps, extraArgs)
|
||||||
if (ZBFeatures.debug()) {
|
return if (ZBFeatures.debug()) {
|
||||||
return baseCfg + listOf(exePath, exeArgs)
|
baseCfg + listOf(debugBuildSteps, debugExtraArgs, exePath, exeArgs)
|
||||||
} else {
|
} else {
|
||||||
return baseCfg
|
baseCfg
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -25,5 +25,4 @@ package com.falsepattern.zigbrains.project.execution.build
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
import com.intellij.execution.runners.ExecutionEnvironment
|
import com.intellij.execution.runners.ExecutionEnvironment
|
||||||
|
|
||||||
class ZigProfileStateBuild(environment: ExecutionEnvironment, configuration: ZigExecConfigBuild) : ZigProfileState<ZigExecConfigBuild>(environment, configuration) {
|
class ZigProfileStateBuild(environment: ExecutionEnvironment, configuration: ZigExecConfigBuild) : ZigProfileState<ZigExecConfigBuild>(environment, configuration)
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -23,7 +23,10 @@
|
||||||
package com.falsepattern.zigbrains.project.execution.run
|
package com.falsepattern.zigbrains.project.execution.run
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
|
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
|
||||||
|
import com.falsepattern.zigbrains.project.execution.base.findBuildZig
|
||||||
|
import com.falsepattern.zigbrains.project.execution.base.hasMainFunction
|
||||||
import com.falsepattern.zigbrains.project.execution.firstConfigFactory
|
import com.falsepattern.zigbrains.project.execution.firstConfigFactory
|
||||||
|
import com.falsepattern.zigbrains.zig.psi.ZigFile
|
||||||
import com.intellij.execution.actions.ConfigurationFromContext
|
import com.intellij.execution.actions.ConfigurationFromContext
|
||||||
import com.intellij.execution.configurations.ConfigurationFactory
|
import com.intellij.execution.configurations.ConfigurationFactory
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
@ -35,16 +38,19 @@ class ZigConfigProducerRun: ZigConfigProducer<ZigExecConfigRun>() {
|
||||||
return firstConfigFactory<ZigConfigTypeRun>()
|
return firstConfigFactory<ZigConfigTypeRun>()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setupConfigurationFromContext(configuration: ZigExecConfigRun, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean {
|
override fun setupConfigurationFromContext(configuration: ZigExecConfigRun, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||||
if (LINE_MARKER.elementMatches(element)) {
|
if (!psiFile.hasMainFunction()) {
|
||||||
configuration.filePath.path = filePath
|
return false
|
||||||
configuration.name = theFile.presentableName
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return false
|
if (theFile.findBuildZig() != null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
configuration.filePath.path = filePath
|
||||||
|
configuration.name = theFile.presentableName
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isConfigurationFromContext(configuration: ZigExecConfigRun, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean {
|
override fun isConfigurationFromContext(configuration: ZigExecConfigRun, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||||
return filePath == configuration.filePath.path
|
return filePath == configuration.filePath.path
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -52,5 +58,3 @@ class ZigConfigProducerRun: ZigConfigProducer<ZigExecConfigRun>() {
|
||||||
return self.configurationType is ZigConfigTypeRun
|
return self.configurationType is ZigConfigTypeRun
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val LINE_MARKER = ZigLineMarkerRun()
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -33,7 +33,7 @@ class ZigConfigTypeRun : ConfigurationTypeBase(
|
||||||
IDENTIFIER,
|
IDENTIFIER,
|
||||||
ZigBrainsBundle.message("configuration.run.name"),
|
ZigBrainsBundle.message("configuration.run.name"),
|
||||||
ZigBrainsBundle.message("configuration.run.description"),
|
ZigBrainsBundle.message("configuration.run.description"),
|
||||||
Icons.ZIG
|
Icons.Zig
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
addFactory(ConfigFactoryRun(this))
|
addFactory(ConfigFactoryRun(this))
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -24,7 +24,6 @@ package com.falsepattern.zigbrains.project.execution.run
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||||
import com.falsepattern.zigbrains.project.execution.base.*
|
import com.falsepattern.zigbrains.project.execution.base.*
|
||||||
import com.falsepattern.zigbrains.shared.cli.coloredCliFlags
|
|
||||||
import com.intellij.execution.ExecutionException
|
import com.intellij.execution.ExecutionException
|
||||||
import com.intellij.execution.Executor
|
import com.intellij.execution.Executor
|
||||||
import com.intellij.execution.configurations.ConfigurationFactory
|
import com.intellij.execution.configurations.ConfigurationFactory
|
||||||
|
@ -35,8 +34,6 @@ import kotlin.io.path.pathString
|
||||||
class ZigExecConfigRun(project: Project, factory: ConfigurationFactory): ZigExecConfig<ZigExecConfigRun>(project, factory, ZigBrainsBundle.message("exec.type.run.label")) {
|
class ZigExecConfigRun(project: Project, factory: ConfigurationFactory): ZigExecConfig<ZigExecConfigRun>(project, factory, ZigBrainsBundle.message("exec.type.run.label")) {
|
||||||
var filePath = FilePathConfigurable("filePath", ZigBrainsBundle.message("exec.option.label.file-path"))
|
var filePath = FilePathConfigurable("filePath", ZigBrainsBundle.message("exec.option.label.file-path"))
|
||||||
private set
|
private set
|
||||||
var colored = ColoredConfigurable("colored")
|
|
||||||
private set
|
|
||||||
var optimization = OptimizationConfigurable("optimization")
|
var optimization = OptimizationConfigurable("optimization")
|
||||||
private set
|
private set
|
||||||
var compilerArgs = ArgsConfigurable("compilerArgs", ZigBrainsBundle.message("exec.option.label.compiler-args"))
|
var compilerArgs = ArgsConfigurable("compilerArgs", ZigBrainsBundle.message("exec.option.label.compiler-args"))
|
||||||
|
@ -47,15 +44,14 @@ class ZigExecConfigRun(project: Project, factory: ConfigurationFactory): ZigExec
|
||||||
override suspend fun buildCommandLineArgs(debug: Boolean): List<String> {
|
override suspend fun buildCommandLineArgs(debug: Boolean): List<String> {
|
||||||
val result = ArrayList<String>()
|
val result = ArrayList<String>()
|
||||||
result.add(if (debug) "build-exe" else "run")
|
result.add(if (debug) "build-exe" else "run")
|
||||||
result.addAll(coloredCliFlags(colored.value, debug))
|
|
||||||
result.add(filePath.path?.pathString ?: throw ExecutionException(ZigBrainsBundle.message("exception.zig.empty-file-path")))
|
result.add(filePath.path?.pathString ?: throw ExecutionException(ZigBrainsBundle.message("exception.zig.empty-file-path")))
|
||||||
if (!debug || optimization.forced) {
|
if (!debug || optimization.forced) {
|
||||||
result.addAll(listOf("-O", optimization.level.name))
|
result.addAll(listOf("-O", optimization.level.name))
|
||||||
}
|
}
|
||||||
result.addAll(compilerArgs.args)
|
result.addAll(compilerArgs.argsSplit())
|
||||||
if (!debug) {
|
if (!debug) {
|
||||||
result.add("--")
|
result.add("--")
|
||||||
result.addAll(exeArgs.args)
|
result.addAll(exeArgs.argsSplit())
|
||||||
}
|
}
|
||||||
return result
|
return result
|
||||||
}
|
}
|
||||||
|
@ -66,7 +62,6 @@ class ZigExecConfigRun(project: Project, factory: ConfigurationFactory): ZigExec
|
||||||
override fun clone(): ZigExecConfigRun {
|
override fun clone(): ZigExecConfigRun {
|
||||||
val clone = super.clone()
|
val clone = super.clone()
|
||||||
clone.filePath = filePath.clone()
|
clone.filePath = filePath.clone()
|
||||||
clone.colored = colored.clone()
|
|
||||||
clone.compilerArgs = compilerArgs.clone()
|
clone.compilerArgs = compilerArgs.clone()
|
||||||
clone.optimization = optimization.clone()
|
clone.optimization = optimization.clone()
|
||||||
clone.exeArgs = exeArgs.clone()
|
clone.exeArgs = exeArgs.clone()
|
||||||
|
@ -74,7 +69,7 @@ class ZigExecConfigRun(project: Project, factory: ConfigurationFactory): ZigExec
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getConfigurables(): List<ZigConfigurable<*>> {
|
override fun getConfigurables(): List<ZigConfigurable<*>> {
|
||||||
return super.getConfigurables() + listOf(filePath, optimization, colored, compilerArgs, exeArgs)
|
return super.getConfigurables() + listOf(filePath, optimization, compilerArgs, exeArgs)
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun getState(executor: Executor, environment: ExecutionEnvironment): ZigProfileState<ZigExecConfigRun> {
|
override fun getState(executor: Executor, environment: ExecutionEnvironment): ZigProfileState<ZigExecConfigRun> {
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -25,5 +25,4 @@ package com.falsepattern.zigbrains.project.execution.run
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
import com.falsepattern.zigbrains.project.execution.base.ZigProfileState
|
||||||
import com.intellij.execution.runners.ExecutionEnvironment
|
import com.intellij.execution.runners.ExecutionEnvironment
|
||||||
|
|
||||||
class ZigProfileStateRun(environment: ExecutionEnvironment, configuration: ZigExecConfigRun) : ZigProfileState<ZigExecConfigRun>(environment, configuration) {
|
class ZigProfileStateRun(environment: ExecutionEnvironment, configuration: ZigExecConfigRun) : ZigProfileState<ZigExecConfigRun>(environment, configuration)
|
||||||
}
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -24,7 +24,10 @@ package com.falsepattern.zigbrains.project.execution.test
|
||||||
|
|
||||||
import com.falsepattern.zigbrains.ZigBrainsBundle
|
import com.falsepattern.zigbrains.ZigBrainsBundle
|
||||||
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
|
import com.falsepattern.zigbrains.project.execution.base.ZigConfigProducer
|
||||||
|
import com.falsepattern.zigbrains.project.execution.base.findBuildZig
|
||||||
|
import com.falsepattern.zigbrains.project.execution.base.hasTests
|
||||||
import com.falsepattern.zigbrains.project.execution.firstConfigFactory
|
import com.falsepattern.zigbrains.project.execution.firstConfigFactory
|
||||||
|
import com.falsepattern.zigbrains.zig.psi.ZigFile
|
||||||
import com.intellij.execution.actions.ConfigurationFromContext
|
import com.intellij.execution.actions.ConfigurationFromContext
|
||||||
import com.intellij.execution.configurations.ConfigurationFactory
|
import com.intellij.execution.configurations.ConfigurationFactory
|
||||||
import com.intellij.openapi.vfs.VirtualFile
|
import com.intellij.openapi.vfs.VirtualFile
|
||||||
|
@ -36,22 +39,23 @@ class ZigConfigProducerTest: ZigConfigProducer<ZigExecConfigTest>() {
|
||||||
return firstConfigFactory<ZigConfigTypeTest>()
|
return firstConfigFactory<ZigConfigTypeTest>()
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun setupConfigurationFromContext(configuration: ZigExecConfigTest, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean {
|
override fun setupConfigurationFromContext(configuration: ZigExecConfigTest, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||||
if (LINE_MARKER.elementMatches(element)) {
|
if (!psiFile.hasTests()) {
|
||||||
configuration.filePath.path = filePath
|
return false
|
||||||
configuration.name = ZigBrainsBundle.message("configuration.test.marker-name", theFile.presentableName)
|
|
||||||
return true
|
|
||||||
}
|
}
|
||||||
return false
|
if (theFile.findBuildZig() != null) {
|
||||||
|
return false
|
||||||
|
}
|
||||||
|
configuration.filePath.path = filePath
|
||||||
|
configuration.name = ZigBrainsBundle.message("configuration.test.marker-name", theFile.presentableName)
|
||||||
|
return true
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun isConfigurationFromContext(configuration: ZigExecConfigTest, element: PsiElement, filePath: Path, theFile: VirtualFile): Boolean {
|
override fun isConfigurationFromContext(configuration: ZigExecConfigTest, element: PsiElement, psiFile: ZigFile, filePath: Path, theFile: VirtualFile): Boolean {
|
||||||
return filePath == configuration.filePath.path
|
return filePath == configuration.filePath.path
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
|
override fun shouldReplace(self: ConfigurationFromContext, other: ConfigurationFromContext): Boolean {
|
||||||
return self.configurationType is ZigConfigTypeTest
|
return self.configurationType is ZigConfigTypeTest
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private val LINE_MARKER = ZigLineMarkerTest()
|
|
|
@ -1,7 +1,7 @@
|
||||||
/*
|
/*
|
||||||
* This file is part of ZigBrains.
|
* This file is part of ZigBrains.
|
||||||
*
|
*
|
||||||
* Copyright (C) 2023-2024 FalsePattern
|
* Copyright (C) 2023-2025 FalsePattern
|
||||||
* All Rights Reserved
|
* All Rights Reserved
|
||||||
*
|
*
|
||||||
* The above copyright notice and this permission notice shall be included
|
* The above copyright notice and this permission notice shall be included
|
||||||
|
@ -33,7 +33,7 @@ class ZigConfigTypeTest : ConfigurationTypeBase(
|
||||||
IDENTIFIER,
|
IDENTIFIER,
|
||||||
ZigBrainsBundle.message("configuration.test.name"),
|
ZigBrainsBundle.message("configuration.test.name"),
|
||||||
ZigBrainsBundle.message("configuration.test.description"),
|
ZigBrainsBundle.message("configuration.test.description"),
|
||||||
Icons.ZIG
|
Icons.Zig
|
||||||
) {
|
) {
|
||||||
init {
|
init {
|
||||||
addFactory(ConfigFactoryRun(this))
|
addFactory(ConfigFactoryRun(this))
|
||||||
|
|
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue