openpencil/op-vs-code/03-vscode-api-integration.md
2026-03-01 18:23:32 +03:00

7.2 KiB
Raw Blame History

03 — VS Code API Integration

Маппинг функциональности расширения на конкретные VS Code API.

Contribution Points (package.json)

contributes.customEditors

Открытие .fig файлов в VS Code как custom editor.

{
  "customEditors": [{
    "viewType": "openPencil.figEditor",
    "displayName": "OpenPencil Design",
    "selector": [{ "filenamePattern": "*.fig" }],
    "priority": "default"
  }]
}

API: CustomReadonlyEditorProvider (не CustomEditorProvider — .fig файлы не редактируются в VS Code, только просматриваются).

Почему CustomReadonlyEditorProvider, а не CustomEditorProvider:

  • .fig — бинарный формат, VS Code TextDocument не подходит
  • Редактирование .fig требует полный editor (OpenPencil app), не VS Code
  • Readonly избавляет от имплементации save, backup, undo в extension

contributes.viewsContainers

Activity Bar иконка OpenPencil.

{
  "viewsContainers": {
    "activitybar": [{
      "id": "openPencil",
      "title": "OpenPencil",
      "icon": "media/icon.svg"
    }]
  }
}

contributes.views

Tree views в sidebar.

{
  "views": {
    "openPencil": [
      { "id": "openPencil.pages", "name": "Pages", "type": "tree" },
      { "id": "openPencil.components", "name": "Components", "type": "tree" },
      { "id": "openPencil.preview", "name": "Preview", "type": "webview" }
    ]
  }
}

contributes.commands

Command Title Когда
openPencil.openFile Open .fig File Всегда
openPencil.copyCSS Copy CSS Элемент выбран
openPencil.copyTailwind Copy Tailwind Элемент выбран
openPencil.inspectElement Inspect Element Элемент выбран
openPencil.refreshTokens Refresh Design Tokens .fig файл открыт
openPencil.openInApp Open in OpenPencil .fig файл открыт

contributes.configuration

{
  "configuration": {
    "title": "OpenPencil",
    "properties": {
      "openPencil.tokenFormat": {
        "type": "string",
        "enum": ["css-custom-properties", "tailwind", "w3c-design-tokens"],
        "default": "css-custom-properties",
        "description": "Output format for design tokens"
      },
      "openPencil.autoDetectFigFiles": {
        "type": "boolean",
        "default": true,
        "description": "Auto-detect .fig files in workspace"
      },
      "openPencil.tokenNamingConvention": {
        "type": "string",
        "enum": ["kebab-case", "camelCase", "snake_case"],
        "default": "kebab-case"
      }
    }
  }
}

contributes.jsonValidation

Валидация .openpencil.json конфига.

{
  "jsonValidation": [{
    "fileMatch": ".openpencil.json",
    "url": "./schemas/openpencil-config.schema.json"
  }]
}

Language Feature Providers

DocumentColorProvider

Inline color swatches для дизайн-токенов в CSS/SCSS/Vue/TSX файлах.

vscode.languages.registerColorProvider(
  [
    { language: 'css' },
    { language: 'scss' },
    { language: 'vue' },
    { language: 'typescriptreact' }
  ],
  colorProvider
)

Сканирует документ на вхождения CSS custom properties (--op-color-*) или hex-значений, совпадающих с дизайн-токенами. Показывает VS Code color picker с привязкой к token registry.

CompletionItemProvider

Autocomplete для дизайн-токенов.

vscode.languages.registerCompletionItemProvider(
  [{ language: 'css' }, { language: 'scss' }, { language: 'vue' }],
  tokenCompletionProvider,
  '-' // trigger на '--'
)

Предлагает --op-primary-500, --op-font-heading, --op-spacing-md и т.д. при наборе CSS custom properties. Каждый CompletionItem содержит:

  • detail: hex-значение или размер
  • documentation: MarkdownString с preview
  • kind: CompletionItemKind.Color / .Value

HoverProvider

Hover на CSS custom property → popup с превью цвета/значения из дизайна.

vscode.languages.registerHoverProvider(
  [{ language: 'css' }, { language: 'scss' }, { language: 'vue' }],
  tokenHoverProvider
)

CodeLensProvider

CodeLens над Vue/React компонентами, связанными с дизайн-компонентами.

vscode.languages.registerCodeLensProvider(
  [{ language: 'vue' }, { language: 'typescriptreact' }],
  codeLensProvider
)

Показывает "🎨 View in OpenPencil" над компонентами с аннотацией @openpencil-component.

TreeDataProvider

Pages Tree

Показывает все страницы (CANVAS nodes) из .fig файла:

📄 Page 1
📄 Page 2
📄 Components

Components Tree

Показывает все COMPONENT и COMPONENT_SET nodes:

◇ Button
  ◇ Button/Primary
  ◇ Button/Secondary
◇ Card
◇ Input

Каждый TreeItem имеет contextValue для контекстного меню ("Copy CSS", "Inspect").

WebviewViewProvider

Preview Panel

Рендерит выбранный элемент дизайна через CanvasKit в webview.

CSP для webview (подтверждено на примерах pixcil, crabviz, audio-preview):

<meta http-equiv="Content-Security-Policy" content="
  default-src 'none';
  script-src 'nonce-${nonce}' 'wasm-unsafe-eval';
  style-src ${webview.cspSource};
  img-src ${webview.cspSource} blob:;
  connect-src ${webview.cspSource};
">

Ключевое: 'wasm-unsafe-eval' разрешает загрузку CanvasKit WASM.

Communication: extension host ↔ webview через postMessage / onDidReceiveMessage.

FileSystemWatcher

const watcher = vscode.workspace.createFileSystemWatcher('**/*.fig')
watcher.onDidChange(uri => refreshDesignTokens(uri))
watcher.onDidCreate(uri => indexFigFile(uri))
watcher.onDidDelete(uri => removeFromTokenRegistry(uri))

StatusBarItem

const statusBar = vscode.window.createStatusBarItem(
  vscode.StatusBarAlignment.Right,
  100
)
statusBar.text = '$(paintcan) OpenPencil: 3 files'
statusBar.command = 'openPencil.showFiles'

Activation Events

{
  "activationEvents": [
    "onCustomEditor:openPencil.figEditor",
    "workspaceContains:**/*.fig"
  ]
}

Расширение активируется при:

  1. Открытии .fig файла
  2. Наличии .fig файлов в workspace (для autocomplete и token indexing)

Чего НЕ используем

API Причина отказа
WebviewPanel (standalone) Дублирует CustomReadonlyEditorProvider для .fig файлов
CustomEditorProvider (writable) .fig не редактируется в VS Code
CustomTextEditorProvider .fig — бинарный формат
DebugAdapterDescriptorFactory Не применимо
AuthenticationProvider Local-first, нет облака