use std::path::PathBuf;
#[cfg(unix)]
mod unix;
#[cfg(windows)]
mod windows;
#[cfg(unix)]
use unix as imp;
#[cfg(windows)]
use windows as imp;
pub fn home_dir() -> Option<PathBuf> {
imp::home_dir()
}
pub fn temp_dir() -> PathBuf {
imp::temp_dir()
}
pub fn denied_read_prefixes() -> &'static [&'static str] {
imp::denied_read_prefixes()
}
pub fn shell_tokenize(cmd: &str) -> Result<Vec<String>, String> {
imp::shell_tokenize(cmd)
}
pub fn terminate_process(pid: u32) -> std::io::Result<()> {
imp::terminate_process(pid)
}
pub fn process_alive(pid: u32) -> bool {
imp::process_alive(pid)
}
pub fn rename_overwrite(from: &std::path::Path, to: &std::path::Path) -> std::io::Result<()> {
imp::rename_overwrite(from, to)
}
pub fn lsp_binary_name(base: &str) -> String {
imp::lsp_binary_name(base)
}
pub fn build_windows_cmdline(cmd: &str) -> String {
format!("/C \"{cmd}\"")
}
#[cfg_attr(not(windows), allow(dead_code))]
pub(crate) fn lsp_binary_name_with(base: &str, exists: impl Fn(&str) -> bool) -> String {
let dual_packaged = matches!(
base,
"typescript-language-server"
| "vscode-json-language-server"
| "yaml-language-server"
| "bash-language-server"
| "pyright-langserver"
);
if !dual_packaged {
return format!("{base}.exe");
}
for ext in ["exe", "cmd", "bat"] {
let candidate = format!("{base}.{ext}");
if exists(&candidate) {
return candidate;
}
}
format!("{base}.cmd")
}
pub fn shell_command_configured(cmd: &str) -> tokio::process::Command {
imp::shell_command_configured(cmd)
}
#[cfg(test)]
mod tests {
use super::*;
#[test]
fn windows_cmdline_wraps_in_outer_quotes() {
assert_eq!(
build_windows_cmdline(r#"py -c "print(1)""#),
r#"/C "py -c "print(1)"""#
);
assert_eq!(
build_windows_cmdline("git --version"),
r#"/C "git --version""#
);
}
#[test]
fn pyright_prefers_exe_when_only_exe_present() {
let only_exe = |name: &str| name == "pyright-langserver.exe";
assert_eq!(
lsp_binary_name_with("pyright-langserver", only_exe),
"pyright-langserver.exe"
);
}
#[test]
fn pyright_prefers_cmd_when_npm_shim_present() {
let only_cmd = |name: &str| name == "pyright-langserver.cmd";
assert_eq!(
lsp_binary_name_with("pyright-langserver", only_cmd),
"pyright-langserver.cmd"
);
}
#[test]
fn pyright_prefers_exe_when_both_present() {
let both = |_: &str| true;
assert_eq!(
lsp_binary_name_with("pyright-langserver", both),
"pyright-langserver.exe"
);
}
#[test]
fn dual_packaged_falls_back_to_cmd_when_absent() {
let none = |_: &str| false;
assert_eq!(
lsp_binary_name_with("pyright-langserver", none),
"pyright-langserver.cmd"
);
}
#[test]
fn non_dual_packaged_server_uses_exe() {
let none = |_: &str| false;
assert_eq!(
lsp_binary_name_with("rust-analyzer", none),
"rust-analyzer.exe"
);
}
}