Графік комітів
35 Коміти
Автор SHA1 Повідомлення Дата
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 WangтаClaude 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 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 18:53:12 +08:00
l0ng-aiтаbghtyu 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 <[email protected]>
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
胡翀таzzxzz12345 413564efcf feat(editor): Increase / Decrease Font Size, followed by the Markdown preview (#81)
Adds Increase Font Size / Decrease Font Size (⌥⇧. / ⌥⇧, in the IntelliJ keymaps) for the active editor, sharing the ±1px step and limits with ⌘/Ctrl + mouse wheel. The Markdown preview, including code blocks, follows its editor's zoom, and Reset Font Size in All Editors resets it too.

Editor zoom had no effect once a font size was configured in settings: the configured size was applied with higher precedence than the zoom. The zoom now wins.

Co-authored-by: zzxzz12345 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 16:52:25 +08:00
胡翀таzzxzz12345 fdd98fbfe4 feat(editor): Navigate inferred type inlay hints (#77)
Some language servers (basedpyright) send inferred type hints as plain text without a label-part location, so ⌘/Ctrl-clicking `: Series` did nothing. For a type hint right after an identifier, ⌘/Ctrl-click now goes to that identifier's type declaration; hints with locations keep direct navigation. Navigable hints show the link underline and pointer only while ⌘/Ctrl is held, including when it is pressed before hovering.

Co-authored-by: zzxzz12345 <[email protected]>
Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 16:10:19 +08:00
l0ng-ai 2eaa6cb0c7 feat(agents): Dispatch and supervise coding agents over ACP (#72)
## What

An Agents feature: hand a task to a coding agent and follow it from the IDE. Agents speak the [Agent Client Protocol](https://agentclientprotocol.com). Built in: Claude Code, Codex, Gemini CLI, GitHub Copilot, Cursor, OpenCode, Qwen Code, Kimi CLI, Goose, Auggie, Kiro, Mistral Vibe. You can add your own in `<config>/agents/<id>.toml` (`name`, `command`, `args`, `[env]`). An agent whose command isn't on `PATH` is listed under "Not installed".

- **New Task page.** An editor page with a prompt box. You pick the agent, model, mode and thinking effort, and whether it runs in a new worktree (from a chosen branch) or in the checkout.
- **Agents tool window.** Tasks are grouped by what they need: Needs Input, Failed, Running, Ready to Review, Archived. It also shows a stripe badge, a status bar item and notifications.
- **Session tab.**
  - The conversation: Markdown, thinking, tool calls with diff stats, the plan.
  - Permission requests appear as an editor banner.
  - The changed files are compared against the task's base commit and open in the diff viewer.
  - A context-usage meter.
- **Composer.**
  - `@` references files from the project index. A referenced file's text is sent when the agent accepts embedded context, otherwise a `resource_link`.
  - `/` lists the agent's commands; ↑/↓ recall earlier messages.
  - Images can be pasted, dropped or picked; Shift+Tab cycles the mode.
  - While the agent works, Enter queues the message and ⌘↵ interrupts the turn and sends it now. Queued messages can be sent now, edited or removed.
- **Send to Agent.** In the editor and Project view context menus. It adds `@file:10-20` references to the message you typed last.
- Landing the work is left to the existing Git features: the worktree is a normal branch.

## How

- **`crates/ide-agent`**: one ACP agent process per task, running in the task's directory.
  - It folds `session/update` into a timeline and answers `session/request_permission`.
  - It tracks the session's settings: `configOptions`, falling back to the older `modes` / `models` fields. The user's choices are applied again on every new or reloaded session.
  - Tasks are saved as JSON per task. Sessions resume with `session/load` without duplicating history, and old task files are upgraded when read.
- **`ide-jsonrpc`**: adds newline-delimited framing (ACP) next to Content-Length (LSP).
- **`ide-vcs`**: adds `numstat_with_worktree` for the changes list.
- **Editor**:
  - The Switcher (⌃⇥) lists every open editor, as IDEA does, not just files.
  - `EditorKindContribution.restorable` lets a kind's tabs be saved with the editor session, so agent tabs survive reloads.
- **UI**: `Select` popups now size to fit short option details (they used to cut them off).

## Testing

- `cargo test -p ide-agent` (14 tests). They use an in-memory ACP agent and cover permissions, restart with `session/load`, settings, the queue with send-now and stop, and prompt blocks.
- There is also an ignored end-to-end test against the real Claude Code adapter: `OPENIDEA_AGENT_E2E=1 cargo test -p ide-agent real_claude -- --ignored`.
- `pnpm vitest run`: 2052 tests.
- `cargo clippy -p ide-agent -p openidea --all-targets -- -D warnings` and typecheck are clean.
- Driven in the running app with Claude Code:
  - A task in a worktree, with permission answers, changes listed and the diff opened.
  - A follow-up after restarting the IDE.
  - `@` reference with embedded content, `/` commands, Shift+Tab mode changes.
  - A queued message and send-now, an image prompt, Send to Agent from a selection.
  - The Switcher and restored tabs after a reload.

Not covered yet: only Claude Code was driven end to end. The other agents go through the same ACP path but weren't run here.


Merged on the maintainer's go-ahead. Merge with main: kept both sides in Cargo.toml (ide-agent + ide-clipboard), the feature registry (agents + vim) and zh.json (no duplicate keys). After the merge: typecheck clean, full vitest 268 files / 2247 tests passed, ide-agent/ide-jsonrpc/ide-vcs 144 passed, bindings unchanged after regeneration.
2026-10-27 14:44:28 +08:00
胡翀 566b4fdeb1 Make static symbol italics configurable (#70)
Python language servers mark class attributes `static`, so their declarations and `self.` references rendered italic, unlike PyCharm. Adds Color Scheme attributes for static symbols: Language Defaults › Identifiers › Static symbol (italic by default, as IDEA's static members) and Python › Static symbol (upright by default), applied to semantic tokens with the `static` modifier.

Verified in the app with basedpyright: a class attribute renders upright by default and italic when Python › Static symbol › Italic is on, applied live. Maintainer follow-up: formatted colorScheme.tsx.

https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 14:27:24 +08:00
l0ng-ai 12418e0184 fix(editor): Show the ⌘/Ctrl-hover link without waiting for documentation (#71)
## Problem
When you hold ⌘ (Ctrl on Windows/Linux) and hover a symbol, the navigation link had three problems:
- **Slow to appear.** The underline and pointer cursor only showed after the hover (documentation) request came back. A slow or stuck documentation request held the link back.
- **Errors were remembered.** If the definition request was cancelled or the server returned an error, the word was cached as having no target. Hovering it again never retried.
- **Stuck requests blocked the word.** A definition request that never answered blocked any new request for that word.

## Changes (`src/editor/lsp/navigation.ts`)
- The link is underlined as soon as a definition is found. The short summary is filled in when the hover request returns.
- Cancellation and server errors count as temporary failures. They are no longer cached, so the next hover retries.
- A definition request expires after 3 seconds and can be retried. If its response arrives later, it is ignored.
- Responses for a word the pointer has already left, or that arrive after the editor plugin is destroyed, are dropped.

## Tests
- Four new tests in `src/editor/lsp/syntaxFallback.test.ts`: the link shows without waiting for documentation, a temporary error is retried, a stuck request is retried and its late answer ignored, and a late answer for the previous word is ignored. The first three fail without this change.
- `pnpm vitest run src/editor/lsp`: 179 passed. `pnpm typecheck` and eslint report no errors.
- Checked in the running app (`fixtures/ts-app`, `cart.ts`): ⌘-hover over `Cents` showed the underline and pointer cursor after 312 ms and the type summary after 356 ms. ⌘-click opened `money.ts` at the definition.
2026-10-27 14:23:23 +08:00
l0ng-ai beab7992f9 feat(editor): Rainbow brackets and semantic highlighting (rainbow variables) (#59)
Two editor toggles under Settings › Editor › Color Scheme › Language Defaults (off by default, also actions `editor.toggleRainbowBrackets` / `editor.toggleSemanticHighlighting`):
- Semantic highlighting (IDEA's rainbow variables): locals and parameters coloured by a name hash from LSP semantic tokens; fields, statics, constants, library symbols untouched.
- Rainbow brackets (VS Code's bracket pair colorization): (), [], {} by depth, unmatched in the error colour, strings/comments skipped, visible ranges only with 4 KB checkpoints.
Palettes are theme tokens (`--syn-rainbow-1..5`, `--syn-bracket-1..3`, light/dark/high-contrast), editable in the Color Scheme tree, and mapped from IntelliJ `.icls` RAINBOW_COLOR1..5.

App verification on macOS found the colours were overridden by the syntax highlighter's span nested inside the marks; the rules now cover descendants. Verified both toggles on/off live in a TS file.

Fixes #56

https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 11:52:07 +08:00
l0ng-ai e16253a890 fix(editor): Ctrl/⌘-hover info replaces hover popups instead of stacking (#60)
Root cause: the quick-doc/problem hover and the Ctrl/⌘-hover navigation info were independent tooltips with no precedence, and the navigation modifier was only seen through the focused editor's key events, so holding Ctrl stacked both popups.

Fix: a window-wide platform navigation modifier (`src/platform/navigationModifier.ts`, ⌘ on macOS / Ctrl elsewhere, unchorded); with it held the plain hover doesn't open, late LSP results are dropped, an open hover closes (unless the pointer is inside it, so Ctrl/⌘+C still copies), release clears the link and info.

Siblings: problem/diagnostic hover, debugger value tooltip, inlay hint hovers (no doc or underline through hints, platform-correct Ctrl/⌘-click), consistent ⌘ vs ⌃ handling on macOS.

Verified in the app on macOS (⌘): hover then ⌘ leaves only the nav info, ⌘ before hover shows only nav info, release clears both and plain hover returns. Not verified on Windows.

Fixes #57

https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 11:46:04 +08:00
l0ng-ai 7146779f6c feat(vim): Built-in Vim mode modelled on IdeaVim (#55)
Built-in Vim emulation on @replit/codemirror-vim (approved dependency), modelled on IdeaVim: `vim.toggle` (Tools › Vim, status widget, Settings › Editor › Vim), mode widget (NORMAL / INSERT / VISUAL / V-LINE / V-BLOCK / REPLACE), IdeaVim-style shortcut conflict handlers (Vim / IDE per key) through a generic `registerKeyClaim()` in the keymap dispatcher, Escape closing popups first, a safe subset of ~/.openideavimrc / ~/.ideavimrc (set, map variants, mapleader, :action / <Action>()), Ex commands :w :wa :q :qa :wq :x :action. Covers file editors, diff editable side and merge result via a new `embeddedEditorExtensions` extension point.

Verified in the app on macOS: motions/operators, i/Esc/V mode widget, :w saves, Ctrl+R redoes in Vim without running Run, toggling off restores plain editing. Not verified on Windows/Linux.

Fixes #27

https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 11:43:37 +08:00
胡翀 55f42d2771 fix(editor): match IDEA font weights in the light scheme (#35)
Root cause: the editor had no font weight settings, and the WebView rendering of JetBrains Mono looks lighter than IDEA (#32).
Fix (IDEA's Settings › Editor › Font › Typography Settings): configurable Main font weight and Bold font weight (defaults Regular 400 / Bold 700) via --fw-code / --fw-code-bold; colour-scheme bold/regular overrides still win; settings preview updates live. Replaces the Light-only 450/550 hard-coding.
Siblings covered: sticky lines, diff/merge, run console (ANSI bold), Find in Files, completion/parameter info/docs, database editor, debugger value popup, matched braces, terminal with "Use editor font".
Verified: scoped vitest, ide-core tests, in-app on macOS (settings UI, editor weight follows the setting end to end).

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 10:41:56 +08:00
l0ng-ai aa5821bb46 fix(spelling): Rename identifiers on Typo fixes, add inspection controls, cut false positives (#51)
Root causes: Typo "Change to" replaced one occurrence even for declared names (breaking references); inspections had no Disable / Edit settings controls anywhere; en_US Hunspell does not derive agent nouns like "checkpointer" and compound identifier words were flagged; local inspections (Typo, file references, SQL) never reached Problems.
Fix (IDEA): "Typo: Rename to…" renames via LSP rename, falling back to syntax-based local rename, never a silent single replace, and lists identifier-safe words only; intention submenu (→) with Edit inspection profile setting / Disable inspection for every inspection; Problems and Inspection Results get Disable Inspection, Change Severity, Edit Inspection Profile Setting; Typo options Process code / literals / comments; -er/-ers derivation and identifier compounds accepted, common misspellings still flagged.
Siblings covered: all LSP and built-in inspections' intentions, file reference and SQL inspections in Problems, severity counter.
Verified: ide-spell tests (issue examples + ~50 real misspellings), vitest (286), in-app on macOS: only 'mesage' flagged, submenu, Rename to → 'message' updated both occurrences.

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 10:38:53 +08:00
l0ng-ai b4a3e866c6 fix(terminal): render the terminal in the bundled JetBrains Mono (#44)
Root cause: the terminal built its own font-family ("JetBrains Mono", Nerd Fonts, monospace) without the bundled "JetBrains Mono Variable", so on Windows (no JetBrains Mono installed) xterm fell back to the system monospace (SimSun on Chinese Windows); xterm also measured cells before the webfont loaded.
Fix: one resolver (src/platform/fonts.ts monoFontFamily) maps JetBrains Mono to the bundled face; xterm re-measures once fonts load; "Use editor font" also takes the editor's fallback font (IDEA).
Siblings covered: embedded run terminal, editor default family + fallback, Settings › Editor › Font preview.
Verified in-app on macOS (terminal renders JetBrains Mono Variable). Not verified on Windows.

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 10:38:18 +08:00
l0ng-ai 5670c2e8dd test: stub Range layout methods once in the test setup (#53)
Root cause: jsdom has no layout and CodeMirror measures text ranges in an animation frame, sometimes after a test finished; test files that did not stub Range.getClientRects (e.g. search/codePreview) threw an unhandled TypeError that failed whole CI runs at random (seen on #41).
Fix: stub Range.getClientRects / getBoundingClientRect once in src/test/setup.ts; drop the six per-file copies.
Verified: vitest on editor/lsp, editor/refactor, templates, search (55 files, 458 tests, no unhandled errors).

Claude-Session: https://claude.ai/code/session_01VUYsdXA2nkF5v6zsC93dpn
2026-10-27 10:38:11 +08:00
l0ng-ai de84a643aa fix(ui): Make read-only content selectable with a Copy context menu (#48)
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
2026-10-27 08:56:13 +08:00
l0ng-ai 1e00ea5ee2 feat: Third pass aligning core experience with IntelliJ IDEA
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
2026-10-25 21:24:00 +08:00
l0ng-ai 82b6980a59 feat: Second pass aligning interactions with IntelliJ IDEA (#23)
* 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.
2026-10-25 09:44:46 +08:00
l0ng-ai 81e0e8e2d0 feat: Align interactions with IntelliJ IDEA (#22)
* feat(nav): Complete file paths and flag unresolved web file references

Path completion in href/src/url()/@import, Markdown links and path-like strings, folders first. HTML and CSS paths that name no file get a 'Cannot resolve file' warning. File references resolve in the backend like IDEA's: relative to the file, /-rooted against the project and resource roots.

* feat: Align editor, workbench, run/debug and VCS interactions with IntelliJ IDEA

Keymap
- Let AltGr characters through instead of firing Ctrl+Alt shortcuts (Windows/Linux)
- Double Shift: strict press/release timing, ignored while typing or after Shift+click
- Chords wait 2s and swallow an unmatched second stroke
- Drop CodeMirror defaults that clash with IDEA keys; ⌘Enter is Split Line, add
  Scroll to Center and Code Block Start/End
- Add missing IDEA defaults (⌃J, ⌘Y, ⇧⌘C, ⌥⌘Y, ⇧⌘M, F9 Resume, ⌘R Rerun, …)

Editor
- Tab inserts at the caret; smart Backspace to the proper indent; Enter continues
  a `//` comment; per-language line comment placement
- Back/Forward records navigations only; ⌘F searches the selected text
- In-place rename; ⌃Space inserts a sole candidate; commit characters only for a
  focused lookup; usage highlighting survives edits; ⌥Enter offers fixes from the
  caret line; ⌘-hover shows declaration info only for navigable targets

Workbench
- Tool windows: primary and split area per side, six Move To anchors, layout migration
- ⌘W closes tool window content; Shift+Esc from the editor; closing a tab
  activates the left neighbour; preview tab and tab limit follow IDEA defaults
- Switcher lists open editors and tool windows; Recent Files Delete removes items
- Search Everywhere tab/scope behaviour; popups close when the window deactivates
- Project view: Copy/Move dialogs on paste, skippable usage search on delete,
  new-file input cancels on blur; Settings search Esc clears the filter
- Status bar breadcrumbs open a children popup; notification timeouts

Run / Debug / Build / Terminal
- Run asks to stop a running single-instance config; Rerun restarts silently;
  "Allow multiple instances" option
- Run chooser: Enter runs, Shift debugs, F4/Delete/digits
- Type into the console for stdin; Stop covers debug sessions
- Log (Shift+click) and temporary (Alt+click) breakpoints; independent suspend/log
  options; Evaluate prefill and history; changed-value highlighting; expandable hints
- Build window opens on failure and jumps to the first error
- Terminal confirms closing a busy tab and lets IDE shortcuts through

VCS
- Correct ours/theirs labels during rebase, cherry-pick and revert
- Smart/Force Checkout; remote branch checkout updates the local branch
- Partial commit by changed block; inline before-commit check results
- F7 continues into the next file; Rollback Lines; Commit and Push; Amend message swap
- Branch delete with Restore; force push confirmation; editable push target;
  update summary with the incoming commits

* chore: Regenerate bindings
2026-10-25 09:34:02 +08:00
l0ng-ai 87b463990c feat(nav): Follow links, file paths and CSS references with Go to Declaration
Go to Declaration and Cmd-click said "Cannot find declaration" on HTML href/src, CSS url() and @import, Markdown links and CSS selectors: language servers expose paths as document links, not definitions, and none resolves class/id to selectors.

- ide-lsp: textDocument/documentLink (lsp_document_links), resolving links that lack a target.
- Editor: when the server has no definition, follow its document links, then URLs and quoted / Markdown / url() paths in any language. Server file links are checked to exist; root-relative paths also resolve against resource roots. Cmd-hover underlines the whole link.
- ide-language: tree-sitter web references (class / id attributes, href="#id", var(--x)) and .class / #id / --var definitions from stylesheets and <style> elements, indexed as symbols. web_goto looks them up by exact name (ProjectIndex::symbols_named), using the open document's unsaved text.
- Detect public/ of package.json modules as a resource root (Vite, Next, CRA serve it at /).
2026-10-24 22:58:23 +08:00
l0ng-ai 046fd37064 fix(ui): Match PyCharm project view, matched tags and text weight
- Project widget initials follow IDEA's AvatarUtils.initials ("idea" → "I").
- "Show directories with changed descendants" is off by default, as in IDEA.
- FileEntry gains `excluded`: only excluded folders get the excluded icon and
  dimming; git-ignored ones keep the plain icon and the ignored colour.
- `.github` folders get IDEA's GitHub folder icon.
- Matched tag names are never bold and use their own background
  (MATCHED_TAG_NAME); matched braces are bold in dark schemes only.
- Revert Greyscale antialiasing to `antialiased` for UI and editor; `auto`
  rendered text heavier than PyCharm.

Claude-Session: https://claude.ai/code/session_01SaPPsVPuk6ZTNsoUCNCbMv
2026-10-24 22:56:48 +08:00
l0ng-ai cacddee19d feat(web): Open HTML in browsers with a built-in server; add Emmet
- ide-web: built-in static server on 127.0.0.1 that serves project files,
  plus detection and launching of installed browsers.
- Open In › Browser in the editor, project view and tab menus; browser bar
  and built-in preview beside HTML editors; ⌃⇧R opens the default browser.
- Emmet: Tab expansion in markup editors and Update Tag with Emmet.

Claude-Session: https://claude.ai/code/session_01SaPPsVPuk6ZTNsoUCNCbMv
2026-10-24 22:16:28 +08:00
l0ng-ai c8cea62eab fix(editor): Match PyCharm syntax colours and text weight
Greyscale antialiasing mapped to `-webkit-font-smoothing: antialiased`,
which drops macOS stem darkening, so editor and UI text rendered thinner
and syntax colours looked lighter than PyCharm's. Use `auto` instead.

Align lezer tag mappings with PyCharm's Light scheme:
- HTML/XML: `<!doctype>` is plain text (documentMeta is a sub-tag of meta).
- CSS/SCSS/Sass: property names use the attribute colour; values and units
  the attribute-value colour; class, id, pseudo, colour and url() the tag colour.
- YAML: keys are keywords.
- Markdown: quotes are strings with keyword markers, link destinations
  italic function colour, titles strings, horizontal rules keywords.

Claude-Session: https://claude.ai/code/session_01SaPPsVPuk6ZTNsoUCNCbMv
2026-10-24 22:16:16 +08:00
l0ng-ai 0bb730039d feat(search): Bring Search Everywhere closer to IDEA's popup
- All tab interleaves classes, files, symbols, actions and text by match
  degree, keeping each source's own order; Enter waits for every source
  except a text search the top row already beats.
- Preview pane under the list (remembered toggle), reusing CodePreview.
- "/" lists scope commands; "/files q" switches scope and searches q.
- Per-tab search history: magnifier dropdown and ⌥↑ / ⌥↓.
- Text hits: syntax colouring, IDEA's boxed-T icon, dimmed repeated file
  names, collapsed indentation.
- Flat scope chooser, IDEA header icons, wider popup with a stable list
  height; the list shrinks so the footer stays visible.
2026-10-24 14:47:45 +08:00
l0ng-ai be5a6f62ad feat(editor): JetBrains-style line-number gutter context menu
Right-click on the gutter now shows Annotate with Git Blame, Add/Remove
Bookmark, Soft-Wrap, Configure Soft Wraps, an Appearance submenu and
Configure Gutter Icons, contributed through a new "editorGutter" menu
group. A breakpoint line still opens the breakpoint popover.
2026-10-24 11:38:08 +08:00
l0ng-ai 1572fc36ea feat(editor): Highlight languages without a CodeMirror mode from tree-sitter
Elixir files opened as plain text: highlighting only came from
@codemirror/language-data, which has no Elixir mode. Grammars now carry
their own highlights.scm; `doc_highlights` folds its captures into a small
kind vocabulary (inner nodes and later patterns win, interpolation clears
the string colour), memoised per document version on the incremental
tree. The editor maps kinds onto Lezer tags, so colours follow the active
scheme, and requests them only when no CodeMirror mode exists.

Enabled for Elixir; other grammar-only languages need their query wired.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-24 11:26:31 +08:00
l0ng-ai c59f93988b feat(vcs): PyCharm-style Commit view and one shared message dialog
- workbench/messages: one promise-based ask/confirm/confirmChecked/showError
  host replaces the per-feature confirm dialogs (app, services, vcs,
  project tree, keymap, run, database, find, LSP choice popup).
- Commit tool window: Commit | Shelf | Stash tabs as the title, IDEA's
  toolbar (Update Project, View Options, Select Opened File), Unversioned
  collapsed, Commit / Commit and Push on one row, empty-message error.
- Commit Options popup: author, sign-off, before-commit checks, Git hooks;
  vcs_commit takes CommitOptions (--author, --no-verify).
- Remove from Recent Projects asks first; refused history rewrites show an
  error dialog.

Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-23 22:59:06 +08:00
l0ng-ai 76d33f0306 feat(ui): IDEA-style message dialogs, project widget popup and Chinese UI text
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
2026-10-23 22:18:50 +08:00
l0ng-ai a66f01ec87 feat(files): Add Ignored Files and Folders setting, honoured everywhere
Name patterns the IDE treats as nonexistent (.DS_Store, __pycache__, *.pyc, VCS dirs, ...) were hard-coded in five places, and Git changes ignored none of them, so .DS_Store showed up as unversioned. files.ignoredNames (IDEA's default list) now drives the project view, navigation bar, index, watcher, Find in Files, inspections and the Git status.
2026-10-23 15:40:41 +08:00
l0ng-ai 5f6e2a9c85 fix(workbench): Reset project state when a window switches projects
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.
2026-10-22 20:26:04 +08:00
l0ng-ai 9a2025b76e Initial open-source release
Claude-Session: https://claude.ai/code/session_01B65qLEKnkeYTGdbwhLpjCu
2026-10-22 18:55:10 +08:00