Section heading keys for all locales, plus English and Spanish corrections - #34
Section heading keys for all locales, plus English and Spanish corrections#34pdalexis wants to merge 6 commits into
Conversation
45cbf2f to
b39e8f0
Compare
`bin/build.js` and `tests/test.spec.js` both dynamic-import each locale file
by absolute path. On Windows that path starts with a drive letter, which
Node's ESM loader reads as a URL scheme:
Error [ERR_UNSUPPORTED_ESM_URL_SCHEME]: Received protocol 'c:'
So `npm run build` and `npm run test` cannot run at all on Windows, which
also means the documented `npm run test` before push cannot be honoured
there. CI runs on ubuntu-latest, so this never surfaced.
Wrapping the path in `pathToFileURL` fixes both. No behaviour change on
Linux or macOS, where an absolute path already resolves.
electerm/electerm#4484 groups the SSH bookmark form fields and the Setting toggles under headings. Two of the labels it needs already exist, auth and window; the other six do not. e() falls back to capitalizeFirstLetter(key) when a key is missing, so in English five of the six already render acceptably -- "Start", "Privacy", "Identity" -- and only onConnect is visibly wrong, as "OnConnect". The gain here is almost entirely in the other fourteen locales, where a missing key means an English word appears in the middle of a translated panel. setting.start groups initDefaultTabOnStart and checkUpdateOnStart, so it is app startup rather than a start button. setting.privacy groups disableConnectionHistory, disableTransferHistory and hideIP. setting.development groups disableDeveloperTool and debug. form.identity groups category, title, host, port and username -- it names the connection, it is not a credential. form.onConnect groups the login script and the start directories. form.environment groups setEnv, envLang, encode, description and type. Only sshAuthFields is grouped in 4484; the basic, telnet, rdp, vnc, ftp and web forms are untouched. All fifteen files, not just en_us and es_es. tests/test.spec.js compares Object.keys() with _.isEqual across every pair of locales, so a key present in two files and absent from thirteen fails `npm run test` -- which is what the first version of this branch did. Position matters for the same reason, so the setting trio sits after `common` and the form trio after `auth` in all fifteen. I wrote en_us and es_es. The other thirteen follow each file's own neighbour for capitalisation -- `common` for the setting trio, `auth` for the form trio -- and its existing vocabulary: fr_fr capitalises the setting trio and not the form trio because that is what Général and authentification already do, and zh_tw takes 啟動 rather than the 啓 variant it also uses, because the three startup strings this heading sits over all use 啟. Overrule any of the thirteen freely.
Twenty-eight value changes, no keys touched. en_us is what the other fourteen files get written from, and nothing here validates a translation once the English moves, so I kept to things that are wrong rather than things I would word differently. Spelling: 'can not be registe' -> 'cannot be registered', and the same 'can not' in tabs.titleEmptyWarn; 'transfered' -> 'transferred'; 'goto parent folder' -> 'go to'. form.privateKey read 'privateKey' -- the camelCase key name reached the radio label the user sees -- and passphraseDesc referred to it the same way. Both now say 'private key'. form.loginScriptTip said 'after logined'. Number agreement: 'open all bookmark in this category', 'allow multi instance', 'disable developer tool', 'support terminal image', 'support screen reader in terminal', 'and all the file/directory in them', and syncDesc's 'sync bookmark / history / setting'. Verb forms: 'role for create terminal command with AI' and 'role for explain terminal output with AI' -> creating/explaining; 'when app start' -> 'when the app starts'; 'when switch to sftp' -> 'when switching to'; 'when click to open terminal link' -> 'when clicking to open'. useSystemTitleBarTip was three clauses with no subject; it now reads 'requires restarting the app to take effect; transparency does not work with the system title bar'. updater.fail was 'check update fails'. Its single call site, upgrade.jsx's renderError, is fed by two paths -- the version check and the download error handler -- so naming the check would be wrong half the time. It now reads 'update failed'. sftp mergeDesc / overwriteDesc / renameDesc used 'rest' as a bare adjective: 'merge rest conflict folders'. It parses as the noun, and the translations show it -- es_es rendered it 'carpetas de conflicto de descanso', folders of conflict of a nap. Now 'merge the remaining conflicting folders'. Also 'create bookmark by ai' -> 'with AI', matching the caps used everywhere else, and a space before the parenthetical in hotkeyDesc and timeoutDesc, where 'millisecond' was also singular.
Sixty-seven value changes in es_es.js. No keys added, removed or reordered.
Left in English: form.proxyIp/proxyPort/proxyType ("proxy port"),
setting.cursorBlink ("Cursor Blink"), and the stray "Bookmarks" and "Start"
in setting.onStartBookmarks and setting.showHiddenFilesOnSftpStart.
Broken when composed. app.toShow was 'mostrar' where init-app.js renders
`${press} ${hotkey} ${toShow}` into a desktop notification title, so under
--autohide it read "presione Ctrl+2 mostrar" with no preposition. sftp.hfd
was 'esconder archivos y directorios' where address-bar.jsx renders
`${hide|show} ${hfd}`, giving "esconder esconder archivos y directorios".
sftp.selected was the infinitive 'seleccionar' where file-item.jsx renders
`${del}:${selected}(${len})`, so it now reads 'seleccionados', plural to
agree with the count.
Wrong word. 'camino' (a road) for path, where the same section already used
'ruta'; 'llave' (a physical key) for private key, where privateKeyDesc
already said 'clave'; 'resumir' (to summarise) for resume; 'reiniciar'
(restart) for reset, colliding with menu.restart; 'correr' (to run on foot)
for running a command; 'lenguaje' (the faculty of language) for UI language;
'mejorar' (to improve) for upgrade; 'defecto' (a defect) for default;
'contener' (to contain) for holding down a modifier key; 'sin objeto'
(pointless) for antd's empty-list text.
Mistranslated. "merge rest conflict folders" became "carpetas de conflicto
de descanso" -- "rest" read as a nap -- in mergeDesc and overwriteDesc, and
renameDesc dropped it. "support screen reader" became "lector de pantalla de
soporte". useSystemTitleBarTip opened with 'Necesito', first person: "I need
to restart the app". fontFamily was 'tipografía familiar', familiar
typography. scaleViewport pointed at the window rather than the viewport.
ssh.nextMatch/prevMatch dropped "match", leaving a search bar labelled
'próximo / anterior'. rightClickSelectsWord was word salad.
settingSync.settingSync, syncSettings and downloadSettings had their two
nouns the wrong way round, so "download settings" read as "the download
settings".
Typos and agreement: 'minimimizar', 'autenticacción', 'omitir esta version',
'error de inicio de sesion', 'comando rápidos', sftp.folder pluralised
against a singular source, transferHistory.clear as the adjective 'limpio'.
Two follow the English changes in the previous commit: screenReaderMode and
disableDeveloperTool are now plural. 'IP' is capitalised in proxyIp to match
proxyIpPlaceholder two lines down, and the deep-link pair settles on
'controlador de protocolo', which is the es-ES term, rather than the calque
'manejador' one of them used.
transferHistory.clear is also the file's only divergent duplicate key:
'clear' appears in both transferHistory and ssh, and since bin/build.js
flattens every section into one namespace, ssh's 'limpiar' silently won.
English has no such divergence.
Seventy-eight value changes, no key touched. Mostly making the file agree
with itself, plus one outright error that only shows up once the register is
consistent.
That error: menu.startspeaking and stopspeaking sit under Electron's macOS
Edit > Speech submenu, where the app reads the selection aloud. 'empieza a
hablar' was clumsy but pointed the right way; anything about dictado would
have pointed at speech-to-text, the opposite feature. They now read
'iniciar la locución' and 'detener la locución'.
Register. Labels take the infinitive and messages address the reader as
usted, which is what most of the file already did. The holdouts split three
ways: tuteo ('Hazlo portátil', '¿Estás seguro?', 'estás usando', 'comprueba',
'Usa la barra de título', and form.aiSecurityNotice, which was the last one
left), usted-imperatives where a label wanted an infinitive ('Elija el
archivo' next to 'elegir carpeta', 'cierre la pestaña actual', 'Abra la
pestaña predeterminada', 'Acceda a esta carpeta'), and third-person
indicatives ('Muestra texto en bruto', 'Soporta expresiones regulares',
'distingue mayúsculas y minúsculas', whose two siblings in the same search
bar were already being converted).
Capitalisation. en_us keeps labels lowercase and lets the app capitalise --
window.translate applies capitalizeFirstLetter to every string, and the
section headings are text-transform uppercase -- so a hardcoded capital in
the locale file just makes the sidebar inconsistent. Forty-seven labels
started with a capital where English did not, and five were in Title Case,
which Spanish does not use: 'Tiempo de Ejecución', 'Solo Vista',
'Credenciales Requeridas', 'Nombre del Perfil', 'Contenido Completo'. Where
en_us itself capitalises (Expand all, UI Themes, Edit with color picker)
Spanish keeps the capital, so the rule is per key rather than blanket
lowercase. Full sentences keep theirs.
sftp.delTip renders as `${delTip} ${names} ${delTip1} (${n})`. It had lost
the demonstrative English carries in "this will delete these", and delTip1
said 'y todos los archivos / directorios que contienen', which parses as
"that contain" with no object. Now 'esto borrará estos' -- borrar, matching
the button that opens the dialog -- and 'y todo su contenido'.
One word per concept, picking whichever the file already used more often:
'ocultar' over 'esconder' (hideIP and hideSshConfig were already 'ocultar'),
'fusionar' over 'unir' (mergeAll was already 'fusionar'), 'actualizar' over
'refrescar', 'buscar actualizaciones' over 'comprueba la actualización',
'restablecer el zoom' over 'reajustar', 'aumentar el zoom' to pair with the
existing 'disminuir el zoom'.
updater.fail becomes the neutral 'error al actualizar' rather than naming
the version check, for the reason given in the English commit.
Also 'Expandir todos' -> 'Expandir todo', 'obligatorio' for a required field
rather than 'necesario', 'usar un gist existente' for the dangling 'utilizar
existente', and syncDesc's preposition: 'sincronizar ... a github secret
gist' -> '... con un gist secreto de GitHub'.
Both genders are correct Spanish and the file used both: eleven masculine against six feminine, sometimes a line apart -- 'nueva terminal' in the toolbar, 'registro del terminal' in Setting. Peninsular usage for a computer terminal leans masculine and this is es_es, so the six feminine ones move. Also 'temas terminales' -> 'temas del terminal', and the one place that called a layout a 'diseño' now says 'disposición', which is what app.layout says. Separate commit on purpose: it is the one judgement call in this branch. Drop it and the other two still stand.
b39e8f0 to
9592e07
Compare
|
One thing I want to flag before you merge, because it is much cheaper to change now than later: I think two of the six key names I am adding are wrong in English, and if they go in as-is, fifteen files end up faithfully translating a word that does not describe what it labels.
It groups You can see the trap in the translations I wrote for it. Russian is the clearest:
It groups
The other four — I have not changed anything. Renaming means touching Separately, and also about these six headings rather than about the locale files: in electerm/electerm#4484 both Turkish loses its dotted İ. CSS uppercasing follows the content language, and electerm never sets a
Arabic loses its joins. Both belong in #4484, not here. If you want them fixed, I would set |
What this is
This started as six new keys and grew, so here is the whole thing in one PR. Six commits. Commit 1 is independent; commits 3-6 are ordered, and commit 6 re-touches three strings from 4 and 5, so it reverts cleanly off the tip but 4 and 5 do not revert in isolation.
bin/build.js,tests/test.spec.jsen_us.jses_es.jses_es.jses_es.jsHappy to split this into four PRs instead if you would rather review it that way — say so and I will. The only reason they are together is that commits 3–6 touch lines adjacent to where commit 2 inserts, so as separate PRs they would conflict pairwise.
npm run lintandnpm run testpass. Note CI does not run here:.github/workflows/test.ymltriggers onbuildandtest, not on PRs tomaster.1. Windows
bin/build.jsandtests/test.spec.jsboth dynamic-import each locale by absolute path. On Windows that starts with a drive letter and Node's ESM loader readsc:as a URL scheme:So neither
npm run buildnornpm run testruns there at all — which means thenpm run testthe README asks for before pushing, and thepre-pushhook, cannot be honoured on Windows.pathToFileURLon both call sites, two lines, no change on Linux or macOS.I put this first because without it I could not verify anything else.
2. The six section headings
electerm#4484 groups the SSH bookmark form (
sshAuthFieldsonly — the basic, telnet, rdp, vnc, ftp and web forms are untouched) and the Setting toggles under headings. Two of the labels it needs already exist (auth,window); the other six do not.e()falls back tocapitalizeFirstLetter(key), so in English five of the six already render acceptably — "Start", "Privacy", "Identity" — and onlyonConnectis visibly wrong, as "OnConnect". The gain is almost entirely in the other fourteen locales, where a missing key drops an English word into the middle of a translated panel.setting.startinitDefaultTabOnStart,checkUpdateOnStartsetting.privacydisableConnectionHistory,disableTransferHistory,hideIPsetting.developmentdisableDeveloperTool,debugform.identitycategory,title,host,port,usernameform.onConnectform.environmentsetEnv,envLang,encode,description,typeTwo are easy to get wrong without that context:
setting.startis app startup, not a start button, andform.identitynames the connection — it sits aboveauthand holds no credential.All fifteen files. The first version of this branch added them to
en_usandes_esonly, which cannot passnpm run test:tests/test.spec.jscomparesObject.keys()with_.isEqualacross every adjacent pair, so position matters as much as presence. The setting trio goes aftercommonand the form trio afterauthin all fifteen.I wrote
en_usandes_es. For the other thirteen I followed each file's own neighbour for capitalisation —commonfor the setting trio,authfor the form trio — and its existing vocabulary:zh_twtakes 啟動 rather than the 啓 variant it also uses, because the three startup strings this heading sits over all use 啟;fr_frcapitalises the setting trio but not the form trio, because that is whatGénéralandauthentificationalready do. They are six ordinary words, but I do not speak most of these languages — overrule any of them freely, or tell me to drop them and runbin/translate-with-ai.jsinstead.3. English
Twenty-eight fixes, no keys touched.
en_us.jsis what the other fourteen get written from, so I kept to things that are wrong, not things I would word differently.hotkey can not be registe→cannot be registered, and the samecan notintabs.titleEmptyWarn;data transfered to→transferred;goto parent folder→go to.form.privateKeywas the string'privateKey'— the camelCase key itself, shown as the field label — andpassphraseDescsaidpassphrase for privateKey.form.loginScriptTipsaidrun script after logined.open all bookmark in this category,allow multi instance,disable developer tool,support terminal image,support screen reader in terminal,and all the file/directory in them,sync bookmark / history / setting.role for create terminal command with AI→ creating;when app start→when the app starts;when switch to sftp→when switching to;updater.failwascheck update fails, but its single call site (upgrade.jsxrenderError) is fed by both the version check and the download error handler, so naming the check would be wrong half the time — it is now the neutralupdate failed.useSystemTitleBarTipwas three clauses with no subject and now readsrequires restarting the app to take effect; transparency does not work with the system title bar.restas a bare adjective inmergeDesc/overwriteDesc/renameDesc:merge rest conflict folders. It parses as the noun, and the translations show it was read that way —es_esrendered it "carpetas de conflicto de descanso", folders of conflict of a nap. Nowmerge the remaining conflicting folders.I left the file's mixed label capitalisation alone (
Workspaces,Expand all,UI Themesagainst several hundred lowercase). It is cosmetic, it would ripple into every other locale, and it is your call.4–6. Spanish
I am not the original translator — that is Federico Pereira, credited in the README. #24, #27, #28 and #32 set the precedent for improving an existing language, so I hope this is welcome; route it past him first if you prefer.
Commit 4, sixty-seven value changes. Most are outright errors; a handful (
sin objeto→sin elementos,tiempo de acceso→fecha de acceso) are word-choice calls. The ones that matter most are three that break when composed at runtime:app.toShowwas'mostrar', andinit-app.jsrenders${press} ${hotkey} ${toShow}into a desktop notification title — shown under--autohide— which read "presione Ctrl+2 mostrar", with no preposition.sftp.hfdwas'esconder archivos y directorios', andaddress-bar.jsxrenders${hide|show} ${hfd}— giving "esconder esconder archivos y directorios".sftp.selectedwas the infinitive'seleccionar'wherefile-item.jsxrenders${del}:${selected}(${len}). It is now'seleccionados', plural to agree with the count.Then five strings still in English (
"proxy ip","proxy port","proxy type","Cursor Blink", and the strayBookmarks/Start); false friends (resumir= to summarise, for resume;defecto= a defect, for default;llave= a physical key, for the private key, whereprivateKeyDescalready saidclave;camino= a road, for path, two lines below aruta;correr= to run on foot, for running a command);useSystemTitleBarTipopening in the first person, "Necesito reiniciar la aplicación";fontFamilyas "tipografía familiar", familiar typography;ssh.nextMatch/prevMatchdropping "match" and leaving a search bar labelled "próximo / anterior"; and thesettingSynctrio with its two nouns reversed, so "download settings" read as "the download settings". Plus typos:minimimizar,autenticacción,omitir esta version,error de inicio de sesion,comando rápidos.Commit 5, seventy-eight changes. Mostly consistency, plus one outright error that only surfaced once the register was uniform:
menu.startspeaking/stopspeakingsit under Electron's macOS Edit ▸ Speech submenu, where the app reads the selection aloud. Anything about dictado would name speech-to-text, the opposite feature; they now readiniciar la locución/detener la locución. Labels take the infinitive and messages address the reader as usted, which is what most of the file already did — the holdouts were tuteo ('Hazlo portátil','¿Estás seguro?'), usted-imperatives where a label wanted an infinitive ('Elija el archivo'next to'elegir carpeta'), and third-person indicatives ('Soporta expresiones regulares'). Forty-seven labels started with a capital where English did not, and five were in Title Case, which Spanish does not use — whereen_usitself capitalises, Spanish keeps the capital, so the rule is per key rather than blanket lowercase.sftp.delTipalso regained the demonstrative English carries in "this will delete these", since it renders as${delTip} ${names} ${delTip1} (${n}). And one word per concept, always the one the file already used more often:ocultaroveresconder,fusionaroverunir,actualizaroverrefrescar.Commit 6, the one judgement call. Both genders of terminal are correct Spanish and the file used both — eleven masculine against six feminine, sometimes a line apart: nueva terminal in the toolbar, registro del terminal in Setting. Peninsular usage leans masculine and this is
es_es, so the six feminine ones move. Separate commit on purpose: drop it and commits 4 and 5 still stand.Two things I found and did not touch
bin/build.jsflattens every section into one namespace, so a key repeated across sections shadows itself. Where the two values differ, the later section silently wins and the earlier one is dead.en_ushas none; nine other files do:zh_cnis the clearest symptom: the transfer-history Clear button says 清屏, "clear screen". I only fixed thees_esone, since it was a plain adjective-for-verb slip. The rest need either a native speaker's call or distinct keys, and both are yours to make.78 keys that
src/clientcalls throughe('...')have no entry inen_us.jsat all (80 counting two more reached viawindow.translate) —category,passwords,width,height,fullscreen,replace,domain,qualityLeveland so on. Ten of them are whole English sentences used as keys ('URL must start with http:// or https://','file too large for code compare'), which cannot be translated at all. Becausee()falls back to the key, English looks fine and only translated UIs show the raw identifier. Nothing to do with this PR; I can open an issue with the full list if that is useful.