Commit Graph
78 Commits
Author SHA1 Message Date
Mykhailo Smolinskyiandnntndfrk 2613e61ebf feat(angular): highlight directive microsyntax and fold control-flow blocks (#458)
Angular templates left parts of their syntax uncoloured or misparsed, and control-flow blocks could not be folded. Binding names such as (keydown.escape) and [style.width.%] now take one colour and parse; structural directive values are parsed as microsyntax rather than JavaScript statements; block keywords are keywords only where one can appear; ?. is styled like . in templates and in JS and TS files; @if, @for, @switch, @defer and related blocks fold from { to } with the closing brace left visible.

Co-authored-by: nntndfrk <2458463+nntndfrk@users.noreply.github.com>
2026-10-31 00:22:26 +08:00
arookieofcanda-rookie-of-C-language 091c25351b feat(keymap): bind Ctrl+Alt+click to Go to Implementation on Windows and Linux (#469)
The Windows/Linux keymap only bound the Ctrl+Alt+B stroke to navigate.implementation, so the click gesture that #405 made remappable did nothing there. Adds Ctrl+Alt+Button1 alongside the existing macOS Meta+Alt+Button1 binding; other Alt-click gestures are unaffected because column mode and multi-caret need different modifiers.

Closes #365

Co-authored-by: a-rookie-of-C-language <186315048+a-rookie-of-C-language@users.noreply.github.com>
2026-10-30 22:51:49 +08:00
l0ng-ai 01defdefe4 feat: multi-project workspaces and project window groups (#448)
Workspaces open several local project folders in one IDE session (File › New / Open / Manage Workspace…, or Attach when opening a project, which creates a workspace automatically for a plain project window). Member folders are the Project view roots and take part in indexing, Find in Files, Git, language servers, run configurations and builds; agent tasks choose which member they work in. Window › Merge All Project Windows groups project windows into one window with project tabs (switch, reorder, close, move to a new window), restored on reopen.

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

- Rename and call hierarchy return why the result may be incomplete and take a
  request id for cancel_request.
- A rename that may have missed usages always opens the preview, with a warning.
- The Callers tree shows the note above the tree or on the expanded node.
- Candidates too large or not readable as text are reported as skipped.
- A newer rename or hierarchy query cancels the one it replaces.
2026-10-30 22:08:10 +08:00
huaqiang yang 669595e045 feat(keymap): support modified left-click shortcuts (#405)
The mouse shortcut recorder accepted only side buttons, so a modified left click such as Option+Command+click couldn't be assigned. Left clicks with Ctrl, Alt or Command now record and dispatch as mouse shortcuts (plain and Shift-only clicks, middle and right clicks keep their meaning; unbound combinations behave as before). In editors the caret moves to the clicked position before the action runs, so navigation targets the symbol under the pointer. The macOS keymap binds Option+Command+click to Go to Implementation(s).

Co-authored-by: huaqiangyang <35088657+huaqiangyang@users.noreply.github.com>
2026-10-30 20:52:27 +08:00
l0ng-ai b2c183dbd4 fix(php): document language constructs and clarify rename failures (#354)
PHP language constructs such as empty and isset had no completion documentation, hover or quick documentation because the language server reports them as plain keywords. They now get built-in documentation in completion, hover, quick documentation and Go to Declaration (which shows the docs instead of failing), without matching strings, comments, methods or other languages. A refused syntax-based rename now states why the language server couldn't rename first.

Closes #340
Refs #221
2026-10-30 19:46:08 +08:00
arookieofcanda-rookie-of-C-language 67e3c60db8 feat(vcs): blame each merge side pane on the branch it belongs to (#391)
The merge view blamed both side panes against HEAD, so lines that only exist on the merged branch showed as Not Committed Yet. vcs_blame takes an optional revision (validated, passed to git blame --contents -); the merge view blames Yours on HEAD and Theirs on MERGE_HEAD (swapped during a rebase).

Co-authored-by: a-rookie-of-C-language <186315048+a-rookie-of-C-language@users.noreply.github.com>
2026-10-30 19:42:05 +08:00
arookieofcanda-rookie-of-C-language b983e3d0b2 fix(vfs): report excluded and ignored directories themselves; keep lane marks aligned while scrolling (#412)
The file watcher dropped events for a directory that matched an exclude or .gitignore rule together with its contents, so a target/ or node_modules/ created by a build never appeared in the Project view. The directory's own create/remove now passes through (it shows as excluded/ignored) while its contents stay filtered. Scrollbar lane marks also recompute on viewport changes, since unmeasured line heights shift as more of the document is measured.

Refs #383

Co-authored-by: a-rookie-of-C-language <186315048+a-rookie-of-C-language@users.noreply.github.com>
2026-10-30 19:28:35 +08:00
arookieofcanda-rookie-of-C-language 19b96b60a4 feat(vcs): offer Compare With… in the editor and tab menus, and outside the desktop app (#433)
Compare With… was only in the Project view menu and needed the OS file dialog. The editor context menu (with Compare with Clipboard) and the editor tab menu now offer it too, and outside the desktop app (remote development, browser) a browser file picker supplies the file, compared as text.

Co-authored-by: a-rookie-of-C-language <186315048+a-rookie-of-C-language@users.noreply.github.com>
2026-10-30 19:25:41 +08:00
l0ng-ai 932ac379bc feat(editor): highlight string interpolation in Kotlin, Scala, Dart, Groovy, C# and shell (#389)
The CodeMirror stream modes for these languages consumed string templates as one string token. A shared wrapper now splits template delimiters ($name, ${...}, C# {...}) from literal text and tokenizes the embedded code with the language's own mode, keeping nested braces, strings, escapes and multiline state; shell parameter, command and arithmetic expansions get the same treatment. Delimiters use the existing special-brace scope. JS/TS, Python, PHP, Swift and Ruby already tokenized embedded code and are unchanged.

Fixes #379
2026-10-30 17:49:54 +08:00
arookieofcanda-rookie-of-C-language 3655961642 feat(vcs): git UX fixes for history, remotes, changelists, branch diff and merge view (#369)
- Git › Show History is offered for folders, multi-selection and the project root, not just single files.
- The Push dialog lets you pick any configured remote; pushing to another remote keeps the upstream's branch name and shows outgoing commits against that remote's branch.
- The Changes toolbar gains New Changelist (changelists already supported new/edit/delete/set active/move).
- Compare with Current gains Show Diff, opening the whole-project diff between the branch and HEAD.
- Merge view: F7 / Shift+F7 navigate conflicts, the three panes scroll together, and each side pane can be annotated with Git Blame of its own content.
- Windows-only test fixes in ide-lsp and ide-sdk.

Fixes #343
Fixes #310
Fixes #358
Fixes #348
Fixes #320
Refs #317

Co-authored-by: a-rookie-of-C-language <186315048+a-rookie-of-C-language@users.noreply.github.com>
2026-10-30 15:17:11 +08:00
l0ng-ai 545fb93744 feat(editor): expand Replace from the Find bar with a chevron (#378)
The in-editor Find bar gains a chevron at its left that expands and collapses the Replace row (Replace, Replace All, Exclude), replacing the separate Replace icon button. Cmd/Ctrl+F opens the bar collapsed and Cmd/Ctrl+R expanded; the search text, options and focus are kept when toggling. The chevron reports aria-expanded.

Fixes #362
2026-10-30 15:11:35 +08:00
kevinh 9d1fe17894 fix(http-client): find the generated request scratch on Windows (#356)
Generate Request in HTTP Client (and Generate Requests for Controller, and the gutter icon) left the scratch file empty on Windows with "Cannot open file …\ai.l0ng.openidea/scratches/generated-requests.http": the scratch path joined the native app data directory (backslashes) with a /-separated suffix, so the opened editor could not be found by its path. Scratch paths now normalise the app data directory to the UI's /-separated form through a shared ipcPath helper, used by scratches, the HTTP client and Spring request generation.

Co-authored-by: kevinh458 <45650311+kevinh458@users.noreply.github.com>

未在 Windows 实机验证。
2026-10-30 15:09:50 +08:00
l0ng-ai 5792e7d9b6 fix(editor): size gutter icons consistently (#322)
The plain run glyph renders at 12px and the other gutter icons (run-all, run status badges, inheritance markers, HTTP request markers) at 14px through a shared gutterIconMarkup, so they look the same size. Run, Docker, HTTP, Spring HTTP and inheritance markers use it, and marker boxes are 14px to match the gutter column instead of overflowing it at 16px.
2026-10-30 10:55:55 +08:00
l0ng-ai 44d0f40b13 fix(completion): replace prefixes typed after cached requests (#324)
Accepting an LSP completion after typing more characters than the request saw (`System.out.` requested, then `Print` typed while the cached list stayed open) inserted the item after the typed text: `System.out.Printprint()`. The cached edit range started exactly at the request caret and was mapped forward past the newly typed characters. The range start now stays at the request caret, so the typed prefix is replaced, whatever its casing. Enter (insert) and Tab (replace) keep their behaviour for the text after the caret; this applies to every language server.

Fixes #316
2026-10-30 10:40:41 +08:00
Mykhailo Smolinskyiandnntndfrk 922bbf493a feat(angular): highlight Angular templates with control-flow blocks (#284)
HTML files in Angular projects were highlighted as plain HTML. Languages can now declare framework UI modes with root markers (angular.json, node_modules/@angular/core); files under such a root get the framework's editor mode, re-detected when a marker appears or disappears, and the root-marker lookup is shared with language server roots. The Angular Template mode (vendored @codemirror/lang-angular, MIT) adds @if/@for/@switch/@defer/@let blocks, key and animation binding names, and colours {{ }} delimiters.

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

Co-authored-by: nntndfrk <2458463+nntndfrk@users.noreply.github.com>
2026-10-30 07:39:31 +08:00
Dimas Victoranddvictor357 0d368ba947 feat(notebook): add native Jupyter notebook editing and execution (#268)
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>
2026-10-30 07:26:43 +08:00
Jaw d1f84ef364 perf(editor): stop re-rendering breadcrumbs on every caret move (#256)
The status-bar breadcrumbs, the code breadcrumbs and the closed Navigation Bar popup subscribed to the whole editor status, which is replaced on every keystroke and caret move, so ~30 crumb buttons re-rendered per key. They now select the symbol chain at the caret with a shallow comparison (re-rendering only when it changes), and the popup subscribes to the caret only while open. Typing 38 characters: 1386 → 152 component renders.

Co-authored-by: jaw52 <53564781+jaw52@users.noreply.github.com>
2026-10-29 23:41:03 +08:00
l0ng-ai 285c7187fb feat(languages): add Windows batch file support (#294)
.bat and .cmd files were plain text: no highlighting, no comment toggling and no Run. Batch is now a built-in language (languages/bat.toml, line comment @REM as in VS Code) with a CodeMirror stream mode for keywords, labels, %VAR% / %%i / !VAR! variables, strings and :: / REM comments. Comment toggling always separates a word-like token (REM) from the code. On Windows hosts the editor and project-view Run use cmd.exe /c <file> in the file's directory; other hosts don't offer it. 未在 Windows 实机验证运行。

Fixes #236
2026-10-29 23:34:22 +08:00
Jaw 5217f8570b chore: add knip and remove the dead code it reports (#247)
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>
2026-10-29 23:21:56 +08:00
l0ng-ai b9cfd54742 fix(editor): clear stale text focus when switching tabs 2026-10-29 22:42:19 +08:00
l0ng-ai b1347dd331 fix(lsp): keep background usage counts from delaying navigation (#282)
* fix(lsp): keep background usage counts from delaying navigation

* fix(lsp): retry incomplete counts and preserve newer hints
2026-10-29 20:49:01 +08:00
Kartik 3f9512056d fix(editor): auto-indent blocks in languages without a CodeMirror mode
Languages without a CodeMirror grammar had no indentation service. Add a low-precedence fallback, GDScript smart Backspace and statement completion. Review fixes preserve literal contents, Elixir inline do expressions and paired-bracket Enter indentation; regression tests cover these sibling cases.

Co-authored-by: kartik-madhak <58913047+kartik-madhak@users.noreply.github.com>
2026-10-29 15:03:25 +08:00
l0ng-ai d37b96002b fix: avoid lookbehind in application regexes for older WebKit
Application regex lookbehind prevented older WebKit from loading the startup module graph. Replace lookbehind with boundary checks across run/terminal links, SQL aliases, debugger targets and refactoring; preserve Unicode boundaries, UTF-16 offsets and empty-match progress. Add compatibility and regression tests.

Fixes #224
Refs #208
2026-10-29 15:01:01 +08:00
Kartik 06d78cf524 fix(lsp): isolate backoff for optional language features
Optional LSP failures shared one backoff with completion and other features. Give each feature its own per-document backoff and clear all feature backoffs when a server becomes ready.

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

Fixes #186

Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
2026-10-29 10:35:37 +08:00
l0ng-ai c6621c5c36 fix(editor): Count wide characters as two columns in column editing (#172)
Column-based editing computed columns with countColumn / findColumn, which count every grapheme as one column, and up/down and Clone Caret moved by pixel x, so block selections and cloned carets drifted on lines with CJK, fullwidth punctuation, Hangul, kana or emoji. A shared visible-column helper (UI side only, UTF-16 offsets in and out) now counts East Asian wide/fullwidth characters and emoji (ZWJ sequences, modifiers, flags, VS16) as 2, combining marks and format characters as 0, and expands tabs to the next tab stop.

It drives Alt+drag block selection, drag and Shift+arrows in Column Selection Mode, middle-drag block selection (new; not on Linux, where middle-click pastes the primary selection), the up/down goal column (kept across short lines; soft-wrapped and folded lines still move visually), Clone Caret Above/Below, the caret move after Comment Line, Tab padding to the next indent stop, and macro playback of arrow keys.

Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
2026-10-29 08:32:15 +08:00
l0ng-ai c7f75cb693 feat(editor): Close read-only tabs and keep a preview tab open from the tab menu (#165)
The editor tab menu gains Close All Read-Only Tabs (shown when the group has
unpinned read-only tabs) and Keep Tab Open (on a preview tab), which turns the
preview into a regular tab.
2026-10-29 03:06:12 +08:00
l0ng-ai e0af8ccce1 feat(editor): Open tabs in the opposite group, flip splitter orientation and unsplit all (#164)
Adds three split actions to the editor tab menu, the Window › Editor Tabs menu and
Find Action: Open in Opposite Group keeps the tab and opens a copy in the
neighbouring group (splitting when there is none), Change Splitter Orientation
flips the split holding the current group, and Unsplit All closes every other
group.
2026-10-29 02:52:30 +08:00
l0ng-ai af3ed649b7 feat(search): Jump between result groups in Search Everywhere (#163)
Page Down / Page Up and ⌘↓ / ⌘↑ (Ctrl+Down / Ctrl+Up on Windows) move the
selection to the first result of the next or previous group (Classes,
Files, Symbols, Actions…), including in the All tab, where groups have no
header rows. ⌘↑ inside a popup no longer jumps to the navigation bar.
2026-10-29 02:34:45 +08:00
l0ng-ai a28600c55a feat(editor): Show the enclosing declarations with Context Info (#161)
View > Context Info (Ctrl+Shift+Q on macOS, Alt+Q on Windows) shows the
class, method and block header lines around the caret in a hint, which helps
when they are scrolled out of view.
2026-10-29 02:01:18 +08:00
l0ng-ai 0c9c51b0f5 feat(editor): Add folding, navigation, editing and window shortcuts (#153)
Editing and folding
- Move Caret to Code Block Start / End with Selection, Auto-Indent Lines,
  Move Element Left / Right (swaps call arguments, parameters and list
  entries).
- Fold Code Block folds the {...} block around the caret; Expand to Level
  and Expand All to Level 1-5.
- Custom folding regions (//region, #region, <editor-fold>) fold to their
  description; Navigate > Custom Folding lists them.
- Error Description shows the problems at the caret; Next / Previous
  Highlighted Usage steps through usage highlights.
- Editor tooltips stay below the editor's top edge, so hints on the first
  lines no longer hide under the tab bar.

Navigation, project and run
- Navigate > File Path lists the file and its folders to reveal in the file
  manager.
- Copy... (F5) opens the Copy dialog for the selection or the open file; the
  project view's Refactor submenu gets Copy File.
- Debug... chooses a configuration to debug; Quick Evaluate Expression shows
  the selection's value in an expandable hint.
- Inspect Current File runs the inspection without the scope dialog.
- Surround with Live Template lists only $SELECTION$ templates; Java gets
  Callable, read / write lock and iterate templates.

Windows
- Stretch the active tool window left / right / up / down, Restore Default
  Layout, Go to Next / Previous Splitter, Close Active Tab on a second key,
  Stop Background Processes.

All actions have default shortcuts in both keymaps, VS Code preset entries,
main menu items and Chinese translations.

Project view and Keymap settings
- Project view Options: Sort by Name / Type / Modification Time (also in
  Find Action).
- Settings > Keymap: Add Mouse Shortcut records a side-button click with
  modifiers and checks conflicts like keyboard shortcuts.
- Folding: Expand to Level / Expand All to Level 1-5.
2026-10-29 00:39:37 +08:00
itninganditning 7e6919010f fix(editor): Draw semantic highlighting above the syntax highlighter (#154)
Semantic token decorations were registered at Prec.high, the same precedence as CodeMirror's tree highlighter, so the syntax span ended up innermost and its colour won over the semantic one (fields, constants and other LSP-coloured identifiers looked like plain text). They now register at Prec.highest. The ⌘-hover link colour is kept over semantic colours, and semantic modifier lookup ignores Object.prototype names, which turned jdtls' `constructor` modifier into a bogus class.

Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
Co-authored-by: itning <19759891+itning@users.noreply.github.com>
2026-10-29 00:36:34 +08:00
Jaw a7c970a6db feat(vcs): Use the editor's find bar in the diff viewer (#148)
Find in the diff viewer (⌘F / ⌘R / ⌘G) opens the editor's find bar instead of CodeMirror's search panel: same field, Match Case / Words / Regex, counter, navigation, filter menu and highlights. In the side-by-side viewer the bar sits over the side with the caret, Replace is offered only on editable sides, and the shortcuts come from the keymap. Esc closes the bar even while a match is selected.

Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
Co-authored-by: jaw52 <53564781+jaw52@users.noreply.github.com>
2026-10-29 00:20:23 +08:00
Jaw 4a15936acb feat(editor): Smooth caret blinking and movement (#146)
Settings › Editor › General › Appearance gets "Use smooth caret blinking" and "Use smooth caret movement" (Snappy / Gliding), both off by default. Smooth movement animates only navigation and clicks; typing, edits and scrolling moves stay instant, and reduced motion turns it off. The diff and merge viewers now use the editor's caret and follow these settings instead of CodeMirror's default caret. Also translates a select's value shown while its checkbox is unchecked.

Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
Co-authored-by: jaw52 <53564781+jaw52@users.noreply.github.com>
2026-10-29 00:18:14 +08:00
Jaw 811da13a76 feat: Syntax-colour Find in Files and Show Usages result lines (#143)
Result lines in the Find in Files popup and tool window and in the Show Usages popup and Usages tool window are coloured like the editor, using the whole file as context, so a line inside a block comment or a multi-line string gets the right colour. The colouring lives in editor/lineTokens and all four lists share it; each file is parsed once and cached, and the parse runs in 8 ms time slices so large files don't block the UI thread. Lines that moved since the search, and files over 500k characters, are coloured on their own.

Claude-Session: https://claude.ai/code/session_01Dq6jQQn8ZhRfkkyj3PRutA
Co-authored-by: jaw52 <53564781+jaw52@users.noreply.github.com>
2026-10-29 00:18:02 +08:00
l0ng-ai 1d383e608c feat(workbench): Open files from Finder in the single-file window (#152)
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
2026-10-28 23:56:23 +08:00
l0ng-ai 2d7726cf53 feat(workbench): Edit single files without opening a project (#145)
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.
2026-10-28 22:06:35 +08:00
l0ng-ai 44b2d11b2d feat(agents): Select the active session in the Agents list (#140)
Switching between agent session tabs in the editor now moves the Agents
tool window's selection to that task, expanding its group (e.g. Archived)
when it is collapsed. The list also opens with the active session selected.
Tabs of other kinds leave the selection as it is.

The editor service gains activeInput() and onActiveInputChange() so
features can follow the active tab of any kind.
2026-10-28 20:36:55 +08:00
Jaw 55836e1b49 chore: Format the codebase with oxfmt and check formatting in CI (#135)
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>
2026-10-28 19:35:16 +08:00
l0ng-ai 630d436e18 fix(editor): Allow selecting and copying text in read-only code previews (#136)
Code previews (Find in Files, Usages) are non-editable CodeMirror views, so their text inherited the workbench's user-select: none and had no tab stop: it couldn't be focused, selected with the keyboard or copied. Previews now opt their content back in with the shared selectable-text class and take a tab stop; editing stays blocked. Same root cause as the read-only diff panes (#126).
2026-10-28 18:32:00 +08:00
Jaw 8ff8f22940 chore: Replace Prettier with oxfmt and ESLint with oxlint (#119)
pnpm lint runs oxlint and pnpm format runs oxfmt: lint ~0.3s instead of ~20s, format check ~0.2s instead of ~11s, with far less memory. Configs come from the official migration tools (.oxlintrc.json from eslint.config.js, .oxfmtrc.json from the Prettier config); six new findings fixed or suppressed in 4 files. No code is reformatted.

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
Co-authored-by: jaw52 <53564781+jaw52@users.noreply.github.com>
2026-10-28 14:19:38 +08:00
Jaw 70f10e741c fix(i18n): Translate the remaining UI text (Git, hierarchy, pull requests, dialogs, aria labels) (#114)
Hard-coded UI text, titles and aria-labels in about 110 components (Git panels, hierarchy, pull requests, dialogs, settings, welcome) now go through tx; spliced fragments became whole sentences (fileCount, noneFoundLabel, hierarchyTitle) and pull request states use keyed messages. 225 zh entries added, stale fragment entries removed.

Also: tx used as a tag without interpolations (tx`No checks`) now looks the text up exactly instead of as a template, so it is translated like tx("No checks"); the text-catalog test checks such tags as plain literals. Check and test counts reuse the existing "{count} passed" / "{failed} failing" entries.

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
Co-authored-by: jaw52 <53564781+jaw52@users.noreply.github.com>
2026-10-28 12:18:46 +08:00
l0ng-ai 357b728f1d Editor: quick fixes, completion, navigation while typing, and split-pane drag (#109)
* feat(editor): Drag tabs and files between split panes

HTML5 drag and drop never reaches the webview while native file drop is
enabled, so tab, project-file and changelist drags did nothing. They now
run on pointer events:

- Drag an editor tab onto another pane, or onto a pane's edge to split it.
- Drag files from the Project view into an editor pane (center opens them
  there, an edge opens them in a new split).
- Drag files between changelists in the Commit view.
- "Drag-and-drop with Alt pressed only" applies to tabs and stripe buttons.

* fix(lsp): Deliver server settings and start servers on a supported JDK

- workspace/configuration answers a server's own section (basedpyright)
  from its settings block; basedpyright runs in "standard" mode and keeps
  auto search paths on, so `src/` layouts resolve from `tests/`.
- jdtls: formatting follows the editor indent, calls complete without
  guessed arguments, and JDK internals stay out of completion.
- `max-java` in a language server config picks an installed JDK no newer
  than that (kotlin-language-server fails on JDK 25).
- Server initialization may take up to 5 minutes (first Gradle import).
- `lsp_resend_diagnostics` re-emits stored diagnostics after a reload.
- Spelling only checks declared names (not called methods like
  `substring`) and accepts plurals of known software terms.

* feat(editor): Quick fixes, completion and navigation while typing

Quick fixes
- Errors get a red quick-fix bulb; Apply Quick Fix (⌥⇧↵) fixes the most
  severe problem at the caret, and the error hover offers the fix directly.
- Code generated by a code action is re-indented to the file's style.
- Python: Implement abstract methods (⌃I or the bulb) from the bases.
- Duplicate code actions are listed once.

Completion
- Overloads sharing a name, and a name importable from several modules,
  are no longer merged into one entry.
- Auto-import entries show the module they import from.
- Call snippets without a stop (`new ArrayList<>()`) leave the caret inside
  the parentheses with parameter info, or past them when nothing takes
  arguments; parameter info also opens after server call snippets.
- The selected item is resolved ahead of acceptance, so its auto-import
  is applied (rust-analyzer).

Navigation and diagnostics
- Language server requests wait for pending edits, so Go to Declaration
  right after typing answers for the current text; an empty answer right
  after an edit is retried while the server catches up.
- Diagnostics come back after a window reload; error underlines stay
  visible under typo / unused highlighting.
- Implementation gutter markers no longer refresh in a loop while the
  server reports progress.
- A missing alternative server no longer shows as a server error.

* chore(lint): Skip agent worktrees under .claude

* fix(editor): Skip cancelled LSP requests and limit generated-code reformat

- Requests cancelled while waiting for pending edits are not sent.
- Code generated by an action is reformatted per changed hunk, so an added
  import doesn't reformat the code between it and the generated lines.
- A long busy spell caused by a settle refresh re-runs it only once.
- Files dropped on a file row of another changelist move to that changelist.
- Python Implement methods: a nested class without bases ends the lookup,
  class bodies continue through unindented string lines, and
  `@abstractproperty` stubs become `@property`.
- Resend diagnostics goes through the host ops, and custom servers get
  `max_java`.

* fix(editor): Rank the exact type first in Java constructor completion

jdtls appends the call or body to filterText (`String(${0})`); matching
on the label instead lets typing `String` rank `String` above
`StringBuilder` and the other types sharing its sort text.

* fix(editor): List identical completion items once

kotlin-language-server repeats a class once per classpath entry declaring
it, so `String()` and `String` were listed three times each.

* fix(editor): Keep the internal cancellation message out of the UI text catalog
2026-10-28 09:07:50 +08:00
l0ng-ai 2fe6b7b87b feat(editor): Implemented / overridden gutter markers (#106)
Adds gutter markers for type hierarchies: ↓ "Is implemented / Has subclasses / Is overridden" on types and methods with implementations, ↑ "Implements / Overrides method in X" on methods that implement or override a supertype method. One target navigates, several open the Choose Implementation popup. Settings › Editor › General › Gutter Icons gets two toggles.

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

Fixes #99

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 21:02:54 +08:00
l0ng-ai 14f72fc307 feat(http-client): Generate requests from Spring Web mappings (#104)
Spring MVC/WebFlux mapping methods (Java and Kotlin) in @RestController / @Controller classes get a gutter icon with "Generate Request in HTTP Client", and the class line gets "Generate Requests for Controller"; both are also actions (`http.generateSpringRequest`, `http.generateSpringControllerRequests`) in Find Action, the editor menu and ⌥↵. Requests are appended to the `generated-requests.http` scratch and opened at the new request.

The URL combines class and method paths ({id} and {id:regex} → {{id}}), with host, port and context path from application.properties / .yml (default http://localhost:8080). @RequestParam, @RequestHeader, params/headers, consumes/produces and @RequestBody (JSON skeleton from the body type, nested one level) are mapped; same-file constants are resolved. Adds an `intentionProviders` editor facet so features can contribute ⌥↵ items.

Fixes #100

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 20:54:48 +08:00
l0ng-ai 8568ff001b fix(i18n): Translate interpolated UI text through a tx template tag (#98)
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
2026-10-27 18:56:54 +08:00
Walter WangandClaude 3b608355a3 feat(themes): Built-in Solarized and One light/dark themes (#85)
Adds Solarized Light, Solarized Dark, One Light and One Dark as built-in themes across the workbench, editor, terminal and Mermaid, keeping the original palettes (MIT notices in THIRD_PARTY_LICENSES.md, mapping in docs/themes.md).

- Native window colours are read from tokens.css at build time (`theme_frame.rs`) instead of a second colour table.
- Startup restores the built-in palette before first paint.
- Editor schemes, the terminal and Mermaid refresh on switches between themes of the same kind.
- The plugin packages of the same themes are removed.
- A test requires every built-in palette theme to define each token (only listed ones may inherit from the base theme), so new tokens can't silently miss them.

Co-authored-by: Claude <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 18:53:12 +08:00
l0ng-aiandbghtyu 24330192c0 feat(themes): Solarized and One theme plugins (#92)
Solarized Light/Dark and One Light/Dark ship as theme plugins (plugins/theme-solarized, plugins/theme-one) with complete UI tokens, editor schemes and terminal colours, and the original palettes' MIT notices. Installing a plugin now also copies its LICENSE/NOTICE/COPYING.

Theme handling that benefits every plugin theme:
- The last plugin theme is restored before first paint (splash, workbench); the native window background follows the theme.
- HSL / color-mix() / var() colours are resolved to RGB for native windows, the Settings window and Mermaid.
- Mermaid, the terminal and editor schemes follow switches between two themes of the same kind.
- An explicitly chosen editor scheme wins over a plugin theme's editor colours.

Supersedes #85.

Co-authored-by: bghtyu <3931591+bghtyu@users.noreply.github.com>
Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 17:53:07 +08:00
l0ng-ai 8ec35c94ec fix(lsp): Find usages in unopened files outside the language server's scope (#89)
Reference-based features only asked the language server, which analyses its configured scope (e.g. Pyright's `include`) plus open files, so usages in unopened files outside that scope were silently missing.

Find Usages, Show Usages, usage counts, Safe Delete of a symbol, Rename and incoming calls now also search project files that contain the symbol's name (whole word, same language, .gitignore/excludes respected, unsaved edits included, up to 300 files, cancellable). Candidates the first answer didn't cover are opened in the server temporarily, queried and closed again. Files the user has open are never touched, and diagnostics for the temporary files are dropped. An empty result while the server is still indexing is retried once indexing ends. When results may still be incomplete (indexing, file cap), the usages UI says so. `lsp_references` takes a RequestId and is cancelled by newer searches. Not covered yet: the Safe Delete scan when deleting a file or directory.

Fixes #83

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