astral-sh / astral-sh/ruff-vscode
Feature: Add virtual workspace support
- 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
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