2 ;; TITLE MAP-LIST MODULE-LIST ? STATE-LIST
11 ;; '(' MAP-NAME RULE * ')'
17 ;; '(' KEYSEQ MAP-ACTION * ')'
20 ;; MTEXT | '(' [ SYMBOL | INTEGER ] * ')'
26 ;; MTEXT | CANDIDATES | '(' ACTION-NAME ACTION-ARG * ')'
29 ;; '(' CANDIDATE-GROUP * ')'
32 ;; MTEXT is a short form of "(insert MTEXT)"
33 ;; CANDIDATES is a short form of "(candidates CANDIDATE-GROUP *)")
36 ;; 'insert' | 'candidates' | 'delete' | 'select' | 'select-group'
37 ;; | 'move' | 'mark' | 'pushback' | 'undo' | 'shift' | 'call'
40 ;; INTEGER | SYMBOL | MTEXT | CANDIDATE-GROUP
42 ;; CANDIDATE-GROUP ::=
43 ;; MTEXT | '(' MTEXT * ')'
45 ;; PREDEFINED-SYMBOL ::=
46 ;; '@0' | '@1' | '@2' | '@3' | '@4' | '@5' | '@6' | '@7' | '@8' | '@9'
47 ;; | '@<' | '@=' | '@>' | '@-' | '@+'
50 ;; PREDEFINED-SYMBOL | SYMBOL
52 ;; CANDIDATE-INDEX ::=
55 ;; CANDIDATE-GROUP-INDEX ::=
58 ;; ;; The first five actions ('insert' .. 'select-group') are for
59 ;; ;; editing a text in the preediting buffer. The buffer can keep
60 ;; ;; multiple markers. Each marker is represented by a symbol, and
61 ;; ;; keeps a position between characters in the preediting buffer.
63 ;; ;; PREDEFINED-SYMBOL has special meanings when used as MARKER:
64 ;; ;; '@0', '@1', ... '@9'
65 ;; ;; The 0th, 1th, ... 9th position.
66 ;; ;; '@<', '@=', '@>'
67 ;; ;; The first, current, and end position.
69 ;; ;; The previous and next position.
71 ;; ;; PREDEFINED-SYMBOL has special meanings when used as CANDIDATE-INDEX:
72 ;; ;; '@0', '@1', ... '@9'
73 ;; ;; The 0th, 1th, ... 9th candidate of the current candidate group.
74 ;; ;; '@<', '@=', '@>'
75 ;; ;; The first, current, and end candidate of the current candidate
78 ;; ;; The previous candidate. If the current candidate is the
79 ;; ;; first of the current candidate group, the last candidate of
80 ;; ;; the previous candidate group.
82 ;; ;; The next candidate. If the current candidate is the last of
83 ;; ;; the current candidate group, the first candidate of the
84 ;; ;; previous candidate group.
86 ;; ;; PREDEFINED-SYMBOL has special meanings when used as CANDIDATE-INDEX:
87 ;; ;; '@0', '@1', ... '@9'
88 ;; ;; The 0th, 1th, ... 9th candidate of the current candidate group.
89 ;; ;; '@<', '@=', '@>'
90 ;; ;; The first, current, and end candidate of the current candidate
93 ;; ;; The previous candidate. If the current candidate is the
94 ;; ;; first of the current candidate group, the last candidate of
95 ;; ;; the previous candidate group.
97 ;; ;; The next candidate. If the current candidate is the last of
98 ;; ;; the current candidate group, the first candidate of the
99 ;; ;; previous candidate group.
101 ;; ;; PREDEFINED-SYMBOL has special meanings when used as
102 ;; ;; CANDIDATE-GROUP-INDEX:
103 ;; ;; '@0', '@1', ... '@9'
104 ;; ;; The 0th, 1th, ... 9th candidate group.
105 ;; ;; '@<', '@=', '@>'
106 ;; ;; The first, current, and end candidate group.
108 ;; ;; The previous and the next candidate group.
110 ;; ;; (insert MTEXT) inserts MTEXT before @=.
112 ;; ;; (candidates CANDIDATE-GROUP *) set the current candidates list
113 ;; ;; to the list of arguments, set the current candidate group to the
114 ;; ;; first argument, insert the first candidate of the current group
115 ;; ;; before @=, and mark the inserted text as the current candidate.
116 ;; ;; Each element of CANDIDATE-GROUP represents a candidate, i.e. if
117 ;; ;; CANDIDATE-GROUP is MTEXT, each character in MTEXT is a
118 ;; ;; candidate, if CANDIDATE-GROUP is a list of MTEXT, each MTEXT is
121 ;; ;; (select CANDIDATE-INDEX) replaces the current candidate with
122 ;; ;; what specified by CANDIDATE-INDEX. If a candidate of the
123 ;; ;; different candidate group is specified, set the current
124 ;; ;; candidate group to that group.
126 ;; ;; (select-group CANDIDATE-GROUP-INDEX) sets the current candidate
127 ;; ;; group to a group indicated by CANDIDATE-GROUP-INDEX, and relaces
128 ;; ;; the current candiate with the candiate of the same index in the
131 ;; ;; (delete MARKER) deletes characters between @= and the position
132 ;; ;; specified by MARKER.
134 ;; ;; (move MARKER) sets @= to the position of specified by MARKER.
136 ;; ;; (mark MARKER) sets MARKER to the position of @=. MARKER must
137 ;; ;; not be PREDEFINED-SYMBOL.
139 ;; ;; (pushback) pushbacks the latest key events to the event queue.
141 ;; ;; (undo) cancels the last key events.
143 ;; ;; (shift STATE-NAME) shifts the current state to the state
144 ;; ;; specified by STATE-NAME.
146 ;; ;; (call FUNCTION ARG *) calls the function FUNCTION of an external
147 ;; ;; module. FUNCTION must be defined in MODULE-LIST.
149 ;; ;; The function is called with a property list (MPlist *) that has
150 ;; ;; these properties in this order.
153 ;; ;; mtext The current preedit text.
154 ;; ;; symbol The current state name (MSymbol).
155 ;; ;; The remaining properties (if any) are ARGs.
157 ;; ;; The function must return a property list (MPlist *) that
158 ;; ;; represents a list of ACTIONs to take.
161 ;; '(' 'module' MODULE * ')'
164 ;; '(' MODULE-NAME FUNCTION * ')'
173 ;; '(' 'state' STATE * ')'
176 ;; '(' STATE-NAME BRANCH * ')'
182 ;; '(' [ MAP-NAME | 'nil' ] BRANCH-ACTION * ')'
184 ;; ;; If MAP-NAME is specified, it must be a name of a map defined in
185 ;; ;; MAP-LIST. Otherwise, BRANCH is the default branch of STATE.
199 ("bb" (("BB" "Bb"))))
202 ((Right) (select @+))))
207 (double (shift selection)))
211 ;; When this input method is loaded, the following state transition
212 ;; machine is created.
214 ;; STATE-TRANSITION-MACHINE ::=
215 ;; '(' STATE-NAME ROOT-MAP ')' *
216 ;; ROOT-MAP ::= TRANSITION-MAP
217 ;; TRANSITION-MAP ::=
218 ;; '(' INDEX [ KEY | 'nil' ]
219 ;; MAP-ACTIONS TRANSITION-MAPS BRANCH-ACTIONS ')'
220 ;; TRANSITION-MAPS ::=
221 ;; '(' TRANSITION-MAP * ')'
223 ;; '(' MAP-ACTION * ')'
224 ;; BRANCH-ACTIONS ::=
225 ;; '(' BRANCH-ACTION * ')'
229 ((#1 'a' ((insert "A")) nil nil)
230 (#2 'b' ((insert "B"))
231 ((#3 'b' ((candidates (("BB" "Bb")))) nil (shift selection)))
236 ((#5 'Left' ((delete @<) (select @-)) nil nil)
237 (#6 'Right' ((delete @<) (select @+)) nil nil))
240 ;; The state transition machine keeps these things:
241 ;; STATE: the current state, initially 'init'.
242 ;; MAP: current transition map, initially #0.
243 ;; PREEDIT: the preediting buffer, initially empty.
244 ;; MARKERS: the positions assigned to each marker, @= is initially 0.
245 ;; PRODUCED: the produced text, initially empty.
246 ;; CANDIDATE-LIST: the current candidate group list, initially NULL.
247 ;; CANDIDATE-GROUP: the current candidate group, initially NULL.
248 ;; CANDIDATE: the the current candidate, initially NULL.
250 ;; When MAP is changed to the root map of the initial state, PREEDIT
251 ;; is concatenated to PRODUCED and reset to empty. This way, the
252 ;; machine produces a text.
254 ;; The machine accepts one key KEY, handles it while updating internal
255 ;; information, and return 'nil' (if KEY is correctly handled) or KEY
256 ;; (if KEY can't be handled in the machine).
258 ;; Here we describes how the key sequence:
259 ;; 'a' 'b' 'b' 'Right' 'b' 'a'
260 ;; is handled by the machine and "aBbba" is produced.
264 ;; Lookup the transition maps of #0 for 'a' and find #1. Change MAP
265 ;; to #1. Perform its map actions. Now PREEDIT contains "a". As it
266 ;; has no sub transition maps, no branch actions, no state to shift,
267 ;; change MAP to #0, the root map of the current state.
269 ;; As we have changed MAP to the root map of the initial map,
270 ;; concatenate PREEDIT to PRODUCED, and reset PREEDIT to empty.
272 ;; Now we have consumed the key. As MAP has sub transition maps, wait
277 ;; Lookup #0 for 'b' and find #2. Change MAP to #2. Perform the map
278 ;; actions. Now, PREEDIT contains "B". As it has sub transition
279 ;; maps, and we have consumed the key, wait for the next key.
284 ;; Lookup #2 for 'b' and find #3. Cancel the change in PREEDIT done
285 ;; by the map actions of #2, and change MAP to #3. Perform the map
286 ;; actions. Now, PREEDIT is "BB", CANDIDATE-LIST is (("BB" "Bb")),
287 ;; CANDIDATE is "BB". As #3 has no sub transition maps and no branch
288 ;; actions, change STATE to 'selection' and change MAP to #4, the root
289 ;; map of 'selection'. As it has sub transition maps, and we have
290 ;; consumed the key. Wait for the next key.
294 ;; Lookup #4 for 'Right' and find #5. Change MAP to #5. Perform the
295 ;; map actions. Now PREEDIT is "Bb". As #5 has no sub transition
296 ;; maps, no branch actions, no state to shift, change MAP to #4 (the
297 ;; initial map of the current state 'selection'.
299 ;; As #4 has sub transition maps, and we have consumed the key. Wait
304 ;; Lookup #4 for 'b' and fail. As #4 has no branch maps, no shift to
305 ;; transit, change STATE to 'init', MAP to #0.
307 ;; As we have changed MAP to the root map of the initial map,
308 ;; concatenate PREEDIT to PRODUCED, and reset PREEDIT to empty. Now
309 ;; PRODUCED has "aBb".
311 ;; As we have not yet consumed the key 'b', handle it in MAP (#0).
313 ;; Lookup #0 for 'b' and find #2. Change MAP to #2. Perform the map
314 ;; actions. Now, PREEDIT contains "B". As it has sub transition
315 ;; maps, and we have consumed the key, wait for the next key.
317 ;; 'a' arrives. Lookup #2 for 'a' and fail. As #2 has no branch
318 ;; actions, no state to shift, Change MAP to #0, the root map of the
321 ;; As we have changed MAP to the root map of the initial map,
322 ;; concatenate PREEDIT to PRODUCED, and reset PREEDIT to empty. Now
323 ;; PRODUCED has "aBbb".
325 ;; As we have not yet consumed the key 'a', handle it in MAP (#0).
327 ;; Lookup #0 for 'a' and find #1. Change MAP to #1. Perform its map
328 ;; actions. Now PREEDIT contains "a". As it has no sub transition
329 ;; maps, no branch actions, no state to shift, change MAP to #0, the
330 ;; root map of the current state.
332 ;; As we have changed MAP to the root map of the initial map,
333 ;; concatenate PREEDIT to PRODUCED, and reset PREEDIT to empty. Now
334 ;; PRODUCED has "aBbba".
336 ;; Now we have consumed the key. As MAP has sub transition maps, wait