Skip to content

Instantly share code, notes, and snippets.

@pickx
Last active May 17, 2024 22:35
Show Gist options
  • Save pickx/ae3bd64b88681c8f2960961a061c5f7e to your computer and use it in GitHub Desktop.
Save pickx/ae3bd64b88681c8f2960961a061c5f7e to your computer and use it in GitHub Desktop.
Patch Pylance's VSCode check
#!/usr/bin/env -S cargo +nightly -Zscript --quiet
---
[package]
edition = "2021"
[dependencies]
eyre = "0.6.12"
home = "0.5.9"
---
use eyre::OptionExt;
use std::fs;
use std::io::Write;
use std::path::PathBuf;
const COMMENT_START: &str = "/*";
const COMMENT_END: &str = "*/";
fn file_path() -> eyre::Result<PathBuf> {
let home_dir = home::home_dir()
.filter(|dir| !dir.as_os_str().is_empty())
.ok_or_eyre("could not fetch home dir")?;
let extensions_dir = home_dir.join(".vscode-oss/extensions");
let pylance_dir = fs::read_dir(extensions_dir)?
.filter_map(|entry| {
let entry = entry.ok()?;
let ty = entry.file_type().ok()?;
let file_name = entry.file_name();
if ty.is_dir() && file_name.to_str()?.starts_with("ms-python.vscode-pylance") {
Some(entry)
} else {
None
}
})
.max_by_key(|entry| {
let create_time = entry.metadata().and_then(|metadata| metadata.created());
create_time.ok() // `None` will always be ordered lower than `Some(time)`
})
.ok_or_eyre("no pylance dirs found in VSCodium extension dir")?
.path();
Ok(pylance_dir.join("dist/extension.bundle.js"))
}
fn pattern_start_and_end(s: &str) -> eyre::Result<(usize, usize)> {
let (start, end) =
find_pattern_delimiters(s).ok_or_eyre("expected pattern not found in file")?;
if s[..start].ends_with(COMMENT_START) || s[end..].starts_with(COMMENT_END) {
eyre::bail!("file already has comments at expected positions")
}
Ok((start, end))
}
fn find_pattern_delimiters(s: &str) -> Option<(usize, usize)> {
let anchor = "disposables";
let pattern_start = "return(0x0";
let pattern_end = "};";
s.match_indices(anchor)
.filter_map(|(start_of_anchor, _)| {
let end = start_of_anchor + s[start_of_anchor..].find(pattern_end)? + pattern_end.len();
let start = s[..start_of_anchor].rfind(pattern_start)?;
Some((start, end))
})
.min_by_key(|(start, end)| end - start)
}
fn write_commented_out(
src: &[u8],
start: usize,
end: usize,
mut dst: impl Write,
) -> eyre::Result<()> {
dst.write_all(&src[..start])?;
dst.write_all(COMMENT_START.as_bytes())?;
dst.write_all(&src[start..end])?;
dst.write_all(COMMENT_END.as_bytes())?;
dst.write_all(&src[end..])?;
Ok(())
}
fn main() -> eyre::Result<()> {
let file_path = file_path()?;
println!("found Pylance file to patch: {}", file_path.display());
let content = fs::read_to_string(&file_path)?;
let (start, end) = pattern_start_and_end(&content)?;
let file = fs::File::create(&file_path)?;
write_commented_out(content.as_bytes(), start, end, file)?;
println!("file patched successfully!");
Ok(())
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment