This commit is contained in:
me
2026-01-29 20:32:59 +08:00
parent de68ced39e
commit d3d99fa223
98 changed files with 17233 additions and 52 deletions

View File

@@ -0,0 +1,108 @@
# Slint LSP Integration Design
**Date:** 2026-01-29
**Status:** Approved
**Phase:** Phase 1 - Core LSP Features
## Overview
Implement complete Slint LSP integration into IntelliJ IDEA, enabling standard LSP features (diagnostics, completion, goto definition, hover, formatting, etc.) through IntelliJ's built-in LSP framework.
## Architecture
### Component Structure
```
IntelliJ IDEA (LSP Client)
SlintLspServerSupportProvider (Entry point)
SlintLspServerDescriptor (Server configuration)
Slint LSP Server (External process)
```
### Core Components
1. **File Type System**
- `SlintLanguage`: Language definition
- `SlintFileType`: File type definition with .slint extension
- File icon and description
2. **LSP Server Integration**
- `SlintLspServerSupportProvider`: LSP entry point (exists, needs refinement)
- `SlintLspServerDescriptor`: Server configuration (rename from FooLspServerDescriptor)
- Automatic capability negotiation via LSP initialize handshake
3. **Syntax Highlighting**
- Use TextMate grammar from official Slint VSCode extension
- `SlintTextMateProvider`: TextMate bundle provider
4. **LSP Feature Mapping** (automatic via IntelliJ)
- Diagnostics → Error/warning annotations
- Completion → Code completion UI
- Goto Definition → Ctrl+Click navigation
- Hover → Quick documentation
- Formatting → Code formatting actions
- References → Find usages
- Rename → Refactor rename
## Implementation Plan
### 1. File Type System
**Files to create:**
- `src/main/kotlin/me/zhouxi/slint/lang/SlintLanguage.kt`
- `src/main/kotlin/me/zhouxi/slint/lang/SlintFileType.kt`
**Changes to plugin.xml:**
- Register `<fileType>` extension
### 2. LSP Server Configuration
**Files to modify:**
- `src/main/kotlin/me/zhouxi/slint/lsp/SlintLspServerSupportProvider.kt`
- Rename `FooLspServerDescriptor``SlintLspServerDescriptor`
- Use `file.fileType == SlintFileType` instead of string comparison
### 3. Syntax Highlighting
**Resources to add:**
- Download `slint.tmLanguage.json` from Slint GitHub
- Place in `src/main/resources/textmate/`
**Files to create:**
- `src/main/kotlin/me/zhouxi/slint/lang/syntax/SlintTextMateProvider.kt`
**Changes to plugin.xml:**
- Register `<textMate.bundleProvider>` extension
### 4. Testing
**Test files to create:**
- Sample .slint files for manual testing
- Verify: diagnostics, completion, goto definition, hover, formatting
## Design Decisions
- **Use IntelliJ LSP Framework**: Leverage built-in LSP client, no manual protocol implementation
- **TextMate for Syntax**: Use official grammar, zero maintenance
- **Minimal Custom Code**: Only implement required extension points
- **Type-Safe File Detection**: Use FileType comparison instead of string extension checks
## Out of Scope (Phase 2)
- Live Preview integration (Slint-specific feature)
- Custom UI components
- Advanced project configuration
## Success Criteria
- .slint files recognized by IntelliJ
- LSP server starts automatically when .slint file opened
- Syntax highlighting works
- Code completion provides suggestions
- Diagnostics show errors/warnings
- Goto definition navigates correctly
- Hover shows documentation
- Code formatting works

View File

@@ -0,0 +1,547 @@
# 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