1 /* vi:set ts=8 sts=4 sw=4 noet:
2  *
3  * VIM - Vi IMproved	by Bram Moolenaar
4  *
5  * Do ":help uganda"  in Vim to read copying and usage conditions.
6  * Do ":help credits" in Vim to see a list of people who contributed.
7  * See README.txt for an overview of the Vim source code.
8  */
9 
10 /*
11  * digraph.c: code for digraphs
12  */
13 
14 #include "vim.h"
15 
16 #if defined(FEAT_DIGRAPHS) || defined(PROTO)
17 
18 typedef int result_T;
19 
20 typedef struct digraph
21 {
22     char_u	char1;
23     char_u	char2;
24     result_T	result;
25 } digr_T;
26 
27 static void printdigraph(digr_T *dp, result_T *previous);
28 
29 // digraphs added by the user
30 static garray_T	user_digraphs = {0, 0, (int)sizeof(digr_T), 10, NULL};
31 
32 /*
33  * Note: Characters marked with XX are not included literally, because some
34  * compilers cannot handle them (Amiga SAS/C is the most picky one).
35  */
36 static digr_T digraphdefault[] =
37 
38 #ifdef HPUX_DIGRAPHS
39 	/*
40 	 * different HPUX digraphs
41 	 */
42        {{'A', '`', 161},	// ¡
43 	{'A', '^', 162},	// ¢
44 	{'E', '`', 163},	// £
45 	{'E', '^', 164},	// ¤
46 	{'E', '"', 165},	// ¥
47 	{'I', '^', 166},	// ¦
48 	{'I', '"', 167},	// §
49 	{'\'', '\'', 168},	// ¨
50 	{'`', '`', 169},	// ©
51 	{'^', '^', 170},	// ª
52 	{'"', '"', 171},	// «
53 	{'~', '~', 172},	// ¬
54 	{'U', '`', 173},	// ­
55 	{'U', '^', 174},	// ®
56 	{'L', '=', 175},	// ¯
57 	{'~', '_', 176},	// °
58 	{'Y', '\'', 177},	// ±
59 	{'y', '\'', 178},	// ²
60 	{'~', 'o', 179},	// ³
61 	{'C', ',', 180},	// ´
62 	{'c', ',', 181},	// µ
63 	{'N', '~', 182},	// ¶
64 	{'n', '~', 183},	// ·
65 	{'~', '!', 184},	// ¸
66 	{'~', '?', 185},	// ¹
67 	{'o', 'x', 186},	// º
68 	{'L', '-', 187},	// »
69 	{'Y', '=', 188},	// ¼
70 	{'p', 'p', 189},	// ½
71 	{'f', 'l', 190},	// ¾
72 	{'c', '|', 191},	// ¿
73 	{'a', '^', 192},	// À
74 	{'e', '^', 193},	// Á
75 	{'o', '^', 194},	// Â
76 	{'u', '^', 195},	// Ã
77 	{'a', '\'', 196},	// Ä
78 	{'e', '\'', 197},	// Å
79 	{'o', '\'', 198},	// Æ
80 	{'u', '\'', 199},	// Ç
81 	{'a', '`', 200},	// È
82 	{'e', '`', 201},	// É
83 	{'o', '`', 202},	// Ê
84 	{'u', '`', 203},	// Ë
85 	{'a', '"', 204},	// Ì
86 	{'e', '"', 205},	// Í
87 	{'o', '"', 206},	// Î
88 	{'u', '"', 207},	// Ï
89 	{'A', 'o', 208},	// Ð
90 	{'i', '^', 209},	// Ñ
91 	{'O', '/', 210},	// Ò
92 	{'A', 'E', 211},	// Ó
93 	{'a', 'o', 212},	// Ô
94 	{'i', '\'', 213},	// Õ
95 	{'o', '/', 214},	// Ö
96 	{'a', 'e', 215},	// ×
97 	{'A', '"', 216},	// Ø
98 	{'i', '`', 217},	// Ù
99 	{'O', '"', 218},	// Ú
100 	{'U', '"', 219},	// Û
101 	{'E', '\'', 220},	// Ü
102 	{'i', '"', 221},	// Ý
103 	{'s', 's', 222},	// Þ
104 	{'O', '^', 223},	// ß
105 	{'A', '\'', 224},	// à
106 	{'A', '~', 225},	// á
107 	{'a', '~', 226},	// â
108 	{'D', '-', 227},	// ã
109 	{'d', '-', 228},	// ä
110 	{'I', '\'', 229},	// å
111 	{'I', '`', 230},	// æ
112 	{'O', '\'', 231},	// ç
113 	{'O', '`', 232},	// è
114 	{'O', '~', 233},	// é
115 	{'o', '~', 234},	// ê
116 	{'S', '~', 235},	// ë
117 	{'s', '~', 236},	// ì
118 	{'U', '\'', 237},	// í
119 	{'Y', '"', 238},	// î
120 	{'y', '"', 239},	// ï
121 	{'p', '-', 240},	// ð
122 	{'p', '~', 241},	// ñ
123 	{'~', '.', 242},	// ò
124 	{'j', 'u', 243},	// ó
125 	{'P', 'p', 244},	// ô
126 	{'3', '4', 245},	// õ
127 	{'-', '-', 246},	// ö
128 	{'1', '4', 247},	// ÷
129 	{'1', '2', 248},	// ø
130 	{'a', '_', 249},	// ù
131 	{'o', '_', 250},	// ú
132 	{'<', '<', 251},	// û
133 	{'x', 'x', 252},	// ü
134 	{'>', '>', 253},	// ý
135 	{'+', '-', 254},	// þ
136 	{'n', 'u', 255},	// x XX
137 	{NUL, NUL, NUL}
138 	};
139 
140 #else	// !HPUX_DIGRAPHS
141 
142 # ifdef EBCDIC
143 
144 	/*
145 	 * EBCDIC - ISO digraphs
146 	 * TODO: EBCDIC Table is Code-Page 1047
147 	 */
148        {{'a', '^',    66},	// â
149 	{'a', '"',    67},	// ä
150 	{'a', '`',    68},	// à
151 	{'a', '\'',   69},	// á
152 	{'a', '~',    70},	// ã
153 	{'a', '@',    71},	// å
154 	{'a', 'a',    71},	// å
155 	{'c', ',',    72},	// ç
156 	{'n', '~',    73},	// ñ
157 	{'c', '|',    74},	// ¢
158 	{'e', '\'',   81},	// é
159 	{'e', '^',    82},	// ê
160 	{'e', '"',    83},	// ë
161 	{'e', '`',    84},	// è
162 	{'i', '\'',   85},	// í
163 	{'i', '^',    86},	// î
164 	{'i', '"',    87},	// ï
165 	{'i', '`',    88},	// ì
166 	{'s', 's',    89},	// ß
167 	{'A', '^',    98},	// Â
168 	{'A', '"',    99},	// Ä
169 	{'A', '`',   100},	// À
170 	{'A', '\'',  101},	// Á
171 	{'A', '~',   102},	// Ã
172 	{'A', '@',   103},	// Å
173 	{'A', 'A',   103},	// Å
174 	{'C', ',',   104},	// Ç
175 	{'N', '~',   105},	// Ñ
176 	{'|', '|',   106},	// ¦
177 	{'o', '/',   112},	// ø
178 	{'E', '\'',  113},	// É
179 	{'E', '^',   114},	// Ê
180 	{'E', '"',   115},	// Ë
181 	{'E', '`',   116},	// È
182 	{'I', '\'',  117},	// Í
183 	{'I', '^',   118},	// Î
184 	{'I', '"',   119},	// Ï
185 	{'I', '`',   120},	// Ì
186 	{'O', '/',   128},	// 0/ XX
187 	{'<', '<',   138},	// «
188 	{'>', '>',   139},	// »
189 	{'d', '-',   140},	// ð
190 	{'y', '\'',  141},	// ý
191 	{'i', 'p',   142},	// þ
192 	{'+', '-',   143},	// ±
193 	{'~', 'o',   144},	// °
194 	{'a', '-',   154},	// ª
195 	{'o', '-',   155},	// º
196 	{'a', 'e',   156},	// æ
197 	{',', ',',   157},	// , XX
198 	{'A', 'E',   158},	// Æ
199 	{'o', 'x',   159},	// ¤ - currency symbol in ISO 8859-1
200 	{'e', '=',   159},	// ¤ - euro symbol in ISO 8859-15
201 	{'E', 'u',   159},	// ¤ - euro symbol in ISO 8859-15
202 	{'j', 'u',   160},	// µ
203 	{'y', '"',   167},	// x XX
204 	{'~', '!',   170},	// ¡
205 	{'~', '?',   171},	// ¿
206 	{'D', '-',   172},	// Ð
207 	{'I', 'p',   174},	// Þ
208 	{'r', 'O',   175},	// ®
209 	{'-', ',',   176},	// ¬
210 	{'$', '$',   177},	// £
211 	{'Y', '-',   178},	// ¥
212 	{'~', '.',   179},	// ·
213 	{'c', 'O',   180},	// ©
214 	{'p', 'a',   181},	// §
215 	{'p', 'p',   182},	// ¶
216 	{'1', '4',   183},	// ¼
217 	{'1', '2',   184},	// ½
218 	{'3', '4',   185},	// ¾
219 	{'Y', '\'',  186},	// Ý
220 	{'"', '"',   187},	// ¨
221 	{'-', '=',   188},	// ¯
222 	{'\'', '\'', 190},	// ´
223 	{'O', 'E',   191},	// × - OE in ISO 8859-15
224 	{'/', '\\',  191},	// × - multiplication symbol in ISO 8859-1
225 	{'-', '-',   202},	// ­
226 	{'o', '^',   203},	// ô
227 	{'o', '"',   204},	// ö
228 	{'o', '`',   205},	// ò
229 	{'o', '\'',  206},	// ó
230 	{'o', '~',   207},	// õ
231 	{'1', '1',   218},	// ¹
232 	{'u', '^',   219},	// û
233 	{'u', '"',   220},	// ü
234 	{'u', '`',   221},	// ù
235 	{'u', '\'',  222},	// ú
236 	{':', '-',   225},	// ÷ - division symbol in ISO 8859-1
237 	{'o', 'e',   225},	// ÷ - oe in ISO 8859-15
238 	{'2', '2',   234},	// ²
239 	{'O', '^',   235},	// Ô
240 	{'O', '"',   236},	// Ö
241 	{'O', '`',   237},	// Ò
242 	{'O', '\'',  238},	// Ó
243 	{'O', '~',   239},	// Õ
244 	{'3', '3',   250},	// ³
245 	{'U', '^',   251},	// Û
246 	{'U', '"',   252},	// Ü
247 	{'U', '`',   253},	// Ù
248 	{'U', '\'',  254},	// Ú
249 	{NUL, NUL, NUL}
250 	};
251 
252 # else // EBCDIC
253 #  ifdef OLD_DIGRAPHS
254 
255 	/*
256 	 * digraphs compatible with Vim 5.x
257 	 */
258        {{'~', '!', 161},	// ¡
259 	{'c', '|', 162},	// ¢
260 	{'$', '$', 163},	// £
261 	{'o', 'x', 164},	// ¤ - currency symbol in ISO 8859-1
262 	{'e', '=', 164},	// ¤ - euro symbol in ISO 8859-15
263 	{'Y', '-', 165},	// ¥
264 	{'|', '|', 166},	// ¦
265 	{'p', 'a', 167},	// §
266 	{'"', '"', 168},	// ¨
267 	{'c', 'O', 169},	// ©
268 	{'a', '-', 170},	// ª
269 	{'<', '<', 171},	// «
270 	{'-', ',', 172},	// ¬
271 	{'-', '-', 173},	// ­
272 	{'r', 'O', 174},	// ®
273 	{'-', '=', 175},	// ¯
274 	{'~', 'o', 176},	// °
275 	{'+', '-', 177},	// ±
276 	{'2', '2', 178},	// ²
277 	{'3', '3', 179},	// ³
278 	{'\'', '\'', 180},	// ´
279 	{'j', 'u', 181},	// µ
280 	{'p', 'p', 182},	// ¶
281 	{'~', '.', 183},	// ·
282 	{',', ',', 184},	// ¸
283 	{'1', '1', 185},	// ¹
284 	{'o', '-', 186},	// º
285 	{'>', '>', 187},	// »
286 	{'1', '4', 188},	// ¼
287 	{'1', '2', 189},	// ½
288 	{'3', '4', 190},	// ¾
289 	{'~', '?', 191},	// ¿
290 	{'A', '`', 192},	// À
291 	{'A', '\'', 193},	// Á
292 	{'A', '^', 194},	// Â
293 	{'A', '~', 195},	// Ã
294 	{'A', '"', 196},	// Ä
295 	{'A', '@', 197},	// Å
296 	{'A', 'A', 197},	// Å
297 	{'A', 'E', 198},	// Æ
298 	{'C', ',', 199},	// Ç
299 	{'E', '`', 200},	// È
300 	{'E', '\'', 201},	// É
301 	{'E', '^', 202},	// Ê
302 	{'E', '"', 203},	// Ë
303 	{'I', '`', 204},	// Ì
304 	{'I', '\'', 205},	// Í
305 	{'I', '^', 206},	// Î
306 	{'I', '"', 207},	// Ï
307 	{'D', '-', 208},	// Ð
308 	{'N', '~', 209},	// Ñ
309 	{'O', '`', 210},	// Ò
310 	{'O', '\'', 211},	// Ó
311 	{'O', '^', 212},	// Ô
312 	{'O', '~', 213},	// Õ
313 	{'O', '"', 214},	// Ö
314 	{'/', '\\', 215},	// × - multiplication symbol in ISO 8859-1
315 	{'O', 'E', 215},	// × - OE in ISO 8859-15
316 	{'O', '/', 216},	// Ø
317 	{'U', '`', 217},	// Ù
318 	{'U', '\'', 218},	// Ú
319 	{'U', '^', 219},	// Û
320 	{'U', '"', 220},	// Ü
321 	{'Y', '\'', 221},	// Ý
322 	{'I', 'p', 222},	// Þ
323 	{'s', 's', 223},	// ß
324 	{'a', '`', 224},	// à
325 	{'a', '\'', 225},	// á
326 	{'a', '^', 226},	// â
327 	{'a', '~', 227},	// ã
328 	{'a', '"', 228},	// ä
329 	{'a', '@', 229},	// å
330 	{'a', 'a', 229},	// å
331 	{'a', 'e', 230},	// æ
332 	{'c', ',', 231},	// ç
333 	{'e', '`', 232},	// è
334 	{'e', '\'', 233},	// é
335 	{'e', '^', 234},	// ê
336 	{'e', '"', 235},	// ë
337 	{'i', '`', 236},	// ì
338 	{'i', '\'', 237},	// í
339 	{'i', '^', 238},	// î
340 	{'i', '"', 239},	// ï
341 	{'d', '-', 240},	// ð
342 	{'n', '~', 241},	// ñ
343 	{'o', '`', 242},	// ò
344 	{'o', '\'', 243},	// ó
345 	{'o', '^', 244},	// ô
346 	{'o', '~', 245},	// õ
347 	{'o', '"', 246},	// ö
348 	{':', '-', 247},	// ÷ - division symbol in ISO 8859-1
349 	{'o', 'e', 247},	// ÷ - oe in ISO 8859-15
350 	{'o', '/', 248},	// ø
351 	{'u', '`', 249},	// ù
352 	{'u', '\'', 250},	// ú
353 	{'u', '^', 251},	// û
354 	{'u', '"', 252},	// ü
355 	{'y', '\'', 253},	// ý
356 	{'i', 'p', 254},	// þ
357 	{'y', '"', 255},	// x XX
358 	{NUL, NUL, NUL}
359 	};
360 #  else // OLD_DIGRAPHS
361 
362 	/*
363 	 * digraphs for Unicode from RFC1345
364 	 * (also work for ISO-8859-1 aka latin1)
365 	 */
366        {
367 	{'N', 'U', 0x0a},	// LF for NUL
368 	{'S', 'H', 0x01},
369 	{'S', 'X', 0x02},
370 	{'E', 'X', 0x03},
371 	{'E', 'T', 0x04},
372 	{'E', 'Q', 0x05},
373 	{'A', 'K', 0x06},
374 	{'B', 'L', 0x07},
375 	{'B', 'S', 0x08},
376 	{'H', 'T', 0x09},
377 	{'L', 'F', 0x0a},
378 	{'V', 'T', 0x0b},
379 	{'F', 'F', 0x0c},
380 	{'C', 'R', 0x0d},
381 	{'S', 'O', 0x0e},
382 	{'S', 'I', 0x0f},
383 	{'D', 'L', 0x10},
384 	{'D', '1', 0x11},
385 	{'D', '2', 0x12},
386 	{'D', '3', 0x13},
387 	{'D', '4', 0x14},
388 	{'N', 'K', 0x15},
389 	{'S', 'Y', 0x16},
390 	{'E', 'B', 0x17},
391 	{'C', 'N', 0x18},
392 	{'E', 'M', 0x19},
393 	{'S', 'B', 0x1a},
394 	{'E', 'C', 0x1b},
395 	{'F', 'S', 0x1c},
396 	{'G', 'S', 0x1d},
397 	{'R', 'S', 0x1e},
398 	{'U', 'S', 0x1f},
399 	{'S', 'P', 0x20},
400 	{'N', 'b', 0x23},
401 	{'D', 'O', 0x24},
402 	{'A', 't', 0x40},
403 	{'<', '(', 0x5b},
404 	{'/', '/', 0x5c},
405 	{')', '>', 0x5d},
406 	{'\'', '>', 0x5e},
407 	{'\'', '!', 0x60},
408 	{'(', '!', 0x7b},
409 	{'!', '!', 0x7c},
410 	{'!', ')', 0x7d},
411 	{'\'', '?', 0x7e},
412 	{'D', 'T', 0x7f},
413 	{'P', 'A', 0x80},
414 	{'H', 'O', 0x81},
415 	{'B', 'H', 0x82},
416 	{'N', 'H', 0x83},
417 	{'I', 'N', 0x84},
418 	{'N', 'L', 0x85},
419 	{'S', 'A', 0x86},
420 	{'E', 'S', 0x87},
421 	{'H', 'S', 0x88},
422 	{'H', 'J', 0x89},
423 	{'V', 'S', 0x8a},
424 	{'P', 'D', 0x8b},
425 	{'P', 'U', 0x8c},
426 	{'R', 'I', 0x8d},
427 	{'S', '2', 0x8e},
428 	{'S', '3', 0x8f},
429 	{'D', 'C', 0x90},
430 	{'P', '1', 0x91},
431 	{'P', '2', 0x92},
432 	{'T', 'S', 0x93},
433 	{'C', 'C', 0x94},
434 	{'M', 'W', 0x95},
435 	{'S', 'G', 0x96},
436 	{'E', 'G', 0x97},
437 	{'S', 'S', 0x98},
438 	{'G', 'C', 0x99},
439 	{'S', 'C', 0x9a},
440 	{'C', 'I', 0x9b},
441 	{'S', 'T', 0x9c},
442 	{'O', 'C', 0x9d},
443 	{'P', 'M', 0x9e},
444 	{'A', 'C', 0x9f},
445 	{'N', 'S', 0xa0},
446 #   define DG_START_LATIN 0xa1
447 	{'!', 'I', 0xa1},
448 	{'~', '!', 0xa1},	// ¡ Vim 5.x compatible
449 	{'C', 't', 0xa2},
450 	{'c', '|', 0xa2},	// ¢ Vim 5.x compatible
451 	{'P', 'd', 0xa3},
452 	{'$', '$', 0xa3},	// £ Vim 5.x compatible
453 	{'C', 'u', 0xa4},
454 	{'o', 'x', 0xa4},	// ¤ Vim 5.x compatible
455 	{'Y', 'e', 0xa5},
456 	{'Y', '-', 0xa5},	// ¥ Vim 5.x compatible
457 	{'B', 'B', 0xa6},
458 	{'|', '|', 0xa6},	// ¦ Vim 5.x compatible
459 	{'S', 'E', 0xa7},
460 	{'\'', ':', 0xa8},
461 	{'C', 'o', 0xa9},
462 	{'c', 'O', 0xa9},	// © Vim 5.x compatible
463 	{'-', 'a', 0xaa},
464 	{'<', '<', 0xab},
465 	{'N', 'O', 0xac},
466 	{'-', ',', 0xac},	// ¬ Vim 5.x compatible
467 	{'-', '-', 0xad},
468 	{'R', 'g', 0xae},
469 	{'\'', 'm', 0xaf},
470 	{'-', '=', 0xaf},	// ¯ Vim 5.x compatible
471 	{'D', 'G', 0xb0},
472 	{'~', 'o', 0xb0},	// ° Vim 5.x compatible
473 	{'+', '-', 0xb1},
474 	{'2', 'S', 0xb2},
475 	{'2', '2', 0xb2},	// ² Vim 5.x compatible
476 	{'3', 'S', 0xb3},
477 	{'3', '3', 0xb3},	// ³ Vim 5.x compatible
478 	{'\'', '\'', 0xb4},
479 	{'M', 'y', 0xb5},
480 	{'P', 'I', 0xb6},
481 	{'p', 'p', 0xb6},	// ¶ Vim 5.x compatible
482 	{'.', 'M', 0xb7},
483 	{'~', '.', 0xb7},	// · Vim 5.x compatible
484 	{'\'', ',', 0xb8},
485 	{'1', 'S', 0xb9},
486 	{'1', '1', 0xb9},	// ¹ Vim 5.x compatible
487 	{'-', 'o', 0xba},
488 	{'>', '>', 0xbb},
489 	{'1', '4', 0xbc},
490 	{'1', '2', 0xbd},
491 	{'3', '4', 0xbe},
492 	{'?', 'I', 0xbf},
493 	{'~', '?', 0xbf},	// ¿ Vim 5.x compatible
494 	{'A', '!', 0xc0},
495 	{'A', '`', 0xc0},	// À Vim 5.x compatible
496 	{'A', '\'', 0xc1},
497 	{'A', '>', 0xc2},
498 	{'A', '^', 0xc2},	// Â Vim 5.x compatible
499 	{'A', '?', 0xc3},
500 	{'A', '~', 0xc3},	// Ã Vim 5.x compatible
501 	{'A', ':', 0xc4},
502 	{'A', '"', 0xc4},	// Ä Vim 5.x compatible
503 	{'A', 'A', 0xc5},
504 	{'A', '@', 0xc5},	// Å Vim 5.x compatible
505 	{'A', 'E', 0xc6},
506 	{'C', ',', 0xc7},
507 	{'E', '!', 0xc8},
508 	{'E', '`', 0xc8},	// È Vim 5.x compatible
509 	{'E', '\'', 0xc9},
510 	{'E', '>', 0xca},
511 	{'E', '^', 0xca},	// Ê Vim 5.x compatible
512 	{'E', ':', 0xcb},
513 	{'E', '"', 0xcb},	// Ë Vim 5.x compatible
514 	{'I', '!', 0xcc},
515 	{'I', '`', 0xcc},	// Ì Vim 5.x compatible
516 	{'I', '\'', 0xcd},
517 	{'I', '>', 0xce},
518 	{'I', '^', 0xce},	// Î Vim 5.x compatible
519 	{'I', ':', 0xcf},
520 	{'I', '"', 0xcf},	// Ï Vim 5.x compatible
521 	{'D', '-', 0xd0},
522 	{'N', '?', 0xd1},
523 	{'N', '~', 0xd1},	// Ñ Vim 5.x compatible
524 	{'O', '!', 0xd2},
525 	{'O', '`', 0xd2},	// Ò Vim 5.x compatible
526 	{'O', '\'', 0xd3},
527 	{'O', '>', 0xd4},
528 	{'O', '^', 0xd4},	// Ô Vim 5.x compatible
529 	{'O', '?', 0xd5},
530 	{'O', '~', 0xd5},	// Õ Vim 5.x compatible
531 	{'O', ':', 0xd6},
532 	{'*', 'X', 0xd7},
533 	{'/', '\\', 0xd7},	// × Vim 5.x compatible
534 	{'O', '/', 0xd8},
535 	{'U', '!', 0xd9},
536 	{'U', '`', 0xd9},	// Ù Vim 5.x compatible
537 	{'U', '\'', 0xda},
538 	{'U', '>', 0xdb},
539 	{'U', '^', 0xdb},	// Û Vim 5.x compatible
540 	{'U', ':', 0xdc},
541 	{'Y', '\'', 0xdd},
542 	{'T', 'H', 0xde},
543 	{'I', 'p', 0xde},	// Þ Vim 5.x compatible
544 	{'s', 's', 0xdf},
545 	{'a', '!', 0xe0},
546 	{'a', '`', 0xe0},	// à Vim 5.x compatible
547 	{'a', '\'', 0xe1},
548 	{'a', '>', 0xe2},
549 	{'a', '^', 0xe2},	// â Vim 5.x compatible
550 	{'a', '?', 0xe3},
551 	{'a', '~', 0xe3},	// ã Vim 5.x compatible
552 	{'a', ':', 0xe4},
553 	{'a', '"', 0xe4},	// ä Vim 5.x compatible
554 	{'a', 'a', 0xe5},
555 	{'a', '@', 0xe5},	// å Vim 5.x compatible
556 	{'a', 'e', 0xe6},
557 	{'c', ',', 0xe7},
558 	{'e', '!', 0xe8},
559 	{'e', '`', 0xe8},	// è Vim 5.x compatible
560 	{'e', '\'', 0xe9},
561 	{'e', '>', 0xea},
562 	{'e', '^', 0xea},	// ê Vim 5.x compatible
563 	{'e', ':', 0xeb},
564 	{'e', '"', 0xeb},	// ë Vim 5.x compatible
565 	{'i', '!', 0xec},
566 	{'i', '`', 0xec},	// ì Vim 5.x compatible
567 	{'i', '\'', 0xed},
568 	{'i', '>', 0xee},
569 	{'i', '^', 0xee},	// î Vim 5.x compatible
570 	{'i', ':', 0xef},
571 	{'d', '-', 0xf0},
572 	{'n', '?', 0xf1},
573 	{'n', '~', 0xf1},	// ñ Vim 5.x compatible
574 	{'o', '!', 0xf2},
575 	{'o', '`', 0xf2},	// ò Vim 5.x compatible
576 	{'o', '\'', 0xf3},
577 	{'o', '>', 0xf4},
578 	{'o', '^', 0xf4},	// ô Vim 5.x compatible
579 	{'o', '?', 0xf5},
580 	{'o', '~', 0xf5},	// õ Vim 5.x compatible
581 	{'o', ':', 0xf6},
582 	{'-', ':', 0xf7},
583 	{'o', '/', 0xf8},
584 	{'u', '!', 0xf9},
585 	{'u', '`', 0xf9},	// ù Vim 5.x compatible
586 	{'u', '\'', 0xfa},
587 	{'u', '>', 0xfb},
588 	{'u', '^', 0xfb},	// û Vim 5.x compatible
589 	{'u', ':', 0xfc},
590 	{'y', '\'', 0xfd},
591 	{'t', 'h', 0xfe},
592 	{'y', ':', 0xff},
593 	{'y', '"', 0xff},	// x XX  Vim 5.x compatible
594 
595 #   define USE_UNICODE_DIGRAPHS
596 
597 	{'A', '-', 0x0100},
598 	{'a', '-', 0x0101},
599 	{'A', '(', 0x0102},
600 	{'a', '(', 0x0103},
601 	{'A', ';', 0x0104},
602 	{'a', ';', 0x0105},
603 	{'C', '\'', 0x0106},
604 	{'c', '\'', 0x0107},
605 	{'C', '>', 0x0108},
606 	{'c', '>', 0x0109},
607 	{'C', '.', 0x010a},
608 	{'c', '.', 0x010b},
609 	{'C', '<', 0x010c},
610 	{'c', '<', 0x010d},
611 	{'D', '<', 0x010e},
612 	{'d', '<', 0x010f},
613 	{'D', '/', 0x0110},
614 	{'d', '/', 0x0111},
615 	{'E', '-', 0x0112},
616 	{'e', '-', 0x0113},
617 	{'E', '(', 0x0114},
618 	{'e', '(', 0x0115},
619 	{'E', '.', 0x0116},
620 	{'e', '.', 0x0117},
621 	{'E', ';', 0x0118},
622 	{'e', ';', 0x0119},
623 	{'E', '<', 0x011a},
624 	{'e', '<', 0x011b},
625 	{'G', '>', 0x011c},
626 	{'g', '>', 0x011d},
627 	{'G', '(', 0x011e},
628 	{'g', '(', 0x011f},
629 	{'G', '.', 0x0120},
630 	{'g', '.', 0x0121},
631 	{'G', ',', 0x0122},
632 	{'g', ',', 0x0123},
633 	{'H', '>', 0x0124},
634 	{'h', '>', 0x0125},
635 	{'H', '/', 0x0126},
636 	{'h', '/', 0x0127},
637 	{'I', '?', 0x0128},
638 	{'i', '?', 0x0129},
639 	{'I', '-', 0x012a},
640 	{'i', '-', 0x012b},
641 	{'I', '(', 0x012c},
642 	{'i', '(', 0x012d},
643 	{'I', ';', 0x012e},
644 	{'i', ';', 0x012f},
645 	{'I', '.', 0x0130},
646 	{'i', '.', 0x0131},
647 	{'I', 'J', 0x0132},
648 	{'i', 'j', 0x0133},
649 	{'J', '>', 0x0134},
650 	{'j', '>', 0x0135},
651 	{'K', ',', 0x0136},
652 	{'k', ',', 0x0137},
653 	{'k', 'k', 0x0138},
654 	{'L', '\'', 0x0139},
655 	{'l', '\'', 0x013a},
656 	{'L', ',', 0x013b},
657 	{'l', ',', 0x013c},
658 	{'L', '<', 0x013d},
659 	{'l', '<', 0x013e},
660 	{'L', '.', 0x013f},
661 	{'l', '.', 0x0140},
662 	{'L', '/', 0x0141},
663 	{'l', '/', 0x0142},
664 	{'N', '\'', 0x0143},
665 	{'n', '\'', 0x0144},
666 	{'N', ',', 0x0145},
667 	{'n', ',', 0x0146},
668 	{'N', '<', 0x0147},
669 	{'n', '<', 0x0148},
670 	{'\'', 'n', 0x0149},
671 	{'N', 'G', 0x014a},
672 	{'n', 'g', 0x014b},
673 	{'O', '-', 0x014c},
674 	{'o', '-', 0x014d},
675 	{'O', '(', 0x014e},
676 	{'o', '(', 0x014f},
677 	{'O', '"', 0x0150},
678 	{'o', '"', 0x0151},
679 	{'O', 'E', 0x0152},
680 	{'o', 'e', 0x0153},
681 	{'R', '\'', 0x0154},
682 	{'r', '\'', 0x0155},
683 	{'R', ',', 0x0156},
684 	{'r', ',', 0x0157},
685 	{'R', '<', 0x0158},
686 	{'r', '<', 0x0159},
687 	{'S', '\'', 0x015a},
688 	{'s', '\'', 0x015b},
689 	{'S', '>', 0x015c},
690 	{'s', '>', 0x015d},
691 	{'S', ',', 0x015e},
692 	{'s', ',', 0x015f},
693 	{'S', '<', 0x0160},
694 	{'s', '<', 0x0161},
695 	{'T', ',', 0x0162},
696 	{'t', ',', 0x0163},
697 	{'T', '<', 0x0164},
698 	{'t', '<', 0x0165},
699 	{'T', '/', 0x0166},
700 	{'t', '/', 0x0167},
701 	{'U', '?', 0x0168},
702 	{'u', '?', 0x0169},
703 	{'U', '-', 0x016a},
704 	{'u', '-', 0x016b},
705 	{'U', '(', 0x016c},
706 	{'u', '(', 0x016d},
707 	{'U', '0', 0x016e},
708 	{'u', '0', 0x016f},
709 	{'U', '"', 0x0170},
710 	{'u', '"', 0x0171},
711 	{'U', ';', 0x0172},
712 	{'u', ';', 0x0173},
713 	{'W', '>', 0x0174},
714 	{'w', '>', 0x0175},
715 	{'Y', '>', 0x0176},
716 	{'y', '>', 0x0177},
717 	{'Y', ':', 0x0178},
718 	{'Z', '\'', 0x0179},
719 	{'z', '\'', 0x017a},
720 	{'Z', '.', 0x017b},
721 	{'z', '.', 0x017c},
722 	{'Z', '<', 0x017d},
723 	{'z', '<', 0x017e},
724 	{'O', '9', 0x01a0},
725 	{'o', '9', 0x01a1},
726 	{'O', 'I', 0x01a2},
727 	{'o', 'i', 0x01a3},
728 	{'y', 'r', 0x01a6},
729 	{'U', '9', 0x01af},
730 	{'u', '9', 0x01b0},
731 	{'Z', '/', 0x01b5},
732 	{'z', '/', 0x01b6},
733 	{'E', 'D', 0x01b7},
734 	{'A', '<', 0x01cd},
735 	{'a', '<', 0x01ce},
736 	{'I', '<', 0x01cf},
737 	{'i', '<', 0x01d0},
738 	{'O', '<', 0x01d1},
739 	{'o', '<', 0x01d2},
740 	{'U', '<', 0x01d3},
741 	{'u', '<', 0x01d4},
742 	{'A', '1', 0x01de},
743 	{'a', '1', 0x01df},
744 	{'A', '7', 0x01e0},
745 	{'a', '7', 0x01e1},
746 	{'A', '3', 0x01e2},
747 	{'a', '3', 0x01e3},
748 	{'G', '/', 0x01e4},
749 	{'g', '/', 0x01e5},
750 	{'G', '<', 0x01e6},
751 	{'g', '<', 0x01e7},
752 	{'K', '<', 0x01e8},
753 	{'k', '<', 0x01e9},
754 	{'O', ';', 0x01ea},
755 	{'o', ';', 0x01eb},
756 	{'O', '1', 0x01ec},
757 	{'o', '1', 0x01ed},
758 	{'E', 'Z', 0x01ee},
759 	{'e', 'z', 0x01ef},
760 	{'j', '<', 0x01f0},
761 	{'G', '\'', 0x01f4},
762 	{'g', '\'', 0x01f5},
763 	{';', 'S', 0x02bf},
764 	{'\'', '<', 0x02c7},
765 	{'\'', '(', 0x02d8},
766 	{'\'', '.', 0x02d9},
767 	{'\'', '0', 0x02da},
768 	{'\'', ';', 0x02db},
769 	{'\'', '"', 0x02dd},
770 #   define DG_START_GREEK 0x0386
771 	{'A', '%', 0x0386},
772 	{'E', '%', 0x0388},
773 	{'Y', '%', 0x0389},
774 	{'I', '%', 0x038a},
775 	{'O', '%', 0x038c},
776 	{'U', '%', 0x038e},
777 	{'W', '%', 0x038f},
778 	{'i', '3', 0x0390},
779 	{'A', '*', 0x0391},
780 	{'B', '*', 0x0392},
781 	{'G', '*', 0x0393},
782 	{'D', '*', 0x0394},
783 	{'E', '*', 0x0395},
784 	{'Z', '*', 0x0396},
785 	{'Y', '*', 0x0397},
786 	{'H', '*', 0x0398},
787 	{'I', '*', 0x0399},
788 	{'K', '*', 0x039a},
789 	{'L', '*', 0x039b},
790 	{'M', '*', 0x039c},
791 	{'N', '*', 0x039d},
792 	{'C', '*', 0x039e},
793 	{'O', '*', 0x039f},
794 	{'P', '*', 0x03a0},
795 	{'R', '*', 0x03a1},
796 	{'S', '*', 0x03a3},
797 	{'T', '*', 0x03a4},
798 	{'U', '*', 0x03a5},
799 	{'F', '*', 0x03a6},
800 	{'X', '*', 0x03a7},
801 	{'Q', '*', 0x03a8},
802 	{'W', '*', 0x03a9},
803 	{'J', '*', 0x03aa},
804 	{'V', '*', 0x03ab},
805 	{'a', '%', 0x03ac},
806 	{'e', '%', 0x03ad},
807 	{'y', '%', 0x03ae},
808 	{'i', '%', 0x03af},
809 	{'u', '3', 0x03b0},
810 	{'a', '*', 0x03b1},
811 	{'b', '*', 0x03b2},
812 	{'g', '*', 0x03b3},
813 	{'d', '*', 0x03b4},
814 	{'e', '*', 0x03b5},
815 	{'z', '*', 0x03b6},
816 	{'y', '*', 0x03b7},
817 	{'h', '*', 0x03b8},
818 	{'i', '*', 0x03b9},
819 	{'k', '*', 0x03ba},
820 	{'l', '*', 0x03bb},
821 	{'m', '*', 0x03bc},
822 	{'n', '*', 0x03bd},
823 	{'c', '*', 0x03be},
824 	{'o', '*', 0x03bf},
825 	{'p', '*', 0x03c0},
826 	{'r', '*', 0x03c1},
827 	{'*', 's', 0x03c2},
828 	{'s', '*', 0x03c3},
829 	{'t', '*', 0x03c4},
830 	{'u', '*', 0x03c5},
831 	{'f', '*', 0x03c6},
832 	{'x', '*', 0x03c7},
833 	{'q', '*', 0x03c8},
834 	{'w', '*', 0x03c9},
835 	{'j', '*', 0x03ca},
836 	{'v', '*', 0x03cb},
837 	{'o', '%', 0x03cc},
838 	{'u', '%', 0x03cd},
839 	{'w', '%', 0x03ce},
840 	{'\'', 'G', 0x03d8},
841 	{',', 'G', 0x03d9},
842 	{'T', '3', 0x03da},
843 	{'t', '3', 0x03db},
844 	{'M', '3', 0x03dc},
845 	{'m', '3', 0x03dd},
846 	{'K', '3', 0x03de},
847 	{'k', '3', 0x03df},
848 	{'P', '3', 0x03e0},
849 	{'p', '3', 0x03e1},
850 	{'\'', '%', 0x03f4},
851 	{'j', '3', 0x03f5},
852 #   define DG_START_CYRILLIC 0x0401
853 	{'I', 'O', 0x0401},
854 	{'D', '%', 0x0402},
855 	{'G', '%', 0x0403},
856 	{'I', 'E', 0x0404},
857 	{'D', 'S', 0x0405},
858 	{'I', 'I', 0x0406},
859 	{'Y', 'I', 0x0407},
860 	{'J', '%', 0x0408},
861 	{'L', 'J', 0x0409},
862 	{'N', 'J', 0x040a},
863 	{'T', 's', 0x040b},
864 	{'K', 'J', 0x040c},
865 	{'V', '%', 0x040e},
866 	{'D', 'Z', 0x040f},
867 	{'A', '=', 0x0410},
868 	{'B', '=', 0x0411},
869 	{'V', '=', 0x0412},
870 	{'G', '=', 0x0413},
871 	{'D', '=', 0x0414},
872 	{'E', '=', 0x0415},
873 	{'Z', '%', 0x0416},
874 	{'Z', '=', 0x0417},
875 	{'I', '=', 0x0418},
876 	{'J', '=', 0x0419},
877 	{'K', '=', 0x041a},
878 	{'L', '=', 0x041b},
879 	{'M', '=', 0x041c},
880 	{'N', '=', 0x041d},
881 	{'O', '=', 0x041e},
882 	{'P', '=', 0x041f},
883 	{'R', '=', 0x0420},
884 	{'S', '=', 0x0421},
885 	{'T', '=', 0x0422},
886 	{'U', '=', 0x0423},
887 	{'F', '=', 0x0424},
888 	{'H', '=', 0x0425},
889 	{'C', '=', 0x0426},
890 	{'C', '%', 0x0427},
891 	{'S', '%', 0x0428},
892 	{'S', 'c', 0x0429},
893 	{'=', '"', 0x042a},
894 	{'Y', '=', 0x042b},
895 	{'%', '"', 0x042c},
896 	{'J', 'E', 0x042d},
897 	{'J', 'U', 0x042e},
898 	{'J', 'A', 0x042f},
899 	{'a', '=', 0x0430},
900 	{'b', '=', 0x0431},
901 	{'v', '=', 0x0432},
902 	{'g', '=', 0x0433},
903 	{'d', '=', 0x0434},
904 	{'e', '=', 0x0435},
905 	{'z', '%', 0x0436},
906 	{'z', '=', 0x0437},
907 	{'i', '=', 0x0438},
908 	{'j', '=', 0x0439},
909 	{'k', '=', 0x043a},
910 	{'l', '=', 0x043b},
911 	{'m', '=', 0x043c},
912 	{'n', '=', 0x043d},
913 	{'o', '=', 0x043e},
914 	{'p', '=', 0x043f},
915 	{'r', '=', 0x0440},
916 	{'s', '=', 0x0441},
917 	{'t', '=', 0x0442},
918 	{'u', '=', 0x0443},
919 	{'f', '=', 0x0444},
920 	{'h', '=', 0x0445},
921 	{'c', '=', 0x0446},
922 	{'c', '%', 0x0447},
923 	{'s', '%', 0x0448},
924 	{'s', 'c', 0x0449},
925 	{'=', '\'', 0x044a},
926 	{'y', '=', 0x044b},
927 	{'%', '\'', 0x044c},
928 	{'j', 'e', 0x044d},
929 	{'j', 'u', 0x044e},
930 	{'j', 'a', 0x044f},
931 	{'i', 'o', 0x0451},
932 	{'d', '%', 0x0452},
933 	{'g', '%', 0x0453},
934 	{'i', 'e', 0x0454},
935 	{'d', 's', 0x0455},
936 	{'i', 'i', 0x0456},
937 	{'y', 'i', 0x0457},
938 	{'j', '%', 0x0458},
939 	{'l', 'j', 0x0459},
940 	{'n', 'j', 0x045a},
941 	{'t', 's', 0x045b},
942 	{'k', 'j', 0x045c},
943 	{'v', '%', 0x045e},
944 	{'d', 'z', 0x045f},
945 	{'Y', '3', 0x0462},
946 	{'y', '3', 0x0463},
947 	{'O', '3', 0x046a},
948 	{'o', '3', 0x046b},
949 	{'F', '3', 0x0472},
950 	{'f', '3', 0x0473},
951 	{'V', '3', 0x0474},
952 	{'v', '3', 0x0475},
953 	{'C', '3', 0x0480},
954 	{'c', '3', 0x0481},
955 	{'G', '3', 0x0490},
956 	{'g', '3', 0x0491},
957 #   define DG_START_HEBREW 0x05d0
958 	{'A', '+', 0x05d0},
959 	{'B', '+', 0x05d1},
960 	{'G', '+', 0x05d2},
961 	{'D', '+', 0x05d3},
962 	{'H', '+', 0x05d4},
963 	{'W', '+', 0x05d5},
964 	{'Z', '+', 0x05d6},
965 	{'X', '+', 0x05d7},
966 	{'T', 'j', 0x05d8},
967 	{'J', '+', 0x05d9},
968 	{'K', '%', 0x05da},
969 	{'K', '+', 0x05db},
970 	{'L', '+', 0x05dc},
971 	{'M', '%', 0x05dd},
972 	{'M', '+', 0x05de},
973 	{'N', '%', 0x05df},
974 	{'N', '+', 0x05e0},
975 	{'S', '+', 0x05e1},
976 	{'E', '+', 0x05e2},
977 	{'P', '%', 0x05e3},
978 	{'P', '+', 0x05e4},
979 	{'Z', 'j', 0x05e5},
980 	{'Z', 'J', 0x05e6},
981 	{'Q', '+', 0x05e7},
982 	{'R', '+', 0x05e8},
983 	{'S', 'h', 0x05e9},
984 	{'T', '+', 0x05ea},
985 #   define DG_START_ARABIC 0x060c
986 	{',', '+', 0x060c},
987 	{';', '+', 0x061b},
988 	{'?', '+', 0x061f},
989 	{'H', '\'', 0x0621},
990 	{'a', 'M', 0x0622},
991 	{'a', 'H', 0x0623},
992 	{'w', 'H', 0x0624},
993 	{'a', 'h', 0x0625},
994 	{'y', 'H', 0x0626},
995 	{'a', '+', 0x0627},
996 	{'b', '+', 0x0628},
997 	{'t', 'm', 0x0629},
998 	{'t', '+', 0x062a},
999 	{'t', 'k', 0x062b},
1000 	{'g', '+', 0x062c},
1001 	{'h', 'k', 0x062d},
1002 	{'x', '+', 0x062e},
1003 	{'d', '+', 0x062f},
1004 	{'d', 'k', 0x0630},
1005 	{'r', '+', 0x0631},
1006 	{'z', '+', 0x0632},
1007 	{'s', '+', 0x0633},
1008 	{'s', 'n', 0x0634},
1009 	{'c', '+', 0x0635},
1010 	{'d', 'd', 0x0636},
1011 	{'t', 'j', 0x0637},
1012 	{'z', 'H', 0x0638},
1013 	{'e', '+', 0x0639},
1014 	{'i', '+', 0x063a},
1015 	{'+', '+', 0x0640},
1016 	{'f', '+', 0x0641},
1017 	{'q', '+', 0x0642},
1018 	{'k', '+', 0x0643},
1019 	{'l', '+', 0x0644},
1020 	{'m', '+', 0x0645},
1021 	{'n', '+', 0x0646},
1022 	{'h', '+', 0x0647},
1023 	{'w', '+', 0x0648},
1024 	{'j', '+', 0x0649},
1025 	{'y', '+', 0x064a},
1026 	{':', '+', 0x064b},
1027 	{'"', '+', 0x064c},
1028 	{'=', '+', 0x064d},
1029 	{'/', '+', 0x064e},
1030 	{'\'', '+', 0x064f},
1031 	{'1', '+', 0x0650},
1032 	{'3', '+', 0x0651},
1033 	{'0', '+', 0x0652},
1034 	{'a', 'S', 0x0670},
1035 	{'p', '+', 0x067e},
1036 	{'v', '+', 0x06a4},
1037 	{'g', 'f', 0x06af},
1038 	{'0', 'a', 0x06f0},
1039 	{'1', 'a', 0x06f1},
1040 	{'2', 'a', 0x06f2},
1041 	{'3', 'a', 0x06f3},
1042 	{'4', 'a', 0x06f4},
1043 	{'5', 'a', 0x06f5},
1044 	{'6', 'a', 0x06f6},
1045 	{'7', 'a', 0x06f7},
1046 	{'8', 'a', 0x06f8},
1047 	{'9', 'a', 0x06f9},
1048 #   define DG_START_LATIN_EXTENDED 0x1e02
1049 	{'B', '.', 0x1e02},
1050 	{'b', '.', 0x1e03},
1051 	{'B', '_', 0x1e06},
1052 	{'b', '_', 0x1e07},
1053 	{'D', '.', 0x1e0a},
1054 	{'d', '.', 0x1e0b},
1055 	{'D', '_', 0x1e0e},
1056 	{'d', '_', 0x1e0f},
1057 	{'D', ',', 0x1e10},
1058 	{'d', ',', 0x1e11},
1059 	{'F', '.', 0x1e1e},
1060 	{'f', '.', 0x1e1f},
1061 	{'G', '-', 0x1e20},
1062 	{'g', '-', 0x1e21},
1063 	{'H', '.', 0x1e22},
1064 	{'h', '.', 0x1e23},
1065 	{'H', ':', 0x1e26},
1066 	{'h', ':', 0x1e27},
1067 	{'H', ',', 0x1e28},
1068 	{'h', ',', 0x1e29},
1069 	{'K', '\'', 0x1e30},
1070 	{'k', '\'', 0x1e31},
1071 	{'K', '_', 0x1e34},
1072 	{'k', '_', 0x1e35},
1073 	{'L', '_', 0x1e3a},
1074 	{'l', '_', 0x1e3b},
1075 	{'M', '\'', 0x1e3e},
1076 	{'m', '\'', 0x1e3f},
1077 	{'M', '.', 0x1e40},
1078 	{'m', '.', 0x1e41},
1079 	{'N', '.', 0x1e44},
1080 	{'n', '.', 0x1e45},
1081 	{'N', '_', 0x1e48},
1082 	{'n', '_', 0x1e49},
1083 	{'P', '\'', 0x1e54},
1084 	{'p', '\'', 0x1e55},
1085 	{'P', '.', 0x1e56},
1086 	{'p', '.', 0x1e57},
1087 	{'R', '.', 0x1e58},
1088 	{'r', '.', 0x1e59},
1089 	{'R', '_', 0x1e5e},
1090 	{'r', '_', 0x1e5f},
1091 	{'S', '.', 0x1e60},
1092 	{'s', '.', 0x1e61},
1093 	{'T', '.', 0x1e6a},
1094 	{'t', '.', 0x1e6b},
1095 	{'T', '_', 0x1e6e},
1096 	{'t', '_', 0x1e6f},
1097 	{'V', '?', 0x1e7c},
1098 	{'v', '?', 0x1e7d},
1099 	{'W', '!', 0x1e80},
1100 	{'W', '`', 0x1e80}, // extra alternative, easier to remember
1101 	{'w', '!', 0x1e81},
1102 	{'w', '`', 0x1e81}, // extra alternative, easier to remember
1103 	{'W', '\'', 0x1e82},
1104 	{'w', '\'', 0x1e83},
1105 	{'W', ':', 0x1e84},
1106 	{'w', ':', 0x1e85},
1107 	{'W', '.', 0x1e86},
1108 	{'w', '.', 0x1e87},
1109 	{'X', '.', 0x1e8a},
1110 	{'x', '.', 0x1e8b},
1111 	{'X', ':', 0x1e8c},
1112 	{'x', ':', 0x1e8d},
1113 	{'Y', '.', 0x1e8e},
1114 	{'y', '.', 0x1e8f},
1115 	{'Z', '>', 0x1e90},
1116 	{'z', '>', 0x1e91},
1117 	{'Z', '_', 0x1e94},
1118 	{'z', '_', 0x1e95},
1119 	{'h', '_', 0x1e96},
1120 	{'t', ':', 0x1e97},
1121 	{'w', '0', 0x1e98},
1122 	{'y', '0', 0x1e99},
1123 	{'A', '2', 0x1ea2},
1124 	{'a', '2', 0x1ea3},
1125 	{'E', '2', 0x1eba},
1126 	{'e', '2', 0x1ebb},
1127 	{'E', '?', 0x1ebc},
1128 	{'e', '?', 0x1ebd},
1129 	{'I', '2', 0x1ec8},
1130 	{'i', '2', 0x1ec9},
1131 	{'O', '2', 0x1ece},
1132 	{'o', '2', 0x1ecf},
1133 	{'U', '2', 0x1ee6},
1134 	{'u', '2', 0x1ee7},
1135 	{'Y', '!', 0x1ef2},
1136 	{'Y', '`', 0x1ef2}, // extra alternative, easier to remember
1137 	{'y', '!', 0x1ef3},
1138 	{'y', '`', 0x1ef3}, // extra alternative, easier to remember
1139 	{'Y', '2', 0x1ef6},
1140 	{'y', '2', 0x1ef7},
1141 	{'Y', '?', 0x1ef8},
1142 	{'y', '?', 0x1ef9},
1143 #   define DG_START_GREEK_EXTENDED 0x1f00
1144 	{';', '\'', 0x1f00},
1145 	{',', '\'', 0x1f01},
1146 	{';', '!', 0x1f02},
1147 	{',', '!', 0x1f03},
1148 	{'?', ';', 0x1f04},
1149 	{'?', ',', 0x1f05},
1150 	{'!', ':', 0x1f06},
1151 	{'?', ':', 0x1f07},
1152 #   define DG_START_PUNCTUATION 0x2002
1153 	{'1', 'N', 0x2002},
1154 	{'1', 'M', 0x2003},
1155 	{'3', 'M', 0x2004},
1156 	{'4', 'M', 0x2005},
1157 	{'6', 'M', 0x2006},
1158 	{'1', 'T', 0x2009},
1159 	{'1', 'H', 0x200a},
1160 	{'-', '1', 0x2010},
1161 	{'-', 'N', 0x2013},
1162 	{'-', 'M', 0x2014},
1163 	{'-', '3', 0x2015},
1164 	{'!', '2', 0x2016},
1165 	{'=', '2', 0x2017},
1166 	{'\'', '6', 0x2018},
1167 	{'\'', '9', 0x2019},
1168 	{'.', '9', 0x201a},
1169 	{'9', '\'', 0x201b},
1170 	{'"', '6', 0x201c},
1171 	{'"', '9', 0x201d},
1172 	{':', '9', 0x201e},
1173 	{'9', '"', 0x201f},
1174 	{'/', '-', 0x2020},
1175 	{'/', '=', 0x2021},
1176 	{'o', 'o', 0x2022},
1177 	{'.', '.', 0x2025},
1178 	{',', '.', 0x2026},
1179 	{'%', '0', 0x2030},
1180 	{'1', '\'', 0x2032},
1181 	{'2', '\'', 0x2033},
1182 	{'3', '\'', 0x2034},
1183 	{'1', '"', 0x2035},
1184 	{'2', '"', 0x2036},
1185 	{'3', '"', 0x2037},
1186 	{'C', 'a', 0x2038},
1187 	{'<', '1', 0x2039},
1188 	{'>', '1', 0x203a},
1189 	{':', 'X', 0x203b},
1190 	{'\'', '-', 0x203e},
1191 	{'/', 'f', 0x2044},
1192 #   define DG_START_SUB_SUPER 0x2070
1193 	{'0', 'S', 0x2070},
1194 	{'4', 'S', 0x2074},
1195 	{'5', 'S', 0x2075},
1196 	{'6', 'S', 0x2076},
1197 	{'7', 'S', 0x2077},
1198 	{'8', 'S', 0x2078},
1199 	{'9', 'S', 0x2079},
1200 	{'+', 'S', 0x207a},
1201 	{'-', 'S', 0x207b},
1202 	{'=', 'S', 0x207c},
1203 	{'(', 'S', 0x207d},
1204 	{')', 'S', 0x207e},
1205 	{'n', 'S', 0x207f},
1206 	{'0', 's', 0x2080},
1207 	{'1', 's', 0x2081},
1208 	{'2', 's', 0x2082},
1209 	{'3', 's', 0x2083},
1210 	{'4', 's', 0x2084},
1211 	{'5', 's', 0x2085},
1212 	{'6', 's', 0x2086},
1213 	{'7', 's', 0x2087},
1214 	{'8', 's', 0x2088},
1215 	{'9', 's', 0x2089},
1216 	{'+', 's', 0x208a},
1217 	{'-', 's', 0x208b},
1218 	{'=', 's', 0x208c},
1219 	{'(', 's', 0x208d},
1220 	{')', 's', 0x208e},
1221 #   define DG_START_CURRENCY 0x20a4
1222 	{'L', 'i', 0x20a4},
1223 	{'P', 't', 0x20a7},
1224 	{'W', '=', 0x20a9},
1225 	{'=', 'e', 0x20ac}, // euro
1226 	{'E', 'u', 0x20ac}, // euro
1227 	{'=', 'R', 0x20bd}, // rouble
1228 	{'=', 'P', 0x20bd}, // rouble
1229 #   define DG_START_OTHER1 0x2103
1230 	{'o', 'C', 0x2103},
1231 	{'c', 'o', 0x2105},
1232 	{'o', 'F', 0x2109},
1233 	{'N', '0', 0x2116},
1234 	{'P', 'O', 0x2117},
1235 	{'R', 'x', 0x211e},
1236 	{'S', 'M', 0x2120},
1237 	{'T', 'M', 0x2122},
1238 	{'O', 'm', 0x2126},
1239 	{'A', 'O', 0x212b},
1240 	{'1', '3', 0x2153},
1241 	{'2', '3', 0x2154},
1242 	{'1', '5', 0x2155},
1243 	{'2', '5', 0x2156},
1244 	{'3', '5', 0x2157},
1245 	{'4', '5', 0x2158},
1246 	{'1', '6', 0x2159},
1247 	{'5', '6', 0x215a},
1248 	{'1', '8', 0x215b},
1249 	{'3', '8', 0x215c},
1250 	{'5', '8', 0x215d},
1251 	{'7', '8', 0x215e},
1252 #   define DG_START_ROMAN 0x2160
1253 	{'1', 'R', 0x2160},
1254 	{'2', 'R', 0x2161},
1255 	{'3', 'R', 0x2162},
1256 	{'4', 'R', 0x2163},
1257 	{'5', 'R', 0x2164},
1258 	{'6', 'R', 0x2165},
1259 	{'7', 'R', 0x2166},
1260 	{'8', 'R', 0x2167},
1261 	{'9', 'R', 0x2168},
1262 	{'a', 'R', 0x2169},
1263 	{'b', 'R', 0x216a},
1264 	{'c', 'R', 0x216b},
1265 	{'1', 'r', 0x2170},
1266 	{'2', 'r', 0x2171},
1267 	{'3', 'r', 0x2172},
1268 	{'4', 'r', 0x2173},
1269 	{'5', 'r', 0x2174},
1270 	{'6', 'r', 0x2175},
1271 	{'7', 'r', 0x2176},
1272 	{'8', 'r', 0x2177},
1273 	{'9', 'r', 0x2178},
1274 	{'a', 'r', 0x2179},
1275 	{'b', 'r', 0x217a},
1276 	{'c', 'r', 0x217b},
1277 #   define DG_START_ARROWS 0x2190
1278 	{'<', '-', 0x2190},
1279 	{'-', '!', 0x2191},
1280 	{'-', '>', 0x2192},
1281 	{'-', 'v', 0x2193},
1282 	{'<', '>', 0x2194},
1283 	{'U', 'D', 0x2195},
1284 	{'<', '=', 0x21d0},
1285 	{'=', '>', 0x21d2},
1286 	{'=', '=', 0x21d4},
1287 #   define DG_START_MATH 0x2200
1288 	{'F', 'A', 0x2200},
1289 	{'d', 'P', 0x2202},
1290 	{'T', 'E', 0x2203},
1291 	{'/', '0', 0x2205},
1292 	{'D', 'E', 0x2206},
1293 	{'N', 'B', 0x2207},
1294 	{'(', '-', 0x2208},
1295 	{'-', ')', 0x220b},
1296 	{'*', 'P', 0x220f},
1297 	{'+', 'Z', 0x2211},
1298 	{'-', '2', 0x2212},
1299 	{'-', '+', 0x2213},
1300 	{'*', '-', 0x2217},
1301 	{'O', 'b', 0x2218},
1302 	{'S', 'b', 0x2219},
1303 	{'R', 'T', 0x221a},
1304 	{'0', '(', 0x221d},
1305 	{'0', '0', 0x221e},
1306 	{'-', 'L', 0x221f},
1307 	{'-', 'V', 0x2220},
1308 	{'P', 'P', 0x2225},
1309 	{'A', 'N', 0x2227},
1310 	{'O', 'R', 0x2228},
1311 	{'(', 'U', 0x2229},
1312 	{')', 'U', 0x222a},
1313 	{'I', 'n', 0x222b},
1314 	{'D', 'I', 0x222c},
1315 	{'I', 'o', 0x222e},
1316 	{'.', ':', 0x2234},
1317 	{':', '.', 0x2235},
1318 	{':', 'R', 0x2236},
1319 	{':', ':', 0x2237},
1320 	{'?', '1', 0x223c},
1321 	{'C', 'G', 0x223e},
1322 	{'?', '-', 0x2243},
1323 	{'?', '=', 0x2245},
1324 	{'?', '2', 0x2248},
1325 	{'=', '?', 0x224c},
1326 	{'H', 'I', 0x2253},
1327 	{'!', '=', 0x2260},
1328 	{'=', '3', 0x2261},
1329 	{'=', '<', 0x2264},
1330 	{'>', '=', 0x2265},
1331 	{'<', '*', 0x226a},
1332 	{'*', '>', 0x226b},
1333 	{'!', '<', 0x226e},
1334 	{'!', '>', 0x226f},
1335 	{'(', 'C', 0x2282},
1336 	{')', 'C', 0x2283},
1337 	{'(', '_', 0x2286},
1338 	{')', '_', 0x2287},
1339 	{'0', '.', 0x2299},
1340 	{'0', '2', 0x229a},
1341 	{'-', 'T', 0x22a5},
1342 	{'.', 'P', 0x22c5},
1343 	{':', '3', 0x22ee},
1344 	{'.', '3', 0x22ef},
1345 #   define DG_START_TECHNICAL 0x2302
1346 	{'E', 'h', 0x2302},
1347 	{'<', '7', 0x2308},
1348 	{'>', '7', 0x2309},
1349 	{'7', '<', 0x230a},
1350 	{'7', '>', 0x230b},
1351 	{'N', 'I', 0x2310},
1352 	{'(', 'A', 0x2312},
1353 	{'T', 'R', 0x2315},
1354 	{'I', 'u', 0x2320},
1355 	{'I', 'l', 0x2321},
1356 	{'<', '/', 0x2329},
1357 	{'/', '>', 0x232a},
1358 #   define DG_START_OTHER2 0x2423
1359 	{'V', 's', 0x2423},
1360 	{'1', 'h', 0x2440},
1361 	{'3', 'h', 0x2441},
1362 	{'2', 'h', 0x2442},
1363 	{'4', 'h', 0x2443},
1364 	{'1', 'j', 0x2446},
1365 	{'2', 'j', 0x2447},
1366 	{'3', 'j', 0x2448},
1367 	{'4', 'j', 0x2449},
1368 	{'1', '.', 0x2488},
1369 	{'2', '.', 0x2489},
1370 	{'3', '.', 0x248a},
1371 	{'4', '.', 0x248b},
1372 	{'5', '.', 0x248c},
1373 	{'6', '.', 0x248d},
1374 	{'7', '.', 0x248e},
1375 	{'8', '.', 0x248f},
1376 	{'9', '.', 0x2490},
1377 #   define DG_START_DRAWING 0x2500
1378 	{'h', 'h', 0x2500},
1379 	{'H', 'H', 0x2501},
1380 	{'v', 'v', 0x2502},
1381 	{'V', 'V', 0x2503},
1382 	{'3', '-', 0x2504},
1383 	{'3', '_', 0x2505},
1384 	{'3', '!', 0x2506},
1385 	{'3', '/', 0x2507},
1386 	{'4', '-', 0x2508},
1387 	{'4', '_', 0x2509},
1388 	{'4', '!', 0x250a},
1389 	{'4', '/', 0x250b},
1390 	{'d', 'r', 0x250c},
1391 	{'d', 'R', 0x250d},
1392 	{'D', 'r', 0x250e},
1393 	{'D', 'R', 0x250f},
1394 	{'d', 'l', 0x2510},
1395 	{'d', 'L', 0x2511},
1396 	{'D', 'l', 0x2512},
1397 	{'L', 'D', 0x2513},
1398 	{'u', 'r', 0x2514},
1399 	{'u', 'R', 0x2515},
1400 	{'U', 'r', 0x2516},
1401 	{'U', 'R', 0x2517},
1402 	{'u', 'l', 0x2518},
1403 	{'u', 'L', 0x2519},
1404 	{'U', 'l', 0x251a},
1405 	{'U', 'L', 0x251b},
1406 	{'v', 'r', 0x251c},
1407 	{'v', 'R', 0x251d},
1408 	{'V', 'r', 0x2520},
1409 	{'V', 'R', 0x2523},
1410 	{'v', 'l', 0x2524},
1411 	{'v', 'L', 0x2525},
1412 	{'V', 'l', 0x2528},
1413 	{'V', 'L', 0x252b},
1414 	{'d', 'h', 0x252c},
1415 	{'d', 'H', 0x252f},
1416 	{'D', 'h', 0x2530},
1417 	{'D', 'H', 0x2533},
1418 	{'u', 'h', 0x2534},
1419 	{'u', 'H', 0x2537},
1420 	{'U', 'h', 0x2538},
1421 	{'U', 'H', 0x253b},
1422 	{'v', 'h', 0x253c},
1423 	{'v', 'H', 0x253f},
1424 	{'V', 'h', 0x2542},
1425 	{'V', 'H', 0x254b},
1426 	{'F', 'D', 0x2571},
1427 	{'B', 'D', 0x2572},
1428 #   define DG_START_BLOCK 0x2580
1429 	{'T', 'B', 0x2580},
1430 	{'L', 'B', 0x2584},
1431 	{'F', 'B', 0x2588},
1432 	{'l', 'B', 0x258c},
1433 	{'R', 'B', 0x2590},
1434 	{'.', 'S', 0x2591},
1435 	{':', 'S', 0x2592},
1436 	{'?', 'S', 0x2593},
1437 #   define DG_START_SHAPES 0x25a0
1438 	{'f', 'S', 0x25a0},
1439 	{'O', 'S', 0x25a1},
1440 	{'R', 'O', 0x25a2},
1441 	{'R', 'r', 0x25a3},
1442 	{'R', 'F', 0x25a4},
1443 	{'R', 'Y', 0x25a5},
1444 	{'R', 'H', 0x25a6},
1445 	{'R', 'Z', 0x25a7},
1446 	{'R', 'K', 0x25a8},
1447 	{'R', 'X', 0x25a9},
1448 	{'s', 'B', 0x25aa},
1449 	{'S', 'R', 0x25ac},
1450 	{'O', 'r', 0x25ad},
1451 	{'U', 'T', 0x25b2},
1452 	{'u', 'T', 0x25b3},
1453 	{'P', 'R', 0x25b6},
1454 	{'T', 'r', 0x25b7},
1455 	{'D', 't', 0x25bc},
1456 	{'d', 'T', 0x25bd},
1457 	{'P', 'L', 0x25c0},
1458 	{'T', 'l', 0x25c1},
1459 	{'D', 'b', 0x25c6},
1460 	{'D', 'w', 0x25c7},
1461 	{'L', 'Z', 0x25ca},
1462 	{'0', 'm', 0x25cb},
1463 	{'0', 'o', 0x25ce},
1464 	{'0', 'M', 0x25cf},
1465 	{'0', 'L', 0x25d0},
1466 	{'0', 'R', 0x25d1},
1467 	{'S', 'n', 0x25d8},
1468 	{'I', 'c', 0x25d9},
1469 	{'F', 'd', 0x25e2},
1470 	{'B', 'd', 0x25e3},
1471 #   define DG_START_SYMBOLS 0x2605
1472 	{'*', '2', 0x2605},
1473 	{'*', '1', 0x2606},
1474 	{'<', 'H', 0x261c},
1475 	{'>', 'H', 0x261e},
1476 	{'0', 'u', 0x263a},
1477 	{'0', 'U', 0x263b},
1478 	{'S', 'U', 0x263c},
1479 	{'F', 'm', 0x2640},
1480 	{'M', 'l', 0x2642},
1481 	{'c', 'S', 0x2660},
1482 	{'c', 'H', 0x2661},
1483 	{'c', 'D', 0x2662},
1484 	{'c', 'C', 0x2663},
1485 	{'M', 'd', 0x2669},
1486 	{'M', '8', 0x266a},
1487 	{'M', '2', 0x266b},
1488 	{'M', 'b', 0x266d},
1489 	{'M', 'x', 0x266e},
1490 	{'M', 'X', 0x266f},
1491 #   define DG_START_DINGBATS 0x2713
1492 	{'O', 'K', 0x2713},
1493 	{'X', 'X', 0x2717},
1494 	{'-', 'X', 0x2720},
1495 #   define DG_START_CJK_SYMBOLS 0x3000
1496 	{'I', 'S', 0x3000},
1497 	{',', '_', 0x3001},
1498 	{'.', '_', 0x3002},
1499 	{'+', '"', 0x3003},
1500 	{'+', '_', 0x3004},
1501 	{'*', '_', 0x3005},
1502 	{';', '_', 0x3006},
1503 	{'0', '_', 0x3007},
1504 	{'<', '+', 0x300a},
1505 	{'>', '+', 0x300b},
1506 	{'<', '\'', 0x300c},
1507 	{'>', '\'', 0x300d},
1508 	{'<', '"', 0x300e},
1509 	{'>', '"', 0x300f},
1510 	{'(', '"', 0x3010},
1511 	{')', '"', 0x3011},
1512 	{'=', 'T', 0x3012},
1513 	{'=', '_', 0x3013},
1514 	{'(', '\'', 0x3014},
1515 	{')', '\'', 0x3015},
1516 	{'(', 'I', 0x3016},
1517 	{')', 'I', 0x3017},
1518 	{'-', '?', 0x301c},
1519 #   define DG_START_HIRAGANA 0x3041
1520 	{'A', '5', 0x3041},
1521 	{'a', '5', 0x3042},
1522 	{'I', '5', 0x3043},
1523 	{'i', '5', 0x3044},
1524 	{'U', '5', 0x3045},
1525 	{'u', '5', 0x3046},
1526 	{'E', '5', 0x3047},
1527 	{'e', '5', 0x3048},
1528 	{'O', '5', 0x3049},
1529 	{'o', '5', 0x304a},
1530 	{'k', 'a', 0x304b},
1531 	{'g', 'a', 0x304c},
1532 	{'k', 'i', 0x304d},
1533 	{'g', 'i', 0x304e},
1534 	{'k', 'u', 0x304f},
1535 	{'g', 'u', 0x3050},
1536 	{'k', 'e', 0x3051},
1537 	{'g', 'e', 0x3052},
1538 	{'k', 'o', 0x3053},
1539 	{'g', 'o', 0x3054},
1540 	{'s', 'a', 0x3055},
1541 	{'z', 'a', 0x3056},
1542 	{'s', 'i', 0x3057},
1543 	{'z', 'i', 0x3058},
1544 	{'s', 'u', 0x3059},
1545 	{'z', 'u', 0x305a},
1546 	{'s', 'e', 0x305b},
1547 	{'z', 'e', 0x305c},
1548 	{'s', 'o', 0x305d},
1549 	{'z', 'o', 0x305e},
1550 	{'t', 'a', 0x305f},
1551 	{'d', 'a', 0x3060},
1552 	{'t', 'i', 0x3061},
1553 	{'d', 'i', 0x3062},
1554 	{'t', 'U', 0x3063},
1555 	{'t', 'u', 0x3064},
1556 	{'d', 'u', 0x3065},
1557 	{'t', 'e', 0x3066},
1558 	{'d', 'e', 0x3067},
1559 	{'t', 'o', 0x3068},
1560 	{'d', 'o', 0x3069},
1561 	{'n', 'a', 0x306a},
1562 	{'n', 'i', 0x306b},
1563 	{'n', 'u', 0x306c},
1564 	{'n', 'e', 0x306d},
1565 	{'n', 'o', 0x306e},
1566 	{'h', 'a', 0x306f},
1567 	{'b', 'a', 0x3070},
1568 	{'p', 'a', 0x3071},
1569 	{'h', 'i', 0x3072},
1570 	{'b', 'i', 0x3073},
1571 	{'p', 'i', 0x3074},
1572 	{'h', 'u', 0x3075},
1573 	{'b', 'u', 0x3076},
1574 	{'p', 'u', 0x3077},
1575 	{'h', 'e', 0x3078},
1576 	{'b', 'e', 0x3079},
1577 	{'p', 'e', 0x307a},
1578 	{'h', 'o', 0x307b},
1579 	{'b', 'o', 0x307c},
1580 	{'p', 'o', 0x307d},
1581 	{'m', 'a', 0x307e},
1582 	{'m', 'i', 0x307f},
1583 	{'m', 'u', 0x3080},
1584 	{'m', 'e', 0x3081},
1585 	{'m', 'o', 0x3082},
1586 	{'y', 'A', 0x3083},
1587 	{'y', 'a', 0x3084},
1588 	{'y', 'U', 0x3085},
1589 	{'y', 'u', 0x3086},
1590 	{'y', 'O', 0x3087},
1591 	{'y', 'o', 0x3088},
1592 	{'r', 'a', 0x3089},
1593 	{'r', 'i', 0x308a},
1594 	{'r', 'u', 0x308b},
1595 	{'r', 'e', 0x308c},
1596 	{'r', 'o', 0x308d},
1597 	{'w', 'A', 0x308e},
1598 	{'w', 'a', 0x308f},
1599 	{'w', 'i', 0x3090},
1600 	{'w', 'e', 0x3091},
1601 	{'w', 'o', 0x3092},
1602 	{'n', '5', 0x3093},
1603 	{'v', 'u', 0x3094},
1604 	{'"', '5', 0x309b},
1605 	{'0', '5', 0x309c},
1606 	{'*', '5', 0x309d},
1607 	{'+', '5', 0x309e},
1608 #   define DG_START_KATAKANA 0x30a1
1609 	{'a', '6', 0x30a1},
1610 	{'A', '6', 0x30a2},
1611 	{'i', '6', 0x30a3},
1612 	{'I', '6', 0x30a4},
1613 	{'u', '6', 0x30a5},
1614 	{'U', '6', 0x30a6},
1615 	{'e', '6', 0x30a7},
1616 	{'E', '6', 0x30a8},
1617 	{'o', '6', 0x30a9},
1618 	{'O', '6', 0x30aa},
1619 	{'K', 'a', 0x30ab},
1620 	{'G', 'a', 0x30ac},
1621 	{'K', 'i', 0x30ad},
1622 	{'G', 'i', 0x30ae},
1623 	{'K', 'u', 0x30af},
1624 	{'G', 'u', 0x30b0},
1625 	{'K', 'e', 0x30b1},
1626 	{'G', 'e', 0x30b2},
1627 	{'K', 'o', 0x30b3},
1628 	{'G', 'o', 0x30b4},
1629 	{'S', 'a', 0x30b5},
1630 	{'Z', 'a', 0x30b6},
1631 	{'S', 'i', 0x30b7},
1632 	{'Z', 'i', 0x30b8},
1633 	{'S', 'u', 0x30b9},
1634 	{'Z', 'u', 0x30ba},
1635 	{'S', 'e', 0x30bb},
1636 	{'Z', 'e', 0x30bc},
1637 	{'S', 'o', 0x30bd},
1638 	{'Z', 'o', 0x30be},
1639 	{'T', 'a', 0x30bf},
1640 	{'D', 'a', 0x30c0},
1641 	{'T', 'i', 0x30c1},
1642 	{'D', 'i', 0x30c2},
1643 	{'T', 'U', 0x30c3},
1644 	{'T', 'u', 0x30c4},
1645 	{'D', 'u', 0x30c5},
1646 	{'T', 'e', 0x30c6},
1647 	{'D', 'e', 0x30c7},
1648 	{'T', 'o', 0x30c8},
1649 	{'D', 'o', 0x30c9},
1650 	{'N', 'a', 0x30ca},
1651 	{'N', 'i', 0x30cb},
1652 	{'N', 'u', 0x30cc},
1653 	{'N', 'e', 0x30cd},
1654 	{'N', 'o', 0x30ce},
1655 	{'H', 'a', 0x30cf},
1656 	{'B', 'a', 0x30d0},
1657 	{'P', 'a', 0x30d1},
1658 	{'H', 'i', 0x30d2},
1659 	{'B', 'i', 0x30d3},
1660 	{'P', 'i', 0x30d4},
1661 	{'H', 'u', 0x30d5},
1662 	{'B', 'u', 0x30d6},
1663 	{'P', 'u', 0x30d7},
1664 	{'H', 'e', 0x30d8},
1665 	{'B', 'e', 0x30d9},
1666 	{'P', 'e', 0x30da},
1667 	{'H', 'o', 0x30db},
1668 	{'B', 'o', 0x30dc},
1669 	{'P', 'o', 0x30dd},
1670 	{'M', 'a', 0x30de},
1671 	{'M', 'i', 0x30df},
1672 	{'M', 'u', 0x30e0},
1673 	{'M', 'e', 0x30e1},
1674 	{'M', 'o', 0x30e2},
1675 	{'Y', 'A', 0x30e3},
1676 	{'Y', 'a', 0x30e4},
1677 	{'Y', 'U', 0x30e5},
1678 	{'Y', 'u', 0x30e6},
1679 	{'Y', 'O', 0x30e7},
1680 	{'Y', 'o', 0x30e8},
1681 	{'R', 'a', 0x30e9},
1682 	{'R', 'i', 0x30ea},
1683 	{'R', 'u', 0x30eb},
1684 	{'R', 'e', 0x30ec},
1685 	{'R', 'o', 0x30ed},
1686 	{'W', 'A', 0x30ee},
1687 	{'W', 'a', 0x30ef},
1688 	{'W', 'i', 0x30f0},
1689 	{'W', 'e', 0x30f1},
1690 	{'W', 'o', 0x30f2},
1691 	{'N', '6', 0x30f3},
1692 	{'V', 'u', 0x30f4},
1693 	{'K', 'A', 0x30f5},
1694 	{'K', 'E', 0x30f6},
1695 	{'V', 'a', 0x30f7},
1696 	{'V', 'i', 0x30f8},
1697 	{'V', 'e', 0x30f9},
1698 	{'V', 'o', 0x30fa},
1699 	{'.', '6', 0x30fb},
1700 	{'-', '6', 0x30fc},
1701 	{'*', '6', 0x30fd},
1702 	{'+', '6', 0x30fe},
1703 #   define DG_START_BOPOMOFO 0x3105
1704 	{'b', '4', 0x3105},
1705 	{'p', '4', 0x3106},
1706 	{'m', '4', 0x3107},
1707 	{'f', '4', 0x3108},
1708 	{'d', '4', 0x3109},
1709 	{'t', '4', 0x310a},
1710 	{'n', '4', 0x310b},
1711 	{'l', '4', 0x310c},
1712 	{'g', '4', 0x310d},
1713 	{'k', '4', 0x310e},
1714 	{'h', '4', 0x310f},
1715 	{'j', '4', 0x3110},
1716 	{'q', '4', 0x3111},
1717 	{'x', '4', 0x3112},
1718 	{'z', 'h', 0x3113},
1719 	{'c', 'h', 0x3114},
1720 	{'s', 'h', 0x3115},
1721 	{'r', '4', 0x3116},
1722 	{'z', '4', 0x3117},
1723 	{'c', '4', 0x3118},
1724 	{'s', '4', 0x3119},
1725 	{'a', '4', 0x311a},
1726 	{'o', '4', 0x311b},
1727 	{'e', '4', 0x311c},
1728 	{'a', 'i', 0x311e},
1729 	{'e', 'i', 0x311f},
1730 	{'a', 'u', 0x3120},
1731 	{'o', 'u', 0x3121},
1732 	{'a', 'n', 0x3122},
1733 	{'e', 'n', 0x3123},
1734 	{'a', 'N', 0x3124},
1735 	{'e', 'N', 0x3125},
1736 	{'e', 'r', 0x3126},
1737 	{'i', '4', 0x3127},
1738 	{'u', '4', 0x3128},
1739 	{'i', 'u', 0x3129},
1740 	{'v', '4', 0x312a},
1741 	{'n', 'G', 0x312b},
1742 	{'g', 'n', 0x312c},
1743 #   define DG_START_OTHER3 0x3220
1744 	{'1', 'c', 0x3220},
1745 	{'2', 'c', 0x3221},
1746 	{'3', 'c', 0x3222},
1747 	{'4', 'c', 0x3223},
1748 	{'5', 'c', 0x3224},
1749 	{'6', 'c', 0x3225},
1750 	{'7', 'c', 0x3226},
1751 	{'8', 'c', 0x3227},
1752 	{'9', 'c', 0x3228},
1753 	// code points 0xe000 - 0xefff excluded, they have no assigned
1754 	// characters, only used in proposals.
1755 	{'f', 'f', 0xfb00},
1756 	{'f', 'i', 0xfb01},
1757 	{'f', 'l', 0xfb02},
1758 	{'f', 't', 0xfb05},
1759 	{'s', 't', 0xfb06},
1760 
1761 	{NUL, NUL, NUL}
1762        };
1763 
1764 #  endif // OLD_DIGRAPHS
1765 # endif // EBCDIC
1766 #endif // !HPUX_DIGRAPHS
1767 
1768 /*
1769  * handle digraphs after typing a character
1770  */
1771     int
do_digraph(int c)1772 do_digraph(int c)
1773 {
1774     static int	backspaced;	// character before K_BS
1775     static int	lastchar;	// last typed character
1776 
1777     if (c == -1)		// init values
1778     {
1779 	backspaced = -1;
1780     }
1781     else if (p_dg)
1782     {
1783 	if (backspaced >= 0)
1784 	    c = digraph_get(backspaced, c, FALSE);
1785 	backspaced = -1;
1786 	if ((c == K_BS || c == Ctrl_H) && lastchar >= 0)
1787 	    backspaced = lastchar;
1788     }
1789     lastchar = c;
1790     return c;
1791 }
1792 
1793 /*
1794  * Find a digraph for "val".  If found return the string to display it.
1795  * If not found return NULL.
1796  */
1797     char_u *
get_digraph_for_char(int val_arg)1798 get_digraph_for_char(int val_arg)
1799 {
1800     int		val = val_arg;
1801     int		i;
1802     int		use_defaults;
1803     digr_T	*dp;
1804     static      char_u      r[3];
1805 
1806 #if defined(USE_UNICODE_DIGRAPHS)
1807     if (!enc_utf8)
1808     {
1809 	char_u	    buf[6], *to;
1810 	vimconv_T   vc;
1811 
1812 	// convert the character from 'encoding' to Unicode
1813 	i = mb_char2bytes(val, buf);
1814 	vc.vc_type = CONV_NONE;
1815 	if (convert_setup(&vc, p_enc, (char_u *)"utf-8") == OK)
1816 	{
1817 	    vc.vc_fail = TRUE;
1818 	    to = string_convert(&vc, buf, &i);
1819 	    if (to != NULL)
1820 	    {
1821 		val = utf_ptr2char(to);
1822 		vim_free(to);
1823 	    }
1824 	    (void)convert_setup(&vc, NULL, NULL);
1825 	}
1826     }
1827 #endif
1828 
1829     for (use_defaults = 0; use_defaults <= 1; use_defaults++)
1830     {
1831 	if (use_defaults == 0)
1832 	    dp = (digr_T *)user_digraphs.ga_data;
1833 	else
1834 	    dp = digraphdefault;
1835 	for (i = 0; use_defaults ? dp->char1 != NUL
1836 					       : i < user_digraphs.ga_len; ++i)
1837 	{
1838 	    if (dp->result == val)
1839 	    {
1840 		r[0] = dp->char1;
1841 		r[1] = dp->char2;
1842 		r[2] = NUL;
1843 		return r;
1844 	    }
1845 	    ++dp;
1846 	}
1847     }
1848     return NULL;
1849 }
1850 
1851 /*
1852  * Get a digraph.  Used after typing CTRL-K on the command line or in normal
1853  * mode.
1854  * Returns composed character, or NUL when ESC was used.
1855  */
1856     int
get_digraph(int cmdline)1857 get_digraph(
1858     int		cmdline)	// TRUE when called from the cmdline
1859 {
1860     int		c, cc;
1861 
1862     ++no_mapping;
1863     ++allow_keys;
1864     c = plain_vgetc();
1865     --no_mapping;
1866     --allow_keys;
1867     if (c != ESC)		// ESC cancels CTRL-K
1868     {
1869 	if (IS_SPECIAL(c))	// insert special key code
1870 	    return c;
1871 	if (cmdline)
1872 	{
1873 	    if (char2cells(c) == 1
1874 #if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
1875 		    && cmdline_star == 0
1876 #endif
1877 		    )
1878 		putcmdline(c, TRUE);
1879 	}
1880 #ifdef FEAT_CMDL_INFO
1881 	else
1882 	    add_to_showcmd(c);
1883 #endif
1884 	++no_mapping;
1885 	++allow_keys;
1886 	cc = plain_vgetc();
1887 	--no_mapping;
1888 	--allow_keys;
1889 	if (cc != ESC)	    // ESC cancels CTRL-K
1890 	    return digraph_get(c, cc, TRUE);
1891     }
1892     return NUL;
1893 }
1894 
1895 /*
1896  * Lookup the pair "char1", "char2" in the digraph tables.
1897  * If no match, return "char2".
1898  * If "meta_char" is TRUE and "char1" is a space, return "char2" | 0x80.
1899  */
1900     static int
getexactdigraph(int char1,int char2,int meta_char)1901 getexactdigraph(int char1, int char2, int meta_char)
1902 {
1903     int		i;
1904     int		retval = 0;
1905     digr_T	*dp;
1906 
1907     if (IS_SPECIAL(char1) || IS_SPECIAL(char2))
1908 	return char2;
1909 
1910     /*
1911      * Search user digraphs first.
1912      */
1913     dp = (digr_T *)user_digraphs.ga_data;
1914     for (i = 0; i < user_digraphs.ga_len; ++i)
1915     {
1916 	if ((int)dp->char1 == char1 && (int)dp->char2 == char2)
1917 	{
1918 	    retval = dp->result;
1919 	    break;
1920 	}
1921 	++dp;
1922     }
1923 
1924     /*
1925      * Search default digraphs.
1926      */
1927     if (retval == 0)
1928     {
1929 	dp = digraphdefault;
1930 	for (i = 0; dp->char1 != 0; ++i)
1931 	{
1932 	    if ((int)dp->char1 == char1 && (int)dp->char2 == char2)
1933 	    {
1934 		retval = dp->result;
1935 		break;
1936 	    }
1937 	    ++dp;
1938 	}
1939     }
1940 #ifdef USE_UNICODE_DIGRAPHS
1941     if (retval != 0 && !enc_utf8)
1942     {
1943 	char_u	    buf[6], *to;
1944 	vimconv_T   vc;
1945 
1946 	/*
1947 	 * Convert the Unicode digraph to 'encoding'.
1948 	 */
1949 	i = utf_char2bytes(retval, buf);
1950 	retval = 0;
1951 	vc.vc_type = CONV_NONE;
1952 	if (convert_setup(&vc, (char_u *)"utf-8", p_enc) == OK)
1953 	{
1954 	    vc.vc_fail = TRUE;
1955 	    to = string_convert(&vc, buf, &i);
1956 	    if (to != NULL)
1957 	    {
1958 		retval = (*mb_ptr2char)(to);
1959 		vim_free(to);
1960 	    }
1961 	    (void)convert_setup(&vc, NULL, NULL);
1962 	}
1963     }
1964 #endif
1965 
1966     // Ignore multi-byte characters when not in multi-byte mode.
1967     if (!has_mbyte && retval > 0xff)
1968 	retval = 0;
1969 
1970     if (retval == 0)		// digraph deleted or not found
1971     {
1972 	if (char1 == ' ' && meta_char)	// <space> <char> --> meta-char
1973 	    return (char2 | 0x80);
1974 	return char2;
1975     }
1976     return retval;
1977 }
1978 
1979 /*
1980  * Get digraph.
1981  * Allow for both char1-char2 and char2-char1
1982  */
1983     int
digraph_get(int char1,int char2,int meta_char)1984 digraph_get(int char1, int char2, int meta_char)
1985 {
1986     int	    retval;
1987 
1988     if (((retval = getexactdigraph(char1, char2, meta_char)) == char2)
1989 	    && (char1 != char2)
1990 	    && ((retval = getexactdigraph(char2, char1, meta_char)) == char1))
1991 	return char2;
1992     return retval;
1993 }
1994 
1995 /*
1996  * Add a digraph to the digraph table.
1997  */
1998     static void
registerdigraph(int char1,int char2,int n)1999 registerdigraph(int char1, int char2, int n)
2000 {
2001     int		i;
2002     digr_T	*dp;
2003 
2004     // If the digraph already exists, replace "result".
2005     dp = (digr_T *)user_digraphs.ga_data;
2006     for (i = 0; i < user_digraphs.ga_len; ++i)
2007     {
2008 	if ((int)dp->char1 == char1 && (int)dp->char2 == char2)
2009 	{
2010 	    dp->result = n;
2011 	    return;
2012 	}
2013 	++dp;
2014     }
2015 
2016     // Add a new digraph to the table.
2017     if (ga_grow(&user_digraphs, 1) == OK)
2018     {
2019 	dp = (digr_T *)user_digraphs.ga_data + user_digraphs.ga_len;
2020 	dp->char1 = char1;
2021 	dp->char2 = char2;
2022 	dp->result = n;
2023 	++user_digraphs.ga_len;
2024     }
2025 }
2026 
2027 /*
2028  * Check the characters are valid for a digraph.
2029  * If they are valid, returns TRUE; otherwise, give an error message and
2030  * returns FALSE.
2031  */
2032     static int
check_digraph_chars_valid(int char1,int char2)2033 check_digraph_chars_valid(int char1, int char2)
2034 {
2035     if (char2 == 0)
2036     {
2037 	char_u msg[MB_MAXBYTES + 1];
2038 
2039 	msg[mb_char2bytes(char1, msg)] = NUL;
2040 
2041 	semsg(_(e_digraph_must_be_just_two_characters_str), msg);
2042 	return FALSE;
2043     }
2044     if (char1 == ESC || char2 == ESC)
2045     {
2046 	emsg(_("E104: Escape not allowed in digraph"));
2047 	return FALSE;
2048     }
2049     return TRUE;
2050 }
2051 
2052 
2053 
2054 /*
2055  * Add the digraphs in the argument to the digraph table.
2056  * format: {c1}{c2} char {c1}{c2} char ...
2057  */
2058     void
putdigraph(char_u * str)2059 putdigraph(char_u *str)
2060 {
2061     int		char1, char2, n;
2062 
2063     while (*str != NUL)
2064     {
2065 	str = skipwhite(str);
2066 	if (*str == NUL)
2067 	    return;
2068 	char1 = *str++;
2069 	char2 = *str++;
2070 
2071 	if (!check_digraph_chars_valid(char1, char2))
2072 	    return;
2073 
2074 	str = skipwhite(str);
2075 	if (!VIM_ISDIGIT(*str))
2076 	{
2077 	    emsg(_(e_number_expected));
2078 	    return;
2079 	}
2080 	n = getdigits(&str);
2081 
2082 	registerdigraph(char1, char2, n);
2083     }
2084 }
2085 
2086 #if defined(USE_UNICODE_DIGRAPHS)
2087     static void
digraph_header(char * msg)2088 digraph_header(char *msg)
2089 {
2090     if (msg_col > 0)
2091 	msg_putchar('\n');
2092     msg_outtrans_attr((char_u *)msg, HL_ATTR(HLF_CM));
2093     msg_putchar('\n');
2094 }
2095 #endif
2096 
2097     void
listdigraphs(int use_headers)2098 listdigraphs(int use_headers)
2099 {
2100     int		i;
2101     digr_T	*dp;
2102     result_T	previous = 0;
2103 
2104     msg_putchar('\n');
2105 
2106     dp = digraphdefault;
2107     for (i = 0; dp->char1 != NUL && !got_int; ++i)
2108     {
2109 #if defined(USE_UNICODE_DIGRAPHS)
2110 	digr_T tmp;
2111 
2112 	// May need to convert the result to 'encoding'.
2113 	tmp.char1 = dp->char1;
2114 	tmp.char2 = dp->char2;
2115 	tmp.result = getexactdigraph(tmp.char1, tmp.char2, FALSE);
2116 	if (tmp.result != 0 && tmp.result != tmp.char2
2117 					  && (has_mbyte || tmp.result <= 255))
2118 	    printdigraph(&tmp, use_headers ? &previous : NULL);
2119 #else
2120 
2121 	if (getexactdigraph(dp->char1, dp->char2, FALSE) == dp->result
2122 		&& (has_mbyte || dp->result <= 255))
2123 	    printdigraph(dp, use_headers ? &previous : NULL);
2124 #endif
2125 	++dp;
2126 	ui_breakcheck();
2127     }
2128 
2129     dp = (digr_T *)user_digraphs.ga_data;
2130     for (i = 0; i < user_digraphs.ga_len && !got_int; ++i)
2131     {
2132 #if defined(USE_UNICODE_DIGRAPHS)
2133 	if (previous >= 0 && use_headers)
2134 	    digraph_header(_("Custom"));
2135 	previous = -1;
2136 #endif
2137 	printdigraph(dp, NULL);
2138 	ui_breakcheck();
2139 	++dp;
2140     }
2141     must_redraw = CLEAR;    // clear screen, because some digraphs may be
2142 			    // wrong, in which case we messed up ScreenLines
2143 }
2144 
2145     static void
digraph_getlist_appendpair(digr_T * dp,list_T * l)2146 digraph_getlist_appendpair(digr_T *dp, list_T *l)
2147 {
2148     char_u	buf[30];
2149     char_u	*p;
2150     list_T	*l2;
2151     listitem_T	*li, *li2;
2152 
2153 
2154     li = listitem_alloc();
2155     if (li == NULL)
2156 	return;
2157     list_append(l, li);
2158     li->li_tv.v_type = VAR_LIST;
2159     li->li_tv.v_lock = 0;
2160 
2161     l2 = list_alloc();
2162     li->li_tv.vval.v_list = l2;
2163     if (l2 == NULL)
2164 	return;
2165     ++l2->lv_refcount;
2166 
2167     li2 = listitem_alloc();
2168     if (li2 == NULL)
2169 	return;
2170     list_append(l2, li2);
2171     li2->li_tv.v_type = VAR_STRING;
2172     li2->li_tv.v_lock = 0;
2173 
2174     buf[0] = dp->char1;
2175     buf[1] = dp->char2;
2176     buf[2] = NUL;
2177     li2->li_tv.vval.v_string = vim_strsave(&buf[0]);
2178 
2179     li2 = listitem_alloc();
2180     if (li2 == NULL)
2181 	return;
2182     list_append(l2, li2);
2183     li2->li_tv.v_type = VAR_STRING;
2184     li2->li_tv.v_lock = 0;
2185 
2186     p = buf;
2187     if (has_mbyte)
2188 	p += (*mb_char2bytes)(dp->result, p);
2189     else
2190 	*p++ = (char_u)dp->result;
2191     *p = NUL;
2192 
2193     li2->li_tv.vval.v_string = vim_strsave(buf);
2194 }
2195 
2196     static void
digraph_getlist_common(int list_all,typval_T * rettv)2197 digraph_getlist_common(int list_all, typval_T *rettv)
2198 {
2199     int		i;
2200     digr_T	*dp;
2201 
2202     if (rettv_list_alloc(rettv) == FAIL)
2203 	return;
2204 
2205     if (list_all)
2206     {
2207 	dp = digraphdefault;
2208 	for (i = 0; dp->char1 != NUL && !got_int; ++i)
2209 	{
2210 #ifdef USE_UNICODE_DIGRAPHS
2211 	    digr_T tmp;
2212 
2213 	    tmp.char1 = dp->char1;
2214 	    tmp.char2 = dp->char2;
2215 	    tmp.result = getexactdigraph(tmp.char1, tmp.char2, FALSE);
2216 	    if (tmp.result != 0 && tmp.result != tmp.char2
2217 					  && (has_mbyte || tmp.result <= 255))
2218 		digraph_getlist_appendpair(&tmp, rettv->vval.v_list);
2219 #else
2220 	    if (getexactdigraph(dp->char1, dp->char2, FALSE) == dp->result
2221 		    && (has_mbyte || dp->result <= 255))
2222 		digraph_getlist_appendpair(dp, rettv->vval.v_list);
2223 #endif
2224 	    ++dp;
2225 	}
2226     }
2227 
2228     dp = (digr_T *)user_digraphs.ga_data;
2229     for (i = 0; i < user_digraphs.ga_len && !got_int; ++i)
2230     {
2231 	digraph_getlist_appendpair(dp, rettv->vval.v_list);
2232 	++dp;
2233     }
2234 }
2235 
2236 static struct dg_header_entry {
2237     int	    dg_start;
2238     char    *dg_header;
2239 } header_table[] = {
2240     {DG_START_LATIN, N_("Latin supplement")},
2241     {DG_START_GREEK, N_("Greek and Coptic")},
2242     {DG_START_CYRILLIC, N_("Cyrillic")},
2243     {DG_START_HEBREW, N_("Hebrew")},
2244     {DG_START_ARABIC, N_("Arabic")},
2245     {DG_START_LATIN_EXTENDED, N_("Latin extended")},
2246     {DG_START_GREEK_EXTENDED, N_("Greek extended")},
2247     {DG_START_PUNCTUATION, N_("Punctuation")},
2248     {DG_START_SUB_SUPER, N_("Super- and subscripts")},
2249     {DG_START_CURRENCY, N_("Currency")},
2250     {DG_START_OTHER1, N_("Other")},
2251     {DG_START_ROMAN, N_("Roman numbers")},
2252     {DG_START_ARROWS, N_("Arrows")},
2253     {DG_START_MATH, N_("Mathematical operators")},
2254     {DG_START_TECHNICAL, N_("Technical")},
2255     {DG_START_OTHER2, N_("Other")},
2256     {DG_START_DRAWING, N_("Box drawing")},
2257     {DG_START_BLOCK, N_("Block elements")},
2258     {DG_START_SHAPES, N_("Geometric shapes")},
2259     {DG_START_SYMBOLS, N_("Symbols")},
2260     {DG_START_DINGBATS, N_("Dingbats")},
2261     {DG_START_CJK_SYMBOLS, N_("CJK symbols and punctuation")},
2262     {DG_START_HIRAGANA, N_("Hiragana")},
2263     {DG_START_KATAKANA, N_("Katakana")},
2264     {DG_START_BOPOMOFO, N_("Bopomofo")},
2265     {DG_START_OTHER3, N_("Other")},
2266     {0xfffffff, NULL},
2267 };
2268 
2269     static void
printdigraph(digr_T * dp,result_T * previous)2270 printdigraph(digr_T *dp, result_T *previous)
2271 {
2272     char_u	buf[30];
2273     char_u	*p;
2274 
2275     int		list_width;
2276 
2277     if ((dy_flags & DY_UHEX) || has_mbyte)
2278 	list_width = 13;
2279     else
2280 	list_width = 11;
2281 
2282     if (dp->result != 0)
2283     {
2284 #if defined(USE_UNICODE_DIGRAPHS)
2285 	if (previous != NULL)
2286 	{
2287 	    int i;
2288 
2289 	    for (i = 0; header_table[i].dg_header != NULL; ++i)
2290 		if (*previous < header_table[i].dg_start
2291 			&& dp->result >= header_table[i].dg_start
2292 			&& dp->result < header_table[i + 1].dg_start)
2293 		{
2294 		    digraph_header(_(header_table[i].dg_header));
2295 		    break;
2296 		}
2297 	    *previous = dp->result;
2298 	}
2299 #endif
2300 	if (msg_col > Columns - list_width)
2301 	    msg_putchar('\n');
2302 	if (msg_col)
2303 	    while (msg_col % list_width != 0)
2304 		msg_putchar(' ');
2305 
2306 	p = buf;
2307 	*p++ = dp->char1;
2308 	*p++ = dp->char2;
2309 	*p++ = ' ';
2310 	*p = NUL;
2311 	msg_outtrans(buf);
2312 	p = buf;
2313 	if (has_mbyte)
2314 	{
2315 	    // add a space to draw a composing char on
2316 	    if (enc_utf8 && utf_iscomposing(dp->result))
2317 		*p++ = ' ';
2318 	    p += (*mb_char2bytes)(dp->result, p);
2319 	}
2320 	else
2321 	    *p++ = (char_u)dp->result;
2322 	*p = NUL;
2323 	msg_outtrans_attr(buf, HL_ATTR(HLF_8));
2324 	p = buf;
2325 	if (char2cells(dp->result) == 1)
2326 	    *p++ = ' ';
2327 	vim_snprintf((char *)p, sizeof(buf) - (p - buf), " %3d", dp->result);
2328 	msg_outtrans(buf);
2329     }
2330 }
2331 
2332 # ifdef FEAT_EVAL
2333 /*
2334  * Get the two digraph characters from a typval.
2335  * Return OK or FAIL.
2336  */
2337     static int
get_digraph_chars(typval_T * arg,int * char1,int * char2)2338 get_digraph_chars(typval_T *arg, int *char1, int *char2)
2339 {
2340     char_u	buf_chars[NUMBUFLEN];
2341     char_u	*chars = tv_get_string_buf_chk(arg, buf_chars);
2342     char_u	*p = chars;
2343 
2344     if (p != NULL)
2345     {
2346 	if (*p != NUL)
2347 	{
2348 	    *char1 = mb_cptr2char_adv(&p);
2349 	    if (*p != NUL)
2350 	    {
2351 		*char2 = mb_cptr2char_adv(&p);
2352 		if (*p == NUL)
2353 		{
2354 		    if (check_digraph_chars_valid(*char1, *char2))
2355 			return OK;
2356 		    return FAIL;
2357 		}
2358 	    }
2359 	}
2360     }
2361     semsg(_(e_digraph_must_be_just_two_characters_str), chars);
2362     return FAIL;
2363 }
2364 
2365     static int
digraph_set_common(typval_T * argchars,typval_T * argdigraph)2366 digraph_set_common(typval_T *argchars, typval_T *argdigraph)
2367 {
2368     int		char1, char2;
2369     char_u	*digraph;
2370     char_u	*p;
2371     char_u	buf_digraph[NUMBUFLEN];
2372     varnumber_T n;
2373 
2374     if (get_digraph_chars(argchars, &char1, &char2) == FAIL)
2375 	return FALSE;
2376 
2377     digraph = tv_get_string_buf_chk(argdigraph, buf_digraph);
2378     if (digraph == NULL)
2379 	return FALSE;
2380     p = digraph;
2381     n = mb_cptr2char_adv(&p);
2382     if (*p != NUL)
2383     {
2384 	semsg(_(e_digraph_argument_must_be_one_character_str), digraph);
2385 	return FALSE;
2386     }
2387 
2388     registerdigraph(char1, char2, (int)n);
2389     return TRUE;
2390 }
2391 # endif
2392 
2393 #endif // FEAT_DIGRAPHS
2394 
2395 #if defined(FEAT_EVAL) || defined(PROTO)
2396 /*
2397  * "digraph_get()" function
2398  */
2399     void
f_digraph_get(typval_T * argvars,typval_T * rettv)2400 f_digraph_get(typval_T *argvars, typval_T *rettv)
2401 {
2402 # ifdef FEAT_DIGRAPHS
2403     int		code;
2404     char_u	buf[NUMBUFLEN];
2405     char_u	*digraphs;
2406 
2407     rettv->v_type = VAR_STRING;
2408     rettv->vval.v_string = NULL;  // Return empty string for failure
2409 
2410     if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
2411 	return;
2412 
2413     digraphs = tv_get_string_chk(&argvars[0]);
2414 
2415     if (digraphs == NULL)
2416 	return;
2417     else if (STRLEN(digraphs) != 2)
2418     {
2419 	semsg(_(e_digraph_must_be_just_two_characters_str), digraphs);
2420 	return;
2421     }
2422     code = digraph_get(digraphs[0], digraphs[1], FALSE);
2423 
2424     if (has_mbyte)
2425 	buf[(*mb_char2bytes)(code, buf)] = NUL;
2426     else {
2427 	buf[0] = code;
2428 	buf[1] = NUL;
2429     }
2430 
2431     rettv->vval.v_string = vim_strsave(buf);
2432 # else
2433     emsg(_(e_no_digraphs_version));
2434 # endif
2435 }
2436 
2437 /*
2438  * "digraph_getlist()" function
2439  */
2440     void
f_digraph_getlist(typval_T * argvars,typval_T * rettv)2441 f_digraph_getlist(typval_T *argvars, typval_T *rettv)
2442 {
2443 # ifdef FEAT_DIGRAPHS
2444     int     flag_list_all;
2445 
2446     if (in_vim9script() && check_for_opt_bool_arg(argvars, 0) == FAIL)
2447 	return;
2448 
2449     if (argvars[0].v_type == VAR_UNKNOWN)
2450 	flag_list_all = FALSE;
2451     else
2452     {
2453 	int         error = FALSE;
2454 	varnumber_T flag = tv_get_number_chk(&argvars[0], &error);
2455 	if (error)
2456 	    return;
2457 	flag_list_all = flag ? TRUE : FALSE;
2458     }
2459 
2460     digraph_getlist_common(flag_list_all, rettv);
2461 # else
2462     emsg(_(e_no_digraphs_version));
2463 # endif
2464 }
2465 
2466 /*
2467  * "digraph_set()" function
2468  */
2469     void
f_digraph_set(typval_T * argvars,typval_T * rettv)2470 f_digraph_set(typval_T *argvars, typval_T *rettv)
2471 {
2472 # ifdef FEAT_DIGRAPHS
2473     rettv->v_type = VAR_BOOL;
2474     rettv->vval.v_number = VVAL_FALSE;
2475 
2476     if (in_vim9script()
2477 	    && (check_for_string_arg(argvars, 0) == FAIL
2478 		|| check_for_string_arg(argvars, 1) == FAIL))
2479 	return;
2480 
2481     if (!digraph_set_common(&argvars[0], &argvars[1]))
2482 	return;
2483 
2484     rettv->vval.v_number = VVAL_TRUE;
2485 # else
2486     emsg(_(e_no_digraphs_version));
2487 # endif
2488 }
2489 
2490 /*
2491  * "digraph_setlist()" function
2492  */
2493     void
f_digraph_setlist(typval_T * argvars,typval_T * rettv)2494 f_digraph_setlist(typval_T * argvars, typval_T *rettv)
2495 {
2496 # ifdef FEAT_DIGRAPHS
2497     list_T	*pl, *l;
2498     listitem_T	*pli;
2499 
2500     rettv->v_type = VAR_BOOL;
2501     rettv->vval.v_number = VVAL_FALSE;
2502 
2503     if (argvars[0].v_type != VAR_LIST)
2504     {
2505 	emsg(_(e_digraph_setlist_argument_must_be_list_of_lists_with_two_items));
2506 	return;
2507     }
2508 
2509     pl = argvars[0].vval.v_list;
2510     if (pl == NULL)
2511     {
2512 	// Empty list always results in success.
2513 	rettv->vval.v_number = VVAL_TRUE;
2514 	return;
2515     }
2516 
2517     FOR_ALL_LIST_ITEMS(pl, pli)
2518     {
2519 	if (pli->li_tv.v_type != VAR_LIST)
2520 	{
2521 	    emsg(_(e_digraph_setlist_argument_must_be_list_of_lists_with_two_items));
2522 	    return;
2523 	}
2524 
2525 	l = pli->li_tv.vval.v_list;
2526 	if (l == NULL || l->lv_len != 2)
2527 	{
2528 	    emsg(_(e_digraph_setlist_argument_must_be_list_of_lists_with_two_items));
2529 	    return;
2530 	}
2531 
2532 	if (!digraph_set_common(&l->lv_first->li_tv,
2533 						 &l->lv_first->li_next->li_tv))
2534 	    return;
2535     }
2536     rettv->vval.v_number = VVAL_TRUE;
2537 # else
2538     emsg(_(e_no_digraphs_version));
2539 # endif
2540 }
2541 
2542 #endif // FEAT_EVAL
2543 
2544 
2545 #if defined(FEAT_KEYMAP) || defined(PROTO)
2546 
2547 // structure used for b_kmap_ga.ga_data
2548 typedef struct
2549 {
2550     char_u	*from;
2551     char_u	*to;
2552 } kmap_T;
2553 
2554 #define KMAP_MAXLEN 20	    // maximum length of "from" or "to"
2555 
2556 static void keymap_unload(void);
2557 
2558 /*
2559  * Set up key mapping tables for the 'keymap' option.
2560  * Returns NULL if OK, an error message for failure.  This only needs to be
2561  * used when setting the option, not later when the value has already been
2562  * checked.
2563  */
2564     char *
keymap_init(void)2565 keymap_init(void)
2566 {
2567     curbuf->b_kmap_state &= ~KEYMAP_INIT;
2568 
2569     if (*curbuf->b_p_keymap == NUL)
2570     {
2571 	// Stop any active keymap and clear the table.  Also remove
2572 	// b:keymap_name, as no keymap is active now.
2573 	keymap_unload();
2574 	do_cmdline_cmd((char_u *)"unlet! b:keymap_name");
2575     }
2576     else
2577     {
2578 	char_u	*buf;
2579 	size_t  buflen;
2580 
2581 	// Source the keymap file.  It will contain a ":loadkeymap" command
2582 	// which will call ex_loadkeymap() below.
2583 	buflen = STRLEN(curbuf->b_p_keymap) + STRLEN(p_enc) + 14;
2584 	buf = alloc(buflen);
2585 	if (buf == NULL)
2586 	    return e_out_of_memory;
2587 
2588 	// try finding "keymap/'keymap'_'encoding'.vim"  in 'runtimepath'
2589 	vim_snprintf((char *)buf, buflen, "keymap/%s_%s.vim",
2590 						   curbuf->b_p_keymap, p_enc);
2591 	if (source_runtime(buf, 0) == FAIL)
2592 	{
2593 	    // try finding "keymap/'keymap'.vim" in 'runtimepath'
2594 	    vim_snprintf((char *)buf, buflen, "keymap/%s.vim",
2595 							  curbuf->b_p_keymap);
2596 	    if (source_runtime(buf, 0) == FAIL)
2597 	    {
2598 		vim_free(buf);
2599 		return N_("E544: Keymap file not found");
2600 	    }
2601 	}
2602 	vim_free(buf);
2603     }
2604 
2605     return NULL;
2606 }
2607 
2608 /*
2609  * ":loadkeymap" command: load the following lines as the keymap.
2610  */
2611     void
ex_loadkeymap(exarg_T * eap)2612 ex_loadkeymap(exarg_T *eap)
2613 {
2614     char_u	*line;
2615     char_u	*p;
2616     char_u	*s;
2617     kmap_T	*kp;
2618 #define KMAP_LLEN   200	    // max length of "to" and "from" together
2619     char_u	buf[KMAP_LLEN + 11];
2620     int		i;
2621     char_u	*save_cpo = p_cpo;
2622 
2623     if (!getline_equal(eap->getline, eap->cookie, getsourceline))
2624     {
2625 	emsg(_("E105: Using :loadkeymap not in a sourced file"));
2626 	return;
2627     }
2628 
2629     /*
2630      * Stop any active keymap and clear the table.
2631      */
2632     keymap_unload();
2633 
2634     curbuf->b_kmap_state = 0;
2635     ga_init2(&curbuf->b_kmap_ga, (int)sizeof(kmap_T), 20);
2636 
2637     // Set 'cpoptions' to "C" to avoid line continuation.
2638     p_cpo = (char_u *)"C";
2639 
2640     /*
2641      * Get each line of the sourced file, break at the end.
2642      */
2643     for (;;)
2644     {
2645 	line = eap->getline(0, eap->cookie, 0, TRUE);
2646 	if (line == NULL)
2647 	    break;
2648 
2649 	p = skipwhite(line);
2650 	if (*p != '"' && *p != NUL && ga_grow(&curbuf->b_kmap_ga, 1) == OK)
2651 	{
2652 	    kp = (kmap_T *)curbuf->b_kmap_ga.ga_data + curbuf->b_kmap_ga.ga_len;
2653 	    s = skiptowhite(p);
2654 	    kp->from = vim_strnsave(p, s - p);
2655 	    p = skipwhite(s);
2656 	    s = skiptowhite(p);
2657 	    kp->to = vim_strnsave(p, s - p);
2658 
2659 	    if (kp->from == NULL || kp->to == NULL
2660 		    || STRLEN(kp->from) + STRLEN(kp->to) >= KMAP_LLEN
2661 		    || *kp->from == NUL || *kp->to == NUL)
2662 	    {
2663 		if (kp->to != NULL && *kp->to == NUL)
2664 		    emsg(_("E791: Empty keymap entry"));
2665 		vim_free(kp->from);
2666 		vim_free(kp->to);
2667 	    }
2668 	    else
2669 		++curbuf->b_kmap_ga.ga_len;
2670 	}
2671 	vim_free(line);
2672     }
2673 
2674     /*
2675      * setup ":lnoremap" to map the keys
2676      */
2677     for (i = 0; i < curbuf->b_kmap_ga.ga_len; ++i)
2678     {
2679 	vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s %s",
2680 				((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].from,
2681 				 ((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].to);
2682 	(void)do_map(2, buf, LANGMAP, FALSE);
2683     }
2684 
2685     p_cpo = save_cpo;
2686 
2687     curbuf->b_kmap_state |= KEYMAP_LOADED;
2688     status_redraw_curbuf();
2689 }
2690 
2691 /*
2692  * Stop using 'keymap'.
2693  */
2694     static void
keymap_unload(void)2695 keymap_unload(void)
2696 {
2697     char_u	buf[KMAP_MAXLEN + 10];
2698     int		i;
2699     char_u	*save_cpo = p_cpo;
2700     kmap_T	*kp;
2701 
2702     if (!(curbuf->b_kmap_state & KEYMAP_LOADED))
2703 	return;
2704 
2705     // Set 'cpoptions' to "C" to avoid line continuation.
2706     p_cpo = (char_u *)"C";
2707 
2708     // clear the ":lmap"s
2709     kp = (kmap_T *)curbuf->b_kmap_ga.ga_data;
2710     for (i = 0; i < curbuf->b_kmap_ga.ga_len; ++i)
2711     {
2712 	vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s", kp[i].from);
2713 	(void)do_map(1, buf, LANGMAP, FALSE);
2714     }
2715     keymap_clear(&curbuf->b_kmap_ga);
2716 
2717     p_cpo = save_cpo;
2718 
2719     ga_clear(&curbuf->b_kmap_ga);
2720     curbuf->b_kmap_state &= ~KEYMAP_LOADED;
2721     status_redraw_curbuf();
2722 }
2723 
2724     void
keymap_clear(garray_T * kmap)2725 keymap_clear(garray_T *kmap)
2726 {
2727     int	    i;
2728     kmap_T  *kp = (kmap_T *)kmap->ga_data;
2729 
2730     for (i = 0; i < kmap->ga_len; ++i)
2731     {
2732 	vim_free(kp[i].from);
2733 	vim_free(kp[i].to);
2734     }
2735 }
2736 #endif // FEAT_KEYMAP
2737