Pulse Language Support for VS Code
Official Visual Studio Code extension for the Pulse programming language.
Pulse is a deterministic concurrency language that compiles to JavaScript, featuring fine-grained reactivity, CSP-style channels, and Go-inspired concurrent primitives.
Features
Core Language Support
Syntax Highlighting: Full TextMate grammar for .pulse files with support for:
- Keywords, control flow, declarations
- Single-line (
//) and multi-line (/* */) comments
- String literals (double, single, template)
- Numeric literals with underscores
- Operators and punctuation
Language Server Protocol (LSP): Professional-grade language server providing:
- Auto-completion: IntelliSense for Pulse keywords and runtime functions
- Hover Documentation: Inline documentation for keywords, functions, and symbols
- Real-time Diagnostics: Syntax error detection using Pulse parser (debounced 150ms)
- Semantic Tokens: Enhanced syntax highlighting based on code semantics
Code Snippets: Quick scaffolding for common patterns:
- Function declarations (
fn, afn)
- Reactivity (
signal, computed, effect, batch)
- Concurrency (
channel, select, spawn)
- Control flow (
for, if, try)
- Imports (
impr, impc)
Advanced Features
- Dynamic Keyword Extraction: Automatically syncs with
lib/lexer.js to stay current with language updates
- Command Palette:
Pulse: Restart Language Server for development
- Workspace Integration: Monitors
.pulse files for changes
Installation
For Local Development and Testing
Clone the Pulse repository (if you haven't already):
git clone https://github.com/osvfelices/pulse.git
cd pulse/pulse-vscode
Install dependencies:
npm install
Build the extension:
npm run build
Launch Extension Development Host:
code .
# Then press F5 in VS Code
Test the extension:
- In the Extension Development Host window, open any
.pulse file
- Verify syntax highlighting, completions, hover, and diagnostics
From VSIX Package
Build the VSIX:
npm run build
npm run vsce:package
Install the extension:
code --install-extension pulse-0.2.0.vsix
Reload VS Code and open a .pulse file
From VS Code Marketplace
Once published:
ext install pulselang.pulse
Usage
Syntax Highlighting
All Pulse syntax is automatically highlighted:
// Single-line comment
/* Multi-line
comment */
import { signal, effect } from 'pulselang/runtime/reactivity'
const [count, setCount] = signal(0)
fn increment() {
setCount(count() + 1)
}
effect(() => {
print('Count is:', count())
})
Auto-completion
Start typing and press Ctrl+Space (or Cmd+Space on macOS):
sig[Ctrl+Space]
// Suggests: signal, with documentation
Completions include:
- Keywords:
fn, let, const, select, spawn, async, await, etc.
- Runtime functions:
signal, computed, effect, channel, selectCase, scheduler, print
- Documentation: Each item includes inline help
Code Snippets
Type a prefix and press Tab:
| Prefix |
Expands To |
fn |
Function declaration |
signal |
Create reactive signal |
effect |
Create effect |
channel |
Create channel |
select |
Select statement with cases |
spawn |
Spawn concurrent task |
impr |
Import reactivity runtime |
Hover Documentation
Hover over keywords and functions to see documentation:
select // Hover shows: "CSP-style select for concurrent channel operations"
Real-time Diagnostics
Syntax errors are highlighted as you type:
fn broken( { // Error: Syntax error
// Missing closing parenthesis and brace
The language server uses Pulse's parser to provide accurate diagnostics with a 150ms debounce for performance.
Project Structure
pulse-vscode/
├── client/ # VS Code extension client
│ ├── src/extension.ts # Extension activation, LSP client
│ ├── out/ # Compiled client code
│ └── package.json # Client dependencies
├── server/ # Language Server
│ ├── src/
│ │ ├── server.ts # LSP server implementation
│ │ ├── keywords.ts # Keyword extraction from lexer
│ │ ├── diagnostics.ts # Syntax error detection
│ │ └── semantic-tokens.ts # Semantic highlighting
│ ├── out/ # Compiled server code
│ └── package.json # Server dependencies
├── test/ # Automated tests
│ ├── suite/
│ │ ├── extension.test.ts # Extension tests
│ │ └── fixtures/ # Test .pulse files
│ └── runTest.ts # Test runner
├── syntaxes/
│ └── pulse.tmLanguage.json # TextMate grammar
├── snippets/
│ └── pulse.code-snippets # Code snippets
├── scripts/
│ └── build-and-pack.sh # Build and package script
└── package.json # Extension manifest
Development
Build Commands
# Install dependencies
npm install
# Build client and server
npm run build
# Watch mode (auto-rebuild on changes)
npm run watch
# Build tests
npm run build:test
# Run tests
npm test
# Type check all code
npm run check
# Package extension
npm run vsce:package
# All-in-one build and package
./scripts/build-and-pack.sh
Debugging
- Open
pulse-vscode/ in VS Code
- Press
F5 to launch Extension Development Host
- Set breakpoints in
client/src/extension.ts or server/src/server.ts
- Use Debug Console to inspect values
- Check Output panel → "Pulse Language Server" for logs
Running Tests
npm run build
npm run build:test
npm test
Tests verify:
- Extension activation
- Language detection for
.pulse files
- Completions for keywords (
fn, signal)
- Hover for keywords (
select)
- Diagnostics for syntax errors
Modifying the Language Server
The LSP server is in server/src/:
- server.ts: Main LSP server, handles initialization, completions, hover, diagnostics
- keywords.ts: Extracts keywords from
lib/lexer.js, provides hover documentation
- diagnostics.ts: Uses Pulse parser to detect syntax errors
- semantic-tokens.ts: Provides semantic highlighting (heuristic until full AST)
After changes:
npm run build
# Press F5 to test, or use "Pulse: Restart Language Server" command
Architecture
LSP Architecture
The extension uses the Language Server Protocol for better performance and separation of concerns:
┌─────────────────────────────────────┐
│ VS Code Extension Host │
│ ┌───────────────────────────────┐ │
│ │ Client (client/src) │ │
│ │ - Extension activation │ │
│ │ - Language client setup │ │
│ └───────────┬───────────────────┘ │
└──────────────┼──────────────────────┘
│ IPC
┌──────────────┼──────────────────────┐
│ Node.js │ │
│ ┌───────────▼───────────────────┐ │
│ │ Server (server/src) │ │
│ │ - Completions │ │
│ │ - Hover │ │
│ │ - Diagnostics (Pulse parser) │ │
│ │ - Semantic tokens │ │
│ │ - Keyword extraction │ │
│ └───────────────────────────────┘ │
└─────────────────────────────────────┘
Key Design Decisions
- Workspace Architecture: Separate
client/ and server/ workspaces for clean dependency management
- Debounced Diagnostics: 150ms debounce prevents excessive parser calls
- Dynamic Keywords: Extracts keywords from
lib/lexer.js at runtime to stay synchronized
- Graceful Degradation: If parser fails, extension continues providing completions and hover
- No Telemetry: Extension respects user privacy
Troubleshooting
Extension not activating
- Check Output → "Pulse Language Server" for errors
- Verify
.pulse file is recognized (check status bar)
- Use command: "Pulse: Restart Language Server"
Completions not working
- Wait 2 seconds for server initialization
- Check if
lib/lexer.js exists in workspace root
- Review server logs in Output panel
Diagnostics not appearing
- Ensure
lib/parser.js is available in workspace
- Parser errors are logged to Output panel
- Diagnostics require valid Pulse syntax to detect errors
Build errors
# Clean and rebuild
rm -rf client/out server/out test/out node_modules
npm install
npm run build
Contributing
Contributions are welcome! Please:
- Fork the repository
- Create a feature branch
- Make your changes
- Run tests:
npm test
- Submit a pull request
Reporting Issues
If you find a bug or inconsistency:
- Check the Output panel for logs
- Include
.pulse file that reproduces the issue
- Note VS Code version and OS
- Open an issue at github.com/osvfelices/pulse
Roadmap
Future enhancements:
- [ ] Go to Definition
- [ ] Find All References
- [ ] Rename symbol
- [ ] Format document
- [ ] Code actions (quick fixes)
- [ ] Full AST-based semantic analysis
- [ ] Inlay hints for types
- [ ] Document symbols and outline
License
MIT License - see LICENSE file for details.
Links