Code View

fson / vscode-ffsmd / extension / extension.js
// SPDX-License-Identifier: MIT
// FFS-MD VS Code extension — activation.
//
// The highlighting is injection-only (no language of its own), so there is
// no `ffsmd` document type to attach a formatter to. Instead this extension
// contributes:
//   1. a command "FFS-MD: Format Document (FFS-MD)" that formats the active
//      Markdown editor with the conservative FFS-MD formatter, and
//   2. an OPT-IN document formatter for `markdown` — off by default, enabled
//      with the setting `ffsmd.format.enable`, so users who want
//      Format Document / format-on-save to use the FFS-MD rules can turn it
//      on without it hijacking every Markdown file by default.
//
// The formatter is conservative and render-neutral (see MDFORMAT.md): it
// normalizes FFS directive fields and safe whitespace, and never touches
// fenced-code content or Markdown structure.

const vscode = require('vscode');
const { format } = require('./formatter');

function makeEdits(document) {
  const original = document.getText();
  let output;
  try {
    output = format(original);
  } catch (err) {
    vscode.window.showErrorMessage(
      'FFS-MD: could not format document — ' + (err && err.message)
    );
    return [];
  }
  if (output === original) return [];
  const fullRange = new vscode.Range(
    document.positionAt(0),
    document.positionAt(original.length)
  );
  return [vscode.TextEdit.replace(fullRange, output)];
}

function activate(context) {
  // 1. explicit command — always available
  context.subscriptions.push(
    vscode.commands.registerCommand('ffsmd.formatDocument', async () => {
      const editor = vscode.window.activeTextEditor;
      if (!editor || editor.document.languageId !== 'markdown') {
        vscode.window.showInformationMessage(
          'FFS-MD: open a Markdown document to format it.'
        );
        return;
      }
      const edits = makeEdits(editor.document);
      if (edits.length === 0) return;
      const wsEdit = new vscode.WorkspaceEdit();
      wsEdit.set(editor.document.uri, edits);
      await vscode.workspace.applyEdit(wsEdit);
    })
  );

  // 2. opt-in document formatter for markdown
  const provider = {
    provideDocumentFormattingEdits(document) {
      const enabled = vscode.workspace
        .getConfiguration('ffsmd.format')
        .get('enable', false);
      if (!enabled) return [];
      return makeEdits(document);
    },
  };
  context.subscriptions.push(
    vscode.languages.registerDocumentFormattingEditProvider(
      { language: 'markdown', scheme: 'file' },
      provider
    ),
    vscode.languages.registerDocumentFormattingEditProvider(
      { language: 'markdown', scheme: 'untitled' },
      provider
    )
  );
}

function deactivate() {}

module.exports = { activate, deactivate };