The thin Oracle driver refuses servers older than 12c during the handshake with a generic "connections to this database server are not supported". That error now says the server is older than 12c and that OpenIDEA connects to 12c and later.
Part of #3301
Session::exec returned only when the server closed the channel, so a remote find whose channel outlived the command (a background child holding stdout) hung sync before run on "Comparing project files" and the folder-by-folder fallback never ran. exec now drains output for a quiet period after the exit status and closes the channel, as spawn already did; the tree listing also stops when the run is cancelled.
Fixes#3299
Partial streamed results (even an empty batch) replaced the whole External Libraries node, and the old node was removed before the new one was added, so the node vanished during every refresh. Partial results now keep the ecosystems that haven't reported yet and the node is replaced in place. When cargo metadata --offline fails because an edited manifest names crates not downloaded yet, the last graph for that workspace stays instead of an empty Cargo.lock fallback.
Numeric values in http-client.env.json and http-client.private.env.json were parsed into serde_json numbers and printed back, which rounds large integers and long decimals (123456789012345678901234567890 became 1.2345678901234568e+29). Variables are now read as raw JSON tokens, so the URL, headers and body get the number exactly as written; strings, booleans, nulls and nested objects behave as before.
Refs #3105.
Co-authored-by: LunarFeller <269972968+LunarFeller@users.noreply.github.com>
The Breakpoints dialog gets a JavaScript Events and Requests section: stop when a debugged page handles a mouse, keyboard, form, page or timer event, or sends a request whose URL contains a given text. They are kept per project and sent through js-debug's setCustomBreakpoints to every page session, live ones at once and later ones when they start. A page's requests wait until js-debug has answered its launch, since requests sent while it sets the session up are acknowledged and dropped. A stop on one of these says what it was for above the frames, and js-debug's Caught Exceptions filter explains that it is how errors a framework catches are stopped at. A new page session whose id was used before (after a backend restart) also gets the breakpoints.
Co-authored-by: ntbang0901 <121003585+ntbang0901@users.noreply.github.com>
Debugging a Node.js program that prints a local address serving an HTML page can open that page in a browser debug session (Settings › Build, Execution, Deployment › Debugger › JavaScript, off by default). Ctrl/Cmd+Shift-clicking a URL in a console debugs it in the browser. The new web_serves_page command only asks loopback addresses, without a proxy, follows redirects only within this machine and times out after 10 s.
Co-authored-by: ntbang0901 <121003585+ntbang0901@users.noreply.github.com>
Code running in a browser could not be debugged: js-debug was only started for Node.js and launch.json entries of type chrome / msedge were skipped on import. A JavaScript Debug run configuration (URL, Chrome or Edge, web root) now opens the page with js-debug attached, so breakpoints in the page's sources are hit through source maps with the usual stepping, variables, evaluate and console. Each project gets its own browser profile under the IDE's local data, a project has one debugged browser of a kind (starting again reuses it), launch.json chrome / msedge launches import as this configuration, child sessions named about:blank take their parent's name, and Vue, Svelte, Astro and HTML files take breakpoints. Not yet available in remote projects.
Co-authored-by: ntbang0901 <121003585+ntbang0901@users.noreply.github.com>
The Node.js settings page becomes JavaScript Runtime with a Preferred runtime choice: Auto (the nearest deno.json / bun.lock, else Node.js, as before), Node.js, Bun or Deno. It decides what runs JavaScript and TypeScript files from the gutter and the editor's Run action, files outside the project included; a chosen runtime that is not installed is reported instead of falling back to Node.js. The package manager sits beside it, the Node interpreter and run target under a Node.js section. New setting languages.node.runtime.
Closes#3233
Reopening a project re-walked every file, canonicalized each path and opened redb before results were available. The index now writes a flat columnar startup snapshot (paths, symbol text, file metadata, symbols, directory mtimes and the ignore inputs) and, on open, validates it against the disk: every directory's mtime, every file's mtime and size, the per-directory and external ignore files and the filter settings. Any difference falls back to the full walk, so the result is the same as before; an unchanged project is hydrated in bulk without walking the tree, and redb opens lazily. Watcher updates refresh the snapshot after reconciling the touched directories. A corrupt snapshot is rejected before any offset is used.
Warm reopen measured about 10x faster (20k files: 204 ms to 21 ms; 100k files: 967 ms to 96 ms); the first index is about 10% slower because it writes the snapshot.
Co-authored-by: akbar1214 <43771058+akbar1214@users.noreply.github.com>
Maven prints Windows source paths as /C:/dev/p/A.java. Joined against the
working directory that became the drive-relative C:dev\p\A.java, so clicking a
build message failed with os error 3. Drop the slash before the drive letter
when parsing Maven paths, as file URIs already did.
A repository folder moved or restored into an open project stayed invisible until the project was reopened: the open scan had already run, and the folder brings no `.git` event of its own where the watcher reports only the created directory. The watcher's rescan, which already ran when a `.git` / `.git/HEAD` appeared, now also runs when a created path is itself a repository root, so the repository is registered the same way a `git init` inside the project is. The project-open scan and the rescan share `discover_repositories`.
Co-authored-by: muutot <92625353+muutot@users.noreply.github.com>
Explicit completion (Ctrl+Space) now bypasses the per-document completion backoff, and a successful completion clears it. Plugin enable/disable or UI changes clear all backoffs, so a newly installed completion provider is asked again. On the host, an empty plugin result only counts as an answer when a completion or injection plugin actually covers the document; otherwise the request stays Unavailable and falls through to the language server.
Co-authored-by: dengliu <5108773+dengliu@users.noreply.github.com>
The scoped status read after a watcher batch handed gitoxide's in-process pathspec the paths as the platform spells them. On Windows a backslash path matched nothing, silently, so the merged answer dropped the file from the change list until a full refresh; a path that is the repository root became an empty pattern and failed the read. The scoped read is git status with the pathspec again, with /-separated patterns and the root meaning the full status, and Restricted Mode answers with the full gitoxide status since it starts no program.
Co-authored-by: muutot <92625353+muutot@users.noreply.github.com>
The SSH/SSL tab gets Test SSH Tunnel: it logs in to the SSH host (shared SSH configuration or the settings typed in the dialog) and checks that the SSH host reaches the database host and port, without the database password or login. Success shows user@host:port and the database host:port reached; failures name the step (connecting, authenticating, reaching the database). An unknown host key offers Trust Host and Retry. The in-process SSH test server now forwards direct-tcpip channels.
A build.zig project gets a configuration per build step (zig build, zig build run, zig build test and the project's own steps) and one per executable it declares, which runs zig build first and then the installed binary, debuggable with CodeLLDB. The build script is parsed, never run, to find them.
Zig files get gutter markers: pub fn main runs the executable built from the file (or zig run for a file on its own), a test block runs zig test <file> --test-filter <name>, a file with tests only runs them all. Debugging a single file or test builds it into a binary first (build-exe, test --test-no-exec) and launches that.
Adds fixtures/zig-app (Zig 0.17). Part of #3260.
Files in a Helm chart's templates folder (yaml, yml, tpl, txt under a Chart.yaml / Chart.yml root) and *.gotmpl files are detected as Helm Template instead of YAML or plain text. They contain Go text/template + Sprig actions that are not valid YAML until rendered, so the YAML language server, formatter and tree-sitter syntax check no longer attach to them and flood the editor with errors.
A CodeMirror stream mode highlights YAML outside {{ … }} and keywords, variables, dot paths, functions and comments (including {{- /* … */ -}}) inside. .tpl outside a chart keeps its current type, since Smarty, Terraform and other engines use it too.
Co-authored-by: dengliu <5108773+dengliu@users.noreply.github.com>
A watcher batch used to re-read the whole working tree status, so a save in a large repository walked every file. The batch's paths now go to a scoped read (vcs_status_paths, gitoxide's status with a pathspec; git status with a pathspec as the fallback) and are merged into the loaded status: a path that is no longer changed drops out, a removed directory drops what is below it, new entries land in path order.
The full status still answers when the scoped one could be wrong: batches over 200 paths, a status that is not loaded yet, ignore-rule changes, a failed read, and batches that can split a rename. Git pairs a deletion with an addition across the whole index, so a pathspec read of a staged rename's target reports it as added and drops the source; batches that touch a rename, read one, or read an addition or deletion while the other side exists elsewhere take the full status. Restricted Mode keeps starting no program: the scoped read is in-process.
Co-authored-by: muutot <92625353+muutot@users.noreply.github.com>
Agents › IDE MCP Server gets a Listen address setting (mcpServer.address): 127.0.0.1 by default, or another address of this computer (LAN / VPN) or 0.0.0.0 / :: so agents on other computers can connect. Requests must still carry the bearer token, and the Host check still refuses host names other than localhost (DNS rebinding). An address that isn't an IP address, or isn't on this computer, stops the server with an error naming it. Clients on this computer keep connecting through loopback; the discovery file records the address. The settings hint and docs warn that anyone who can reach the address and has the token can use the tools.
Co-authored-by: guoyucode <29471644+guoyucode@users.noreply.github.com>
The remote plugin API test still filled the UI Problems reports after #3103 moved plugin diagnostics to the host-owned snapshot, so it failed on main with an empty result. It now publishes through the project's recording event sink and checks the snapshot's per-file / per-producer semantics, project close and RPC disconnect.
Co-authored-by: amphetamlne <55946742+amphetamlne@users.noreply.github.com>
F7 / Shift+F7 past the last difference opened the neighbouring file with focus on the editor tab's host, so the diff's keymap no longer applied; it had only worked through a stale navigator registration that #3137 removed. The diff now forwards the host's focus to its focused pane, as the image and hex viewers do. Also fixes the htmlFrame test's race with its listener effect and formats the diagnostics plugin fixture, so main's Frontend and Plugins jobs pass.
Static [[contributes.fileIcons]] entries match file names only, so a plugin could not tell a Helm chart folder, its templates or a Kustomize overlay from any other YAML file or folder. API 1.8 adds decorations.set-file-icon and the batched set-file-icons (up to 10,000 paths per set, requires project.read): a plugin assigns one of its declared file icons to an exact file or plain-folder path, shown in the project tree and editor tabs after the user's own file type icons. Under engines.openidea = "^1.8" a fileIcons entry may omit patterns, for icons used only this way. Both WIT copies, the SDK (host functions and mock), the plugins README and the bundled components are updated.
Co-authored-by: dengliu <5108773+dengliu@users.noreply.github.com>
Selecting a test in the Run tool window's test tree shows only that test's
output, and a class shows its own output followed by its tests'.
- Maven: Surefire's console names failures but not what passed tests printed.
The JUnit XML reports carry each test case's <system-out>/<system-err>;
they are now read into a separate `stdout` field and shown for every test,
before the failure details. Failures already reported on the console get
the printed lines in front of their stack trace.
- Gradle: output of a class's own setup and teardown (@BeforeAll, @AfterAll)
arrived under the class descriptor and showed up as an extra child named
after the class. The init script now sends it without a test name and it
belongs to the class node.
TypeScript 7 has no tsserver or JavaScript API; its platform package's native executable serves LSP itself. When the TypeScript setting selects one (the project's or a chosen directory), vtsls / typescript-language-server launch that executable with --lsp --stdio instead. The project's TypeScript 7 is listed as "TypeScript 7.x (native)".
A server Path pointing at a script in a Node.js installation's bin (nvm's bin/tsc, bin/npx) ran through #!/usr/bin/env node on the project's Node.js interpreter or the first node on PATH; TypeScript 7's extensionless ESM tsc crashed on Node 20.9. That installation's bin now comes first on the server's PATH.
Settings › Languages & Frameworks › Language Servers looks for newer versions of the tools in the IDE's tools folder once per session and from its refresh button: release downloads resolve their latest release as an install does, npm packages ask npm view through the user's registry. A tool with a newer version gets an Update tag, the available version in its details and an Update button that installs it.
Remote command handlers read arguments by name; a name the desktop client doesn't send reads as null (#3231). The test checks every c.arg / c.sender / c.channel name of each .add("command", …) registration in crates/ide-host/src against that command's arguments in src/bindings.ts.
editor.apply-edits-at applies edits that may come from another machine (a collaboration session), so it no longer uses the ordinary read resolver. The path must be project-relative, every component is checked with symlink_metadata from the canonical root, and symbolic links, junctions and other reparse points are refused, as are VCS and IDE control directories (.git, .hg, .svn, .idea, .openidea, .vscode, including Windows alternate spellings). The WIT docs describe the rule in both wit/ and the SDK copy.
Co-authored-by: SorPuti <56741582+SorPuti@users.noreply.github.com>
Rename Branch always failed in remote development windows with `argument unset_upstream: invalid type: null, expected a boolean`: the remote JSON-RPC handler read the argument as `unset_upstream` while the client sends `unsetUpstream`. A sweep of every RPC handler's argument names against the client bindings found no other mismatch.
Closes#3231
Co-authored-by: Mr0Bread <55754540+Mr0Bread@users.noreply.github.com>
Erlang and Elixir projects had no run configurations. A rebar.config now gives rebar3 shell, rebar3 eunit and, with *_SUITE.erl suites (also in umbrella apps), rebar3 ct; a rebar3 script in the project is used over the PATH. A mix.exs gives iex -S mix (iex -S mix phx.server for Phoenix) and mix test. An .escript file runs with escript. The configurations show the Erlang and Elixir file icons.
Closes#3208
A plugin's document index can link a declaration's name elsewhere: MyBatis Duo links a mapper method to its XML statement. Go to Declaration followed such a link at once, in the editor and in the host, so ⌘B on the method jumped to the XML instead of showing its usages as it does on any declaration (and did for plugins that answer through a definition provider). When the syntax tree puts the caret on a declaration's name, the link is no longer followed directly: the language server's answer comes along and the usages show, the plugin's target among them. Elsewhere plugin links are followed as before, without waiting for the language server.
Fixes#3207
jdtls on Windows sends a project path as is in its URIs (file:///H:/项目/…). lsp-types rejects such a URI, so the whole response failed: Find Usages, Go to Declaration, references, implementations and call hierarchy fell back to a text search for any project under a non-ASCII folder. Every message from a language server now has the characters URIs don't allow (non-ASCII, spaces, brackets…) percent-encoded in its file: URIs, string values and object keys (a workspace edit's changes) alike, before it is read.
Fixes#3205
Search and scope enumeration walked into directories that an exclusion mask covers entirely and dropped their files one by one. A directory is now skipped before its children are read when an exclusion with a trailing `/**` (e.g. `**/node_modules/**`) covers it; every file below such a directory is already excluded by the same mask, so results are unchanged. Other masks keep filtering individual files.
Co-authored-by: amphetamlne <55946742+amphetamlne@users.noreply.github.com>
After unpacking, the IDE removed the previous install, moved the new one into place and cleared the quarantine flag without checking for Cancel or reporting progress, so the install log kept saying Extracting… and Cancel did nothing; on a slower disk, deleting a large tool such as kotlin-lsp (about 1 GB) took seconds. Cancel is now checked right before the swap, as JDK downloads already do; the quarantine flag is cleared before it, and the previous install is moved aside and deleted in the background.
Refs #2925
Editor focus events are routed by the focused file's project, so a relative path is dropped before it reaches the plugin and the test never woke Git Toolbox. Editors always report absolute paths; the test now does too.
Several official plugins trusted crafted input: paths outside the project were accepted where only project files were meant, some loops and replacements had no upper bound, and CSV Add Row wrapped its row index on wasm32.
- ai-completion: only treat a real OpenAI host as OpenAI
- checkstyle, license-header, mybatis: keep resolved paths under the project root
- license-header: keep the generated header on one line where one is expected
- csv-editor: Add Row appends on wasm32 instead of overwriting the header
- regex-tester: cap the replaced output
- solidity: linearisation stops on cyclic inheritance
- mybatis: bound the mappers and statements it indexes
- string-tools, graphviz: guard the remaining crafted-input cases
- Rebuilt the changed components from source.
Co-authored-by: rohitdanda <10144914+rohitdanda@users.noreply.github.com>
Index queries (find_files, find_dirs, find_symbols) walked FileEntry values and per-file Box<str> / Box<[Sym]> allocations on every keystroke. They now scan compact tables kept in sync under the IndexData write lock: packed file rows and interned path/symbol arenas, a flat symbol table, precomputed masks, an ASCII fast path, a per-file union of symbol masks to skip files, and O(1) recents lookup. Ranking, scores, match indices, recency boosts, cancellation and incremental updates are unchanged.
Criterion (index_100k), main vs this change: find_files 45-60% faster (zzzz flat), find_dirs 20-48% faster (a flat), find_symbols 50-61% faster except OCo (flat).
Co-authored-by: akbar1214 <43771058+akbar1214@users.noreply.github.com>
JetBrains preview builds of kotlin-lsp stop starting once their date passes (exit code 7). The server was restarted three times and a manual restart only reported the same failure. A server that reports an expired build is no longer restarted, and the tools feature offers the latest release (Update for the IDE's copy, Install Latest for one on PATH, the Language Servers page for a chosen executable).
Fixes#2925
Plugins read problems from a host-owned snapshot that records every Diagnostics event per file and producer, instead of the UI-reported Problems reports, so what a plugin sees no longer depends on window lifetime or the invoking window. Adds the problems-changed workbench event (plugin API 1.8.0, gated at needs_api 8), editor focus events for files of other windows, severity style previews in plugin settings, and lays plugin annotations on the line-end chain before code-vision hints and inline blame. Components and fixtures are rebuilt for API 1.8.0.
Co-authored-by: muutot <92625353+muutot@users.noreply.github.com>
Settings › Appearance › Background Image picks an image shown through the project window, with opacity (default 15%), fill (scale, original size, tile) and anchor. Drawn over the workbench under dialogs and popups without taking clicks; the settings row previews the image and shows why a path cannot be loaded.
Adds a Slint language definition (.slint) served by slint-lsp, installable from the slint-ui/slint GitHub releases (macOS universal, Linux and Windows x64/arm64).
Claude Code run over stdio never generates a session title, and codex app-server leaves thread naming to its clients, so both kept the first line of their prompt as their title. After a turn without a title, the Claude shim sends the generate_session_title control request (persist: true) with the last 1000 characters of the prompts and replies; the Codex shim asks thread/sample for a title after the first completed turn of an unnamed top-level thread and stores it with thread/name/set. Without a title the next turn tries again, and a task renamed in the IDE keeps its name. Imported Codex sessions take their name from ~/.codex/session_index.jsonl.
Without a Project JDK and without a Java version the build declares, the jdtls Gradle import ran on jdtls's own runtime, which an older Gradle cannot run on, so every non-JDK dependency stayed unresolved. When the Gradle version is known, the import now uses the newest installed JDK that Gradle supports; a Project JDK, Gradle JVM or declared toolchain still wins.
Fixes#2681
FTP and FTPS deployment servers had no password field: the password was only asked for after a failed Test Connection. The Connection tab now has Password and Save password below User name, staged like a setting and written on Apply (saved, or for this session); clearing Save password forgets a saved password, and a saved one shows as "Password already stored". Test Connection logs in with a typed, not yet applied password.
Fixes#3151
In a workspace window the plugin asked vcs_status of the window's project, the workspace container, which is usually not a git repository, so the branch item disappeared and Fetch Now fetched nothing. Git Toolbox now resolves the editor-focused file to the deepest open project containing it and shows that repository, falling back to the window's project, the one shown last, then the first open one. Fetch Now fetches only the repository the status bar shows. Covered by plugin unit tests and a host e2e test with a two-member workspace.
Fixes#2556
Co-authored-by: Inf1mum <8135225+Inf1mum@users.noreply.github.com>
Environment variable and header values of the user's MCP servers move from the user settings.toml into the credential store (AgentSecrets, as for agent environment values): on start-up, on settings import/export, and when the MCP page saves. They are filled back in when the page lists servers and when a session starts. A project's own servers keep their values in the project's .openidea/settings.toml, where the project shares them.
Co-authored-by: rohitdanda <10144914+rohitdanda@users.noreply.github.com>
Editing the name in an opening or closing HTML tag renames the matching tag of the same element as you type, from the @lezer/html syntax tree, in one undoable transaction. Covers HTML, Vue, Angular templates, JSP, Django and Astro (ERB is token-based and stays out). Smart Keys gains Simultaneous <tag></tag> editing (on by default). Review fix: the Gutter Icons bookmarks group keeps its real gutter class.
Co-authored-by: Inf1mum <8135225+Inf1mum@users.noreply.github.com>
Attach to Process lists .NET apps (dotnet host or apphost with <name>.runtimeconfig.json) under ".NET (netcoredbg)" and attaches by process id. On Windows the process list is now implemented (ToolHelp + image path + command line with limited query access), so the action no longer fails as unsupported. On macOS the executable path comes from proc_pidpath, since ps comm kept relative launch paths and hid apphosts and Go binaries started as ./bin/app.
Closing a task's connection (idle release, archive, delete) stopped its claude -p processes through a weak reference to the in-process shim, which the closing connection could already have dropped; the processes then ran until the app quit. The close watcher now holds the shim, and a session dropped without being stopped stops its process. Rollback and fork, which start a stopped agent without a turn, now schedule the same idle release.
A SNAPSHOT installed again replaces its jar in place, so class URIs and jdtls' class handles stay the same; the backend's virtual document cache, the editor's cache and jdtls' decompiler cache all kept the old contents. Cached library classes now record their archive's modification time and are read again once it changes; after a build tool sync jdtls refreshes external archives, closes the changed roots and drops its decompiled sources (openidea.java.refreshArchives, java-usages 1.14.0), and open classes whose jar changed are replaced. The editor drops cached virtual documents when project roots change.