How do I use the language server for error detection?
← Debugging and Troubleshooting · Ref: Q249
EK9 includes a full Language Server Protocol (LSP) implementation that provides real-time error detection, hover documentation, go-to-definition, and completions in your editor.
STARTING THE LSP
Two modes are available:
ek9 -ls Full LSP mode for IDE integration ek9 -lsh Hover-help-only mode for lightweight editors
The LSP communicates over stdio using the standard LSP JSON-RPC protocol. Any editor that supports LSP can use it (VSCode, Neovim, Emacs, Sublime Text, etc.).
VSCODE EXTENSION
A VSCode extension is available that provides:
Syntax highlighting for .ek9 files Real-time error detection as you type Hover documentation showing type information and method signatures Go-to-definition for navigating to symbol declarations Code completions for types, methods, and operators
REAL-TIME ERROR DETECTION
The LSP compiles your code through the PRE_IR_CHECKS phase (phase 9 of 22). This means ALL type errors, flow analysis errors, duplicate detection, and resolution errors appear instantly in your editor. You see errors before you save the file.
HOVER DOCUMENTATION
Hovering over any symbol shows its type, documentation, and available methods. For built-in types, this includes the full API. For your own types, it shows the declared operators and methods.
PROGRESSIVE ERROR DETECTION
The multi-phase pipeline means errors are detected progressively:
Phase 2-3: Duplicate names and definitions Phase 4-5: Unresolved references and types Phase 6-7: Type hierarchy and generic resolution errors Phase 8-9: Flow analysis (unset variables, uninitialised returns)
Each phase builds on the previous, so fixing early errors often resolves later ones.
COMMAND LINE ALTERNATIVE
If you prefer the command line, use:
ek9 -c myfile.ek9 compile and check for errors ek9 -E1 -c myfile.ek9 visual errors with source snippets ek9 -E2 -c myfile.ek9 add fuzzy suggestions
See Q246 for debugging strategies. See Q252 for verbose compilation modes. See Q253 for understanding compiler phases.
Example
defines module qa.debugging.languageserver defines trait Describable describe() as pure abstract <- rtn as String? defines class Point x <- Float() y <- Float() Point() -> px as Float py as Float this.x :=: px this.y :=: py distanceTo() as pure -> other as Point <- rtn as Float: Float() dx <- x - other.x dy <- y - other.y rtn: sqrt (dx * dx + dy * dy) operator $ as pure <- rtn as String: `(${x}, ${y})` override operator ? as pure <- rtn as Boolean: x? and y? Sensor with trait of Describable name <- String() reading <- Float() Sensor() -> sensorName as String sensorReading as Float this.name :=: sensorName this.reading :=: sensorReading override describe() as pure <- rtn as String: `Sensor ${name}: ${reading}` operator $ as pure <- rtn as String: `${name}=${reading}` override operator ? as pure <- rtn as Boolean: name? and reading? defines program LanguageServerDemo() stdout <- Stdout() // Types that the LSP would provide hover info for p1 <- Point(0.0, 0.0) p2 <- Point(3.0, 4.0) stdout.println(`Point 1: ${p1}`) stdout.println(`Point 2: ${p2}`) stdout.println(`Distance: ${p1.distanceTo(p2)}`) // Sensor with trait sensor <- Sensor("Temp", 22.5) stdout.println(`Sensor: ${sensor}`) stdout.println(`Description: ${sensor.describe()}`)
Common mistakes
E50060 — The method is named 'distanceTo' not 'distance'. Calling a method that does not exist on the type produces a resolution error. See ek9 -h E50060 for details.
Incorrect:
stdout.println(`Distance: ${p1.distance(p2)}`)
Correct:
stdout.println(`Distance: ${p1.distanceTo(p2)}`)
E08090 — If the variable 'sensor' is declared but never used in any expression, the compiler rejects it. Every declared variable must be referenced. See ek9 -h E50050 for details.
Incorrect:
sensorLabel <- `Sensor: ${sensor}`
Correct:
stdout.println(`Sensor: ${sensor}`)
Other ways to ask this
- What is the EK9 language server?
- How do I get real-time errors in my editor?
- Does EK9 support IDE integration?
Coming from another language?
Java: IntelliJ/Eclipse provide rich IDE support, separate from compiler. Python: Pylance/Pyright LSP servers, type checking optional. Rust: rust-analyzer provides excellent LSP support. Go: gopls is the official LSP server. C++: clangd provides LSP, but C++ complexity limits accuracy. Kotlin: IntelliJ native support, kotlin-language-server for other editors. EK9: built-in LSP as part of the compiler itself, compiles through 10 phases for comprehensive error detection, hover documentation, go-to-definition.
Keywords: vscode, editor, error, realtime, ide, lsp, troubleshoot, detection, server, error-message, hover, completion, language, definition, integration, debug