дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
* feat(editor): Drag tabs and files between split panes
HTML5 drag and drop never reaches the webview while native file drop is
enabled, so tab, project-file and changelist drags did nothing. They now
run on pointer events:
- Drag an editor tab onto another pane, or onto a pane's edge to split it.
- Drag files from the Project view into an editor pane (center opens them
there, an edge opens them in a new split).
- Drag files between changelists in the Commit view.
- "Drag-and-drop with Alt pressed only" applies to tabs and stripe buttons.
* fix(lsp): Deliver server settings and start servers on a supported JDK
- workspace/configuration answers a server's own section (basedpyright)
from its settings block; basedpyright runs in "standard" mode and keeps
auto search paths on, so `src/` layouts resolve from `tests/`.
- jdtls: formatting follows the editor indent, calls complete without
guessed arguments, and JDK internals stay out of completion.
- `max-java` in a language server config picks an installed JDK no newer
than that (kotlin-language-server fails on JDK 25).
- Server initialization may take up to 5 minutes (first Gradle import).
- `lsp_resend_diagnostics` re-emits stored diagnostics after a reload.
- Spelling only checks declared names (not called methods like
`substring`) and accepts plurals of known software terms.
* feat(editor): Quick fixes, completion and navigation while typing
Quick fixes
- Errors get a red quick-fix bulb; Apply Quick Fix (⌥⇧↵) fixes the most
severe problem at the caret, and the error hover offers the fix directly.
- Code generated by a code action is re-indented to the file's style.
- Python: Implement abstract methods (⌃I or the bulb) from the bases.
- Duplicate code actions are listed once.
Completion
- Overloads sharing a name, and a name importable from several modules,
are no longer merged into one entry.
- Auto-import entries show the module they import from.
- Call snippets without a stop (`new ArrayList<>()`) leave the caret inside
the parentheses with parameter info, or past them when nothing takes
arguments; parameter info also opens after server call snippets.
- The selected item is resolved ahead of acceptance, so its auto-import
is applied (rust-analyzer).
Navigation and diagnostics
- Language server requests wait for pending edits, so Go to Declaration
right after typing answers for the current text; an empty answer right
after an edit is retried while the server catches up.
- Diagnostics come back after a window reload; error underlines stay
visible under typo / unused highlighting.
- Implementation gutter markers no longer refresh in a loop while the
server reports progress.
- A missing alternative server no longer shows as a server error.
* chore(lint): Skip agent worktrees under .claude
* fix(editor): Skip cancelled LSP requests and limit generated-code reformat
- Requests cancelled while waiting for pending edits are not sent.
- Code generated by an action is reformatted per changed hunk, so an added
import doesn't reformat the code between it and the generated lines.
- A long busy spell caused by a settle refresh re-runs it only once.
- Files dropped on a file row of another changelist move to that changelist.
- Python Implement methods: a nested class without bases ends the lookup,
class bodies continue through unindented string lines, and
`@abstractproperty` stubs become `@property`.
- Resend diagnostics goes through the host ops, and custom servers get
`max_java`.
* fix(editor): Rank the exact type first in Java constructor completion
jdtls appends the call or body to filterText (`String(${0})`); matching
on the label instead lets typing `String` rank `String` above
`StringBuilder` and the other types sharing its sort text.
* fix(editor): List identical completion items once
kotlin-language-server repeats a class once per classpath entry declaring
it, so `String()` and `String` were listed three times each.
* fix(editor): Keep the internal cancellation message out of the UI text catalog
199 рядки
7.0 KiB
Rust
199 рядки
7.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::{FileTypes, LanguageRegistry};
|
||
pub use syntax::{
|
||
CSS_CLASS, CSS_ID, CSS_VARIABLE, FileReference, Literal, LiteralKind, MAX_CACHED_TREES, MAX_PARSE_BYTES,
|
||
ParsedTree, SpellingKind, SpellingRegion, Syntax, SyntaxCache, SyntaxCacheStats, SyntaxHighlightKind,
|
||
SyntaxHighlights, TreeError, WebReference, WebReferenceKind, merge_visibility,
|
||
};
|
||
|
||
/// 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>,
|
||
/// Answers `workspace/configuration`; without it the sections are looked up
|
||
/// in `initialization_options`.
|
||
#[serde(default)]
|
||
pub settings: Option<serde_json::Value>,
|
||
/// Human hint shown when the binary is missing.
|
||
#[serde(default)]
|
||
pub install_hint: Option<String>,
|
||
/// `host:port` of a server that speaks LSP over TCP (Godot's editor). Connects
|
||
/// there when something listens; otherwise starts `command` (when installed)
|
||
/// and connects once it accepts: to `127.0.0.1:${port}` when the arguments
|
||
/// contain `${port}` (a free port), else to this address. `${root}` in the
|
||
/// arguments is the workspace root. A server reached without starting it is
|
||
/// never shut down or killed by the IDE.
|
||
#[serde(default)]
|
||
pub connect: 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,
|
||
/// Newest Java release the server runs on (kotlin-language-server: 21). A
|
||
/// newer `JAVA_HOME` is replaced by the newest installed JDK that fits.
|
||
#[serde(default)]
|
||
pub max_java: Option<u32>,
|
||
/// 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,
|
||
/// `tcp` only: `host:port` of an adapter running inside another program (the
|
||
/// Godot editor). Used when it accepts connections; otherwise `command` is started.
|
||
#[serde(default)]
|
||
pub connect: Option<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,
|
||
/// Names of the configured language servers (Settings › Inspections).
|
||
#[serde(default)]
|
||
#[specta(optional)]
|
||
pub language_servers: Vec<String>,
|
||
/// Exact file names and file-name patterns of the definition (Settings › File Types).
|
||
#[serde(default)]
|
||
#[specta(optional)]
|
||
pub filenames: Vec<String>,
|
||
/// First-line regex of the definition (shebangs, `<?php`).
|
||
#[serde(default)]
|
||
#[specta(optional)]
|
||
pub first_line: Option<String>,
|
||
}
|
||
|
||
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(),
|
||
language_servers: c.language_servers.iter().map(|s| s.name.clone()).collect(),
|
||
filenames: c.filenames.clone(),
|
||
first_line: c.first_line.clone(),
|
||
}
|
||
}
|
||
}
|
||
|
||
#[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,
|
||
}
|