1 // This is an open source non-commercial project. Dear PVS-Studio, please check
2 // it. PVS-Studio Static Code Analyzer for C, C++ and C#: http://www.viva64.com
3
4 /// @file digraph.c
5 ///
6 /// code for digraphs
7
8 #include <assert.h>
9 #include <inttypes.h>
10 #include <stdbool.h>
11
12 #include "nvim/ascii.h"
13 #include "nvim/charset.h"
14 #include "nvim/digraph.h"
15 #include "nvim/ex_cmds2.h"
16 #include "nvim/ex_docmd.h"
17 #include "nvim/ex_getln.h"
18 #include "nvim/garray.h"
19 #include "nvim/getchar.h"
20 #include "nvim/mbyte.h"
21 #include "nvim/memory.h"
22 #include "nvim/message.h"
23 #include "nvim/misc1.h"
24 #include "nvim/normal.h"
25 #include "nvim/os/input.h"
26 #include "nvim/screen.h"
27 #include "nvim/strings.h"
28 #include "nvim/vim.h"
29
30 typedef int result_T;
31
32 typedef struct digraph {
33 char_u char1;
34 char_u char2;
35 result_T result;
36 } digr_T;
37
38
39 #ifdef INCLUDE_GENERATED_DECLARATIONS
40 # include "digraph.c.generated.h"
41 #endif
42 // digraphs added by the user
43 static garray_T user_digraphs = { 0, 0, (int)sizeof(digr_T), 10, NULL };
44
45 /// Note: Characters marked with XX are not included literally, because some
46 /// compilers cannot handle them (Amiga SAS/C is the most picky one).
47 static digr_T digraphdefault[] =
48
49 // digraphs for Unicode from RFC1345
50 // (also work for ISO-8859-1 aka latin1)
51 {
52 { 'N', 'U', 0x0a }, // LF for NUL
53 { 'S', 'H', 0x01 },
54 { 'S', 'X', 0x02 },
55 { 'E', 'X', 0x03 },
56 { 'E', 'T', 0x04 },
57 { 'E', 'Q', 0x05 },
58 { 'A', 'K', 0x06 },
59 { 'B', 'L', 0x07 },
60 { 'B', 'S', 0x08 },
61 { 'H', 'T', 0x09 },
62 { 'L', 'F', 0x0a },
63 { 'V', 'T', 0x0b },
64 { 'F', 'F', 0x0c },
65 { 'C', 'R', 0x0d },
66 { 'S', 'O', 0x0e },
67 { 'S', 'I', 0x0f },
68 { 'D', 'L', 0x10 },
69 { 'D', '1', 0x11 },
70 { 'D', '2', 0x12 },
71 { 'D', '3', 0x13 },
72 { 'D', '4', 0x14 },
73 { 'N', 'K', 0x15 },
74 { 'S', 'Y', 0x16 },
75 { 'E', 'B', 0x17 },
76 { 'C', 'N', 0x18 },
77 { 'E', 'M', 0x19 },
78 { 'S', 'B', 0x1a },
79 { 'E', 'C', 0x1b },
80 { 'F', 'S', 0x1c },
81 { 'G', 'S', 0x1d },
82 { 'R', 'S', 0x1e },
83 { 'U', 'S', 0x1f },
84 { 'S', 'P', 0x20 },
85 { 'N', 'b', 0x23 },
86 { 'D', 'O', 0x24 },
87 { 'A', 't', 0x40 },
88 { '<', '(', 0x5b },
89 { '/', '/', 0x5c },
90 { ')', '>', 0x5d },
91 { '\'', '>', 0x5e },
92 { '\'', '!', 0x60 },
93 { '(', '!', 0x7b },
94 { '!', '!', 0x7c },
95 { '!', ')', 0x7d },
96 { '\'', '?', 0x7e },
97 { 'D', 'T', 0x7f },
98 { 'P', 'A', 0x80 },
99 { 'H', 'O', 0x81 },
100 { 'B', 'H', 0x82 },
101 { 'N', 'H', 0x83 },
102 { 'I', 'N', 0x84 },
103 { 'N', 'L', 0x85 },
104 { 'S', 'A', 0x86 },
105 { 'E', 'S', 0x87 },
106 { 'H', 'S', 0x88 },
107 { 'H', 'J', 0x89 },
108 { 'V', 'S', 0x8a },
109 { 'P', 'D', 0x8b },
110 { 'P', 'U', 0x8c },
111 { 'R', 'I', 0x8d },
112 { 'S', '2', 0x8e },
113 { 'S', '3', 0x8f },
114 { 'D', 'C', 0x90 },
115 { 'P', '1', 0x91 },
116 { 'P', '2', 0x92 },
117 { 'T', 'S', 0x93 },
118 { 'C', 'C', 0x94 },
119 { 'M', 'W', 0x95 },
120 { 'S', 'G', 0x96 },
121 { 'E', 'G', 0x97 },
122 { 'S', 'S', 0x98 },
123 { 'G', 'C', 0x99 },
124 { 'S', 'C', 0x9a },
125 { 'C', 'I', 0x9b },
126 { 'S', 'T', 0x9c },
127 { 'O', 'C', 0x9d },
128 { 'P', 'M', 0x9e },
129 { 'A', 'C', 0x9f },
130 { 'N', 'S', 0xa0 },
131 #define DG_START_LATIN 0xa1
132 { '!', 'I', 0xa1 },
133 { '~', '!', 0xa1 }, // ¡ Vim 5.x compatible
134 { 'C', 't', 0xa2 },
135 { 'c', '|', 0xa2 }, // ¢ Vim 5.x compatible
136 { 'P', 'd', 0xa3 },
137 { '$', '$', 0xa3 }, // £ Vim 5.x compatible
138 { 'C', 'u', 0xa4 },
139 { 'o', 'x', 0xa4 }, // ¤ Vim 5.x compatible
140 { 'Y', 'e', 0xa5 },
141 { 'Y', '-', 0xa5 }, // ¥ Vim 5.x compatible
142 { 'B', 'B', 0xa6 },
143 { '|', '|', 0xa6 }, // ¦ Vim 5.x compatible
144 { 'S', 'E', 0xa7 },
145 { '\'', ':', 0xa8 },
146 { 'C', 'o', 0xa9 },
147 { 'c', 'O', 0xa9 }, // © Vim 5.x compatible
148 { '-', 'a', 0xaa },
149 { '<', '<', 0xab },
150 { 'N', 'O', 0xac },
151 { '-', ',', 0xac }, // ¬ Vim 5.x compatible
152 { '-', '-', 0xad },
153 { 'R', 'g', 0xae },
154 { '\'', 'm', 0xaf },
155 { '-', '=', 0xaf }, // ¯ Vim 5.x compatible
156 { 'D', 'G', 0xb0 },
157 { '~', 'o', 0xb0 }, // ° Vim 5.x compatible
158 { '+', '-', 0xb1 },
159 { '2', 'S', 0xb2 },
160 { '2', '2', 0xb2 }, // ² Vim 5.x compatible
161 { '3', 'S', 0xb3 },
162 { '3', '3', 0xb3 }, // ³ Vim 5.x compatible
163 { '\'', '\'', 0xb4 },
164 { 'M', 'y', 0xb5 },
165 { 'P', 'I', 0xb6 },
166 { 'p', 'p', 0xb6 }, // ¶ Vim 5.x compatible
167 { '.', 'M', 0xb7 },
168 { '~', '.', 0xb7 }, // · Vim 5.x compatible
169 { '\'', ',', 0xb8 },
170 { '1', 'S', 0xb9 },
171 { '1', '1', 0xb9 }, // ¹ Vim 5.x compatible
172 { '-', 'o', 0xba },
173 { '>', '>', 0xbb },
174 { '1', '4', 0xbc },
175 { '1', '2', 0xbd },
176 { '3', '4', 0xbe },
177 { '?', 'I', 0xbf },
178 { '~', '?', 0xbf }, // ¿ Vim 5.x compatible
179 { 'A', '!', 0xc0 },
180 { 'A', '`', 0xc0 }, // À Vim 5.x compatible
181 { 'A', '\'', 0xc1 },
182 { 'A', '>', 0xc2 },
183 { 'A', '^', 0xc2 }, // Â Vim 5.x compatible
184 { 'A', '?', 0xc3 },
185 { 'A', '~', 0xc3 }, // Ã Vim 5.x compatible
186 { 'A', ':', 0xc4 },
187 { 'A', '"', 0xc4 }, // Ä Vim 5.x compatible
188 { 'A', 'A', 0xc5 },
189 { 'A', '@', 0xc5 }, // Å Vim 5.x compatible
190 { 'A', 'E', 0xc6 },
191 { 'C', ',', 0xc7 },
192 { 'E', '!', 0xc8 },
193 { 'E', '`', 0xc8 }, // È Vim 5.x compatible
194 { 'E', '\'', 0xc9 },
195 { 'E', '>', 0xca },
196 { 'E', '^', 0xca }, // Ê Vim 5.x compatible
197 { 'E', ':', 0xcb },
198 { 'E', '"', 0xcb }, // Ë Vim 5.x compatible
199 { 'I', '!', 0xcc },
200 { 'I', '`', 0xcc }, // Ì Vim 5.x compatible
201 { 'I', '\'', 0xcd },
202 { 'I', '>', 0xce },
203 { 'I', '^', 0xce }, // Î Vim 5.x compatible
204 { 'I', ':', 0xcf },
205 { 'I', '"', 0xcf }, // Ï Vim 5.x compatible
206 { 'D', '-', 0xd0 },
207 { 'N', '?', 0xd1 },
208 { 'N', '~', 0xd1 }, // Ñ Vim 5.x compatible
209 { 'O', '!', 0xd2 },
210 { 'O', '`', 0xd2 }, // Ò Vim 5.x compatible
211 { 'O', '\'', 0xd3 },
212 { 'O', '>', 0xd4 },
213 { 'O', '^', 0xd4 }, // Ô Vim 5.x compatible
214 { 'O', '?', 0xd5 },
215 { 'O', '~', 0xd5 }, // Õ Vim 5.x compatible
216 { 'O', ':', 0xd6 },
217 { '*', 'X', 0xd7 },
218 { '/', '\\', 0xd7 }, // × Vim 5.x compatible
219 { 'O', '/', 0xd8 },
220 { 'U', '!', 0xd9 },
221 { 'U', '`', 0xd9 }, // Ù Vim 5.x compatible
222 { 'U', '\'', 0xda },
223 { 'U', '>', 0xdb },
224 { 'U', '^', 0xdb }, // Û Vim 5.x compatible
225 { 'U', ':', 0xdc },
226 { 'Y', '\'', 0xdd },
227 { 'T', 'H', 0xde },
228 { 'I', 'p', 0xde }, // Þ Vim 5.x compatible
229 { 's', 's', 0xdf },
230 { 'a', '!', 0xe0 },
231 { 'a', '`', 0xe0 }, // à Vim 5.x compatible
232 { 'a', '\'', 0xe1 },
233 { 'a', '>', 0xe2 },
234 { 'a', '^', 0xe2 }, // â Vim 5.x compatible
235 { 'a', '?', 0xe3 },
236 { 'a', '~', 0xe3 }, // ã Vim 5.x compatible
237 { 'a', ':', 0xe4 },
238 { 'a', '"', 0xe4 }, // ä Vim 5.x compatible
239 { 'a', 'a', 0xe5 },
240 { 'a', '@', 0xe5 }, // å Vim 5.x compatible
241 { 'a', 'e', 0xe6 },
242 { 'c', ',', 0xe7 },
243 { 'e', '!', 0xe8 },
244 { 'e', '`', 0xe8 }, // è Vim 5.x compatible
245 { 'e', '\'', 0xe9 },
246 { 'e', '>', 0xea },
247 { 'e', '^', 0xea }, // ê Vim 5.x compatible
248 { 'e', ':', 0xeb },
249 { 'e', '"', 0xeb }, // ë Vim 5.x compatible
250 { 'i', '!', 0xec },
251 { 'i', '`', 0xec }, // ì Vim 5.x compatible
252 { 'i', '\'', 0xed },
253 { 'i', '>', 0xee },
254 { 'i', '^', 0xee }, // î Vim 5.x compatible
255 { 'i', ':', 0xef },
256 { 'd', '-', 0xf0 },
257 { 'n', '?', 0xf1 },
258 { 'n', '~', 0xf1 }, // ñ Vim 5.x compatible
259 { 'o', '!', 0xf2 },
260 { 'o', '`', 0xf2 }, // ò Vim 5.x compatible
261 { 'o', '\'', 0xf3 },
262 { 'o', '>', 0xf4 },
263 { 'o', '^', 0xf4 }, // ô Vim 5.x compatible
264 { 'o', '?', 0xf5 },
265 { 'o', '~', 0xf5 }, // õ Vim 5.x compatible
266 { 'o', ':', 0xf6 },
267 { '-', ':', 0xf7 },
268 { 'o', '/', 0xf8 },
269 { 'u', '!', 0xf9 },
270 { 'u', '`', 0xf9 }, // ù Vim 5.x compatible
271 { 'u', '\'', 0xfa },
272 { 'u', '>', 0xfb },
273 { 'u', '^', 0xfb }, // û Vim 5.x compatible
274 { 'u', ':', 0xfc },
275 { 'y', '\'', 0xfd },
276 { 't', 'h', 0xfe },
277 { 'y', ':', 0xff },
278 { 'y', '"', 0xff }, // x XX Vim 5.x compatible
279
280 { 'A', '-', 0x0100 },
281 { 'a', '-', 0x0101 },
282 { 'A', '(', 0x0102 },
283 { 'a', '(', 0x0103 },
284 { 'A', ';', 0x0104 },
285 { 'a', ';', 0x0105 },
286 { 'C', '\'', 0x0106 },
287 { 'c', '\'', 0x0107 },
288 { 'C', '>', 0x0108 },
289 { 'c', '>', 0x0109 },
290 { 'C', '.', 0x010a },
291 { 'c', '.', 0x010b },
292 { 'C', '<', 0x010c },
293 { 'c', '<', 0x010d },
294 { 'D', '<', 0x010e },
295 { 'd', '<', 0x010f },
296 { 'D', '/', 0x0110 },
297 { 'd', '/', 0x0111 },
298 { 'E', '-', 0x0112 },
299 { 'e', '-', 0x0113 },
300 { 'E', '(', 0x0114 },
301 { 'e', '(', 0x0115 },
302 { 'E', '.', 0x0116 },
303 { 'e', '.', 0x0117 },
304 { 'E', ';', 0x0118 },
305 { 'e', ';', 0x0119 },
306 { 'E', '<', 0x011a },
307 { 'e', '<', 0x011b },
308 { 'G', '>', 0x011c },
309 { 'g', '>', 0x011d },
310 { 'G', '(', 0x011e },
311 { 'g', '(', 0x011f },
312 { 'G', '.', 0x0120 },
313 { 'g', '.', 0x0121 },
314 { 'G', ',', 0x0122 },
315 { 'g', ',', 0x0123 },
316 { 'H', '>', 0x0124 },
317 { 'h', '>', 0x0125 },
318 { 'H', '/', 0x0126 },
319 { 'h', '/', 0x0127 },
320 { 'I', '?', 0x0128 },
321 { 'i', '?', 0x0129 },
322 { 'I', '-', 0x012a },
323 { 'i', '-', 0x012b },
324 { 'I', '(', 0x012c },
325 { 'i', '(', 0x012d },
326 { 'I', ';', 0x012e },
327 { 'i', ';', 0x012f },
328 { 'I', '.', 0x0130 },
329 { 'i', '.', 0x0131 },
330 { 'I', 'J', 0x0132 },
331 { 'i', 'j', 0x0133 },
332 { 'J', '>', 0x0134 },
333 { 'j', '>', 0x0135 },
334 { 'K', ',', 0x0136 },
335 { 'k', ',', 0x0137 },
336 { 'k', 'k', 0x0138 },
337 { 'L', '\'', 0x0139 },
338 { 'l', '\'', 0x013a },
339 { 'L', ',', 0x013b },
340 { 'l', ',', 0x013c },
341 { 'L', '<', 0x013d },
342 { 'l', '<', 0x013e },
343 { 'L', '.', 0x013f },
344 { 'l', '.', 0x0140 },
345 { 'L', '/', 0x0141 },
346 { 'l', '/', 0x0142 },
347 { 'N', '\'', 0x0143 },
348 { 'n', '\'', 0x0144 },
349 { 'N', ',', 0x0145 },
350 { 'n', ',', 0x0146 },
351 { 'N', '<', 0x0147 },
352 { 'n', '<', 0x0148 },
353 { '\'', 'n', 0x0149 },
354 { 'N', 'G', 0x014a },
355 { 'n', 'g', 0x014b },
356 { 'O', '-', 0x014c },
357 { 'o', '-', 0x014d },
358 { 'O', '(', 0x014e },
359 { 'o', '(', 0x014f },
360 { 'O', '"', 0x0150 },
361 { 'o', '"', 0x0151 },
362 { 'O', 'E', 0x0152 },
363 { 'o', 'e', 0x0153 },
364 { 'R', '\'', 0x0154 },
365 { 'r', '\'', 0x0155 },
366 { 'R', ',', 0x0156 },
367 { 'r', ',', 0x0157 },
368 { 'R', '<', 0x0158 },
369 { 'r', '<', 0x0159 },
370 { 'S', '\'', 0x015a },
371 { 's', '\'', 0x015b },
372 { 'S', '>', 0x015c },
373 { 's', '>', 0x015d },
374 { 'S', ',', 0x015e },
375 { 's', ',', 0x015f },
376 { 'S', '<', 0x0160 },
377 { 's', '<', 0x0161 },
378 { 'T', ',', 0x0162 },
379 { 't', ',', 0x0163 },
380 { 'T', '<', 0x0164 },
381 { 't', '<', 0x0165 },
382 { 'T', '/', 0x0166 },
383 { 't', '/', 0x0167 },
384 { 'U', '?', 0x0168 },
385 { 'u', '?', 0x0169 },
386 { 'U', '-', 0x016a },
387 { 'u', '-', 0x016b },
388 { 'U', '(', 0x016c },
389 { 'u', '(', 0x016d },
390 { 'U', '0', 0x016e },
391 { 'u', '0', 0x016f },
392 { 'U', '"', 0x0170 },
393 { 'u', '"', 0x0171 },
394 { 'U', ';', 0x0172 },
395 { 'u', ';', 0x0173 },
396 { 'W', '>', 0x0174 },
397 { 'w', '>', 0x0175 },
398 { 'Y', '>', 0x0176 },
399 { 'y', '>', 0x0177 },
400 { 'Y', ':', 0x0178 },
401 { 'Z', '\'', 0x0179 },
402 { 'z', '\'', 0x017a },
403 { 'Z', '.', 0x017b },
404 { 'z', '.', 0x017c },
405 { 'Z', '<', 0x017d },
406 { 'z', '<', 0x017e },
407 { 'O', '9', 0x01a0 },
408 { 'o', '9', 0x01a1 },
409 { 'O', 'I', 0x01a2 },
410 { 'o', 'i', 0x01a3 },
411 { 'y', 'r', 0x01a6 },
412 { 'U', '9', 0x01af },
413 { 'u', '9', 0x01b0 },
414 { 'Z', '/', 0x01b5 },
415 { 'z', '/', 0x01b6 },
416 { 'E', 'D', 0x01b7 },
417 { 'A', '<', 0x01cd },
418 { 'a', '<', 0x01ce },
419 { 'I', '<', 0x01cf },
420 { 'i', '<', 0x01d0 },
421 { 'O', '<', 0x01d1 },
422 { 'o', '<', 0x01d2 },
423 { 'U', '<', 0x01d3 },
424 { 'u', '<', 0x01d4 },
425 { 'A', '1', 0x01de },
426 { 'a', '1', 0x01df },
427 { 'A', '7', 0x01e0 },
428 { 'a', '7', 0x01e1 },
429 { 'A', '3', 0x01e2 },
430 { 'a', '3', 0x01e3 },
431 { 'G', '/', 0x01e4 },
432 { 'g', '/', 0x01e5 },
433 { 'G', '<', 0x01e6 },
434 { 'g', '<', 0x01e7 },
435 { 'K', '<', 0x01e8 },
436 { 'k', '<', 0x01e9 },
437 { 'O', ';', 0x01ea },
438 { 'o', ';', 0x01eb },
439 { 'O', '1', 0x01ec },
440 { 'o', '1', 0x01ed },
441 { 'E', 'Z', 0x01ee },
442 { 'e', 'z', 0x01ef },
443 { 'j', '<', 0x01f0 },
444 { 'G', '\'', 0x01f4 },
445 { 'g', '\'', 0x01f5 },
446 { ';', 'S', 0x02bf },
447 { '\'', '<', 0x02c7 },
448 { '\'', '(', 0x02d8 },
449 { '\'', '.', 0x02d9 },
450 { '\'', '0', 0x02da },
451 { '\'', ';', 0x02db },
452 { '\'', '"', 0x02dd },
453 #define DG_START_GREEK 0x0386
454 { 'A', '%', 0x0386 },
455 { 'E', '%', 0x0388 },
456 { 'Y', '%', 0x0389 },
457 { 'I', '%', 0x038a },
458 { 'O', '%', 0x038c },
459 { 'U', '%', 0x038e },
460 { 'W', '%', 0x038f },
461 { 'i', '3', 0x0390 },
462 { 'A', '*', 0x0391 },
463 { 'B', '*', 0x0392 },
464 { 'G', '*', 0x0393 },
465 { 'D', '*', 0x0394 },
466 { 'E', '*', 0x0395 },
467 { 'Z', '*', 0x0396 },
468 { 'Y', '*', 0x0397 },
469 { 'H', '*', 0x0398 },
470 { 'I', '*', 0x0399 },
471 { 'K', '*', 0x039a },
472 { 'L', '*', 0x039b },
473 { 'M', '*', 0x039c },
474 { 'N', '*', 0x039d },
475 { 'C', '*', 0x039e },
476 { 'O', '*', 0x039f },
477 { 'P', '*', 0x03a0 },
478 { 'R', '*', 0x03a1 },
479 { 'S', '*', 0x03a3 },
480 { 'T', '*', 0x03a4 },
481 { 'U', '*', 0x03a5 },
482 { 'F', '*', 0x03a6 },
483 { 'X', '*', 0x03a7 },
484 { 'Q', '*', 0x03a8 },
485 { 'W', '*', 0x03a9 },
486 { 'J', '*', 0x03aa },
487 { 'V', '*', 0x03ab },
488 { 'a', '%', 0x03ac },
489 { 'e', '%', 0x03ad },
490 { 'y', '%', 0x03ae },
491 { 'i', '%', 0x03af },
492 { 'u', '3', 0x03b0 },
493 { 'a', '*', 0x03b1 },
494 { 'b', '*', 0x03b2 },
495 { 'g', '*', 0x03b3 },
496 { 'd', '*', 0x03b4 },
497 { 'e', '*', 0x03b5 },
498 { 'z', '*', 0x03b6 },
499 { 'y', '*', 0x03b7 },
500 { 'h', '*', 0x03b8 },
501 { 'i', '*', 0x03b9 },
502 { 'k', '*', 0x03ba },
503 { 'l', '*', 0x03bb },
504 { 'm', '*', 0x03bc },
505 { 'n', '*', 0x03bd },
506 { 'c', '*', 0x03be },
507 { 'o', '*', 0x03bf },
508 { 'p', '*', 0x03c0 },
509 { 'r', '*', 0x03c1 },
510 { '*', 's', 0x03c2 },
511 { 's', '*', 0x03c3 },
512 { 't', '*', 0x03c4 },
513 { 'u', '*', 0x03c5 },
514 { 'f', '*', 0x03c6 },
515 { 'x', '*', 0x03c7 },
516 { 'q', '*', 0x03c8 },
517 { 'w', '*', 0x03c9 },
518 { 'j', '*', 0x03ca },
519 { 'v', '*', 0x03cb },
520 { 'o', '%', 0x03cc },
521 { 'u', '%', 0x03cd },
522 { 'w', '%', 0x03ce },
523 { '\'', 'G', 0x03d8 },
524 { ',', 'G', 0x03d9 },
525 { 'T', '3', 0x03da },
526 { 't', '3', 0x03db },
527 { 'M', '3', 0x03dc },
528 { 'm', '3', 0x03dd },
529 { 'K', '3', 0x03de },
530 { 'k', '3', 0x03df },
531 { 'P', '3', 0x03e0 },
532 { 'p', '3', 0x03e1 },
533 { '\'', '%', 0x03f4 },
534 { 'j', '3', 0x03f5 },
535 #define DG_START_CYRILLIC 0x0401
536 { 'I', 'O', 0x0401 },
537 { 'D', '%', 0x0402 },
538 { 'G', '%', 0x0403 },
539 { 'I', 'E', 0x0404 },
540 { 'D', 'S', 0x0405 },
541 { 'I', 'I', 0x0406 },
542 { 'Y', 'I', 0x0407 },
543 { 'J', '%', 0x0408 },
544 { 'L', 'J', 0x0409 },
545 { 'N', 'J', 0x040a },
546 { 'T', 's', 0x040b },
547 { 'K', 'J', 0x040c },
548 { 'V', '%', 0x040e },
549 { 'D', 'Z', 0x040f },
550 { 'A', '=', 0x0410 },
551 { 'B', '=', 0x0411 },
552 { 'V', '=', 0x0412 },
553 { 'G', '=', 0x0413 },
554 { 'D', '=', 0x0414 },
555 { 'E', '=', 0x0415 },
556 { 'Z', '%', 0x0416 },
557 { 'Z', '=', 0x0417 },
558 { 'I', '=', 0x0418 },
559 { 'J', '=', 0x0419 },
560 { 'K', '=', 0x041a },
561 { 'L', '=', 0x041b },
562 { 'M', '=', 0x041c },
563 { 'N', '=', 0x041d },
564 { 'O', '=', 0x041e },
565 { 'P', '=', 0x041f },
566 { 'R', '=', 0x0420 },
567 { 'S', '=', 0x0421 },
568 { 'T', '=', 0x0422 },
569 { 'U', '=', 0x0423 },
570 { 'F', '=', 0x0424 },
571 { 'H', '=', 0x0425 },
572 { 'C', '=', 0x0426 },
573 { 'C', '%', 0x0427 },
574 { 'S', '%', 0x0428 },
575 { 'S', 'c', 0x0429 },
576 { '=', '"', 0x042a },
577 { 'Y', '=', 0x042b },
578 { '%', '"', 0x042c },
579 { 'J', 'E', 0x042d },
580 { 'J', 'U', 0x042e },
581 { 'J', 'A', 0x042f },
582 { 'a', '=', 0x0430 },
583 { 'b', '=', 0x0431 },
584 { 'v', '=', 0x0432 },
585 { 'g', '=', 0x0433 },
586 { 'd', '=', 0x0434 },
587 { 'e', '=', 0x0435 },
588 { 'z', '%', 0x0436 },
589 { 'z', '=', 0x0437 },
590 { 'i', '=', 0x0438 },
591 { 'j', '=', 0x0439 },
592 { 'k', '=', 0x043a },
593 { 'l', '=', 0x043b },
594 { 'm', '=', 0x043c },
595 { 'n', '=', 0x043d },
596 { 'o', '=', 0x043e },
597 { 'p', '=', 0x043f },
598 { 'r', '=', 0x0440 },
599 { 's', '=', 0x0441 },
600 { 't', '=', 0x0442 },
601 { 'u', '=', 0x0443 },
602 { 'f', '=', 0x0444 },
603 { 'h', '=', 0x0445 },
604 { 'c', '=', 0x0446 },
605 { 'c', '%', 0x0447 },
606 { 's', '%', 0x0448 },
607 { 's', 'c', 0x0449 },
608 { '=', '\'', 0x044a },
609 { 'y', '=', 0x044b },
610 { '%', '\'', 0x044c },
611 { 'j', 'e', 0x044d },
612 { 'j', 'u', 0x044e },
613 { 'j', 'a', 0x044f },
614 { 'i', 'o', 0x0451 },
615 { 'd', '%', 0x0452 },
616 { 'g', '%', 0x0453 },
617 { 'i', 'e', 0x0454 },
618 { 'd', 's', 0x0455 },
619 { 'i', 'i', 0x0456 },
620 { 'y', 'i', 0x0457 },
621 { 'j', '%', 0x0458 },
622 { 'l', 'j', 0x0459 },
623 { 'n', 'j', 0x045a },
624 { 't', 's', 0x045b },
625 { 'k', 'j', 0x045c },
626 { 'v', '%', 0x045e },
627 { 'd', 'z', 0x045f },
628 { 'Y', '3', 0x0462 },
629 { 'y', '3', 0x0463 },
630 { 'O', '3', 0x046a },
631 { 'o', '3', 0x046b },
632 { 'F', '3', 0x0472 },
633 { 'f', '3', 0x0473 },
634 { 'V', '3', 0x0474 },
635 { 'v', '3', 0x0475 },
636 { 'C', '3', 0x0480 },
637 { 'c', '3', 0x0481 },
638 { 'G', '3', 0x0490 },
639 { 'g', '3', 0x0491 },
640 #define DG_START_HEBREW 0x05d0
641 { 'A', '+', 0x05d0 },
642 { 'B', '+', 0x05d1 },
643 { 'G', '+', 0x05d2 },
644 { 'D', '+', 0x05d3 },
645 { 'H', '+', 0x05d4 },
646 { 'W', '+', 0x05d5 },
647 { 'Z', '+', 0x05d6 },
648 { 'X', '+', 0x05d7 },
649 { 'T', 'j', 0x05d8 },
650 { 'J', '+', 0x05d9 },
651 { 'K', '%', 0x05da },
652 { 'K', '+', 0x05db },
653 { 'L', '+', 0x05dc },
654 { 'M', '%', 0x05dd },
655 { 'M', '+', 0x05de },
656 { 'N', '%', 0x05df },
657 { 'N', '+', 0x05e0 },
658 { 'S', '+', 0x05e1 },
659 { 'E', '+', 0x05e2 },
660 { 'P', '%', 0x05e3 },
661 { 'P', '+', 0x05e4 },
662 { 'Z', 'j', 0x05e5 },
663 { 'Z', 'J', 0x05e6 },
664 { 'Q', '+', 0x05e7 },
665 { 'R', '+', 0x05e8 },
666 { 'S', 'h', 0x05e9 },
667 { 'T', '+', 0x05ea },
668 #define DG_START_ARABIC 0x060c
669 { ',', '+', 0x060c },
670 { ';', '+', 0x061b },
671 { '?', '+', 0x061f },
672 { 'H', '\'', 0x0621 },
673 { 'a', 'M', 0x0622 },
674 { 'a', 'H', 0x0623 },
675 { 'w', 'H', 0x0624 },
676 { 'a', 'h', 0x0625 },
677 { 'y', 'H', 0x0626 },
678 { 'a', '+', 0x0627 },
679 { 'b', '+', 0x0628 },
680 { 't', 'm', 0x0629 },
681 { 't', '+', 0x062a },
682 { 't', 'k', 0x062b },
683 { 'g', '+', 0x062c },
684 { 'h', 'k', 0x062d },
685 { 'x', '+', 0x062e },
686 { 'd', '+', 0x062f },
687 { 'd', 'k', 0x0630 },
688 { 'r', '+', 0x0631 },
689 { 'z', '+', 0x0632 },
690 { 's', '+', 0x0633 },
691 { 's', 'n', 0x0634 },
692 { 'c', '+', 0x0635 },
693 { 'd', 'd', 0x0636 },
694 { 't', 'j', 0x0637 },
695 { 'z', 'H', 0x0638 },
696 { 'e', '+', 0x0639 },
697 { 'i', '+', 0x063a },
698 { '+', '+', 0x0640 },
699 { 'f', '+', 0x0641 },
700 { 'q', '+', 0x0642 },
701 { 'k', '+', 0x0643 },
702 { 'l', '+', 0x0644 },
703 { 'm', '+', 0x0645 },
704 { 'n', '+', 0x0646 },
705 { 'h', '+', 0x0647 },
706 { 'w', '+', 0x0648 },
707 { 'j', '+', 0x0649 },
708 { 'y', '+', 0x064a },
709 { ':', '+', 0x064b },
710 { '"', '+', 0x064c },
711 { '=', '+', 0x064d },
712 { '/', '+', 0x064e },
713 { '\'', '+', 0x064f },
714 { '1', '+', 0x0650 },
715 { '3', '+', 0x0651 },
716 { '0', '+', 0x0652 },
717 { 'a', 'S', 0x0670 },
718 { 'p', '+', 0x067e },
719 { 'v', '+', 0x06a4 },
720 { 'g', 'f', 0x06af },
721 { '0', 'a', 0x06f0 },
722 { '1', 'a', 0x06f1 },
723 { '2', 'a', 0x06f2 },
724 { '3', 'a', 0x06f3 },
725 { '4', 'a', 0x06f4 },
726 { '5', 'a', 0x06f5 },
727 { '6', 'a', 0x06f6 },
728 { '7', 'a', 0x06f7 },
729 { '8', 'a', 0x06f8 },
730 { '9', 'a', 0x06f9 },
731 #define DG_START_LATIN_EXTENDED 0x1e02
732 { 'B', '.', 0x1e02 },
733 { 'b', '.', 0x1e03 },
734 { 'B', '_', 0x1e06 },
735 { 'b', '_', 0x1e07 },
736 { 'D', '.', 0x1e0a },
737 { 'd', '.', 0x1e0b },
738 { 'D', '_', 0x1e0e },
739 { 'd', '_', 0x1e0f },
740 { 'D', ',', 0x1e10 },
741 { 'd', ',', 0x1e11 },
742 { 'F', '.', 0x1e1e },
743 { 'f', '.', 0x1e1f },
744 { 'G', '-', 0x1e20 },
745 { 'g', '-', 0x1e21 },
746 { 'H', '.', 0x1e22 },
747 { 'h', '.', 0x1e23 },
748 { 'H', ':', 0x1e26 },
749 { 'h', ':', 0x1e27 },
750 { 'H', ',', 0x1e28 },
751 { 'h', ',', 0x1e29 },
752 { 'K', '\'', 0x1e30 },
753 { 'k', '\'', 0x1e31 },
754 { 'K', '_', 0x1e34 },
755 { 'k', '_', 0x1e35 },
756 { 'L', '_', 0x1e3a },
757 { 'l', '_', 0x1e3b },
758 { 'M', '\'', 0x1e3e },
759 { 'm', '\'', 0x1e3f },
760 { 'M', '.', 0x1e40 },
761 { 'm', '.', 0x1e41 },
762 { 'N', '.', 0x1e44 },
763 { 'n', '.', 0x1e45 },
764 { 'N', '_', 0x1e48 },
765 { 'n', '_', 0x1e49 },
766 { 'P', '\'', 0x1e54 },
767 { 'p', '\'', 0x1e55 },
768 { 'P', '.', 0x1e56 },
769 { 'p', '.', 0x1e57 },
770 { 'R', '.', 0x1e58 },
771 { 'r', '.', 0x1e59 },
772 { 'R', '_', 0x1e5e },
773 { 'r', '_', 0x1e5f },
774 { 'S', '.', 0x1e60 },
775 { 's', '.', 0x1e61 },
776 { 'T', '.', 0x1e6a },
777 { 't', '.', 0x1e6b },
778 { 'T', '_', 0x1e6e },
779 { 't', '_', 0x1e6f },
780 { 'V', '?', 0x1e7c },
781 { 'v', '?', 0x1e7d },
782 { 'W', '!', 0x1e80 },
783 { 'W', '`', 0x1e80 }, // extra alternative, easier to remember
784 { 'w', '!', 0x1e81 },
785 { 'w', '`', 0x1e81 }, // extra alternative, easier to remember
786 { 'W', '\'', 0x1e82 },
787 { 'w', '\'', 0x1e83 },
788 { 'W', ':', 0x1e84 },
789 { 'w', ':', 0x1e85 },
790 { 'W', '.', 0x1e86 },
791 { 'w', '.', 0x1e87 },
792 { 'X', '.', 0x1e8a },
793 { 'x', '.', 0x1e8b },
794 { 'X', ':', 0x1e8c },
795 { 'x', ':', 0x1e8d },
796 { 'Y', '.', 0x1e8e },
797 { 'y', '.', 0x1e8f },
798 { 'Z', '>', 0x1e90 },
799 { 'z', '>', 0x1e91 },
800 { 'Z', '_', 0x1e94 },
801 { 'z', '_', 0x1e95 },
802 { 'h', '_', 0x1e96 },
803 { 't', ':', 0x1e97 },
804 { 'w', '0', 0x1e98 },
805 { 'y', '0', 0x1e99 },
806 { 'A', '2', 0x1ea2 },
807 { 'a', '2', 0x1ea3 },
808 { 'E', '2', 0x1eba },
809 { 'e', '2', 0x1ebb },
810 { 'E', '?', 0x1ebc },
811 { 'e', '?', 0x1ebd },
812 { 'I', '2', 0x1ec8 },
813 { 'i', '2', 0x1ec9 },
814 { 'O', '2', 0x1ece },
815 { 'o', '2', 0x1ecf },
816 { 'U', '2', 0x1ee6 },
817 { 'u', '2', 0x1ee7 },
818 { 'Y', '!', 0x1ef2 },
819 { 'Y', '`', 0x1ef2 }, // extra alternative, easier to remember
820 { 'y', '!', 0x1ef3 },
821 { 'y', '`', 0x1ef3 }, // extra alternative, easier to remember
822 { 'Y', '2', 0x1ef6 },
823 { 'y', '2', 0x1ef7 },
824 { 'Y', '?', 0x1ef8 },
825 { 'y', '?', 0x1ef9 },
826 #define DG_START_GREEK_EXTENDED 0x1f00
827 { ';', '\'', 0x1f00 },
828 { ',', '\'', 0x1f01 },
829 { ';', '!', 0x1f02 },
830 { ',', '!', 0x1f03 },
831 { '?', ';', 0x1f04 },
832 { '?', ',', 0x1f05 },
833 { '!', ':', 0x1f06 },
834 { '?', ':', 0x1f07 },
835 #define DG_START_PUNCTUATION 0x2002
836 { '1', 'N', 0x2002 },
837 { '1', 'M', 0x2003 },
838 { '3', 'M', 0x2004 },
839 { '4', 'M', 0x2005 },
840 { '6', 'M', 0x2006 },
841 { '1', 'T', 0x2009 },
842 { '1', 'H', 0x200a },
843 { '-', '1', 0x2010 },
844 { '-', 'N', 0x2013 },
845 { '-', 'M', 0x2014 },
846 { '-', '3', 0x2015 },
847 { '!', '2', 0x2016 },
848 { '=', '2', 0x2017 },
849 { '\'', '6', 0x2018 },
850 { '\'', '9', 0x2019 },
851 { '.', '9', 0x201a },
852 { '9', '\'', 0x201b },
853 { '"', '6', 0x201c },
854 { '"', '9', 0x201d },
855 { ':', '9', 0x201e },
856 { '9', '"', 0x201f },
857 { '/', '-', 0x2020 },
858 { '/', '=', 0x2021 },
859 { 'o', 'o', 0x2022 },
860 { '.', '.', 0x2025 },
861 { ',', '.', 0x2026 },
862 { '%', '0', 0x2030 },
863 { '1', '\'', 0x2032 },
864 { '2', '\'', 0x2033 },
865 { '3', '\'', 0x2034 },
866 { '1', '"', 0x2035 },
867 { '2', '"', 0x2036 },
868 { '3', '"', 0x2037 },
869 { 'C', 'a', 0x2038 },
870 { '<', '1', 0x2039 },
871 { '>', '1', 0x203a },
872 { ':', 'X', 0x203b },
873 { '\'', '-', 0x203e },
874 { '/', 'f', 0x2044 },
875 #define DG_START_SUB_SUPER 0x2070
876 { '0', 'S', 0x2070 },
877 { '4', 'S', 0x2074 },
878 { '5', 'S', 0x2075 },
879 { '6', 'S', 0x2076 },
880 { '7', 'S', 0x2077 },
881 { '8', 'S', 0x2078 },
882 { '9', 'S', 0x2079 },
883 { '+', 'S', 0x207a },
884 { '-', 'S', 0x207b },
885 { '=', 'S', 0x207c },
886 { '(', 'S', 0x207d },
887 { ')', 'S', 0x207e },
888 { 'n', 'S', 0x207f },
889 { '0', 's', 0x2080 },
890 { '1', 's', 0x2081 },
891 { '2', 's', 0x2082 },
892 { '3', 's', 0x2083 },
893 { '4', 's', 0x2084 },
894 { '5', 's', 0x2085 },
895 { '6', 's', 0x2086 },
896 { '7', 's', 0x2087 },
897 { '8', 's', 0x2088 },
898 { '9', 's', 0x2089 },
899 { '+', 's', 0x208a },
900 { '-', 's', 0x208b },
901 { '=', 's', 0x208c },
902 { '(', 's', 0x208d },
903 { ')', 's', 0x208e },
904 #define DG_START_CURRENCY 0x20a4
905 { 'L', 'i', 0x20a4 },
906 { 'P', 't', 0x20a7 },
907 { 'W', '=', 0x20a9 },
908 { '=', 'e', 0x20ac }, // euro
909 { 'E', 'u', 0x20ac }, // euro
910 { '=', 'R', 0x20bd }, // rouble
911 { '=', 'P', 0x20bd }, // rouble
912 #define DG_START_OTHER1 0x2103
913 { 'o', 'C', 0x2103 },
914 { 'c', 'o', 0x2105 },
915 { 'o', 'F', 0x2109 },
916 { 'N', '0', 0x2116 },
917 { 'P', 'O', 0x2117 },
918 { 'R', 'x', 0x211e },
919 { 'S', 'M', 0x2120 },
920 { 'T', 'M', 0x2122 },
921 { 'O', 'm', 0x2126 },
922 { 'A', 'O', 0x212b },
923 { '1', '3', 0x2153 },
924 { '2', '3', 0x2154 },
925 { '1', '5', 0x2155 },
926 { '2', '5', 0x2156 },
927 { '3', '5', 0x2157 },
928 { '4', '5', 0x2158 },
929 { '1', '6', 0x2159 },
930 { '5', '6', 0x215a },
931 { '1', '8', 0x215b },
932 { '3', '8', 0x215c },
933 { '5', '8', 0x215d },
934 { '7', '8', 0x215e },
935 #define DG_START_ROMAN 0x2160
936 { '1', 'R', 0x2160 },
937 { '2', 'R', 0x2161 },
938 { '3', 'R', 0x2162 },
939 { '4', 'R', 0x2163 },
940 { '5', 'R', 0x2164 },
941 { '6', 'R', 0x2165 },
942 { '7', 'R', 0x2166 },
943 { '8', 'R', 0x2167 },
944 { '9', 'R', 0x2168 },
945 { 'a', 'R', 0x2169 },
946 { 'b', 'R', 0x216a },
947 { 'c', 'R', 0x216b },
948 { '1', 'r', 0x2170 },
949 { '2', 'r', 0x2171 },
950 { '3', 'r', 0x2172 },
951 { '4', 'r', 0x2173 },
952 { '5', 'r', 0x2174 },
953 { '6', 'r', 0x2175 },
954 { '7', 'r', 0x2176 },
955 { '8', 'r', 0x2177 },
956 { '9', 'r', 0x2178 },
957 { 'a', 'r', 0x2179 },
958 { 'b', 'r', 0x217a },
959 { 'c', 'r', 0x217b },
960 #define DG_START_ARROWS 0x2190
961 { '<', '-', 0x2190 },
962 { '-', '!', 0x2191 },
963 { '-', '>', 0x2192 },
964 { '-', 'v', 0x2193 },
965 { '<', '>', 0x2194 },
966 { 'U', 'D', 0x2195 },
967 { '<', '=', 0x21d0 },
968 { '=', '>', 0x21d2 },
969 { '=', '=', 0x21d4 },
970 #define DG_START_MATH 0x2200
971 { 'F', 'A', 0x2200 },
972 { 'd', 'P', 0x2202 },
973 { 'T', 'E', 0x2203 },
974 { '/', '0', 0x2205 },
975 { 'D', 'E', 0x2206 },
976 { 'N', 'B', 0x2207 },
977 { '(', '-', 0x2208 },
978 { '-', ')', 0x220b },
979 { '*', 'P', 0x220f },
980 { '+', 'Z', 0x2211 },
981 { '-', '2', 0x2212 },
982 { '-', '+', 0x2213 },
983 { '*', '-', 0x2217 },
984 { 'O', 'b', 0x2218 },
985 { 'S', 'b', 0x2219 },
986 { 'R', 'T', 0x221a },
987 { '0', '(', 0x221d },
988 { '0', '0', 0x221e },
989 { '-', 'L', 0x221f },
990 { '-', 'V', 0x2220 },
991 { 'P', 'P', 0x2225 },
992 { 'A', 'N', 0x2227 },
993 { 'O', 'R', 0x2228 },
994 { '(', 'U', 0x2229 },
995 { ')', 'U', 0x222a },
996 { 'I', 'n', 0x222b },
997 { 'D', 'I', 0x222c },
998 { 'I', 'o', 0x222e },
999 { '.', ':', 0x2234 },
1000 { ':', '.', 0x2235 },
1001 { ':', 'R', 0x2236 },
1002 { ':', ':', 0x2237 },
1003 { '?', '1', 0x223c },
1004 { 'C', 'G', 0x223e },
1005 { '?', '-', 0x2243 },
1006 { '?', '=', 0x2245 },
1007 { '?', '2', 0x2248 },
1008 { '=', '?', 0x224c },
1009 { 'H', 'I', 0x2253 },
1010 { '!', '=', 0x2260 },
1011 { '=', '3', 0x2261 },
1012 { '=', '<', 0x2264 },
1013 { '>', '=', 0x2265 },
1014 { '<', '*', 0x226a },
1015 { '*', '>', 0x226b },
1016 { '!', '<', 0x226e },
1017 { '!', '>', 0x226f },
1018 { '(', 'C', 0x2282 },
1019 { ')', 'C', 0x2283 },
1020 { '(', '_', 0x2286 },
1021 { ')', '_', 0x2287 },
1022 { '0', '.', 0x2299 },
1023 { '0', '2', 0x229a },
1024 { '-', 'T', 0x22a5 },
1025 { '.', 'P', 0x22c5 },
1026 { ':', '3', 0x22ee },
1027 { '.', '3', 0x22ef },
1028 #define DG_START_TECHNICAL 0x2302
1029 { 'E', 'h', 0x2302 },
1030 { '<', '7', 0x2308 },
1031 { '>', '7', 0x2309 },
1032 { '7', '<', 0x230a },
1033 { '7', '>', 0x230b },
1034 { 'N', 'I', 0x2310 },
1035 { '(', 'A', 0x2312 },
1036 { 'T', 'R', 0x2315 },
1037 { 'I', 'u', 0x2320 },
1038 { 'I', 'l', 0x2321 },
1039 { '<', '/', 0x2329 },
1040 { '/', '>', 0x232a },
1041 #define DG_START_OTHER2 0x2423
1042 { 'V', 's', 0x2423 },
1043 { '1', 'h', 0x2440 },
1044 { '3', 'h', 0x2441 },
1045 { '2', 'h', 0x2442 },
1046 { '4', 'h', 0x2443 },
1047 { '1', 'j', 0x2446 },
1048 { '2', 'j', 0x2447 },
1049 { '3', 'j', 0x2448 },
1050 { '4', 'j', 0x2449 },
1051 { '1', '.', 0x2488 },
1052 { '2', '.', 0x2489 },
1053 { '3', '.', 0x248a },
1054 { '4', '.', 0x248b },
1055 { '5', '.', 0x248c },
1056 { '6', '.', 0x248d },
1057 { '7', '.', 0x248e },
1058 { '8', '.', 0x248f },
1059 { '9', '.', 0x2490 },
1060 #define DG_START_DRAWING 0x2500
1061 { 'h', 'h', 0x2500 },
1062 { 'H', 'H', 0x2501 },
1063 { 'v', 'v', 0x2502 },
1064 { 'V', 'V', 0x2503 },
1065 { '3', '-', 0x2504 },
1066 { '3', '_', 0x2505 },
1067 { '3', '!', 0x2506 },
1068 { '3', '/', 0x2507 },
1069 { '4', '-', 0x2508 },
1070 { '4', '_', 0x2509 },
1071 { '4', '!', 0x250a },
1072 { '4', '/', 0x250b },
1073 { 'd', 'r', 0x250c },
1074 { 'd', 'R', 0x250d },
1075 { 'D', 'r', 0x250e },
1076 { 'D', 'R', 0x250f },
1077 { 'd', 'l', 0x2510 },
1078 { 'd', 'L', 0x2511 },
1079 { 'D', 'l', 0x2512 },
1080 { 'L', 'D', 0x2513 },
1081 { 'u', 'r', 0x2514 },
1082 { 'u', 'R', 0x2515 },
1083 { 'U', 'r', 0x2516 },
1084 { 'U', 'R', 0x2517 },
1085 { 'u', 'l', 0x2518 },
1086 { 'u', 'L', 0x2519 },
1087 { 'U', 'l', 0x251a },
1088 { 'U', 'L', 0x251b },
1089 { 'v', 'r', 0x251c },
1090 { 'v', 'R', 0x251d },
1091 { 'V', 'r', 0x2520 },
1092 { 'V', 'R', 0x2523 },
1093 { 'v', 'l', 0x2524 },
1094 { 'v', 'L', 0x2525 },
1095 { 'V', 'l', 0x2528 },
1096 { 'V', 'L', 0x252b },
1097 { 'd', 'h', 0x252c },
1098 { 'd', 'H', 0x252f },
1099 { 'D', 'h', 0x2530 },
1100 { 'D', 'H', 0x2533 },
1101 { 'u', 'h', 0x2534 },
1102 { 'u', 'H', 0x2537 },
1103 { 'U', 'h', 0x2538 },
1104 { 'U', 'H', 0x253b },
1105 { 'v', 'h', 0x253c },
1106 { 'v', 'H', 0x253f },
1107 { 'V', 'h', 0x2542 },
1108 { 'V', 'H', 0x254b },
1109 { 'F', 'D', 0x2571 },
1110 { 'B', 'D', 0x2572 },
1111 #define DG_START_BLOCK 0x2580
1112 { 'T', 'B', 0x2580 },
1113 { 'L', 'B', 0x2584 },
1114 { 'F', 'B', 0x2588 },
1115 { 'l', 'B', 0x258c },
1116 { 'R', 'B', 0x2590 },
1117 { '.', 'S', 0x2591 },
1118 { ':', 'S', 0x2592 },
1119 { '?', 'S', 0x2593 },
1120 #define DG_START_SHAPES 0x25a0
1121 { 'f', 'S', 0x25a0 },
1122 { 'O', 'S', 0x25a1 },
1123 { 'R', 'O', 0x25a2 },
1124 { 'R', 'r', 0x25a3 },
1125 { 'R', 'F', 0x25a4 },
1126 { 'R', 'Y', 0x25a5 },
1127 { 'R', 'H', 0x25a6 },
1128 { 'R', 'Z', 0x25a7 },
1129 { 'R', 'K', 0x25a8 },
1130 { 'R', 'X', 0x25a9 },
1131 { 's', 'B', 0x25aa },
1132 { 'S', 'R', 0x25ac },
1133 { 'O', 'r', 0x25ad },
1134 { 'U', 'T', 0x25b2 },
1135 { 'u', 'T', 0x25b3 },
1136 { 'P', 'R', 0x25b6 },
1137 { 'T', 'r', 0x25b7 },
1138 { 'D', 't', 0x25bc },
1139 { 'd', 'T', 0x25bd },
1140 { 'P', 'L', 0x25c0 },
1141 { 'T', 'l', 0x25c1 },
1142 { 'D', 'b', 0x25c6 },
1143 { 'D', 'w', 0x25c7 },
1144 { 'L', 'Z', 0x25ca },
1145 { '0', 'm', 0x25cb },
1146 { '0', 'o', 0x25ce },
1147 { '0', 'M', 0x25cf },
1148 { '0', 'L', 0x25d0 },
1149 { '0', 'R', 0x25d1 },
1150 { 'S', 'n', 0x25d8 },
1151 { 'I', 'c', 0x25d9 },
1152 { 'F', 'd', 0x25e2 },
1153 { 'B', 'd', 0x25e3 },
1154 #define DG_START_SYMBOLS 0x2605
1155 { '*', '2', 0x2605 },
1156 { '*', '1', 0x2606 },
1157 { '<', 'H', 0x261c },
1158 { '>', 'H', 0x261e },
1159 { '0', 'u', 0x263a },
1160 { '0', 'U', 0x263b },
1161 { 'S', 'U', 0x263c },
1162 { 'F', 'm', 0x2640 },
1163 { 'M', 'l', 0x2642 },
1164 { 'c', 'S', 0x2660 },
1165 { 'c', 'H', 0x2661 },
1166 { 'c', 'D', 0x2662 },
1167 { 'c', 'C', 0x2663 },
1168 { 'M', 'd', 0x2669 },
1169 { 'M', '8', 0x266a },
1170 { 'M', '2', 0x266b },
1171 { 'M', 'b', 0x266d },
1172 { 'M', 'x', 0x266e },
1173 { 'M', 'X', 0x266f },
1174 #define DG_START_DINGBATS 0x2713
1175 { 'O', 'K', 0x2713 },
1176 { 'X', 'X', 0x2717 },
1177 { '-', 'X', 0x2720 },
1178 #define DG_START_CJK_SYMBOLS 0x3000
1179 { 'I', 'S', 0x3000 },
1180 { ',', '_', 0x3001 },
1181 { '.', '_', 0x3002 },
1182 { '+', '"', 0x3003 },
1183 { '+', '_', 0x3004 },
1184 { '*', '_', 0x3005 },
1185 { ';', '_', 0x3006 },
1186 { '0', '_', 0x3007 },
1187 { '<', '+', 0x300a },
1188 { '>', '+', 0x300b },
1189 { '<', '\'', 0x300c },
1190 { '>', '\'', 0x300d },
1191 { '<', '"', 0x300e },
1192 { '>', '"', 0x300f },
1193 { '(', '"', 0x3010 },
1194 { ')', '"', 0x3011 },
1195 { '=', 'T', 0x3012 },
1196 { '=', '_', 0x3013 },
1197 { '(', '\'', 0x3014 },
1198 { ')', '\'', 0x3015 },
1199 { '(', 'I', 0x3016 },
1200 { ')', 'I', 0x3017 },
1201 { '-', '?', 0x301c },
1202 #define DG_START_HIRAGANA 0x3041
1203 { 'A', '5', 0x3041 },
1204 { 'a', '5', 0x3042 },
1205 { 'I', '5', 0x3043 },
1206 { 'i', '5', 0x3044 },
1207 { 'U', '5', 0x3045 },
1208 { 'u', '5', 0x3046 },
1209 { 'E', '5', 0x3047 },
1210 { 'e', '5', 0x3048 },
1211 { 'O', '5', 0x3049 },
1212 { 'o', '5', 0x304a },
1213 { 'k', 'a', 0x304b },
1214 { 'g', 'a', 0x304c },
1215 { 'k', 'i', 0x304d },
1216 { 'g', 'i', 0x304e },
1217 { 'k', 'u', 0x304f },
1218 { 'g', 'u', 0x3050 },
1219 { 'k', 'e', 0x3051 },
1220 { 'g', 'e', 0x3052 },
1221 { 'k', 'o', 0x3053 },
1222 { 'g', 'o', 0x3054 },
1223 { 's', 'a', 0x3055 },
1224 { 'z', 'a', 0x3056 },
1225 { 's', 'i', 0x3057 },
1226 { 'z', 'i', 0x3058 },
1227 { 's', 'u', 0x3059 },
1228 { 'z', 'u', 0x305a },
1229 { 's', 'e', 0x305b },
1230 { 'z', 'e', 0x305c },
1231 { 's', 'o', 0x305d },
1232 { 'z', 'o', 0x305e },
1233 { 't', 'a', 0x305f },
1234 { 'd', 'a', 0x3060 },
1235 { 't', 'i', 0x3061 },
1236 { 'd', 'i', 0x3062 },
1237 { 't', 'U', 0x3063 },
1238 { 't', 'u', 0x3064 },
1239 { 'd', 'u', 0x3065 },
1240 { 't', 'e', 0x3066 },
1241 { 'd', 'e', 0x3067 },
1242 { 't', 'o', 0x3068 },
1243 { 'd', 'o', 0x3069 },
1244 { 'n', 'a', 0x306a },
1245 { 'n', 'i', 0x306b },
1246 { 'n', 'u', 0x306c },
1247 { 'n', 'e', 0x306d },
1248 { 'n', 'o', 0x306e },
1249 { 'h', 'a', 0x306f },
1250 { 'b', 'a', 0x3070 },
1251 { 'p', 'a', 0x3071 },
1252 { 'h', 'i', 0x3072 },
1253 { 'b', 'i', 0x3073 },
1254 { 'p', 'i', 0x3074 },
1255 { 'h', 'u', 0x3075 },
1256 { 'b', 'u', 0x3076 },
1257 { 'p', 'u', 0x3077 },
1258 { 'h', 'e', 0x3078 },
1259 { 'b', 'e', 0x3079 },
1260 { 'p', 'e', 0x307a },
1261 { 'h', 'o', 0x307b },
1262 { 'b', 'o', 0x307c },
1263 { 'p', 'o', 0x307d },
1264 { 'm', 'a', 0x307e },
1265 { 'm', 'i', 0x307f },
1266 { 'm', 'u', 0x3080 },
1267 { 'm', 'e', 0x3081 },
1268 { 'm', 'o', 0x3082 },
1269 { 'y', 'A', 0x3083 },
1270 { 'y', 'a', 0x3084 },
1271 { 'y', 'U', 0x3085 },
1272 { 'y', 'u', 0x3086 },
1273 { 'y', 'O', 0x3087 },
1274 { 'y', 'o', 0x3088 },
1275 { 'r', 'a', 0x3089 },
1276 { 'r', 'i', 0x308a },
1277 { 'r', 'u', 0x308b },
1278 { 'r', 'e', 0x308c },
1279 { 'r', 'o', 0x308d },
1280 { 'w', 'A', 0x308e },
1281 { 'w', 'a', 0x308f },
1282 { 'w', 'i', 0x3090 },
1283 { 'w', 'e', 0x3091 },
1284 { 'w', 'o', 0x3092 },
1285 { 'n', '5', 0x3093 },
1286 { 'v', 'u', 0x3094 },
1287 { '"', '5', 0x309b },
1288 { '0', '5', 0x309c },
1289 { '*', '5', 0x309d },
1290 { '+', '5', 0x309e },
1291 #define DG_START_KATAKANA 0x30a1
1292 { 'a', '6', 0x30a1 },
1293 { 'A', '6', 0x30a2 },
1294 { 'i', '6', 0x30a3 },
1295 { 'I', '6', 0x30a4 },
1296 { 'u', '6', 0x30a5 },
1297 { 'U', '6', 0x30a6 },
1298 { 'e', '6', 0x30a7 },
1299 { 'E', '6', 0x30a8 },
1300 { 'o', '6', 0x30a9 },
1301 { 'O', '6', 0x30aa },
1302 { 'K', 'a', 0x30ab },
1303 { 'G', 'a', 0x30ac },
1304 { 'K', 'i', 0x30ad },
1305 { 'G', 'i', 0x30ae },
1306 { 'K', 'u', 0x30af },
1307 { 'G', 'u', 0x30b0 },
1308 { 'K', 'e', 0x30b1 },
1309 { 'G', 'e', 0x30b2 },
1310 { 'K', 'o', 0x30b3 },
1311 { 'G', 'o', 0x30b4 },
1312 { 'S', 'a', 0x30b5 },
1313 { 'Z', 'a', 0x30b6 },
1314 { 'S', 'i', 0x30b7 },
1315 { 'Z', 'i', 0x30b8 },
1316 { 'S', 'u', 0x30b9 },
1317 { 'Z', 'u', 0x30ba },
1318 { 'S', 'e', 0x30bb },
1319 { 'Z', 'e', 0x30bc },
1320 { 'S', 'o', 0x30bd },
1321 { 'Z', 'o', 0x30be },
1322 { 'T', 'a', 0x30bf },
1323 { 'D', 'a', 0x30c0 },
1324 { 'T', 'i', 0x30c1 },
1325 { 'D', 'i', 0x30c2 },
1326 { 'T', 'U', 0x30c3 },
1327 { 'T', 'u', 0x30c4 },
1328 { 'D', 'u', 0x30c5 },
1329 { 'T', 'e', 0x30c6 },
1330 { 'D', 'e', 0x30c7 },
1331 { 'T', 'o', 0x30c8 },
1332 { 'D', 'o', 0x30c9 },
1333 { 'N', 'a', 0x30ca },
1334 { 'N', 'i', 0x30cb },
1335 { 'N', 'u', 0x30cc },
1336 { 'N', 'e', 0x30cd },
1337 { 'N', 'o', 0x30ce },
1338 { 'H', 'a', 0x30cf },
1339 { 'B', 'a', 0x30d0 },
1340 { 'P', 'a', 0x30d1 },
1341 { 'H', 'i', 0x30d2 },
1342 { 'B', 'i', 0x30d3 },
1343 { 'P', 'i', 0x30d4 },
1344 { 'H', 'u', 0x30d5 },
1345 { 'B', 'u', 0x30d6 },
1346 { 'P', 'u', 0x30d7 },
1347 { 'H', 'e', 0x30d8 },
1348 { 'B', 'e', 0x30d9 },
1349 { 'P', 'e', 0x30da },
1350 { 'H', 'o', 0x30db },
1351 { 'B', 'o', 0x30dc },
1352 { 'P', 'o', 0x30dd },
1353 { 'M', 'a', 0x30de },
1354 { 'M', 'i', 0x30df },
1355 { 'M', 'u', 0x30e0 },
1356 { 'M', 'e', 0x30e1 },
1357 { 'M', 'o', 0x30e2 },
1358 { 'Y', 'A', 0x30e3 },
1359 { 'Y', 'a', 0x30e4 },
1360 { 'Y', 'U', 0x30e5 },
1361 { 'Y', 'u', 0x30e6 },
1362 { 'Y', 'O', 0x30e7 },
1363 { 'Y', 'o', 0x30e8 },
1364 { 'R', 'a', 0x30e9 },
1365 { 'R', 'i', 0x30ea },
1366 { 'R', 'u', 0x30eb },
1367 { 'R', 'e', 0x30ec },
1368 { 'R', 'o', 0x30ed },
1369 { 'W', 'A', 0x30ee },
1370 { 'W', 'a', 0x30ef },
1371 { 'W', 'i', 0x30f0 },
1372 { 'W', 'e', 0x30f1 },
1373 { 'W', 'o', 0x30f2 },
1374 { 'N', '6', 0x30f3 },
1375 { 'V', 'u', 0x30f4 },
1376 { 'K', 'A', 0x30f5 },
1377 { 'K', 'E', 0x30f6 },
1378 { 'V', 'a', 0x30f7 },
1379 { 'V', 'i', 0x30f8 },
1380 { 'V', 'e', 0x30f9 },
1381 { 'V', 'o', 0x30fa },
1382 { '.', '6', 0x30fb },
1383 { '-', '6', 0x30fc },
1384 { '*', '6', 0x30fd },
1385 { '+', '6', 0x30fe },
1386 #define DG_START_BOPOMOFO 0x3105
1387 { 'b', '4', 0x3105 },
1388 { 'p', '4', 0x3106 },
1389 { 'm', '4', 0x3107 },
1390 { 'f', '4', 0x3108 },
1391 { 'd', '4', 0x3109 },
1392 { 't', '4', 0x310a },
1393 { 'n', '4', 0x310b },
1394 { 'l', '4', 0x310c },
1395 { 'g', '4', 0x310d },
1396 { 'k', '4', 0x310e },
1397 { 'h', '4', 0x310f },
1398 { 'j', '4', 0x3110 },
1399 { 'q', '4', 0x3111 },
1400 { 'x', '4', 0x3112 },
1401 { 'z', 'h', 0x3113 },
1402 { 'c', 'h', 0x3114 },
1403 { 's', 'h', 0x3115 },
1404 { 'r', '4', 0x3116 },
1405 { 'z', '4', 0x3117 },
1406 { 'c', '4', 0x3118 },
1407 { 's', '4', 0x3119 },
1408 { 'a', '4', 0x311a },
1409 { 'o', '4', 0x311b },
1410 { 'e', '4', 0x311c },
1411 { 'a', 'i', 0x311e },
1412 { 'e', 'i', 0x311f },
1413 { 'a', 'u', 0x3120 },
1414 { 'o', 'u', 0x3121 },
1415 { 'a', 'n', 0x3122 },
1416 { 'e', 'n', 0x3123 },
1417 { 'a', 'N', 0x3124 },
1418 { 'e', 'N', 0x3125 },
1419 { 'e', 'r', 0x3126 },
1420 { 'i', '4', 0x3127 },
1421 { 'u', '4', 0x3128 },
1422 { 'i', 'u', 0x3129 },
1423 { 'v', '4', 0x312a },
1424 { 'n', 'G', 0x312b },
1425 { 'g', 'n', 0x312c },
1426 #define DG_START_OTHER3 0x3220
1427 { '1', 'c', 0x3220 },
1428 { '2', 'c', 0x3221 },
1429 { '3', 'c', 0x3222 },
1430 { '4', 'c', 0x3223 },
1431 { '5', 'c', 0x3224 },
1432 { '6', 'c', 0x3225 },
1433 { '7', 'c', 0x3226 },
1434 { '8', 'c', 0x3227 },
1435 { '9', 'c', 0x3228 },
1436
1437 // code points 0xe000 - 0xefff excluded, they have no assigned
1438 // characters, only used in proposals.
1439 { 'f', 'f', 0xfb00 },
1440 { 'f', 'i', 0xfb01 },
1441 { 'f', 'l', 0xfb02 },
1442 { 'f', 't', 0xfb05 },
1443 { 's', 't', 0xfb06 },
1444
1445 { NUL, NUL, NUL }
1446 };
1447
1448 /// handle digraphs after typing a character
1449 ///
1450 /// @param c
1451 ///
1452 /// @return The digraph.
do_digraph(int c)1453 int do_digraph(int c)
1454 {
1455 static int backspaced; // character before K_BS
1456 static int lastchar; // last typed character
1457
1458 if (c == -1) { // init values
1459 backspaced = -1;
1460 } else if (p_dg) {
1461 if (backspaced >= 0) {
1462 c = getdigraph(backspaced, c, false);
1463 }
1464 backspaced = -1;
1465
1466 if (((c == K_BS) || (c == Ctrl_H)) && (lastchar >= 0)) {
1467 backspaced = lastchar;
1468 }
1469 }
1470 lastchar = c;
1471 return c;
1472 }
1473
1474 /// Find a digraph for "val". If found return the string to display it.
1475 /// If not found return NULL.
get_digraph_for_char(int val_arg)1476 char_u *get_digraph_for_char(int val_arg)
1477 {
1478 const int val = val_arg;
1479 digr_T *dp;
1480 static char_u r[3];
1481
1482 for (int use_defaults = 0; use_defaults <= 1; use_defaults++) {
1483 if (use_defaults == 0) {
1484 dp = (digr_T *)user_digraphs.ga_data;
1485 } else {
1486 dp = digraphdefault;
1487 }
1488 for (int i = 0;
1489 use_defaults ? dp->char1 != NUL : i < user_digraphs.ga_len; i++) {
1490 if (dp->result == val) {
1491 r[0] = dp->char1;
1492 r[1] = dp->char2;
1493 r[2] = NUL;
1494 return r;
1495 }
1496 dp++;
1497 }
1498 }
1499 return NULL;
1500 }
1501
1502 /// Get a digraph. Used after typing CTRL-K on the command line or in normal
1503 /// mode.
1504 ///
1505 /// @param cmdline true when called from the cmdline
1506 ///
1507 /// @returns composed character, or NUL when ESC was used.
get_digraph(bool cmdline)1508 int get_digraph(bool cmdline)
1509 {
1510 int cc;
1511 no_mapping++;
1512 int c = plain_vgetc();
1513 no_mapping--;
1514
1515 if (c != ESC) {
1516 // ESC cancels CTRL-K
1517 if (IS_SPECIAL(c)) {
1518 // insert special key code
1519 return c;
1520 }
1521
1522 if (cmdline) {
1523 if ((char2cells(c) == 1) && c < 128 && (cmdline_star == 0)) {
1524 putcmdline((char)c, true);
1525 }
1526 } else {
1527 add_to_showcmd(c);
1528 }
1529 no_mapping++;
1530 cc = plain_vgetc();
1531 no_mapping--;
1532
1533 if (cc != ESC) {
1534 // ESC cancels CTRL-K
1535 return getdigraph(c, cc, true);
1536 }
1537 }
1538 return NUL;
1539 }
1540
1541 /// Lookup the pair "char1", "char2" in the digraph tables.
1542 ///
1543 /// @param char1
1544 /// @param char2
1545 /// @param meta_char
1546 ///
1547 /// @return If no match, return "char2". If "meta_char" is true and "char1"
1548 // is a space, return "char2" | 0x80.
getexactdigraph(int char1,int char2,bool meta_char)1549 static int getexactdigraph(int char1, int char2, bool meta_char)
1550 {
1551 int retval = 0;
1552
1553 if (IS_SPECIAL(char1) || IS_SPECIAL(char2)) {
1554 return char2;
1555 }
1556
1557 // Search user digraphs first.
1558 digr_T *dp = (digr_T *)user_digraphs.ga_data;
1559 for (int i = 0; i < user_digraphs.ga_len; ++i) {
1560 if (((int)dp->char1 == char1) && ((int)dp->char2 == char2)) {
1561 retval = dp->result;
1562 break;
1563 }
1564 ++dp;
1565 }
1566
1567 // Search default digraphs.
1568 if (retval == 0) {
1569 dp = digraphdefault;
1570
1571 for (int i = 0; dp->char1 != 0; ++i) {
1572 if (((int)dp->char1 == char1) && ((int)dp->char2 == char2)) {
1573 retval = dp->result;
1574 break;
1575 }
1576 ++dp;
1577 }
1578 }
1579
1580 if (retval == 0) {
1581 // digraph deleted or not found
1582 if ((char1 == ' ') && meta_char) {
1583 // <space> <char> --> meta-char
1584 return char2 | 0x80;
1585 }
1586 return char2;
1587 }
1588 return retval;
1589 }
1590
1591 /// Get digraph.
1592 /// Allow for both char1-char2 and char2-char1
1593 ///
1594 /// @param char1
1595 /// @param char2
1596 /// @param meta_char
1597 ///
1598 /// @return The digraph.
getdigraph(int char1,int char2,bool meta_char)1599 int getdigraph(int char1, int char2, bool meta_char)
1600 {
1601 int retval;
1602
1603 if (((retval = getexactdigraph(char1, char2, meta_char)) == char2)
1604 && (char1 != char2)
1605 && ((retval = getexactdigraph(char2, char1, meta_char)) // -V764
1606 == char1)) {
1607 return char2;
1608 }
1609 return retval;
1610 }
1611
1612 /// Add the digraphs in the argument to the digraph table.
1613 /// format: {c1}{c2} char {c1}{c2} char ...
1614 ///
1615 /// @param str
putdigraph(char_u * str)1616 void putdigraph(char_u *str)
1617 {
1618 char_u char1, char2;
1619 digr_T *dp;
1620
1621 while (*str != NUL) {
1622 str = skipwhite(str);
1623
1624 if (*str == NUL) {
1625 return;
1626 }
1627 char1 = *str++;
1628 char2 = *str++;
1629
1630 if (char2 == 0) {
1631 emsg(_(e_invarg));
1632 return;
1633 }
1634
1635 if ((char1 == ESC) || (char2 == ESC)) {
1636 emsg(_("E104: Escape not allowed in digraph"));
1637 return;
1638 }
1639 str = skipwhite(str);
1640
1641 if (!ascii_isdigit(*str)) {
1642 emsg(_(e_number_exp));
1643 return;
1644 }
1645 int n = getdigits_int(&str, true, 0);
1646
1647 // If the digraph already exists, replace the result.
1648 dp = (digr_T *)user_digraphs.ga_data;
1649
1650 int i;
1651 for (i = 0; i < user_digraphs.ga_len; ++i) {
1652 if (((int)dp->char1 == char1) && ((int)dp->char2 == char2)) {
1653 dp->result = n;
1654 break;
1655 }
1656 ++dp;
1657 }
1658
1659 // Add a new digraph to the table.
1660 if (i == user_digraphs.ga_len) {
1661 dp = GA_APPEND_VIA_PTR(digr_T, &user_digraphs);
1662 dp->char1 = char1;
1663 dp->char2 = char2;
1664 dp->result = n;
1665 }
1666 }
1667 }
1668
digraph_header(const char * msg)1669 static void digraph_header(const char *msg)
1670 FUNC_ATTR_NONNULL_ALL
1671 {
1672 if (msg_col > 0) {
1673 msg_putchar('\n');
1674 }
1675 msg_outtrans_attr((const char_u *)msg, HL_ATTR(HLF_CM));
1676 msg_putchar('\n');
1677 }
1678
listdigraphs(bool use_headers)1679 void listdigraphs(bool use_headers)
1680 {
1681 digr_T *dp;
1682 result_T previous = 0;
1683
1684 msg_putchar('\n');
1685
1686 dp = digraphdefault;
1687
1688 for (int i = 0; dp->char1 != NUL && !got_int; ++i) {
1689 digr_T tmp;
1690
1691 // May need to convert the result to 'encoding'.
1692 tmp.char1 = dp->char1;
1693 tmp.char2 = dp->char2;
1694 tmp.result = getexactdigraph(tmp.char1, tmp.char2, false);
1695
1696 if ((tmp.result != 0)
1697 && (tmp.result != tmp.char2)) {
1698 printdigraph(&tmp, use_headers ? &previous : NULL);
1699 }
1700 dp++;
1701 fast_breakcheck();
1702 }
1703
1704 dp = (digr_T *)user_digraphs.ga_data;
1705 for (int i = 0; i < user_digraphs.ga_len && !got_int; i++) {
1706 if (previous >= 0 && use_headers) {
1707 digraph_header(_("Custom"));
1708 }
1709 previous = -1;
1710 printdigraph(dp, NULL);
1711 fast_breakcheck();
1712 dp++;
1713 }
1714 }
1715
1716 struct dg_header_entry {
1717 int dg_start;
1718 const char *dg_header;
1719 } header_table[] = {
1720 { DG_START_LATIN, N_("Latin supplement") },
1721 { DG_START_GREEK, N_("Greek and Coptic") },
1722 { DG_START_CYRILLIC, N_("Cyrillic") },
1723 { DG_START_HEBREW, N_("Hebrew") },
1724 { DG_START_ARABIC, N_("Arabic") },
1725 { DG_START_LATIN_EXTENDED, N_("Latin extended") },
1726 { DG_START_GREEK_EXTENDED, N_("Greek extended") },
1727 { DG_START_PUNCTUATION, N_("Punctuation") },
1728 { DG_START_SUB_SUPER, N_("Super- and subscripts") },
1729 { DG_START_CURRENCY, N_("Currency") },
1730 { DG_START_OTHER1, N_("Other") },
1731 { DG_START_ROMAN, N_("Roman numbers") },
1732 { DG_START_ARROWS, N_("Arrows") },
1733 { DG_START_MATH, N_("Mathematical operators") },
1734 { DG_START_TECHNICAL, N_("Technical") },
1735 { DG_START_OTHER2, N_("Other") },
1736 { DG_START_DRAWING, N_("Box drawing") },
1737 { DG_START_BLOCK, N_("Block elements") },
1738 { DG_START_SHAPES, N_("Geometric shapes") },
1739 { DG_START_SYMBOLS, N_("Symbols") },
1740 { DG_START_DINGBATS, N_("Dingbats") },
1741 { DG_START_CJK_SYMBOLS, N_("CJK symbols and punctuation") },
1742 { DG_START_HIRAGANA, N_("Hiragana") },
1743 { DG_START_KATAKANA, N_("Katakana") },
1744 { DG_START_BOPOMOFO, N_("Bopomofo") },
1745 { DG_START_OTHER3, N_("Other") },
1746 { 0xfffffff, NULL },
1747 };
1748
printdigraph(const digr_T * dp,result_T * previous)1749 static void printdigraph(const digr_T *dp, result_T *previous)
1750 FUNC_ATTR_NONNULL_ARG(1)
1751 {
1752 char_u buf[30];
1753 char_u *p;
1754
1755 int list_width;
1756
1757 list_width = 13;
1758
1759 if (dp->result != 0) {
1760 if (previous != NULL) {
1761 for (int i = 0; header_table[i].dg_header != NULL; i++) {
1762 if (*previous < header_table[i].dg_start
1763 && dp->result >= header_table[i].dg_start
1764 && dp->result < header_table[i + 1].dg_start) {
1765 digraph_header(_(header_table[i].dg_header));
1766 break;
1767 }
1768 }
1769 *previous = dp->result;
1770 }
1771 if (msg_col > Columns - list_width) {
1772 msg_putchar('\n');
1773 }
1774
1775
1776 // Make msg_col a multiple of list_width by using spaces.
1777 if (msg_col % list_width != 0) {
1778 int spaces = (msg_col / list_width + 1) * list_width - msg_col;
1779 while (spaces--) {
1780 msg_putchar(' ');
1781 }
1782 }
1783
1784 p = &buf[0];
1785 *p++ = dp->char1;
1786 *p++ = dp->char2;
1787 *p++ = ' ';
1788 *p = NUL;
1789 msg_outtrans(buf);
1790 p = buf;
1791
1792 // add a space to draw a composing char on
1793 if (utf_iscomposing(dp->result)) {
1794 *p++ = ' ';
1795 }
1796 p += utf_char2bytes(dp->result, p);
1797
1798 *p = NUL;
1799 msg_outtrans_attr(buf, HL_ATTR(HLF_8));
1800 p = buf;
1801 if (char2cells(dp->result) == 1) {
1802 *p++ = ' ';
1803 }
1804 assert(p >= buf);
1805 vim_snprintf((char *)p, sizeof(buf) - (size_t)(p - buf), " %3d", dp->result);
1806 msg_outtrans(buf);
1807 }
1808 }
1809
1810 /// structure used for b_kmap_ga.ga_data
1811 typedef struct {
1812 char_u *from;
1813 char_u *to;
1814 } kmap_T;
1815
1816 #define KMAP_MAXLEN 20 // maximum length of "from" or "to"
1817
1818
1819 /// Set up key mapping tables for the 'keymap' option.
1820 ///
1821 /// @return NULL if OK, an error message for failure. This only needs to be
1822 /// used when setting the option, not later when the value has already
1823 /// been checked.
keymap_init(void)1824 char *keymap_init(void)
1825 {
1826 curbuf->b_kmap_state &= ~KEYMAP_INIT;
1827
1828 if (*curbuf->b_p_keymap == NUL) {
1829 // Stop any active keymap and clear the table. Also remove
1830 // b:keymap_name, as no keymap is active now.
1831 keymap_unload();
1832 do_cmdline_cmd("unlet! b:keymap_name");
1833 } else {
1834 char *buf;
1835 size_t buflen;
1836
1837 // Source the keymap file. It will contain a ":loadkeymap" command
1838 // which will call ex_loadkeymap() below.
1839 buflen = STRLEN(curbuf->b_p_keymap) + STRLEN(p_enc) + 14;
1840 buf = xmalloc(buflen);
1841
1842 // try finding "keymap/'keymap'_'encoding'.vim" in 'runtimepath'
1843 vim_snprintf(buf, buflen, "keymap/%s_%s.vim",
1844 curbuf->b_p_keymap, p_enc);
1845
1846 if (source_runtime(buf, 0) == FAIL) {
1847 // try finding "keymap/'keymap'.vim" in 'runtimepath'
1848 vim_snprintf(buf, buflen, "keymap/%s.vim",
1849 curbuf->b_p_keymap);
1850
1851 if (source_runtime(buf, 0) == FAIL) {
1852 xfree(buf);
1853 return N_("E544: Keymap file not found");
1854 }
1855 }
1856 xfree(buf);
1857 }
1858
1859 return NULL;
1860 }
1861
1862 /// ":loadkeymap" command: load the following lines as the keymap.
1863 ///
1864 /// @param eap
ex_loadkeymap(exarg_T * eap)1865 void ex_loadkeymap(exarg_T *eap)
1866 {
1867 char_u *line;
1868 char_u *p;
1869 char_u *s;
1870
1871 #define KMAP_LLEN 200 // max length of "to" and "from" together
1872 char_u buf[KMAP_LLEN + 11];
1873 char_u *save_cpo = p_cpo;
1874
1875 if (!getline_equal(eap->getline, eap->cookie, getsourceline)) {
1876 emsg(_("E105: Using :loadkeymap not in a sourced file"));
1877 return;
1878 }
1879
1880 // Stop any active keymap and clear the table.
1881 keymap_unload();
1882
1883 curbuf->b_kmap_state = 0;
1884 ga_init(&curbuf->b_kmap_ga, (int)sizeof(kmap_T), 20);
1885
1886 // Set 'cpoptions' to "C" to avoid line continuation.
1887 p_cpo = (char_u *)"C";
1888
1889 // Get each line of the sourced file, break at the end.
1890 for (;;) {
1891 line = eap->getline(0, eap->cookie, 0, true);
1892
1893 if (line == NULL) {
1894 break;
1895 }
1896
1897 p = skipwhite(line);
1898
1899 if ((*p != '"') && (*p != NUL)) {
1900 kmap_T *kp = GA_APPEND_VIA_PTR(kmap_T, &curbuf->b_kmap_ga);
1901 s = skiptowhite(p);
1902 kp->from = vim_strnsave(p, (size_t)(s - p));
1903 p = skipwhite(s);
1904 s = skiptowhite(p);
1905 kp->to = vim_strnsave(p, (size_t)(s - p));
1906
1907 if ((STRLEN(kp->from) + STRLEN(kp->to) >= KMAP_LLEN)
1908 || (*kp->from == NUL)
1909 || (*kp->to == NUL)) {
1910 if (*kp->to == NUL) {
1911 emsg(_("E791: Empty keymap entry"));
1912 }
1913 xfree(kp->from);
1914 xfree(kp->to);
1915 --curbuf->b_kmap_ga.ga_len;
1916 }
1917 }
1918 xfree(line);
1919 }
1920
1921 // setup ":lmap" to map the keys
1922 for (int i = 0; i < curbuf->b_kmap_ga.ga_len; i++) {
1923 vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s %s",
1924 ((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].from,
1925 ((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].to);
1926 (void)do_map(0, buf, LANGMAP, false);
1927 }
1928
1929 p_cpo = save_cpo;
1930
1931 curbuf->b_kmap_state |= KEYMAP_LOADED;
1932 status_redraw_curbuf();
1933 }
1934
1935 /// Frees the buf_T.b_kmap_ga field of a buffer.
keymap_ga_clear(garray_T * kmap_ga)1936 void keymap_ga_clear(garray_T *kmap_ga)
1937 {
1938 kmap_T *kp = (kmap_T *)kmap_ga->ga_data;
1939 for (int i = 0; i < kmap_ga->ga_len; i++) {
1940 xfree(kp[i].from);
1941 xfree(kp[i].to);
1942 }
1943 }
1944
1945 /// Stop using 'keymap'.
keymap_unload(void)1946 static void keymap_unload(void)
1947 {
1948 char_u buf[KMAP_MAXLEN + 10];
1949 char_u *save_cpo = p_cpo;
1950 kmap_T *kp;
1951
1952 if (!(curbuf->b_kmap_state & KEYMAP_LOADED)) {
1953 return;
1954 }
1955
1956 // Set 'cpoptions' to "C" to avoid line continuation.
1957 p_cpo = (char_u *)"C";
1958
1959 // clear the ":lmap"s
1960 kp = (kmap_T *)curbuf->b_kmap_ga.ga_data;
1961
1962 for (int i = 0; i < curbuf->b_kmap_ga.ga_len; i++) {
1963 vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s", kp[i].from);
1964 (void)do_map(1, buf, LANGMAP, false);
1965 }
1966 keymap_ga_clear(&curbuf->b_kmap_ga);
1967
1968 p_cpo = save_cpo;
1969
1970 ga_clear(&curbuf->b_kmap_ga);
1971 curbuf->b_kmap_state &= ~KEYMAP_LOADED;
1972 status_redraw_curbuf();
1973 }
1974