Commit | Line | Data |
---|---|---|
60370d40 | 1 | ;;; encoded-kb.el --- handler to input multibyte characters encoded somehow |
4ed46869 | 2 | |
4ed46869 | 3 | ;; Copyright (C) 1995 Electrotechnical Laboratory, JAPAN. |
fa526c4a | 4 | ;; Licensed to the Free Software Foundation. |
4ed46869 KH |
5 | |
6 | ;; This file is part of GNU Emacs. | |
7 | ||
8 | ;; GNU Emacs is free software; you can redistribute it and/or modify | |
9 | ;; it under the terms of the GNU General Public License as published by | |
10 | ;; the Free Software Foundation; either version 2, or (at your option) | |
11 | ;; any later version. | |
12 | ||
13 | ;; GNU Emacs is distributed in the hope that it will be useful, | |
14 | ;; but WITHOUT ANY WARRANTY; without even the implied warranty of | |
15 | ;; MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the | |
16 | ;; GNU General Public License for more details. | |
17 | ||
18 | ;; You should have received a copy of the GNU General Public License | |
369314dc KH |
19 | ;; along with GNU Emacs; see the file COPYING. If not, write to the |
20 | ;; Free Software Foundation, Inc., 59 Temple Place - Suite 330, | |
21 | ;; Boston, MA 02111-1307, USA. | |
4ed46869 | 22 | |
60370d40 PJ |
23 | ;;; Commentary: |
24 | ||
25 | ;;; Code: | |
26 | ||
068b074e | 27 | (defconst encoded-kbd-mode-map (make-sparse-keymap) |
4ed46869 KH |
28 | "Keymap for Encoded-kbd minor mode.") |
29 | ||
4ed46869 KH |
30 | ;; Subsidiary keymaps for handling ISO2022 escape sequences. |
31 | ||
32 | (defvar encoded-kbd-iso2022-esc-map | |
33 | (let ((map (make-sparse-keymap))) | |
34 | (define-key map "$" 'encoded-kbd-iso2022-esc-dollar-prefix) | |
35 | (define-key map "(" 'encoded-kbd-iso2022-designation-prefix) | |
36 | (define-key map ")" 'encoded-kbd-iso2022-designation-prefix) | |
37 | (define-key map "," 'encoded-kbd-iso2022-designation-prefix) | |
38 | (define-key map "-" 'encoded-kbd-iso2022-designation-prefix) | |
4ed46869 KH |
39 | map) |
40 | "Keymap for handling ESC code in Encoded-kbd mode.") | |
f61d15a7 | 41 | (fset 'encoded-kbd-iso2022-esc-prefix encoded-kbd-iso2022-esc-map) |
4ed46869 KH |
42 | |
43 | (defvar encoded-kbd-iso2022-esc-dollar-map | |
44 | (let ((map (make-sparse-keymap))) | |
45 | (define-key map "(" 'encoded-kbd-iso2022-designation-prefix) | |
46 | (define-key map ")" 'encoded-kbd-iso2022-designation-prefix) | |
47 | (define-key map "," 'encoded-kbd-iso2022-designation-prefix) | |
48 | (define-key map "-" 'encoded-kbd-iso2022-designation-prefix) | |
49 | (define-key map "@" 'encoded-kbd-iso2022-designation) | |
50 | (define-key map "A" 'encoded-kbd-iso2022-designation) | |
51 | (define-key map "B" 'encoded-kbd-iso2022-designation) | |
4ed46869 | 52 | map) |
f61d15a7 | 53 | "Keymap for handling ESC $ sequence in Encoded-kbd mode.") |
4ed46869 KH |
54 | (fset 'encoded-kbd-iso2022-esc-dollar-prefix |
55 | encoded-kbd-iso2022-esc-dollar-map) | |
56 | ||
57 | (defvar encoded-kbd-iso2022-designation-map | |
58 | (let ((map (make-sparse-keymap)) | |
164edac8 KH |
59 | (l charset-list) |
60 | final-char) | |
f61d15a7 | 61 | (while l |
164edac8 | 62 | (setq final-char (charset-iso-final-char (car l))) |
71b898fe | 63 | (if (> final-char 0) |
164edac8 KH |
64 | (define-key map (char-to-string final-char) |
65 | 'encoded-kbd-iso2022-designation)) | |
f61d15a7 | 66 | (setq l (cdr l))) |
4ed46869 KH |
67 | map) |
68 | "Keymap for handling ISO2022 designation sequence in Encoded-kbd mode.") | |
69 | (fset 'encoded-kbd-iso2022-designation-prefix | |
70 | encoded-kbd-iso2022-designation-map) | |
71 | ||
72 | (defvar encoded-kbd-iso2022-non-ascii-map | |
73 | (let ((map (make-keymap)) | |
74 | (i 32)) | |
75 | (while (< i 128) | |
76 | (define-key map (char-to-string i) 'encoded-kbd-self-insert-iso2022-7bit) | |
77 | (setq i (1+ i))) | |
f61d15a7 | 78 | (define-key map "\e" 'encoded-kbd-iso2022-esc-prefix) |
a0d4676a KH |
79 | (setq i 160) |
80 | (while (< i 256) | |
81 | (define-key map (vector i) 'encoded-kbd-handle-8bit) | |
82 | (setq i (1+ i))) | |
4ed46869 KH |
83 | map) |
84 | "Keymap for handling non-ASCII character set in Encoded-kbd mode.") | |
85 | ||
86 | ;; One of the symbols `sjis', `iso2022-7', `iso2022-8', or `big5' to | |
87 | ;; denote what kind of coding-system we are now handling in | |
88 | ;; Encoded-kbd mode. | |
89 | (defvar encoded-kbd-coding nil) | |
90 | ||
068b074e KH |
91 | ;; Keep information of designation state of ISO2022 encoding. When |
92 | ;; Encoded-kbd mode is on, this is set to a vector of length 4, the | |
93 | ;; elements are character sets currently designated to graphic | |
94 | ;; registers 0 thru 3. | |
4ed46869 KH |
95 | |
96 | (defvar encoded-kbd-iso2022-designations nil) | |
4ed46869 KH |
97 | (put 'encoded-kbd-iso2022-designations 'permanent-local t) |
98 | ||
068b074e KH |
99 | ;; Keep information of invocation state of ISO2022 encoding. When |
100 | ;; Encoded-kbd mode is on, this is set to a vector of length 3, | |
101 | ;; graphic register numbers currently invoked to graphic plane 1 and | |
102 | ;; 2, and a single shifted graphic register number. | |
4ed46869 KH |
103 | |
104 | (defvar encoded-kbd-iso2022-invocations nil) | |
4ed46869 KH |
105 | (put 'encoded-kbd-iso2022-invocations 'permanent-local t) |
106 | ||
107 | (defun encoded-kbd-iso2022-designation () | |
e8dd0160 | 108 | "Do ISO2022 designation according to the current key in Encoded-kbd mode. |
4ed46869 KH |
109 | The following key sequence may cause multilingual text insertion." |
110 | (interactive) | |
111 | (let ((key-seq (this-command-keys)) | |
a0d4676a KH |
112 | (prev-g0-charset (aref encoded-kbd-iso2022-designations |
113 | (aref encoded-kbd-iso2022-invocations 0))) | |
4ed46869 KH |
114 | intermediate-char final-char |
115 | reg dimension chars charset) | |
f61d15a7 KH |
116 | (if (= (length key-seq) 4) |
117 | ;; ESC $ <intermediate-char> <final-char> | |
118 | (setq intermediate-char (aref key-seq 2) | |
4ed46869 KH |
119 | dimension 2 |
120 | chars (if (< intermediate-char ?,) 94 96) | |
f61d15a7 | 121 | final-char (aref key-seq 3) |
4ed46869 KH |
122 | reg (mod intermediate-char 4)) |
123 | (if (= (aref key-seq 1) ?$) | |
f61d15a7 | 124 | ;; ESC $ <final-char> |
4ed46869 KH |
125 | (setq dimension 2 |
126 | chars 94 | |
f61d15a7 | 127 | final-char (aref key-seq 2) |
4ed46869 | 128 | reg 0) |
f61d15a7 KH |
129 | ;; ESC <intermediate-char> <final-char> |
130 | (setq intermediate-char (aref key-seq 1) | |
4ed46869 KH |
131 | dimension 1 |
132 | chars (if (< intermediate-char ?,) 94 96) | |
f61d15a7 | 133 | final-char (aref key-seq 2) |
4ed46869 KH |
134 | reg (mod intermediate-char 4)))) |
135 | (if (setq charset (iso-charset dimension chars final-char)) | |
136 | (aset encoded-kbd-iso2022-designations reg charset) | |
137 | (error "Character set of DIMENSION %s, CHARS %s, FINAL-CHAR `%c' is not supported" | |
138 | dimension chars final-char)) | |
139 | ||
f61d15a7 | 140 | (if (memq (aref encoded-kbd-iso2022-designations |
a0d4676a | 141 | (aref encoded-kbd-iso2022-invocations 0)) |
f61d15a7 | 142 | '(ascii latin-jisx0201)) |
4ed46869 KH |
143 | ;; Graphic plane 0 (0x20..0x7f) is for ASCII. We don't have |
144 | ;; to handle characters in this range specially. | |
a0d4676a | 145 | (if (not (memq prev-g0-charset '(ascii latin-jisx0201))) |
e8dd0160 | 146 | ;; We must exit recursive edit now. |
a0d4676a | 147 | (throw 'exit nil)) |
4ed46869 | 148 | ;; Graphic plane 0 is for non-ASCII. |
a0d4676a | 149 | (if (memq prev-g0-charset '(ascii latin-jisx0201)) |
e8dd0160 | 150 | ;; We must handle keys specially. |
a0d4676a KH |
151 | (let ((overriding-local-map encoded-kbd-iso2022-non-ascii-map)) |
152 | (recursive-edit)))))) | |
4ed46869 KH |
153 | |
154 | (defun encoded-kbd-handle-8bit () | |
e8dd0160 | 155 | "Handle an 8-bit character entered in Encoded-kbd mode." |
4ed46869 KH |
156 | (interactive) |
157 | (cond ((eq encoded-kbd-coding 'iso2022-7) | |
158 | (error "Can't handle the character code %d" last-command-char)) | |
159 | ||
160 | ((eq encoded-kbd-coding 'iso2022-8) | |
161 | (cond ((= last-command-char ?\216) | |
162 | (aset encoded-kbd-iso2022-invocations 2 2)) | |
163 | ||
164 | ((= last-command-char ?\217) | |
165 | (aset encoded-kbd-iso2022-invocations 2 3)) | |
166 | ||
75c44f31 | 167 | ((>= last-command-char ?\240) |
4ed46869 KH |
168 | (encoded-kbd-self-insert-iso2022-8bit)) |
169 | ||
170 | (t | |
171 | (error "Can't handle the character code %d" | |
172 | last-command-char)))) | |
173 | ||
174 | ((eq encoded-kbd-coding 'sjis) | |
175 | (encoded-kbd-self-insert-sjis)) | |
176 | ||
177 | (t | |
178 | (encoded-kbd-self-insert-big5)))) | |
179 | ||
180 | (defun encoded-kbd-self-insert-iso2022-7bit () | |
181 | (interactive) | |
182 | (let* ((charset (aref encoded-kbd-iso2022-designations | |
183 | (or (aref encoded-kbd-iso2022-invocations 2) | |
184 | (aref encoded-kbd-iso2022-invocations 0)))) | |
946fdacf KH |
185 | (char (if (= (charset-dimension charset) 1) |
186 | (make-char charset last-command-char) | |
187 | (make-char charset last-command-char (read-char-exclusive))))) | |
4ed46869 | 188 | (aset encoded-kbd-iso2022-invocations 2 nil) |
946fdacf | 189 | (setq unread-command-events (cons char unread-command-events)))) |
4ed46869 KH |
190 | |
191 | (defun encoded-kbd-self-insert-iso2022-8bit () | |
192 | (interactive) | |
068b074e KH |
193 | (cond |
194 | ((= last-command-char ?\216) ; SS2 (Single Shift 2) | |
195 | (aset encoded-kbd-iso2022-invocations 2 2)) | |
196 | ((= last-command-char ?\217) ; SS3 (Single Shift 3) | |
197 | (aset encoded-kbd-iso2022-invocations 2 3)) | |
198 | (t | |
33182c8a SM |
199 | (let* ((charset (aref encoded-kbd-iso2022-designations |
200 | (or (aref encoded-kbd-iso2022-invocations 2) | |
201 | (aref encoded-kbd-iso2022-invocations 1)))) | |
202 | (char (if (= (charset-dimension charset) 1) | |
203 | (make-char charset last-command-char) | |
068b074e KH |
204 | (make-char charset last-command-char |
205 | (read-char-exclusive))))) | |
33182c8a | 206 | (aset encoded-kbd-iso2022-invocations 2 nil) |
068b074e | 207 | (setq unread-command-events (cons char unread-command-events)))))) |
4ed46869 KH |
208 | |
209 | (defun encoded-kbd-self-insert-sjis () | |
210 | (interactive) | |
946fdacf KH |
211 | (let ((char (if (or (< last-command-char ?\xA0) (>= last-command-char ?\xE0)) |
212 | (decode-sjis-char (+ (ash last-command-char 8) | |
213 | (read-char-exclusive))) | |
214 | (make-char 'katakana-jisx0201 last-command-char)))) | |
215 | (setq unread-command-events (cons char unread-command-events)))) | |
4ed46869 KH |
216 | |
217 | (defun encoded-kbd-self-insert-big5 () | |
218 | (interactive) | |
946fdacf KH |
219 | (let ((char (decode-big5-char (+ (ash last-command-char 8) |
220 | (read-char-exclusive))))) | |
221 | (setq unread-command-events (cons char unread-command-events)))) | |
4ed46869 | 222 | |
068b074e KH |
223 | (defun encoded-kbd-self-insert-ccl () |
224 | (interactive) | |
225 | (let ((str (char-to-string last-command-char)) | |
4c8d5b4b | 226 | (ccl (car (aref (coding-system-spec (keyboard-coding-system)) 4))) |
81a23e88 | 227 | (vec [nil nil nil nil nil nil nil nil nil]) |
4c8d5b4b KH |
228 | result) |
229 | (while (= (length (setq result (ccl-execute-on-string ccl vec str t))) 0) | |
81a23e88 KH |
230 | (dotimes (i 9) (aset vec i nil)) |
231 | (setq str (format "%s%c" str (read-char-exclusive)))) | |
068b074e | 232 | (setq unread-command-events |
17fd77dd | 233 | (append result unread-command-events)))) |
068b074e KH |
234 | |
235 | (defun encoded-kbd-setup-keymap (coding) | |
236 | ;; At first, reset the keymap. | |
237 | (setcdr encoded-kbd-mode-map nil) | |
238 | ;; Then setup the keymap according to the keyboard coding system. | |
239 | (cond | |
240 | ((eq encoded-kbd-coding 'sjis) | |
241 | (let ((i 128)) | |
242 | (while (< i 256) | |
243 | (define-key encoded-kbd-mode-map | |
244 | (vector i) 'encoded-kbd-self-insert-sjis) | |
245 | (setq i (1+ i))))) | |
246 | ||
247 | ((eq encoded-kbd-coding 'big5) | |
248 | (let ((i 161)) | |
249 | (while (< i 255) | |
250 | (define-key encoded-kbd-mode-map | |
251 | (vector i) 'encoded-kbd-self-insert-big5) | |
252 | (setq i (1+ i))))) | |
253 | ||
254 | ((eq encoded-kbd-coding 'iso2022-7) | |
255 | (define-key encoded-kbd-mode-map "\e" 'encoded-kbd-iso2022-esc-prefix)) | |
a1506d29 | 256 | |
068b074e KH |
257 | ((eq encoded-kbd-coding 'iso2022-8) |
258 | (define-key encoded-kbd-mode-map | |
259 | (vector ?\216) 'encoded-kbd-self-insert-iso2022-8bit) | |
260 | (define-key encoded-kbd-mode-map | |
261 | (vector ?\217) 'encoded-kbd-self-insert-iso2022-8bit) | |
262 | (let ((i 160)) | |
263 | (while (< i 256) | |
264 | (define-key encoded-kbd-mode-map | |
265 | (vector i) 'encoded-kbd-self-insert-iso2022-8bit) | |
266 | (setq i (1+ i))))) | |
267 | ||
268 | ((eq encoded-kbd-coding 'ccl) | |
269 | (let ((valid-codes (or (coding-system-get coding 'valid-codes) | |
4c8d5b4b | 270 | '((128 . 255)))) |
068b074e KH |
271 | elt from to) |
272 | (while valid-codes | |
273 | (setq elt (car valid-codes) valid-codes (cdr valid-codes)) | |
274 | (if (consp elt) | |
275 | (setq from (car elt) to (cdr elt)) | |
276 | (setq from (setq to elt))) | |
277 | (while (<= from to) | |
278 | (if (>= from 128) | |
279 | (define-key encoded-kbd-mode-map | |
280 | (vector from) 'encoded-kbd-self-insert-ccl)) | |
281 | (setq from (1+ from)))))) | |
282 | ||
283 | (t | |
284 | (error "Invalid value in encoded-kbd-coding: %s" encoded-kbd-coding)))) | |
285 | ||
286 | ||
586ec68a KH |
287 | ;; Input mode at the time Encoded-kbd mode is turned on is saved here. |
288 | (defvar saved-input-mode nil) | |
289 | ||
ff14aafb | 290 | (put 'encoded-kbd-mode 'permanent-local t) |
f61d15a7 | 291 | ;;;###autoload |
ff14aafb | 292 | (define-minor-mode encoded-kbd-mode |
4ed46869 | 293 | "Toggle Encoded-kbd minor mode. |
586ec68a | 294 | With arg, turn Encoded-kbd mode on if and only if arg is positive. |
4ed46869 | 295 | |
a0d4676a | 296 | You should not turn this mode on manually, instead use the command |
f7e5a632 | 297 | \\[set-keyboard-coding-system] which turns on or off this mode |
a0d4676a KH |
298 | automatically. |
299 | ||
300 | In Encoded-kbd mode, a text sent from keyboard is accepted | |
301 | as a multilingual text encoded in a coding system set by | |
f7e5a632 | 302 | \\[set-keyboard-coding-system]." |
ff14aafb SM |
303 | :global t |
304 | ;; We must at first reset input-mode to the original. | |
305 | (if saved-input-mode (apply 'set-input-mode saved-input-mode)) | |
4ed46869 | 306 | (if encoded-kbd-mode |
586ec68a KH |
307 | (let ((coding (keyboard-coding-system))) |
308 | (setq saved-input-mode (current-input-mode)) | |
4ed46869 | 309 | (cond ((null coding) |
a1506d29 | 310 | (setq encoded-kbd-mode nil) |
586ec68a | 311 | (error "No coding system for keyboard input is set")) |
4ed46869 | 312 | |
c4ede6a2 | 313 | ((= (coding-system-type coding) 1) ; SJIS |
586ec68a KH |
314 | (set-input-mode |
315 | (nth 0 saved-input-mode) (nth 1 saved-input-mode) | |
a1506d29 | 316 | 'use-8th-bit (nth 3 saved-input-mode)) |
4ed46869 KH |
317 | (setq encoded-kbd-coding 'sjis)) |
318 | ||
c4ede6a2 KH |
319 | ((= (coding-system-type coding) 2) ; ISO2022 |
320 | (if (aref (coding-system-flags coding) 7) ; 7-bit only | |
4ed46869 | 321 | (setq encoded-kbd-coding 'iso2022-7) |
586ec68a KH |
322 | (set-input-mode |
323 | (nth 0 saved-input-mode) (nth 1 saved-input-mode) | |
a1506d29 | 324 | 'use-8th-bit (nth 3 saved-input-mode)) |
4ed46869 | 325 | (setq encoded-kbd-coding 'iso2022-8)) |
4ed46869 | 326 | (setq encoded-kbd-iso2022-designations (make-vector 4 nil)) |
c4ede6a2 | 327 | (let ((flags (coding-system-flags coding)) |
4ed46869 KH |
328 | (i 0)) |
329 | (while (< i 4) | |
f61d15a7 | 330 | (if (charsetp (aref flags i)) |
4ed46869 | 331 | (aset encoded-kbd-iso2022-designations i |
586ec68a KH |
332 | (aref flags i)) |
333 | (if (charsetp (car-safe (aref flags i))) | |
334 | (aset encoded-kbd-iso2022-designations i | |
335 | (car (aref flags i))))) | |
4ed46869 | 336 | (setq i (1+ i)))) |
f61d15a7 KH |
337 | (setq encoded-kbd-iso2022-invocations (make-vector 3 nil)) |
338 | (aset encoded-kbd-iso2022-invocations 0 0) | |
4ed46869 KH |
339 | (aset encoded-kbd-iso2022-invocations 1 1)) |
340 | ||
c4ede6a2 | 341 | ((= (coding-system-type coding) 3) ; BIG5 |
586ec68a KH |
342 | (set-input-mode |
343 | (nth 0 saved-input-mode) (nth 1 saved-input-mode) | |
a1506d29 | 344 | 'use-8th-bit (nth 3 saved-input-mode)) |
4ed46869 KH |
345 | (setq encoded-kbd-coding 'big5)) |
346 | ||
068b074e KH |
347 | ((= (coding-system-type coding) 4) ; CCL based coding |
348 | (set-input-mode | |
349 | (nth 0 saved-input-mode) (nth 1 saved-input-mode) | |
a1506d29 | 350 | 'use-8th-bit (nth 3 saved-input-mode)) |
068b074e KH |
351 | (setq encoded-kbd-coding 'ccl)) |
352 | ||
4ed46869 KH |
353 | (t |
354 | (setq encoded-kbd-mode nil) | |
355 | (error "Coding-system `%s' is not supported in Encoded-kbd mode" | |
356 | (keyboard-coding-system)))) | |
ff14aafb | 357 | (encoded-kbd-setup-keymap coding)))) |
4ed46869 | 358 | |
9c93c95a MR |
359 | (provide 'encoded-kb) |
360 | ||
4ed46869 | 361 | ;;; encoded-kb.el ends here |