Skip to content

VS Code to Lapis mapping

This page maps VS Code language extension concepts to the Lapis codebase. Use it when you know what you want to build in VS Code and need the Lapis equivalent.

VS Code conceptLapis equivalentHow you implement it
TextMate grammarLezer parser + CodeMirror LanguageregisterEditorExtension(markupEditor(langPackage()), viewType)
Language configurationCodeMirror languageData + shared editor configPer-language close-bracket rules, indent behavior, or shared defaults in the editor shell
SnippetsNot a first-class manifest contributionRegister CodeMirror autocomplete or use command-based insertion
contributes.languageslapis.contributes.languagesDeclares language IDs for activation indexing; code still registers parsers
Language Server (LSP)LanguageServiceProviderManifest contributes.services or Plugin.registerLapisServiceProvider()
DiagnosticsprovideDiagnostics on a language-service providerRendered through shared CodeMirror lint adapters
CompletionprovideCompletions or CodeMirror autocompleteTypeScript uses language services; markdown links use editor extensions
HoverprovideHoverTypeScript only today; wired through languageServiceExtensions()
Go to definitionprovideDefinitionProvider API exists; editor UI binding is not shipped yet
Custom editorregisterEditorView() + registerView()Metadata in manifest optional; constructor registration required
File associationregisterExtensions() + workspace.editorAssociationsGlob patterns in user settings or filenamePatterns on editor views
Extension manifestmanifest.json + lapis namespaceSee Lapis manifest
contributes.configurationlapis.contributes.configurationJSON Schema properties rendered in Settings
contributes.commandslapis.contributes.commandsManifest-only commands with optional when clauses
Activation eventslapis.activationEventsLazy activation for Lapis extensions
Context keys / whenApp.contextKeys + manifest whenShared evaluator for command and contribution visibility
  • Contribution manifest. Optional lapis.contributes in manifest.json indexes commands, configuration, languages, editor views, and services before plugin code runs.
  • Activation events. onCommand:, onLanguage:, onService:, and similar events defer code execution until needed.
  • Context keys and when clauses. Declarative contributions can gate visibility on editor and workspace state.
  • Editor associations. Users can map glob patterns to editor-view IDs, similar to VS Code’s workbench.editorAssociations.
  • Command label icons. Command names can include VS Code-style $(play) or $(lucide:file-text) icon tokens.
  • Editor engine. Lapis uses CodeMirror 6, not Monaco or VS Code’s editor stack.
  • Syntax. Lezer grammars replace TextMate. The markdown plugin extends CodeMirror’s Markdown parser with wiki links, tags, grid tables, and directives.
  • Language intelligence. Providers implement a Lapis-specific contract consumed by app.languageServices, not JSON-RPC LSP messages.
  • Plugin host. Community plugins follow the Obsidian-compatible JavaScript plugin model. The lapis namespace extends that model rather than replacing it.

Many features need both layers:

FeatureManifest (declarative)Code (imperative)
Markdown lint diagnosticscontributes.services + contributes.configurationSystem extension binds the provider at boot
TypeScript completionsOptional service metadataLangCode plugin registers CodeMirror extensions with languageServiceExtensions()
Custom file editorcontributes.editorViews metadataregisterView() + registerEditorView() + registerExtensions()
Sidebar commandcontributes.commandsOptional callback after lazy activation

Rule of thumb:

  • Use the manifest when Lapis can install metadata, settings, or service declarations without running your plugin code.
  • Use imperative registration when you need a view constructor, CodeMirror extension, or provider implementation.

Manifest-only plugins can contribute commands, settings, status bar items, editor-view metadata, and language-service bindings. They cannot register CodeMirror extensions or custom view classes without code.

Language-service providers can run in different hosts:

RuntimeWhere it runsTypical use
workerBrowser Web Workermarkdownlint, TypeScript in PWA
nativeDesktop Electron sidecarHigher-priority TypeScript and markdownlint on desktop
in-processRenderer main threadLightweight or test providers

When multiple providers target the same language and capability, Lapis merges results by priority (higher number wins for diagnostics; first successful provider wins for completions and hover).