дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
* fix(lsp): Run jdtls on a JDK 21+ and offer Install in the server popup jdtls refuses to start on Java < 21, and its launcher took whatever JAVA_HOME / PATH pointed at, so it crash-looped with a Python traceback when that was an older JDK (#1). Pick the first detected JDK 21+ and pass it via JAVA_HOME; projects still compile against their own runtimes. When none is found, report a clear message instead of launching, and rescan on restart so a newly installed JDK is picked up. JDK detection now also covers the java on PATH and Windows vendor directories. The Language Servers status popup showed the manual install hint for missing servers; it now has an Install button that runs tools.install, which opens the Language Servers settings page for tools the IDE cannot install itself. Fixes #1 Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu * fix(lsp): Address review of the jdtls runtime check - Cache the JDK scan and rescan at most every 10s while no JDK 21+ is found, refreshing the shared list instead of discarding it; skip duplicate Windows Program Files roots. - Check `launch_error` in the manager (inside the blocking launch task) rather than in ProcessLauncher, and skip such servers in batch inspection. - Keep the install hint visible next to the Install button; when the tool list failed to load, try the install so the error is reported. - Don't let a server snapshot requested before a status event overwrite that newer status (left jdtls showing "Starting…" while missing).
160 рядки
5.0 KiB
Rust
160 рядки
5.0 KiB
Rust
//! Language registry and syntax-tree powered structure.
|
|
//!
|
|
//! Every language is described by `languages/<id>.toml` at the repo root
|
|
//! (embedded at build time). Tree-sitter gives zero-config outline, folding
|
|
//! and symbol tags; LSP/DAP configs are consumed by `ide-lsp` / `ide-dap`.
|
|
|
|
use ide_core::{LanguageId, Range, SymbolKind};
|
|
use serde::{Deserialize, Serialize};
|
|
use specta::Type;
|
|
use std::collections::BTreeMap;
|
|
|
|
mod registry;
|
|
mod syntax;
|
|
pub use registry::LanguageRegistry;
|
|
pub use syntax::{MAX_CACHED_TREES, MAX_PARSE_BYTES, ParsedTree, Syntax, SyntaxCache, SyntaxCacheStats, TreeError};
|
|
|
|
/// Parsed form of `languages/<id>.toml`. Backend-only; the UI gets [`LanguageInfo`].
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
#[serde(rename_all = "kebab-case")]
|
|
pub struct LanguageConfig {
|
|
pub id: LanguageId,
|
|
pub name: String,
|
|
#[serde(default)]
|
|
pub extensions: Vec<String>,
|
|
/// Exact file names, e.g. `Cargo.lock`, `Dockerfile`.
|
|
#[serde(default)]
|
|
pub filenames: Vec<String>,
|
|
/// First-line regex, e.g. shebang `^#!.*\bpython`.
|
|
#[serde(default)]
|
|
pub first_line: Option<String>,
|
|
#[serde(default)]
|
|
pub line_comment: Option<String>,
|
|
#[serde(default)]
|
|
pub block_comment: Option<(String, String)>,
|
|
#[serde(default)]
|
|
pub indent: Option<IndentConfig>,
|
|
/// Name of the CodeMirror/Lezer language the UI should load for instant highlighting.
|
|
#[serde(default)]
|
|
pub ui_mode: Option<String>,
|
|
#[serde(default)]
|
|
pub tree_sitter: Option<String>,
|
|
#[serde(default)]
|
|
pub language_servers: Vec<LanguageServerConfig>,
|
|
#[serde(default)]
|
|
pub debugger: Option<DebuggerConfig>,
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, Serialize, Deserialize, Type)]
|
|
#[serde(rename_all(serialize = "camelCase", deserialize = "kebab-case"))]
|
|
pub struct IndentConfig {
|
|
pub tab_size: u32,
|
|
pub insert_spaces: bool,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Serialize, Deserialize)]
|
|
#[serde(rename_all = "kebab-case")]
|
|
pub struct LanguageServerConfig {
|
|
/// Stable name, e.g. `rust-analyzer`.
|
|
pub name: String,
|
|
pub command: String,
|
|
#[serde(default)]
|
|
pub args: Vec<String>,
|
|
#[serde(default)]
|
|
pub env: BTreeMap<String, String>,
|
|
/// Files whose presence marks a workspace root, e.g. `Cargo.toml`.
|
|
#[serde(default)]
|
|
pub root_markers: Vec<String>,
|
|
/// JSON passed as `initializationOptions`.
|
|
#[serde(default)]
|
|
pub initialization_options: Option<toml::Value>,
|
|
/// Human hint shown when the binary is missing.
|
|
#[serde(default)]
|
|
pub install_hint: Option<String>,
|
|
/// An alternative to the servers listed before it (pyright after
|
|
/// basedpyright): only used while none of those is installed.
|
|
#[serde(default)]
|
|
pub fallback: bool,
|
|
/// Set by the settings hook when the server can't run here (jdtls without
|
|
/// a JDK 21+); reported as the failure instead of launching it.
|
|
#[serde(skip)]
|
|
pub launch_error: Option<String>,
|
|
}
|
|
|
|
#[derive(Clone, Debug, Serialize, Deserialize)]
|
|
#[serde(rename_all = "kebab-case")]
|
|
pub struct DebuggerConfig {
|
|
/// DAP adapter name, e.g. `codelldb`, `debugpy`, `js-debug`, `delve`.
|
|
pub adapter: String,
|
|
pub command: String,
|
|
#[serde(default)]
|
|
pub args: Vec<String>,
|
|
/// `stdio` or `tcp`.
|
|
#[serde(default = "default_transport")]
|
|
pub transport: String,
|
|
#[serde(default)]
|
|
pub install_hint: Option<String>,
|
|
}
|
|
|
|
fn default_transport() -> String {
|
|
"stdio".into()
|
|
}
|
|
|
|
/// The UI-facing view of a language.
|
|
#[derive(Clone, Debug, Serialize, Deserialize, Type)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct LanguageInfo {
|
|
pub id: LanguageId,
|
|
pub name: String,
|
|
pub extensions: Vec<String>,
|
|
pub ui_mode: Option<String>,
|
|
pub line_comment: Option<String>,
|
|
pub block_comment: Option<(String, String)>,
|
|
pub indent: Option<IndentConfig>,
|
|
/// A debug adapter is configured (breakpoints make sense in these files).
|
|
#[serde(default)]
|
|
#[specta(optional)]
|
|
pub debuggable: bool,
|
|
}
|
|
|
|
impl From<&LanguageConfig> for LanguageInfo {
|
|
fn from(c: &LanguageConfig) -> Self {
|
|
Self {
|
|
id: c.id.clone(),
|
|
name: c.name.clone(),
|
|
extensions: c.extensions.clone(),
|
|
ui_mode: c.ui_mode.clone(),
|
|
line_comment: c.line_comment.clone(),
|
|
block_comment: c.block_comment.clone(),
|
|
indent: c.indent,
|
|
debuggable: c.debugger.is_some(),
|
|
}
|
|
}
|
|
}
|
|
|
|
#[derive(Clone, Copy, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub enum FoldKind {
|
|
Region,
|
|
Comment,
|
|
Imports,
|
|
}
|
|
|
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
|
|
pub struct FoldRange {
|
|
pub start_line: u32,
|
|
pub end_line: u32,
|
|
pub kind: FoldKind,
|
|
}
|
|
|
|
/// A symbol definition extracted for the project index.
|
|
#[derive(Clone, Debug, PartialEq, Eq, Serialize, Deserialize, Type)]
|
|
#[serde(rename_all = "camelCase")]
|
|
pub struct SymbolTag {
|
|
pub name: String,
|
|
pub kind: SymbolKind,
|
|
/// Enclosing symbol, e.g. class name for a method.
|
|
pub container: Option<String>,
|
|
pub range: Range,
|
|
}
|