дзеркало
https://github.com/l0ng-ai/openidea.git
синхронізовано 2026-11-09 19:25:54 +02:00
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
Цей коміт міститься в:
1 джерело
2a8e5e791d
коміт
8568ff001b
142 files changed
+1031
-362
No files matched your search
@@ -43,6 +43,7 @@ import {
|
||||
openSmartStepChooser,
|
||||
useOverlays,
|
||||
} from "./ui/popoverStore";
|
||||
import { tx } from "@/platform/i18n";
|
||||
|
||||
function isRunConfig(arg: unknown): arg is RunConfig {
|
||||
return !!arg && typeof arg === "object" && "command" in arg && "args" in arg && "debugAdapter" in arg;
|
||||
@@ -159,7 +160,7 @@ async function listenForJvm(name: string, host: string, port: number): Promise<n
|
||||
key,
|
||||
sticky: true,
|
||||
title: `'${name}': listening for the remote JVM on port ${port}`,
|
||||
body: `Start the remote JVM with -agentlib:jdwp=transport=dt_socket,server=n,address=${host}:${port},suspend=y`,
|
||||
body: tx`Start the remote JVM with -agentlib:jdwp=transport=dt_socket,server=n,address=${host}:${port},suspend=y`,
|
||||
actions: [{ label: "Cancel", run: () => void commands.cancelRequest(request) }],
|
||||
});
|
||||
try {
|
||||
|
||||
@@ -8,6 +8,7 @@
|
||||
import { call, commands, isTauri, type DebugEvent, type DebugSessionId } from "@/platform/ipc";
|
||||
import { maybeEditorService, notifications } from "@/workbench/contributions";
|
||||
import { isLive, useDebug, type DebugSession } from "./state";
|
||||
import { tx } from "@/platform/i18n";
|
||||
|
||||
const KEY = "debug.hotswap";
|
||||
/** `BUILD_COMPLETE` events of our own build are not worth a prompt. */
|
||||
@@ -25,7 +26,7 @@ function plural(n: number, word: string) {
|
||||
export function hotSwapMessage(changed: number, errors: string[]): { level: "info" | "error"; title: string; body?: string } {
|
||||
if (errors.length) return { level: "error", title: "Hot Swap failed", body: errors.join("\n") };
|
||||
if (changed === 0) return { level: "info", title: "Loaded classes are up to date. Nothing to reload." };
|
||||
return { level: "info", title: `${plural(changed, "class")} reloaded` };
|
||||
return { level: "info", title: tx`${plural(changed, "class")} reloaded` };
|
||||
}
|
||||
|
||||
/** Compiles (unless `build` is false) and reloads changed classes into every Java debug session. */
|
||||
|
||||
@@ -5,11 +5,11 @@
|
||||
import { IpcError } from "@/platform/ipc";
|
||||
|
||||
/** Adapters the tools installer can provide (adapter id → tool name). */
|
||||
const INSTALLABLE: Record<string, { tool: string; label: string }> = {
|
||||
debugpy: { tool: "debugpy", label: "debugpy" },
|
||||
"js-debug": { tool: "js-debug", label: "the JavaScript debugger (vscode-js-debug)" },
|
||||
delve: { tool: "delve", label: "Delve" },
|
||||
codelldb: { tool: "codelldb", label: "CodeLLDB" },
|
||||
const INSTALLABLE: Record<string, { tool: string; title: string }> = {
|
||||
debugpy: { tool: "debugpy", title: "debugpy is not installed" },
|
||||
"js-debug": { tool: "js-debug", title: "The JavaScript debugger (vscode-js-debug) is not installed" },
|
||||
delve: { tool: "delve", title: "Delve is not installed" },
|
||||
codelldb: { tool: "codelldb", title: "CodeLLDB is not installed" },
|
||||
};
|
||||
|
||||
export interface MissingAdapter {
|
||||
@@ -25,14 +25,14 @@ export function missingAdapter(adapter: string, e: unknown): MissingAdapter | nu
|
||||
if (adapter === "debugpy" && e.message.startsWith("debugpy is not installed")) {
|
||||
return {
|
||||
tool: entry.tool,
|
||||
title: "debugpy is not installed",
|
||||
title: entry.title,
|
||||
body: `${e.message}. OpenIDEA can install a private copy that every Python interpreter uses for debugging.`,
|
||||
};
|
||||
}
|
||||
if (!e.message.startsWith(`debug adapter \`${adapter}\` not found`)) return null;
|
||||
return {
|
||||
tool: entry.tool,
|
||||
title: `${entry.label[0]!.toUpperCase()}${entry.label.slice(1)} is not installed`,
|
||||
title: entry.title,
|
||||
body: e.message,
|
||||
};
|
||||
}
|
||||
@@ -40,6 +40,7 @@ import {
|
||||
} from "../state";
|
||||
import { VariablesView, type VarRoot } from "./VariablesView";
|
||||
import styles from "./DebugToolWindow.module.css";
|
||||
import { tx } from "@/platform/i18n";
|
||||
|
||||
function useActionEnabled(id: string): boolean {
|
||||
const ctx = useContextKeys();
|
||||
@@ -114,7 +115,7 @@ export function DebugTabs() {
|
||||
if (!list.length) return null;
|
||||
const items: TabItem[] = list.map((s) => ({
|
||||
id: String(s.id),
|
||||
label: s.parent != null ? `${s.name} (child)` : s.name,
|
||||
label: s.parent != null ? tx`${s.name} (child)` : s.name,
|
||||
text: s.name,
|
||||
icon: "debug",
|
||||
italic: s.status === "terminated",
|
||||
|
||||
@@ -34,6 +34,7 @@ import { VariablesView, type VarRoot } from "./VariablesView";
|
||||
import { pushHistory, readHistory } from "./expressionHistory";
|
||||
import styles from "./Overlays.module.css";
|
||||
import { isImeKey } from "@/platform/ime";
|
||||
import { tx } from "@/platform/i18n";
|
||||
|
||||
export function DebuggerOverlays() {
|
||||
return (
|
||||
@@ -447,7 +448,7 @@ function BreakpointsDialog() {
|
||||
<Checkbox
|
||||
checked={r.bp.enabled}
|
||||
onChange={(enabled) => updateSpecial(r.bp.id, { enabled })}
|
||||
aria-label={`Enable ${specialTitle(r.bp)}`}
|
||||
aria-label={tx`Enable ${specialTitle(r.bp)}`}
|
||||
/>
|
||||
<Icon name={r.bp.kind === "method" ? "breakpoint-method" : "breakpoint-field"} size={14} />
|
||||
<span className={styles.bpName}>{specialTitle(r.bp)}</span>
|
||||
@@ -467,7 +468,7 @@ function BreakpointsDialog() {
|
||||
<Checkbox
|
||||
checked={r.bp.enabled}
|
||||
onChange={(enabled) => updateBreakpoint(r.path, r.bp.id, { enabled })}
|
||||
aria-label={`Enable breakpoint at ${basename(r.path)}:${r.bp.line + 1}`}
|
||||
aria-label={tx`Enable breakpoint at ${basename(r.path)}:${r.bp.line + 1}`}
|
||||
/>
|
||||
<span
|
||||
className={styles.bpDot}
|
||||
|
||||
Reference in new issue
Заблокувати користувача