13 KiB
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:
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
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:
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
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:
<fileType
name="Slint"
implementationClass="me.zhouxi.slint.lang.SlintFileType"
fieldName="INSTANCE"
language="Slint"
extensions="slint"/>
The complete extensions block should look like:
<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
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:
import me.zhouxi.slint.lang.SlintFileType
Step 2: Rename FooLspServerDescriptor to SlintLspServerDescriptor
Change line 20 from:
serverStarter.ensureServerStarted(FooLspServerDescriptor(project))
To:
serverStarter.ensureServerStarted(SlintLspServerDescriptor(project))
Change line 34 from:
private class FooLspServerDescriptor(project: Project) : ProjectWideLspServerDescriptor(project, "Slint") {
To:
private class SlintLspServerDescriptor(project: Project) : ProjectWideLspServerDescriptor(project, "Slint") {
Step 3: Update file type checking to use SlintFileType
Change line 19 from:
if (file.extension == "slint") {
To:
if (file.fileType == SlintFileType) {
Change line 35 from:
override fun isSupportedFile(file: VirtualFile) = file.extension == "slint"
To:
override fun isSupportedFile(file: VirtualFile) = file.fileType == SlintFileType
Step 4: Verify compilation
Run: ./gradlew compileKotlin
Expected: BUILD SUCCESSFUL
Step 5: Commit
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:
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
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:
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
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:
<textMate.bundleProvider implementation="me.zhouxi.slint.lang.syntax.SlintTextMateProvider"/>
The complete extensions block should now look like:
<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
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:
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:
- Open
test-files/hello.slint - Verify: File icon shows Slint logo
- Verify: Syntax highlighting is applied (keywords, strings, comments colored)
- Verify: LSP server starts (check status bar widget)
- Verify: Type
Buttand trigger completion (Ctrl+Space) - should suggestButton - Verify: Hover over
Button- should show documentation - Verify: Ctrl+Click on
Button- should jump to definition - Verify: Introduce syntax error (e.g., remove semicolon) - should show red underline
- Verify: Format code (Ctrl+Alt+L) - should format the file
Step 5: Document test results
Create a file documenting what works:
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
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":
## Testing the Plugin
### Manual Testing
1. **Build and run in sandbox:**
```bash
./gradlew runIde
-
Test with sample file:
- Open
test-files/hello.slint - Verify file icon, syntax highlighting, and LSP features
- Open
-
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:
./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
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