m2e resolves the local repository from the Maven settings XML, never from
-Dmaven.repo.local, so JDTLS imports kept downloading into ~/.m2/repository
even when the IDE's own mvn runs honored the configured path. When a local
repository is configured but the user settings lack <localRepository>, derive
an effective settings file under <root>/.openidea/ and pass it as
java.configuration.maven.userSettings. Settings that already declare
<localRepository> are passed through untouched.
IDEA writes path options as URLs (`WORKING_DIRECTORY = file://$PROJECT_DIR$`). The run configuration importer expanded the macros but never stripped the `file:` scheme, so on Windows `file://C:/project` became the drive-relative `C:project` and was joined onto the project directory, and imported configurations failed to launch. Every path-valued option the importer reads (working directories, SDK home, script and settings files, pytest targets, env files including EnvFile entries, package.json, package manager, node interpreter, config file, test directory/file, JS file, interpreter path, path arguments) now goes through one conversion: drive letters in the authority position, `localhost` as a local authority, UNC for a real host, and IDEA's unencoded paths kept verbatim. Env-file lists no longer split at a URL's scheme colon on Unix.
Co-authored-by: Clarence404 <[email protected]>
reid() made cached Mermaid diagrams' ids unique by suffixing every id, but only rewrote references followed by `"` or `)`. The root svg id changed while the selectors in the SVG's own <style> (`#id{`, `#id .cluster rect`, `#id>`…) did not, so none of Mermaid's rules matched and clusters, nodes and edges rendered solid black; the suffix also broke selectors that match marker ids by suffix. Ids now get a per-application prefix, rewritten consistently in id, href/xlink:href, aria-labelledby/describedby, url(#…) in presentation attributes (quoted or not) and the ID selectors of <style> rules, leaving declarations (hex colours), labels and unknown references untouched; an id that is a prefix of another (`-1` vs `-10`) stays distinct.
Co-authored-by: dengliu <[email protected]>
codemirror-vim matches special keys only in their exact canonical spelling, so rc mappings written for Vim/IdeaVim such as `inoremap jk <esc>` never fired. The rc parser now canonicalizes `<...>` key names on both sides of a mapping: any case and the usual aliases (Esc, CR/Enter/Return, BS, Del, Ins, Space, Tab, Bar, Bslash, arrows, Home/End, PageUp/PageDown, F1-F12), modifier prefixes in any case and order (C-/S-/A-/M-, D- as Command), `<lt>` kept literal on the right-hand side, Ex mappings ending in <Enter>/<Return>, and leader values containing `$&`. Unknown tokens are left untouched.
Closes#2281
Co-authored-by: ppxb <[email protected]>
The inspection widget and the Review Mode group float in `.cm-editor`,
outside `.cm-scroller`: they neither scroll with the text nor count in
`scrollWidth`, so at full horizontal scroll the last characters of a line
landed under them.
Reserve the corner's measured width in the lines' right padding, next to
the room the fixed padding already keeps for the overview lane.
Co-authored-by: yhqian <[email protected]>
Co-authored-by: Claude Code <[email protected]>
Find Usages and usage counts searched again on every request: about two
seconds each for a common type such as String.
- The Java usages extension (1.12.0) keeps answers by search target until a
Java element, the classpath or an unsaved edit changes, and requests for
the same target share one search.
- Widening checks up to 5000 candidates against the server's analysis scope
before applying the 300-file limit, so names mentioned in many covered
files no longer report "too many files".
- Candidate scans skip the source folders the server covers fully
(openidea.workspace.coveredRoots) instead of reading every file.
- Commands a server registers after initializing are added to its commands.
* perf(java): count usage lenses in the project sources only
Usage lenses asked JDT LS for a full references search per declaration,
which also scans every dependency jar and the JDK. In a library class such
as java.lang.String that kept JDT LS busy for tens of seconds per pass,
and failed counts were asked again on every scroll.
- Scoped Java searches without libraries pass the "sources" scope.
- Lenses count declarations near the viewport (10 lines instead of 60).
- Incomplete counts are remembered per document version and asked again
once the server settles, instead of on every pass.
* perf(java): turn off the language server's own reference lenses
JDT LS shows a references lens above each declaration by default and the
editor resolved them all at once, a references search per declaration on
every open and edit. The editor's usage lenses already count usages.
* style(editor): keep the usage lens's unrelated lines as they were
Console search exists (⌘F, the magnifier in a Run tab's toolbar), but a console without a
toolbar of its own — a stack-trace tab, say — offered no visible way in: the shortcut only
worked once the output had focus, and nothing said so.
Every uncontrolled ConsoleView now shows a small Find button over the output's top-right
corner, opening the same find bar (query, match count, Enter/Shift+Enter, case and regex
options). Consoles whose find bar a toolbar drives keep exactly one entry: the toolbar's.
How it was verified:
- pnpm vitest run src/features/run/findBar.test.tsx: 9 passed, including a new test that
the button opens the find bar and focuses its input.
- pnpm typecheck.
xterm's DOM renderer rebuilds every dirty row with replaceChildren even when
the new spans are identical. Full-screen TUIs (Grok, Claude Code) redraw the
whole screen on each spinner tick, so WebKitGTK restyles, lays out and paints
all rows several times a second and keystrokes queue behind it.
Install a row cache on xterm 6's DomRenderer: rows are still built, but a row
whose markup matches what is already shown is left in place. clear() and link
underlines rebuild rows outside renderRows, so they reset the cache. The
install is a no-op when xterm's renderer no longer has the expected shape.
Co-authored-by: Claude Opus 5.5 <[email protected]>
Following the end snapped back any scroll away from it that didn't follow a
wheel, touch, key or pointer press. A scroll without one, like dragging the
scrollbar thumb where no pointer event reaches the page or a programmatic
jump, was undone. The offset WebKit moves back on its own comes with a change
of the content height while rows lay out; only such a scroll keeps following
now, any other leaves the end.
Switching between file tabs destroyed the hidden tab's CodeMirror view and
built a new one on return: every switch re-ran the view's plugins, re-measured
the height map (the scrollbar jumped) and re-requested inlay hints, usages and
diagnostics, which popped in and shifted the text up to a second later.
The eight most recently hidden views are now kept detached and re-attached on
return, with their decorations, height map and plugin state. Edits while hidden
go to the kept view; plugins that skip work while their view is detached catch
up when it is shown again (`viewShown`).
Switching also forces fewer layouts: the Switcher no longer gives focus back to
the editor left behind when it opens another tab, the tab strip only measures
the active tab when it isn't known to be in view, and focus moving between
editors no longer drops the old editor's DOM caret.
The tabs perf scenario counts views rebuilt when switching back (budget 0).
Python SDK discovery only scanned ~/anaconda3-style install roots and
<root>/envs — an Anaconda installed off the home dir (D:\soft\anaconda3,
ProgramData) hid every environment from the Conda Environment picker even
though 'conda env list' saw them all.
Now: the conda binary on PATH reveals its install root (<root>/Scripts or
bin → prefix), 'conda env list' adds --prefix envs kept outside envs/ and
envs_dirs configured in .condarc, and the env probe looks for python.exe at
the env root on Windows — where conda puts it — instead of only under
Scripts/ (virtualenv layout).
A Surefire/Failsafe fork started with suspend=y never reaches the console
with its "Listening for transport" line: surefire buffers the fork's
output until the tests run, and the tests wait for the debugger. The IDE
found no port, never attached, and Stop left an orphan debug session.
Pick a free port up front (new debug_free_port IPC), pass it to the
-Dmaven.surefire.debug/-Dmaven.failsafe.debug agent as
address=127.0.0.1:<port>, and attach right away — java-debug retries the
connect while the fork starts, so no output line is needed. A duplicated
line that does arrive later is deduplicated by port.
Only user scrolling (wheel, touch, keys, the scrollbar, Find) leaves the end of an agent conversation; offsets WebKit moves back on its own while rows lay out no longer stop it following and painting its history.
The Switcher popup unmounts synchronously and gives focus back, then the selection opens in the same task, so closing and switching paint in one frame instead of two.
A just-killed dlv can still hold this session's binary while the previous
run's lock is already released, so one remove_file attempt only ever
deleted the older leftover. Retry with a short back-off so the sweep
outlasts the handle release.
Adds the agentTabs perf scenario: two 2,100-entry agent conversations switched with Ctrl+Tab and scrolled, with budgets on DOM size, rows skipping rendering off screen, switch latency, scroll jumps and frame pacing.
.editBody had a min-height but no cap, so a tall form grew it past the
viewport and the dialog body scrolled both panes together. Cap it below
the dialog's own body bound and let each pane's overflow take over.
* fix(java): run jdtls on a new-enough JDK behind Scoop shims and project JAVA_HOME
Two ways jdtls ended up on a JDK too old for its bundles (#2227):
- jdtls_min_java resolved the command's own path to derive the install
root, but a Scoop shim (shims\jdtls.exe) hides the release layout, so
the bundles' real requirement fell back to JDTLS_MIN_JAVA (21) while a
1.64 install needs JavaSE 25. Extract the resolve/follow-shim flow
from launch_directly into jdtls::script_for and share it.
- configure_jdtls only wrote JAVA_HOME when the config had none, so a
project JAVA_HOME (JDK 8 for compilation) won over the chosen
server_jdk. Probe the configured value: a home too old or incomplete
for the server is replaced by server_jdk or any usable JDK; an
unresolvable explicit value stays (the user's call).
* test(java): compare JDK homes against canonical paths
jdk_at reports the canonicalized home (macOS /var -> /private/var,
Windows 8.3 short names), which configure_jdtls now writes to JAVA_HOME.
Have test_jdk canonicalize too, and assert the runtimes/JAVA_HOME values
against the Jdk.home fields instead of raw fixtures.path() joins, which
also differ on Windows when the join arg uses forward slashes.
* test(jdtls): compare JAVA_HOME against the canonical jdk home
test_jdk now canonicalizes home, so the duplicate-versions assertion must
compare against server.home rather than the raw tempdir join, which on
Windows carries 8.3 short names.
Folded conversation sections render their content only when opened (or while Find in Conversation is open), and off-screen rows skip rendering once laid out, so showing a kept-alive agent tab no longer restyles the whole history.
A paged Git log only carries each commit's summary line; the Edit Commit
Message dialog therefore opened with the body missing, and OK rewrote the
commit to the subject alone.
Load the full message through loadLogDetails when the commit's
messageTruncated flag is set, the same path Copy Commit Message already
uses, so the dialog edits subject and body together.
Fixes#2238
New agent tasks defaulted to Bypass whenever the provider offered it, whatever the user had chosen. A task now starts with the settings shown in the composer: the provider's reported mode, or Ask for Cursor. An explicit choice is kept, including Bypass, and running tasks keep their own mode. Cached provider settings could hold a Bypass written automatically with no record of its source, so a cached bypass is dropped on load, read and save while the option stays offered.
Fixes#740
The Vue editor mode (`@codemirror/lang-vue` over the stock HTML base)
parses every `<style>` block as plain CSS, so SCSS — nested rules,
$-variables, and so on — rendered uncoloured or mis-highlighted.
Register a Vue mode of our own (overriding the language-data entry) that
gives the HTML base a nested Sass grammar for `<style>` whose `lang`
is `scss` or `sass`; blocks without a dialect keep CSS.
`kill_tree` and `kill_tree_of` run `taskkill /T /F /PID` on Windows even when the child has no descendants, which is the common case for a program a plugin started, read from and closed. `taskkill` is a process spawn — ~0.7 s here, measured on this machine — and it runs inside host calls that are inside a plugin call's budget: dropping eight process handles at once overran a 5 s budget, so the plugin was trapped for something the host did.
When `descendants(pid)` is empty the child itself is all there is to kill, and both callers already do that (`kill_tree` follows with `child.kill()` + `child.wait()`, `kill_tree_of` leaves the child to its owner), so the spawn buys nothing. Skip it.
Verified:
- `cargo test -p ide-core` → 77 passed.
- `cargo test -p ide-host --test plugins` → 95 passed, including `a_plugin_keeps_a_process_running_behind_a_handle`, which fails on unmodified `main` on Windows (`plugin "misbehave" timed out after 5s` at its `childdrop` step, which drops eight handles) and now passes in 9.7 s instead of 20 s.
- clippy `--all-targets -D warnings` and `cargo fmt --check` clean; no component or WIT change, so nothing to rebuild.
Co-authored-by: chao <[email protected]>
Co-authored-by: l0ng-ai <[email protected]>
Plugin API 1.4: grants for unencrypted HTTP, local sockets, IDE commands and owned database sources; window status items, output channels, content tabs, editor selections, decorations, search, Problems and VCS reads; runs, keyed terminals with exit events, plugin run targets, dynamic run configurations and test parsers; language features, injections, snippets and menu locations; plugin MCP tools on the built-in server; four official API examples. Released 1.3 plugins keep working.
Choosing an agent model took two popovers, and the list cut a name on one row while showing it in full on another. The chip's popover now shows the effort slider above a searchable model list. Names with a description keep their full width, and the description is cut instead. The list is extracted from `Select` as `SelectListbox`; `Select` keeps its previews across popup open and close.
Co-authored-by: panda-student <[email protected]>
New Agent Task showed no model, effort or mode for Claude until an agent had run a task. The `initialize` request that already loads commands also returns those options, so they are now remembered and shown, with one extra `get_settings` request to read the configured effort. No prompt or session starts, a failed lookup is not repeated, and a session's own report always wins, in memory and on disk.
Co-authored-by: panda-student <[email protected]>
The main toolbar and status bar could not be hidden, Tool Window Bars was a Settings row only, and widgets could be switched only from the status bar's context menu. View > Appearance now has Toolbar, Tool Window Bars, Status Bar and Status Bar Widgets, with check marks in the macOS and in-app menus, plus Settings toggles. Both new settings default to shown. With the toolbar hidden, the window keeps a compact header with the title, which Distraction Free now shares.
Controls stay reachable with a bar hidden: the Git branches popup and background tasks have their own hosts, and background tasks has an action.
Co-authored-by: lleviathe <[email protected]>
The refusal added for indexed-only renames missed code names in Go, Ruby and PHP, ran without the rename cancellation, and was English only. It now covers those node kinds, honours cancellation, and translates the hint.
The `.icls` effect table used the wrong `EFFECT_TYPE` codes, so imports lost underlines and wavy underlines, and exports gave IntelliJ a box where the IDE showed an underline. Codes now match IntelliJ: 1 underline, 2 wave, 3 strikeout, 4 and 5 become underline, 0 and 6 are skipped. As in IntelliJ, an effect without an effect colour is not drawn on import, and export writes a colour for every effect, leaving a cleared error or warning effect off. Export also keeps effects defined by theme tokens, such as the doc tag underline in Islands Light.
Co-authored-by: lleviathe <[email protected]>
When no language server answers a rename (none running, or no rename
support) and the indexed anchor under the caret is a code identifier,
prepare and rename now refuse instead of renaming only the plugin's
anchors, which left the declaration, imports and file name behind.
Anchors in strings, comments, attribute values or files without a
grammar keep their indexed rename.
Closes#2204