From 8ebf839d8e7360db8204df9364a150eb107495a0 Mon Sep 17 00:00:00 2001 From: Jaw <53564781+jaw52@users.noreply.github.com> Date: Sat, 7 Nov 2026 11:12:50 +0800 Subject: [PATCH] feat(project): rename Autoscroll from Source to Always Select Opened File (#1694) Following the active editor already worked, but the option kept IDEA's pre-2023 name and sat second under Behavior, so people didn't find it (#1666). It is now Always Select Opened File, listed first, and the header's Select Opened File button hides while it's on. Find Action still matches the old name; the setting key is unchanged. Closes #1666 Co-authored-by: jaw52 <53564781+jaw52@users.noreply.github.com> --- src/features/project-tree/HeaderActions.tsx | 20 ++++++----- .../project-tree/ProjectView.test.tsx | 35 ++++++++++++++++++- src/features/project-tree/actions.ts | 3 +- src/features/project-tree/store.ts | 2 +- src/platform/locales/text/es.json | 1 + src/platform/locales/text/fr.json | 1 + src/platform/locales/text/ko.json | 1 + src/platform/locales/text/pl.json | 1 + src/platform/locales/text/pt.json | 1 + src/platform/locales/text/zh.json | 1 + 10 files changed, 55 insertions(+), 11 deletions(-) diff --git a/src/features/project-tree/HeaderActions.tsx b/src/features/project-tree/HeaderActions.tsx index 4c979fc0..a7296361 100644 --- a/src/features/project-tree/HeaderActions.tsx +++ b/src/features/project-tree/HeaderActions.tsx @@ -29,8 +29,8 @@ export const OPTION_LABELS: Array<[ToggleOption, string]> = [ ["showMembers", "Show Members"], ["compact", "Compact Middle Packages"], ["foldersFirst", "Sort Folders First"], + ["autoscrollFromSource", "Always Select Opened File"], ["autoscrollToSource", "Autoscroll to Source"], - ["autoscrollFromSource", "Autoscroll from Source"], ["singleClickOpen", "Open Files with Single Click"], ["singleClickExpand", "Expand Directories with Single Click"], ["previewTab", "Enable Preview Tab"], @@ -38,15 +38,19 @@ export const OPTION_LABELS: Array<[ToggleOption, string]> = [ /** Header controls of the Project tool window (IDEA: Locate, Expand/Collapse All). */ export function ProjectHeaderActions() { + // IDEA hides Select Opened File while Always Select Opened File keeps the tree in sync. + const alwaysSelect = useProjectTree((s) => s.options.autoscrollFromSource); return ( <> - + {!alwaysSelect && ( + + )} diff --git a/src/features/project-tree/ProjectView.test.tsx b/src/features/project-tree/ProjectView.test.tsx index 2e588057..1822a795 100644 --- a/src/features/project-tree/ProjectView.test.tsx +++ b/src/features/project-tree/ProjectView.test.tsx @@ -14,7 +14,8 @@ import { ProjectView } from "./ProjectView"; import { beginNew, canPaste } from "./operations"; import { initProjectTree, setViewOption, useProjectTree } from "./store"; import type { OutlineItem } from "@/bindings"; -import { _emitEditorEvent } from "@/editor/api"; +import { _emitEditorEvent, useEditorRegistry } from "@/editor/api"; +import { ProjectHeaderActions } from "./HeaderActions"; import { loadOutline } from "./store"; const ipc = vi.hoisted(() => ({ @@ -220,6 +221,38 @@ describe("ProjectView", () => { act(() => setViewOption("previewTab", false)); }); + it("follows tab switches with Always Select Opened File, hiding Select Opened File", async () => { + const focusEditor = (path: string) => act(() => useEditorRegistry.setState({ active: { ctx: { path } } } as never)); + const selected = () => + screen + .getAllByRole("treeitem") + .filter((r) => r.getAttribute("aria-selected") === "true") + .map((r) => r.textContent); + try { + render(); + const { rows } = setup(); + await waitFor(() => expect(rows()).toContain("README.md")); + expect(screen.getByRole("button", { name: "Select Opened File" })).toBeTruthy(); + focusEditor("/w/acme/src/Util.kt"); + expect(rows()).not.toContain("Util.kt"); + + act(() => setViewOption("autoscrollFromSource", true)); + await waitFor(() => expect(selected()).toEqual(["Util.kt"])); + expect(screen.queryByRole("button", { name: "Select Opened File" })).toBeNull(); + focusEditor("/w/acme/README.md"); + await waitFor(() => expect(selected()).toEqual(["README.md"])); + focusEditor("/w/acme/src/App.kt"); + await waitFor(() => expect(selected()).toEqual(["App.kt"])); + + act(() => setViewOption("autoscrollFromSource", false)); + focusEditor("/w/acme/README.md"); + expect(selected()).toEqual(["App.kt"]); + expect(screen.getByRole("button", { name: "Select Opened File" })).toBeTruthy(); + } finally { + act(() => useEditorRegistry.setState({ active: null })); + } + }); + it("expands and collapses folders on single click only when enabled", async () => { const { row, rows } = setup(); await waitFor(() => expect(rows()).toContain("README.md")); diff --git a/src/features/project-tree/actions.ts b/src/features/project-tree/actions.ts index 5e02d211..77f604b6 100644 --- a/src/features/project-tree/actions.ts +++ b/src/features/project-tree/actions.ts @@ -166,7 +166,8 @@ export function registerProjectActions(): () => void { id: `project.option.${key}`, title: tx`Project View: ${label}`, category: "View", - keywords: ["project", "tree", "toggle"], + // IDEA's former name of Always Select Opened File. + keywords: ["project", "tree", "toggle", ...(key === "autoscrollFromSource" ? ["autoscroll from source"] : [])], toggled: () => useProjectTree.getState().options[key], run: () => setViewOption(key, !useProjectTree.getState().options[key]), })); diff --git a/src/features/project-tree/store.ts b/src/features/project-tree/store.ts index 3b51e349..8619341c 100644 --- a/src/features/project-tree/store.ts +++ b/src/features/project-tree/store.ts @@ -38,7 +38,7 @@ import { projectViewRoots, useProjectViewRoots, type ProjectViewRootContribution import { ancestorsWithin, isSameOrInside, nameOf, type PackageKind } from "./paths"; export interface ViewOptions extends TreeOptions { - /** Select the active editor's file in the tree. */ + /** Select the active editor's file in the tree (IDEA: Always Select Opened File). */ autoscrollFromSource: boolean; /** Open the selected file while navigating the tree (preview, no focus change). */ autoscrollToSource: boolean; diff --git a/src/platform/locales/text/es.json b/src/platform/locales/text/es.json index 442e2260..ec1d5d60 100644 --- a/src/platform/locales/text/es.json +++ b/src/platform/locales/text/es.json @@ -227,6 +227,7 @@ "Allow placing breakpoints in any file": "Permitir colocar puntos de interrupción en cualquier archivo", "Also expand in comments and strings": "Expandir también en comentarios y cadenas", "Always": "Siempre", + "Always Select Opened File": "Seleccionar siempre el archivo abierto", "Always show full path in window header": "Mostrar siempre la ruta completa en el encabezado de la ventana", "Amend": "Enmendar", "Analysing…": "Analizando…", diff --git a/src/platform/locales/text/fr.json b/src/platform/locales/text/fr.json index 057fe0ee..fb9398f3 100644 --- a/src/platform/locales/text/fr.json +++ b/src/platform/locales/text/fr.json @@ -175,6 +175,7 @@ "Allow placing breakpoints in any file": "Autoriser les points d'arrêt dans n'importe quel fichier", "Also expand in comments and strings": "Développer aussi dans les commentaires et les chaînes", "Always": "Toujours", + "Always Select Opened File": "Toujours sélectionner le fichier ouvert", "Always show full path in window header": "Toujours afficher le chemin complet dans l'en-tête de la fenêtre", "Amend": "Amender", "Analysing…": "Analyse…", diff --git a/src/platform/locales/text/ko.json b/src/platform/locales/text/ko.json index 89da00ab..847280f0 100644 --- a/src/platform/locales/text/ko.json +++ b/src/platform/locales/text/ko.json @@ -267,6 +267,7 @@ "Allow placing breakpoints in any file": "모든 파일에 중단점 설정 허용", "Also expand in comments and strings": "주석과 문자열에서도 확장", "Always": "항상", + "Always Select Opened File": "항상 열린 파일 선택", "Always show full path in window header": "항상 창 헤더에 전체 경로 표시", "Amend": "수정", "Analysing…": "분석 중…", diff --git a/src/platform/locales/text/pl.json b/src/platform/locales/text/pl.json index ecc1d63e..dff586ba 100644 --- a/src/platform/locales/text/pl.json +++ b/src/platform/locales/text/pl.json @@ -219,6 +219,7 @@ "Allow placing breakpoints in any file": "Zezwalaj na umieszczanie punktów przerwania w dowolnym pliku", "Also expand in comments and strings": "Rozwijaj również w komentarzach i ciągach znaków", "Always": "Zawsze", + "Always Select Opened File": "Zawsze zaznaczaj otwarty plik", "Always show full path in window header": "Zawsze pokazuj pełną ścieżkę w nagłówku okna", "Amend": "Popraw (Amend)", "Analysing…": "Analizowanie…", diff --git a/src/platform/locales/text/pt.json b/src/platform/locales/text/pt.json index 5db18741..81f418cf 100644 --- a/src/platform/locales/text/pt.json +++ b/src/platform/locales/text/pt.json @@ -219,6 +219,7 @@ "Allow placing breakpoints in any file": "Permitir colocar pontos de interrupção em qualquer arquivo", "Also expand in comments and strings": "Também expandir em comentários e strings", "Always": "Sempre", + "Always Select Opened File": "Sempre selecionar o arquivo aberto", "Always show full path in window header": "Sempre mostrar o caminho completo no cabeçalho da janela", "Amend": "Amend", "Analysing…": "Analisando…", diff --git a/src/platform/locales/text/zh.json b/src/platform/locales/text/zh.json index d2de7cb8..663bef61 100644 --- a/src/platform/locales/text/zh.json +++ b/src/platform/locales/text/zh.json @@ -271,6 +271,7 @@ "Allow placing breakpoints in any file": "允许在任意文件中设置断点", "Also expand in comments and strings": "也在注释和字符串中展开", "Always": "始终", + "Always Select Opened File": "始终选择打开的文件", "Always show full path in window header": "始终在窗口标题中显示完整路径", "Amend": "修改", "Analysing…": "正在分析…",