Change-Id: I203cc50997f9292cef7a3383dadb96fc97108ca6 Reviewed-on: https://cl.tvl.fyi/c/depot/+/13099 Tested-by: BuildkiteCI Autosubmit: sterni <sternenseemann@systemli.org> Reviewed-by: sterni <sternenseemann@systemli.org>
66 lines
2.9 KiB
BQN
Executable file
66 lines
2.9 KiB
BQN
Executable file
#!/usr/bin/env BQN
|
||
# SPDX-FileCopyrightText: Copyright © 2024-2025 by sterni
|
||
# SPDX-License-Identifier: MIT
|
||
#
|
||
# Generate Compose Sequences for /lib/keyboard that enable entering BQN specific
|
||
# Unicode characters using their familiar key combinations in Plan 9 programs.
|
||
|
||
# TODO(sterni): move these helper functions somewhere reusable
|
||
LogBase ← ÷˜○•math.Log10
|
||
Digs ← (⌊ 1⊸+)∘LogBase
|
||
DivMod ← ⌊∘÷˜⋈|
|
||
hd←"0123456789ABCDEF"
|
||
ToHex ← {hd⊏˜(16⊸DivMod⟜⊑ ∾ 1⊸↓)⍟(-⟜1 𝕨⊸⌈⟜(16⊸Digs)) 𝕩} # 𝕨 is the min amount of digits
|
||
FromHex ← {+´(16⋆⌽↕≠𝕩)×hd⊐𝕩}
|
||
IsAscii ← 127⊸≥-⟜@
|
||
|
||
# Parse CLI
|
||
opts ← {
|
||
flags‿args ← 2↑'-' ((≠⟜⊑)¨⊔⊢) 𝕩
|
||
⟨sort,help,inPlace⟩ ⇐ "shi"∊∾1⊸↓¨flags
|
||
|
||
argCount ← 2
|
||
{𝕤
|
||
•Out "Usage: "∾•name∾" [-s] [-i] /path/to/inputrc /path/to/lib/keyboard
|
||
|
||
-i Modify lib/keyboard in place. If not given, print to stdout.
|
||
-s Sort output by Unicode Codepoint."
|
||
•Exit ¬help
|
||
}⍟(help∨argCount≠≠args) @
|
||
|
||
inputrcPath‿keyboardPath ⇐ •wdpath⊸•file.At¨args
|
||
WriteOutput ⇐ inPlace◶⟨•out¨,keyboardPath⊸•fLines⟩
|
||
} •args
|
||
|
||
# Main Program
|
||
|
||
# Read inputrc, dropping comment and empty lines. Also drop the rule for \\.
|
||
# Since Plan9 requires an explicit keypress before entering a compose sequence,
|
||
# we don't need to add a way to type \ (or any ASCII character for that matter).
|
||
# This simplifies the parser below since we don't need to unescape anything.
|
||
inputrc←1↓(("#"⊸≢⟜(1⊸↑)∧0⊸≠∘≠)¨/⊢)•FLines opts.inputrcPath
|
||
# After removing all backslashes, the ASCII character used representing the used
|
||
# key and the resulting codepoint have a consistent position in the lines.
|
||
# Remove all ASCII chars in a second step.
|
||
# map contains pairs of ⟨BQN char, key used to type it as an ASCII char⟩
|
||
map←(¬∘IsAscii∘⊑¨/⊢)5‿1⊸⊏¨'\'(≠/⊢)¨inputrc
|
||
|
||
# Render the first three fields of lib/keyboard:
|
||
# ⟨Codepoint (Hex), Compose Sequence, Resulting Character⟩
|
||
newfields←{𝕊 c‿k: ⟨4 ToHex c-@,"\"∾k,c⟩}¨map
|
||
# In the file, the fields need be padded to a specific length…
|
||
fieldsz←6‿12‿0⌈⌈´˘⍉≠¨>newfields
|
||
# … and there's a fourth name field separated by a tab.
|
||
# We don't make an effort to add a per character description there (yet).
|
||
tab←@+9
|
||
newlines←((tab∾"BQN char") ∾´fieldsz⊸(↑¨))¨ newfields
|
||
|
||
# Due to the consistent spacing we can just compute the sort order on the
|
||
# resulting character at index 18.
|
||
Sort ← (⍋ 18⊸⊑¨)⊏⊢
|
||
|
||
# Deduplicate output before writing, so the script can be executed multiple
|
||
# times or after inputrc has been changed without introducing duplicates. Since
|
||
# we duplicate on entire lines, existing alternative compose sequences aren't
|
||
# removed.
|
||
opts.WriteOutput ⍷ Sort⍟opts.sort (•FLines opts.keyboardPath)∾newlines
|