Commit Graph
60 Commits
Author SHA1 Message Date
l0ng-ai eb258b0912 fix(java): list dependencies' implementations after the project's in Go to Implementation
Go to Implementation on a type or method declared in a dependency (Runnable, a Spring interface) listed only the project's implementations once the project had one. openidea.java.implementations (java-usages 1.5.0) now answers {locations, complete}: complete when the type is declared in the sources, which no dependency implements. Its search also covers the project's Kotlin classes attached by the Kotlin bridge.

When the answer is not complete, ide-lsp passes those found first to the new lsp_goto_implementation channel and runs the standard request for the rest. The chooser opens with the project's implementations ("1 found, searching…") and fills in the dependencies' when the search ends; closing it cancels the search. Gutter markers keep the source-only answer for project types.
2026-11-06 08:14:57 +08:00
l0ng-ai 6026374973 perf(java): find implementations in the project sources first (#1616)
JDT LS answers textDocument/implementation by building the type hierarchy over every dependency jar, so Go to Implementation and the implemented/overridden gutter markers were slow in projects with many dependencies. The app-owned JDT LS bundle (1.4.0) adds openidea.java.implementations: subtypes, or overriding methods with type arguments substituted and abstract ones left out, within the workspace's source folders only. ide-lsp asks it first and falls back to the standard request when the sources have none or the command is missing.
2026-11-06 03:12:18 +08:00
l0ng-ai 07df51f308 fix(lsp): keep rust-analyzer's developer notices out of notifications (#1597)
A rust-analyzer built from source reports its own slow main-loop turns ("overly long loop turn took …") as error messages meant for its developers. They are logged now instead of shown as error notifications.
2026-11-06 01:08:27 +08:00
l0ng-ai dadec04d62 fix(lsp): wait for a loading server before reporting no definition (#1444)
Right after a project opens, rust-analyzer answers navigation with nothing (or withdraws answers with ContentModified) until it has loaded the project, and the client treated both as final, so Go to Definition reported "Cannot find declaration to go to".

The client now enables experimental/serverStatus. While a server reports it is still loading (quiescent: false), an empty or withdrawn definition, declaration, type definition, implementation or hover answer is asked again each time a loading phase ends, for up to 30 s. Servers that don't send serverStatus behave as before.
2026-11-05 20:42:01 +08:00
l0ng-ai 2d20e5a203 fix(lsp): update TypeScript imports when files move (#1346)
vtsls has no workspace/willRenameFiles: after didRenameFiles it updates
imports itself, behind a prompt sent as window/showMessageRequest. The
IDE shows that request as a message without choices, so moving a
TypeScript or JavaScript file never updated the imports of the files
that use it.

For a tsserver-backed server without willRename filters, the IDE now
asks tsserver for the edits up front (getEditsForFileRename through
typescript.tsserverRequest). The edits join the move's preview and undo
like any server's. The server's own update is turned off
(updateImportsOnFileMove.enabled = "never"), so it no longer prompts.
2026-11-05 02:26:28 +08:00
Daniel AdámekandDanielADK f3afe69ca2 feat(php): PHP language level for Intelephense (#1264)
Intelephense checked PHP code against its default 8.5, whatever version the project targets. Settings › Languages & Frameworks › PHP gets a PHP language level, Auto (default: composer.json config.platform.php, else the lowest version require.php allows) or 5.6–8.5, sent as environment.phpVersion; nothing is sent without a requirement. Intelephense applies the version only to documents it parses after reading its configuration, so servers that opt in (resync-on-configuration, Intelephense only) get their open documents again right after workspace/configuration is answered (new jsonrpc Handler::after_response), and Intelephense keeps one index per level because it fixes the built-in functions when it indexes. A change to a root or workspace member composer.json reconfigures the servers.

Co-authored-by: DanielADK <18214958+DanielADK@users.noreply.github.com>
2026-11-05 00:04:01 +08:00
l0ng-ai 20c439baaa fix(lsp): pull diagnostics from servers that provide them (#1307)
rust-analyzer reports its own analysis (a missing field, a wrong type) only
to clients that pull diagnostics; it pushes just `cargo check`'s, so in the
editor a Rust type error showed up only after saving. The client now
advertises `textDocument/diagnostic` and pulls an open file's diagnostics
from servers with a `diagnosticProvider`: when it opens or its server
starts, after edits (once typing pauses), on save (and other open files
for servers with inter-file dependencies) and on
`workspace/diagnostic/refresh`. Pulled and pushed diagnostics are kept
apart and shown, and given to code actions, together; a newer pull
supersedes an older reply, a server-cancelled pull is retried, and closing
a file drops what was pulled.
2026-11-04 23:33:04 +08:00
l0ng-ai 3100aa2c00 feat(scratch): start new scratch files from a language template
A new Java scratch was an empty file that couldn't run until a class and
main method were typed in. Languages can now define `scratch-template` in
`languages/<id>.toml`; a new scratch gets that content with the caret at
`$END$`.

- Java, Kotlin, Go, Rust, C and C++ get a runnable `main`.
- Other languages still start empty.
2026-11-04 21:09:12 +08:00
l0ng-ai 2cd16a723d fix(lsp): let language servers register the files they watch (#1223)
* fix(lsp): resolve newly installed Python packages without a restart

Packages installed into an excluded .venv (uv add, uv pip install) never
reached the Python language servers: the watcher reports changes in excluded
folders only as excluded_dirs, and didChangeWatchedFiles forwarded nothing but
the server's own source files. basedpyright kept its failed import resolution
until restarted.

Language servers get a watched-files list of globs. Files matching it, and
excluded folders matching it, are forwarded too; the Python servers watch
their configuration and site-packages.

* fix(lsp): let servers register the files they watch

Clients now support dynamic registration of workspace/didChangeWatchedFiles,
with relative patterns. Changes on disk go to each server as its registered
watchers match them, including folders in excluded trees (a package installed
into .venv, go.mod rewritten by go get). Folders outside the project that
relative patterns name (a virtualenv elsewhere, a path dependency) get their
own watchers. Servers that register nothing keep hearing of their languages'
files.

Registrations sent right after initialized are no longer dropped while the
server is still being marked ready.

Replaces the per-server watched-files list.
2026-11-04 20:44:24 +08:00
Park Jong Hyun ed145e3046 feat(refactor): Java Pull Members Up / Push Members Down (#1183)
Refactor | Pull Members Up… and Push Members Down… for Java, from the Refactor menu, the editor context menu and Refactor This. A dialog picks the destination and the members (Make abstract / Keep abstract); problems are confirmed before anything changes; the edit is applied as one change or previewed first.

JDT LS offers neither as a code action, so the app-owned JDT LS bundle (plugins/java-usages 1.3.0) adds two delegate commands that run JDT's PullUpRefactoringProcessor / PushDownRefactoringProcessor and return the problems and the edit without applying it, exposed as lsp_hierarchy_members / lsp_hierarchy_refactor (also over the remote host dispatcher). The bundled jar was rebuilt from source with JDT LS 1.63.0 and matches the recorded SHA-256.

Co-authored-by: fhrmrk <81476595+fhrmrk@users.noreply.github.com>
2026-11-04 14:55:42 +08:00
l0ng-ai 770178966f fix(lsp): tell language servers about files changed outside the editor (#1135)
Language servers never got workspace/didChangeWatchedFiles, so files changed on disk outside the editor (checkout, pull, another tool) stayed unknown to them; jdtls's incremental build skipped them and Java / Spring Boot launches ran their old classes (e.g. another module of a multi-module project). The project's file watcher now forwards each batch to the running servers: created, changed and removed files of a server's languages under its root.

Refs #1015
2026-11-04 09:16:32 +08:00
Andrea Basileandandreabasile 4d224f80c9 feat(lsp): per-server features and code-action-kinds filter (#1099)
A [[language-servers]] entry (or languageServers.<name> in settings) can list features and code-action-kinds: capabilities outside features are dropped after initialize and from later registrations, publishDiagnostics and Inspect Code only use servers with diagnostics, and code actions are narrowed to the kept kinds (advertised kinds and answers both). No built-in definition uses them yet. First stage of #901: lets a refactoring-only server sit next to the language's own one.

Co-authored-by: andreabasile <7715018+andreabasile@users.noreply.github.com>
2026-11-04 06:43:31 +08:00
1c5a92f952 feat(plugins): plugin system with extension points, consent, Wasm runtime and plugin API 1.0 (#971)
A plugin system built on WebAssembly components (wasmtime, WASI p2), with a
typed WIT API (`openidea:plugin@1.0.0`) and a Rust SDK, shipped as a preview.

- Extension points declared in `plugin.toml` (commands, languages, themes,
  icon themes, menus, key bindings, status items, settings, views, custom
  editors, file icons and templates, run detectors, editor providers),
  validated before anything takes effect and projected onto the workbench's
  own registries: plugin themes and file icon themes are chosen in
  Settings › Appearance and Quick Switch, plugin shortcuts are edited in
  Settings › Keymap, plugin problems are grouped in Settings › Inspections.
- Capabilities with risk levels and consent at install, pinned `process:`
  programs, secrets in the OS keychain.
- Runtime: one thread per active plugin, fuel/time/memory budgets, soft and
  hard deadlines on the editing path, cancellation, crash backoff, idle
  reclaim, a precompiled-component cache; remote projects run code plugins on
  `openidea-server`.
- Web views and custom editors with a sandboxed page, a document bridge
  joined to the text editor's undo history, and split or preview layouts.
- Distribution: signed `.oiplugin` packages, a static marketplace index with
  revocation, versioned installs with rollback, install from a `.zip` or a
  folder. The release workflow signs and publishes the official plugins and
  their index, which released builds use as the default marketplace.
- Official plugins: String Tools, Key Promoter, Git Toolbox, AI Completion,
  Checkstyle, MyBatis Navigator, CSV Editor, Solidity, Material Icons, Harbor
  Night, Excalidraw, Graphviz, Regex Tester, License Header.

Closes #732

Co-authored-by: Deng Liu <5108773+dengliu@users.noreply.github.com>
Co-authored-by: florentvdry <16673235+florentvdry@users.noreply.github.com>
2026-11-04 02:54:31 +08:00
l0ng-ai 2f75628c87 fix(tasks): show a progress title's executable path as the program name (#1061)
rust-analyzer titles its check with the full command line, starting with the absolute path of cargo, so the status bar and Background Tasks popup showed /Users/…/Application Support/…/bin/cargo check … truncated before the useful part. LSP $/progress and DAP progressStart titles now go through ide_core::task::display_title, which turns a leading absolute executable path (with spaces, Windows drive/UNC, .exe/.cmd/.bat) into the program name.

Fixes #1060
2026-11-04 02:09:13 +08:00
d0whc3r c5727141a0 feat(format): make oxfmt a first-class formatter next to Prettier (#1010)
oxfmt ran only below an oxfmt configuration and reused the Prettier settings. It now has its own settings group and page (path, enabled languages, formatting provider, run on save) next to Prettier. For a language with an external formatter, oxfmt formats it when enabled for that language and either an oxfmt configuration is found above the file or oxfmt is the selected provider; otherwise Prettier, when enabled. Turning Prettier off for a language still leaves it to the language server. New Reformat with Prettier / Reformat with oxfmt commands run that tool regardless of the settings and report languages it cannot format.

Co-authored-by: d0whc3r <1378986+d0whc3r@users.noreply.github.com>
2026-11-03 23:54:55 +08:00
l0ng-ai d54ef98a59 fix(lsp): open library classes behind jar: URIs (#1048)
The official Kotlin LSP answers navigation into a dependency with a
`jar:///…/lib.jar!/pkg/Name.class` URI but does not serve its contents through
`workspace/textDocumentContent`, so opening the target failed with "no
language server provides the contents of jar:…", locally and remotely.

`jar:` URIs are now resolved by the backend, where the jars are:
- An entry that is not a class (a sources jar entry, a resource) is read from
  its archive.
- A class is shown as its source from the artifact's `-sources.jar` in the
  Maven repository or the Gradle cache (`Name.java`/`Name.kt`, an inner
  class's outer file, a `FileKt` facade's `File.kt`, a `@file:JvmName`
  file); Go to Declaration then lands on the declaration of the name it was
  invoked on.
- Otherwise the server's `decompile` command is used when it offers one, and
  the error says that neither a source nor a decompiler is available.
- Library tabs name the archive and package (`spring-boot-3.5.16.jar ›
  org.springframework.boot`).

Fixes #982
2026-11-03 22:04:05 +08:00
l0ng-ai ae406ca2fb fix(java): resolve Maven projects with the profiles chosen in the Maven tool window (#1044)
The profiles checked in the Maven tool window only reached `mvn` (sync and
goal runs) and the Kotlin bridge. jdtls imported every module without them,
so a dependency whose version, or module, comes from a profile stayed
unresolved and its classes were reported as missing, while Build Project ran
without `-P` as well.

- A Maven sync records the profiles it ran with. jdtls gets a copy of the
  user settings.xml with them in `<activeProfiles>` (m2e has no other input
  for profiles), sent as a setting so a running server re-imports instead of
  restarting; the file name follows its content so m2e reloads it.
- Toggling a profile reloads the Maven projects (once for several toggles in
  a row, again after a sync that started with the previous choice).
- Build Project passes the synced profiles with `-P`.
- When jdtls finishes an import or project update it does not re-check open
  files, so their errors stayed until the next edit; open Java files are now
  re-checked on its ProjectStatus report. This also covers a POM edit or a
  dependency added to ~/.m2.

Fixes #993
2026-11-03 22:02:40 +08:00
l0ng-ai dcd8ecc5ae fix(java): name reserved Windows device files that abort the Java import (#1032)
On Windows, a project file named after a device (nul, con, aux, prn, com1-9, lpt1-9; nul is typically left by a 2>nul redirect in Git Bash) aborts the Java import: Files.exists reports it missing, Eclipse's refresh builds a child path with an empty name and throws "Path must include project and resource name", so m2e never creates the Java project.

When JDT LS reports that failure on Windows, the server root is scanned for reserved device names (bounded, ignore files not honoured) and a one-time error notification lists them with how to recover. The name check covers COM0-9/LPT0-9 including superscript digits, case-insensitive, with or without extension or trailing spaces. Backend notification texts now go through txTemplate so templated catalog entries translate; zh text added.

Refs #976
2026-11-03 21:09:03 +08:00
l0ng-ai 5ad179a9e6 perf(java): stop configuration indexing from blocking navigation and keep it warm (#1012)
Java Go to Definition consults the Spring configuration command only inside @Value / getProperty / getRequiredProperty arguments (tree-sitter check), so ordinary Ctrl+click and Ctrl+hover go straight to JDT instead of waiting on a project-wide index rebuild.

The java-usages bundle (1.2.1) keeps its configuration snapshot across editor open/close, builds, saves of non-Java resources and reconciles; it invalidates on Java model changes and unsaved Java edits only.

Fixes #998
Fixes #1002
2026-11-03 18:12:43 +08:00
Piettro b55c398fb5 feat(python): add Pyrefly language server (#911)
Pyrefly (`pyrefly lsp`) joins basedpyright, Pyright and ty as a fallback Python language server. It is installable from Tools as a managed virtualenv tool and is listed among the interchangeable type checkers, before Ruff, so Ruff still runs after them.

Pyrefly only reports type errors in projects with a Pyrefly configuration (`pyrefly.toml` or `[tool.pyrefly]`); hover, completion and navigation work without one. A real-server test (ignored by default, needs `pyrefly` on PATH) covers startup, go-to-definition and diagnostics.

Co-authored-by: pcastro93 <2058578+pcastro93@users.noreply.github.com>
2026-11-03 14:42:45 +08:00
arookieofcanda-rookie-of-C-language 2161a2ca03 fix(lsp): serialize the jdt.ls classpath resolve with the build lock (#946)
Running a main class in a multi-module Maven project could fail with "Cannot resolve the classpath: jdtls: Attempted to beginRule: P/<dependency>, does not match outer scope rule: P/<module>".

`java.project.getClasspaths` and `getSettings` ran outside the jdt.ls build lock, so they could overlap a build or an m2e refresh of a sibling module that takes a nested Eclipse scheduling rule. The launch now resolves the classpath and JDK under the same build lock the build commands use. A delegated external build already holds that lock across the launch, so its callers pass `build_lock_held` instead of waiting on it again, which would deadlock.

Fixes #933.

Co-authored-by: a-rookie-of-C-language <186315048+a-rookie-of-C-language@users.noreply.github.com>
2026-11-03 14:39:29 +08:00
qiaojianlongandClaude Opus 5.5 d981603f3c feat(java): navigate Spring configuration keys and usages (#823)
YAML/properties keys stayed inside the generic YAML language server, so Spring configuration bindings and their consumers were unreachable from the editor. A new command in the bundled JDT LS extension (java-usages 1.2.0) resolves keys to @ConfigurationProperties members (prefixes, nested/inherited members, records, constructor aliases, collections), @Value placeholders and PropertyResolver calls, and back from Java to configuration entries; Find Usages merges configuration consumers and declarations with the native Java results. Several profiles or modules are offered as candidates. Closes #796.

Co-authored-by: qjlqyf <109515705+qjlqyf@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 22:23:09 +08:00
7fdf1d62c3 fix(refactor): preserve versions and recover multi-file workspace edits (#488)
Multi-file refactorings could drop LSP document versions, overwrite content changed after a preview, or leave earlier files saved after a later write failed. Workspace edits now keep server versions and preview fingerprints, are validated on a staging copy, snapshot disk and open buffers, and roll back on commit failure (retaining recovery files if rollback fails). The whole edit is one Undo/Redo step in editors and in the notification. Version reads and transaction work run off the async workers. Closes #461.

Co-authored-by: shohruh-genius <7658451+shohruh-genius@users.noreply.github.com>
Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-11-02 22:18:16 +08:00
Andrea Basileandandreabasile a623e5d385 feat(python): add ruff language server for lint, format and organize imports (#859)
In projects configured for Ruff (ruff.toml, .ruff.toml, or pyproject.toml with a [tool.ruff] table), ruff server runs next to basedpyright as a managed pip tool: its lint diagnostics, Reformat Code / format on save, Optimize Imports and Code Cleanup's fix-all. It is listed after the type checkers, so hover, navigation and rename stay with them; projects without a Ruff configuration never start or install it. Root markers accept file#table to require a TOML table, and a hand-defined server named ruff now only overrides how the built-in one launches. Verified with the real-servers end-to-end test against ruff and basedpyright.

Co-authored-by: andreabasile <7715018+andreabasile@users.noreply.github.com>
2026-11-02 20:27:24 +08:00
l0ng-ai e2f8e8d5bc fix(cpp): explain missing clang-tidy checks with Apple's clangd (#770)
Apple's clangd (/usr/bin/clangd, Xcode and CommandLineTools toolchains) is built without clang-tidy, so on a Mac without a managed clangd the checks from .clang-tidy never appear. When a clangd server for C, C++, Objective-C or Objective-C++ resolves to Apple's binary and the project has a .clang-tidy, show one warning per session with Install (managed LLVM clangd, which already takes precedence once installed) and Language Servers… actions. Fixes #692.
2026-11-02 11:14:27 +08:00
l0ng-ai bf2427bd3a feat(java): selectable Java formatting profiles (#680)
Java formatting comes from jdtls' Eclipse formatter, whose defaults differ from the IntelliJ IDEA code style. Settings › Editor › Code Style › Java now offers a formatting profile: Default (unchanged), IntelliJ IDEA, or a custom Eclipse formatter XML (absolute or project-relative path).

The IntelliJ IDEA profile is a bundled Eclipse formatter XML that follows IDEA's default Java code style item by item (indents, aligned multi-line parameters, annotation placement, else/catch/finally on the same line, array initializers, lambdas, blank lines, comments not reflowed). Manual line breaks are kept; lines longer than 120 columns wrap where necessary, which differs from IDEA's default of not wrapping. The profile reaches a running jdtls through didChangeConfiguration without a restart; an unreadable custom file shows a warning and leaves code intelligence running. Code style changes reconfigure language servers without scheduling Kotlin bridge builds.

Also drops two catalog entries whose texts are no longer used.

Fixes #649
2026-11-01 18:26:24 +08:00
l0ng-ai ec5193f827 feat(format): external formatting with managed Prettier (#671)
Reformat Code only asked the language server for formatting, so files whose server has no formatting capability (Markdown with marksman, and others depending on the server) could not be formatted.

Languages can now declare an external formatter. Prettier is the first: a managed tool installed on demand, or the project's own node_modules/prettier, an explicit path, or PATH. It runs on the backend copy of the document with the file's path so Prettier resolves the project's config, overrides and ignore files, and its result is applied as one undoable edit. Language servers that format a file keep doing so unless Prettier is preferred in Settings › Languages › Prettier; formatting on save is opt-in. Parsers without range support format the whole file and say so.

Errors carry structured tool data, so a missing Prettier reuses the shared install prompt and Prettier diagnostics or timeouts show as non-sticky notifications.

Fixes #639
2026-11-01 16:54:31 +08:00
arookieofcanda-rookie-of-C-language 683f8d8826 test(jdtls): compare resolved source paths as paths, not strings (#665)
java_class_file joins the package path with std::path, so on Windows the result uses backslashes while the test's expectation kept the literal forward slash from "p/Outer.java". Compare as Path so separator style does not matter.

Co-authored-by: a-rookie-of-C-language <186315048+a-rookie-of-C-language@users.noreply.github.com>
2026-11-01 16:16:14 +08:00
l0ng-ai 482241ebb9 feat(java): open class files as decompiled sources with breakpoints (#657)
Opening a .class file showed binary content. Class files from library jars, project output directories, navigation, Go to Class and debugger frames now all go through one route to JDT class documents:

- Library classes open the attached source, or the FernFlower decompilation when there is none, read-only and marked as decompiled. java-debug's decompiled-source support is enabled, so breakpoints set in decompiled code map to the original lines and hit, and stepping into such classes lands on the right line.
- Output-directory classes (target/classes, build/classes) open their project source when it exists; otherwise the decompiled text is shown read-only with breakpoints disabled, because jdt.ls returns no line mapping for classes outside the Java model.
- The preferred content provider id is corrected to fernflowerContentProvider (attached sources still win), and the decompiled marker recognises the current FernFlower header.

Verified on macOS with a Maven project: library class from Libraries and Go to Class, breakpoint hit and step into decompiled code, output class with and without source. Not run on Windows, Linux or Gradle projects.

Fixes #394
2026-11-01 15:04:28 +08:00
l0ng-ai 2c3eabb786 feat(go): support interactive Generate actions (#632)
Go's test generation and interface stubs were reachable only through context actions, because Generate filtered their titles, and implementing an interface on a plain struct wasn't available since the client didn't support gopls's interactive commands.

Generate and the editor's context menu now list `Add test for ...`, `Declare missing methods ...` and `Add methods to ... implement ...`, and a generated test file opens in the editor. For gopls only, the client advertises `interactiveResolve` and runs its `command/resolve` handshake: a prompt titled from the server asks for the interface, shows validation errors in place, and Cancel writes nothing. Requests are cancellable and other servers and existing commands are unchanged.

Fixes #620
2026-11-01 10:27:36 +08:00
Ning YuanLin 6456f0e404 feat(java): add read/write filters for Java field usages (#569)
Find Usages mixed reads and writes of a Java field, including Lombok getter and setter calls, because jdtls has no read/write classification in its references. The usages popup and Find window now have Read and Write toggles. Read-write accesses stay visible in either mode and unclassified results are kept.

Classification comes from a jdtls extension in `plugins/java-usages`, embedded as a jar and installed beside the other bundles. The checked-in jar was rebuilt from source with ECJ and matches byte for byte. Any extension failure falls back to standard references, so a jdtls upgrade can lose the filter but not Find Usages; rebuilding the jar on an upgrade is manual and described in the plugin README. Older installed jars are removed. Other languages keep their plain result count.

Co-authored-by: NingYuanLin <57001533+NingYuanLin@users.noreply.github.com>
2026-11-01 09:09:15 +08:00
l0ng-ai 0be97c4323 fix(java): apply unmanaged project source roots (#611)
Source and Test roots marked in Project Structure never reached jdtls, so projects without Maven, Gradle or Eclipse metadata relied on jdtls's inference. That inference could treat a package directory as the source root, which gave wrong-package and unresolved-import errors in the editor and in Run.

Marked roots now go to jdtls as `java.project.sourcePaths`. Unmarked projects use `src/main/java` and `src/test/java`, or `src`; other layouts keep the inference. Changing the roots restarts only jdtls, with a separate workspace per source model, because a cached invisible project does not pick up new folders. Maven, Gradle and Eclipse projects keep their own model. Ant layouts count as unmanaged, since jdtls has no Ant importer.

Settings sent to jdtls are now merged the same way for initialization, configuration requests and change notifications. A Run with no editor open finds a trigger file inside the source roots so the project still imports.
2026-11-01 03:49:40 +08:00
l0ng-ai 999eb86408 test(lsp): compare mock server results against canonical paths (#553)
Edits and references report canonical paths, while the mock server fixture used the temporary directory as given. On macOS and Windows those differ.
2026-10-31 14:46:48 +08:00
l0ng-ai 8dc1ee062f fix(java): show why jdtls crashed when a run needs it
A run that needed a crashed jdtls reported only "jdtls is not ready (Crashed)",
although the server's exit code and last output were already recorded for its
status. The run console and notification now show them.
2026-10-31 03:49:20 +08:00
l0ng-ai 8fabf054ef fix(lsp): offer auto-imports from unopened files in projects without a tsconfig (#496)
Without a tsconfig.json or jsconfig.json, tsserver's inferred project holds only
open files and what they import, so completion never offered exports from other
files. Register the project's sources with tsserver as an external project,
using the options an inferred project assumes, so no file is written to disk.

Registration needs `typescript.tsserverRequest`. Projects with a configuration,
including one in a subfolder, stay as they were, and so do trees over 10,000
sources or 16 MiB of JavaScript, since tsserver disables its language service
past 20 MiB. Created and deleted files update the project, and unopened files
stay out of Problems.
2026-10-31 01:49:00 +08:00
l0ng-ai 01defdefe4 feat: multi-project workspaces and project window groups (#448)
Workspaces open several local project folders in one IDE session (File › New / Open / Manage Workspace…, or Attach when opening a project, which creates a workspace automatically for a plain project window). Member folders are the Project view roots and take part in indexing, Find in Files, Git, language servers, run configurations and builds; agent tasks choose which member they work in. Window › Merge All Project Windows groups project windows into one window with project tabs (switch, reorder, close, move to a new window), restored on reopen.

Closes #241
Closes #198
Closes #286
2026-10-30 22:45:42 +08:00
l0ng-ai 5bab140968 fix(lsp): report incomplete rename and caller searches, make them cancellable (#472)
Rename and incoming calls open the project files that mention the name, like
Find Usages, but dropped the reason a search could miss usages and could not be
cancelled. A rename past the 300-file limit changed part of the usages without
saying so.

- Rename and call hierarchy return why the result may be incomplete and take a
  request id for cancel_request.
- A rename that may have missed usages always opens the preview, with a warning.
- The Callers tree shows the note above the tree or on the expanded node.
- Candidates too large or not readable as text are reported as skipped.
- A newer rename or hierarchy query cancels the one it replaces.
2026-10-30 22:08:10 +08:00
l0ng-ai 9575500dd6 fix(java): provision an isolated runtime for the Java language server (#370)
Recent Eclipse JDT LS releases need Java 25 to run, so projects on JDK 21 had no Java language support until the user downloaded a newer JDK by hand. When JDT LS is about to start, no installed JDK is new enough, and no language-server JDK is set explicitly, the IDE now downloads the Temurin JRE of the required version (about 50 MB, falling back to the JDK image where no JRE build exists) with a cancellable background task, then starts the server on it. The runtime lives in its own folder under the app data directory, outside the roots scanned for project JDKs, so the project JDK, run configurations and JDT LS's project runtimes are unchanged. One download runs at a time across windows and is reused; a failed attempt falls back to the existing manual Download JDK action and is not retried until the next start.

Fixes #258
Refs #271

未在 Windows / Linux 实机验证。
2026-10-30 14:38:45 +08:00
l0ng-ai 503bbb2f02 fix(tools): install TypeScript 6 without a shell-unsafe version range (#359)
Fixes #341
2026-10-30 13:37:58 +08:00
Mykhailo Smolinskyiandnntndfrk 922bbf493a feat(angular): highlight Angular templates with control-flow blocks (#284)
HTML files in Angular projects were highlighted as plain HTML. Languages can now declare framework UI modes with root markers (angular.json, node_modules/@angular/core); files under such a root get the framework's editor mode, re-detected when a marker appears or disappears, and the root-marker lookup is shared with language server roots. The Angular Template mode (vendored @codemirror/lang-angular, MIT) adds @if/@for/@switch/@defer/@let blocks, key and animation binding names, and colours {{ }} delimiters.

Lazily loaded editor modes are now loaded before a document's first editor opens, so a file never renders as plain text first (this also left Angular templates uncoloured).

Co-authored-by: nntndfrk <2458463+nntndfrk@users.noreply.github.com>
2026-10-30 07:39:31 +08:00
l0ng-ai c8e3fe9d2e fix(lsp): Name the running server when it lacks a feature (#201)
ide-lsp returned the same `unavailable` error whether no server was running or a running server didn't implement the request, so the UI said no language server was available, and Invoke Inline Completion said no language server provides inline completion, while jdtls was running fine (it doesn't implement textDocument/inlineCompletion). When servers are running but none supports the feature, the error now names them ("jdtls doesn't support inline completion"), and every explicit action shares one message helper: Invoke Inline Completion, go to declaration / implementation / type declaration, quick documentation, parameter info, rename, reformat, intention actions, highlight usages, call / type hierarchy, find usages, safe delete and workspace symbols. With no server running it still says no language server is available. Background requests while typing stay silent.

Fixes #186

Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
2026-10-29 10:35:37 +08:00
l0ng-ai 1c46a1cd04 fix(tasks): Make every background task cancellable, queued or running (#177)
Background tasks often couldn't be cancelled, or cancelling didn't stop them:
- A cancel that arrived before the backend registered the request was dropped (build while saving files, multi-repository fetch/pull between repositories). The host now remembers early cancels (bounded, 2 min), and request ids start at a random value per page.
- There was no queue and no common cancel path: backend-reported tasks (LSP progress, deployment transfers) couldn't be cancelled, and tool installs, VCS operations and update checks had no cancel button in Background Tasks.
- Only the direct child process was killed, and JDK / tool archives were extracted without checking for cancellation.

Tool installs and JDK downloads now share a downloads queue; cancelling a queued task removes it without starting any work. Every task cancels through one path that shows "Cancelling…" and then removes it; tasks that can't be interrupted show a disabled cancel button with the reason. IdeEvent::Task carries `cancellable` with a cancel_task command, cancellable LSP progress sends window/workDoneProgress/cancel, installers, curl and tar run in their own process group and are killed as a group, and extraction checks for cancellation between entries.

Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
2026-10-29 09:05:12 +08:00
Mykhailo Smolinskyiandnntndfrk 0184a9c395 feat(angular): Add the Angular Language Server (#147)
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 <2458463+nntndfrk@users.noreply.github.com>
2026-10-29 00:18:19 +08:00
l0ng-ai 5b63a2b95c fix(lsp): Drop language servers that leave the list from the status bar (#125)
Removing a language server (disabled in settings via stop_unlisted, or a fallback detached when its preferred server comes back) only emitted a stopped state, and the status bar list only refreshed for unknown servers, so the removed server stayed until the project was reopened. Both paths now go through forget(), which drops the server and emits IdeEvent::LanguageServerRemoved; the frontend drops the entry and ignores stale lsp_servers results that still contain it. Stopped servers no longer count towards "+N".

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-28 15:06:45 +08:00
胡翀andzzxzz12345 ac426c8881 feat(python): Add ty and select the Python language server (#121)
ty (`ty server`) joins basedpyright and Pyright as a Python language server (fallback, gets the project venv like the others, installable from Tools). Settings › Language Servers gets a Python language server picker: Automatic (first available), basedpyright, Pyright, ty or None, written through the per-server enabled settings (null globally / true in a project for enabled, false for disabled); other combinations show as Custom combination. Picker text is translated; the hint sits on its own line.

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
Co-authored-by: zzxzz12345 <8338183+zzxzz12345@users.noreply.github.com>
2026-10-28 14:57:34 +08:00
l0ng-ai 357b728f1d Editor: quick fixes, completion, navigation while typing, and split-pane drag (#109)
* 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
2026-10-28 09:07:50 +08:00
l0ng-ai 48ac2094fc feat(lsp): Configure language servers and add servers of one's own (#108)
Language servers can be configured from settings.toml (global or project) and Settings › Language Servers: arguments, environment, initialization options and workspace settings per server, enable/disable, and any stdio LSP server can be added for a language. Settings-only changes are pushed with workspace/didChangeConfiguration; launch changes restart the server.

Also: re-enabling a server now detaches and stops the fallback that stood in for it, and a server added from the dialog is written as its own [languageServers.<name>] table.

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-28 03:40:18 +08:00
l0ng-ai 8eb4834a48 fix(lsp): Make the language server tests deterministic (#107)
`ide-lsp` tests failed intermittently (about 1 run in 4, more under load).

The main cause, requests from the other side starting before earlier notifications, is fixed on main by b5bc150; this adds a regression test for it in `ide-jsonrpc`, documents that `on_notification` must not wait for the remote side, and drops the 200 ms polling workaround in `ide-agent` that papered over the same race for `session/request_permission`.

Test-only races fixed: mock replies are held with a gate instead of fixed sleeps and timing asserts; the indexing-retry test ends indexing after the first reply; the crash test counts Ready/Crashed transitions instead of reading the last status; the mock records a notification and applies its effect under one lock; `eventually` waits up to a deadline; `tcp_server` reserves its port with a bound socket and waits for the server's start marker.

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 22:15:47 +08:00
l0ng-ai 2fe6b7b87b feat(editor): Implemented / overridden gutter markers (#106)
Adds gutter markers for type hierarchies: ↓ "Is implemented / Has subclasses / Is overridden" on types and methods with implementations, ↑ "Implements / Overrides method in X" on methods that implement or override a supertype method. One target navigates, several open the Choose Implementation popup. Settings › Editor › General › Gutter Icons gets two toggles.

Markers come from the language server: a new batched `lsp_implementations` command (up to 4 concurrent, cancellable, sharing the goto query path) for ↓, and the Super Method lookup for ↑, which now prefers the overload with matching parameters (also fixes ⌘U on overloads). Only declarations near the viewport are queried, debounced, cached per document version and cancelled when superseded. Works for any server with implementation / type hierarchy support; servers without type hierarchy show ↓ only.

Fixes #99

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 21:02:54 +08:00
l0ng-ai a065189516 fix(lsp): Launch jdtls with java and surface output outside the protocol (#102)
On Windows the auto-downloaded jdtls ran through `bin\jdtls.bat`, which starts the Python wrapper and ends with `pause`. When Python failed, `pause` wrote its prompt to stdout in the console code page; the transport treated that as a broken LSP header ("non-UTF-8 header"), dropped it and the server was killed, so the status only said "exited with code 1".

- jdtls is now launched with `java` directly on every platform (Equinox launcher, platform config dir, JDK 24+ flags, forwarded JVM args, `-data`), so Python is no longer needed; user wrappers and unusual layouts keep their command.
- Output outside the protocol on stdout (and non-UTF-8 stderr) is decoded (UTF-8, then the Windows OEM/ANSI code page, then lossy), logged and included in the crash message, for stdio and TCP language servers, DAP adapters and ACP agents.
- Crash messages carry the real exit code and the last lines of output.

未在 Windows 实机验证 (Windows paths covered by unit tests and a Windows-target clippy run).

Fixes #90

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 20:44:09 +08:00