Compare with Local, Compare Versions and the other revision comparisons open in a separate window that belongs to their project window. The window can be moved outside the main window, resized from its edges and corners, and shows the full diff. Edits made there and in the project window are mirrored both ways.
Root cause of #798: the comparison was an in-window dialog with a fixed size.
Settings and comparison windows now share one auxiliary-window mechanism (`AuxKind`, `open_auxiliary_window`). It handles labels, the title bar, placement over the parent, event forwarding, document-edit mirroring, menu routing, closing together with the parent, and remembered geometry per kind.
Co-authored-by: xdpan1234 <277608284+xdpan1234@users.noreply.github.com>
Connecting a remote window titles it `<project> [<user@host>]`, but the frontend rewrote the title from the project and active file whenever either changed (and after a reload), dropping the host. The title now includes the remote session's host.
`openidea --line 120 --column 8 <file>` opens the file at that position (1-based; without --column the line start; clamped). The position is kept by file until the window that opens it takes its launch: new instance, second instance, a project open elsewhere, an already open file. The path argument skips these flags' values.
Closes#829
Ctrl+Z / Cmd+Z in the Project view (and Edit › Undo while it has focus) reverts the latest file operation there: a delete as well as a move or rename. Deleted files come back from their last Local History snapshot, folders are re-created and the restored items selected; items without a snapshot are named in a warning. Edit › Undo reaches the view through a new registerUndoHandler contribution; the Project view is found by a data attribute instead of its translated aria-label (also fixes the New popup's fallback anchor).
Project view options such as "Open Files with Single Click" live in localStorage under openidea.projectTree.options, which was not on the export allowlist, so Export/Import Settings dropped them.
Other IDE-level preferences stored the same way are exported and restored too: TODO patterns, IdeaVim settings, diff/merge options, branches popup options, markdown and image viewer defaults, reopen last project. Per-project state stays out.
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>
Right-clicking a project tab in a merged window group offers Close Other Tabs, Close Tabs to the Left and Close Tabs to the Right (left/right disabled at the ends); the same commands are in the Command Palette and can take shortcuts.
The backend closes the projects one at a time, focusing each so its own unsaved-changes prompt is visible, as Quit does. Cancelling a prompt stops the batch and leaves that project and the rest open; the clicked tab stays and is selected when the batch finishes. Starting Quit clears a pending batch.
Closes#942.
Co-authored-by: jaw52 <53564781+jaw52@users.noreply.github.com>
Check for Updates on the welcome screen showed nothing while the request was out: the check ran only as a status-bar task, and the welcome screen has no status bar. Leaving a project also dropped every notification, including a running update download.
A check started with no project or LightEdit window open now shows its progress in a balloon (keyed like the result, so the result replaces it); project windows keep it in the status bar. A project switch clears only project notifications and keeps the app-wide update ones.
Co-authored-by: youngtseup <53266026+youngtseup@users.noreply.github.com>
Root cause: Cmd/Ctrl+A in the Run console fell through to the browser and selected the whole window, and copying only saw the rows the virtualizer had mounted. Select All now selects the console only (also in its context menu), and copying after it — keyboard, context menu or native copy — takes the whole buffer. copySelectionOnKeyDown accepts a textOf callback for other views that do not mount all their text.
Refs #746
Co-authored-by: ntbang0901 <121003585+ntbang0901@users.noreply.github.com>
Project windows only joined a tab group when merged explicitly or restored at startup; the macOS "Prefer tabs when opening documents" setting was never read, so opening another project or a workspace always created a separate window.
New project windows now follow that preference: with Always they join the active project window's tab group (forming one if needed) and are selected; with In Full Screen they do so only while the active window is full screen; with Manually they stay separate. This covers every path that creates a project window — Open, recent projects, workspaces, drag and drop, and opening from the command line or Finder — while LightEdit windows and restored groups keep their behaviour. New Workspace now opens through the same Open project in policy as Open Workspace, and a race when toggling full screen during the join is fixed.
Fixes#678
AppKit puts the title bar container and window buttons back at their defaults on every live resize step, title change and fullscreen exit. They were corrected from window notifications after that layout had been drawn, so the buttons bounced between positions, or stayed at the defaults when no notification followed. The frames are now corrected in a main run loop observer ordered just before the Core Animation commit, project windows are created hidden on macOS so the buttons are placed before the first frame, and repeated title bar height updates are skipped.
Choosing This Window for a local project in a remote window was routed to the remote host or skipped when the path matched the remote root. open_project and light_edit_open now run on the local backend and leave remote mode once they succeed, project trust for these opens is checked locally, and a failed open cancels the pending close.
Help › About showed no version, build or runtime in untrusted project windows and on the welcome screen.
Root cause: the restricted-mode allowlist added with project trust missed app_build_info and other application-level commands, so they were rejected wherever the window had no trusted project; the frontend then cached the failed build info for the whole session.
Fix: classify all registered commands and allow the 24 that only read application information or change the user's own application state (build info, log location, update checks, cache invalidation, file clipboard, JDK download, Docker settings, database export paths, patch export, system environment); JDK download now uses the application tool directory instead of project tool settings. Execution commands (run, build, debug, language servers, tool install from project settings) stay blocked. Build info is retried after a failure instead of being cached. Verified on macOS in an untrusted project and on the welcome screen; Windows not run.
Related to #519
Projects now open with a user-owned trust decision. The prompt offers Preview in Restricted Mode, Don't Open and Trust Project, with an optional trusted parent folder; preview is the default focus so Enter never grants trust.
Restricted projects keep browsing, editing, saving, search and highlighting. Project-controlled execution is denied by default in the backend: run, debug, build, tools, language servers, plugins and Git commands that could honour repository configuration. Trusting a project enables those paths without reopening it, and decisions can be revoked in Settings.
Terminals stay available when the user opens one, without project shell settings, environment or virtualenv activation. A shell prompt that runs git in the folder can still honour the repository's core.fsmonitor.
Fixes#462
The welcome screen has no status bar, so clicking Install and Restart there showed nothing until the download ended. The notification now stays with the download progress and Cancel, and a cancelled update says so.
Fixes#491
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#241Closes#198Closes#286
On Windows and Linux, Ctrl+C in the Run/Debug consoles and other DOM output views did nothing because no handler copied the selection. Each output view (Run and Debug consoles, Build output and message detail, Git console, database output, Docker logs) now copies its own selection on Ctrl+C / Ctrl+Insert (Cmd+C on macOS) through a shared helper, leaving views with their own copy handling (database grid, Problems) untouched. In terminals, Ctrl+C copies a selection on Windows and Linux and otherwise interrupts; on macOS it always interrupts. The console menu shows the host's copy shortcut.
Not verified on a real Windows machine.
Fixes#372
Opens .ipynb files in a native notebook editor, in a project or LightEdit.
- crates/ide-notebook: lossless nbformat documents (unchanged notebooks save byte-for-byte, unknown fields kept, external changes detected) and owned local kernels over ZMQ via kernelspec — the selected Python environment only needs ipykernel, no Jupyter server.
- ide-host owns notebook documents per project incarnation and admits one execution batch at a time; outputs stream over IPC channels and kernel status is an IdeEvent.
- src/features/notebook: virtualized Python/Markdown cells, insert/delete/move/change type, Run Cell / Run All (Shift+Enter), interrupt, restart, interpreter selection from ide-sdk discovery, shared split views. Raw/unknown cells stay read-only.
- Custom editor kinds take part in dirty state, save/save all, undo/redo and Save/Don't Save/Cancel; closing editors from other features awaits that decision.
- Outputs: text, tracebacks, PNG/JPEG and sanitized SVG inline; HTML sanitized in a sandboxed iframe without allow-same-origin; JavaScript output is shown as inert source.
- Explicit launches (opening a notebook from the OS) win over session restoration.
Closes#131
Co-authored-by: dvictor357 <187467850+dvictor357@users.noreply.github.com>
Adds knip (pnpm knip, knip.ts covering src, scripts, perf and e2e) and runs it in the CI frontend job. Removes what it reported: the unused codemirror and @types/dompurify dependencies, exports and test hooks used nowhere (AppLogo, Tooltip, barrel re-exports, duplicate default exports of lazily loaded settings pages), the unused iterateAll helper, and the zh entry for a deleted notification. rustfmt (used by lint-staged) is ignored as a toolchain binary.
Co-authored-by: jaw52 <53564781+jaw52@users.noreply.github.com>
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
Installing an update gave no feedback: app_install_update discarded the download progress callbacks and downloaded the whole package silently before restarting, the UI had no pending state, and repeated clicks started parallel downloads. Manual Check for Updates also showed nothing while checking.
The update now runs as a status-bar background task: "Checking for updates…", then "Downloading OpenIDEA x.y.z" with size and percentage (streamed over a Channel, one event per percent) and Cancel until the download completes, then "Installing…". A running check or install is shared, so clicks from the notification, the notification log, Help › Check for Updates, the toolbar menu, the welcome screen or Search Everywhere join it; the backend allows one install at a time. Failures show an error notification with Retry. After installing, the app restarts through every window's unsaved-changes check and leaves an "installed" notification with Restart in case a window cancels it. Signature verification, endpoints and updater configuration are unchanged.
Fixes#156
Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
Files opened from inside the app (File › Open File…, a drop on the Welcome screen, Open File in a single-file window) were always kept in the requesting window, so a file belonging to a project open in another window went to the single-file window instead. These paths now follow the same rule as Finder, Dock and second-instance opens: window_open_files normalises the paths and routes them through plan_open via plan_open_files, which sends files inside an open local project to that project's window. It returns only the files the requesting window should open itself. The TypeScript side no longer has any routing logic. Files dropped onto a project window still open in that window.
Refs #128
On macOS, OpenIDEA is now listed under Finder's Open With for text and source files and for folders. It never becomes the default app for any of them: all document types are declared with rank Alternate, and only in tauri.macos.conf.json, so Windows and Linux installers register nothing.
Files opened from Finder, the Dock or a second instance share one routing path (plan_open). A file inside a local project that is already open, or still opening, goes to that project's window, choosing the deepest root when projects are nested. Any other file goes to the existing single-file window, or to a new one. A folder focuses the window that already has it open, otherwise it opens as a project. Paths that arrive before setup are queued and opened with the first launch.
The single-file window now closes with its last tab, restores its files the next time it opens, and only offers Open File and drop hints when empty. Also fixes a regression: reopening projects on startup no longer replaces a file opened at cold start.
Refs #128
Files can now be opened without a project. A file dropped on the Welcome screen, picked with File › Open File…, or passed on the command line or to a second instance opens in a lightweight window: editor tabs only, with no project tree, indexing, language servers, VCS or project tool windows. Syntax highlighting, find, save, undo and Local History still work. More files opened later join the same window as new tabs. Open as Project in the status bar opens the file's directory as a full project, following the open-project policy, and reopens the file there.
Backend: a light session reuses Project with an unindexed index, no LSP or VCS, and a flat watch on each opened file's directory. It is never reused as a project for the same root. Previously a file passed at launch opened its parent directory as a project.
Run oxfmt once over the whole repository (formatting only, no logic changes) and add `pnpm format:check` to the frontend CI job so unformatted code no longer builds up. `.oxfmtrc.json` now skips the generated theme docs, test fixtures and code blocks inside Markdown.
Co-authored-by: jaw52 <53564781+jaw52@users.noreply.github.com>
- The title bar project popup lists Remote Development… next to Open… and Clone Repository….
- Opening a remote project follows "Open project in" (new window / this window / ask) when this window already has a project, and confirms leaving the current one first.
- A remote project already open in another window focuses that window.
- A new window connects to the host itself and shows the connection progress on its welcome screen.
- Recent remote projects get Open in New Window.
About 270 UI strings were JS template literals with interpolation passed to exact catalog lookup, so they could never be translated; about 25 more spliced lowercase English fragments into sentences.
`tx` now also works as a template tag (`` tx`Remove data source '${name}'?` ``): it looks up the entry by the literal parts (`{name}` placeholders), translates interpolated values that have entries, and remembers generated text so it re-translates after a language switch or when the catalog loads later. Call sites use the tag; spliced fragments are written as whole sentences per variant. Adds 280 Chinese translations and removes stale ones.
The catalog guard now also fails on untagged template literals reaching exact lookup (unless allowlisted with a reason), tagged text missing from the catalog, case-changed or ternary-suffix interpolations, and duplicate template patterns.
Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
Keymaps only understood keystrokes, so the mouse back / forward side buttons did nothing. Keymaps now accept mouse shortcuts (Button4, Shift+Button5, …); every preset binds Button4 / Button5 to Navigate Back / Forward. The dispatcher handles side-button presses in the capture phase, so they work over the editor, tool windows and empty space, never change the editor selection and don't trigger the webview's own history navigation. Menus and tooltips keep showing the keyboard shortcut.
Fixes#75
Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
Root cause: body is user-select: none and each feature had to opt back in; the Markdown preview (and other read-only views) never did, and the app-wide contextmenu guard left no Copy item.
Fix: shared selectableText class (src/ui) for read-only content, and a fallback Copy context menu from browserGuards when right-clicking a selection or a selectable area (component menus still win).
Siblings covered: Quick Documentation / hover / completion docs, hover errors, Quick Definition, debugger value tooltip, inspection messages, message dialogs (no drag on body text), notification titles, About dialog; existing selectable consoles now get Copy too.
Verified in-app on macOS: select in Markdown preview, right-click Copy puts the text on the clipboard; tab context menu unchanged.
Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
Project & files
- Project view modes (Project Files / Open Files / All Changed Files /
Scratches); External Libraries for Python, JDK (src.zip), Node, Cargo, Go,
Maven/Gradle jars; read-only jar/zip browsing
- ⌘N New popup with type search and more file kinds; New Project, Rename
Project, Reload All from Disk, Export/Import Settings, Power Save Mode
- File type associations, extra content roots and exclude patterns (indexed
and watched without reopening the project)
Editor & navigation
- Find bar: search scope (comments/strings), Preserve Case, Exclude, multiline,
history; Find in Files: Module scope, custom pattern scopes, multiline
- Search Everywhere filters, Assign Shortcut, settings results; named bookmark
lists, file/folder bookmarks; Structure filters and Show Inherited; Recent
Locations timestamps and breadcrumbs; Code Vision author
- Completion options, editor tab placement/layout, inline completion (LSP 3.18)
- Spell checking (Typo inspection, ide-spell) and Inspections settings with
custom profiles; Code Style schemes, formatter markers, Do not format
Run, VCS, services, database
- Typed run configurations (Shell, Program, npm, Gradle, Maven, Docker,
Compound), Modify options, Before launch, env dialog, Current File,
Emulate terminal (PTY)
- Git log graph/view options, Go to Hash/Branch/Tag, date filter keeps the
graph; Pull/Merge/Rebase dialogs, Manage Remotes, Worktrees
- Generic Services host (Docker connections/registries, run sessions); TODO
scope/changes tabs with changelists; Coverage report import
- Data sources: wire-compatible vendors, URL import, SSL certs, Options,
Schemas and Advanced tabs, color and comment
Workbench
- Run Anything, Customize Main Toolbar, named tool window layouts, menu
completeness, Code Cleanup, macros, "Don't Show Again", editor banners
- Chinese translations for the new UI
Claude-Session: https://claude.ai/code/session_01SaPPsVPuk6ZTNsoUCNCbMv
* feat: Second pass aligning interactions with IntelliJ IDEA
Result tool windows
- Next/Previous Occurrence (⌥⌘↓/↑) across Find, Usages, Problems, TODO,
Inspection and Hierarchy, with an "N of M" status hint
- Find: reuse the unpinned tab, Pin Tab, source preview, group by file or
directory, exclude moves to the next result, Rerun
- Usages: tabs with pinning, exclude and preview
- Problems, TODO, Inspection: no autoscroll by default, severity-first sorting,
context menu with quick fixes and copy description
- Trees: F4/⌘↓ jump to source; speed search Home/End and arrow handling
Find in Files, bookmarks, navigation
- Replace mode: Enter replaces the selection, ⇧⌥Enter replaces all, multi-select
- Pin Window toggle, highlighted read-only preview, search/replace history (⌥↓),
Alt mnemonics, search context filter (comments / string literals)
- Mnemonic bookmarks (⌥F3, ⌃⇧digit, ⌃digit), ⌘F3 bookmarks popup, descriptions,
⌘-click gutter toggles a bookmark
- Select In popup (⌥F1); Recent Locations double-click and Delete;
Search Everywhere remembers the query per tab
Code insight and refactoring
- Extract/Introduce continue with in-place rename and name suggestions;
expression and occurrence choosers with live highlighting
- Safe Delete confirms first; numbered Refactor This
- Quick Documentation history, in-popup links and a Documentation tool window;
Quick Definition switches between targets and shows the whole declaration
- Goto chooser lists symbol names and can pin to the Find window
- Parameter Info Tab/⇧Tab, intention preview, Reformat dialog and summary,
inlay hint ⌘-click and context menu
- Live templates: Enter moves to the next field, two-step Esc, ⌘J as a lookup,
language surrounders with mnemonics
- File Structure popup as a filterable tree; Show Usages filter and preview;
call hierarchy jumps to call sites
Editor
- Paste re-indents each line by default; Move Statement moves whole statements
in and out of blocks and re-indents
- Type over closing quotes of existing strings; ⌘D/⌘⌫ cover folded regions;
⌥⌫ deletes the preceding word
- ⌃G / ⌃⌘G whole-word rules and wrap hint; double-modifier caret cloning
- Visual-column block selection, nested Collapse All, recursive folding,
fold selection toggle, Go to Matching Brace, gutter drag selects lines,
sticky line and error stripe clicks, Insert toggles overwrite mode
Run, VCS, workbench
- Gutter icons show the last test result; Modify Run Configuration; test tree
hides passed tests, context menu and assertion diff
- Stack frames resolve by fully qualified class name; context run chooser
- Inline Smart Step Into
- Git Log multi-select filters, "me" and date range; favourite branches,
Fetch and tags in the branch popup; stash Keep index and Unstash options
- Terminal tab titles follow the shell; Distraction Free persists; gear menu;
sticky balloons move to the notifications tool window after a while
* fix(vcs): Label restored local changes as yours after Smart Checkout; name the branch checked out
Conflicts from restoring stashed changes show the user's uncommitted
changes on the left like other operations, and the checkout notification
names the new branch instead of the previous one.
* fix: Close the merge editor on Apply; confirm before terminating a running Run tab
Like IDEA, applying a merge result closes its tab, and closing a Run tab
whose process still runs asks before terminating it (with a Settings
toggle and "Do not ask again").
* fix(terminal): Don't start a new session in the background after closing the last tab
The hidden Terminal window stays mounted, so it reopened a session as soon
as the last tab closed. It now opens the Local tab only once the window is
shown again, as IDEA does.
* fix(vcs): Start the merge result from a three-way merge; close the editor on Apply
The result pane now begins with non-conflicting changes merged and each
conflict showing the base text, resolved from the side panes, instead of
raw conflict markers. Apply now reports success, so the tab closes.
fix(search): Match File Structure filter on word starts
* fix: Limit Smart Step Into to the paused line; drop usages hints on callbacks; show full intention titles
Adapters that list every remaining call in the function (debugpy) made Smart
Step Into fall back to a chooser that offered calls from later lines. Targets
are now narrowed to the calls on the paused line, so they are picked in place.
Anonymous functions and callbacks no longer get a 'no usages' hint, and
intention titles are no longer cut short when there is room for them.
* fix: Undo / Redo from the Edit menu and Find Action use the editor's history
They ran the webview's native undo, which misses programmatic edits such as
templates, completion and refactorings, so nothing happened in the editor.
Configure the updater public key and the releases/latest latest.json
endpoint, and build updater artifacts so tauri-action uploads signatures
and latest.json. Check for updates once per app start (release builds
only) and offer Install and Restart when one is available.
Message dialogs: `Dialog` gets an `icon` (question / info / warning / error)
that renders IDEA's alert layout: no title bar, a 32px icon, bold title,
text, checkbox under it. Every confirmation helper (prompt, VCS, services,
project tree, keymap, LSP choices, run, database, Replace All) uses it. Open
Project matches IDEA: "This Window" is the default and has focus. The Code
Analysis and TODO commit checks default to Review.
Project widget: the title bar project button opens a popup like IDEA's
ProjectWidget, with Open… / Clone Repository…, the projects open in other
windows (new `window_open_projects` command) and recent projects, filtered by
typing.
Chinese UI: UI text stays written in English and is translated through a
source-text catalog (`locales/text/zh.json`, about 2300 strings). The UI
primitives (buttons, checkboxes, selects, tabs, dialogs, menus, tooltips,
toasts, settings labels and hints) translate the strings they are given.
Action titles and categories are localised in the registry, and static JSX
text uses `<T>`, so text follows a locale switch without a reload. The
Settings window now syncs the locale too. Settings search matches both
languages.
Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
Project windows are created in setup with the saved theme's frame colour, and the splash covers the first render while the launch project opens, so a window no longer flashes white or the Welcome screen. Single-instance is now release-only so a dev build can run beside an installed release.
* fix: Stop the status refresh loop and the double project open at startup
Every status rewrote .git/index, even with nothing to persist: gix's
`write_changes` writes an empty change set too. The watcher reports
.git/index writes as VCS changes, so each status triggered the next one,
together with an ahead/behind walk. On a repository with a long history
(freqtrade, 33k commits behind upstream) that kept a core busy for as long
as the project was open. Write back only when `has_changes()`.
A project passed on the command line was opened twice: the launch and the
"reopen last project" restore ran concurrently, and the restore checked
for an open project before the launch had finished. The second open found
the index cache locked and indexed in memory only; with a different last
project, the window ended up on whichever finished last. The restore now
waits for the startup launch.
* fix(lsp): Run jdtls on the Java version its bundles need
jdtls's launcher checks for Java 21, and so did JDTLS_MIN_JAVA, but the
Eclipse platform a release ships moves on: 1.63 bundles
org.eclipse.core.filesystem with JavaSE-25, so on a JDK 21 the server died
resolving its bundles ("jdtls is not ready (Crashed)") and the error told
users to install the 21 they already had.
Read the requirement from the installed jdtls instead: the highest osgi.ee
capability / Bundle-RequiredExecutionEnvironment among its plugins'
manifests (cached per install), never below 21. The runtime choice, the
rescan while no JDK fits and the "needs JDK N" message use it.
Fixes#4
Opening another project in the same window left the previous project's state in
module-level stores: Amend and the commit message carried over, debug sessions kept
running, and Git Log, usages, hierarchy, inspection, HTTP client, recent locations,
navigation history and notifications still showed the old project.
Reset each of them on a project root change, stop the old debug sessions, ask about
unsaved changes before leaving a project, close the settings window (it would apply
to the new project) and end the indexing task when a scan is cancelled.