Plugins

Authoring

Write an editor plugin.

A plugin is a plain object from a factory. Everything is optional except name.

import { definePlugin } from 'comark-codemirror'

export default definePlugin<{ icons?: string[] }>((options = {}) => ({
  name: 'icons',
  // manifest entries (merged by name)
  components: [{ name: 'icon', kind: 'inline', props: { name: { enum: options.icons ?? ['star', 'heart'] } } }],
  // items for a context kind
  completions: [{
    kinds: ['attr-value'],
    provide: ({ context }) => (context.name === 'name' ? (options.icons ?? []).map(i => ({ label: i, glyph: '★', exit: true, chain: true })) : null),
  }],
  // entries in the block (`/`) or inline menu
  snippets: [{ label: 'Icon row', insert: ':icon{name="$1"} :icon{name="$2"}', section: 'Media' }],
  // binding roots
  scopes: [() => ({ name: 'meta', shape: { type: 'object', properties: { icons: { type: 'array' } } } })],
  lint: [({ state, index }) => []],
  hover: [({ pos }) => null],
  commands: [],
  // fence languages offered after ```
  fences: ['icons'],
  // a note for agents (llms())
  llms: 'Icons: `:icon{name="star"}`.',
  // anything else CodeMirror
  extensions: [],
}))

Items

Field
labelwhat is shown and matched
inserttemplate; $0 is the cursor, ${1:text} adds Tab stops; braces are literal
detail, inforight column, docs panel (string or { title, description, rows, example, value, link })
typeicon: component, prop, value, slot, binding-key, snippet, …
section, boostgrouping and ranking
chainreopen the menu after this pick
drillhas a next level (chevron, → key)
commitkeys that accept it (and are not typed)
exitstep over the closing quote of an attribute value
glyph, swatcha leading character or a color
applya custom CodeMirror apply function

Providers get { context, state, index, config, explicit, scopes() } — the cursor context, the document index (outline, frontmatter, headings, footnotes, usages) and the binding roots at the cursor. They may be async.

Convention

A comark plugin package can ship its editor plugin at <package>/editor, so one install gives both the renderer and the editor support.

Copyright © 2026