Compile localizations with build.rs (#591)

This commit is contained in:
Leonard Hecker 2025-07-31 23:36:49 +02:00 committed by GitHub
parent 63d2574774
commit 3c41b85ae4
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
6 changed files with 1099 additions and 1113 deletions

171
Cargo.lock generated
View file

@ -19,15 +19,15 @@ checksum = "4b46cbb362ab8752921c97e041f5e366ee6297bd428a31275b9fcf1e380f7299"
[[package]]
name = "anstyle"
version = "1.0.10"
version = "1.0.11"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "55cc3b69f167a1ef2e161439aa98aed94e6028e5f9a59be9a6ffb47aef1651f9"
checksum = "862ed96ca487e809f1c8e5a8447f6ee2cf102f846893800b20cebdf541fc6bbd"
[[package]]
name = "autocfg"
version = "1.4.0"
version = "1.5.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "ace50bade8e6234aa140d9a2f552bbee1db4d353f69b8217bc503490fc1a9f26"
checksum = "c08606f8c3cbf4ce6ec8e28fb0014a2c086708fe954eaa885384a6165172e7e8"
[[package]]
name = "bitflags"
@ -37,9 +37,9 @@ checksum = "1b8e56985ec62d17e9c1001dc89c88ecd7dc08e47eba5ec7c29c7b5eeecde967"
[[package]]
name = "bumpalo"
version = "3.17.0"
version = "3.19.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "1628fb46dfa0b37568d12e5edd512553eccf6a22a78e8bde00bb4aed84d5bdbf"
checksum = "46c5e41b57b8bba42a04676d81cb89e9ee8e859a1a66f80a5a72e1cb76b34d43"
[[package]]
name = "cast"
@ -49,9 +49,9 @@ checksum = "37b2a672a2cb129a2e41c10b1224bb368f9f37a2b16b612598138befd7b37eb5"
[[package]]
name = "cc"
version = "1.2.25"
version = "1.2.30"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d0fc897dc1e865cc67c0e05a836d9d3f1df3cbe442aa4a9473b18e12624a4951"
checksum = "deec109607ca693028562ed836a5f1c4b8bd77755c4e132fc5ce11b0b6211ae7"
dependencies = [
"jobserver",
"libc",
@ -60,9 +60,9 @@ dependencies = [
[[package]]
name = "cfg-if"
version = "1.0.0"
version = "1.0.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "baf1de4339761588bc0619e3cbc0120ee582ebb74b53b4efbf79117bd2da40fd"
checksum = "9555578bc9e57714c812a1f84e4fc5b4d21fcb063490c624de019f7464c91268"
[[package]]
name = "ciborium"
@ -93,18 +93,18 @@ dependencies = [
[[package]]
name = "clap"
version = "4.5.39"
version = "4.5.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "fd60e63e9be68e5fb56422e397cf9baddded06dae1d2e523401542383bc72a9f"
checksum = "ed87a9d530bb41a67537289bafcac159cb3ee28460e0a4571123d2a778a6a882"
dependencies = [
"clap_builder",
]
[[package]]
name = "clap_builder"
version = "4.5.39"
version = "4.5.42"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "89cc6392a1f72bbeb820d71f32108f61fdaf18bc526e1d23954168a67759ef51"
checksum = "64f4f3f3c77c94aff3c7e9aac9a2ca1974a5adf392a8bb751e827d6d127ab966"
dependencies = [
"anstyle",
"clap_lex",
@ -112,22 +112,22 @@ dependencies = [
[[package]]
name = "clap_lex"
version = "0.7.4"
version = "0.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "f46ad14479a25103f283c0f10005961cf086d8dc42205bb44c46ac563475dca6"
checksum = "b94f61472cee1439c0b966b47e3aca9ae07e45d070759512cd390ea2bebc6675"
[[package]]
name = "criterion"
version = "0.6.0"
version = "0.7.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3bf7af66b0989381bd0be551bd7cc91912a655a58c6918420c9527b1fd8b4679"
checksum = "e1c047a62b0cc3e145fa84415a3191f628e980b194c2755aa12300a4e6cbd928"
dependencies = [
"anes",
"cast",
"ciborium",
"clap",
"criterion-plot",
"itertools 0.13.0",
"itertools",
"num-traits",
"oorandom",
"plotters",
@ -141,12 +141,12 @@ dependencies = [
[[package]]
name = "criterion-plot"
version = "0.5.0"
version = "0.6.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "6b50826342786a51a89e2da3a28f1c32b06e387201bc2d19791f622c673706b1"
checksum = "9b1bcc0dc7dfae599d84ad0b1a55f80cde8af3725da8313b528da95ef783e338"
dependencies = [
"cast",
"itertools 0.10.5",
"itertools",
]
[[package]]
@ -176,9 +176,9 @@ checksum = "d0a5c400df2834b80a4c3327b3aad3a4c4cd4de0629063962b03235697506a28"
[[package]]
name = "crunchy"
version = "0.2.3"
version = "0.2.4"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "43da5946c66ffcc7745f48db692ffbb10a83bfe0afd96235c5c2a4fb23994929"
checksum = "460fbee9c2c2f33933d720630a6a0bac33ba7053db5344fac858d4b8952d77d5"
[[package]]
name = "edit"
@ -188,6 +188,7 @@ dependencies = [
"libc",
"serde",
"serde_json",
"toml-span",
"windows-sys",
"winresource",
"zstd",
@ -199,12 +200,6 @@ version = "1.15.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "48c757948c5ede0e46177b7add2e67155f70e33c07fea8284df6576da70b3719"
[[package]]
name = "equivalent"
version = "1.0.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "877a4ace8713b0bcf2a4e7eec82529c029f1d0619886d18145fea96c3ffe5c0f"
[[package]]
name = "getrandom"
version = "0.3.3"
@ -227,31 +222,6 @@ dependencies = [
"crunchy",
]
[[package]]
name = "hashbrown"
version = "0.15.3"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "84b26c544d002229e640969970a2e74021aadf6e2f96372b9c58eff97de08eb3"
[[package]]
name = "indexmap"
version = "2.9.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "cea70ddb795996207ad57735b50c5982d8844f38ba9ee5f1aedcfb708a2aa11e"
dependencies = [
"equivalent",
"hashbrown",
]
[[package]]
name = "itertools"
version = "0.10.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "b0fd2260e829bddf4cb6ea802289de2f86d6a7a690192fbe91b3f46e0f2c8473"
dependencies = [
"either",
]
[[package]]
name = "itertools"
version = "0.13.0"
@ -289,9 +259,9 @@ dependencies = [
[[package]]
name = "libc"
version = "0.2.172"
version = "0.2.174"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "d750af042f7ef4f724306de029d18836c26c1765a54a6a3f094cbd23a7267ffa"
checksum = "1171693293099992e19cddea4e8b849964e9846f4acee11b3948bcc337be8776"
[[package]]
name = "log"
@ -301,9 +271,9 @@ checksum = "13dc2df351e3202783a1fe0d44375f7295ffb4049267b0f3018346dc122a1d94"
[[package]]
name = "memchr"
version = "2.7.4"
version = "2.7.5"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "78ca9ab1a0babb1e7d5695e3530886289c18cf2f87ec19a575a0abdce112e3a3"
checksum = "32a282da65faaf38286cf3be983213fcf1d2e2a58700e808f83f4ea9a4804bc0"
[[package]]
name = "num-traits"
@ -380,9 +350,9 @@ dependencies = [
[[package]]
name = "r-efi"
version = "5.2.0"
version = "5.3.0"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "74765f6d916ee2faa39bc8e68e4f3ed8949b48cccdac59983d287a7cb71ce9c5"
checksum = "69cdb34c158ceb288df11e18b4bd39de994f6657d83847bdffdbd7f346754b0f"
[[package]]
name = "rayon"
@ -476,9 +446,9 @@ dependencies = [
[[package]]
name = "serde_json"
version = "1.0.140"
version = "1.0.141"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "20068b6e96dc6c9bd23e01df8827e6c7e1f2fddd43c21810382803c136b99373"
checksum = "30b9eff21ebe718216c6ec64e1d9ac57087aad11efc64e32002bce4a0d4c03d3"
dependencies = [
"itoa",
"memchr",
@ -486,15 +456,6 @@ dependencies = [
"serde",
]
[[package]]
name = "serde_spanned"
version = "0.6.8"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "87607cb1398ed59d48732e575a4c28a7a8ebf2454b964fe3f224f2afc07909e1"
dependencies = [
"serde",
]
[[package]]
name = "shlex"
version = "1.3.0"
@ -502,10 +463,16 @@ source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "0fda2ff0d084019ba4d7c6f371c95d8fd75ce3524c3cb8fb653a3023f6323e64"
[[package]]
name = "syn"
version = "2.0.101"
name = "smallvec"
version = "1.15.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "8ce2b7fc941b3a24138a0a7cf8e858bfc6a992e7978a068a5c760deb0ed43caf"
checksum = "67b1b7a3b5fe4f1376887184045fcf45c69e92af734b7aaddc05fb777b6fbd03"
[[package]]
name = "syn"
version = "2.0.104"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "17b6f705963418cdb9927482fa304bc562ece2fdd4f616084c50b7023b435a40"
dependencies = [
"proc-macro2",
"quote",
@ -523,46 +490,14 @@ dependencies = [
]
[[package]]
name = "toml"
version = "0.8.22"
name = "toml-span"
version = "0.5.2"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "05ae329d1f08c4d17a59bed7ff5b5a769d062e64a62d34a3261b219e62cd5aae"
checksum = "2d36acfca70d66f9b5f9c4786fec60096c3594169bf77b8d4207174dc862e6a4"
dependencies = [
"serde",
"serde_spanned",
"toml_datetime",
"toml_edit",
"smallvec",
]
[[package]]
name = "toml_datetime"
version = "0.6.9"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "3da5db5a963e24bc68be8b17b6fa82814bb22ee8660f192bb182771d498f09a3"
dependencies = [
"serde",
]
[[package]]
name = "toml_edit"
version = "0.22.26"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "310068873db2c5b3e7659d2cc35d21855dbafa50d1ce336397c666e3cb08137e"
dependencies = [
"indexmap",
"serde",
"serde_spanned",
"toml_datetime",
"toml_write",
"winnow",
]
[[package]]
name = "toml_write"
version = "0.1.1"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "bfb942dfe1d8e29a7ee7fcbde5bd2b9a25fb89aa70caea2eba3bee836ff41076"
[[package]]
name = "unicode-ident"
version = "1.0.18"
@ -744,22 +679,12 @@ version = "0.52.6"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "589f6da84c646204747d1270a2a5661ea66ed1cced2631d546fdfb155959f9ec"
[[package]]
name = "winnow"
version = "0.7.10"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "c06928c8748d81b05c9be96aad92e1b6ff01833332f281e8cfca3be4b35fc9ec"
dependencies = [
"memchr",
]
[[package]]
name = "winresource"
version = "0.1.22"
version = "0.1.23"
source = "registry+https://github.com/rust-lang/crates.io-index"
checksum = "a179ac8923651ff1d15efbee760b4dd3679fd85fa5a8b2bb1109b7248f80e30f"
checksum = "edcacf11b6f48dd21b9ba002f991bdd5de29b2da8cc2800412f4b80f677e4957"
dependencies = [
"toml",
"version_check",
]

View file

@ -38,8 +38,13 @@ lto = "thin" # Similarly, speed up linking by a ton
[target.'cfg(unix)'.dependencies]
libc = "0.2"
[build-dependencies]
# The default toml crate bundles its dependencies with bad compile times. Thanks.
# Thankfully toml-span exists. FWIW the alternative is yaml-rust (without the 2 suffix).
toml-span = { version = "0.5", default-features = false }
[target.'cfg(windows)'.build-dependencies]
winresource = "0.1.22"
winresource = { version = "0.1.22", default-features = false }
[target.'cfg(windows)'.dependencies.windows-sys]
version = "0.59"
@ -56,7 +61,7 @@ features = [
]
[dev-dependencies]
criterion = { version = "0.6", features = ["html_reports"] }
criterion = { version = "0.7", features = ["html_reports"] }
serde = { version = "1.0", features = ["derive"] }
serde_json = { version = "1.0" }
zstd = { version = "0.13", default-features = false }

View file

@ -27,6 +27,15 @@ winget install Microsoft.Edit
* Clone the repository
* For a release build, run: `cargo build --config .cargo/release.toml --release`
### Build Configuration
During compilation you can set various environment variables to configure the build. The following table lists the available configuration options:
Environment variable | Description
--- | ---
`EDIT_CFG_ICU*` | See [ICU library name (SONAME)](#icu-library-name-soname) for details.
`EDIT_CFG_LANGUAGES` | A comma-separated list of languages to include in the build. See [i18n/edit.toml](i18n/edit.toml) for available languages.
## Notes to Package Maintainers
### Package Naming

237
build.rs
View file

@ -1,10 +1,13 @@
// Copyright (c) Microsoft Corporation.
// Licensed under the MIT License.
use core::panic;
use std::env::VarError;
#![allow(irrefutable_let_patterns)]
#[derive(PartialEq, Eq)]
use std::collections::{BTreeMap, HashMap, HashSet};
use std::env::VarError;
use std::io::Write as _;
#[derive(Clone, Copy, PartialEq, Eq)]
enum TargetOs {
Windows,
MacOS,
@ -17,6 +20,210 @@ fn main() {
"macos" | "ios" => TargetOs::MacOS,
_ => TargetOs::Unix,
};
compile_i18n();
configure_icu(target_os);
#[cfg(windows)]
configure_windows_binary(target_os);
}
fn compile_i18n() {
const PATH: &str = "i18n/edit.toml";
let i18n = std::fs::read_to_string(PATH).unwrap();
let i18n = toml_span::parse(&i18n).expect("Failed to parse i18n file");
let root = i18n.as_table().unwrap();
let mut languages = Vec::new();
let mut aliases = Vec::new();
let mut translations: BTreeMap<String, HashMap<String, String>> = BTreeMap::new();
for (k, v) in root.iter() {
match &k.name[..] {
"__default__" => {
const ERROR: &str = "i18n: __default__ must be [str]";
languages = Vec::from_iter(
v.as_array()
.expect(ERROR)
.iter()
.map(|lang| lang.as_str().expect(ERROR).to_string()),
);
}
"__alias__" => {
const ERROR: &str = "i18n: __alias__ must be str->str";
aliases.extend(v.as_table().expect(ERROR).iter().map(|(alias, lang)| {
(alias.to_string(), lang.as_str().expect(ERROR).to_string())
}));
}
_ => {
const ERROR: &str = "i18n: LocId must be str->str";
translations.insert(
k.name.to_string(),
HashMap::from_iter(
v.as_table().expect(ERROR).iter().map(|(k, v)| {
(k.name.to_string(), v.as_str().expect(ERROR).to_string())
}),
),
);
}
}
}
// Use EDIT_CFG_LANGUAGES for the language list if it is set.
if let cfg_languages = env_opt("EDIT_CFG_LANGUAGES")
&& !cfg_languages.is_empty()
{
languages = cfg_languages.split(',').map(|lang| lang.to_string()).collect();
}
// Ensure English as the fallback language is always present.
if !languages.iter().any(|l| l == "en") {
languages.push("en".to_string());
}
// Normalize language tags for use in source code (i.e. no "-").
for lang in &mut languages {
if lang.is_empty() {
panic!("i18n: empty language tag");
}
for c in unsafe { lang.as_bytes_mut() } {
*c = match *c {
b'A'..=b'Z' | b'a'..=b'z' => c.to_ascii_lowercase(),
b'-' => b'_',
b'_' => b'_',
_ => panic!("i18n: language tag \"{lang}\" must be [a-zA-Z_-]"),
}
}
}
// * Validate that there are no duplicate language tags.
// * Validate that all language tags are valid.
// * Merge the aliases into the languages list.
let mut languages_with_aliases: Vec<_>;
{
let mut specified = HashSet::new();
for lang in &languages {
if !specified.insert(lang.as_str()) {
panic!("i18n: duplicate language tag \"{lang}\"");
}
}
let mut available = HashSet::new();
for v in translations.values() {
for lang in v.keys() {
available.insert(lang.as_str());
}
}
let mut invalid = Vec::new();
for lang in &languages {
if !available.contains(lang.as_str()) {
invalid.push(lang.as_str());
}
}
if !invalid.is_empty() {
panic!("i18n: invalid language tags {invalid:?}");
}
languages_with_aliases = languages.iter().map(|l| (l.clone(), l.clone())).collect();
for (alias, lang) in aliases {
if specified.contains(lang.as_str()) && !specified.contains(alias.as_str()) {
languages_with_aliases.push((alias, lang));
}
}
}
// Sort languages by:
// - "en" first, because it'll map to `LangId::en == 0`, which is the default.
// - then alphabetically
// - but tags with subtags (e.g. "zh_hans") before those without (e.g. "zh").
{
fn sort(a: &String, b: &String) -> std::cmp::Ordering {
match (a == "en", b == "en") {
(true, false) => std::cmp::Ordering::Less,
(false, true) => std::cmp::Ordering::Greater,
_ => {
let (a0, a1) = a.split_once('_').unwrap_or((a, "xxxxxx"));
let (b0, b1) = b.split_once('_').unwrap_or((b, "xxxxxx"));
match a0.cmp(b0) {
std::cmp::Ordering::Equal => a1.cmp(b1),
ord => ord,
}
}
}
}
languages.sort_unstable_by(sort);
languages_with_aliases.sort_unstable_by(|a, b| sort(&a.0, &b.0));
}
// Generate the source code for the i18n data.
{
let out_dir = env_opt("OUT_DIR");
let mut out = std::fs::File::create(format!("{out_dir}/i18n_edit.rs")).unwrap();
let mut writer = std::io::BufWriter::new(&mut out);
_ = write!(
writer,
"// This file is generated by build.rs. Do not edit it manually.\n\
\n\
#[derive(Clone, Copy, PartialEq, Eq)]\n\
pub enum LocId {{\n",
);
for (k, _) in translations.iter() {
_ = writeln!(writer, " {k},");
}
_ = write!(
writer,
"}}\n\
\n\
#[allow(non_camel_case_types)]\n\
#[derive(Clone, Copy, PartialEq, Eq)]\n\
pub enum LangId {{\n",
);
for lang in &languages {
_ = writeln!(writer, " {lang},");
}
_ = write!(
writer,
"}}\n\
\n\
const LANGUAGES: &[(&str, LangId)] = &[\n"
);
for (alias, lang) in &languages_with_aliases {
_ = writeln!(writer, " ({alias:?}, LangId::{lang}),");
}
_ = write!(
writer,
"];\n\
\n\
const TRANSLATIONS: [[&str; {}]; {}] = [\n",
translations.len(),
languages.len(),
);
for lang in &languages {
_ = writeln!(writer, " [");
for (_, v) in translations.iter() {
const DEFAULT: &String = &String::new();
let v = v.get(lang).or_else(|| v.get("en")).unwrap_or(DEFAULT);
_ = writeln!(writer, " {v:?},");
}
_ = writeln!(writer, " ],");
}
_ = writeln!(writer, "];");
}
println!("cargo::rerun-if-env-changed=EDIT_CFG_LANGUAGES");
println!("cargo::rerun-if-changed={PATH}");
}
fn configure_icu(target_os: TargetOs) {
let icuuc_soname = env_opt("EDIT_CFG_ICUUC_SONAME");
let icui18n_soname = env_opt("EDIT_CFG_ICUI18N_SONAME");
let cpp_exports = env_opt("EDIT_CFG_ICU_CPP_EXPORTS");
@ -78,17 +285,23 @@ fn main() {
if renaming_auto_detect {
println!("cargo::rustc-cfg=edit_icu_renaming_auto_detect");
}
}
#[cfg(windows)]
if target_os == TargetOs::Windows {
winresource::WindowsResource::new()
.set_manifest_file("src/bin/edit/edit.exe.manifest")
.set("FileDescription", "Microsoft Edit")
.set("LegalCopyright", "© Microsoft Corporation. All rights reserved.")
.set_icon("assets/edit.ico")
.compile()
.unwrap();
#[cfg(windows)]
fn configure_windows_binary(target_os: TargetOs) {
if target_os != TargetOs::Windows {
return;
}
const PATH: &str = "src/bin/edit/edit.exe.manifest";
println!("cargo::rerun-if-changed={PATH}");
winresource::WindowsResource::new()
.set_manifest_file(PATH)
.set("FileDescription", "Microsoft Edit")
.set("LegalCopyright", "© Microsoft Corporation. All rights reserved.")
.set_icon("assets/edit.ico")
.compile()
.unwrap();
}
fn env_opt(name: &str) -> String {

807
i18n/edit.toml Normal file
View file

@ -0,0 +1,807 @@
__default__ = [
"en",
# --------
"de",
"es",
"fr",
"it",
"ja",
"ko",
"pt_br",
"ru",
"zh_hans",
"zh_hant",
]
[__alias__]
zh = "zh_hans"
# The keyboard key
[Ctrl]
en = "Ctrl"
de = "Strg"
es = "Ctrl"
fr = "Ctrl"
it = "Ctrl"
ja = "Ctrl"
ko = "Ctrl"
pt_br = "Ctrl"
ru = "Ctrl"
zh_hans = "Ctrl"
zh_hant = "Ctrl"
# The keyboard key
[Alt]
en = "Alt"
de = "Alt"
es = "Alt"
fr = "Alt"
it = "Alt"
ja = "Alt"
ko = "Alt"
pt_br = "Alt"
ru = "Alt"
zh_hans = "Alt"
zh_hant = "Alt"
# The keyboard key
[Shift]
en = "Shift"
de = "Umschalt"
es = "Mayús"
fr = "Maj"
it = "Maiusc"
ja = "Shift"
ko = "Shift"
pt_br = "Shift"
ru = "Shift"
zh_hans = "Shift"
zh_hant = "Shift"
# Used as a common dialog button
[Ok]
en = "Ok"
de = "OK"
es = "Aceptar"
fr = "OK"
it = "OK"
ja = "OK"
ko = "확인"
pt_br = "OK"
ru = "ОК"
zh_hans = "确定"
zh_hant = "確定"
# Used as a common dialog button
[Yes]
en = "Yes"
de = "Ja"
es = "Sí"
fr = "Oui"
it = "Sì"
ja = "はい"
ko = "예"
pt_br = "Sim"
ru = "Да"
zh_hans = "是"
zh_hant = "是"
# Used as a common dialog button
[No]
en = "No"
de = "Nein"
es = "No"
fr = "Non"
it = "No"
ja = "いいえ"
ko = "아니오"
pt_br = "Não"
ru = "Нет"
zh_hans = "否"
zh_hant = "否"
# Used as a common dialog button
[Cancel]
en = "Cancel"
de = "Abbrechen"
es = "Cancelar"
fr = "Annuler"
it = "Annulla"
ja = "キャンセル"
ko = "취소"
pt_br = "Cancelar"
ru = "Отмена"
zh_hans = "取消"
zh_hant = "取消"
# Used as a common dialog button
[Always]
en = "Always"
de = "Immer"
es = "Siempre"
fr = "Toujours"
it = "Sempre"
ja = "常に"
ko = "항상"
pt_br = "Sempre"
ru = "Всегда"
zh_hans = "总是"
zh_hant = "總是"
# A menu bar item
[File]
en = "File"
de = "Datei"
es = "Archivo"
fr = "Fichier"
it = "File"
ja = "ファイル"
ko = "파일"
pt_br = "Arquivo"
ru = "Файл"
zh_hans = "文件"
zh_hant = "檔案"
[FileNew]
en = "New File"
de = "Neue Datei"
es = "Nuevo archivo"
fr = "Nouveau fichier"
it = "Nuovo file"
ja = "新規ファイル"
ko = "새 파일"
pt_br = "Novo arquivo"
ru = "Новый файл"
zh_hans = "新建文件"
zh_hant = "新增檔案"
[FileOpen]
en = "Open File…"
de = "Datei öffnen…"
es = "Abrir archivo…"
fr = "Ouvrir un fichier…"
it = "Apri file…"
ja = "ファイルを開く…"
ko = "파일 열기…"
pt_br = "Abrir arquivo…"
ru = "Открыть файл…"
zh_hans = "打开文件…"
zh_hant = "開啟檔案…"
[FileSave]
en = "Save"
de = "Speichern"
es = "Guardar"
fr = "Enregistrer"
it = "Salva"
ja = "保存"
ko = "저장"
pt_br = "Salvar"
ru = "Сохранить"
zh_hans = "保存"
zh_hant = "儲存"
[FileSaveAs]
en = "Save As…"
de = "Speichern unter…"
es = "Guardar como…"
fr = "Enregistrer sous…"
it = "Salva come…"
ja = "名前を付けて保存…"
ko = "다른 이름으로 저장…"
pt_br = "Salvar como…"
ru = "Сохранить как…"
zh_hans = "另存为…"
zh_hant = "另存新檔…"
[FileClose]
en = "Close File"
de = "Datei schließen"
es = "Cerrar archivo"
fr = "Fermer le fichier"
it = "Chiudi file"
ja = "ファイルを閉じる"
ko = "파일 닫기"
pt_br = "Fechar arquivo"
ru = "Закрыть файл"
zh_hans = "关闭文件"
zh_hant = "關閉檔案"
[FileExit]
en = "Exit"
de = "Beenden"
es = "Salir"
fr = "Quitter"
it = "Esci"
ja = "終了"
ko = "종료"
pt_br = "Sair"
ru = "Выход"
zh_hans = "退出"
zh_hant = "退出"
[FileGoto]
en = "Go to Line:Column…"
de = "Gehe zu Zeile:Spalte…"
es = "Ir a línea:columna…"
fr = "Aller à la ligne:colonne…"
it = "Vai a riga:colonna…"
ja = "行:列へ移動…"
ko = "행:열로 이동…"
pt_br = "Ir para linha:coluna…"
ru = "Перейти к строке:столбцу…"
zh_hans = "转到行:列…"
zh_hant = "跳至行:列…"
# A menu bar item
[Edit]
en = "Edit"
de = "Bearbeiten"
es = "Editar"
fr = "Édition"
it = "Modifica"
ja = "編集"
ko = "편집"
pt_br = "Editar"
ru = "Правка"
zh_hans = "编辑"
zh_hant = "編輯"
[EditUndo]
en = "Undo"
de = "Rückgängig"
es = "Deshacer"
fr = "Annuler"
it = "Annulla"
ja = "元に戻す"
ko = "실행 취소"
pt_br = "Desfazer"
ru = "Отменить"
zh_hans = "撤销"
zh_hant = "復原"
[EditRedo]
en = "Redo"
de = "Wiederholen"
es = "Rehacer"
fr = "Rétablir"
it = "Ripeti"
ja = "やり直し"
ko = "다시 실행"
pt_br = "Refazer"
ru = "Повторить"
zh_hans = "重做"
zh_hant = "重做"
[EditCut]
en = "Cut"
de = "Ausschneiden"
es = "Cortar"
fr = "Couper"
it = "Taglia"
ja = "切り取り"
ko = "잘라내기"
pt_br = "Cortar"
ru = "Вырезать"
zh_hans = "剪切"
zh_hant = "剪下"
[EditCopy]
en = "Copy"
de = "Kopieren"
es = "Copiar"
fr = "Copier"
it = "Copia"
ja = "コピー"
ko = "복사"
pt_br = "Copiar"
ru = "Копировать"
zh_hans = "复制"
zh_hant = "複製"
[EditPaste]
en = "Paste"
de = "Einfügen"
es = "Pegar"
fr = "Coller"
it = "Incolla"
ja = "貼り付け"
ko = "붙여넣기"
pt_br = "Colar"
ru = "Вставить"
zh_hans = "粘贴"
zh_hant = "貼上"
[EditFind]
en = "Find"
de = "Suchen"
es = "Buscar"
fr = "Rechercher"
it = "Trova"
ja = "検索"
ko = "찾기"
pt_br = "Encontrar"
ru = "Найти"
zh_hans = "查找"
zh_hant = "尋找"
[EditReplace]
en = "Replace"
de = "Ersetzen"
es = "Reemplazar"
fr = "Remplacer"
it = "Sostituisci"
ja = "置換"
ko = "바꾸기"
pt_br = "Substituir"
ru = "Заменить"
zh_hans = "替换"
zh_hant = "取代"
[EditSelectAll]
en = "Select All"
de = "Alles auswählen"
es = "Seleccionar todo"
fr = "Tout sélectionner"
it = "Seleziona tutto"
ja = "すべて選択"
ko = "모두 선택"
pt_br = "Selecionar tudo"
ru = "Выделить всё"
zh_hans = "全选"
zh_hant = "全選"
# A menu bar item
[View]
en = "View"
de = "Ansicht"
es = "Ver"
fr = "Affichage"
it = "Visualizza"
ja = "表示"
ko = "보기"
pt_br = "Exibir"
ru = "Вид"
zh_hans = "视图"
zh_hant = "檢視"
[ViewFocusStatusbar]
en = "Focus Statusbar"
de = "Statusleiste fokussieren"
es = "Enfocar barra de estado"
fr = "Activer la barre détat"
it = "Attiva barra di stato"
ja = "ステータスバーにフォーカス"
ko = "상태 표시줄로 포커스 이동"
pt_br = "Focar barra de status"
ru = "Фокус на строку состояния"
zh_hans = "聚焦状态栏"
zh_hant = "聚焦狀態列"
[ViewWordWrap]
en = "Word Wrap"
de = "Zeilenumbruch"
es = "Ajuste de línea"
fr = "Retour automatique à la ligne"
it = "A capo automatico"
ja = "折り返し"
ko = "자동 줄 바꿈"
pt_br = "Quebra de linha"
ru = "Перенос слов"
zh_hans = "自动换行"
zh_hant = "自動換行"
[ViewGoToFile]
en = "Go to File…"
de = "Gehe zu Datei…"
es = "Ir a archivo…"
fr = "Aller au fichier…"
it = "Vai al file…"
ja = "ファイルへ移動…"
ko = "파일로 이동…"
pt_br = "Ir para arquivo…"
ru = "Перейти к файлу…"
zh_hans = "转到文件…"
zh_hant = "跳至檔案…"
# A menu bar item
[Help]
en = "Help"
de = "Hilfe"
es = "Ayuda"
fr = "Aide"
it = "Aiuto"
ja = "ヘルプ"
ko = "도움말"
pt_br = "Ajuda"
ru = "Помощь"
zh_hans = "帮助"
zh_hant = "幫助"
[HelpAbout]
en = "About"
de = "Über"
es = "Acerca de"
fr = "À propos"
it = "Informazioni"
ja = "情報"
ko = "정보"
pt_br = "Sobre"
ru = "О программе"
zh_hans = "关于"
zh_hant = "關於"
[UnsavedChangesDialogTitle]
en = "Unsaved Changes"
de = "Ungespeicherte Änderungen"
es = "Cambios sin guardar"
fr = "Modifications non enregistrées"
it = "Modifiche non salvate"
ja = "未保存の変更"
ko = "저장되지 않은 변경 사항"
pt_br = "Alterações não salvas"
ru = "Несохраненные изменения"
zh_hans = "未保存的更改"
zh_hant = "未儲存的變更"
[UnsavedChangesDialogDescription]
en = "Do you want to save the changes you made?"
de = "Möchten Sie die vorgenommenen Änderungen speichern?"
es = "¿Desea guardar los cambios realizados?"
fr = "Voulez-vous enregistrer les modifications apportées ?"
it = "Vuoi salvare le modifiche apportate?"
ja = "変更内容を保存しますか?"
ko = "변경한 내용을 저장하시겠습니까?"
pt_br = "Deseja salvar as alterações feitas?"
ru = "Вы хотите сохранить внесённые изменения?"
zh_hans = "您要保存所做的更改吗?"
zh_hant = "您要保存所做的變更嗎?"
[UnsavedChangesDialogYes]
en = "Save"
de = "Speichern"
es = "Guardar"
fr = "Enregistrer"
it = "Salva"
ja = "保存する"
ko = "저장"
pt_br = "Salvar"
ru = "Сохранить"
zh_hans = "保存"
zh_hant = "儲存"
[UnsavedChangesDialogNo]
en = "Don't Save"
de = "Nicht speichern"
es = "No guardar"
fr = "Ne pas enregistrer"
it = "Non salvare"
ja = "保存しない"
ko = "저장 안 함"
pt_br = "Não salvar"
ru = "Не сохранять"
zh_hans = "不保存"
zh_hant = "不儲存"
[AboutDialogTitle]
en = "About"
de = "Über"
es = "Acerca de"
fr = "À propos"
it = "Informazioni"
ja = "情報"
ko = "정보"
pt_br = "Sobre"
ru = "О программе"
zh_hans = "关于"
zh_hant = "關於"
[AboutDialogVersion]
en = "Version: "
de = "Version: "
es = "Versión: "
fr = "Version : "
it = "Versione: "
ja = "バージョン: "
ko = "버전: "
pt_br = "Versão: "
ru = "Версия: "
zh_hans = "版本: "
zh_hant = "版本: "
# Shown when the clipboard size exceeds the limit for OSC 52
[LargeClipboardWarningLine1]
en = "Text you copy is shared with the terminal clipboard."
de = "Der kopierte Text wird mit der Terminal-Zwischenablage geteilt."
es = "El texto que copies se comparte con el portapapeles del terminal."
fr = "Le texte que vous copiez est partagé avec le presse-papiers du terminal."
it = "Il testo copiato viene condiviso con gli appunti del terminale."
ja = "コピーしたテキストはターミナルのクリップボードと共有されます。"
ko = "복사한 텍스트가 터미널 클립보드와 공유됩니다."
pt_br = "O texto copiado é compartilhado com a área de transferência do terminal."
ru = "Скопированный текст передаётся в буфер обмена терминала."
zh_hans = "你复制的文本将共享到终端剪贴板。"
zh_hant = "您複製的文字將會與終端機剪貼簿分享。"
# Shown when the clipboard size exceeds the limit for OSC 52
[LargeClipboardWarningLine2]
en = "You copied {size} which may take a long time to share."
de = "Sie haben {size} kopiert. Das Weitergeben könnte länger dauern."
es = "Copiaste {size}, lo que puede tardar en compartirse."
fr = "Vous avez copié {size}, ce qui peut être long à partager."
it = "Hai copiato {size}, potrebbe richiedere molto tempo per condividerlo."
ja = "{size} をコピーしました。共有に時間がかかる可能性があります。"
ko = "{size}를 복사했습니다. 공유하는 데 시간이 오래 걸릴 수 있습니다."
pt_br = "Você copiou {size}, o que pode demorar para compartilhar."
ru = "Вы скопировали {size}; передача может занять много времени."
zh_hans = "你复制了 {size},共享可能需要较长时间。"
zh_hant = "您已複製 {size},共享可能需要較長時間。"
# Shown when the clipboard size exceeds the limit for OSC 52
[LargeClipboardWarningLine3]
en = "Do you want to send it anyway?"
de = "Möchten Sie es trotzdem senden?"
es = "¿Desea enviarlo de todas formas?"
fr = "Voulez-vous quand même lenvoyer ?"
it = "Vuoi inviarlo comunque?"
ja = "それでも送信しますか?"
ko = "그래도 전송하시겠습니까?"
pt_br = "Deseja enviar mesmo assim?"
ru = "Отправить в любом случае?"
zh_hans = "仍要发送吗?"
zh_hant = "仍要傳送嗎?"
# As an alternative to LargeClipboardWarningLine2 and 3
[SuperLargeClipboardWarning]
en = "The text you copied is too large to be shared."
de = "Der kopierte Text ist zu groß, um geteilt zu werden."
es = "El texto que copiaste es demasiado grande para compartirse."
fr = "Le texte que vous avez copié est trop volumineux pour être partagé."
it = "Il testo copiato è troppo grande per essere condiviso."
ja = "コピーしたテキストは大きすぎて共有できません。"
ko = "복사한 텍스트가 너무 커서 공유할 수 없습니다."
pt_br = "O texto copiado é grande demais para ser compartilhado."
ru = "Скопированный текст слишком велик для передачи."
zh_hans = "你复制的文本过大,无法共享。"
zh_hant = "您複製的文字過大,無法分享。"
[WarningDialogTitle]
en = "Warning"
de = "Warnung"
es = "Advertencia"
fr = "Avertissement"
it = "Avviso"
ja = "警告"
ko = "경고"
pt_br = "Aviso"
ru = "Предупреждение"
zh_hans = "警告"
zh_hant = "警告"
[ErrorDialogTitle]
en = "Error"
de = "Fehler"
es = "Error"
fr = "Erreur"
it = "Errore"
ja = "エラー"
ko = "오류"
pt_br = "Erro"
ru = "Ошибка"
zh_hans = "错误"
zh_hant = "錯誤"
[ErrorIcuMissing]
en = "This operation requires the ICU library"
de = "Diese Operation erfordert die ICU-Bibliothek"
es = "Esta operación requiere la biblioteca ICU"
fr = "Cette opération nécessite la bibliothèque ICU"
it = "Questa operazione richiede la libreria ICU"
ja = "この操作にはICUライブラリが必要です"
ko = "이 작업에는 ICU 라이브러리가 필요합니다"
pt_br = "Esta operação requer a biblioteca ICU"
ru = "Эта операция требует наличия библиотеки ICU"
zh_hans = "此操作需要 ICU 库"
zh_hant = "此操作需要 ICU 庫"
# For input field
[SearchNeedleLabel]
en = "Find:"
de = "Suchen:"
es = "Buscar:"
fr = "Rechercher :"
it = "Trova:"
ja = "検索:"
ko = "찾기:"
pt_br = "Encontrar:"
ru = "Найти:"
zh_hans = "查找:"
zh_hant = "尋找:"
# For input field
[SearchReplacementLabel]
en = "Replace:"
de = "Ersetzen:"
es = "Reemplazar:"
fr = "Remplacer :"
it = "Sostituire:"
ja = "置換:"
ko = "바꾸기:"
pt_br = "Substituir:"
ru = "Замена:"
zh_hans = "替换:"
zh_hant = "替換:"
# Toggle
[SearchMatchCase]
en = "Match Case"
de = "Groß/Klein"
es = "May/Min"
fr = "Resp. la casse"
it = "Maius/minus"
ja = "大/小文字を区別"
ko = "대소문자"
pt_br = "Maius/minus"
ru = "Регистр"
zh_hans = "区分大小写"
zh_hant = "區分大小寫"
# Toggle
[SearchWholeWord]
en = "Whole Word"
de = "Ganzes Wort"
es = "Palabra"
fr = "Mot entier"
it = "Parola"
ja = "単語全体"
ko = "전체 단어"
pt_br = "Palavra"
ru = "Слово"
zh_hans = "全字匹配"
zh_hant = "全字匹配"
# Toggle
[SearchUseRegex]
en = "Use Regex"
de = "RegEx"
es = "RegEx"
fr = "RegEx"
it = "RegEx"
ja = "正規表現"
ko = "정규식"
pt_br = "RegEx"
ru = "RegEx"
zh_hans = "正则"
zh_hant = "正則"
# Button
[SearchReplaceAll]
en = "Replace All"
de = "Alle ersetzen"
es = "Reemplazar todo"
fr = "Remplacer tout"
it = "Sostituisci tutto"
ja = "すべて置換"
ko = "모두 바꾸기"
pt_br = "Substituir tudo"
ru = "Заменить все"
zh_hans = "全部替换"
zh_hant = "全部取代"
# Button
[SearchClose]
en = "Close"
de = "Schließen"
es = "Cerrar"
fr = "Fermer"
it = "Chiudi"
ja = "閉じる"
ko = "닫기"
pt_br = "Fechar"
ru = "Закрыть"
zh_hans = "关闭"
zh_hant = "關閉"
[EncodingReopen]
en = "Reopen with encoding…"
de = "Mit Kodierung erneut öffnen…"
es = "Reabrir con codificación…"
fr = "Rouvrir avec un encodage différent…"
it = "Riapri con codifica…"
ja = "指定エンコーディングで再度開く…"
ko = "인코딩으로 다시 열기…"
pt_br = "Reabrir com codificação…"
ru = "Открыть снова с кодировкой…"
zh_hans = "使用编码重新打开…"
zh_hant = "使用編碼重新打開…"
[EncodingConvert]
en = "Convert to encoding…"
de = "In Kodierung konvertieren…"
es = "Convertir a otra codificación…"
fr = "Convertir vers lencodage…"
it = "Converti in codifica…"
ja = "エンコーディングを変換…"
ko = "인코딩으로 변환…"
pt_br = "Converter para codificação…"
ru = "Преобразовать в кодировку…"
zh_hans = "转换为编码…"
zh_hant = "轉換為編碼…"
[IndentationTabs]
en = "Tabs"
de = "Tabs"
es = "Tabulaciones"
fr = "Tabulations"
it = "Tabulazioni"
ja = "タブ"
ko = "탭"
pt_br = "Tabulações"
ru = "Табы"
zh_hans = "制表符"
zh_hant = "製表符"
[IndentationSpaces]
en = "Spaces"
de = "Leerzeichen"
es = "Espacios"
fr = "Espaces"
it = "Spazi"
ja = "スペース"
ko = "공백"
pt_br = "Espaços"
ru = "Пробелы"
zh_hans = "空格"
zh_hant = "空格"
[SaveAsDialogPathLabel]
en = "Folder:"
de = "Ordner:"
es = "Carpeta:"
fr = "Dossier :"
it = "Cartella:"
ja = "フォルダ:"
ko = "폴더:"
pt_br = "Pasta:"
ru = "Папка:"
zh_hans = "文件夹:"
zh_hant = "資料夾:"
[SaveAsDialogNameLabel]
en = "File name:"
de = "Dateiname:"
es = "Nombre de archivo:"
fr = "Nom du fichier :"
it = "Nome del file:"
ja = "ファイル名:"
ko = "파일 이름:"
pt_br = "Nome do arquivo:"
ru = "Имя файла:"
zh_hans = "文件名:"
zh_hant = "檔案名稱:"
[FileOverwriteWarning]
en = "Confirm Save As"
de = "Speichern unter bestätigen"
es = "Confirmar Guardar como"
fr = "Confirmer Enregistrer sous"
it = "Conferma Salva con nome"
ja = "名前を付けて保存の確認"
ko = "다른 이름으로 저장 확인"
pt_br = "Confirmar Salvar como"
ru = "Подтвердите «Сохранить как…»"
zh_hans = "确认另存为"
zh_hant = "確認另存新檔"
[FileOverwriteWarningDescription]
en = "File already exists. Do you want to overwrite it?"
de = "Datei existiert bereits. Möchten Sie sie überschreiben?"
es = "El archivo ya existe. ¿Desea sobrescribirlo?"
fr = "Le fichier existe déjà. Voulez-vous lécraser ?"
it = "Il file esiste già. Vuoi sovrascriverlo?"
ja = "ファイルは既に存在します。上書きしますか?"
ko = "파일이 이미 존재합니다. 덮어쓰시겠습니까?"
pt_br = "O arquivo já existe. Deseja sobrescrevê-lo?"
ru = "Файл уже существует. Перезаписать?"
zh_hans = "文件已存在。要覆盖它吗?"
zh_hant = "檔案已存在。要覆蓋它嗎?"

View file

@ -5,990 +5,17 @@ use edit::arena::scratch_arena;
use edit::helpers::AsciiStringHelpers;
use edit::sys;
#[derive(Clone, Copy, PartialEq, Eq)]
pub enum LocId {
Ctrl,
Alt,
Shift,
Ok,
Yes,
No,
Cancel,
Always,
// File menu
File,
FileNew,
FileOpen,
FileSave,
FileSaveAs,
FileClose,
FileExit,
FileGoto,
// Edit menu
Edit,
EditUndo,
EditRedo,
EditCut,
EditCopy,
EditPaste,
EditFind,
EditReplace,
EditSelectAll,
// View menu
View,
ViewFocusStatusbar,
ViewWordWrap,
ViewGoToFile,
// Help menu
Help,
HelpAbout,
// Exit dialog
UnsavedChangesDialogTitle,
UnsavedChangesDialogDescription,
UnsavedChangesDialogYes,
UnsavedChangesDialogNo,
// About dialog
AboutDialogTitle,
AboutDialogVersion,
// Shown when the clipboard size exceeds the limit for OSC 52
LargeClipboardWarningLine1,
LargeClipboardWarningLine2,
LargeClipboardWarningLine3,
SuperLargeClipboardWarning,
// Warning dialog
WarningDialogTitle,
// Error dialog
ErrorDialogTitle,
ErrorIcuMissing,
SearchNeedleLabel,
SearchReplacementLabel,
SearchMatchCase,
SearchWholeWord,
SearchUseRegex,
SearchReplaceAll,
SearchClose,
EncodingReopen,
EncodingConvert,
IndentationTabs,
IndentationSpaces,
SaveAsDialogPathLabel,
SaveAsDialogNameLabel,
FileOverwriteWarning,
FileOverwriteWarningDescription,
Count,
}
#[allow(non_camel_case_types)]
#[derive(Clone, Copy, PartialEq, Eq)]
enum LangId {
// Base language. It's always the first one.
en,
// Other languages. Sorted alphabetically.
de,
es,
fr,
it,
ja,
ko,
pt_br,
ru,
zh_hans,
zh_hant,
Count,
}
#[rustfmt::skip]
const S_LANG_LUT: [[&str; LangId::Count as usize]; LocId::Count as usize] = [
// Ctrl (the keyboard key)
[
/* en */ "Ctrl",
/* de */ "Strg",
/* es */ "Ctrl",
/* fr */ "Ctrl",
/* it */ "Ctrl",
/* ja */ "Ctrl",
/* ko */ "Ctrl",
/* pt_br */ "Ctrl",
/* ru */ "Ctrl",
/* zh_hans */ "Ctrl",
/* zh_hant */ "Ctrl",
],
// Alt (the keyboard key)
[
/* en */ "Alt",
/* de */ "Alt",
/* es */ "Alt",
/* fr */ "Alt",
/* it */ "Alt",
/* ja */ "Alt",
/* ko */ "Alt",
/* pt_br */ "Alt",
/* ru */ "Alt",
/* zh_hans */ "Alt",
/* zh_hant */ "Alt",
],
// Shift (the keyboard key)
[
/* en */ "Shift",
/* de */ "Umschalt",
/* es */ "Mayús",
/* fr */ "Maj",
/* it */ "Maiusc",
/* ja */ "Shift",
/* ko */ "Shift",
/* pt_br */ "Shift",
/* ru */ "Shift",
/* zh_hans */ "Shift",
/* zh_hant */ "Shift",
],
// Ok (used as a common dialog button)
[
/* en */ "Ok",
/* de */ "OK",
/* es */ "Aceptar",
/* fr */ "OK",
/* it */ "OK",
/* ja */ "OK",
/* ko */ "확인",
/* pt_br */ "OK",
/* ru */ "ОК",
/* zh_hans */ "确定",
/* zh_hant */ "確定",
],
// Yes (used as a common dialog button)
[
/* en */ "Yes",
/* de */ "Ja",
/* es */ "",
/* fr */ "Oui",
/* it */ "",
/* ja */ "はい",
/* ko */ "",
/* pt_br */ "Sim",
/* ru */ "Да",
/* zh_hans */ "",
/* zh_hant */ "",
],
// No (used as a common dialog button)
[
/* en */ "No",
/* de */ "Nein",
/* es */ "No",
/* fr */ "Non",
/* it */ "No",
/* ja */ "いいえ",
/* ko */ "아니오",
/* pt_br */ "Não",
/* ru */ "Нет",
/* zh_hans */ "",
/* zh_hant */ "",
],
// Cancel (used as a common dialog button)
[
/* en */ "Cancel",
/* de */ "Abbrechen",
/* es */ "Cancelar",
/* fr */ "Annuler",
/* it */ "Annulla",
/* ja */ "キャンセル",
/* ko */ "취소",
/* pt_br */ "Cancelar",
/* ru */ "Отмена",
/* zh_hans */ "取消",
/* zh_hant */ "取消",
],
// Always (used as a common dialog button)
[
/* en */ "Always",
/* de */ "Immer",
/* es */ "Siempre",
/* fr */ "Toujours",
/* it */ "Sempre",
/* ja */ "常に",
/* ko */ "항상",
/* pt_br */ "Sempre",
/* ru */ "Всегда",
/* zh_hans */ "总是",
/* zh_hant */ "總是",
],
// File (a menu bar item)
[
/* en */ "File",
/* de */ "Datei",
/* es */ "Archivo",
/* fr */ "Fichier",
/* it */ "File",
/* ja */ "ファイル",
/* ko */ "파일",
/* pt_br */ "Arquivo",
/* ru */ "Файл",
/* zh_hans */ "文件",
/* zh_hant */ "檔案",
],
// FileNew
[
/* en */ "New File",
/* de */ "Neue Datei",
/* es */ "Nuevo archivo",
/* fr */ "Nouveau fichier",
/* it */ "Nuovo file",
/* ja */ "新規ファイル",
/* ko */ "새 파일",
/* pt_br */ "Novo arquivo",
/* ru */ "Новый файл",
/* zh_hans */ "新建文件",
/* zh_hant */ "新增檔案",
],
// FileOpen
[
/* en */ "Open File…",
/* de */ "Datei öffnen…",
/* es */ "Abrir archivo…",
/* fr */ "Ouvrir un fichier…",
/* it */ "Apri file…",
/* ja */ "ファイルを開く…",
/* ko */ "파일 열기…",
/* pt_br */ "Abrir arquivo…",
/* ru */ "Открыть файл…",
/* zh_hans */ "打开文件…",
/* zh_hant */ "開啟檔案…",
],
// FileSave
[
/* en */ "Save",
/* de */ "Speichern",
/* es */ "Guardar",
/* fr */ "Enregistrer",
/* it */ "Salva",
/* ja */ "保存",
/* ko */ "저장",
/* pt_br */ "Salvar",
/* ru */ "Сохранить",
/* zh_hans */ "保存",
/* zh_hant */ "儲存",
],
// FileSaveAs
[
/* en */ "Save As…",
/* de */ "Speichern unter…",
/* es */ "Guardar como…",
/* fr */ "Enregistrer sous…",
/* it */ "Salva come…",
/* ja */ "名前を付けて保存…",
/* ko */ "다른 이름으로 저장…",
/* pt_br */ "Salvar como…",
/* ru */ "Сохранить как…",
/* zh_hans */ "另存为…",
/* zh_hant */ "另存新檔…",
],
// FileClose
[
/* en */ "Close File",
/* de */ "Datei schließen",
/* es */ "Cerrar archivo",
/* fr */ "Fermer le fichier",
/* it */ "Chiudi file",
/* ja */ "ファイルを閉じる",
/* ko */ "파일 닫기",
/* pt_br */ "Fechar arquivo",
/* ru */ "Закрыть файл",
/* zh_hans */ "关闭文件",
/* zh_hant */ "關閉檔案",
],
// FileExit
[
/* en */ "Exit",
/* de */ "Beenden",
/* es */ "Salir",
/* fr */ "Quitter",
/* it */ "Esci",
/* ja */ "終了",
/* ko */ "종료",
/* pt_br */ "Sair",
/* ru */ "Выход",
/* zh_hans */ "退出",
/* zh_hant */ "退出",
],
// FileGoto
[
/* en */ "Go to Line:Column…",
/* de */ "Gehe zu Zeile:Spalte…",
/* es */ "Ir a línea:columna…",
/* fr */ "Aller à la ligne:colonne…",
/* it */ "Vai a riga:colonna…",
/* ja */ "行:列へ移動…",
/* ko */ "행:열로 이동…",
/* pt_br */ "Ir para linha:coluna…",
/* ru */ "Перейти к строке:столбцу…",
/* zh_hans */ "转到行:列…",
/* zh_hant */ "跳至行:列…",
],
// Edit (a menu bar item)
[
/* en */ "Edit",
/* de */ "Bearbeiten",
/* es */ "Editar",
/* fr */ "Édition",
/* it */ "Modifica",
/* ja */ "編集",
/* ko */ "편집",
/* pt_br */ "Editar",
/* ru */ "Правка",
/* zh_hans */ "编辑",
/* zh_hant */ "編輯",
],
// EditUndo
[
/* en */ "Undo",
/* de */ "Rückgängig",
/* es */ "Deshacer",
/* fr */ "Annuler",
/* it */ "Annulla",
/* ja */ "元に戻す",
/* ko */ "실행 취소",
/* pt_br */ "Desfazer",
/* ru */ "Отменить",
/* zh_hans */ "撤销",
/* zh_hant */ "復原",
],
// EditRedo
[
/* en */ "Redo",
/* de */ "Wiederholen",
/* es */ "Rehacer",
/* fr */ "Rétablir",
/* it */ "Ripeti",
/* ja */ "やり直し",
/* ko */ "다시 실행",
/* pt_br */ "Refazer",
/* ru */ "Повторить",
/* zh_hans */ "重做",
/* zh_hant */ "重做",
],
// EditCut
[
/* en */ "Cut",
/* de */ "Ausschneiden",
/* es */ "Cortar",
/* fr */ "Couper",
/* it */ "Taglia",
/* ja */ "切り取り",
/* ko */ "잘라내기",
/* pt_br */ "Cortar",
/* ru */ "Вырезать",
/* zh_hans */ "剪切",
/* zh_hant */ "剪下",
],
// EditCopy
[
/* en */ "Copy",
/* de */ "Kopieren",
/* es */ "Copiar",
/* fr */ "Copier",
/* it */ "Copia",
/* ja */ "コピー",
/* ko */ "복사",
/* pt_br */ "Copiar",
/* ru */ "Копировать",
/* zh_hans */ "复制",
/* zh_hant */ "複製",
],
// EditPaste
[
/* en */ "Paste",
/* de */ "Einfügen",
/* es */ "Pegar",
/* fr */ "Coller",
/* it */ "Incolla",
/* ja */ "貼り付け",
/* ko */ "붙여넣기",
/* pt_br */ "Colar",
/* ru */ "Вставить",
/* zh_hans */ "粘贴",
/* zh_hant */ "貼上",
],
// EditFind
[
/* en */ "Find",
/* de */ "Suchen",
/* es */ "Buscar",
/* fr */ "Rechercher",
/* it */ "Trova",
/* ja */ "検索",
/* ko */ "찾기",
/* pt_br */ "Encontrar",
/* ru */ "Найти",
/* zh_hans */ "查找",
/* zh_hant */ "尋找",
],
// EditReplace
[
/* en */ "Replace",
/* de */ "Ersetzen",
/* es */ "Reemplazar",
/* fr */ "Remplacer",
/* it */ "Sostituisci",
/* ja */ "置換",
/* ko */ "바꾸기",
/* pt_br */ "Substituir",
/* ru */ "Заменить",
/* zh_hans */ "替换",
/* zh_hant */ "取代",
],
// EditSelectAll
[
/* en */ "Select All",
/* de */ "Alles auswählen",
/* es */ "Seleccionar todo",
/* fr */ "Tout sélectionner",
/* it */ "Seleziona tutto",
/* ja */ "すべて選択",
/* ko */ "모두 선택",
/* pt_br */ "Selecionar tudo",
/* ru */ "Выделить всё",
/* zh_hans */ "全选",
/* zh_hant */ "全選"
],
// View (a menu bar item)
[
/* en */ "View",
/* de */ "Ansicht",
/* es */ "Ver",
/* fr */ "Affichage",
/* it */ "Visualizza",
/* ja */ "表示",
/* ko */ "보기",
/* pt_br */ "Exibir",
/* ru */ "Вид",
/* zh_hans */ "视图",
/* zh_hant */ "檢視",
],
// ViewFocusStatusbar
[
/* en */ "Focus Statusbar",
/* de */ "Statusleiste fokussieren",
/* es */ "Enfocar barra de estado",
/* fr */ "Activer la barre détat",
/* it */ "Attiva barra di stato",
/* ja */ "ステータスバーにフォーカス",
/* ko */ "상태 표시줄로 포커스 이동",
/* pt_br */ "Focar barra de status",
/* ru */ "Фокус на строку состояния",
/* zh_hans */ "聚焦状态栏",
/* zh_hant */ "聚焦狀態列",
],
// ViewWordWrap
[
/* en */ "Word Wrap",
/* de */ "Zeilenumbruch",
/* es */ "Ajuste de línea",
/* fr */ "Retour automatique à la ligne",
/* it */ "A capo automatico",
/* ja */ "折り返し",
/* ko */ "자동 줄 바꿈",
/* pt_br */ "Quebra de linha",
/* ru */ "Перенос слов",
/* zh_hans */ "自动换行",
/* zh_hant */ "自動換行",
],
// ViewGoToFile
[
/* en */ "Go to File…",
/* de */ "Gehe zu Datei…",
/* es */ "Ir a archivo…",
/* fr */ "Aller au fichier…",
/* it */ "Vai al file…",
/* ja */ "ファイルへ移動…",
/* ko */ "파일로 이동…",
/* pt_br */ "Ir para arquivo…",
/* ru */ "Перейти к файлу…",
/* zh_hans */ "转到文件…",
/* zh_hant */ "跳至檔案…",
],
// Help (a menu bar item)
[
/* en */ "Help",
/* de */ "Hilfe",
/* es */ "Ayuda",
/* fr */ "Aide",
/* it */ "Aiuto",
/* ja */ "ヘルプ",
/* ko */ "도움말",
/* pt_br */ "Ajuda",
/* ru */ "Помощь",
/* zh_hans */ "帮助",
/* zh_hant */ "幫助",
],
// HelpAbout
[
/* en */ "About",
/* de */ "Über",
/* es */ "Acerca de",
/* fr */ "À propos",
/* it */ "Informazioni",
/* ja */ "情報",
/* ko */ "정보",
/* pt_br */ "Sobre",
/* ru */ "О программе",
/* zh_hans */ "关于",
/* zh_hant */ "關於",
],
// UnsavedChangesDialogTitle
[
/* en */ "Unsaved Changes",
/* de */ "Ungespeicherte Änderungen",
/* es */ "Cambios sin guardar",
/* fr */ "Modifications non enregistrées",
/* it */ "Modifiche non salvate",
/* ja */ "未保存の変更",
/* ko */ "저장되지 않은 변경 사항",
/* pt_br */ "Alterações não salvas",
/* ru */ "Несохраненные изменения",
/* zh_hans */ "未保存的更改",
/* zh_hant */ "未儲存的變更",
],
// UnsavedChangesDialogDescription
[
/* en */ "Do you want to save the changes you made?",
/* de */ "Möchten Sie die vorgenommenen Änderungen speichern?",
/* es */ "¿Desea guardar los cambios realizados?",
/* fr */ "Voulez-vous enregistrer les modifications apportées ?",
/* it */ "Vuoi salvare le modifiche apportate?",
/* ja */ "変更内容を保存しますか?",
/* ko */ "변경한 내용을 저장하시겠습니까?",
/* pt_br */ "Deseja salvar as alterações feitas?",
/* ru */ "Вы хотите сохранить внесённые изменения?",
/* zh_hans */ "您要保存所做的更改吗?",
/* zh_hant */ "您要保存所做的變更嗎?",
],
// UnsavedChangesDialogYes
[
/* en */ "Save",
/* de */ "Speichern",
/* es */ "Guardar",
/* fr */ "Enregistrer",
/* it */ "Salva",
/* ja */ "保存する",
/* ko */ "저장",
/* pt_br */ "Salvar",
/* ru */ "Сохранить",
/* zh_hans */ "保存",
/* zh_hant */ "儲存",
],
// UnsavedChangesDialogNo
[
/* en */ "Don't Save",
/* de */ "Nicht speichern",
/* es */ "No guardar",
/* fr */ "Ne pas enregistrer",
/* it */ "Non salvare",
/* ja */ "保存しない",
/* ko */ "저장 안 함",
/* pt_br */ "Não salvar",
/* ru */ "Не сохранять",
/* zh_hans */ "不保存",
/* zh_hant */ "不儲存",
],
// AboutDialogTitle
[
/* en */ "About",
/* de */ "Über",
/* es */ "Acerca de",
/* fr */ "À propos",
/* it */ "Informazioni",
/* ja */ "情報",
/* ko */ "정보",
/* pt_br */ "Sobre",
/* ru */ "О программе",
/* zh_hans */ "关于",
/* zh_hant */ "關於",
],
// AboutDialogVersion
[
/* en */ "Version: ",
/* de */ "Version: ",
/* es */ "Versión: ",
/* fr */ "Version : ",
/* it */ "Versione: ",
/* ja */ "バージョン: ",
/* ko */ "버전: ",
/* pt_br */ "Versão: ",
/* ru */ "Версия: ",
/* zh_hans */ "版本: ",
/* zh_hant */ "版本: ",
],
// Shown when the clipboard size exceeds the limit for OSC 52
// LargeClipboardWarningLine1
[
/* en */ "Text you copy is shared with the terminal clipboard.",
/* de */ "Der kopierte Text wird mit der Terminal-Zwischenablage geteilt.",
/* es */ "El texto que copies se comparte con el portapapeles del terminal.",
/* fr */ "Le texte que vous copiez est partagé avec le presse-papiers du terminal.",
/* it */ "Il testo copiato viene condiviso con gli appunti del terminale.",
/* ja */ "コピーしたテキストはターミナルのクリップボードと共有されます。",
/* ko */ "복사한 텍스트가 터미널 클립보드와 공유됩니다.",
/* pt_br */ "O texto copiado é compartilhado com a área de transferência do terminal.",
/* ru */ "Скопированный текст передаётся в буфер обмена терминала.",
/* zh_hans */ "你复制的文本将共享到终端剪贴板。",
/* zh_hant */ "您複製的文字將會與終端機剪貼簿分享。",
],
// LargeClipboardWarningLine2
[
/* en */ "You copied {size} which may take a long time to share.",
/* de */ "Sie haben {size} kopiert. Das Weitergeben könnte länger dauern.",
/* es */ "Copiaste {size}, lo que puede tardar en compartirse.",
/* fr */ "Vous avez copié {size}, ce qui peut être long à partager.",
/* it */ "Hai copiato {size}, potrebbe richiedere molto tempo per condividerlo.",
/* ja */ "{size} をコピーしました。共有に時間がかかる可能性があります。",
/* ko */ "{size}를 복사했습니다. 공유하는 데 시간이 오래 걸릴 수 있습니다.",
/* pt_br */ "Você copiou {size}, o que pode demorar para compartilhar.",
/* ru */ "Вы скопировали {size}; передача может занять много времени.",
/* zh_hans */ "你复制了 {size},共享可能需要较长时间。",
/* zh_hant */ "您已複製 {size},共享可能需要較長時間。",
],
// LargeClipboardWarningLine3
[
/* en */ "Do you want to send it anyway?",
/* de */ "Möchten Sie es trotzdem senden?",
/* es */ "¿Desea enviarlo de todas formas?",
/* fr */ "Voulez-vous quand même lenvoyer ?",
/* it */ "Vuoi inviarlo comunque?",
/* ja */ "それでも送信しますか?",
/* ko */ "그래도 전송하시겠습니까?",
/* pt_br */ "Deseja enviar mesmo assim?",
/* ru */ "Отправить в любом случае?",
/* zh_hans */ "仍要发送吗?",
/* zh_hant */ "仍要傳送嗎?",
],
// SuperLargeClipboardWarning (as an alternative to LargeClipboardWarningLine2 and 3)
[
/* en */ "The text you copied is too large to be shared.",
/* de */ "Der kopierte Text ist zu groß, um geteilt zu werden.",
/* es */ "El texto que copiaste es demasiado grande para compartirse.",
/* fr */ "Le texte que vous avez copié est trop volumineux pour être partagé.",
/* it */ "Il testo copiato è troppo grande per essere condiviso.",
/* ja */ "コピーしたテキストは大きすぎて共有できません。",
/* ko */ "복사한 텍스트가 너무 커서 공유할 수 없습니다.",
/* pt_br */ "O texto copiado é grande demais para ser compartilhado.",
/* ru */ "Скопированный текст слишком велик для передачи.",
/* zh_hans */ "你复制的文本过大,无法共享。",
/* zh_hant */ "您複製的文字過大,無法分享。",
],
// WarningDialogTitle
[
/* en */ "Warning",
/* de */ "Warnung",
/* es */ "Advertencia",
/* fr */ "Avertissement",
/* it */ "Avviso",
/* ja */ "警告",
/* ko */ "경고",
/* pt_br */ "Aviso",
/* ru */ "Предупреждение",
/* zh_hans */ "警告",
/* zh_hant */ "警告",
],
// ErrorDialogTitle
[
/* en */ "Error",
/* de */ "Fehler",
/* es */ "Error",
/* fr */ "Erreur",
/* it */ "Errore",
/* ja */ "エラー",
/* ko */ "오류",
/* pt_br */ "Erro",
/* ru */ "Ошибка",
/* zh_hans */ "错误",
/* zh_hant */ "錯誤",
],
// ErrorIcuMissing
[
/* en */ "This operation requires the ICU library",
/* de */ "Diese Operation erfordert die ICU-Bibliothek",
/* es */ "Esta operación requiere la biblioteca ICU",
/* fr */ "Cette opération nécessite la bibliothèque ICU",
/* it */ "Questa operazione richiede la libreria ICU",
/* ja */ "この操作にはICUライブラリが必要です",
/* ko */ "이 작업에는 ICU 라이브러리가 필요합니다",
/* pt_br */ "Esta operação requer a biblioteca ICU",
/* ru */ "Эта операция требует наличия библиотеки ICU",
/* zh_hans */ "此操作需要 ICU 库",
/* zh_hant */ "此操作需要 ICU 庫",
],
// SearchNeedleLabel (for input field)
[
/* en */ "Find:",
/* de */ "Suchen:",
/* es */ "Buscar:",
/* fr */ "Rechercher :",
/* it */ "Trova:",
/* ja */ "検索:",
/* ko */ "찾기:",
/* pt_br */ "Encontrar:",
/* ru */ "Найти:",
/* zh_hans */ "查找:",
/* zh_hant */ "尋找:",
],
// SearchReplacementLabel (for input field)
[
/* en */ "Replace:",
/* de */ "Ersetzen:",
/* es */ "Reemplazar:",
/* fr */ "Remplacer :",
/* it */ "Sostituire:",
/* ja */ "置換:",
/* ko */ "바꾸기:",
/* pt_br */ "Substituir:",
/* ru */ "Замена:",
/* zh_hans */ "替换:",
/* zh_hant */ "替換:",
],
// SearchMatchCase (toggle)
[
/* en */ "Match Case",
/* de */ "Groß/Klein",
/* es */ "May/Min",
/* fr */ "Resp. la casse",
/* it */ "Maius/minus",
/* ja */ "大/小文字を区別",
/* ko */ "대소문자",
/* pt_br */ "Maius/minus",
/* ru */ "Регистр",
/* zh_hans */ "区分大小写",
/* zh_hant */ "區分大小寫",
],
// SearchWholeWord (toggle)
[
/* en */ "Whole Word",
/* de */ "Ganzes Wort",
/* es */ "Palabra",
/* fr */ "Mot entier",
/* it */ "Parola",
/* ja */ "単語全体",
/* ko */ "전체 단어",
/* pt_br */ "Palavra",
/* ru */ "Слово",
/* zh_hans */ "全字匹配",
/* zh_hant */ "全字匹配",
],
// SearchUseRegex (toggle)
[
/* en */ "Use Regex",
/* de */ "RegEx",
/* es */ "RegEx",
/* fr */ "RegEx",
/* it */ "RegEx",
/* ja */ "正規表現",
/* ko */ "정규식",
/* pt_br */ "RegEx",
/* ru */ "RegEx",
/* zh_hans */ "正则",
/* zh_hant */ "正則",
],
// SearchReplaceAll (button)
[
/* en */ "Replace All",
/* de */ "Alle ersetzen",
/* es */ "Reemplazar todo",
/* fr */ "Remplacer tout",
/* it */ "Sostituisci tutto",
/* ja */ "すべて置換",
/* ko */ "모두 바꾸기",
/* pt_br */ "Substituir tudo",
/* ru */ "Заменить все",
/* zh_hans */ "全部替换",
/* zh_hant */ "全部取代",
],
// SearchClose (button)
[
/* en */ "Close",
/* de */ "Schließen",
/* es */ "Cerrar",
/* fr */ "Fermer",
/* it */ "Chiudi",
/* ja */ "閉じる",
/* ko */ "닫기",
/* pt_br */ "Fechar",
/* ru */ "Закрыть",
/* zh_hans */ "关闭",
/* zh_hant */ "關閉",
],
// EncodingReopen
[
/* en */ "Reopen with encoding…",
/* de */ "Mit Kodierung erneut öffnen…",
/* es */ "Reabrir con codificación…",
/* fr */ "Rouvrir avec un encodage différent…",
/* it */ "Riapri con codifica…",
/* ja */ "指定エンコーディングで再度開く…",
/* ko */ "인코딩으로 다시 열기…",
/* pt_br */ "Reabrir com codificação…",
/* ru */ "Открыть снова с кодировкой…",
/* zh_hans */ "使用编码重新打开…",
/* zh_hant */ "使用編碼重新打開…",
],
// EncodingConvert
[
/* en */ "Convert to encoding…",
/* de */ "In Kodierung konvertieren…",
/* es */ "Convertir a otra codificación…",
/* fr */ "Convertir vers lencodage…",
/* it */ "Converti in codifica…",
/* ja */ "エンコーディングを変換…",
/* ko */ "인코딩으로 변환…",
/* pt_br */ "Converter para codificação…",
/* ru */ "Преобразовать в кодировку…",
/* zh_hans */ "转换为编码…",
/* zh_hant */ "轉換為編碼…",
],
// IndentationTabs
[
/* en */ "Tabs",
/* de */ "Tabs",
/* es */ "Tabulaciones",
/* fr */ "Tabulations",
/* it */ "Tabulazioni",
/* ja */ "タブ",
/* ko */ "",
/* pt_br */ "Tabulações",
/* ru */ "Табы",
/* zh_hans */ "制表符",
/* zh_hant */ "製表符",
],
// IndentationSpaces
[
/* en */ "Spaces",
/* de */ "Leerzeichen",
/* es */ "Espacios",
/* fr */ "Espaces",
/* it */ "Spazi",
/* ja */ "スペース",
/* ko */ "공백",
/* pt_br */ "Espaços",
/* ru */ "Пробелы",
/* zh_hans */ "空格",
/* zh_hant */ "空格",
],
// SaveAsDialogPathLabel
[
/* en */ "Folder:",
/* de */ "Ordner:",
/* es */ "Carpeta:",
/* fr */ "Dossier :",
/* it */ "Cartella:",
/* ja */ "フォルダ:",
/* ko */ "폴더:",
/* pt_br */ "Pasta:",
/* ru */ "Папка:",
/* zh_hans */ "文件夹:",
/* zh_hant */ "資料夾:",
],
// SaveAsDialogNameLabel
[
/* en */ "File name:",
/* de */ "Dateiname:",
/* es */ "Nombre de archivo:",
/* fr */ "Nom du fichier :",
/* it */ "Nome del file:",
/* ja */ "ファイル名:",
/* ko */ "파일 이름:",
/* pt_br */ "Nome do arquivo:",
/* ru */ "Имя файла:",
/* zh_hans */ "文件名:",
/* zh_hant */ "檔案名稱:",
],
// FileOverwriteWarning
[
/* en */ "Confirm Save As",
/* de */ "Speichern unter bestätigen",
/* es */ "Confirmar Guardar como",
/* fr */ "Confirmer Enregistrer sous",
/* it */ "Conferma Salva con nome",
/* ja */ "名前を付けて保存の確認",
/* ko */ "다른 이름으로 저장 확인",
/* pt_br */ "Confirmar Salvar como",
/* ru */ "Подтвердите «Сохранить как…»",
/* zh_hans */ "确认另存为",
/* zh_hant */ "確認另存新檔",
],
// FileOverwriteWarningDescription
[
/* en */ "File already exists. Do you want to overwrite it?",
/* de */ "Datei existiert bereits. Möchten Sie sie überschreiben?",
/* es */ "El archivo ya existe. ¿Desea sobrescribirlo?",
/* fr */ "Le fichier existe déjà. Voulez-vous lécraser ?",
/* it */ "Il file esiste già. Vuoi sovrascriverlo?",
/* ja */ "ファイルは既に存在します。上書きしますか?",
/* ko */ "파일이 이미 존재합니다. 덮어쓰시겠습니까?",
/* pt_br */ "O arquivo já existe. Deseja sobrescrevê-lo?",
/* ru */ "Файл уже существует. Перезаписать?",
/* zh_hans */ "文件已存在。要覆盖它吗?",
/* zh_hant */ "檔案已存在。要覆蓋它嗎?",
],
];
include!(concat!(env!("OUT_DIR"), "/i18n_edit.rs"));
static mut S_LANG: LangId = LangId::en;
pub fn init() {
// WARNING:
// Generic language tags such as "zh" MUST be sorted after more specific tags such
// as "zh-hant" to ensure that the prefix match finds the most specific one first.
const LANG_MAP: &[(&str, LangId)] = &[
("en", LangId::en),
// ----------------
("de", LangId::de),
("es", LangId::es),
("fr", LangId::fr),
("it", LangId::it),
("ja", LangId::ja),
("ko", LangId::ko),
("pt-br", LangId::pt_br),
("ru", LangId::ru),
("zh-hant", LangId::zh_hant),
("zh-tw", LangId::zh_hant),
("zh", LangId::zh_hans),
];
let scratch = scratch_arena(None);
let langs = sys::preferred_languages(&scratch);
let mut lang = LangId::en;
'outer: for l in langs {
for (prefix, id) in LANG_MAP {
for (prefix, id) in LANGUAGES {
if l.starts_with_ignore_ascii_case(prefix) {
lang = *id;
break 'outer;
@ -1002,5 +29,5 @@ pub fn init() {
}
pub fn loc(id: LocId) -> &'static str {
S_LANG_LUT[id as usize][unsafe { S_LANG as usize }]
TRANSLATIONS[unsafe { S_LANG as usize }][id as usize]
}