дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-08 19:02:17 +02:00
ngserver (@angular/language-server) runs next to vtsls and the HTML server in Angular projects, bringing completion, hover, definition, diagnostics, references and rename to external and inline component templates. A language server can now require a root marker (require-root-marker), so the Angular server only serves files below angular.json or node_modules/@angular/core and never hides the typescript-language-server fallback elsewhere. Attached servers keep definition order, and rename merges the edits of every server that accepts the position. Installable from the tools registry via npm. Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA Co-authored-by: nntndfrk <[email protected]>
37 рядки
1.5 KiB
Rust
37 рядки
1.5 KiB
Rust
//! Node-based language servers installed with npm: the package behind a command.
|
|
|
|
use std::ffi::OsStr;
|
|
use std::path::{Path, PathBuf};
|
|
|
|
/// `command` as given (a path) or found on `path`, npm shims included.
|
|
pub(crate) fn find_command(command: &str, path: &OsStr) -> Option<PathBuf> {
|
|
let p = Path::new(command);
|
|
if p.is_absolute() {
|
|
return p.is_file().then(|| p.to_path_buf());
|
|
}
|
|
let exts: &[&str] = if cfg!(windows) { &[".cmd", ".exe", ""] } else { &[""] };
|
|
std::env::split_paths(path)
|
|
.flat_map(|d| exts.iter().map(move |e| d.join(format!("{command}{e}"))))
|
|
.find(|c| c.is_file())
|
|
}
|
|
|
|
/// The npm package an executable comes from: next to a `node_modules/.bin` shim
|
|
/// (the IDE's tools dir, a project), a Windows global shim (`%APPDATA%\npm`), a
|
|
/// Unix global `<prefix>/bin` or a symlink into the package.
|
|
pub(crate) fn package_dir(bin: &Path, package: &str) -> Option<PathBuf> {
|
|
let dir = bin.parent()?;
|
|
let mut candidates = vec![dir.join("node_modules").join(package)];
|
|
if dir.file_name() == Some(OsStr::new(".bin"))
|
|
&& let Some(node_modules) = dir.parent()
|
|
{
|
|
candidates.push(node_modules.join(package));
|
|
}
|
|
if let Ok(real) = dunce::canonicalize(bin) {
|
|
candidates.extend(real.ancestors().filter(|a| a.ends_with(package)).map(Path::to_path_buf));
|
|
}
|
|
if let Some(prefix) = dir.parent() {
|
|
candidates.push(prefix.join("lib").join("node_modules").join(package));
|
|
}
|
|
candidates.into_iter().find(|c| c.join("package.json").is_file())
|
|
}
|