Commit | Line | Data |
---|---|---|
b3ccb19c | 1 | ;;; hangul.el --- Korean Hangul input method |
24b31c88 | 2 | |
73b0cd50 | 3 | ;; Copyright (C) 2008-2011 Free Software Foundation, Inc. |
4ad9c1c9 | 4 | |
b3ccb19c | 5 | ;; Author: Jihyun Cho <jihyun.jo@gmail.com> |
24b31c88 KH |
6 | ;; Keywords: multilingual, input method, Korean, Hangul |
7 | ||
8 | ;; This file is part of GNU Emacs. | |
9 | ||
3d544458 | 10 | ;; GNU Emacs is free software: you can redistribute it and/or modify |
24b31c88 | 11 | ;; it under the terms of the GNU General Public License as published by |
3d544458 GM |
12 | ;; the Free Software Foundation, either version 3 of the License, or |
13 | ;; (at your option) any later version. | |
24b31c88 KH |
14 | |
15 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
16 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
17 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
18 | ;; GNU General Public License for more details. | |
19 | ||
20 | ;; You should have received a copy of the GNU General Public License | |
3d544458 | 21 | ;; along with GNU Emacs. If not, see <http://www.gnu.org/licenses/>. |
24b31c88 | 22 | |
be567141 PJ |
23 | ;;; Commentary: |
24 | ||
b3ccb19c KH |
25 | ;; This file is to implement the following hangul automata: |
26 | ;; - Hangul 2-Bulsik input method | |
27 | ;; - Hangul 3-Bulsik final input method | |
28 | ;; - Hangul 3-Bulsik 390 input method | |
a155c353 | 29 | |
24b31c88 KH |
30 | ;;; Code: |
31 | ||
32 | (require 'quail) | |
5ac1f9e0 | 33 | (eval-when-compile (require 'cl)) ; for setf |
b3ccb19c KH |
34 | (require 'hanja-util) |
35 | ||
3436ab42 | 36 | ;; Hangul double Jamo table. |
ebba3e08 KH |
37 | ;; The format is an alist of JAMO-TYPE vs. DOUBLE-JAMO-TABLE. |
38 | ;; | |
39 | ;; JAMO-TYPE is a symbol `cho' for Choseong, `jung' for Jungseong, and | |
40 | ;; `jong' for Jongseong. | |
41 | ;; | |
3436ab42 | 42 | ;; DOUBLE-JAMO-TABLE is an alist of Jamo index vs. the vector of Jamo |
ebba3e08 KH |
43 | ;; indies that can be combined with the car part. |
44 | ;; | |
45 | ;; Jamo index is a relative index in `hangul Compatibility Jamo' area | |
46 | ;; of the Unicode (i.e. 1 for U+3131). | |
47 | ||
b3ccb19c | 48 | (defconst hangul-djamo-table |
ebba3e08 | 49 | '((cho . ((1 . [1]) ; Choseong |
b3ccb19c KH |
50 | (7 . [7]) |
51 | (18 . [18]) | |
52 | (21 . [21]) | |
53 | (24 . [24]))) | |
ebba3e08 | 54 | (jung . ((39 . [31 32 51]) ; Jungseong |
b3ccb19c KH |
55 | (44 . [35 36 51]) |
56 | (49 . [51]))) | |
ebba3e08 | 57 | (jong . ((1 . [1 21]) ; Jongseong |
b3ccb19c KH |
58 | (4 . [24 30]) |
59 | (9 . [1 17 18 21 28 29 30]) | |
60 | (18 . [18 21]) | |
61 | (21 . [21]))))) | |
62 | ||
63 | ;; Hangul 2-Bulsik keymap. | |
ebba3e08 | 64 | ;; It converts an ASCII code A-Z, a-z, to the corresponding hangul |
3436ab42 | 65 | ;; Jamo index. |
ebba3e08 | 66 | |
b3ccb19c KH |
67 | (defconst hangul2-keymap |
68 | [17 48 26 23 7 9 30 39 33 35 31 51 49 44 32 36 18 1 4 21 37 29 24 28 43 27]) | |
69 | ||
70 | ;; Hangul 3-Bulsik final keymap. 3-Bulsik use full keyboard layout. | |
ebba3e08 | 71 | ;; Therefore, we must map all printable ASCII codes (`!' to `~') |
b3ccb19c | 72 | ;; to Hangul 3-Bulsik codes. |
ebba3e08 | 73 | ;; Other parts are the same as `hangul2-keymap'. |
b3ccb19c KH |
74 | (defconst hangul3-keymap |
75 | [2 183 24 15 14 8220 120 39 126 8221 43 44 41 46 74 119 30 22 18 78 83 | |
76 | 68 73 85 79 52 110 44 62 46 33 10 7 63 27 12 5 11 69 48 55 49 50 51 | |
77 | 34 45 56 57 29 16 6 13 54 3 28 20 53 26 40 58 60 61 59 42 23 79 71 | |
78 | 86 72 66 84 96 109 115 93 116 122 113 118 121 21 67 4 70 99 74 9 1 | |
79 | 101 17 37 92 47 8251]) | |
80 | ||
81 | ;; Hangul 3-Bulsik 390 keymap. | |
ebba3e08 | 82 | ;; The role is the same as `hangul3-keymap'. |
b3ccb19c KH |
83 | (defconst hangul390-keymap |
84 | [24 34 35 36 37 38 120 40 41 42 43 44 45 46 73 119 30 22 18 77 82 67 72 | |
85 | 84 78 58 110 50 61 51 63 64 7 33 11 10 27 2 47 39 56 52 53 54 49 48 | |
86 | 57 62 29 68 6 59 55 16 28 20 60 26 91 92 93 94 95 96 23 78 70 85 71 | |
87 | 65 83 90 109 115 87 116 122 113 118 121 21 66 4 69 99 73 9 1 101 17 | |
88 | 123 124 125 126]) | |
89 | ||
90 | (defvar hangul-im-keymap | |
91 | (let ((map (make-sparse-keymap))) | |
92 | (define-key map "\d" 'hangul-delete-backward-char) | |
93 | (define-key map [f9] 'hangul-to-hanja-conversion) | |
d5e9630f | 94 | (define-key map [Hangul_Hanja] 'hangul-to-hanja-conversion) |
b3ccb19c | 95 | map) |
ad8f55ac | 96 | "Keymap for Hangul method. It is used by all Hangul input methods.") |
b3ccb19c KH |
97 | |
98 | ;; Current input character buffer. Store separated hangul character. | |
3436ab42 KH |
99 | ;; The first and second are Choseong position. |
100 | ;; The third and forth are Jungseong position. | |
101 | ;; The fifth and sixth are Jongseong position. | |
102 | ;; The second, forth and sixth are double Jamo position. | |
b3ccb19c KH |
103 | (defvar hangul-queue |
104 | (make-vector 6 0)) | |
105 | ||
106 | (defsubst notzerop (number) | |
107 | (not (zerop number))) | |
108 | ||
109 | (defsubst alphabetp (char) | |
110 | (or (and (>= char ?A) (<= char ?Z)) | |
111 | (and (>= char ?a) (<= char ?z)))) | |
112 | ||
113 | (defun hangul-character (cho jung jong) | |
ebba3e08 KH |
114 | "Convert CHO, JUNG, JONG to the precomposed `Hangul Syllables' character. |
115 | CHO, JUNG, JONG are relative indices in `Hangul Compatibility Jamo' of unicode. | |
116 | Return a zero-length string if the conversion fails." | |
b3ccb19c KH |
117 | (or |
118 | (decode-char | |
119 | 'ucs | |
120 | (if (and (/= cho 0) (/= jung 0)) | |
121 | (+ #xac00 | |
122 | (* 588 | |
123 | (- cho | |
124 | (cond ((< cho 3) 1) | |
125 | ((< cho 5) 2) | |
126 | ((< cho 10) 4) | |
127 | ((< cho 20) 11) | |
128 | (t 12)))) | |
129 | (* 28 (- jung 31)) | |
130 | (- jong | |
131 | (cond ((< jong 8) 0) | |
132 | ((< jong 19) 1) | |
133 | ((< jong 25) 2) | |
134 | (t 3)))) | |
3436ab42 KH |
135 | (+ #x3130 |
136 | (cond ((/= cho 0) cho) | |
137 | ((/= jung 0) jung) | |
138 | ((/= jong 0) jong))))) | |
b3ccb19c KH |
139 | "")) |
140 | ||
141 | (defun hangul-insert-character (&rest queues) | |
ad8f55ac JB |
142 | "Insert characters generated from QUEUES. |
143 | Each queue has the same form as `hangul-queue'. | |
ebba3e08 | 144 | Setup `quail-overlay' to the last character." |
b3ccb19c KH |
145 | (if (and mark-active transient-mark-mode) |
146 | (progn | |
147 | (delete-region (region-beginning) (region-end)) | |
148 | (deactivate-mark))) | |
149 | (quail-delete-region) | |
150 | (let ((first (car queues))) | |
151 | (insert | |
152 | (hangul-character | |
153 | (+ (aref first 0) (hangul-djamo 'cho (aref first 0) (aref first 1))) | |
154 | (+ (aref first 2) (hangul-djamo 'jung (aref first 2) (aref first 3))) | |
155 | (+ (aref first 4) (hangul-djamo 'jong (aref first 4) (aref first 5)))))) | |
156 | (move-overlay quail-overlay (overlay-start quail-overlay) (point)) | |
157 | (dolist (queue (cdr queues)) | |
158 | (insert | |
159 | (hangul-character | |
160 | (+ (aref queue 0) (hangul-djamo 'cho (aref queue 0) (aref queue 1))) | |
161 | (+ (aref queue 2) (hangul-djamo 'jung (aref queue 2) (aref queue 3))) | |
162 | (+ (aref queue 4) (hangul-djamo 'jong (aref queue 4) (aref queue 5))))) | |
163 | (move-overlay quail-overlay (1+ (overlay-start quail-overlay)) (point)))) | |
164 | ||
165 | (defun hangul-djamo (jamo char1 char2) | |
ad8f55ac | 166 | "Return the double Jamo index calculated from the arguments. |
3436ab42 | 167 | JAMO is a type of Hangul Jamo; `cho', `jung', or `jong'. |
53a8f9db | 168 | CHAR1 and CHAR2 are Hangul Jamo indices. |
ad8f55ac | 169 | Return nil if CHAR1 and CHAR2 can not be combined." |
b3ccb19c KH |
170 | (let* ((jamo (cdr (assoc jamo hangul-djamo-table))) |
171 | (char1 (cdr (assoc char1 jamo)))) | |
172 | (if char1 | |
173 | (let ((i (length char1))) | |
174 | (or (catch 'found | |
175 | (while (> i 0) | |
176 | (if (= char2 (aref char1 (1- i))) | |
177 | (throw 'found i)) | |
178 | (setf i (1- i)))) | |
179 | 0)) | |
3436ab42 | 180 | 0))) |
b3ccb19c | 181 | |
b3ccb19c | 182 | (defsubst hangul2-input-method-jaum (char) |
3436ab42 KH |
183 | "Store Hangul Jamo indice CHAR in `hangul-queue'. |
184 | It is a Hangul 2-Bulsik Jaum. | |
185 | This function processes a Hangul 2-Bulsik Jaum. | |
186 | The Hangul 2-Bulsik is composed of a Jaum and a Moum. | |
187 | The Jaum can be located in a Choseong position and a Jongseong position. | |
188 | Unless the function inserts CHAR to `hangul-queue', | |
189 | commit current `hangul-queue' and then set a new `hangul-queue', | |
190 | and insert CHAR to new `hangul-queue'." | |
b3ccb19c KH |
191 | (if (cond ((zerop (aref hangul-queue 0)) |
192 | (aset hangul-queue 0 char)) | |
193 | ((and (zerop (aref hangul-queue 1)) | |
194 | (zerop (aref hangul-queue 2)) | |
195 | (notzerop (hangul-djamo 'cho (aref hangul-queue 0) char))) | |
196 | (aset hangul-queue 1 char)) | |
197 | ((and (zerop (aref hangul-queue 4)) | |
198 | (notzerop (aref hangul-queue 2)) | |
199 | (/= char 8) | |
200 | (/= char 19) | |
201 | (/= char 25) | |
202 | (numberp | |
203 | (hangul-character | |
204 | (+ (aref hangul-queue 0) | |
205 | (hangul-djamo | |
206 | 'cho | |
207 | (aref hangul-queue 0) | |
208 | (aref hangul-queue 1))) | |
209 | (+ (aref hangul-queue 2) | |
210 | (hangul-djamo | |
211 | 'jung | |
212 | (aref hangul-queue 2) | |
213 | (aref hangul-queue 3))) | |
214 | char))) | |
215 | (aset hangul-queue 4 char)) | |
216 | ((and (zerop (aref hangul-queue 5)) | |
217 | (notzerop (hangul-djamo 'jong (aref hangul-queue 4) char)) | |
218 | (numberp | |
219 | (hangul-character | |
220 | (+ (aref hangul-queue 0) | |
221 | (hangul-djamo | |
222 | 'cho | |
223 | (aref hangul-queue 0) | |
224 | (aref hangul-queue 1))) | |
225 | (+ (aref hangul-queue 2) | |
226 | (hangul-djamo | |
227 | 'jung | |
228 | (aref hangul-queue 2) | |
229 | (aref hangul-queue 3))) | |
230 | (+ (aref hangul-queue 4) | |
231 | (hangul-djamo | |
232 | 'jong | |
233 | (aref hangul-queue 4) | |
234 | char))))) | |
235 | (aset hangul-queue 5 char))) | |
236 | (hangul-insert-character hangul-queue) | |
3436ab42 KH |
237 | (hangul-insert-character hangul-queue |
238 | (setq hangul-queue (vector char 0 0 0 0 0))))) | |
b3ccb19c KH |
239 | |
240 | (defsubst hangul2-input-method-moum (char) | |
3436ab42 KH |
241 | "Store Hangul Jamo indice CHAR in `hangul-queue'. |
242 | It is a Hangul 2-Bulsik Moum. | |
ad8f55ac | 243 | This function processes a Hangul 2-Bulsik Moum. |
3436ab42 | 244 | The Moum can be located in a Jungseong position. |
ebba3e08 | 245 | Other parts are the same as a `hangul2-input-method-jaum'." |
b3ccb19c KH |
246 | (if (cond ((zerop (aref hangul-queue 2)) |
247 | (aset hangul-queue 2 char)) | |
248 | ((and (zerop (aref hangul-queue 3)) | |
249 | (zerop (aref hangul-queue 4)) | |
250 | (notzerop (hangul-djamo 'jung (aref hangul-queue 2) char))) | |
251 | (aset hangul-queue 3 char))) | |
252 | (hangul-insert-character hangul-queue) | |
3436ab42 KH |
253 | (let ((next-char (vector 0 0 char 0 0 0))) |
254 | (cond ((notzerop (aref hangul-queue 5)) | |
255 | (aset next-char 0 (aref hangul-queue 5)) | |
256 | (aset hangul-queue 5 0)) | |
257 | ((notzerop (aref hangul-queue 4)) | |
258 | (aset next-char 0 (aref hangul-queue 4)) | |
259 | (aset hangul-queue 4 0))) | |
260 | (hangul-insert-character hangul-queue | |
261 | (setq hangul-queue next-char))))) | |
b3ccb19c KH |
262 | |
263 | (defsubst hangul3-input-method-cho (char) | |
3436ab42 KH |
264 | "Store Hangul Jamo indice CHAR in `hangul-queue'. |
265 | It is a Hangul 3-Bulsik Choseong. | |
ad8f55ac | 266 | This function processes a Hangul 3-Bulsik Choseong. |
3436ab42 KH |
267 | The Hangul 3-Bulsik is composed of a Choseong, a Jungseong and a Jongseong. |
268 | The Choseong can be located in a Choseong position. | |
ebba3e08 | 269 | Other parts are the same as a `hangul2-input-method-jaum'." |
b3ccb19c KH |
270 | (if (cond ((and (zerop (aref hangul-queue 0)) |
271 | (zerop (aref hangul-queue 4))) | |
272 | (aset hangul-queue 0 char)) | |
273 | ((and (zerop (aref hangul-queue 1)) | |
274 | (zerop (aref hangul-queue 2)) | |
275 | (notzerop (hangul-djamo 'cho (aref hangul-queue 0) char))) | |
276 | (aset hangul-queue 1 char))) | |
277 | (hangul-insert-character hangul-queue) | |
3436ab42 KH |
278 | (hangul-insert-character hangul-queue |
279 | (setq hangul-queue (vector char 0 0 0 0 0))))) | |
b3ccb19c KH |
280 | |
281 | (defsubst hangul3-input-method-jung (char) | |
3436ab42 KH |
282 | "Store Hangul Jamo indice CHAR in `hangul-queue'. |
283 | It is a Hangul 3-Bulsik Jungseong. | |
ad8f55ac | 284 | This function processes a Hangul 3-Bulsik Jungseong. |
3436ab42 | 285 | The Jungseong can be located in a Jungseong position. |
ebba3e08 | 286 | Other parts are the same as a `hangul3-input-method-cho'." |
b3ccb19c KH |
287 | (if (cond ((and (zerop (aref hangul-queue 2)) |
288 | (zerop (aref hangul-queue 4))) | |
289 | (aset hangul-queue 2 char)) | |
290 | ((and (zerop (aref hangul-queue 3)) | |
291 | (notzerop (hangul-djamo 'jung (aref hangul-queue 2) char))) | |
292 | (aset hangul-queue 3 char))) | |
293 | (hangul-insert-character hangul-queue) | |
3436ab42 KH |
294 | (hangul-insert-character hangul-queue |
295 | (setq hangul-queue (vector 0 0 char 0 0 0))))) | |
b3ccb19c KH |
296 | |
297 | (defsubst hangul3-input-method-jong (char) | |
3436ab42 KH |
298 | "Store Hangul Jamo indice CHAR in `hangul-queue'. |
299 | It is a Hangul 3-Bulsik Jongseong. | |
ad8f55ac | 300 | This function processes a Hangul 3-Bulsik Jongseong. |
3436ab42 | 301 | The Jongseong can be located in a Jongseong position. |
ebba3e08 | 302 | Other parts are the same as a `hangul3-input-method-cho'." |
b3ccb19c KH |
303 | (if (cond ((and (zerop (aref hangul-queue 4)) |
304 | (notzerop (aref hangul-queue 0)) | |
305 | (notzerop (aref hangul-queue 2)) | |
306 | (numberp | |
307 | (hangul-character | |
308 | (+ (aref hangul-queue 0) | |
309 | (hangul-djamo | |
310 | 'cho | |
311 | (aref hangul-queue 0) | |
312 | (aref hangul-queue 1))) | |
313 | (+ (aref hangul-queue 2) | |
314 | (hangul-djamo | |
315 | 'jung | |
316 | (aref hangul-queue 2) | |
317 | (aref hangul-queue 3))) | |
318 | char))) | |
319 | (aset hangul-queue 4 char)) | |
320 | ((and (zerop (aref hangul-queue 5)) | |
321 | (notzerop (hangul-djamo 'jong (aref hangul-queue 4) char)) | |
322 | (numberp | |
323 | (hangul-character | |
324 | (+ (aref hangul-queue 0) | |
325 | (hangul-djamo | |
326 | 'cho | |
327 | (aref hangul-queue 0) | |
328 | (aref hangul-queue 1))) | |
329 | (+ (aref hangul-queue 2) | |
330 | (hangul-djamo | |
331 | 'jung | |
332 | (aref hangul-queue 2) | |
333 | (aref hangul-queue 3))) | |
334 | (+ (aref hangul-queue 4) | |
335 | (hangul-djamo | |
336 | 'jong | |
337 | (aref hangul-queue 4) | |
338 | char))))) | |
92135d25 | 339 | (aset hangul-queue 5 char))) |
b3ccb19c | 340 | (hangul-insert-character hangul-queue) |
3436ab42 KH |
341 | (if (zerop (apply '+ (append hangul-queue nil))) |
342 | (hangul-insert-character (setq hangul-queue (vector 0 0 0 0 char 0))) | |
343 | (hangul-insert-character hangul-queue | |
344 | (setq hangul-queue (vector 0 0 0 0 char 0)))))) | |
b3ccb19c KH |
345 | |
346 | (defun hangul-delete-backward-char () | |
3436ab42 | 347 | "Delete the previous hangul character by Jaso units." |
b3ccb19c KH |
348 | (interactive) |
349 | (let ((i 5)) | |
350 | (while (and (> i 0) (zerop (aref hangul-queue i))) | |
351 | (setq i (1- i))) | |
352 | (aset hangul-queue i 0)) | |
353 | (if (notzerop (apply '+ (append hangul-queue nil))) | |
354 | (hangul-insert-character hangul-queue) | |
3436ab42 | 355 | (delete-backward-char 1))) |
24b31c88 | 356 | |
b3ccb19c | 357 | (defun hangul-to-hanja-conversion () |
8000b1d5 KH |
358 | "Convert the previous hangul character to the corresponding hanja character. |
359 | When a Korean input method is off, convert the following hangul character." | |
b3ccb19c KH |
360 | (interactive) |
361 | (let ((echo-keystrokes 0) | |
362 | delete-func | |
363 | hanja-character) | |
8000b1d5 KH |
364 | (if (and (overlayp quail-overlay) (overlay-start quail-overlay)) |
365 | (progn | |
366 | (setq hanja-character (hangul-to-hanja-char (preceding-char))) | |
367 | (setq delete-func (lambda () (delete-backward-char 1)))) | |
368 | (setq hanja-character (hangul-to-hanja-char (following-char))) | |
369 | (setq delete-func (lambda () (delete-char 1)))) | |
b3ccb19c | 370 | (when hanja-character |
8000b1d5 | 371 | (funcall delete-func) |
b3ccb19c KH |
372 | (insert hanja-character) |
373 | (setq hangul-queue (make-vector 6 0)) | |
8000b1d5 KH |
374 | (if (and (overlayp quail-overlay) (overlay-start quail-overlay)) |
375 | (move-overlay quail-overlay (point) (point)))))) | |
24b31c88 | 376 | |
ebba3e08 KH |
377 | ;; Support function for `hangul2-input-method'. Actually, this |
378 | ;; function handles the Hangul 2-Bulsik. KEY is an entered key code | |
379 | ;; used for looking up `hangul2-keymap'." | |
b3ccb19c KH |
380 | (defun hangul2-input-method-internal (key) |
381 | (let ((char (+ (aref hangul2-keymap (1- (% key 32))) | |
382 | (cond ((or (= key ?O) (= key ?P)) 2) | |
383 | ((or (= key ?E) (= key ?Q) (= key ?R) | |
384 | (= key ?T) (= key ?W)) 1) | |
385 | (t 0))))) | |
386 | (if (< char 31) | |
387 | (hangul2-input-method-jaum char) | |
3436ab42 | 388 | (hangul2-input-method-moum char)))) |
24b31c88 | 389 | |
b3ccb19c | 390 | (defun hangul2-input-method (key) |
ebba3e08 | 391 | "2-Bulsik input method." |
b3ccb19c KH |
392 | (if (or buffer-read-only (not (alphabetp key))) |
393 | (list key) | |
3436ab42 KH |
394 | (quail-setup-overlays nil) |
395 | (let ((input-method-function nil) | |
396 | (echo-keystrokes 0) | |
397 | (help-char nil)) | |
398 | (setq hangul-queue (make-vector 6 0)) | |
399 | (hangul2-input-method-internal key) | |
400 | (unwind-protect | |
401 | (catch 'exit-input-loop | |
402 | (while t | |
403 | (let* ((seq (read-key-sequence nil)) | |
404 | (cmd (lookup-key hangul-im-keymap seq)) | |
405 | key) | |
406 | (cond ((and (stringp seq) | |
407 | (= 1 (length seq)) | |
408 | (setq key (aref seq 0)) | |
409 | (alphabetp key)) | |
410 | (hangul2-input-method-internal key)) | |
411 | ((commandp cmd) | |
412 | (call-interactively cmd)) | |
413 | (t | |
414 | (setq unread-command-events (listify-key-sequence seq)) | |
415 | (throw 'exit-input-loop nil)))))) | |
416 | (quail-delete-overlays))))) | |
24b31c88 | 417 | |
ebba3e08 KH |
418 | ;; Support function for `hangul3-input-method'. Actually, this |
419 | ;; function handles the Hangul 3-Bulsik final. KEY is an entered key | |
420 | ;; code used for looking up `hangul3-keymap'." | |
b3ccb19c KH |
421 | (defun hangul3-input-method-internal (key) |
422 | (let ((char (aref hangul3-keymap (- key 33)))) | |
423 | (cond ((and (> char 92) (< char 123)) | |
424 | (hangul3-input-method-cho (- char 92))) | |
425 | ((and (> char 65) (< char 87)) | |
426 | (hangul3-input-method-jung (- char 35))) | |
427 | ((< char 31) | |
428 | (hangul3-input-method-jong char)) | |
429 | (t | |
430 | (setq hangul-queue (make-vector 6 0)) | |
431 | (insert (decode-char 'ucs char)) | |
432 | (move-overlay quail-overlay (point) (point)))))) | |
177c0ea7 | 433 | |
b3ccb19c | 434 | (defun hangul3-input-method (key) |
ebba3e08 | 435 | "3-Bulsik final input method." |
b3ccb19c KH |
436 | (if (or buffer-read-only (< key 33) (>= key 127)) |
437 | (list key) | |
3436ab42 KH |
438 | (quail-setup-overlays nil) |
439 | (let ((input-method-function nil) | |
440 | (echo-keystrokes 0) | |
441 | (help-char nil)) | |
442 | (setq hangul-queue (make-vector 6 0)) | |
443 | (hangul3-input-method-internal key) | |
444 | (unwind-protect | |
445 | (catch 'exit-input-loop | |
446 | (while t | |
447 | (let* ((seq (read-key-sequence nil)) | |
448 | (cmd (lookup-key hangul-im-keymap seq)) | |
449 | key) | |
450 | (cond ((and (stringp seq) | |
451 | (= 1 (length seq)) | |
452 | (setq key (aref seq 0)) | |
453 | (and (>= key 33) (< key 127))) | |
454 | (hangul3-input-method-internal key)) | |
455 | ((commandp cmd) | |
456 | (call-interactively cmd)) | |
457 | (t | |
458 | (setq unread-command-events (listify-key-sequence seq)) | |
459 | (throw 'exit-input-loop nil)))))) | |
460 | (quail-delete-overlays))))) | |
177c0ea7 | 461 | |
ebba3e08 KH |
462 | ;; Support function for `hangul390-input-method'. Actually, this |
463 | ;; function handles the Hangul 3-Bulsik 390. KEY is an entered key | |
464 | ;; code used for looking up `hangul390-keymap'." | |
b3ccb19c KH |
465 | (defun hangul390-input-method-internal (key) |
466 | (let ((char (aref hangul390-keymap (- key 33)))) | |
467 | (cond ((or (and (> char 86) (< char 91)) | |
468 | (and (> char 96) (< char 123))) | |
469 | (hangul3-input-method-cho (- char (if (< char 97) 86 92)))) | |
470 | ((and (> char 64) (< char 86)) | |
471 | (hangul3-input-method-jung (- char 34))) | |
472 | ((< char 31) | |
473 | (hangul3-input-method-jong char)) | |
474 | (t | |
475 | (setq hangul-queue (make-vector 6 0)) | |
476 | (insert (decode-char 'ucs char)) | |
477 | (move-overlay quail-overlay (point) (point)))))) | |
177c0ea7 | 478 | |
b3ccb19c | 479 | (defun hangul390-input-method (key) |
ebba3e08 | 480 | "3-Bulsik 390 input method." |
b3ccb19c KH |
481 | (if (or buffer-read-only (< key 33) (>= key 127)) |
482 | (list key) | |
3436ab42 KH |
483 | (quail-setup-overlays nil) |
484 | (let ((input-method-function nil) | |
485 | (echo-keystrokes 0) | |
486 | (help-char nil)) | |
487 | (setq hangul-queue (make-vector 6 0)) | |
488 | (hangul390-input-method-internal key) | |
489 | (unwind-protect | |
490 | (catch 'exit-input-loop | |
491 | (while t | |
492 | (let* ((seq (read-key-sequence nil)) | |
493 | (cmd (lookup-key hangul-im-keymap seq)) | |
494 | key) | |
495 | (cond ((and (stringp seq) | |
496 | (= 1 (length seq)) | |
497 | (setq key (aref seq 0)) | |
498 | (and (>= key 33) (< key 127))) | |
499 | (hangul390-input-method-internal key)) | |
500 | ((commandp cmd) | |
501 | (call-interactively cmd)) | |
502 | (t | |
503 | (setq unread-command-events (listify-key-sequence seq)) | |
504 | (throw 'exit-input-loop nil)))))) | |
505 | (quail-delete-overlays))))) | |
177c0ea7 | 506 | |
b3ccb19c KH |
507 | ;; Text shown by describe-input-method. Set to a proper text by |
508 | ;; hangul-input-method-activate. | |
509 | (defvar hangul-input-method-help-text nil) | |
510 | (make-variable-buffer-local 'hangul-input-method-help-text) | |
177c0ea7 | 511 | |
b3ccb19c KH |
512 | (defun hangul-input-method-activate (input-method func help-text &rest args) |
513 | "Activate Hangul input method INPUT-METHOD. | |
514 | FUNC is a function to handle input key. | |
515 | HELP-TEXT is a text set in `hangul-input-method-help-text'." | |
516 | (setq inactivate-current-input-method-function 'hangul-input-method-inactivate | |
3436ab42 KH |
517 | describe-current-input-method-function 'hangul-input-method-help |
518 | hangul-input-method-help-text help-text) | |
b3ccb19c KH |
519 | (quail-delete-overlays) |
520 | (if (eq (selected-window) (minibuffer-window)) | |
521 | (add-hook 'minibuffer-exit-hook 'quail-exit-from-minibuffer)) | |
522 | (set (make-local-variable 'input-method-function) func)) | |
177c0ea7 | 523 | |
b3ccb19c KH |
524 | (defun hangul-input-method-inactivate () |
525 | "Inactivate the current Hangul input method." | |
526 | (interactive) | |
527 | (unwind-protect | |
528 | (progn | |
3436ab42 KH |
529 | (quail-hide-guidance) |
530 | (quail-delete-overlays) | |
531 | (setq describe-current-input-method-function nil)) | |
b3ccb19c | 532 | (kill-local-variable 'input-method-function))) |
177c0ea7 | 533 | |
b3ccb19c KH |
534 | (defun hangul-input-method-help () |
535 | "Describe the current Hangul input method." | |
536 | (interactive) | |
537 | (with-output-to-temp-buffer "*Help*" | |
538 | (princ hangul-input-method-help-text))) | |
177c0ea7 | 539 | |
b3ccb19c | 540 | (provide 'hangul) |
be567141 PJ |
541 | |
542 | ;;; hangul.el ends here |