A taken port now says which port is in use instead of Node's EADDRINUSE text; a listening PHP Remote Debug session shows "Listening for Xdebug on port N" instead of "Running…"; clearing the only field of a debug-only remote type keeps the form and shows the field as required; php-debug leaves the generic Debug adapter list until it has a launch template (#1623).
Co-authored-by: DanielADK <18214958+DanielADK@users.noreply.github.com>
Bash Debug had no entry in the missing-adapter table, so a shell script debug session without it failed with a plain error pointing at mason.nvim. The install hints of the debuggers OpenIDEA installs itself (CodeLLDB, vscode-js-debug, Kotlin Debug Adapter, netcoredbg, Bash Debug) now point to Settings › Languages & Frameworks › Language Servers, in languages/*.toml and in ide-dap's built-in definitions.
A program started through runInTerminal had stdin from /dev/null, and CodeLLDB's launcher only hands the program a terminal it can read from when it runs on one. runInTerminal now starts the command on a pseudo-terminal, forwards its output to the console (CRLF as LF, without CodeLLDB's clear-screen request) and reports that the program takes input; while it runs, the console's input line goes to it, while paused it evaluates as before. debugpy and js-debug programs started in a terminal get the same.
Dart projects that depend on the Flutter SDK were debugged through
`dart debug_adapter`, which cannot start a program importing dart:ui and has no
hot reload. A session now uses `flutter debug_adapter` when the program's or the
working directory's pubspec.yaml depends on the Flutter SDK, or when an attach
configuration asks for it (add-to-app: vm-service-uri and device map to the
adapter's attach arguments). Hot Reload and Hot Restart are sent over DAP and
appear in the toolbar of Dart sessions. Dart files also get a debug configuration.
Co-authored-by: payailk <80739895+payailk@users.noreply.github.com>
* fix(tools): find Python on Windows without python3.exe
Installing debugpy on Windows failed with "cannot run python3.exe … (os error 3)": the tool
manager looked for `python3` first, and on Windows that only finds the App Execution Alias in
WindowsApps, which can't start without the Store's Python. Windows installs `python.exe` and the
`py` launcher instead. On Windows the interpreter is now looked up as `python`, `py`, then
`python3`, and a WindowsApps alias only counts when it runs. The debugpy adapter's default
interpreter is `python` on Windows too. macOS and Linux keep `python3` first.
* fix(tools): keep searching past broken Python aliases
debugpy ran the project manager (`uv`, `poetry`, …) as a module. Configurations run through uv, poetry, pdm, pipenv, hatch or rye now pass the manager as the debuggee's interpreter, keep the script / -m module / tool as the target, and run the adapter and launcher on a plain interpreter (debugLauncherPython, now preferred by the backend for the adapter command).
CodeLLDB runs debug-console input as LLDB commands unless its console mode says otherwise, so Evaluate Expression, the Debug Console and breakpoint log messages failed with "'x' is not a valid command". Launch and attach requests now set `_adapterSettings.consoleMode` to `evaluate` unless the configuration picks a mode; LLDB commands still run with a leading backtick.
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.
While suspended, the debugger's expression fields complete from the debug adapter (DAP completions) in the selected frame: Evaluate, the Variables evaluate field and the Debug console share one hook. The list opens while typing an identifier or after '.', or on Ctrl+Space; Up/Down, Enter/Tab, Escape. The Evaluate dialog is resizable and its result tree grows with it. Backend: ide-dap completions (skipped without supportsCompletionsRequest), debug_completions on the host and the desktop app.
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>
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
Closing a project only cancelled its agents and notebooks; its window's requests, run processes, terminal shells and debug sessions kept running until app exit, and the language server shutdown was a detached task a closing app could drop (orphaned jdtls). Closing now cancels the window's requests, kills its run processes and shells, stops its debug sessions and waits for the language servers to shut down; other windows are untouched. Terminals are keyed by owner window so they can be closed per window.
Co-authored-by: misswell <28730815+misswell@users.noreply.github.com>
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
Keep the program output test out of the Unix-only attribute it landed under,
skip the Go process tests when no toolchain is installed, and list Go variable
names and placeholder values as untranslated text instead of identical
translations.
Go settings, execution, debugging and test reporting were disconnected, leaving Go projects without editable build/test fields and workspace maintenance actions.
- Add project build constraints that update gopls in place, and notices on excluded files.
- Add editable Go Build and Go Test configurations with directory, package and file targets, separate tool and program arguments, modules, environment, output selection and build-only execution, and pass the same settings to Delve.
- Decode Go JSON test output into the results view, with subtests, failures, skips and rerun failed. Add gutter targets for benchmarks and generate directives.
- Add module environment and vendoring settings, read go.work members, and offer tidy, download, sync and use from file menus.
- Add file and package generate actions, and format and organize imports through gopls on Save and Reformat.
- Show what a Go program prints in the debug console: Delve's debuggee shares its stdio, which no DAP event carries.
- Keep the default build output out of version control, and keep configurations produced by an earlier run out of the gutter choices.
Fixes#507Fixes#237
Kotlin line breakpoints never verified through java-debug because jdtls cannot resolve classes for .kt files. Kotlin Application configurations and JDWP attach for modules with Kotlin sources now use the official Kotlin Debug Adapter (installable from the debugger prompt, running on the language-server JDK); pure Java keeps java-debug.
The adapter resolves classes from source paths, so sources whose directories don't match their package are mirrored package-aligned outside the project (symlinks, copies where links fail) and paths are mapped back for breakpoints and stack frames; files that can't be mirrored are skipped rather than failing the session. Kotlin applications start with JDWP suspend=y and a session-owned JDWP relay holds the adapter's early resume until attach completes, so breakpoints are installed before the program runs.
Limitations (docs/kotlin-debugging.md): @file:JvmName facades are not resolved; package/source-root changes need a new session. Not verified on a real Windows machine.
Fixes#374
java-debug treated forward-slash Windows drive paths as URIs, so breakpoints never verified; source paths are now sent with native separators and mapped back for stack frames and breakpoint events. Debug sessions also flush every file's pending breakpoint updates before starting, so configurationDone never runs with an empty breakpoint snapshot (all adapters, launch and attach).
Not verified on a real Windows machine; the path conversion is covered by unit tests.
Fixes#380
Refs #374
On Chinese Windows the Maven tool window showed sync errors as mojibake: tool output was decoded as UTF-8, but while JVMs are told to write UTF-8, cmd.exe, batch launchers (mvn.cmd, gradlew.bat) and native tools write their diagnostics in the ANSI code page (GBK). ide_core::output_encoding::decode_tool_output keeps valid UTF-8 and decodes other lines in the system code page (GetACP). It is used wherever OpenIDEA shows output of tools it launches itself: Maven/Gradle sync and tasks, tool installers, SDK probes, Docker, coverage, environment setup, Cargo stderr for debugging, agent version probes and notebook kernel stderr. Run consoles and protocol streams keep their own encodings. 未在 Windows 实机验证。
Refs #262
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>
java-debug runs inside jdtls and is reached through its debugServer port, but configurations that aren't Application / Spring Boot and select java-debug (a Shell Script running `catalina.bat run`, say) fell through to the generic launch template, and the adapter launcher tried to start com.microsoft.java.debug.plugin.jar as a process: on Windows that failed with os error 193, elsewhere with a misleading "debug adapter not found".
- Shell script / program configurations with java-debug start with a suspended JDWP agent injected through JAVA_TOOL_OPTIONS and attach once the JVM prints its port, so `catalina.bat run` / `catalina.sh run` can be debugged.
- Maven goals that run the app in Maven's JVM (tomcat7:run, jetty:run(-war), exec:java, or any Maven config with java-debug) are debugged through MAVEN_OPTS.
- Gradle tasks that start no JVM say why they can't be debugged; `debug.startConfig` with a single debuggable config goes through the run debug flow.
- .jar adapters are never spawned as processes, and Windows adapter lookup only accepts PATHEXT files (so npm-installed adapters pick the .cmd shim instead of the POSIX one); the PATHEXT expansion moves to ide_core::process::executable_names, shared with ide-run.
Not run on Windows; the Windows resolution is covered by tests with an injected platform.
Fixes#179
Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
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
Fixes#117
Inside an AppImage, AppRun and the linuxdeploy GTK/GStreamer hooks point LD_LIBRARY_PATH, PATH, XDG_DATA_DIRS, GIO_MODULE_DIR, GTK_PATH, GST_PLUGIN_* … into the mounted image, and every child inherited them, so host programs loaded the image's older libraries (curl + bundled nghttp2 → symbol lookup error when installing Kotlin LSP). ide_core::process::prepare (formerly no_window) now gives children the host environment back: entries inside $APPDIR are dropped (a <NAME>_ORIG wins), emptied variables and the runtime's launch variables are removed, explicit call-site values are kept; the IDE process itself is unchanged. Covers all spawn sites that used no_window plus terminal/run PTYs, run configuration environments and stop commands, login-shell probes, attach ps/kill, docker PATH, tool search PATH and the Linux browser opener. No-op outside an AppImage. Not verified on a Linux AppImage.
Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
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
An app started from Finder or the Dock took only PATH from the login shell, so
variables exported in rc files never reached agents, language servers, run
configurations or debug targets. Claude Code configured for Bedrock through
CLAUDE_CODE_USE_BEDROCK / AWS_REGION in ~/.zshrc fell back to the Anthropic API
and failed with 403.
The shell's environment is read once at startup (in the background when PATH
comes from the cache) and kept in memory only, since it may hold secrets. Spawns
add the variables this process lacks before their own.
Adds GDScript, Godot resource and shader file types with tree-sitter highlighting, the GDScript language server over TCP (a headless Godot editor started on demand), "Godot Project" / current-scene run configurations, and debugging through Godot's debug adapter.
Breakpoints set through symlinked paths (/tmp, /var on macOS) were reported verified but never hit; the adapter now sends resolved paths and maps stack frames back to the paths the IDE opened. The duplicate exit event Godot sends after disconnect is ignored.
Fixes#68
Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
Root cause: run configurations could only launch a process; there was no "attach to a debugger that is already listening" type, and debugServer only connected to 127.0.0.1.
Fix (IDEA / GoLand / PyCharm): debug-only Remote JVM Debug (attach / listen, live JDWP agent args per JDK version), Go Remote (dlv --headless, substitutePath), Python Remote Debug (debugpy --listen, pathMappings) and Attach to Node.js (inspector, localRoot/remoteRoot); debugServer accepts host:port and [v6]:port; JVM listen mode via a cancellable relay so java-debug can attach.
Verified: ide-dap tests (host:port, relay handshake, cancel), run/debugger vitest, in-app on macOS: Python Remote Debug attached to a debugpy server, paused at app.py:3 with variables. Remote JVM/Go/Node not exercised in-app.
Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
Release builds use the GUI subsystem, so a console child spawned without
CREATE_NO_WINDOW gets its own console window. git, gh, docker, builds and
run configurations already set the flag; language servers, SDK and tool
probes, debug adapters, tool downloads, coverage export and perf did not.
Add ide_core::process::no_window and use it at every remaining spawn.
Fixes#16
Servers and debug adapters could only be found on PATH or in the IDE's
tools folder; the only way to pick another executable (a version that
matches the project's Elixir/OTP, a local build) was an undocumented
languages/*.toml override. `tools.<command>.path` now names the
executable to launch: language servers (configure_server, restarted on
change), debug sessions and the tool list honour it, the latter
reporting a Custom status with its version or why the path is unusable.
The Language Servers page is laid out like Plugins: a compact list
grouped by availability on the left, the selected tool's command, path,
location, version, install actions and hints on the right.
A debugger named like its language server (ElixirLS's elixir-ls /
elixir-ls-debugger) was folded into the server's row and never listed;
it now gets a row of its own.
Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu