astral-sh / astral-sh/ruff-vscode

Feature: Add virtual workspace support

Open
#1,007 7 comments 0 reactions 0 assignees View on GitHub
Dominant language
TypeScript
Stars
1.7k
Forks
80
Avg merge
8h 22m
Merged PRs (30d)
22

Description

## Summary

I'd like to propose adding virtual workspace support to ruff-vscode by exporting a `registerUriTranslator` API — the same pattern Pylance already uses.

## Problem

The extension currently declares `virtualWorkspaces.supported: false`. This blocks Ruff from providing linting/formatting in virtual workspace environments (GitHub Repositories, Microsoft Fabric notebooks, custom `FileSystemProvider` workspaces).

No Python linter or formatter currently supports virtual workspaces (see [microsoft/vscode-python#21459](https://github.com/microsoft/vscode-python/issues/21459)).

## Proposed approach

**Ruff exports `registerUriTranslator()`, the VFS provider owns the cache.**

This is the exact pattern Pylance uses. The VFS provider extension (which already maintains a disk cache for its own purposes) registers a translator with Ruff:

```typescript
const ruff = vscode.extensions.getExtension('charliermarsh.ruff');
await ruff.activate();
ruff.exports.registerUriTranslator({
translateToDisk(uri) { /* virtual URI → cached file:// URI */ },
translateToVirtual(uri) { /* file:// URI → virtual URI */ },
clearTranslationCache() { /* invalidate */ }
});
```

On registration, Ruff restarts its language server with LSP middleware that calls the translator.

**Key point addressing the copy-all-files concern:** Ruff does NOT need to copy any files itself. The VFS provider already maintains a persistent disk cache (for Pylance integration, editor operations, etc.). Ruff simply plugs into that existing cache via the translator interface. The caching is lazy — only files that are actually opened/referenced get cached by the VFS provider.

### Changes needed in ruff-vscode

1. `package.json` — set `virtualWorkspaces.supported: true`
2. New `src/common/uriTranslator.ts` — interface definitions + `registerUriTranslator` export
3. `src/extension.ts` — `activate()` returns the API; on registration triggers server restart
4. `src/common/server.ts` — configure LSP middleware when translator is registered
5. `src/common/settings.ts` / `utilities.ts` — handle non-`file://` URI schemes

Zero changes needed in the Ruff binary — the native `ruff server` already speaks LSP and doesn't care about URI schemes.

## Context

I work on the [Microsoft Fabric Data Engineering VS Code extension](https://marketplace.visualstudio.com/items?itemName=synapsevscode.synapse-vscode) which uses a custom VFS. We already register a URI translator with Pylance for Python IntelliSense. Adding the same integration for Ruff would give our users linting/formatting in virtual workspaces.

## Environment

- Extension version: 2026.40.0
- Ruff version: Any (native server)

Contributor guide

Open the contributing guide

Research direction

Start with package.json, src/extension.ts, src/common/server.ts, src/common/settings.ts, and utilities.ts to trace activation, server restart, middleware, and URI handling. Add the uriTranslator.ts interface and exported registration API, enable virtual workspace support, and verify that registered translators support virtual-workspace linting and formatting without changes to the Ruff binary.

Written by the indexing model from the issue text.

Assessment

Tech stack
typescript, vscode
Domain
developer-experience, devtools
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
45/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.