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
Цей коміт міститься в:
l0ng-ai committed 2026-10-25 21:24:00 +08:00
1 джерело 294198a727
коміт 1e00ea5ee2
426 files changed
+85241 -2886

No files matched your search

+1 -1
Переглянути файл
@@ -4,5 +4,5 @@
* is not usable (see `@/editor/structure`).
*/
export { introduceFallback, type FallbackReason, type IntroduceKind } from "./introduce";
export { refactorThis, runRefactoring } from "./refactorThis";
export { refactorThis, runRefactoring, showNothingHere } from "./refactorThis";
export { askUsagesDetected, fileUsages, safeDelete, viewUsages, type FileUsages, type UsagesAnswer } from "./safeDelete";
+4 -2
Переглянути файл
@@ -188,8 +188,10 @@ describe("Refactor This", () => {
it("says so when nothing applies", async () => {
const v = editor();
await refactorThis(v, vi.fn());
expect(useLspPopup.getState().popup).toBeNull();
expect(showHint).toHaveBeenCalledWith(v, "No refactorings available at the caret");
expect(labels()).toEqual(["Nothing here"]);
const popup = useLspPopup.getState().popup as { items: { disabled?: string | null }[] };
expect(popup.items[0]!.disabled).toBeTruthy();
expect(showHint).not.toHaveBeenCalled();
});
it("cancels a superseded query and drops answers after the caret moved", async () => {
+11 -1
Переглянути файл
@@ -261,8 +261,18 @@ export async function refactorThis(view: EditorView, rename: (view: EditorView)
// Superseded, or the caret moved / the text changed meanwhile: the answer is stale.
if (run.signal.aborted || view.state.doc !== state.doc || !view.state.selection.eq(state.selection)) return;
if (!items.length) {
showHint(view, "No refactorings available at the caret");
showNothingHere(caretAnchor(view, state.selection.main.head));
return;
}
openPopup({ kind: "list", anchor: caretAnchor(view, state.selection.main.head), title: "Refactor This", items, numbered: true });
}
/** IDEA's "Nothing here" popup: Refactor This where no refactoring applies (or outside an editor). */
export function showNothingHere(anchor: { x: number; y: number } = { x: window.innerWidth / 2, y: window.innerHeight / 3 }) {
openPopup({
kind: "list",
anchor,
title: "Refactor This",
items: [{ id: "nothing", label: "Nothing here", disabled: "No refactoring applies here", run: () => {} }],
});
}