forked from extern/Unexpected-Keyboard
Allow extending the compose key (#713)
This allows adding more compose sequences without modifying en_US_UTF_8_Compose.pre. This is done by grouping sequences files that should be merged together into a directory. This also allows moving keysymdef.h into that directory.
This commit is contained in:
parent
84e10e0470
commit
2696f42144
@ -190,6 +190,12 @@ As translations need to be updated regularly, you can subscribe to this issue
|
|||||||
to receive a notification when an update is needed:
|
to receive a notification when an update is needed:
|
||||||
https://github.com/Julow/Unexpected-Keyboard/issues/373
|
https://github.com/Julow/Unexpected-Keyboard/issues/373
|
||||||
|
|
||||||
|
### Adding Compose key sequences
|
||||||
|
|
||||||
|
New Compose sequences can be added into `srcs/compose/compose/extra.json`.
|
||||||
|
If a entirely new family of sequences were to be added, a new `.json` file can
|
||||||
|
be created in the same directory to host them.
|
||||||
|
|
||||||
### Adding key combinations
|
### Adding key combinations
|
||||||
|
|
||||||
Key combinations are defined in `srcs/juloo.keyboard2/KeyModifier.java`.
|
Key combinations are defined in `srcs/juloo.keyboard2/KeyModifier.java`.
|
||||||
|
@ -151,7 +151,7 @@ tasks.register('compileComposeSequences') {
|
|||||||
println "\nGenerating ${out}"
|
println "\nGenerating ${out}"
|
||||||
exec {
|
exec {
|
||||||
def sequences = new File(projectDir, "srcs/compose").listFiles().findAll {
|
def sequences = new File(projectDir, "srcs/compose").listFiles().findAll {
|
||||||
it.name.endsWith(".pre") || it.name.endsWith(".json")
|
!it.name.endsWith(".py") && !it.name.endsWith(".md")
|
||||||
}
|
}
|
||||||
workingDir = projectDir
|
workingDir = projectDir
|
||||||
commandLine("python", "srcs/compose/compile.py", *sequences)
|
commandLine("python", "srcs/compose/compile.py", *sequences)
|
||||||
|
@ -3,6 +3,8 @@
|
|||||||
The `compose.py` program parses the compose sequences found in this directory
|
The `compose.py` program parses the compose sequences found in this directory
|
||||||
and generates `srcs/juloo.keyboard2/ComposeKeyData.java`.
|
and generates `srcs/juloo.keyboard2/ComposeKeyData.java`.
|
||||||
|
|
||||||
## `en_US_UTF_8_Compose.pre`
|
## `compose/en_US_UTF_8_Compose.pre`
|
||||||
|
|
||||||
This file is copied from the `xorg` project. Copyright applies.
|
This file is copied from the `xorg` project. Copyright applies.
|
||||||
|
|
||||||
|
## `compose/extra.json`
|
||||||
|
@ -12,20 +12,18 @@ from array import array
|
|||||||
# Parse symbol names from keysymdef.h. Many compose sequences in
|
# Parse symbol names from keysymdef.h. Many compose sequences in
|
||||||
# en_US_UTF_8_Compose.pre reference theses. For example, all the sequences on
|
# en_US_UTF_8_Compose.pre reference theses. For example, all the sequences on
|
||||||
# the Greek, Cyrillic and Hebrew scripts need these symbols.
|
# the Greek, Cyrillic and Hebrew scripts need these symbols.
|
||||||
def parse_keysymdef_h():
|
def parse_keysymdef_h(fname):
|
||||||
with open(os.path.join(os.path.dirname(__file__), "keysymdef.h"), "r") as inp:
|
with open(fname, "r") as inp:
|
||||||
keysym_re = re.compile(r'^#define XK_(\S+)\s+\S+\s*/\*.U\+([0-9a-fA-F]+)\s')
|
keysym_re = re.compile(r'^#define XK_(\S+)\s+\S+\s*/\*.U\+([0-9a-fA-F]+)\s')
|
||||||
for line in inp:
|
for line in inp:
|
||||||
m = re.match(keysym_re, line)
|
m = re.match(keysym_re, line)
|
||||||
if m != None:
|
if m != None:
|
||||||
yield (m.group(1), chr(int(m.group(2), 16)))
|
yield (m.group(1), chr(int(m.group(2), 16)))
|
||||||
|
|
||||||
xkb_char_extra_names = dict(parse_keysymdef_h())
|
|
||||||
|
|
||||||
dropped_sequences = 0
|
dropped_sequences = 0
|
||||||
|
|
||||||
# Parse XKB's Compose.pre files
|
# Parse XKB's Compose.pre files
|
||||||
def parse_sequences_file_xkb(fname):
|
def parse_sequences_file_xkb(fname, xkb_char_extra_names):
|
||||||
# Parse a line of the form:
|
# Parse a line of the form:
|
||||||
# <Multi_key> <minus> <space> : "~" asciitilde # TILDE
|
# <Multi_key> <minus> <space> : "~" asciitilde # TILDE
|
||||||
# Sequences not starting with <Multi_key> are ignored.
|
# Sequences not starting with <Multi_key> are ignored.
|
||||||
@ -99,13 +97,30 @@ def parse_sequences_file_json(fname):
|
|||||||
return list(seqs.items())
|
return list(seqs.items())
|
||||||
|
|
||||||
# Format of the sequences file is determined by its extension
|
# Format of the sequences file is determined by its extension
|
||||||
def parse_sequences_file(fname):
|
def parse_sequences_file(fname, xkb_char_extra_names={}):
|
||||||
if fname.endswith(".pre"):
|
if fname.endswith(".pre"):
|
||||||
return parse_sequences_file_xkb(fname)
|
return parse_sequences_file_xkb(fname, xkb_char_extra_names)
|
||||||
if fname.endswith(".json"):
|
if fname.endswith(".json"):
|
||||||
return parse_sequences_file_json(fname)
|
return parse_sequences_file_json(fname)
|
||||||
raise Exception(fname + ": Unsupported format")
|
raise Exception(fname + ": Unsupported format")
|
||||||
|
|
||||||
|
# A sequence directory can contain several sequence files as well as
|
||||||
|
# 'keysymdef.h'.
|
||||||
|
def parse_sequences_dir(dname):
|
||||||
|
compose_files = []
|
||||||
|
xkb_char_extra_names = {}
|
||||||
|
# Parse keysymdef.h first if present
|
||||||
|
for fbasename in os.listdir(dname):
|
||||||
|
fname = os.path.join(dname, fbasename)
|
||||||
|
if fbasename == "keysymdef.h":
|
||||||
|
xkb_char_extra_names = dict(parse_keysymdef_h(fname))
|
||||||
|
else:
|
||||||
|
compose_files.append(fname)
|
||||||
|
sequences = []
|
||||||
|
for fname in compose_files:
|
||||||
|
sequences.extend(parse_sequences_file(fname, xkb_char_extra_names))
|
||||||
|
return sequences
|
||||||
|
|
||||||
# Turn a list of sequences into a trie.
|
# Turn a list of sequences into a trie.
|
||||||
def add_sequences_to_trie(seqs, trie):
|
def add_sequences_to_trie(seqs, trie):
|
||||||
def add_seq_to_trie(t_, seq, result):
|
def add_seq_to_trie(t_, seq, result):
|
||||||
@ -238,9 +253,12 @@ public final class ComposeKeyData
|
|||||||
|
|
||||||
total_sequences = 0
|
total_sequences = 0
|
||||||
tries = {} # Orderred dict
|
tries = {} # Orderred dict
|
||||||
for fname in sys.argv[1:]:
|
for fname in sorted(sys.argv[1:]):
|
||||||
tname, _ = os.path.splitext(os.path.basename(fname))
|
tname, _ = os.path.splitext(os.path.basename(fname))
|
||||||
sequences = parse_sequences_file(fname)
|
if os.path.isdir(fname):
|
||||||
|
sequences = parse_sequences_dir(fname)
|
||||||
|
else:
|
||||||
|
sequences = parse_sequences_file(fname)
|
||||||
add_sequences_to_trie(sequences, tries.setdefault(tname, {}))
|
add_sequences_to_trie(sequences, tries.setdefault(tname, {}))
|
||||||
total_sequences += len(sequences)
|
total_sequences += len(sequences)
|
||||||
entry_states, automata = make_automata(tries)
|
entry_states, automata = make_automata(tries)
|
||||||
|
5
srcs/compose/compose/extra.json
Normal file
5
srcs/compose/compose/extra.json
Normal file
@ -0,0 +1,5 @@
|
|||||||
|
{
|
||||||
|
"V": {
|
||||||
|
"s": "Š"
|
||||||
|
}
|
||||||
|
}
|
Binary file not shown.
@ -570,7 +570,7 @@ public final class KeyValue implements Comparable<KeyValue>
|
|||||||
case "autofill": return editingKey("auto", Editing.AUTOFILL);
|
case "autofill": return editingKey("auto", Editing.AUTOFILL);
|
||||||
|
|
||||||
/* The compose key */
|
/* The compose key */
|
||||||
case "compose": return makeComposePending(0xE016, ComposeKeyData.en_US_UTF_8_Compose, FLAG_SECONDARY | FLAG_SMALLER_FONT | FLAG_SPECIAL);
|
case "compose": return makeComposePending(0xE016, ComposeKeyData.compose, FLAG_SECONDARY | FLAG_SMALLER_FONT | FLAG_SPECIAL);
|
||||||
|
|
||||||
/* Placeholder keys */
|
/* Placeholder keys */
|
||||||
case "removed": return placeholderKey(Placeholder.REMOVED);
|
case "removed": return placeholderKey(Placeholder.REMOVED);
|
||||||
|
Loading…
Reference in New Issue
Block a user