Tinymist IntelliJ Plugin
July 7, 2026 · View on GitHub
Last Updated: August 31, 2025
The goal of this project is to provide comprehensive Typst language support for IntelliJ-based IDEs.
We are using the lsp4ij library developed by Red Hat (https://github.com/redhat-developer/lsp4ij).
Prerequisites
- IntelliJ IDEA: Other IDEs will also work, but given developing a plugin for IntelliJ, the best support for that is provided by IntelliJ.
- JDK 21 You must choose JDK 21 in the IntelliJ IDEA settings.
Core Directory Structure
editors/intellij/: Root directory for the IntelliJ plugin.build.gradle.kts: Gradle build script for managing dependencies (likelsp4ij, IntelliJ Platform SDK) and plugin packaging.src/main/kotlin/org/tinymist/intellij/: Contains the core Kotlin source code for the plugin. This is further structured into sub-packages likelsp,preview, andstructure.src/main/resources/META-INF/plugin.xml: The plugin descriptor file, essential for IntelliJ to load and recognize the plugin and its components (e.g., language support, LSP integration, preview editors, structure view).
Build the Plugin
You can build the plugin using the Gradle tool window in IntelliJ (Tasks > intellij > buildPlugin) or via the terminal:
./gradlew :intellij:buildPlugin
Launch the Plugin
Use the Gradle task runIde (Tasks > intellij > runIde) from the Gradle tool window or terminal:
./gradlew :intellij:runIde
Using a custom tinymist Language Server Executable
Ensure that tinymist is installed on your system and the path in TinymistLspStreamConnectionProvider.kt is correct for your development environment if you are modifying the LSP.
Viewing Logs
- IntelliJ Plugin Logs: Check the
idea.logfile of the sandboxed IntelliJ instance. You can find its location via "Help" > "Show Log in Finder/Explorer" in the sandbox IDE. - LSP Communication Logs:
lsp4ijprovides an "LSP Consoles" view in the sandbox IDE (usually accessible from the tool window bar at the bottom left). Set its verbosity (e.g., to "verbose") viaLanguages & Frameworks > Language Serverssettings to see JSON-RPC messages between the plugin andtinymist.
Project Roadmap & Status
I. Completed Milestones
- Initial Server Integration: Resolved server startup crashes.
- Basic Diagnostics: Implemented linting/diagnostics with custom formatting.
- Core LSP Features:
textDocument/completion(Code Completion) - Fully implemented and testedtextDocument/hover(Hover Information) - Fully implemented and testedtextDocument/definition(Go To Definition) - Fully implemented and testedtextDocument/signatureHelp(Signature Help) - ImplementedtextDocument/rename(Rename Symbol) - Implemented
- Configuration: Robust executable path resolution with settings integration
- Preview Integration: Full JCEF-based preview with tinymist's background preview server
- Settings Panel: Comprehensive settings panel with server management modes (auto-install vs custom path)
- Automated Server Installation: Full cross-platform auto-installation system for tinymist binaries
- Server Management: Dual-mode server management (AUTO_MANAGE for auto-installation, CUSTOM_PATH for manual configuration)
LSP Features Implementation Status
The following table shows the implementation status of LSP features as supported by the tinymist server:
| LSP Feature | Status | Implementation Type | Notes |
|---|---|---|---|
textDocument/completion | ✅ Implemented | Handled by lsp4ij | Auto-completion for Typst syntax and functions |
textDocument/hover | ✅ Implemented | Handled by lsp4ij | Documentation and type information on hover |
textDocument/definition | ✅ Implemented | Handled by lsp4ij | Go to definition functionality |
textDocument/signatureHelp | ✅ Implemented | Handled by lsp4ij | Function signature hints |
textDocument/rename | ✅ Implemented | Handled by lsp4ij | Symbol renaming |
textDocument/publishDiagnostics | ✅ Implemented | Direct implementation | Custom diagnostic formatting with HTML support (TinymistLanguageClient.kt:24) |
textDocument/semanticTokens | ✅ Implemented | Handled by lsp4ij | Semantic syntax highlighting |
textDocument/references | ✅ Implemented | Handled by lsp4ij | Find all references to a symbol |
textDocument/documentHighlight | ✅ partly implemented | Handled by lsp4ij | Highlight related symbols; currently the highlight only works upon entirely selecting a symbol not just placing the carret there |
textDocument/documentSymbol | ✅ Implemented | Handled by lsp4ij | Document outline/structure view |
textDocument/inlayHint | ✅ Implemented | Handled by lsp4ij | Inlay additional information into code editor, i.e. the names of function parameters |
textDocument/codeAction | ✅ Implemented | Handled by lsp4ij | Code fixes and refactoring actions |
textDocument/formatting | ❌ Not implemented | - | Document formatting |
textDocument/rangeFormatting | ❌ Not implemented | - | Range-based formatting |
textDocument/onTypeFormatting | ❌ Not implemented | - | Format-on-type |
textDocument/codeLens | ❌ Not implemented | - | Inline code annotations |
textDocument/foldingRange | ✅ Implemented | Handled by lsp4ij | Code folding regions |
textDocument/selectionRange | ✅ Implemented | Handled by lsp4ij | Smart text selection |
textDocument/prepareCallHierarchy | ❌ Not implemented | - | Call hierarchy preparation |
textDocument/callHierarchy/incomingCalls | ❌ Not implemented | - | Incoming call hierarchy |
textDocument/callHierarchy/outgoingCalls | ❌ Not implemented | - | Outgoing call hierarchy |
textDocument/linkedEditingRange | ❌ Not implemented | - | Linked editing of related symbols |
textDocument/moniker | ❌ Not implemented | - | Symbol monikers for cross-references |
workspace/didChangeConfiguration | ✅ Implemented | Handled by lsp4ij | Configuration change notifications |
workspace/didChangeWatchedFiles | ✅ Implemented | Handled by lsp4ij | File watching |
workspace/symbol | ✅ Implemented | Handled by lsp4ij | Workspace-wide symbol search |
window/showMessage | ✅ Implemented | Handled by lsp4ij | Server messages to client |
window/showMessageRequest | ✅ Implemented | Handled by lsp4ij | Message request handling |
tinymist/document | ✅ Implemented | Direct implementation | Custom tinymist notification (TinymistLanguageClient.kt:58) |
tinymist/documentOutline | ✅ Not implemented | Direct implementation | Custom outline notification (TinymistLSPDiagnosticFeature) |
Legend:
- ✅ Implemented: Feature is working and available
- ❌ Not implemented: Feature is not yet implemented in the plugin
- Handled by lsp4ij: Feature implementation is provided by the lsp4ij library
- Direct implementation: Feature has custom implementation in the plugin code
II. Current Focus
- Debug server startup procedure
- currently no logs are shown in the preview. Is this because, our current method sends a command before the initialization?
- Preview Panel Stability: Handle server connection state
- A PreviewServerManager class to manage the server connection state and setup
- The preview panel should subscribe to the events from the preview manager
- The
PreviewServerManagershould start (and stop?) the preview server via the LSP commandtinymist/startPreview - The preview server holds one of these states:
- Server starting up -> the preview panel displays a message
- Server ready -> the preview panel loads URL:port as preview
- Server failed -> the preview panel displays an error message
- The
PreviewServerManagerinforms its subscribers (mainly the preview panel) about state change
III. Next steps
- Investigate
textDocument/formatting+ variant capabilities - Debug failing integration tests
V. Planned Features & Enhancements
- Additional LSP Features:
textDocument/formatting(Document formatting)
- Enhanced Settings Panel:
- Configure font paths, PDF export options
- Settings for
tinymistpreview server configuration
- Make the editor more colorfull. Does the current situation have something to do with 'textDocument/documentColor' not answering?
VI. Technical Debt & Refinements
- Missing File Type Icon: TODO in
TypstLanguage.kt- need to add custom icon for .typ files. - LSP Initialization Options: Currently commented out in
TinymistLspStreamConnectionProvider.kt- initialization options for the LSP server (e.g.,colorTheme, preview URL,preview.background.enabled) should be configurable via settings panel.
File Overview
This section outlines the architecture of the Tinymist IntelliJ plugin, detailing the roles of key files and their interactions, particularly with the IntelliJ Platform and LSP4IJ APIs.
Kotlin Source Files (src/main/kotlin/org/tinymist/intellij/)
The source code is organized into the following main areas:
-
Base Language Support (
org.tinymist.intellij)TypstLanguage.kt: DefinesTypstLanguage(a subclass ofcom.intellij.lang.Language) andTypstFileType(a subclass ofcom.intellij.openapi.fileTypes.LanguageFileType). This is the fundamental registration of "Typst" as a recognized language and file type within the IntelliJ Platform.TypstFile.kt: DefinesTypstFile(a subclass ofcom.intellij.extapi.psi.PsiFileBase). This class represents a Typst file in IntelliJ's Program Structure Interface (PSI) tree, allowing the platform to understand it as a structured file.- Local Parsing/Lexing/Highlighting: The plugin does not currently include or register custom local lexers (
TypstLexerAdapter.kt), parsers (TypstParserDefinition.kt), or syntax highlighters (TypstSyntaxHighlighter.kt). It relies on the LSP server for semantic tokens for syntax highlighting and for other structural understanding. The grammar files insrc/main/grammars/are unused by the plugin's runtime.
-
LSP (Language Server Protocol) Integration (
org.tinymist.intellij.lsp)TinymistLanguageServerFactory.kt: Implementscom.redhat.devtools.lsp4ij.LanguageServerFactory. Creates instances ofTinymistLspStreamConnectionProviderfor server connection, providesTinymistLSPDiagnosticFeaturefor custom diagnostic handling, and includesTinymistLanguageServerInstallerfor automated server installation.TinymistLspStreamConnectionProvider.kt: Extendscom.redhat.devtools.lsp4ij.server.OSProcessStreamConnectionProvider. This class manages the lifecycle and communication with thetinymistLSP executable using sophisticated executable resolution:- Uses
TinymistSettingsServiceto determine server management mode (AUTO_MANAGE or CUSTOM_PATH) - For AUTO_MANAGE mode: Uses
TinymistLanguageServerInstallerto get automatically installed executable path - For CUSTOM_PATH mode: Uses user-configured executable path from settings
- Initialization options are currently commented out (TODO) but previously provided server configuration
- Uses
TinymistLanguageServerInstaller.kt: Comprehensive auto-installation system that downloads and installs platform-specific tinymist binaries from GitHub releases. Supports Windows, macOS (x64/ARM64), and Linux (x64/ARM64) with proper archive extraction and executable permissions.TinymistLanguageClient.kt: Extendscom.redhat.devtools.lsp4ij.client.LanguageClientImpl. This custom client handles Tinymist-specific LSP notifications and can customize how standard LSP messages are processed.@JsonNotification("tinymist/document") handleDocument(...): Placeholder for handling a custom notification, potentially for preview updates or other document-specific events. (Currently logs receipt).publishDiagnostics(...): Overrides the default handler to reformat diagnostic messages (errors, warnings) from the server (e.g., replacing newlines with<br>) for better display in IntelliJ's UI.showMessageRequest(...): Overrides the default to handlewindow/showMessageRequestfrom the server, mainly to log them and prevent potential NPEs inlsp4ijif actions are null.
-
Settings Management (
org.tinymist.intellij.settings)TinymistSettingsService.kt: Application-level service that implementsPersistentStateComponent<TinymistSettingsState>for persistent storage of plugin settings. Provides convenient accessors fortinymistExecutablePathandserverManagementMode.TinymistSettingsState.kt: Data class defining the plugin's settings state, includingServerManagementModeenum (AUTO_MANAGE vs CUSTOM_PATH) and executable path configuration.TinymistSettingsPanel.kt: Swing-based UI panel for the settings interface with radio buttons for server management mode and text field for custom executable path.TinymistSettingsConfigurable.kt: ImplementsConfigurableinterface to integrate the settings panel into IntelliJ's Settings/Preferences dialog under "Tools > Tinymist LSP".TinymistVersion.kt: Version management for the tinymist server, used by the installer to determine which version to download.
-
JCEF-based Preview (
org.tinymist.intellij.preview)TypstPreviewFileEditor.kt: Implementscom.intellij.openapi.fileEditor.FileEditorand usescom.intellij.ui.jcef.JCEFHtmlPanelto embed a Chromium-based browser view. This editor displays the live preview of the Typst document.- It connects to a web server (e.g.,
http://127.0.0.1:23635) that is started and managed by thetinymistlanguage server itself (whenpreview.background.enabledis true). - It includes logic to wait for the server to be available before attempting to load the URL.
- It handles cases where JCEF might not be supported in the user's environment.
- It connects to a web server (e.g.,
TypstPreviewFileEditorProvider.kt: Implementscom.intellij.openapi.fileEditor.FileEditorProvider. This provider is responsible for creating instances ofTypstPreviewFileEditorwhen IntelliJ needs to open a preview for a Typst file. It also defines the editor's ID and policy (e.g., where it should be placed relative to other editors).TypstTextEditorWithPreviewProvider.kt: Extendscom.intellij.openapi.fileEditor.TextEditorWithPreviewProvider. This class is the main entry point registered inplugin.xmlfor opening Typst files. It combines a standard text editor (provided by IntelliJ) with the customTypstPreviewFileEditor(obtained viaTypstPreviewFileEditorProvider), allowing for a side-by-side text and preview editing experience. It accepts files of typeTypstFileType.
Key Interactions
- IntelliJ Platform & Plugin Startup: IntelliJ reads
plugin.xmlto discover the plugin's capabilities. It registersTypstLanguageandTypstFileType. - Opening a Typst File:
TypstTextEditorWithPreviewProvideris invoked, creating a split editor with a text part and aTypstPreviewFileEditor.TinymistLanguageServerFactoryis triggered, which startsTinymistLspStreamConnectionProviderto launch thetinymistLSP server process.TinymistLanguageClientestablishes communication with the server.
- LSP Communication:
- The client and server exchange JSON-RPC messages for features like diagnostics, completion, hover, etc.
TinymistLanguageClienthandles custom notifications liketinymist/document(currently a placeholder). Atinymist/documentOutlinehandler would be needed for a Structure View.
- Structure View:
- (Currently not implemented as described in
dev-notes.md). If implemented, when the user opens the Structure View, aTypstStructureViewFactorywould create aTypstStructureViewModel. - The view model would fetch data (potentially from an
OutlineDataHolderpopulated byTinymistLanguageClient) and build the tree.
- (Currently not implemented as described in
- Preview Panel:
TypstPreviewFileEditorloads its content from the HTTP server run by thetinymistLSP (ifpreview.background.enabledis true in initialization options).- Updates to the preview are likely driven by the
tinymistserver itself, potentially triggered bytextDocument/didChangenotifications from the client or its own file watching.