Using LSP Features
cem generate to update your manifest and refresh editor features.
The Language Server Protocol integration provides editor features like autocomplete, hover documentation, and go-to-definition for custom elements in HTML and TypeScript files. After setting up the LSP , your editor reads your Custom Elements Manifest to power intelligent code completion for tag names, attributes, slot names, and enum values. This complements the development workflow by catching typos and invalid attributes as you write code, reducing the time spent switching between editor and browser during the test phase .
The LSP uses your manifest as the source of truth, so
running cem generate
after documenting components makes those APIs immediately available in your editor. Features work in plain HTML files, Lit template literals, and anywhere custom elements appear in your code.
Autocomplete
Press Ctrl+Space (or your editor’s autocomplete trigger) after typing <my-bu to see custom element suggestions like my-button and my-button-group with their descriptions. Type a space after a tag name to see available attributes with type information and descriptions. For attributes with enum values like variant, autocomplete suggests valid options like primary, secondary, and danger. When adding slot="" attributes, autocomplete suggests valid slot names based on the parent element’s documented slots.
The LSP works in Lit template literals with special syntax support—use @eventName for events, .propertyName for properties, and ?booleanAttr for boolean attributes. All completions include inline documentation from your manifest.
Hover Documentation
Hover over tag names to see element summaries, complete API documentation (properties, attributes, slots, events), CSS custom properties and parts, and links to source code. Attributes show descriptions, type information, default values, and valid enum values when hovered. In CSS files, hovering over ::part() selectors displays styling guidance for that shadow part.
Go-to-Definition
Position your cursor on a tag name like <my-button> and press F12 (VS Code) or ctrl-] (Neovim) to jump to the component source file. Works from attributes too—trigger go-to-definition on variant="primary" to jump to the property definition in the component class.
Find References
Position your cursor on a custom element tag and press Shift+F12 (VS Code) or gr (Neovim) to see all usages across HTML, TypeScript, and JavaScript files. Results are filtered by .gitignore to exclude node_modules/, show only start tags to avoid duplicates, and work in template literals.
Workspace Symbols
Press Ctrl+T (VS Code) or use :Telescope lsp_workspace_symbols (Neovim) to search for custom elements across your entire workspace with fuzzy matching. Typing btn finds my-button, icon-button, and button-group.
Error Detection & Quick Fixes
The LSP validates HTML and provides one-click fixes for common errors. Position your cursor on red squiggles and press Ctrl+. (VS Code) or <leader>ca (Neovim) to see available fixes.
Detected errors include invalid slot names (slot="heade" suggests "header"), typos in tag names (<my-buttom> suggests <my-button>), invalid attribute names (varient suggests variant), invalid enum values (variant="primar" suggests "primary"), and missing imports (suggests adding import statements for undeclared elements).
Troubleshooting
If autocomplete doesn’t work, check that custom-elements.json exists, verify the LSP is running in your editor’s status bar, regenerate the manifest with cem generate, and restart your editor if needed.
If suggestions are outdated, regenerate the manifest—the LSP watches for changes and reloads automatically. For validation errors that don’t appear, check that diagnostics are enabled in your editor and that your manifest contains element schemas.
For large projects with performance issues, limit workspace scope, exclude build directories in .gitignore, or enable verbose logging to diagnose what’s happening.
Debug Logging
Debug logging is controlled via the LSP standard $/setTrace notification. Most editors expose this through trace level settings:
"off"- No debug logging (default)"messages"- Basic debug logging"verbose"- Detailed debug logging
Enable verbose logging to troubleshoot issues:
VS Code: Set "cem.lsp.trace.server": "verbose" in settings.json
Neovim: Set trace = 'verbose' in your LSP configuration
Other editors: Consult your LSP client documentation for trace level settings
See Also
- LSP Integration - Setup instructions for editors
- LSP Protocol Reference - Technical implementation details
- Development Workflow - How LSP fits into the dev cycle