diff --git a/modules/vscode.nix b/modules/vscode.nix index ec50c2c..6d07965 100644 --- a/modules/vscode.nix +++ b/modules/vscode.nix @@ -7,7 +7,9 @@ vscode = pkgs.vscode-extensions; in [ - vscode.charliermarsh.ruff + # Built from source (see vscode/ruff) to drop the spurious binary-lookup + # modal; nixpkgs' prebuilt `vscode.charliermarsh.ruff` shows it. + (pkgs.callPackage ../vscode/ruff { }) vscode.esbenp.prettier-vscode vscode.github.vscode-github-actions vscode.gplane.wasm-language-tools diff --git a/vscode/ruff/default.nix b/vscode/ruff/default.nix new file mode 100644 index 0000000..1b64521 --- /dev/null +++ b/vscode/ruff/default.nix @@ -0,0 +1,75 @@ +# The Ruff VS Code extension, built from source (nixpkgs ships the prebuilt +# Marketplace VSIX) so we can patch its TypeScript rather than minified JS. +# +# The patch drops the modal error the extension pops when its interpreter probe +# throws -- which happens in non-Python projects where direnv has leaked the Nix +# SDK's DEVELOPER_DIR and thereby broken Apple's /usr/bin/python3 shim. The +# extension already falls back to the bundled ruff and works, so we keep only +# the log line. +# +# To bump `version`, refresh both hashes: +# nix flake prefetch github:astral-sh/ruff-vscode/ # -> hash +# nix run nixpkgs#prefetch-npm-deps -- /package-lock.json # -> npmDepsHash +# and re-check that no-popup.patch still applies (it fails loudly if not). +{ + lib, + buildNpmPackage, + fetchFromGitHub, + ruff, +}: + +buildNpmPackage rec { + pname = "vscode-extension-charliermarsh-ruff"; + version = "2026.56.0"; + + src = fetchFromGitHub { + owner = "astral-sh"; + repo = "ruff-vscode"; + rev = version; + hash = "sha256-96aITdErMnwJmhMmu2MUSVDu1kOavizUZWYQKFuIR6g="; + }; + + npmDepsHash = "sha256-sHv1J1O1q64161ImBOja8m6xzH+vmk3gsYkQc3YYNk8="; + + patches = [ ./no-popup.patch ]; + + # Match upstream's `npm ci --ignore-scripts`; the deps are pure JS. + npmFlags = [ "--ignore-scripts" ]; + + # `npm run package` == webpack --mode production -> dist/extension.js + npmBuildScript = "package"; + + # home-manager's vscode module reads these off each extension (unconditionally, + # via nixpkgs' vscode-utils `toExtensionJsonEntry`) to write extensions.json. + # nixpkgs' marketplace builder attaches them; a bare buildNpmPackage does not. + passthru = { + vscodeExtPublisher = "charliermarsh"; + vscodeExtName = "ruff"; + vscodeExtUniqueId = "charliermarsh.ruff"; + }; + + installPhase = '' + runHook preInstall + + ext="$out/share/vscode/extensions/charliermarsh.ruff" + mkdir -p "$ext/bundled" + + cp package.json icon.png README.md CHANGELOG.md LICENSE "$ext/" + cp -r dist "$ext/dist" + cp -r bundled/tool "$ext/bundled/tool" + + # The native server (ruff.nativeServer, the default) runs this ruff binary + # directly. We skip the rest of bundled/libs -- the deprecated ruff-lsp + # Python stack, only used when ruff.nativeServer = "off". + mkdir -p "$ext/bundled/libs/bin" + ln -s ${lib.getExe ruff} "$ext/bundled/libs/bin/ruff" + + runHook postInstall + ''; + + meta = { + description = "Ruff VS Code extension, from source, with the spurious binary-lookup modal removed"; + homepage = "https://github.com/astral-sh/ruff-vscode"; + license = lib.licenses.mit; + }; +} diff --git a/vscode/ruff/no-popup.patch b/vscode/ruff/no-popup.patch new file mode 100644 index 0000000..26bfe6b --- /dev/null +++ b/vscode/ruff/no-popup.patch @@ -0,0 +1,21 @@ +diff --git a/src/common/server.ts b/src/common/server.ts +index aba6275..9d02aae 100644 +--- a/src/common/server.ts ++++ b/src/common/server.ts +@@ -203,16 +203,6 @@ export async function findRuffBinaryPath( + ]); + ruffBinaryPath = stdout.trim(); + } catch (err) { +- vscode.window +- .showErrorMessage( +- "Unexpected error while trying to find the Ruff binary. See the logs for more details.", +- "Show Logs", +- ) +- .then((selection) => { +- if (selection) { +- logger.channel.show(); +- } +- }); + logger.error(`Error while trying to find the Ruff binary: ${err}`); + } + } else {