add zh-Hans translations for macOS app

Signed-off-by: Aaron Ruan <i@ar212.com>
This commit is contained in:
Aaron Ruan
2025-03-15 17:53:00 +08:00
parent 4ab3754a59
commit 55212019ae
18 changed files with 1814 additions and 66 deletions

View File

@ -3,14 +3,16 @@
archiveVersion = 1; archiveVersion = 1;
classes = { classes = {
}; };
objectVersion = 56; objectVersion = 60;
objects = { objects = {
/* Begin PBXBuildFile section */ /* Begin PBXBuildFile section */
29C15B1D2CDC3B2900520DD4 /* bat in Resources */ = {isa = PBXBuildFile; fileRef = 29C15B1C2CDC3B2000520DD4 /* bat */; }; 29C15B1D2CDC3B2900520DD4 /* bat in Resources */ = {isa = PBXBuildFile; fileRef = 29C15B1C2CDC3B2000520DD4 /* bat */; };
55154BE02B33911F001622DC /* ghostty in Resources */ = {isa = PBXBuildFile; fileRef = 55154BDF2B33911F001622DC /* ghostty */; }; 55154BE02B33911F001622DC /* ghostty in Resources */ = {isa = PBXBuildFile; fileRef = 55154BDF2B33911F001622DC /* ghostty */; };
552964E62B34A9B400030505 /* vim in Resources */ = {isa = PBXBuildFile; fileRef = 552964E52B34A9B400030505 /* vim */; }; 552964E62B34A9B400030505 /* vim in Resources */ = {isa = PBXBuildFile; fileRef = 552964E52B34A9B400030505 /* vim */; };
857F63812A5E64F200CA4815 /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 857F63802A5E64F200CA4815 /* MainMenu.xib */; }; 8DA16F602D84598D009A416E /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 8DA16F5F2D84598D009A416E /* Localizable.xcstrings */; };
8DA16F612D84598D009A416E /* Localizable.xcstrings in Resources */ = {isa = PBXBuildFile; fileRef = 8DA16F5F2D84598D009A416E /* Localizable.xcstrings */; };
8DA16F662D845EF6009A416E /* MainMenu.xib in Resources */ = {isa = PBXBuildFile; fileRef = 8DA16F652D845EF6009A416E /* MainMenu.xib */; };
9351BE8E3D22937F003B3499 /* nvim in Resources */ = {isa = PBXBuildFile; fileRef = 9351BE8E2D22937F003B3499 /* nvim */; }; 9351BE8E3D22937F003B3499 /* nvim in Resources */ = {isa = PBXBuildFile; fileRef = 9351BE8E2D22937F003B3499 /* nvim */; };
A514C8D62B54A16400493A16 /* Ghostty.Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = A514C8D52B54A16400493A16 /* Ghostty.Config.swift */; }; A514C8D62B54A16400493A16 /* Ghostty.Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = A514C8D52B54A16400493A16 /* Ghostty.Config.swift */; };
A514C8D72B54A16400493A16 /* Ghostty.Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = A514C8D52B54A16400493A16 /* Ghostty.Config.swift */; }; A514C8D72B54A16400493A16 /* Ghostty.Config.swift in Sources */ = {isa = PBXBuildFile; fileRef = A514C8D52B54A16400493A16 /* Ghostty.Config.swift */; };
@ -117,7 +119,9 @@
3B39CAA42B33949B00DABEB8 /* GhosttyReleaseLocal.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GhosttyReleaseLocal.entitlements; sourceTree = "<group>"; }; 3B39CAA42B33949B00DABEB8 /* GhosttyReleaseLocal.entitlements */ = {isa = PBXFileReference; lastKnownFileType = text.plist.entitlements; path = GhosttyReleaseLocal.entitlements; sourceTree = "<group>"; };
55154BDF2B33911F001622DC /* ghostty */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ghostty; path = "../zig-out/share/ghostty"; sourceTree = "<group>"; }; 55154BDF2B33911F001622DC /* ghostty */ = {isa = PBXFileReference; lastKnownFileType = folder; name = ghostty; path = "../zig-out/share/ghostty"; sourceTree = "<group>"; };
552964E52B34A9B400030505 /* vim */ = {isa = PBXFileReference; lastKnownFileType = folder; name = vim; path = "../zig-out/share/vim"; sourceTree = "<group>"; }; 552964E52B34A9B400030505 /* vim */ = {isa = PBXFileReference; lastKnownFileType = folder; name = vim; path = "../zig-out/share/vim"; sourceTree = "<group>"; };
857F63802A5E64F200CA4815 /* MainMenu.xib */ = {isa = PBXFileReference; lastKnownFileType = file.xib; path = MainMenu.xib; sourceTree = "<group>"; }; 8DA16F5F2D84598D009A416E /* Localizable.xcstrings */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; path = Localizable.xcstrings; sourceTree = "<group>"; };
8DA16F642D845EF6009A416E /* Base */ = {isa = PBXFileReference; lastKnownFileType = file.xib; name = Base; path = Base.lproj/MainMenu.xib; sourceTree = "<group>"; };
8DA16F672D845EF6009A416E /* mul */ = {isa = PBXFileReference; lastKnownFileType = text.json.xcstrings; name = mul; path = mul.lproj/MainMenu.xcstrings; sourceTree = "<group>"; };
9351BE8E2D22937F003B3499 /* nvim */ = {isa = PBXFileReference; lastKnownFileType = folder; name = nvim; path = "../zig-out/share/nvim"; sourceTree = "<group>"; }; 9351BE8E2D22937F003B3499 /* nvim */ = {isa = PBXFileReference; lastKnownFileType = folder; name = nvim; path = "../zig-out/share/nvim"; sourceTree = "<group>"; };
A514C8D52B54A16400493A16 /* Ghostty.Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Config.swift; sourceTree = "<group>"; }; A514C8D52B54A16400493A16 /* Ghostty.Config.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = Ghostty.Config.swift; sourceTree = "<group>"; };
A51B78462AF4B58B00F3EDB9 /* TerminalWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalWindow.swift; sourceTree = "<group>"; }; A51B78462AF4B58B00F3EDB9 /* TerminalWindow.swift */ = {isa = PBXFileReference; lastKnownFileType = sourcecode.swift; path = TerminalWindow.swift; sourceTree = "<group>"; };
@ -336,7 +340,7 @@
children = ( children = (
A5FEB2FF2ABB69450068369E /* main.swift */, A5FEB2FF2ABB69450068369E /* main.swift */,
A53426342A7DA53D00EBB7A2 /* AppDelegate.swift */, A53426342A7DA53D00EBB7A2 /* AppDelegate.swift */,
857F63802A5E64F200CA4815 /* MainMenu.xib */, 8DA16F652D845EF6009A416E /* MainMenu.xib */,
C1F26EEA2B76CC2400404083 /* ghostty-bridging-header.h */, C1F26EEA2B76CC2400404083 /* ghostty-bridging-header.h */,
); );
path = macOS; path = macOS;
@ -439,6 +443,7 @@
A5B30528299BEAAA0047F10C = { A5B30528299BEAAA0047F10C = {
isa = PBXGroup; isa = PBXGroup;
children = ( children = (
8DA16F5F2D84598D009A416E /* Localizable.xcstrings */,
A571AB1C2A206FC600248498 /* Ghostty-Info.plist */, A571AB1C2A206FC600248498 /* Ghostty-Info.plist */,
A5B30538299BEAAB0047F10C /* Assets.xcassets */, A5B30538299BEAAB0047F10C /* Assets.xcassets */,
A5B3053D299BEAAB0047F10C /* Ghostty.entitlements */, A5B3053D299BEAAB0047F10C /* Ghostty.entitlements */,
@ -575,6 +580,7 @@
knownRegions = ( knownRegions = (
en, en,
Base, Base,
"zh-Hans",
); );
mainGroup = A5B30528299BEAAA0047F10C; mainGroup = A5B30528299BEAAA0047F10C;
packageReferences = ( packageReferences = (
@ -603,13 +609,14 @@
A5985CE62C33060F00C57AD3 /* man in Resources */, A5985CE62C33060F00C57AD3 /* man in Resources */,
9351BE8E3D22937F003B3499 /* nvim in Resources */, 9351BE8E3D22937F003B3499 /* nvim in Resources */,
A5A1F8852A489D6800D1E8BC /* terminfo in Resources */, A5A1F8852A489D6800D1E8BC /* terminfo in Resources */,
8DA16F602D84598D009A416E /* Localizable.xcstrings in Resources */,
552964E62B34A9B400030505 /* vim in Resources */, 552964E62B34A9B400030505 /* vim in Resources */,
FC5218FA2D10FFCE004C93E0 /* zsh in Resources */, FC5218FA2D10FFCE004C93E0 /* zsh in Resources */,
A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */, A5B30539299BEAAB0047F10C /* Assets.xcassets in Resources */,
A51BFC1E2B2FB5CE00E92F16 /* About.xib in Resources */, A51BFC1E2B2FB5CE00E92F16 /* About.xib in Resources */,
A5E112932AF73E6E00C6E0C2 /* ClipboardConfirmation.xib in Resources */, A5E112932AF73E6E00C6E0C2 /* ClipboardConfirmation.xib in Resources */,
A5CDF1912AAF9A5800513312 /* ConfigurationErrors.xib in Resources */, A5CDF1912AAF9A5800513312 /* ConfigurationErrors.xib in Resources */,
857F63812A5E64F200CA4815 /* MainMenu.xib in Resources */, 8DA16F662D845EF6009A416E /* MainMenu.xib in Resources */,
A596309A2AEE1C6400D64628 /* Terminal.xib in Resources */, A596309A2AEE1C6400D64628 /* Terminal.xib in Resources */,
A5CBD05C2CA0C5C70017A1AE /* QuickTerminal.xib in Resources */, A5CBD05C2CA0C5C70017A1AE /* QuickTerminal.xib in Resources */,
); );
@ -619,6 +626,7 @@
isa = PBXResourcesBuildPhase; isa = PBXResourcesBuildPhase;
buildActionMask = 2147483647; buildActionMask = 2147483647;
files = ( files = (
8DA16F612D84598D009A416E /* Localizable.xcstrings in Resources */,
A53D0C952B53B4D800305CE6 /* Assets.xcassets in Resources */, A53D0C952B53B4D800305CE6 /* Assets.xcassets in Resources */,
); );
runOnlyForDeploymentPostprocessing = 0; runOnlyForDeploymentPostprocessing = 0;
@ -723,6 +731,18 @@
}; };
/* End PBXSourcesBuildPhase section */ /* End PBXSourcesBuildPhase section */
/* Begin PBXVariantGroup section */
8DA16F652D845EF6009A416E /* MainMenu.xib */ = {
isa = PBXVariantGroup;
children = (
8DA16F642D845EF6009A416E /* Base */,
8DA16F672D845EF6009A416E /* mul */,
);
name = MainMenu.xib;
sourceTree = "<group>";
};
/* End PBXVariantGroup section */
/* Begin XCBuildConfiguration section */ /* Begin XCBuildConfiguration section */
3B39CAA22B33946300DABEB8 /* ReleaseLocal */ = { 3B39CAA22B33946300DABEB8 /* ReleaseLocal */ = {
isa = XCBuildConfiguration; isa = XCBuildConfiguration;
@ -775,6 +795,7 @@
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule; SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_OPTIMIZATION_LEVEL = "-O";
}; };
name = ReleaseLocal; name = ReleaseLocal;
@ -890,6 +911,7 @@
ONLY_ACTIVE_ARCH = YES; ONLY_ACTIVE_ARCH = YES;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG; SWIFT_ACTIVE_COMPILATION_CONDITIONS = DEBUG;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-Onone"; SWIFT_OPTIMIZATION_LEVEL = "-Onone";
}; };
name = Debug; name = Debug;
@ -945,6 +967,7 @@
MTL_FAST_MATH = YES; MTL_FAST_MATH = YES;
SDKROOT = macosx; SDKROOT = macosx;
SWIFT_COMPILATION_MODE = wholemodule; SWIFT_COMPILATION_MODE = wholemodule;
SWIFT_EMIT_LOC_STRINGS = YES;
SWIFT_OPTIMIZATION_LEVEL = "-O"; SWIFT_OPTIMIZATION_LEVEL = "-O";
}; };
name = Release; name = Release;

512
macos/Localizable.xcstrings Normal file
View File

@ -0,0 +1,512 @@
{
"sourceLanguage" : "en",
"strings" : {
"%lld error(s) was/were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines." : {
"localizations" : {
"en" : {
"variations" : {
"plural" : {
"one" : {
"stringUnit" : {
"state" : "translated",
"value" : "%lld error wasfound while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines."
}
},
"other" : {
"stringUnit" : {
"state" : "translated",
"value" : "%lld errors were found while loading the configuration. Please review the errors below and reload your configuration or ignore the erroneous lines."
}
}
}
}
},
"zh-Hans" : {
"variations" : {
"plural" : {
"other" : {
"stringUnit" : {
"state" : "translated",
"value" : "加载设置时发现了%lld个错误。请查看下方的错误并重新加载您的设置或忽略出错的行。"
}
}
}
}
}
}
},
"All terminal sessions in this window will be terminated." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "窗口内所有运行中的进程将被终止。"
}
}
}
},
"All terminal sessions will be terminated." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "终端内所有运行中的进程将被终止。"
}
}
}
},
"Allow" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "允许"
}
}
}
},
"Authorize Clipboard Access" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "剪切板访问授权"
}
}
}
},
"Cancel" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "取消"
}
}
}
},
"Cannot Create New Tab" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "无法创建新的标签页"
}
}
}
},
"Change Terminal Title" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更改终端标题"
}
}
}
},
"Change Title..." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "更改标题…"
}
}
}
},
"Close" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭"
}
}
}
},
"Close All Windows" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭所有窗口"
}
}
}
},
"Close All Windows?" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭所有窗口吗?"
}
}
}
},
"Close Ghostty" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭Ghostty"
}
}
}
},
"Close Tab?" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭标签页吗?"
}
}
}
},
"Close Terminal?" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭终端吗?"
}
}
}
},
"Close the Terminal" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭这个终端"
}
}
}
},
"Close Window?" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "关闭窗口吗?"
}
}
}
},
"Coming Soon. 🚧" : {
"shouldTranslate" : false
},
"Copy" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拷贝"
}
}
}
},
"Debug builds of Ghostty are very slow and you may experience\nperformance problems. Debug builds are only recommended during\ndevelopment." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ghostty的调试版本运行非常缓慢可能\n会出现性能问题。建议仅在开发过程中使\n用调试版本。"
}
}
}
},
"Deny" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "拒绝"
}
}
}
},
"Docs" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "文档"
}
}
}
},
"Enable window decorations to use tabs" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "启用窗口装饰以使用标签页"
}
}
}
},
"Fast, native, feature-rich terminal \nemulator pushing modern features." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "快速、原生、功能丰富的终端模拟器,提供现代功能。"
}
}
}
},
"Ghostty" : {
"shouldTranslate" : false
},
"GitHub" : {
"shouldTranslate" : false
},
"Ignore" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "忽略"
}
}
}
},
"Leave blank to restore the default." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "留空以重置至默认标题。"
}
}
}
},
"Loading" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "加载中"
}
}
}
},
"New tabs are unsupported while in non-native fullscreen. Exit fullscreen and try again." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "在非原生全屏幕模式下无法新建标签页。退出全屏幕后再试试。"
}
}
}
},
"Oh, no. 😭" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "大事不妙😭"
}
}
}
},
"OK" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "好"
}
}
}
},
"Paste" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "粘贴"
}
}
}
},
"Quit Ghostty?" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "退出Ghostty吗"
}
}
}
},
"Reload Configuration" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重新加载设置"
}
}
}
},
"Reset Terminal" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重置终端"
}
}
}
},
"Reset Zoom" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "重置缩放"
}
}
}
},
"Secure Input is active. Secure Input is a macOS security feature that \nprevents applications from reading keyboard events. This is enabled \nautomatically whenever Ghostty detects a password prompt in the terminal, \nor at all times if `Ghostty > Secure Keyboard Entry` is active." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "安全输入已启用。安全输入是macOS的一项安全功能\n可防止其他应用程序读取键盘事件。当Ghostty在终端\n中检测到密码输入提示时会自动启用该功能如果启用\n`Ghostty > 安全键盘输入`,则会始终保持启用状态。"
}
}
}
},
"Something went fatally wrong.\nCheck the logs and restart Ghostty." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "发生致命错误。请检查日志并重新启动Ghostty。"
}
}
}
},
"Split Down" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "向下分屏"
}
}
}
},
"Split Left" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "向左分屏"
}
}
}
},
"Split Right" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "向右分屏"
}
}
}
},
"Split Up" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "向上分屏"
}
}
}
},
"Tabs are disabled" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "标签页已被禁用"
}
}
}
},
"Tabs aren't supported in the Quick Terminal." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "快捷终端不支持标签页"
}
}
}
},
"The terminal still has a running process. If you close the tab the process will be killed." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "这个终端中有正在运行的进程。关闭这个标签页将终止该进程。"
}
}
}
},
"The terminal still has a running process. If you close the terminal the process will be killed." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "这个终端中有正在运行的进程。关闭这个终端将终止该进程。"
}
}
}
},
"Toggle Terminal Inspector" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "切换终端检视器"
}
}
}
},
"Warning: Potentially Unsafe Paste" : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "警告:粘贴内容可能不安全"
}
}
}
},
"You can't configure settings in the GUI yet. To modify settings, edit the file at $HOME/.config/ghostty/config and restart Ghostty." : {
"shouldTranslate" : false
},
"You're running a debug build of Ghostty! Performance will be degraded." : {
"localizations" : {
"zh-Hans" : {
"stringUnit" : {
"state" : "translated",
"value" : "Ghostty正在以调试模式运行性能将大打折扣。"
}
}
}
}
},
"version" : "1.0"
}

View File

@ -287,10 +287,10 @@ class AppDelegate: NSObject,
// We have some visible window. Show an app-wide modal to confirm quitting. // We have some visible window. Show an app-wide modal to confirm quitting.
let alert = NSAlert() let alert = NSAlert()
alert.messageText = "Quit Ghostty?" alert.messageText = String(localized: "Quit Ghostty?")
alert.informativeText = "All terminal sessions will be terminated." alert.informativeText = String(localized: "All terminal sessions will be terminated.")
alert.addButton(withTitle: "Close Ghostty") alert.addButton(withTitle: String(localized: "Close Ghostty"))
alert.addButton(withTitle: "Cancel") alert.addButton(withTitle: String(localized: "Cancel"))
alert.alertStyle = .warning alert.alertStyle = .warning
switch (alert.runModal()) { switch (alert.runModal()) {
case .alertFirstButtonReturn: case .alertFirstButtonReturn:

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23504" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23727" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23504"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23727"/>
</dependencies> </dependencies>
<objects> <objects>
<customObject id="-2" userLabel="File's Owner" customClass="NSApplication"> <customObject id="-2" userLabel="File's Owner" customClass="NSApplication">

File diff suppressed because it is too large Load Diff

View File

@ -35,9 +35,9 @@ class ClipboardConfirmationController: NSWindowController {
switch (request) { switch (request) {
case .paste: case .paste:
window.title = "Warning: Potentially Unsafe Paste" window.title = String(localized: "Warning: Potentially Unsafe Paste")
case .osc_52_read, .osc_52_write: case .osc_52_read, .osc_52_write:
window.title = "Authorize Clipboard Access" window.title = String(localized: "Authorize Clipboard Access")
} }
window.contentView = NSHostingView(rootView: ClipboardConfirmationView( window.contentView = NSHostingView(rootView: ClipboardConfirmationView(

View File

@ -14,13 +14,13 @@ struct ClipboardConfirmationView: View {
static func text(_ action: Action, _ reason: Ghostty.ClipboardRequest) -> String { static func text(_ action: Action, _ reason: Ghostty.ClipboardRequest) -> String {
switch (action, reason) { switch (action, reason) {
case (.cancel, .paste): case (.cancel, .paste):
return "Cancel" return String(localized: "Cancel")
case (.cancel, .osc_52_read), (.cancel, .osc_52_write): case (.cancel, .osc_52_read), (.cancel, .osc_52_write):
return "Deny" return String(localized: "Deny")
case (.confirm, .paste): case (.confirm, .paste):
return "Paste" return String(localized: "Paste")
case (.confirm, .osc_52_read), (.confirm, .osc_52_write): case (.confirm, .osc_52_read), (.confirm, .osc_52_write):
return "Allow" return String(localized: "Allow")
} }
} }
} }

View File

@ -445,9 +445,9 @@ class QuickTerminalController: BaseTerminalController {
private func showNoNewTabAlert() { private func showNoNewTabAlert() {
guard let window else { return } guard let window else { return }
let alert = NSAlert() let alert = NSAlert()
alert.messageText = "Cannot Create New Tab" alert.messageText = String(localized: "Cannot Create New Tab")
alert.informativeText = "Tabs aren't supported in the Quick Terminal." alert.informativeText = String(localized: "Tabs aren't supported in the Quick Terminal.")
alert.addButton(withTitle: "OK") alert.addButton(withTitle: String(localized: "OK"))
alert.alertStyle = .warning alert.alertStyle = .warning
alert.beginSheetModal(for: window) alert.beginSheetModal(for: window)
} }

View File

@ -17,7 +17,7 @@ struct ConfigurationErrorsView<ViewModel: ConfigurationErrorsViewModel>: View {
.frame(alignment: .center) .frame(alignment: .center)
Text(""" Text("""
^[\(model.errors.count) error(s) were](inflect: true) found while loading the configuration. \ \(model.errors.count) error(s) was/were found while loading the configuration. \
Please review the errors below and reload your configuration or ignore the erroneous lines. Please review the errors below and reload your configuration or ignore the erroneous lines.
""") """)
.frame(maxWidth: .infinity, alignment: .leading) .frame(maxWidth: .infinity, alignment: .leading)

View File

@ -13,8 +13,10 @@ struct SettingsView: View {
VStack(alignment: .leading) { VStack(alignment: .leading) {
Text("Coming Soon. 🚧").font(.title) Text("Coming Soon. 🚧").font(.title)
Text("You can't configure settings in the GUI yet. To modify settings, " + Text("""
"edit the file at $HOME/.config/ghostty/config and restart Ghostty.") You can't configure settings in the GUI yet. To modify settings, \
edit the file at $HOME/.config/ghostty/config and restart Ghostty.
""")
.multilineTextAlignment(.leading) .multilineTextAlignment(.leading)
.lineLimit(nil) .lineLimit(nil)
} }

View File

@ -450,11 +450,16 @@ class BaseTerminalController: NSWindowController,
// We require confirmation, so show an alert as long as we aren't already. // We require confirmation, so show an alert as long as we aren't already.
let alert = NSAlert() let alert = NSAlert()
alert.messageText = "Close Terminal?" alert.messageText = String(localized: "Close Terminal?")
alert.informativeText = "The terminal still has a running process. If you close the " + alert.informativeText = String(
"terminal the process will be killed." localized:
alert.addButton(withTitle: "Close the Terminal") """
alert.addButton(withTitle: "Cancel") The terminal still has a running process. If you close the \
terminal the process will be killed.
"""
)
alert.addButton(withTitle: String(localized: "Close the Terminal"))
alert.addButton(withTitle: String(localized: "Cancel"))
alert.alertStyle = .warning alert.alertStyle = .warning
alert.beginSheetModal(for: window, completionHandler: { response in alert.beginSheetModal(for: window, completionHandler: { response in
self.alert = nil self.alert = nil

View File

@ -1,8 +1,8 @@
<?xml version="1.0" encoding="UTF-8"?> <?xml version="1.0" encoding="UTF-8"?>
<document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23094" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct"> <document type="com.apple.InterfaceBuilder3.Cocoa.XIB" version="3.0" toolsVersion="23727" targetRuntime="MacOSX.Cocoa" propertyAccessControl="none" useAutolayout="YES" customObjectInstantitationMethod="direct">
<dependencies> <dependencies>
<deployment identifier="macosx"/> <deployment identifier="macosx"/>
<plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23094"/> <plugIn identifier="com.apple.InterfaceBuilder.CocoaPlugin" version="23727"/>
<capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/> <capability name="documents saved in the Xcode 8 format" minToolsVersion="8.0"/>
</dependencies> </dependencies>
<objects> <objects>
@ -17,7 +17,7 @@
<windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/> <windowStyleMask key="styleMask" titled="YES" closable="YES" miniaturizable="YES" resizable="YES"/>
<windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/> <windowPositionMask key="initialPositionMask" leftStrut="YES" rightStrut="YES" topStrut="YES" bottomStrut="YES"/>
<rect key="contentRect" x="0.0" y="0.0" width="800" height="600"/> <rect key="contentRect" x="0.0" y="0.0" width="800" height="600"/>
<rect key="screenRect" x="0.0" y="0.0" width="3008" height="1667"/> <rect key="screenRect" x="0.0" y="0.0" width="1710" height="1074"/>
<view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ"> <view key="contentView" wantsLayer="YES" id="EiT-Mj-1SZ">
<rect key="frame" x="0.0" y="0.0" width="800" height="600"/> <rect key="frame" x="0.0" y="0.0" width="800" height="600"/>
<autoresizingMask key="autoresizingMask"/> <autoresizingMask key="autoresizingMask"/>

View File

@ -592,8 +592,8 @@ class TerminalController: BaseTerminalController {
let alert = NSAlert() let alert = NSAlert()
alert.messageText = messageText alert.messageText = messageText
alert.informativeText = informativeText alert.informativeText = informativeText
alert.addButton(withTitle: "Close") alert.addButton(withTitle: String(localized: "Close"))
alert.addButton(withTitle: "Cancel") alert.addButton(withTitle: String(localized: "Cancel"))
alert.alertStyle = .warning alert.alertStyle = .warning
alert.beginSheetModal(for: window) { response in alert.beginSheetModal(for: window) { response in
if response == .alertFirstButtonReturn { if response == .alertFirstButtonReturn {
@ -613,8 +613,8 @@ class TerminalController: BaseTerminalController {
if surfaceTree?.needsConfirmQuit() ?? false { if surfaceTree?.needsConfirmQuit() ?? false {
confirmClose( confirmClose(
window: window, window: window,
messageText: "Close Tab?", messageText: String(localized: "Close Tab?"),
informativeText: "The terminal still has a running process. If you close the tab the process will be killed." informativeText: String(localized: "The terminal still has a running process. If you close the tab the process will be killed.")
) { ) {
window.close() window.close()
} }
@ -659,8 +659,8 @@ class TerminalController: BaseTerminalController {
confirmClose( confirmClose(
window: window, window: window,
messageText: "Close Window?", messageText: String(localized: "Close Window?"),
informativeText: "All terminal sessions in this window will be terminated." informativeText: String(localized: "All terminal sessions in this window will be terminated.")
) { ) {
tabGroup.windows.forEach { $0.close() } tabGroup.windows.forEach { $0.close() }
} }

View File

@ -134,9 +134,11 @@ class TerminalManager {
let fullscreenStyle = controller.fullscreenStyle, let fullscreenStyle = controller.fullscreenStyle,
fullscreenStyle.isFullscreen && !fullscreenStyle.supportsTabs { fullscreenStyle.isFullscreen && !fullscreenStyle.supportsTabs {
let alert = NSAlert() let alert = NSAlert()
alert.messageText = "Cannot Create New Tab" alert.messageText = String(localized: "Cannot Create New Tab")
alert.informativeText = "New tabs are unsupported while in non-native fullscreen. Exit fullscreen and try again." alert.informativeText = String(
alert.addButton(withTitle: "OK") localized: "New tabs are unsupported while in non-native fullscreen. Exit fullscreen and try again."
)
alert.addButton(withTitle: String(localized: "OK"))
alert.alertStyle = .warning alert.alertStyle = .warning
alert.beginSheetModal(for: parent) alert.beginSheetModal(for: parent)
return return
@ -296,10 +298,10 @@ class TerminalManager {
// If we need confirmation by any, show one confirmation for all windows // If we need confirmation by any, show one confirmation for all windows
let alert = NSAlert() let alert = NSAlert()
alert.messageText = "Close All Windows?" alert.messageText = String(localized: "Close All Windows?")
alert.informativeText = "All terminal sessions will be terminated." alert.informativeText = String(localized: "All terminal sessions will be terminated.")
alert.addButton(withTitle: "Close All Windows") alert.addButton(withTitle: String(localized: "Close All Windows"))
alert.addButton(withTitle: "Cancel") alert.addButton(withTitle: String(localized: "Cancel"))
alert.alertStyle = .warning alert.alertStyle = .warning
alert.beginSheetModal(for: alertWindow, completionHandler: { response in alert.beginSheetModal(for: alertWindow, completionHandler: { response in
if (response == .alertFirstButtonReturn) { if (response == .alertFirstButtonReturn) {

View File

@ -390,7 +390,7 @@ class TerminalWindow: NSWindow {
button.action = #selector(TerminalController.splitZoom(_:)) button.action = #selector(TerminalController.splitZoom(_:))
button.isBordered = false button.isBordered = false
button.allowsExpansionToolTips = true button.allowsExpansionToolTips = true
button.toolTip = "Reset Zoom" button.toolTip = String(localized: "Reset Zoom")
button.contentTintColor = .controlAccentColor button.contentTintColor = .controlAccentColor
button.state = .on button.state = .on
button.image = NSImage(named:"ResetZoom") button.image = NSImage(named:"ResetZoom")

View File

@ -614,9 +614,9 @@ extension Ghostty {
guard let appState = self.appState(fromView: surfaceView) else { return } guard let appState = self.appState(fromView: surfaceView) else { return }
guard appState.config.windowDecorations else { guard appState.config.windowDecorations else {
let alert = NSAlert() let alert = NSAlert()
alert.messageText = "Tabs are disabled" alert.messageText = String(localized: "Tabs are disabled")
alert.informativeText = "Enable window decorations to use tabs" alert.informativeText = String(localized: "Enable window decorations to use tabs")
alert.addButton(withTitle: "OK") alert.addButton(withTitle: String(localized: "OK"))
alert.alertStyle = .warning alert.alertStyle = .warning
_ = alert.runModal() _ = alert.runModal()
return return

View File

@ -189,11 +189,13 @@ extension Ghostty {
// so SwiftUI does not update any of the bindings to note that window is no longer // so SwiftUI does not update any of the bindings to note that window is no longer
// being shown, and provides no callback to detect this. // being shown, and provides no callback to detect this.
let alert = NSAlert() let alert = NSAlert()
alert.messageText = "Close Terminal?" alert.messageText = String(localized: "Close Terminal?")
alert.informativeText = "The terminal still has a running process. If you close the " + alert.informativeText = String(localized: """
"terminal the process will be killed." The terminal still has a running process. If you close the \
alert.addButton(withTitle: "Close the Terminal") terminal the process will be killed.
alert.addButton(withTitle: "Cancel") """)
alert.addButton(withTitle: String(localized: "Close the Terminal"))
alert.addButton(withTitle: String(localized: "Cancel"))
alert.alertStyle = .warning alert.alertStyle = .warning
alert.beginSheetModal(for: window, completionHandler: { response in alert.beginSheetModal(for: window, completionHandler: { response in
switch (response) { switch (response) {

View File

@ -389,8 +389,8 @@ extension Ghostty {
func promptTitle() { func promptTitle() {
// Create an alert dialog // Create an alert dialog
let alert = NSAlert() let alert = NSAlert()
alert.messageText = "Change Terminal Title" alert.messageText = String(localized: "Change Terminal Title")
alert.informativeText = "Leave blank to restore the default." alert.informativeText = String(localized: "Leave blank to restore the default.")
alert.alertStyle = .informational alert.alertStyle = .informational
// Add a text field to the alert // Add a text field to the alert
@ -399,8 +399,8 @@ extension Ghostty {
alert.accessoryView = textField alert.accessoryView = textField
// Add buttons // Add buttons
alert.addButton(withTitle: "OK") alert.addButton(withTitle: String(localized: "OK"))
alert.addButton(withTitle: "Cancel") alert.addButton(withTitle: String(localized: "Cancel"))
let response = alert.runModal() let response = alert.runModal()
@ -1155,21 +1155,21 @@ extension Ghostty {
// If we have a selection, add copy // If we have a selection, add copy
if self.selectedRange().length > 0 { if self.selectedRange().length > 0 {
menu.addItem(withTitle: "Copy", action: #selector(copy(_:)), keyEquivalent: "") menu.addItem(withTitle: String(localized: "Copy"), action: #selector(copy(_:)), keyEquivalent: "")
} }
menu.addItem(withTitle: "Paste", action: #selector(paste(_:)), keyEquivalent: "") menu.addItem(withTitle: String(localized: "Paste"), action: #selector(paste(_:)), keyEquivalent: "")
menu.addItem(.separator()) menu.addItem(.separator())
menu.addItem(withTitle: "Split Right", action: #selector(splitRight(_:)), keyEquivalent: "") menu.addItem(withTitle: String(localized: "Split Right"), action: #selector(splitRight(_:)), keyEquivalent: "")
menu.addItem(withTitle: "Split Left", action: #selector(splitLeft(_:)), keyEquivalent: "") menu.addItem(withTitle: String(localized: "Split Left"), action: #selector(splitLeft(_:)), keyEquivalent: "")
menu.addItem(withTitle: "Split Down", action: #selector(splitDown(_:)), keyEquivalent: "") menu.addItem(withTitle: String(localized: "Split Down"), action: #selector(splitDown(_:)), keyEquivalent: "")
menu.addItem(withTitle: "Split Up", action: #selector(splitUp(_:)), keyEquivalent: "") menu.addItem(withTitle: String(localized: "Split Up"), action: #selector(splitUp(_:)), keyEquivalent: "")
menu.addItem(.separator()) menu.addItem(.separator())
menu.addItem(withTitle: "Reset Terminal", action: #selector(resetTerminal(_:)), keyEquivalent: "") menu.addItem(withTitle: String(localized: "Reset Terminal"), action: #selector(resetTerminal(_:)), keyEquivalent: "")
menu.addItem(withTitle: "Toggle Terminal Inspector", action: #selector(toggleTerminalInspector(_:)), keyEquivalent: "") menu.addItem(withTitle: String(localized: "Toggle Terminal Inspector"), action: #selector(toggleTerminalInspector(_:)), keyEquivalent: "")
menu.addItem(.separator()) menu.addItem(.separator())
menu.addItem(withTitle: "Change Title...", action: #selector(changeTitle(_:)), keyEquivalent: "") menu.addItem(withTitle: String(localized: "Change Title..."), action: #selector(changeTitle(_:)), keyEquivalent: "")
return menu return menu
} }