Skip to content

Support multi-root workspaces for MkDocs config auto-detection #47

Description

@jcouball

Description

The extension currently has limited support for multi-root workspaces. While it loads configuration and monitors files from the first workspace folder, it does not properly handle multiple workspace folders where each may have its own mkdocs.yml configuration.

Current Limitations

  1. Single Config Loading: Only loads mkdocs.yml from workspaceFolders[0] on activation
  2. Single File Watcher: Creates only one file system watcher for the first workspace folder
  3. No Per-Folder State: DiagnosticManager doesn't maintain separate config state for each workspace folder
  4. Config Changes: Changes to mkdocs.yml in secondary workspace folders are not detected

Expected Behavior

  • Each workspace folder should have its own mkdocs.yml config loaded
  • File system watchers should monitor each workspace folder's root for config changes
  • DiagnosticManager should maintain per-folder config state
  • When a document is opened, the extension should determine which workspace folder it belongs to and use that folder's config

Implementation Approach

From PR #46 review feedback, the recommended approach is:

1. Load config for all workspace folders on activation

// Load MkDocs configuration on activation for all workspace folders
const workspaceFolders = vscode.workspace.workspaceFolders;
if (workspaceFolders && workspaceFolders.length > 0) {
  for (const folder of workspaceFolders) {
    await diagnosticManager.loadMkdocsConfig(folder.uri.fsPath);
  }
}

2. Create a file watcher per workspace folder

// Watch for changes to mkdocs.yml/mkdocs.yaml in each workspace folder root
if (workspaceFolders && workspaceFolders.length > 0) {
  for (const folder of workspaceFolders) {
    const pattern = new vscode.RelativePattern(folder, '{mkdocs.yml,mkdocs.yaml}');
    const mkdocsWatcher = vscode.workspace.createFileSystemWatcher(
      pattern,
      false, // ignoreCreateEvents
      false, // ignoreChangeEvents
      false  // ignoreDeleteEvents
    );

    // Reload config for this workspace folder and refresh diagnostics
    const reloadMkdocsConfig = async (_uri: vscode.Uri) => {
      await diagnosticManager.loadMkdocsConfig(folder.uri.fsPath);

      // Refresh diagnostics for all open markdown files
      vscode.window.visibleTextEditors
        .filter(editor => editor.document.languageId === 'markdown')
        .forEach(editor => {
          diagnosticManager.updateDiagnostics(editor.document);
        });
    };

    mkdocsWatcher.onDidCreate(reloadMkdocsConfig, undefined, context.subscriptions);
    mkdocsWatcher.onDidChange(reloadMkdocsConfig, undefined, context.subscriptions);
    mkdocsWatcher.onDidDelete(reloadMkdocsConfig, undefined, context.subscriptions);
    context.subscriptions.push(mkdocsWatcher);
  }
}

3. Update DiagnosticManager to store per-folder config

The DiagnosticManager class needs to:

  • Store a Map<string, MkdocsConfig> where key is the workspace folder path
  • When loadMkdocsConfig(workspacePath) is called, store the config for that specific folder
  • When updating diagnostics for a document, determine which workspace folder the document belongs to and use that folder's config
  • Use vscode.workspace.getWorkspaceFolder(document.uri) to determine the correct folder

Related Files

  • src/extension.ts - Activation logic and file watchers
  • src/diagnosticManager.ts - Config storage and diagnostic severity resolution
  • src/severityResolver.ts - May need workspace folder context

Testing Requirements

  • Unit tests for per-folder config storage in DiagnosticManager
  • Integration tests with mock multi-root workspace
  • Verify correct config is used for documents in different workspace folders
  • Verify config changes in one folder don't affect other folders

Priority

Medium - Works correctly for single-folder workspaces (most common case), but should be improved for multi-root workspace users.

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Fields

    No fields configured for issues without a type.

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions