548 lines
13 KiB
Markdown
548 lines
13 KiB
Markdown
# Slint LSP Integration Implementation Plan
|
|
|
|
> **For Claude:** REQUIRED SUB-SKILL: Use superpowers:executing-plans to implement this plan task-by-task.
|
|
|
|
**Goal:** Implement complete Slint LSP integration into IntelliJ IDEA with file type system, LSP server configuration, and syntax highlighting.
|
|
|
|
**Architecture:** Use IntelliJ's built-in LSP framework to connect to Slint LSP server. Register .slint file type, configure LSP server descriptor, and add TextMate-based syntax highlighting.
|
|
|
|
**Tech Stack:** Kotlin, IntelliJ Platform SDK, LSP API, TextMate grammar
|
|
|
|
---
|
|
|
|
## Task 1: Create Slint Language Definition
|
|
|
|
**Files:**
|
|
- Create: `src/main/kotlin/me/zhouxi/slint/lang/SlintLanguage.kt`
|
|
|
|
**Step 1: Create SlintLanguage object**
|
|
|
|
Create the file with this content:
|
|
|
|
```kotlin
|
|
package me.zhouxi.slint.lang
|
|
|
|
import com.intellij.lang.Language
|
|
|
|
object SlintLanguage : Language("Slint") {
|
|
override fun getDisplayName(): String = "Slint"
|
|
}
|
|
```
|
|
|
|
**Step 2: Verify compilation**
|
|
|
|
Run: `./gradlew compileKotlin`
|
|
Expected: BUILD SUCCESSFUL
|
|
|
|
**Step 3: Commit**
|
|
|
|
```bash
|
|
git add src/main/kotlin/me/zhouxi/slint/lang/SlintLanguage.kt
|
|
git commit -m "feat: add Slint language definition"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 2: Create Slint File Type
|
|
|
|
**Files:**
|
|
- Create: `src/main/kotlin/me/zhouxi/slint/lang/SlintFileType.kt`
|
|
|
|
**Step 1: Create SlintFileType object**
|
|
|
|
Create the file with this content:
|
|
|
|
```kotlin
|
|
package me.zhouxi.slint.lang
|
|
|
|
import com.intellij.openapi.fileTypes.LanguageFileType
|
|
import me.zhouxi.slint.icons.SlintIcons
|
|
import javax.swing.Icon
|
|
|
|
object SlintFileType : LanguageFileType(SlintLanguage) {
|
|
override fun getName(): String = "Slint"
|
|
|
|
override fun getDescription(): String = "Slint UI file"
|
|
|
|
override fun getDefaultExtension(): String = "slint"
|
|
|
|
override fun getIcon(): Icon = SlintIcons.Primary
|
|
}
|
|
```
|
|
|
|
**Step 2: Verify compilation**
|
|
|
|
Run: `./gradlew compileKotlin`
|
|
Expected: BUILD SUCCESSFUL
|
|
|
|
**Step 3: Commit**
|
|
|
|
```bash
|
|
git add src/main/kotlin/me/zhouxi/slint/lang/SlintFileType.kt
|
|
git commit -m "feat: add Slint file type definition"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 3: Register File Type in plugin.xml
|
|
|
|
**Files:**
|
|
- Modify: `src/main/resources/META-INF/plugin.xml`
|
|
|
|
**Step 1: Add fileType extension**
|
|
|
|
Add this inside the `<extensions defaultExtensionNs="com.intellij">` block:
|
|
|
|
```xml
|
|
<fileType
|
|
name="Slint"
|
|
implementationClass="me.zhouxi.slint.lang.SlintFileType"
|
|
fieldName="INSTANCE"
|
|
language="Slint"
|
|
extensions="slint"/>
|
|
```
|
|
|
|
The complete extensions block should look like:
|
|
|
|
```xml
|
|
<extensions defaultExtensionNs="com.intellij">
|
|
<fileType
|
|
name="Slint"
|
|
implementationClass="me.zhouxi.slint.lang.SlintFileType"
|
|
fieldName="INSTANCE"
|
|
language="Slint"
|
|
extensions="slint"/>
|
|
<platform.lsp.serverSupportProvider implementation="me.zhouxi.slint.lsp.SlintLspServerSupportProvider"/>
|
|
</extensions>
|
|
```
|
|
|
|
**Step 2: Verify plugin configuration**
|
|
|
|
Run: `./gradlew verifyPluginProjectConfiguration`
|
|
Expected: BUILD SUCCESSFUL
|
|
|
|
**Step 3: Commit**
|
|
|
|
```bash
|
|
git add src/main/resources/META-INF/plugin.xml
|
|
git commit -m "feat: register Slint file type in plugin.xml"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 4: Update LSP Server Descriptor
|
|
|
|
**Files:**
|
|
- Modify: `src/main/kotlin/me/zhouxi/slint/lsp/SlintLspServerSupportProvider.kt`
|
|
|
|
**Step 1: Add import for SlintFileType**
|
|
|
|
Add this import at the top:
|
|
|
|
```kotlin
|
|
import me.zhouxi.slint.lang.SlintFileType
|
|
```
|
|
|
|
**Step 2: Rename FooLspServerDescriptor to SlintLspServerDescriptor**
|
|
|
|
Change line 20 from:
|
|
```kotlin
|
|
serverStarter.ensureServerStarted(FooLspServerDescriptor(project))
|
|
```
|
|
|
|
To:
|
|
```kotlin
|
|
serverStarter.ensureServerStarted(SlintLspServerDescriptor(project))
|
|
```
|
|
|
|
Change line 34 from:
|
|
```kotlin
|
|
private class FooLspServerDescriptor(project: Project) : ProjectWideLspServerDescriptor(project, "Slint") {
|
|
```
|
|
|
|
To:
|
|
```kotlin
|
|
private class SlintLspServerDescriptor(project: Project) : ProjectWideLspServerDescriptor(project, "Slint") {
|
|
```
|
|
|
|
**Step 3: Update file type checking to use SlintFileType**
|
|
|
|
Change line 19 from:
|
|
```kotlin
|
|
if (file.extension == "slint") {
|
|
```
|
|
|
|
To:
|
|
```kotlin
|
|
if (file.fileType == SlintFileType) {
|
|
```
|
|
|
|
Change line 35 from:
|
|
```kotlin
|
|
override fun isSupportedFile(file: VirtualFile) = file.extension == "slint"
|
|
```
|
|
|
|
To:
|
|
```kotlin
|
|
override fun isSupportedFile(file: VirtualFile) = file.fileType == SlintFileType
|
|
```
|
|
|
|
**Step 4: Verify compilation**
|
|
|
|
Run: `./gradlew compileKotlin`
|
|
Expected: BUILD SUCCESSFUL
|
|
|
|
**Step 5: Commit**
|
|
|
|
```bash
|
|
git add src/main/kotlin/me/zhouxi/slint/lsp/SlintLspServerSupportProvider.kt
|
|
git commit -m "refactor: use SlintFileType for type-safe file detection"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 5: Download TextMate Grammar File
|
|
|
|
**Files:**
|
|
- Create: `src/main/resources/textmate/slint.tmLanguage.json`
|
|
|
|
**Step 1: Create textmate directory**
|
|
|
|
Run: `mkdir -p src/main/resources/textmate`
|
|
|
|
**Step 2: Download Slint TextMate grammar**
|
|
|
|
Run:
|
|
```bash
|
|
curl -o src/main/resources/textmate/slint.tmLanguage.json \
|
|
https://raw.githubusercontent.com/slint-ui/slint/master/editors/vscode/syntaxes/slint.tmLanguage.json
|
|
```
|
|
|
|
Expected: File downloaded successfully
|
|
|
|
**Step 3: Verify file exists and is valid JSON**
|
|
|
|
Run: `cat src/main/resources/textmate/slint.tmLanguage.json | head -20`
|
|
Expected: Should see JSON content starting with `{` and containing `"scopeName": "source.slint"`
|
|
|
|
**Step 4: Commit**
|
|
|
|
```bash
|
|
git add src/main/resources/textmate/slint.tmLanguage.json
|
|
git commit -m "feat: add Slint TextMate grammar for syntax highlighting"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 6: Create TextMate Bundle Provider
|
|
|
|
**Files:**
|
|
- Create: `src/main/kotlin/me/zhouxi/slint/lang/syntax/SlintTextMateProvider.kt`
|
|
|
|
**Step 1: Create syntax directory**
|
|
|
|
Run: `mkdir -p src/main/kotlin/me/zhouxi/slint/lang/syntax`
|
|
|
|
**Step 2: Create SlintTextMateProvider class**
|
|
|
|
Create the file with this content:
|
|
|
|
```kotlin
|
|
package me.zhouxi.slint.lang.syntax
|
|
|
|
import org.jetbrains.plugins.textmate.api.TextMateBundle
|
|
import org.jetbrains.plugins.textmate.api.TextMateBundleProvider
|
|
|
|
class SlintTextMateProvider : TextMateBundleProvider {
|
|
override fun getBundles(): List<TextMateBundle> {
|
|
return listOf(
|
|
TextMateBundle(
|
|
"Slint",
|
|
"textmate/slint.tmLanguage.json",
|
|
SlintTextMateProvider::class.java.classLoader
|
|
)
|
|
)
|
|
}
|
|
}
|
|
```
|
|
|
|
**Step 3: Verify compilation**
|
|
|
|
Run: `./gradlew compileKotlin`
|
|
Expected: BUILD SUCCESSFUL
|
|
|
|
**Step 4: Commit**
|
|
|
|
```bash
|
|
git add src/main/kotlin/me/zhouxi/slint/lang/syntax/SlintTextMateProvider.kt
|
|
git commit -m "feat: add TextMate bundle provider for Slint syntax highlighting"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 7: Register TextMate Bundle Provider
|
|
|
|
**Files:**
|
|
- Modify: `src/main/resources/META-INF/plugin.xml`
|
|
|
|
**Step 1: Add textMate.bundleProvider extension**
|
|
|
|
Add this inside the `<extensions defaultExtensionNs="com.intellij">` block:
|
|
|
|
```xml
|
|
<textMate.bundleProvider implementation="me.zhouxi.slint.lang.syntax.SlintTextMateProvider"/>
|
|
```
|
|
|
|
The complete extensions block should now look like:
|
|
|
|
```xml
|
|
<extensions defaultExtensionNs="com.intellij">
|
|
<fileType
|
|
name="Slint"
|
|
implementationClass="me.zhouxi.slint.lang.SlintFileType"
|
|
fieldName="INSTANCE"
|
|
language="Slint"
|
|
extensions="slint"/>
|
|
<platform.lsp.serverSupportProvider implementation="me.zhouxi.slint.lsp.SlintLspServerSupportProvider"/>
|
|
<textMate.bundleProvider implementation="me.zhouxi.slint.lang.syntax.SlintTextMateProvider"/>
|
|
</extensions>
|
|
```
|
|
|
|
**Step 2: Verify plugin configuration**
|
|
|
|
Run: `./gradlew verifyPluginProjectConfiguration`
|
|
Expected: BUILD SUCCESSFUL
|
|
|
|
**Step 3: Commit**
|
|
|
|
```bash
|
|
git add src/main/resources/META-INF/plugin.xml
|
|
git commit -m "feat: register TextMate bundle provider in plugin.xml"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 8: Build and Test Plugin
|
|
|
|
**Files:**
|
|
- Create: `test-files/hello.slint` (for manual testing)
|
|
|
|
**Step 1: Create test directory and sample Slint file**
|
|
|
|
Run:
|
|
```bash
|
|
mkdir -p test-files
|
|
cat > test-files/hello.slint << 'EOF'
|
|
import { Button, VerticalBox } from "std-widgets.slint";
|
|
|
|
export component HelloWorld inherits Window {
|
|
width: 400px;
|
|
height: 300px;
|
|
|
|
VerticalBox {
|
|
alignment: center;
|
|
|
|
Text {
|
|
text: "Hello, World!";
|
|
font-size: 24px;
|
|
}
|
|
|
|
Button {
|
|
text: "Click me";
|
|
clicked => {
|
|
debug("Button clicked!");
|
|
}
|
|
}
|
|
}
|
|
}
|
|
EOF
|
|
```
|
|
|
|
**Step 2: Build the plugin**
|
|
|
|
Run: `./gradlew buildPlugin`
|
|
Expected: BUILD SUCCESSFUL, plugin ZIP created in `build/distributions/`
|
|
|
|
**Step 3: Run plugin in sandbox IDE**
|
|
|
|
Run: `./gradlew runIde`
|
|
Expected: IntelliJ IDEA opens with plugin installed
|
|
|
|
**Step 4: Manual testing checklist**
|
|
|
|
In the sandbox IDE:
|
|
1. Open `test-files/hello.slint`
|
|
2. Verify: File icon shows Slint logo
|
|
3. Verify: Syntax highlighting is applied (keywords, strings, comments colored)
|
|
4. Verify: LSP server starts (check status bar widget)
|
|
5. Verify: Type `Butt` and trigger completion (Ctrl+Space) - should suggest `Button`
|
|
6. Verify: Hover over `Button` - should show documentation
|
|
7. Verify: Ctrl+Click on `Button` - should jump to definition
|
|
8. Verify: Introduce syntax error (e.g., remove semicolon) - should show red underline
|
|
9. Verify: Format code (Ctrl+Alt+L) - should format the file
|
|
|
|
**Step 5: Document test results**
|
|
|
|
Create a file documenting what works:
|
|
|
|
```bash
|
|
cat > test-files/TEST_RESULTS.md << 'EOF'
|
|
# Slint LSP Integration Test Results
|
|
|
|
Date: 2026-01-29
|
|
|
|
## Test Environment
|
|
- IntelliJ IDEA: 2025.2.4
|
|
- Slint LSP Version: 1.14.1
|
|
- Plugin Version: 1.0-SNAPSHOT
|
|
|
|
## Test Results
|
|
|
|
### File Type Recognition
|
|
- [ ] .slint files show Slint icon
|
|
- [ ] File type is recognized as "Slint"
|
|
|
|
### Syntax Highlighting
|
|
- [ ] Keywords highlighted (import, export, component, inherits)
|
|
- [ ] Strings highlighted
|
|
- [ ] Comments highlighted
|
|
- [ ] Properties highlighted
|
|
|
|
### LSP Features
|
|
- [ ] LSP server starts automatically
|
|
- [ ] Code completion works
|
|
- [ ] Hover documentation works
|
|
- [ ] Goto definition works
|
|
- [ ] Diagnostics show errors/warnings
|
|
- [ ] Code formatting works
|
|
- [ ] Find references works
|
|
- [ ] Rename refactoring works
|
|
|
|
## Issues Found
|
|
(Document any issues here)
|
|
|
|
## Notes
|
|
(Any additional observations)
|
|
EOF
|
|
```
|
|
|
|
**Step 6: Commit test files**
|
|
|
|
```bash
|
|
git add test-files/
|
|
git commit -m "test: add sample Slint file and test results template"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 9: Update CLAUDE.md Documentation
|
|
|
|
**Files:**
|
|
- Modify: `CLAUDE.md`
|
|
|
|
**Step 1: Add testing section to CLAUDE.md**
|
|
|
|
Add this section before "## Development Notes":
|
|
|
|
```markdown
|
|
## Testing the Plugin
|
|
|
|
### Manual Testing
|
|
|
|
1. **Build and run in sandbox:**
|
|
```bash
|
|
./gradlew runIde
|
|
```
|
|
|
|
2. **Test with sample file:**
|
|
- Open `test-files/hello.slint`
|
|
- Verify file icon, syntax highlighting, and LSP features
|
|
|
|
3. **Test LSP features:**
|
|
- Code completion: Type and press Ctrl+Space
|
|
- Goto definition: Ctrl+Click on symbols
|
|
- Hover: Mouse over symbols
|
|
- Diagnostics: Introduce syntax errors
|
|
- Formatting: Ctrl+Alt+L
|
|
|
|
### Verify LSP Server
|
|
|
|
Check LSP server status in the status bar (bottom right). Should show "Slint" when a .slint file is open.
|
|
|
|
### Common Issues
|
|
|
|
- **LSP server not starting**: Check that LSP binary exists in sandbox at `sandbox/plugins/slint/lsp/slint-lsp-{platform}`
|
|
- **No syntax highlighting**: Verify TextMate grammar file is in resources
|
|
- **No completion**: Check LSP server logs in `idea.log`
|
|
```
|
|
|
|
**Step 2: Commit documentation update**
|
|
|
|
```bash
|
|
git add CLAUDE.md
|
|
git commit -m "docs: add testing instructions to CLAUDE.md"
|
|
```
|
|
|
|
---
|
|
|
|
## Task 10: Final Verification and Cleanup
|
|
|
|
**Step 1: Run all verification tasks**
|
|
|
|
Run:
|
|
```bash
|
|
./gradlew clean build verifyPlugin
|
|
```
|
|
|
|
Expected: All tasks complete successfully
|
|
|
|
**Step 2: Check plugin structure**
|
|
|
|
Run: `./gradlew buildPlugin && unzip -l build/distributions/slint-1.0-SNAPSHOT.zip | grep -E "(slint-lsp|\.slint\.tmLanguage)"`
|
|
|
|
Expected: Should see LSP binaries and TextMate grammar in the plugin ZIP
|
|
|
|
**Step 3: Review all changes**
|
|
|
|
Run: `git log --oneline --graph`
|
|
|
|
Expected: Should see all commits from this implementation
|
|
|
|
**Step 4: Create final summary commit**
|
|
|
|
```bash
|
|
git add -A
|
|
git commit -m "feat: complete Slint LSP integration with file type, syntax highlighting, and LSP features
|
|
|
|
- Added SlintLanguage and SlintFileType definitions
|
|
- Registered .slint file type with IntelliJ
|
|
- Integrated Slint LSP server with type-safe file detection
|
|
- Added TextMate-based syntax highlighting
|
|
- Included test files and documentation
|
|
- All standard LSP features now available: completion, diagnostics, goto definition, hover, formatting, references, rename"
|
|
```
|
|
|
|
---
|
|
|
|
## Success Criteria
|
|
|
|
✅ .slint files recognized by IntelliJ with proper icon
|
|
✅ Syntax highlighting works using TextMate grammar
|
|
✅ LSP server starts automatically when .slint file opened
|
|
✅ Code completion provides suggestions
|
|
✅ Diagnostics show errors and warnings
|
|
✅ Goto definition navigates correctly
|
|
✅ Hover shows documentation
|
|
✅ Code formatting works
|
|
✅ Find references works
|
|
✅ Rename refactoring works
|
|
✅ Plugin builds and runs in sandbox IDE
|
|
✅ All changes committed with clear messages
|
|
|
|
## Next Steps (Phase 2)
|
|
|
|
- Implement live preview integration (Slint-specific feature)
|
|
- Add project configuration UI
|
|
- Optimize LSP server startup time
|
|
- Add more comprehensive tests
|