Add a Setup > Region toggle with Chinese language and input method

`omarchy region china` switches the system language to zh_CN, installs the
Rime Ice input method through Andy Stewart's rime-ice-installer, makes Rime
the default with Ctrl+Space as the toggle, and swaps the Omarchy menu to
Chinese labels through the user-extension overlay; `omarchy region world`
puts the language and menu back and leaves the input method installed.
mergeMenuSources now only overrides the fields an extension declares, as
docs/menu.md documents, which the label-only overlay needs.

Co-authored-by: Andy Stewart <lazycat.manatee@gmail.com>
This commit is contained in:
2026-09-01 11:34:07 -04:00
co-authored by Andy Stewart
parent b686ed892d
commit d897cff7bf
8 changed files with 450 additions and 7 deletions
+22 -5
View File
@@ -58,7 +58,9 @@ function parseMenuJsonc(raw) {
for (var id in source) {
var entry = source[id]
if (!entry || typeof entry !== "object" || Array.isArray(entry)) continue
out.push(normalizeItem(id, entry))
var item = normalizeItem(id, entry)
item.declared = Object.keys(entry)
out.push(item)
}
return out
}
@@ -74,11 +76,25 @@ function mergeMenuSources(defaultItems, userItems) {
var entry = src[i]
if (!entry || !entry.id) continue
if (!nextItems[entry.id]) nextOrder.push(entry.id)
var prior = nextItems[entry.id] || {}
var prior = nextItems[entry.id]
var merged = {}
for (var k in prior) merged[k] = prior[k]
for (var k2 in entry) merged[k2] = entry[k2]
// Overriding an existing id only replaces the fields the file declared,
// so a label-only entry retitles a row without clearing its action.
if (prior && entry.declared) {
for (var k in prior) merged[k] = prior[k]
for (var d = 0; d < entry.declared.length; d++) {
var key = entry.declared[d]
if (key in entry) merged[key] = entry[key]
}
if (entry.declared.indexOf("action") >= 0 || entry.declared.indexOf("target") >= 0)
merged.kind = merged.action ? "action" : (merged.target ? "link" : "menu")
} else {
prior = prior || {}
for (var k1 in prior) merged[k1] = prior[k1]
for (var k2 in entry) merged[k2] = entry[k2]
}
merged.id = entry.id
delete merged.declared
nextItems[entry.id] = merged
}
}
@@ -398,7 +414,8 @@ var GUARD_READERS = [
"omarchy-default-browser",
"omarchy-default-editor",
"omarchy-default-terminal",
"omarchy-dns"
"omarchy-dns",
"omarchy-region"
]
// Package and command presence account for most of what the guards ask, and