blob: a5dff00d1b884eaf4817fe4837f1c0d13fbffb37 [file] [log] [blame]
Bram Moolenaaredf3f972016-08-29 22:49:24 +02001/* vi:set ts=8 sts=4 sw=4 noet:
Bram Moolenaar071d4272004-06-13 20:20:40 +00002 *
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
Bram Moolenaar071d4272004-06-13 20:20:40 +000018typedef int result_T;
Bram Moolenaar071d4272004-06-13 20:20:40 +000019
20typedef struct digraph
21{
22 char_u char1;
23 char_u char2;
24 result_T result;
25} digr_T;
26
Bram Moolenaareae8ae12018-12-14 18:53:02 +010027static void printdigraph(digr_T *dp, result_T *previous);
Bram Moolenaar071d4272004-06-13 20:20:40 +000028
Bram Moolenaar5d18efe2019-12-01 21:11:22 +010029// digraphs added by the user
Bram Moolenaar0ab2a882009-05-13 10:51:08 +000030static garray_T user_digraphs = {0, 0, (int)sizeof(digr_T), 10, NULL};
Bram Moolenaar071d4272004-06-13 20:20:40 +000031
32/*
Bram Moolenaare27d6e62022-08-30 15:05:30 +010033 * digraphs for Unicode from RFC1345
34 * (also work for ISO-8859-1 aka latin1)
35 *
Bram Moolenaar071d4272004-06-13 20:20:40 +000036 * Note: Characters marked with XX are not included literally, because some
37 * compilers cannot handle them (Amiga SAS/C is the most picky one).
38 */
Bram Moolenaare27d6e62022-08-30 15:05:30 +010039static digr_T digraphdefault[] = {
Bram Moolenaar5d18efe2019-12-01 21:11:22 +010040 {'N', 'U', 0x0a}, // LF for NUL
Bram Moolenaar071d4272004-06-13 20:20:40 +000041 {'S', 'H', 0x01},
42 {'S', 'X', 0x02},
43 {'E', 'X', 0x03},
44 {'E', 'T', 0x04},
45 {'E', 'Q', 0x05},
46 {'A', 'K', 0x06},
47 {'B', 'L', 0x07},
48 {'B', 'S', 0x08},
49 {'H', 'T', 0x09},
50 {'L', 'F', 0x0a},
51 {'V', 'T', 0x0b},
52 {'F', 'F', 0x0c},
53 {'C', 'R', 0x0d},
54 {'S', 'O', 0x0e},
55 {'S', 'I', 0x0f},
56 {'D', 'L', 0x10},
57 {'D', '1', 0x11},
58 {'D', '2', 0x12},
59 {'D', '3', 0x13},
60 {'D', '4', 0x14},
61 {'N', 'K', 0x15},
62 {'S', 'Y', 0x16},
63 {'E', 'B', 0x17},
64 {'C', 'N', 0x18},
65 {'E', 'M', 0x19},
66 {'S', 'B', 0x1a},
67 {'E', 'C', 0x1b},
68 {'F', 'S', 0x1c},
69 {'G', 'S', 0x1d},
70 {'R', 'S', 0x1e},
71 {'U', 'S', 0x1f},
72 {'S', 'P', 0x20},
73 {'N', 'b', 0x23},
74 {'D', 'O', 0x24},
75 {'A', 't', 0x40},
76 {'<', '(', 0x5b},
77 {'/', '/', 0x5c},
78 {')', '>', 0x5d},
79 {'\'', '>', 0x5e},
80 {'\'', '!', 0x60},
81 {'(', '!', 0x7b},
82 {'!', '!', 0x7c},
83 {'!', ')', 0x7d},
84 {'\'', '?', 0x7e},
85 {'D', 'T', 0x7f},
86 {'P', 'A', 0x80},
87 {'H', 'O', 0x81},
88 {'B', 'H', 0x82},
89 {'N', 'H', 0x83},
90 {'I', 'N', 0x84},
91 {'N', 'L', 0x85},
92 {'S', 'A', 0x86},
93 {'E', 'S', 0x87},
94 {'H', 'S', 0x88},
95 {'H', 'J', 0x89},
96 {'V', 'S', 0x8a},
97 {'P', 'D', 0x8b},
98 {'P', 'U', 0x8c},
99 {'R', 'I', 0x8d},
100 {'S', '2', 0x8e},
101 {'S', '3', 0x8f},
102 {'D', 'C', 0x90},
103 {'P', '1', 0x91},
104 {'P', '2', 0x92},
105 {'T', 'S', 0x93},
106 {'C', 'C', 0x94},
107 {'M', 'W', 0x95},
108 {'S', 'G', 0x96},
109 {'E', 'G', 0x97},
110 {'S', 'S', 0x98},
111 {'G', 'C', 0x99},
112 {'S', 'C', 0x9a},
113 {'C', 'I', 0x9b},
114 {'S', 'T', 0x9c},
115 {'O', 'C', 0x9d},
116 {'P', 'M', 0x9e},
117 {'A', 'C', 0x9f},
118 {'N', 'S', 0xa0},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200119# define DG_START_LATIN 0xa1
Bram Moolenaar071d4272004-06-13 20:20:40 +0000120 {'!', 'I', 0xa1},
Bram Moolenaar41193092019-08-24 21:53:31 +0200121 {'~', '!', 0xa1}, // ¡ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000122 {'C', 't', 0xa2},
Bram Moolenaar41193092019-08-24 21:53:31 +0200123 {'c', '|', 0xa2}, // ¢ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000124 {'P', 'd', 0xa3},
Bram Moolenaar41193092019-08-24 21:53:31 +0200125 {'$', '$', 0xa3}, // £ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000126 {'C', 'u', 0xa4},
Bram Moolenaar41193092019-08-24 21:53:31 +0200127 {'o', 'x', 0xa4}, // ¤ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000128 {'Y', 'e', 0xa5},
Bram Moolenaar41193092019-08-24 21:53:31 +0200129 {'Y', '-', 0xa5}, // ¥ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000130 {'B', 'B', 0xa6},
Bram Moolenaar41193092019-08-24 21:53:31 +0200131 {'|', '|', 0xa6}, // ¦ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000132 {'S', 'E', 0xa7},
133 {'\'', ':', 0xa8},
134 {'C', 'o', 0xa9},
Bram Moolenaar41193092019-08-24 21:53:31 +0200135 {'c', 'O', 0xa9}, // © Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000136 {'-', 'a', 0xaa},
137 {'<', '<', 0xab},
138 {'N', 'O', 0xac},
Bram Moolenaar41193092019-08-24 21:53:31 +0200139 {'-', ',', 0xac}, // ¬ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000140 {'-', '-', 0xad},
141 {'R', 'g', 0xae},
142 {'\'', 'm', 0xaf},
Bram Moolenaar41193092019-08-24 21:53:31 +0200143 {'-', '=', 0xaf}, // ¯ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000144 {'D', 'G', 0xb0},
Bram Moolenaar41193092019-08-24 21:53:31 +0200145 {'~', 'o', 0xb0}, // ° Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000146 {'+', '-', 0xb1},
147 {'2', 'S', 0xb2},
Bram Moolenaar41193092019-08-24 21:53:31 +0200148 {'2', '2', 0xb2}, // ² Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000149 {'3', 'S', 0xb3},
Bram Moolenaar41193092019-08-24 21:53:31 +0200150 {'3', '3', 0xb3}, // ³ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000151 {'\'', '\'', 0xb4},
152 {'M', 'y', 0xb5},
153 {'P', 'I', 0xb6},
Bram Moolenaar41193092019-08-24 21:53:31 +0200154 {'p', 'p', 0xb6}, // ¶ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000155 {'.', 'M', 0xb7},
Bram Moolenaar41193092019-08-24 21:53:31 +0200156 {'~', '.', 0xb7}, // · Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000157 {'\'', ',', 0xb8},
158 {'1', 'S', 0xb9},
Bram Moolenaar41193092019-08-24 21:53:31 +0200159 {'1', '1', 0xb9}, // ¹ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000160 {'-', 'o', 0xba},
161 {'>', '>', 0xbb},
162 {'1', '4', 0xbc},
163 {'1', '2', 0xbd},
164 {'3', '4', 0xbe},
165 {'?', 'I', 0xbf},
Bram Moolenaar41193092019-08-24 21:53:31 +0200166 {'~', '?', 0xbf}, // ¿ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000167 {'A', '!', 0xc0},
Bram Moolenaar41193092019-08-24 21:53:31 +0200168 {'A', '`', 0xc0}, // À Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000169 {'A', '\'', 0xc1},
170 {'A', '>', 0xc2},
Bram Moolenaar41193092019-08-24 21:53:31 +0200171 {'A', '^', 0xc2}, // Â Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000172 {'A', '?', 0xc3},
Bram Moolenaar41193092019-08-24 21:53:31 +0200173 {'A', '~', 0xc3}, // Ã Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000174 {'A', ':', 0xc4},
Bram Moolenaar41193092019-08-24 21:53:31 +0200175 {'A', '"', 0xc4}, // Ä Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000176 {'A', 'A', 0xc5},
Bram Moolenaar41193092019-08-24 21:53:31 +0200177 {'A', '@', 0xc5}, // Å Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000178 {'A', 'E', 0xc6},
179 {'C', ',', 0xc7},
180 {'E', '!', 0xc8},
Bram Moolenaar41193092019-08-24 21:53:31 +0200181 {'E', '`', 0xc8}, // È Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000182 {'E', '\'', 0xc9},
183 {'E', '>', 0xca},
Bram Moolenaar41193092019-08-24 21:53:31 +0200184 {'E', '^', 0xca}, // Ê Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000185 {'E', ':', 0xcb},
Bram Moolenaar41193092019-08-24 21:53:31 +0200186 {'E', '"', 0xcb}, // Ë Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000187 {'I', '!', 0xcc},
Bram Moolenaar41193092019-08-24 21:53:31 +0200188 {'I', '`', 0xcc}, // Ì Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000189 {'I', '\'', 0xcd},
190 {'I', '>', 0xce},
Bram Moolenaar41193092019-08-24 21:53:31 +0200191 {'I', '^', 0xce}, // Î Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000192 {'I', ':', 0xcf},
Bram Moolenaar41193092019-08-24 21:53:31 +0200193 {'I', '"', 0xcf}, // Ï Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000194 {'D', '-', 0xd0},
195 {'N', '?', 0xd1},
Bram Moolenaar41193092019-08-24 21:53:31 +0200196 {'N', '~', 0xd1}, // Ñ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000197 {'O', '!', 0xd2},
Bram Moolenaar41193092019-08-24 21:53:31 +0200198 {'O', '`', 0xd2}, // Ò Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000199 {'O', '\'', 0xd3},
200 {'O', '>', 0xd4},
Bram Moolenaar41193092019-08-24 21:53:31 +0200201 {'O', '^', 0xd4}, // Ô Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000202 {'O', '?', 0xd5},
Bram Moolenaar41193092019-08-24 21:53:31 +0200203 {'O', '~', 0xd5}, // Õ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000204 {'O', ':', 0xd6},
205 {'*', 'X', 0xd7},
Bram Moolenaar41193092019-08-24 21:53:31 +0200206 {'/', '\\', 0xd7}, // × Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000207 {'O', '/', 0xd8},
208 {'U', '!', 0xd9},
Bram Moolenaar41193092019-08-24 21:53:31 +0200209 {'U', '`', 0xd9}, // Ù Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000210 {'U', '\'', 0xda},
211 {'U', '>', 0xdb},
Bram Moolenaar41193092019-08-24 21:53:31 +0200212 {'U', '^', 0xdb}, // Û Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000213 {'U', ':', 0xdc},
214 {'Y', '\'', 0xdd},
215 {'T', 'H', 0xde},
Bram Moolenaar41193092019-08-24 21:53:31 +0200216 {'I', 'p', 0xde}, // Þ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000217 {'s', 's', 0xdf},
218 {'a', '!', 0xe0},
Bram Moolenaar41193092019-08-24 21:53:31 +0200219 {'a', '`', 0xe0}, // à Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000220 {'a', '\'', 0xe1},
221 {'a', '>', 0xe2},
Bram Moolenaar41193092019-08-24 21:53:31 +0200222 {'a', '^', 0xe2}, // â Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000223 {'a', '?', 0xe3},
Bram Moolenaar41193092019-08-24 21:53:31 +0200224 {'a', '~', 0xe3}, // ã Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000225 {'a', ':', 0xe4},
Bram Moolenaar41193092019-08-24 21:53:31 +0200226 {'a', '"', 0xe4}, // ä Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000227 {'a', 'a', 0xe5},
Bram Moolenaar41193092019-08-24 21:53:31 +0200228 {'a', '@', 0xe5}, // å Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000229 {'a', 'e', 0xe6},
230 {'c', ',', 0xe7},
231 {'e', '!', 0xe8},
Bram Moolenaar41193092019-08-24 21:53:31 +0200232 {'e', '`', 0xe8}, // è Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000233 {'e', '\'', 0xe9},
234 {'e', '>', 0xea},
Bram Moolenaar41193092019-08-24 21:53:31 +0200235 {'e', '^', 0xea}, // ê Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000236 {'e', ':', 0xeb},
Bram Moolenaar41193092019-08-24 21:53:31 +0200237 {'e', '"', 0xeb}, // ë Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000238 {'i', '!', 0xec},
Bram Moolenaar41193092019-08-24 21:53:31 +0200239 {'i', '`', 0xec}, // ì Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000240 {'i', '\'', 0xed},
241 {'i', '>', 0xee},
Bram Moolenaar41193092019-08-24 21:53:31 +0200242 {'i', '^', 0xee}, // î Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000243 {'i', ':', 0xef},
244 {'d', '-', 0xf0},
245 {'n', '?', 0xf1},
Bram Moolenaar41193092019-08-24 21:53:31 +0200246 {'n', '~', 0xf1}, // ñ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000247 {'o', '!', 0xf2},
Bram Moolenaar41193092019-08-24 21:53:31 +0200248 {'o', '`', 0xf2}, // ò Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000249 {'o', '\'', 0xf3},
250 {'o', '>', 0xf4},
Bram Moolenaar41193092019-08-24 21:53:31 +0200251 {'o', '^', 0xf4}, // ô Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000252 {'o', '?', 0xf5},
Bram Moolenaar41193092019-08-24 21:53:31 +0200253 {'o', '~', 0xf5}, // õ Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000254 {'o', ':', 0xf6},
255 {'-', ':', 0xf7},
256 {'o', '/', 0xf8},
257 {'u', '!', 0xf9},
Bram Moolenaar41193092019-08-24 21:53:31 +0200258 {'u', '`', 0xf9}, // ù Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000259 {'u', '\'', 0xfa},
260 {'u', '>', 0xfb},
Bram Moolenaar41193092019-08-24 21:53:31 +0200261 {'u', '^', 0xfb}, // û Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000262 {'u', ':', 0xfc},
263 {'y', '\'', 0xfd},
264 {'t', 'h', 0xfe},
265 {'y', ':', 0xff},
Bram Moolenaareae8ae12018-12-14 18:53:02 +0100266 {'y', '"', 0xff}, // x XX Vim 5.x compatible
Bram Moolenaar071d4272004-06-13 20:20:40 +0000267
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200268# define USE_UNICODE_DIGRAPHS
Bram Moolenaar071d4272004-06-13 20:20:40 +0000269
270 {'A', '-', 0x0100},
271 {'a', '-', 0x0101},
272 {'A', '(', 0x0102},
273 {'a', '(', 0x0103},
274 {'A', ';', 0x0104},
275 {'a', ';', 0x0105},
276 {'C', '\'', 0x0106},
277 {'c', '\'', 0x0107},
278 {'C', '>', 0x0108},
279 {'c', '>', 0x0109},
280 {'C', '.', 0x010a},
281 {'c', '.', 0x010b},
282 {'C', '<', 0x010c},
283 {'c', '<', 0x010d},
284 {'D', '<', 0x010e},
285 {'d', '<', 0x010f},
286 {'D', '/', 0x0110},
287 {'d', '/', 0x0111},
288 {'E', '-', 0x0112},
289 {'e', '-', 0x0113},
290 {'E', '(', 0x0114},
291 {'e', '(', 0x0115},
292 {'E', '.', 0x0116},
293 {'e', '.', 0x0117},
294 {'E', ';', 0x0118},
295 {'e', ';', 0x0119},
296 {'E', '<', 0x011a},
297 {'e', '<', 0x011b},
298 {'G', '>', 0x011c},
299 {'g', '>', 0x011d},
300 {'G', '(', 0x011e},
301 {'g', '(', 0x011f},
302 {'G', '.', 0x0120},
303 {'g', '.', 0x0121},
304 {'G', ',', 0x0122},
305 {'g', ',', 0x0123},
306 {'H', '>', 0x0124},
307 {'h', '>', 0x0125},
308 {'H', '/', 0x0126},
309 {'h', '/', 0x0127},
310 {'I', '?', 0x0128},
311 {'i', '?', 0x0129},
312 {'I', '-', 0x012a},
313 {'i', '-', 0x012b},
314 {'I', '(', 0x012c},
315 {'i', '(', 0x012d},
316 {'I', ';', 0x012e},
317 {'i', ';', 0x012f},
318 {'I', '.', 0x0130},
319 {'i', '.', 0x0131},
320 {'I', 'J', 0x0132},
321 {'i', 'j', 0x0133},
322 {'J', '>', 0x0134},
323 {'j', '>', 0x0135},
324 {'K', ',', 0x0136},
325 {'k', ',', 0x0137},
326 {'k', 'k', 0x0138},
327 {'L', '\'', 0x0139},
328 {'l', '\'', 0x013a},
329 {'L', ',', 0x013b},
330 {'l', ',', 0x013c},
331 {'L', '<', 0x013d},
332 {'l', '<', 0x013e},
333 {'L', '.', 0x013f},
334 {'l', '.', 0x0140},
335 {'L', '/', 0x0141},
336 {'l', '/', 0x0142},
337 {'N', '\'', 0x0143},
338 {'n', '\'', 0x0144},
339 {'N', ',', 0x0145},
340 {'n', ',', 0x0146},
341 {'N', '<', 0x0147},
342 {'n', '<', 0x0148},
343 {'\'', 'n', 0x0149},
344 {'N', 'G', 0x014a},
345 {'n', 'g', 0x014b},
346 {'O', '-', 0x014c},
347 {'o', '-', 0x014d},
348 {'O', '(', 0x014e},
349 {'o', '(', 0x014f},
350 {'O', '"', 0x0150},
351 {'o', '"', 0x0151},
352 {'O', 'E', 0x0152},
353 {'o', 'e', 0x0153},
354 {'R', '\'', 0x0154},
355 {'r', '\'', 0x0155},
356 {'R', ',', 0x0156},
357 {'r', ',', 0x0157},
358 {'R', '<', 0x0158},
359 {'r', '<', 0x0159},
360 {'S', '\'', 0x015a},
361 {'s', '\'', 0x015b},
362 {'S', '>', 0x015c},
363 {'s', '>', 0x015d},
364 {'S', ',', 0x015e},
365 {'s', ',', 0x015f},
366 {'S', '<', 0x0160},
367 {'s', '<', 0x0161},
368 {'T', ',', 0x0162},
369 {'t', ',', 0x0163},
370 {'T', '<', 0x0164},
371 {'t', '<', 0x0165},
372 {'T', '/', 0x0166},
373 {'t', '/', 0x0167},
374 {'U', '?', 0x0168},
375 {'u', '?', 0x0169},
376 {'U', '-', 0x016a},
377 {'u', '-', 0x016b},
378 {'U', '(', 0x016c},
379 {'u', '(', 0x016d},
380 {'U', '0', 0x016e},
381 {'u', '0', 0x016f},
382 {'U', '"', 0x0170},
383 {'u', '"', 0x0171},
384 {'U', ';', 0x0172},
385 {'u', ';', 0x0173},
386 {'W', '>', 0x0174},
387 {'w', '>', 0x0175},
388 {'Y', '>', 0x0176},
389 {'y', '>', 0x0177},
390 {'Y', ':', 0x0178},
391 {'Z', '\'', 0x0179},
392 {'z', '\'', 0x017a},
393 {'Z', '.', 0x017b},
394 {'z', '.', 0x017c},
395 {'Z', '<', 0x017d},
396 {'z', '<', 0x017e},
397 {'O', '9', 0x01a0},
398 {'o', '9', 0x01a1},
399 {'O', 'I', 0x01a2},
400 {'o', 'i', 0x01a3},
401 {'y', 'r', 0x01a6},
402 {'U', '9', 0x01af},
403 {'u', '9', 0x01b0},
404 {'Z', '/', 0x01b5},
405 {'z', '/', 0x01b6},
406 {'E', 'D', 0x01b7},
407 {'A', '<', 0x01cd},
408 {'a', '<', 0x01ce},
409 {'I', '<', 0x01cf},
410 {'i', '<', 0x01d0},
411 {'O', '<', 0x01d1},
412 {'o', '<', 0x01d2},
413 {'U', '<', 0x01d3},
414 {'u', '<', 0x01d4},
415 {'A', '1', 0x01de},
416 {'a', '1', 0x01df},
417 {'A', '7', 0x01e0},
418 {'a', '7', 0x01e1},
419 {'A', '3', 0x01e2},
420 {'a', '3', 0x01e3},
421 {'G', '/', 0x01e4},
422 {'g', '/', 0x01e5},
423 {'G', '<', 0x01e6},
424 {'g', '<', 0x01e7},
425 {'K', '<', 0x01e8},
426 {'k', '<', 0x01e9},
427 {'O', ';', 0x01ea},
428 {'o', ';', 0x01eb},
429 {'O', '1', 0x01ec},
430 {'o', '1', 0x01ed},
431 {'E', 'Z', 0x01ee},
432 {'e', 'z', 0x01ef},
433 {'j', '<', 0x01f0},
434 {'G', '\'', 0x01f4},
435 {'g', '\'', 0x01f5},
436 {';', 'S', 0x02bf},
437 {'\'', '<', 0x02c7},
438 {'\'', '(', 0x02d8},
439 {'\'', '.', 0x02d9},
440 {'\'', '0', 0x02da},
441 {'\'', ';', 0x02db},
442 {'\'', '"', 0x02dd},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200443# define DG_START_GREEK 0x0386
Bram Moolenaar071d4272004-06-13 20:20:40 +0000444 {'A', '%', 0x0386},
445 {'E', '%', 0x0388},
446 {'Y', '%', 0x0389},
447 {'I', '%', 0x038a},
448 {'O', '%', 0x038c},
449 {'U', '%', 0x038e},
450 {'W', '%', 0x038f},
451 {'i', '3', 0x0390},
452 {'A', '*', 0x0391},
453 {'B', '*', 0x0392},
454 {'G', '*', 0x0393},
455 {'D', '*', 0x0394},
456 {'E', '*', 0x0395},
457 {'Z', '*', 0x0396},
458 {'Y', '*', 0x0397},
459 {'H', '*', 0x0398},
460 {'I', '*', 0x0399},
461 {'K', '*', 0x039a},
462 {'L', '*', 0x039b},
463 {'M', '*', 0x039c},
464 {'N', '*', 0x039d},
465 {'C', '*', 0x039e},
466 {'O', '*', 0x039f},
467 {'P', '*', 0x03a0},
468 {'R', '*', 0x03a1},
469 {'S', '*', 0x03a3},
470 {'T', '*', 0x03a4},
471 {'U', '*', 0x03a5},
472 {'F', '*', 0x03a6},
473 {'X', '*', 0x03a7},
474 {'Q', '*', 0x03a8},
475 {'W', '*', 0x03a9},
476 {'J', '*', 0x03aa},
477 {'V', '*', 0x03ab},
478 {'a', '%', 0x03ac},
479 {'e', '%', 0x03ad},
480 {'y', '%', 0x03ae},
481 {'i', '%', 0x03af},
482 {'u', '3', 0x03b0},
483 {'a', '*', 0x03b1},
484 {'b', '*', 0x03b2},
485 {'g', '*', 0x03b3},
486 {'d', '*', 0x03b4},
487 {'e', '*', 0x03b5},
488 {'z', '*', 0x03b6},
489 {'y', '*', 0x03b7},
490 {'h', '*', 0x03b8},
491 {'i', '*', 0x03b9},
492 {'k', '*', 0x03ba},
493 {'l', '*', 0x03bb},
494 {'m', '*', 0x03bc},
495 {'n', '*', 0x03bd},
496 {'c', '*', 0x03be},
497 {'o', '*', 0x03bf},
498 {'p', '*', 0x03c0},
499 {'r', '*', 0x03c1},
500 {'*', 's', 0x03c2},
501 {'s', '*', 0x03c3},
502 {'t', '*', 0x03c4},
503 {'u', '*', 0x03c5},
504 {'f', '*', 0x03c6},
505 {'x', '*', 0x03c7},
506 {'q', '*', 0x03c8},
507 {'w', '*', 0x03c9},
508 {'j', '*', 0x03ca},
509 {'v', '*', 0x03cb},
510 {'o', '%', 0x03cc},
511 {'u', '%', 0x03cd},
512 {'w', '%', 0x03ce},
513 {'\'', 'G', 0x03d8},
514 {',', 'G', 0x03d9},
515 {'T', '3', 0x03da},
516 {'t', '3', 0x03db},
517 {'M', '3', 0x03dc},
518 {'m', '3', 0x03dd},
519 {'K', '3', 0x03de},
520 {'k', '3', 0x03df},
521 {'P', '3', 0x03e0},
522 {'p', '3', 0x03e1},
523 {'\'', '%', 0x03f4},
524 {'j', '3', 0x03f5},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200525# define DG_START_CYRILLIC 0x0401
Bram Moolenaar071d4272004-06-13 20:20:40 +0000526 {'I', 'O', 0x0401},
527 {'D', '%', 0x0402},
528 {'G', '%', 0x0403},
529 {'I', 'E', 0x0404},
530 {'D', 'S', 0x0405},
531 {'I', 'I', 0x0406},
532 {'Y', 'I', 0x0407},
533 {'J', '%', 0x0408},
534 {'L', 'J', 0x0409},
535 {'N', 'J', 0x040a},
536 {'T', 's', 0x040b},
537 {'K', 'J', 0x040c},
538 {'V', '%', 0x040e},
539 {'D', 'Z', 0x040f},
540 {'A', '=', 0x0410},
541 {'B', '=', 0x0411},
542 {'V', '=', 0x0412},
543 {'G', '=', 0x0413},
544 {'D', '=', 0x0414},
545 {'E', '=', 0x0415},
546 {'Z', '%', 0x0416},
547 {'Z', '=', 0x0417},
548 {'I', '=', 0x0418},
549 {'J', '=', 0x0419},
550 {'K', '=', 0x041a},
551 {'L', '=', 0x041b},
552 {'M', '=', 0x041c},
553 {'N', '=', 0x041d},
554 {'O', '=', 0x041e},
555 {'P', '=', 0x041f},
556 {'R', '=', 0x0420},
557 {'S', '=', 0x0421},
558 {'T', '=', 0x0422},
559 {'U', '=', 0x0423},
560 {'F', '=', 0x0424},
561 {'H', '=', 0x0425},
562 {'C', '=', 0x0426},
563 {'C', '%', 0x0427},
564 {'S', '%', 0x0428},
565 {'S', 'c', 0x0429},
566 {'=', '"', 0x042a},
567 {'Y', '=', 0x042b},
568 {'%', '"', 0x042c},
569 {'J', 'E', 0x042d},
570 {'J', 'U', 0x042e},
571 {'J', 'A', 0x042f},
572 {'a', '=', 0x0430},
573 {'b', '=', 0x0431},
574 {'v', '=', 0x0432},
575 {'g', '=', 0x0433},
576 {'d', '=', 0x0434},
577 {'e', '=', 0x0435},
578 {'z', '%', 0x0436},
579 {'z', '=', 0x0437},
580 {'i', '=', 0x0438},
581 {'j', '=', 0x0439},
582 {'k', '=', 0x043a},
583 {'l', '=', 0x043b},
584 {'m', '=', 0x043c},
585 {'n', '=', 0x043d},
586 {'o', '=', 0x043e},
587 {'p', '=', 0x043f},
588 {'r', '=', 0x0440},
589 {'s', '=', 0x0441},
590 {'t', '=', 0x0442},
591 {'u', '=', 0x0443},
592 {'f', '=', 0x0444},
593 {'h', '=', 0x0445},
594 {'c', '=', 0x0446},
595 {'c', '%', 0x0447},
596 {'s', '%', 0x0448},
597 {'s', 'c', 0x0449},
598 {'=', '\'', 0x044a},
599 {'y', '=', 0x044b},
600 {'%', '\'', 0x044c},
601 {'j', 'e', 0x044d},
602 {'j', 'u', 0x044e},
603 {'j', 'a', 0x044f},
604 {'i', 'o', 0x0451},
605 {'d', '%', 0x0452},
606 {'g', '%', 0x0453},
607 {'i', 'e', 0x0454},
608 {'d', 's', 0x0455},
609 {'i', 'i', 0x0456},
610 {'y', 'i', 0x0457},
611 {'j', '%', 0x0458},
612 {'l', 'j', 0x0459},
613 {'n', 'j', 0x045a},
614 {'t', 's', 0x045b},
615 {'k', 'j', 0x045c},
616 {'v', '%', 0x045e},
617 {'d', 'z', 0x045f},
618 {'Y', '3', 0x0462},
619 {'y', '3', 0x0463},
620 {'O', '3', 0x046a},
621 {'o', '3', 0x046b},
622 {'F', '3', 0x0472},
623 {'f', '3', 0x0473},
624 {'V', '3', 0x0474},
625 {'v', '3', 0x0475},
626 {'C', '3', 0x0480},
627 {'c', '3', 0x0481},
628 {'G', '3', 0x0490},
629 {'g', '3', 0x0491},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200630# define DG_START_HEBREW 0x05d0
Bram Moolenaar071d4272004-06-13 20:20:40 +0000631 {'A', '+', 0x05d0},
632 {'B', '+', 0x05d1},
633 {'G', '+', 0x05d2},
634 {'D', '+', 0x05d3},
635 {'H', '+', 0x05d4},
636 {'W', '+', 0x05d5},
637 {'Z', '+', 0x05d6},
638 {'X', '+', 0x05d7},
639 {'T', 'j', 0x05d8},
640 {'J', '+', 0x05d9},
641 {'K', '%', 0x05da},
642 {'K', '+', 0x05db},
643 {'L', '+', 0x05dc},
644 {'M', '%', 0x05dd},
645 {'M', '+', 0x05de},
646 {'N', '%', 0x05df},
647 {'N', '+', 0x05e0},
648 {'S', '+', 0x05e1},
649 {'E', '+', 0x05e2},
650 {'P', '%', 0x05e3},
651 {'P', '+', 0x05e4},
652 {'Z', 'j', 0x05e5},
653 {'Z', 'J', 0x05e6},
654 {'Q', '+', 0x05e7},
655 {'R', '+', 0x05e8},
656 {'S', 'h', 0x05e9},
657 {'T', '+', 0x05ea},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200658# define DG_START_ARABIC 0x060c
Bram Moolenaar071d4272004-06-13 20:20:40 +0000659 {',', '+', 0x060c},
660 {';', '+', 0x061b},
661 {'?', '+', 0x061f},
662 {'H', '\'', 0x0621},
663 {'a', 'M', 0x0622},
664 {'a', 'H', 0x0623},
665 {'w', 'H', 0x0624},
666 {'a', 'h', 0x0625},
667 {'y', 'H', 0x0626},
668 {'a', '+', 0x0627},
669 {'b', '+', 0x0628},
670 {'t', 'm', 0x0629},
671 {'t', '+', 0x062a},
672 {'t', 'k', 0x062b},
673 {'g', '+', 0x062c},
674 {'h', 'k', 0x062d},
675 {'x', '+', 0x062e},
676 {'d', '+', 0x062f},
677 {'d', 'k', 0x0630},
678 {'r', '+', 0x0631},
679 {'z', '+', 0x0632},
680 {'s', '+', 0x0633},
681 {'s', 'n', 0x0634},
682 {'c', '+', 0x0635},
683 {'d', 'd', 0x0636},
684 {'t', 'j', 0x0637},
685 {'z', 'H', 0x0638},
686 {'e', '+', 0x0639},
687 {'i', '+', 0x063a},
688 {'+', '+', 0x0640},
689 {'f', '+', 0x0641},
690 {'q', '+', 0x0642},
691 {'k', '+', 0x0643},
692 {'l', '+', 0x0644},
693 {'m', '+', 0x0645},
694 {'n', '+', 0x0646},
695 {'h', '+', 0x0647},
696 {'w', '+', 0x0648},
697 {'j', '+', 0x0649},
698 {'y', '+', 0x064a},
699 {':', '+', 0x064b},
700 {'"', '+', 0x064c},
701 {'=', '+', 0x064d},
702 {'/', '+', 0x064e},
703 {'\'', '+', 0x064f},
704 {'1', '+', 0x0650},
705 {'3', '+', 0x0651},
706 {'0', '+', 0x0652},
707 {'a', 'S', 0x0670},
708 {'p', '+', 0x067e},
709 {'v', '+', 0x06a4},
710 {'g', 'f', 0x06af},
711 {'0', 'a', 0x06f0},
712 {'1', 'a', 0x06f1},
713 {'2', 'a', 0x06f2},
714 {'3', 'a', 0x06f3},
715 {'4', 'a', 0x06f4},
716 {'5', 'a', 0x06f5},
717 {'6', 'a', 0x06f6},
718 {'7', 'a', 0x06f7},
719 {'8', 'a', 0x06f8},
720 {'9', 'a', 0x06f9},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200721# define DG_START_LATIN_EXTENDED 0x1e02
Bram Moolenaar071d4272004-06-13 20:20:40 +0000722 {'B', '.', 0x1e02},
723 {'b', '.', 0x1e03},
724 {'B', '_', 0x1e06},
725 {'b', '_', 0x1e07},
726 {'D', '.', 0x1e0a},
727 {'d', '.', 0x1e0b},
728 {'D', '_', 0x1e0e},
729 {'d', '_', 0x1e0f},
730 {'D', ',', 0x1e10},
731 {'d', ',', 0x1e11},
732 {'F', '.', 0x1e1e},
733 {'f', '.', 0x1e1f},
734 {'G', '-', 0x1e20},
735 {'g', '-', 0x1e21},
736 {'H', '.', 0x1e22},
737 {'h', '.', 0x1e23},
738 {'H', ':', 0x1e26},
739 {'h', ':', 0x1e27},
740 {'H', ',', 0x1e28},
741 {'h', ',', 0x1e29},
742 {'K', '\'', 0x1e30},
743 {'k', '\'', 0x1e31},
744 {'K', '_', 0x1e34},
745 {'k', '_', 0x1e35},
746 {'L', '_', 0x1e3a},
747 {'l', '_', 0x1e3b},
748 {'M', '\'', 0x1e3e},
749 {'m', '\'', 0x1e3f},
750 {'M', '.', 0x1e40},
751 {'m', '.', 0x1e41},
752 {'N', '.', 0x1e44},
753 {'n', '.', 0x1e45},
754 {'N', '_', 0x1e48},
755 {'n', '_', 0x1e49},
756 {'P', '\'', 0x1e54},
757 {'p', '\'', 0x1e55},
758 {'P', '.', 0x1e56},
759 {'p', '.', 0x1e57},
760 {'R', '.', 0x1e58},
761 {'r', '.', 0x1e59},
762 {'R', '_', 0x1e5e},
763 {'r', '_', 0x1e5f},
764 {'S', '.', 0x1e60},
765 {'s', '.', 0x1e61},
766 {'T', '.', 0x1e6a},
767 {'t', '.', 0x1e6b},
768 {'T', '_', 0x1e6e},
769 {'t', '_', 0x1e6f},
770 {'V', '?', 0x1e7c},
771 {'v', '?', 0x1e7d},
772 {'W', '!', 0x1e80},
Bram Moolenaareae8ae12018-12-14 18:53:02 +0100773 {'W', '`', 0x1e80}, // extra alternative, easier to remember
Bram Moolenaar071d4272004-06-13 20:20:40 +0000774 {'w', '!', 0x1e81},
Bram Moolenaareae8ae12018-12-14 18:53:02 +0100775 {'w', '`', 0x1e81}, // extra alternative, easier to remember
Bram Moolenaar071d4272004-06-13 20:20:40 +0000776 {'W', '\'', 0x1e82},
777 {'w', '\'', 0x1e83},
778 {'W', ':', 0x1e84},
779 {'w', ':', 0x1e85},
780 {'W', '.', 0x1e86},
781 {'w', '.', 0x1e87},
782 {'X', '.', 0x1e8a},
783 {'x', '.', 0x1e8b},
784 {'X', ':', 0x1e8c},
785 {'x', ':', 0x1e8d},
786 {'Y', '.', 0x1e8e},
787 {'y', '.', 0x1e8f},
788 {'Z', '>', 0x1e90},
789 {'z', '>', 0x1e91},
790 {'Z', '_', 0x1e94},
791 {'z', '_', 0x1e95},
792 {'h', '_', 0x1e96},
793 {'t', ':', 0x1e97},
794 {'w', '0', 0x1e98},
795 {'y', '0', 0x1e99},
796 {'A', '2', 0x1ea2},
797 {'a', '2', 0x1ea3},
798 {'E', '2', 0x1eba},
799 {'e', '2', 0x1ebb},
800 {'E', '?', 0x1ebc},
801 {'e', '?', 0x1ebd},
802 {'I', '2', 0x1ec8},
803 {'i', '2', 0x1ec9},
804 {'O', '2', 0x1ece},
805 {'o', '2', 0x1ecf},
806 {'U', '2', 0x1ee6},
807 {'u', '2', 0x1ee7},
808 {'Y', '!', 0x1ef2},
Bram Moolenaareae8ae12018-12-14 18:53:02 +0100809 {'Y', '`', 0x1ef2}, // extra alternative, easier to remember
Bram Moolenaar071d4272004-06-13 20:20:40 +0000810 {'y', '!', 0x1ef3},
Bram Moolenaareae8ae12018-12-14 18:53:02 +0100811 {'y', '`', 0x1ef3}, // extra alternative, easier to remember
Bram Moolenaar071d4272004-06-13 20:20:40 +0000812 {'Y', '2', 0x1ef6},
813 {'y', '2', 0x1ef7},
814 {'Y', '?', 0x1ef8},
815 {'y', '?', 0x1ef9},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200816# define DG_START_GREEK_EXTENDED 0x1f00
Bram Moolenaar071d4272004-06-13 20:20:40 +0000817 {';', '\'', 0x1f00},
818 {',', '\'', 0x1f01},
819 {';', '!', 0x1f02},
820 {',', '!', 0x1f03},
821 {'?', ';', 0x1f04},
822 {'?', ',', 0x1f05},
823 {'!', ':', 0x1f06},
824 {'?', ':', 0x1f07},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200825# define DG_START_PUNCTUATION 0x2002
Bram Moolenaar071d4272004-06-13 20:20:40 +0000826 {'1', 'N', 0x2002},
827 {'1', 'M', 0x2003},
828 {'3', 'M', 0x2004},
829 {'4', 'M', 0x2005},
830 {'6', 'M', 0x2006},
831 {'1', 'T', 0x2009},
832 {'1', 'H', 0x200a},
833 {'-', '1', 0x2010},
834 {'-', 'N', 0x2013},
835 {'-', 'M', 0x2014},
836 {'-', '3', 0x2015},
837 {'!', '2', 0x2016},
838 {'=', '2', 0x2017},
839 {'\'', '6', 0x2018},
840 {'\'', '9', 0x2019},
841 {'.', '9', 0x201a},
842 {'9', '\'', 0x201b},
843 {'"', '6', 0x201c},
844 {'"', '9', 0x201d},
845 {':', '9', 0x201e},
846 {'9', '"', 0x201f},
847 {'/', '-', 0x2020},
848 {'/', '=', 0x2021},
Bram Moolenaar57ad94c2020-09-08 19:06:30 +0200849 {'o', 'o', 0x2022},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000850 {'.', '.', 0x2025},
Bram Moolenaar81615512016-11-04 22:17:16 +0100851 {',', '.', 0x2026},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000852 {'%', '0', 0x2030},
853 {'1', '\'', 0x2032},
854 {'2', '\'', 0x2033},
855 {'3', '\'', 0x2034},
Jonathan Wright47416d12023-10-20 12:08:09 +0200856 {'4', '\'', 0x2057},
Bram Moolenaar071d4272004-06-13 20:20:40 +0000857 {'1', '"', 0x2035},
858 {'2', '"', 0x2036},
859 {'3', '"', 0x2037},
860 {'C', 'a', 0x2038},
861 {'<', '1', 0x2039},
862 {'>', '1', 0x203a},
863 {':', 'X', 0x203b},
864 {'\'', '-', 0x203e},
865 {'/', 'f', 0x2044},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200866# define DG_START_SUB_SUPER 0x2070
Bram Moolenaar071d4272004-06-13 20:20:40 +0000867 {'0', 'S', 0x2070},
868 {'4', 'S', 0x2074},
869 {'5', 'S', 0x2075},
870 {'6', 'S', 0x2076},
871 {'7', 'S', 0x2077},
872 {'8', 'S', 0x2078},
873 {'9', 'S', 0x2079},
874 {'+', 'S', 0x207a},
875 {'-', 'S', 0x207b},
876 {'=', 'S', 0x207c},
877 {'(', 'S', 0x207d},
878 {')', 'S', 0x207e},
879 {'n', 'S', 0x207f},
880 {'0', 's', 0x2080},
881 {'1', 's', 0x2081},
882 {'2', 's', 0x2082},
883 {'3', 's', 0x2083},
884 {'4', 's', 0x2084},
885 {'5', 's', 0x2085},
886 {'6', 's', 0x2086},
887 {'7', 's', 0x2087},
888 {'8', 's', 0x2088},
889 {'9', 's', 0x2089},
890 {'+', 's', 0x208a},
891 {'-', 's', 0x208b},
892 {'=', 's', 0x208c},
893 {'(', 's', 0x208d},
894 {')', 's', 0x208e},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200895# define DG_START_CURRENCY 0x20a4
Bram Moolenaar071d4272004-06-13 20:20:40 +0000896 {'L', 'i', 0x20a4},
897 {'P', 't', 0x20a7},
898 {'W', '=', 0x20a9},
Bram Moolenaar5d18efe2019-12-01 21:11:22 +0100899 {'=', 'e', 0x20ac}, // euro
900 {'E', 'u', 0x20ac}, // euro
901 {'=', 'R', 0x20bd}, // rouble
902 {'=', 'P', 0x20bd}, // rouble
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200903# define DG_START_OTHER1 0x2103
Bram Moolenaar071d4272004-06-13 20:20:40 +0000904 {'o', 'C', 0x2103},
905 {'c', 'o', 0x2105},
906 {'o', 'F', 0x2109},
907 {'N', '0', 0x2116},
908 {'P', 'O', 0x2117},
909 {'R', 'x', 0x211e},
910 {'S', 'M', 0x2120},
911 {'T', 'M', 0x2122},
912 {'O', 'm', 0x2126},
913 {'A', 'O', 0x212b},
914 {'1', '3', 0x2153},
915 {'2', '3', 0x2154},
916 {'1', '5', 0x2155},
917 {'2', '5', 0x2156},
918 {'3', '5', 0x2157},
919 {'4', '5', 0x2158},
920 {'1', '6', 0x2159},
921 {'5', '6', 0x215a},
922 {'1', '8', 0x215b},
923 {'3', '8', 0x215c},
924 {'5', '8', 0x215d},
925 {'7', '8', 0x215e},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200926# define DG_START_ROMAN 0x2160
Bram Moolenaar071d4272004-06-13 20:20:40 +0000927 {'1', 'R', 0x2160},
928 {'2', 'R', 0x2161},
929 {'3', 'R', 0x2162},
930 {'4', 'R', 0x2163},
931 {'5', 'R', 0x2164},
932 {'6', 'R', 0x2165},
933 {'7', 'R', 0x2166},
934 {'8', 'R', 0x2167},
935 {'9', 'R', 0x2168},
936 {'a', 'R', 0x2169},
937 {'b', 'R', 0x216a},
938 {'c', 'R', 0x216b},
939 {'1', 'r', 0x2170},
940 {'2', 'r', 0x2171},
941 {'3', 'r', 0x2172},
942 {'4', 'r', 0x2173},
943 {'5', 'r', 0x2174},
944 {'6', 'r', 0x2175},
945 {'7', 'r', 0x2176},
946 {'8', 'r', 0x2177},
947 {'9', 'r', 0x2178},
948 {'a', 'r', 0x2179},
949 {'b', 'r', 0x217a},
950 {'c', 'r', 0x217b},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200951# define DG_START_ARROWS 0x2190
Bram Moolenaar071d4272004-06-13 20:20:40 +0000952 {'<', '-', 0x2190},
953 {'-', '!', 0x2191},
954 {'-', '>', 0x2192},
955 {'-', 'v', 0x2193},
956 {'<', '>', 0x2194},
957 {'U', 'D', 0x2195},
958 {'<', '=', 0x21d0},
959 {'=', '>', 0x21d2},
960 {'=', '=', 0x21d4},
Bram Moolenaare3f915d2020-07-14 23:02:44 +0200961# define DG_START_MATH 0x2200
Bram Moolenaar071d4272004-06-13 20:20:40 +0000962 {'F', 'A', 0x2200},
963 {'d', 'P', 0x2202},
964 {'T', 'E', 0x2203},
965 {'/', '0', 0x2205},
966 {'D', 'E', 0x2206},
967 {'N', 'B', 0x2207},
968 {'(', '-', 0x2208},
969 {'-', ')', 0x220b},
970 {'*', 'P', 0x220f},
971 {'+', 'Z', 0x2211},
972 {'-', '2', 0x2212},
973 {'-', '+', 0x2213},
974 {'*', '-', 0x2217},
975 {'O', 'b', 0x2218},
976 {'S', 'b', 0x2219},
977 {'R', 'T', 0x221a},
978 {'0', '(', 0x221d},
979 {'0', '0', 0x221e},
980 {'-', 'L', 0x221f},
981 {'-', 'V', 0x2220},
982 {'P', 'P', 0x2225},
983 {'A', 'N', 0x2227},
984 {'O', 'R', 0x2228},
985 {'(', 'U', 0x2229},
986 {')', 'U', 0x222a},
987 {'I', 'n', 0x222b},
988 {'D', 'I', 0x222c},
989 {'I', 'o', 0x222e},
990 {'.', ':', 0x2234},
991 {':', '.', 0x2235},
992 {':', 'R', 0x2236},
993 {':', ':', 0x2237},
994 {'?', '1', 0x223c},
995 {'C', 'G', 0x223e},
996 {'?', '-', 0x2243},
997 {'?', '=', 0x2245},
998 {'?', '2', 0x2248},
999 {'=', '?', 0x224c},
Hans Ginzel3a621182025-02-01 16:15:11 +01001000 {'.', '=', 0x2250},
Bram Moolenaar071d4272004-06-13 20:20:40 +00001001 {'H', 'I', 0x2253},
1002 {'!', '=', 0x2260},
1003 {'=', '3', 0x2261},
1004 {'=', '<', 0x2264},
1005 {'>', '=', 0x2265},
1006 {'<', '*', 0x226a},
1007 {'*', '>', 0x226b},
1008 {'!', '<', 0x226e},
1009 {'!', '>', 0x226f},
1010 {'(', 'C', 0x2282},
1011 {')', 'C', 0x2283},
1012 {'(', '_', 0x2286},
1013 {')', '_', 0x2287},
1014 {'0', '.', 0x2299},
1015 {'0', '2', 0x229a},
1016 {'-', 'T', 0x22a5},
1017 {'.', 'P', 0x22c5},
1018 {':', '3', 0x22ee},
1019 {'.', '3', 0x22ef},
Bram Moolenaare3f915d2020-07-14 23:02:44 +02001020# define DG_START_TECHNICAL 0x2302
Bram Moolenaar071d4272004-06-13 20:20:40 +00001021 {'E', 'h', 0x2302},
1022 {'<', '7', 0x2308},
1023 {'>', '7', 0x2309},
1024 {'7', '<', 0x230a},
1025 {'7', '>', 0x230b},
1026 {'N', 'I', 0x2310},
1027 {'(', 'A', 0x2312},
1028 {'T', 'R', 0x2315},
1029 {'I', 'u', 0x2320},
1030 {'I', 'l', 0x2321},
1031 {'<', '/', 0x2329},
1032 {'/', '>', 0x232a},
Bram Moolenaare3f915d2020-07-14 23:02:44 +02001033# define DG_START_OTHER2 0x2423
Bram Moolenaar071d4272004-06-13 20:20:40 +00001034 {'V', 's', 0x2423},
1035 {'1', 'h', 0x2440},
1036 {'3', 'h', 0x2441},
1037 {'2', 'h', 0x2442},
1038 {'4', 'h', 0x2443},
1039 {'1', 'j', 0x2446},
1040 {'2', 'j', 0x2447},
1041 {'3', 'j', 0x2448},
1042 {'4', 'j', 0x2449},
1043 {'1', '.', 0x2488},
1044 {'2', '.', 0x2489},
1045 {'3', '.', 0x248a},
1046 {'4', '.', 0x248b},
1047 {'5', '.', 0x248c},
1048 {'6', '.', 0x248d},
1049 {'7', '.', 0x248e},
1050 {'8', '.', 0x248f},
1051 {'9', '.', 0x2490},
Bram Moolenaare3f915d2020-07-14 23:02:44 +02001052# define DG_START_DRAWING 0x2500
Bram Moolenaar071d4272004-06-13 20:20:40 +00001053 {'h', 'h', 0x2500},
1054 {'H', 'H', 0x2501},
1055 {'v', 'v', 0x2502},
1056 {'V', 'V', 0x2503},
1057 {'3', '-', 0x2504},
1058 {'3', '_', 0x2505},
1059 {'3', '!', 0x2506},
1060 {'3', '/', 0x2507},
1061 {'4', '-', 0x2508},
1062 {'4', '_', 0x2509},
1063 {'4', '!', 0x250a},
1064 {'4', '/', 0x250b},
1065 {'d', 'r', 0x250c},
1066 {'d', 'R', 0x250d},
1067 {'D', 'r', 0x250e},
1068 {'D', 'R', 0x250f},
1069 {'d', 'l', 0x2510},
1070 {'d', 'L', 0x2511},
1071 {'D', 'l', 0x2512},
1072 {'L', 'D', 0x2513},
1073 {'u', 'r', 0x2514},
1074 {'u', 'R', 0x2515},
1075 {'U', 'r', 0x2516},
1076 {'U', 'R', 0x2517},
1077 {'u', 'l', 0x2518},
1078 {'u', 'L', 0x2519},
1079 {'U', 'l', 0x251a},
1080 {'U', 'L', 0x251b},
1081 {'v', 'r', 0x251c},
1082 {'v', 'R', 0x251d},
1083 {'V', 'r', 0x2520},
1084 {'V', 'R', 0x2523},
1085 {'v', 'l', 0x2524},
1086 {'v', 'L', 0x2525},
1087 {'V', 'l', 0x2528},
1088 {'V', 'L', 0x252b},
1089 {'d', 'h', 0x252c},
1090 {'d', 'H', 0x252f},
1091 {'D', 'h', 0x2530},
1092 {'D', 'H', 0x2533},
1093 {'u', 'h', 0x2534},
1094 {'u', 'H', 0x2537},
1095 {'U', 'h', 0x2538},
1096 {'U', 'H', 0x253b},
1097 {'v', 'h', 0x253c},
1098 {'v', 'H', 0x253f},
1099 {'V', 'h', 0x2542},
1100 {'V', 'H', 0x254b},
1101 {'F', 'D', 0x2571},
1102 {'B', 'D', 0x2572},
Bram Moolenaare3f915d2020-07-14 23:02:44 +02001103# define DG_START_BLOCK 0x2580
Bram Moolenaar071d4272004-06-13 20:20:40 +00001104 {'T', 'B', 0x2580},
1105 {'L', 'B', 0x2584},
1106 {'F', 'B', 0x2588},
1107 {'l', 'B', 0x258c},
1108 {'R', 'B', 0x2590},
1109 {'.', 'S', 0x2591},
1110 {':', 'S', 0x2592},
1111 {'?', 'S', 0x2593},
Bram Moolenaare3f915d2020-07-14 23:02:44 +02001112# define DG_START_SHAPES 0x25a0
Bram Moolenaar071d4272004-06-13 20:20:40 +00001113 {'f', 'S', 0x25a0},
1114 {'O', 'S', 0x25a1},
1115 {'R', 'O', 0x25a2},
1116 {'R', 'r', 0x25a3},
1117 {'R', 'F', 0x25a4},
1118 {'R', 'Y', 0x25a5},
1119 {'R', 'H', 0x25a6},
1120 {'R', 'Z', 0x25a7},
1121 {'R', 'K', 0x25a8},
1122 {'R', 'X', 0x25a9},
1123 {'s', 'B', 0x25aa},
1124 {'S', 'R', 0x25ac},
1125 {'O', 'r', 0x25ad},
1126 {'U', 'T', 0x25b2},
1127 {'u', 'T', 0x25b3},
1128 {'P', 'R', 0x25b6},
1129 {'T', 'r', 0x25b7},
1130 {'D', 't', 0x25bc},
1131 {'d', 'T', 0x25bd},
1132 {'P', 'L', 0x25c0},
1133 {'T', 'l', 0x25c1},
1134 {'D', 'b', 0x25c6},
1135 {'D', 'w', 0x25c7},
1136 {'L', 'Z', 0x25ca},
1137 {'0', 'm', 0x25cb},
1138 {'0', 'o', 0x25ce},
1139 {'0', 'M', 0x25cf},
1140 {'0', 'L', 0x25d0},
1141 {'0', 'R', 0x25d1},
1142 {'S', 'n', 0x25d8},
1143 {'I', 'c', 0x25d9},
1144 {'F', 'd', 0x25e2},
1145 {'B', 'd', 0x25e3},
Bram Moolenaare3f915d2020-07-14 23:02:44 +02001146# define DG_START_SYMBOLS 0x2605
Bram Moolenaar071d4272004-06-13 20:20:40 +00001147 {'*', '2', 0x2605},
1148 {'*', '1', 0x2606},
1149 {'<', 'H', 0x261c},
1150 {'>', 'H', 0x261e},
1151 {'0', 'u', 0x263a},
1152 {'0', 'U', 0x263b},
1153 {'S', 'U', 0x263c},
1154 {'F', 'm', 0x2640},
1155 {'M', 'l', 0x2642},
1156 {'c', 'S', 0x2660},
1157 {'c', 'H', 0x2661},
1158 {'c', 'D', 0x2662},
1159 {'c', 'C', 0x2663},
1160 {'M', 'd', 0x2669},
1161 {'M', '8', 0x266a},
1162 {'M', '2', 0x266b},
1163 {'M', 'b', 0x266d},
1164 {'M', 'x', 0x266e},
1165 {'M', 'X', 0x266f},
Bram Moolenaare3f915d2020-07-14 23:02:44 +02001166# define DG_START_DINGBATS 0x2713
Bram Moolenaar071d4272004-06-13 20:20:40 +00001167 {'O', 'K', 0x2713},
1168 {'X', 'X', 0x2717},
1169 {'-', 'X', 0x2720},
Bram Moolenaare3f915d2020-07-14 23:02:44 +02001170# define DG_START_CJK_SYMBOLS 0x3000
Bram Moolenaar071d4272004-06-13 20:20:40 +00001171 {'I', 'S', 0x3000},
1172 {',', '_', 0x3001},
1173 {'.', '_', 0x3002},
1174 {'+', '"', 0x3003},
1175 {'+', '_', 0x3004},
1176 {'*', '_', 0x3005},
1177 {';', '_', 0x3006},
1178 {'0', '_', 0x3007},
1179 {'<', '+', 0x300a},
1180 {'>', '+', 0x300b},
1181 {'<', '\'', 0x300c},
1182 {'>', '\'', 0x300d},
1183 {'<', '"', 0x300e},
1184 {'>', '"', 0x300f},
1185 {'(', '"', 0x3010},
1186 {')', '"', 0x3011},
1187 {'=', 'T', 0x3012},
1188 {'=', '_', 0x3013},
1189 {'(', '\'', 0x3014},
1190 {')', '\'', 0x3015},
1191 {'(', 'I', 0x3016},
1192 {')', 'I', 0x3017},
1193 {'-', '?', 0x301c},
Bram Moolenaare3f915d2020-07-14 23:02:44 +02001194# define DG_START_HIRAGANA 0x3041
Bram Moolenaar071d4272004-06-13 20:20:40 +00001195 {'A', '5', 0x3041},
1196 {'a', '5', 0x3042},
1197 {'I', '5', 0x3043},
1198 {'i', '5', 0x3044},
1199 {'U', '5', 0x3045},
1200 {'u', '5', 0x3046},
1201 {'E', '5', 0x3047},
1202 {'e', '5', 0x3048},
1203 {'O', '5', 0x3049},
1204 {'o', '5', 0x304a},
1205 {'k', 'a', 0x304b},
1206 {'g', 'a', 0x304c},
1207 {'k', 'i', 0x304d},
1208 {'g', 'i', 0x304e},
1209 {'k', 'u', 0x304f},
1210 {'g', 'u', 0x3050},
1211 {'k', 'e', 0x3051},
1212 {'g', 'e', 0x3052},
1213 {'k', 'o', 0x3053},
1214 {'g', 'o', 0x3054},
1215 {'s', 'a', 0x3055},
1216 {'z', 'a', 0x3056},
1217 {'s', 'i', 0x3057},
1218 {'z', 'i', 0x3058},
1219 {'s', 'u', 0x3059},
1220 {'z', 'u', 0x305a},
1221 {'s', 'e', 0x305b},
1222 {'z', 'e', 0x305c},
1223 {'s', 'o', 0x305d},
1224 {'z', 'o', 0x305e},
1225 {'t', 'a', 0x305f},
1226 {'d', 'a', 0x3060},
1227 {'t', 'i', 0x3061},
1228 {'d', 'i', 0x3062},
1229 {'t', 'U', 0x3063},
1230 {'t', 'u', 0x3064},
1231 {'d', 'u', 0x3065},
1232 {'t', 'e', 0x3066},
1233 {'d', 'e', 0x3067},
1234 {'t', 'o', 0x3068},
1235 {'d', 'o', 0x3069},
1236 {'n', 'a', 0x306a},
1237 {'n', 'i', 0x306b},
1238 {'n', 'u', 0x306c},
1239 {'n', 'e', 0x306d},
1240 {'n', 'o', 0x306e},
1241 {'h', 'a', 0x306f},
1242 {'b', 'a', 0x3070},
1243 {'p', 'a', 0x3071},
1244 {'h', 'i', 0x3072},
1245 {'b', 'i', 0x3073},
1246 {'p', 'i', 0x3074},
1247 {'h', 'u', 0x3075},
1248 {'b', 'u', 0x3076},
1249 {'p', 'u', 0x3077},
1250 {'h', 'e', 0x3078},
1251 {'b', 'e', 0x3079},
1252 {'p', 'e', 0x307a},
1253 {'h', 'o', 0x307b},
1254 {'b', 'o', 0x307c},
1255 {'p', 'o', 0x307d},
1256 {'m', 'a', 0x307e},
1257 {'m', 'i', 0x307f},
1258 {'m', 'u', 0x3080},
1259 {'m', 'e', 0x3081},
1260 {'m', 'o', 0x3082},
1261 {'y', 'A', 0x3083},
1262 {'y', 'a', 0x3084},
1263 {'y', 'U', 0x3085},
1264 {'y', 'u', 0x3086},
1265 {'y', 'O', 0x3087},
1266 {'y', 'o', 0x3088},
1267 {'r', 'a', 0x3089},
1268 {'r', 'i', 0x308a},
1269 {'r', 'u', 0x308b},
1270 {'r', 'e', 0x308c},
1271 {'r', 'o', 0x308d},
1272 {'w', 'A', 0x308e},
1273 {'w', 'a', 0x308f},
1274 {'w', 'i', 0x3090},
1275 {'w', 'e', 0x3091},
1276 {'w', 'o', 0x3092},
1277 {'n', '5', 0x3093},
1278 {'v', 'u', 0x3094},
1279 {'"', '5', 0x309b},
1280 {'0', '5', 0x309c},
1281 {'*', '5', 0x309d},
1282 {'+', '5', 0x309e},
Bram Moolenaare3f915d2020-07-14 23:02:44 +02001283# define DG_START_KATAKANA 0x30a1
Bram Moolenaar071d4272004-06-13 20:20:40 +00001284 {'a', '6', 0x30a1},
1285 {'A', '6', 0x30a2},
1286 {'i', '6', 0x30a3},
1287 {'I', '6', 0x30a4},
1288 {'u', '6', 0x30a5},
1289 {'U', '6', 0x30a6},
1290 {'e', '6', 0x30a7},
1291 {'E', '6', 0x30a8},
1292 {'o', '6', 0x30a9},
1293 {'O', '6', 0x30aa},
1294 {'K', 'a', 0x30ab},
1295 {'G', 'a', 0x30ac},
1296 {'K', 'i', 0x30ad},
1297 {'G', 'i', 0x30ae},
1298 {'K', 'u', 0x30af},
1299 {'G', 'u', 0x30b0},
1300 {'K', 'e', 0x30b1},
1301 {'G', 'e', 0x30b2},
1302 {'K', 'o', 0x30b3},
1303 {'G', 'o', 0x30b4},
1304 {'S', 'a', 0x30b5},
1305 {'Z', 'a', 0x30b6},
1306 {'S', 'i', 0x30b7},
1307 {'Z', 'i', 0x30b8},
1308 {'S', 'u', 0x30b9},
1309 {'Z', 'u', 0x30ba},
1310 {'S', 'e', 0x30bb},
1311 {'Z', 'e', 0x30bc},
1312 {'S', 'o', 0x30bd},
1313 {'Z', 'o', 0x30be},
1314 {'T', 'a', 0x30bf},
1315 {'D', 'a', 0x30c0},
1316 {'T', 'i', 0x30c1},
1317 {'D', 'i', 0x30c2},
1318 {'T', 'U', 0x30c3},
1319 {'T', 'u', 0x30c4},
1320 {'D', 'u', 0x30c5},
1321 {'T', 'e', 0x30c6},
1322 {'D', 'e', 0x30c7},
1323 {'T', 'o', 0x30c8},
1324 {'D', 'o', 0x30c9},
1325 {'N', 'a', 0x30ca},
1326 {'N', 'i', 0x30cb},
1327 {'N', 'u', 0x30cc},
1328 {'N', 'e', 0x30cd},
1329 {'N', 'o', 0x30ce},
1330 {'H', 'a', 0x30cf},
1331 {'B', 'a', 0x30d0},
1332 {'P', 'a', 0x30d1},
1333 {'H', 'i', 0x30d2},
1334 {'B', 'i', 0x30d3},
1335 {'P', 'i', 0x30d4},
1336 {'H', 'u', 0x30d5},
1337 {'B', 'u', 0x30d6},
1338 {'P', 'u', 0x30d7},
1339 {'H', 'e', 0x30d8},
1340 {'B', 'e', 0x30d9},
1341 {'P', 'e', 0x30da},
1342 {'H', 'o', 0x30db},
1343 {'B', 'o', 0x30dc},
1344 {'P', 'o', 0x30dd},
1345 {'M', 'a', 0x30de},
1346 {'M', 'i', 0x30df},
1347 {'M', 'u', 0x30e0},
1348 {'M', 'e', 0x30e1},
1349 {'M', 'o', 0x30e2},
1350 {'Y', 'A', 0x30e3},
1351 {'Y', 'a', 0x30e4},
1352 {'Y', 'U', 0x30e5},
1353 {'Y', 'u', 0x30e6},
1354 {'Y', 'O', 0x30e7},
1355 {'Y', 'o', 0x30e8},
1356 {'R', 'a', 0x30e9},
1357 {'R', 'i', 0x30ea},
1358 {'R', 'u', 0x30eb},
1359 {'R', 'e', 0x30ec},
1360 {'R', 'o', 0x30ed},
1361 {'W', 'A', 0x30ee},
1362 {'W', 'a', 0x30ef},
1363 {'W', 'i', 0x30f0},
1364 {'W', 'e', 0x30f1},
1365 {'W', 'o', 0x30f2},
1366 {'N', '6', 0x30f3},
1367 {'V', 'u', 0x30f4},
1368 {'K', 'A', 0x30f5},
1369 {'K', 'E', 0x30f6},
1370 {'V', 'a', 0x30f7},
1371 {'V', 'i', 0x30f8},
1372 {'V', 'e', 0x30f9},
1373 {'V', 'o', 0x30fa},
1374 {'.', '6', 0x30fb},
1375 {'-', '6', 0x30fc},
1376 {'*', '6', 0x30fd},
1377 {'+', '6', 0x30fe},
Bram Moolenaare3f915d2020-07-14 23:02:44 +02001378# define DG_START_BOPOMOFO 0x3105
Bram Moolenaar071d4272004-06-13 20:20:40 +00001379 {'b', '4', 0x3105},
1380 {'p', '4', 0x3106},
1381 {'m', '4', 0x3107},
1382 {'f', '4', 0x3108},
1383 {'d', '4', 0x3109},
1384 {'t', '4', 0x310a},
1385 {'n', '4', 0x310b},
1386 {'l', '4', 0x310c},
1387 {'g', '4', 0x310d},
1388 {'k', '4', 0x310e},
1389 {'h', '4', 0x310f},
1390 {'j', '4', 0x3110},
1391 {'q', '4', 0x3111},
1392 {'x', '4', 0x3112},
1393 {'z', 'h', 0x3113},
1394 {'c', 'h', 0x3114},
1395 {'s', 'h', 0x3115},
1396 {'r', '4', 0x3116},
1397 {'z', '4', 0x3117},
1398 {'c', '4', 0x3118},
1399 {'s', '4', 0x3119},
1400 {'a', '4', 0x311a},
1401 {'o', '4', 0x311b},
1402 {'e', '4', 0x311c},
1403 {'a', 'i', 0x311e},
1404 {'e', 'i', 0x311f},
1405 {'a', 'u', 0x3120},
1406 {'o', 'u', 0x3121},
1407 {'a', 'n', 0x3122},
1408 {'e', 'n', 0x3123},
1409 {'a', 'N', 0x3124},
1410 {'e', 'N', 0x3125},
1411 {'e', 'r', 0x3126},
1412 {'i', '4', 0x3127},
1413 {'u', '4', 0x3128},
1414 {'i', 'u', 0x3129},
1415 {'v', '4', 0x312a},
1416 {'n', 'G', 0x312b},
1417 {'g', 'n', 0x312c},
Bram Moolenaare3f915d2020-07-14 23:02:44 +02001418# define DG_START_OTHER3 0x3220
Bram Moolenaar071d4272004-06-13 20:20:40 +00001419 {'1', 'c', 0x3220},
1420 {'2', 'c', 0x3221},
1421 {'3', 'c', 0x3222},
1422 {'4', 'c', 0x3223},
1423 {'5', 'c', 0x3224},
1424 {'6', 'c', 0x3225},
1425 {'7', 'c', 0x3226},
1426 {'8', 'c', 0x3227},
1427 {'9', 'c', 0x3228},
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01001428 // code points 0xe000 - 0xefff excluded, they have no assigned
1429 // characters, only used in proposals.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001430 {'f', 'f', 0xfb00},
1431 {'f', 'i', 0xfb01},
1432 {'f', 'l', 0xfb02},
1433 {'f', 't', 0xfb05},
1434 {'s', 't', 0xfb06},
Bram Moolenaar5f91c0c2008-01-03 16:54:33 +00001435
Bram Moolenaare27d6e62022-08-30 15:05:30 +01001436 {NUL, NUL, NUL} // end marker
1437};
Bram Moolenaar071d4272004-06-13 20:20:40 +00001438
1439/*
1440 * handle digraphs after typing a character
1441 */
1442 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001443do_digraph(int c)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001444{
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01001445 static int backspaced; // character before K_BS
1446 static int lastchar; // last typed character
Bram Moolenaar071d4272004-06-13 20:20:40 +00001447
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01001448 if (c == -1) // init values
Bram Moolenaar071d4272004-06-13 20:20:40 +00001449 {
1450 backspaced = -1;
1451 }
1452 else if (p_dg)
1453 {
1454 if (backspaced >= 0)
h-east29b85712021-07-26 21:54:04 +02001455 c = digraph_get(backspaced, c, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001456 backspaced = -1;
1457 if ((c == K_BS || c == Ctrl_H) && lastchar >= 0)
1458 backspaced = lastchar;
1459 }
1460 lastchar = c;
1461 return c;
1462}
1463
1464/*
Bram Moolenaar5f73ef82018-02-27 21:09:30 +01001465 * Find a digraph for "val". If found return the string to display it.
1466 * If not found return NULL.
1467 */
1468 char_u *
Bram Moolenaarbc5020a2018-06-16 17:25:22 +02001469get_digraph_for_char(int val_arg)
Bram Moolenaar5f73ef82018-02-27 21:09:30 +01001470{
Bram Moolenaarbc5020a2018-06-16 17:25:22 +02001471 int val = val_arg;
Bram Moolenaar5f73ef82018-02-27 21:09:30 +01001472 int i;
1473 int use_defaults;
1474 digr_T *dp;
1475 static char_u r[3];
1476
Bram Moolenaareae8ae12018-12-14 18:53:02 +01001477#if defined(USE_UNICODE_DIGRAPHS)
Bram Moolenaarbc5020a2018-06-16 17:25:22 +02001478 if (!enc_utf8)
1479 {
1480 char_u buf[6], *to;
1481 vimconv_T vc;
1482
1483 // convert the character from 'encoding' to Unicode
1484 i = mb_char2bytes(val, buf);
1485 vc.vc_type = CONV_NONE;
1486 if (convert_setup(&vc, p_enc, (char_u *)"utf-8") == OK)
1487 {
1488 vc.vc_fail = TRUE;
1489 to = string_convert(&vc, buf, &i);
1490 if (to != NULL)
1491 {
1492 val = utf_ptr2char(to);
1493 vim_free(to);
1494 }
1495 (void)convert_setup(&vc, NULL, NULL);
1496 }
1497 }
1498#endif
1499
Bram Moolenaar5f73ef82018-02-27 21:09:30 +01001500 for (use_defaults = 0; use_defaults <= 1; use_defaults++)
1501 {
1502 if (use_defaults == 0)
1503 dp = (digr_T *)user_digraphs.ga_data;
1504 else
1505 dp = digraphdefault;
1506 for (i = 0; use_defaults ? dp->char1 != NUL
1507 : i < user_digraphs.ga_len; ++i)
1508 {
1509 if (dp->result == val)
1510 {
1511 r[0] = dp->char1;
1512 r[1] = dp->char2;
1513 r[2] = NUL;
1514 return r;
1515 }
1516 ++dp;
1517 }
1518 }
1519 return NULL;
1520}
1521
1522/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00001523 * Get a digraph. Used after typing CTRL-K on the command line or in normal
1524 * mode.
1525 * Returns composed character, or NUL when ESC was used.
1526 */
1527 int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001528get_digraph(
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01001529 int cmdline) // TRUE when called from the cmdline
Bram Moolenaar071d4272004-06-13 20:20:40 +00001530{
1531 int c, cc;
1532
1533 ++no_mapping;
1534 ++allow_keys;
Bram Moolenaar61abfd12007-09-13 16:26:47 +00001535 c = plain_vgetc();
Bram Moolenaar071d4272004-06-13 20:20:40 +00001536 --no_mapping;
1537 --allow_keys;
Yegappan Lakshmanan1cfb14a2023-01-09 19:04:23 +00001538
1539 if (c == ESC) // ESC cancels CTRL-K
1540 return NUL;
1541
1542 if (IS_SPECIAL(c)) // insert special key code
1543 return c;
1544 if (cmdline)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001545 {
Yegappan Lakshmanan1cfb14a2023-01-09 19:04:23 +00001546 if (char2cells(c) == 1
Bram Moolenaar071d4272004-06-13 20:20:40 +00001547#if defined(FEAT_CRYPT) || defined(FEAT_EVAL)
Yegappan Lakshmanan1cfb14a2023-01-09 19:04:23 +00001548 && cmdline_star == 0
Bram Moolenaar071d4272004-06-13 20:20:40 +00001549#endif
Yegappan Lakshmanan1cfb14a2023-01-09 19:04:23 +00001550 )
1551 putcmdline(c, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001552 }
Yegappan Lakshmanan1cfb14a2023-01-09 19:04:23 +00001553 else
1554 add_to_showcmd(c);
1555 ++no_mapping;
1556 ++allow_keys;
1557 cc = plain_vgetc();
1558 --no_mapping;
1559 --allow_keys;
1560 if (cc != ESC) // ESC cancels CTRL-K
1561 return digraph_get(c, cc, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001562 return NUL;
1563}
1564
1565/*
1566 * Lookup the pair "char1", "char2" in the digraph tables.
1567 * If no match, return "char2".
Bram Moolenaar70b2a562012-01-10 22:26:17 +01001568 * If "meta_char" is TRUE and "char1" is a space, return "char2" | 0x80.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001569 */
1570 static int
Bram Moolenaar7454a062016-01-30 15:14:10 +01001571getexactdigraph(int char1, int char2, int meta_char)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001572{
1573 int i;
1574 int retval = 0;
1575 digr_T *dp;
1576
1577 if (IS_SPECIAL(char1) || IS_SPECIAL(char2))
1578 return char2;
1579
1580 /*
1581 * Search user digraphs first.
1582 */
1583 dp = (digr_T *)user_digraphs.ga_data;
1584 for (i = 0; i < user_digraphs.ga_len; ++i)
1585 {
1586 if ((int)dp->char1 == char1 && (int)dp->char2 == char2)
1587 {
1588 retval = dp->result;
1589 break;
1590 }
1591 ++dp;
1592 }
1593
1594 /*
1595 * Search default digraphs.
1596 */
1597 if (retval == 0)
1598 {
1599 dp = digraphdefault;
dundargocb2209f22022-09-24 15:55:27 +01001600 while (dp->char1 != 0)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001601 {
1602 if ((int)dp->char1 == char1 && (int)dp->char2 == char2)
1603 {
1604 retval = dp->result;
1605 break;
1606 }
1607 ++dp;
1608 }
1609 }
Bram Moolenaar13505972019-01-24 15:04:48 +01001610#ifdef USE_UNICODE_DIGRAPHS
Bram Moolenaar071d4272004-06-13 20:20:40 +00001611 if (retval != 0 && !enc_utf8)
1612 {
1613 char_u buf[6], *to;
1614 vimconv_T vc;
1615
1616 /*
1617 * Convert the Unicode digraph to 'encoding'.
1618 */
1619 i = utf_char2bytes(retval, buf);
1620 retval = 0;
1621 vc.vc_type = CONV_NONE;
1622 if (convert_setup(&vc, (char_u *)"utf-8", p_enc) == OK)
1623 {
1624 vc.vc_fail = TRUE;
1625 to = string_convert(&vc, buf, &i);
1626 if (to != NULL)
1627 {
1628 retval = (*mb_ptr2char)(to);
1629 vim_free(to);
1630 }
1631 (void)convert_setup(&vc, NULL, NULL);
1632 }
1633 }
Bram Moolenaar13505972019-01-24 15:04:48 +01001634#endif
Bram Moolenaar071d4272004-06-13 20:20:40 +00001635
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01001636 // Ignore multi-byte characters when not in multi-byte mode.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001637 if (!has_mbyte && retval > 0xff)
1638 retval = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001639
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01001640 if (retval == 0) // digraph deleted or not found
Bram Moolenaar071d4272004-06-13 20:20:40 +00001641 {
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01001642 if (char1 == ' ' && meta_char) // <space> <char> --> meta-char
Bram Moolenaar071d4272004-06-13 20:20:40 +00001643 return (char2 | 0x80);
1644 return char2;
1645 }
1646 return retval;
1647}
1648
1649/*
1650 * Get digraph.
1651 * Allow for both char1-char2 and char2-char1
1652 */
1653 int
h-east29b85712021-07-26 21:54:04 +02001654digraph_get(int char1, int char2, int meta_char)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001655{
1656 int retval;
1657
Bram Moolenaar70b2a562012-01-10 22:26:17 +01001658 if (((retval = getexactdigraph(char1, char2, meta_char)) == char2)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001659 && (char1 != char2)
Bram Moolenaar70b2a562012-01-10 22:26:17 +01001660 && ((retval = getexactdigraph(char2, char1, meta_char)) == char1))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001661 return char2;
1662 return retval;
1663}
1664
1665/*
mityu61065042021-07-19 20:07:21 +02001666 * Add a digraph to the digraph table.
1667 */
1668 static void
1669registerdigraph(int char1, int char2, int n)
1670{
1671 int i;
1672 digr_T *dp;
1673
1674 // If the digraph already exists, replace "result".
1675 dp = (digr_T *)user_digraphs.ga_data;
1676 for (i = 0; i < user_digraphs.ga_len; ++i)
1677 {
1678 if ((int)dp->char1 == char1 && (int)dp->char2 == char2)
1679 {
1680 dp->result = n;
1681 return;
1682 }
1683 ++dp;
1684 }
1685
1686 // Add a new digraph to the table.
Yegappan Lakshmananfadc02a2023-01-27 21:03:12 +00001687 if (ga_grow(&user_digraphs, 1) == FAIL)
Yegappan Lakshmanan465de3a2022-12-26 12:50:04 +00001688 return;
1689
1690 dp = (digr_T *)user_digraphs.ga_data + user_digraphs.ga_len;
1691 dp->char1 = char1;
1692 dp->char2 = char2;
1693 dp->result = n;
1694 ++user_digraphs.ga_len;
mityu61065042021-07-19 20:07:21 +02001695}
1696
1697/*
1698 * Check the characters are valid for a digraph.
1699 * If they are valid, returns TRUE; otherwise, give an error message and
1700 * returns FALSE.
1701 */
Yegappan Lakshmanan8ee52af2021-08-09 19:59:06 +02001702 static int
mityu61065042021-07-19 20:07:21 +02001703check_digraph_chars_valid(int char1, int char2)
1704{
1705 if (char2 == 0)
1706 {
1707 char_u msg[MB_MAXBYTES + 1];
1708
1709 msg[mb_char2bytes(char1, msg)] = NUL;
1710
1711 semsg(_(e_digraph_must_be_just_two_characters_str), msg);
1712 return FALSE;
1713 }
1714 if (char1 == ESC || char2 == ESC)
1715 {
Bram Moolenaare1242042021-12-16 20:56:57 +00001716 emsg(_(e_escape_not_allowed_in_digraph));
mityu61065042021-07-19 20:07:21 +02001717 return FALSE;
1718 }
1719 return TRUE;
1720}
1721
1722
1723
1724/*
Bram Moolenaar071d4272004-06-13 20:20:40 +00001725 * Add the digraphs in the argument to the digraph table.
1726 * format: {c1}{c2} char {c1}{c2} char ...
1727 */
1728 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01001729putdigraph(char_u *str)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001730{
1731 int char1, char2, n;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001732
1733 while (*str != NUL)
1734 {
1735 str = skipwhite(str);
1736 if (*str == NUL)
1737 return;
1738 char1 = *str++;
1739 char2 = *str++;
mityu61065042021-07-19 20:07:21 +02001740
1741 if (!check_digraph_chars_valid(char1, char2))
Bram Moolenaar071d4272004-06-13 20:20:40 +00001742 return;
mityu61065042021-07-19 20:07:21 +02001743
Bram Moolenaar071d4272004-06-13 20:20:40 +00001744 str = skipwhite(str);
1745 if (!VIM_ISDIGIT(*str))
1746 {
Bram Moolenaare29a27f2021-07-20 21:07:36 +02001747 emsg(_(e_number_expected));
Bram Moolenaar071d4272004-06-13 20:20:40 +00001748 return;
1749 }
1750 n = getdigits(&str);
1751
mityu61065042021-07-19 20:07:21 +02001752 registerdigraph(char1, char2, n);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001753 }
1754}
1755
Bram Moolenaareae8ae12018-12-14 18:53:02 +01001756#if defined(USE_UNICODE_DIGRAPHS)
1757 static void
1758digraph_header(char *msg)
1759{
1760 if (msg_col > 0)
1761 msg_putchar('\n');
1762 msg_outtrans_attr((char_u *)msg, HL_ATTR(HLF_CM));
1763 msg_putchar('\n');
1764}
1765#endif
1766
Bram Moolenaar071d4272004-06-13 20:20:40 +00001767 void
Bram Moolenaareae8ae12018-12-14 18:53:02 +01001768listdigraphs(int use_headers)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001769{
1770 int i;
1771 digr_T *dp;
Bram Moolenaareae8ae12018-12-14 18:53:02 +01001772 result_T previous = 0;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001773
1774 msg_putchar('\n');
1775
1776 dp = digraphdefault;
dundargocb2209f22022-09-24 15:55:27 +01001777 while (dp->char1 != NUL && !got_int)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001778 {
Bram Moolenaareae8ae12018-12-14 18:53:02 +01001779#if defined(USE_UNICODE_DIGRAPHS)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001780 digr_T tmp;
1781
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01001782 // May need to convert the result to 'encoding'.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001783 tmp.char1 = dp->char1;
1784 tmp.char2 = dp->char2;
1785 tmp.result = getexactdigraph(tmp.char1, tmp.char2, FALSE);
1786 if (tmp.result != 0 && tmp.result != tmp.char2
1787 && (has_mbyte || tmp.result <= 255))
Bram Moolenaareae8ae12018-12-14 18:53:02 +01001788 printdigraph(&tmp, use_headers ? &previous : NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001789#else
1790
1791 if (getexactdigraph(dp->char1, dp->char2, FALSE) == dp->result
Bram Moolenaar13505972019-01-24 15:04:48 +01001792 && (has_mbyte || dp->result <= 255))
Bram Moolenaareae8ae12018-12-14 18:53:02 +01001793 printdigraph(dp, use_headers ? &previous : NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001794#endif
1795 ++dp;
1796 ui_breakcheck();
1797 }
1798
1799 dp = (digr_T *)user_digraphs.ga_data;
1800 for (i = 0; i < user_digraphs.ga_len && !got_int; ++i)
1801 {
Bram Moolenaareae8ae12018-12-14 18:53:02 +01001802#if defined(USE_UNICODE_DIGRAPHS)
1803 if (previous >= 0 && use_headers)
1804 digraph_header(_("Custom"));
1805 previous = -1;
1806#endif
1807 printdigraph(dp, NULL);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001808 ui_breakcheck();
1809 ++dp;
1810 }
Bram Moolenaara4d158b2022-08-14 14:17:45 +01001811
1812 // clear screen, because some digraphs may be wrong, in which case we
1813 // messed up ScreenLines
Bram Moolenaar471c0fa2022-08-22 15:19:16 +01001814 set_must_redraw(UPD_CLEAR);
Bram Moolenaar071d4272004-06-13 20:20:40 +00001815}
1816
mityu61065042021-07-19 20:07:21 +02001817 static void
h-east29b85712021-07-26 21:54:04 +02001818digraph_getlist_appendpair(digr_T *dp, list_T *l)
mityu61065042021-07-19 20:07:21 +02001819{
1820 char_u buf[30];
1821 char_u *p;
1822 list_T *l2;
1823 listitem_T *li, *li2;
1824
1825
1826 li = listitem_alloc();
1827 if (li == NULL)
1828 return;
1829 list_append(l, li);
1830 li->li_tv.v_type = VAR_LIST;
1831 li->li_tv.v_lock = 0;
1832
1833 l2 = list_alloc();
1834 li->li_tv.vval.v_list = l2;
1835 if (l2 == NULL)
1836 return;
1837 ++l2->lv_refcount;
1838
1839 li2 = listitem_alloc();
1840 if (li2 == NULL)
1841 return;
1842 list_append(l2, li2);
1843 li2->li_tv.v_type = VAR_STRING;
1844 li2->li_tv.v_lock = 0;
1845
1846 buf[0] = dp->char1;
1847 buf[1] = dp->char2;
1848 buf[2] = NUL;
1849 li2->li_tv.vval.v_string = vim_strsave(&buf[0]);
1850
1851 li2 = listitem_alloc();
1852 if (li2 == NULL)
1853 return;
1854 list_append(l2, li2);
1855 li2->li_tv.v_type = VAR_STRING;
1856 li2->li_tv.v_lock = 0;
1857
1858 p = buf;
1859 if (has_mbyte)
1860 p += (*mb_char2bytes)(dp->result, p);
1861 else
1862 *p++ = (char_u)dp->result;
1863 *p = NUL;
1864
1865 li2->li_tv.vval.v_string = vim_strsave(buf);
1866}
1867
Yegappan Lakshmanan8ee52af2021-08-09 19:59:06 +02001868 static void
h-east29b85712021-07-26 21:54:04 +02001869digraph_getlist_common(int list_all, typval_T *rettv)
mityu61065042021-07-19 20:07:21 +02001870{
1871 int i;
1872 digr_T *dp;
1873
1874 if (rettv_list_alloc(rettv) == FAIL)
1875 return;
1876
1877 if (list_all)
1878 {
1879 dp = digraphdefault;
dundargocb2209f22022-09-24 15:55:27 +01001880 while (dp->char1 != NUL && !got_int)
mityu61065042021-07-19 20:07:21 +02001881 {
1882#ifdef USE_UNICODE_DIGRAPHS
1883 digr_T tmp;
1884
1885 tmp.char1 = dp->char1;
1886 tmp.char2 = dp->char2;
1887 tmp.result = getexactdigraph(tmp.char1, tmp.char2, FALSE);
1888 if (tmp.result != 0 && tmp.result != tmp.char2
1889 && (has_mbyte || tmp.result <= 255))
h-east29b85712021-07-26 21:54:04 +02001890 digraph_getlist_appendpair(&tmp, rettv->vval.v_list);
mityu61065042021-07-19 20:07:21 +02001891#else
1892 if (getexactdigraph(dp->char1, dp->char2, FALSE) == dp->result
1893 && (has_mbyte || dp->result <= 255))
h-east29b85712021-07-26 21:54:04 +02001894 digraph_getlist_appendpair(dp, rettv->vval.v_list);
mityu61065042021-07-19 20:07:21 +02001895#endif
1896 ++dp;
1897 }
1898 }
1899
1900 dp = (digr_T *)user_digraphs.ga_data;
1901 for (i = 0; i < user_digraphs.ga_len && !got_int; ++i)
1902 {
h-east29b85712021-07-26 21:54:04 +02001903 digraph_getlist_appendpair(dp, rettv->vval.v_list);
mityu61065042021-07-19 20:07:21 +02001904 ++dp;
1905 }
1906}
1907
Bram Moolenaar5843f5f2019-08-20 20:13:45 +02001908static struct dg_header_entry {
Bram Moolenaareae8ae12018-12-14 18:53:02 +01001909 int dg_start;
1910 char *dg_header;
1911} header_table[] = {
1912 {DG_START_LATIN, N_("Latin supplement")},
1913 {DG_START_GREEK, N_("Greek and Coptic")},
1914 {DG_START_CYRILLIC, N_("Cyrillic")},
1915 {DG_START_HEBREW, N_("Hebrew")},
1916 {DG_START_ARABIC, N_("Arabic")},
1917 {DG_START_LATIN_EXTENDED, N_("Latin extended")},
1918 {DG_START_GREEK_EXTENDED, N_("Greek extended")},
1919 {DG_START_PUNCTUATION, N_("Punctuation")},
1920 {DG_START_SUB_SUPER, N_("Super- and subscripts")},
1921 {DG_START_CURRENCY, N_("Currency")},
1922 {DG_START_OTHER1, N_("Other")},
1923 {DG_START_ROMAN, N_("Roman numbers")},
1924 {DG_START_ARROWS, N_("Arrows")},
1925 {DG_START_MATH, N_("Mathematical operators")},
1926 {DG_START_TECHNICAL, N_("Technical")},
1927 {DG_START_OTHER2, N_("Other")},
1928 {DG_START_DRAWING, N_("Box drawing")},
1929 {DG_START_BLOCK, N_("Block elements")},
1930 {DG_START_SHAPES, N_("Geometric shapes")},
1931 {DG_START_SYMBOLS, N_("Symbols")},
1932 {DG_START_DINGBATS, N_("Dingbats")},
1933 {DG_START_CJK_SYMBOLS, N_("CJK symbols and punctuation")},
1934 {DG_START_HIRAGANA, N_("Hiragana")},
1935 {DG_START_KATAKANA, N_("Katakana")},
1936 {DG_START_BOPOMOFO, N_("Bopomofo")},
1937 {DG_START_OTHER3, N_("Other")},
1938 {0xfffffff, NULL},
1939};
1940
Bram Moolenaar071d4272004-06-13 20:20:40 +00001941 static void
Bram Moolenaareae8ae12018-12-14 18:53:02 +01001942printdigraph(digr_T *dp, result_T *previous)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001943{
1944 char_u buf[30];
1945 char_u *p;
1946
1947 int list_width;
1948
Bram Moolenaar13505972019-01-24 15:04:48 +01001949 if ((dy_flags & DY_UHEX) || has_mbyte)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001950 list_width = 13;
1951 else
1952 list_width = 11;
1953
Yegappan Lakshmanan465de3a2022-12-26 12:50:04 +00001954 if (dp->result == 0)
1955 return;
1956
Bram Moolenaareae8ae12018-12-14 18:53:02 +01001957#if defined(USE_UNICODE_DIGRAPHS)
Yegappan Lakshmanan465de3a2022-12-26 12:50:04 +00001958 if (previous != NULL)
1959 {
1960 int i;
Bram Moolenaareae8ae12018-12-14 18:53:02 +01001961
Yegappan Lakshmanan465de3a2022-12-26 12:50:04 +00001962 for (i = 0; header_table[i].dg_header != NULL; ++i)
1963 if (*previous < header_table[i].dg_start
1964 && dp->result >= header_table[i].dg_start
1965 && dp->result < header_table[i + 1].dg_start)
1966 {
1967 digraph_header(_(header_table[i].dg_header));
1968 break;
1969 }
1970 *previous = dp->result;
Bram Moolenaar071d4272004-06-13 20:20:40 +00001971 }
Yegappan Lakshmanan465de3a2022-12-26 12:50:04 +00001972#endif
1973 if (msg_col > Columns - list_width)
1974 msg_putchar('\n');
1975 if (msg_col)
1976 while (msg_col % list_width != 0)
1977 msg_putchar(' ');
1978
1979 p = buf;
1980 *p++ = dp->char1;
1981 *p++ = dp->char2;
1982 *p++ = ' ';
1983 *p = NUL;
1984 msg_outtrans(buf);
1985 p = buf;
1986 if (has_mbyte)
1987 {
1988 // add a space to draw a composing char on
1989 if (enc_utf8 && utf_iscomposing(dp->result))
1990 *p++ = ' ';
1991 p += (*mb_char2bytes)(dp->result, p);
1992 }
1993 else
1994 *p++ = (char_u)dp->result;
1995 *p = NUL;
1996 msg_outtrans_attr(buf, HL_ATTR(HLF_8));
1997 p = buf;
1998 if (char2cells(dp->result) == 1)
1999 *p++ = ' ';
2000 vim_snprintf((char *)p, sizeof(buf) - (p - buf), " %3d", dp->result);
2001 msg_outtrans(buf);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002002}
2003
mityu61065042021-07-19 20:07:21 +02002004# ifdef FEAT_EVAL
2005/*
2006 * Get the two digraph characters from a typval.
2007 * Return OK or FAIL.
2008 */
2009 static int
2010get_digraph_chars(typval_T *arg, int *char1, int *char2)
2011{
2012 char_u buf_chars[NUMBUFLEN];
2013 char_u *chars = tv_get_string_buf_chk(arg, buf_chars);
2014 char_u *p = chars;
2015
2016 if (p != NULL)
2017 {
2018 if (*p != NUL)
2019 {
2020 *char1 = mb_cptr2char_adv(&p);
2021 if (*p != NUL)
2022 {
2023 *char2 = mb_cptr2char_adv(&p);
2024 if (*p == NUL)
2025 {
2026 if (check_digraph_chars_valid(*char1, *char2))
2027 return OK;
2028 return FAIL;
2029 }
2030 }
2031 }
2032 }
2033 semsg(_(e_digraph_must_be_just_two_characters_str), chars);
2034 return FAIL;
2035}
2036
2037 static int
h-east29b85712021-07-26 21:54:04 +02002038digraph_set_common(typval_T *argchars, typval_T *argdigraph)
mityu61065042021-07-19 20:07:21 +02002039{
2040 int char1, char2;
2041 char_u *digraph;
2042 char_u *p;
2043 char_u buf_digraph[NUMBUFLEN];
2044 varnumber_T n;
2045
2046 if (get_digraph_chars(argchars, &char1, &char2) == FAIL)
2047 return FALSE;
2048
2049 digraph = tv_get_string_buf_chk(argdigraph, buf_digraph);
2050 if (digraph == NULL)
2051 return FALSE;
2052 p = digraph;
2053 n = mb_cptr2char_adv(&p);
2054 if (*p != NUL)
2055 {
2056 semsg(_(e_digraph_argument_must_be_one_character_str), digraph);
2057 return FALSE;
2058 }
2059
2060 registerdigraph(char1, char2, (int)n);
2061 return TRUE;
2062}
2063# endif
2064
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01002065#endif // FEAT_DIGRAPHS
Bram Moolenaar071d4272004-06-13 20:20:40 +00002066
mityu61065042021-07-19 20:07:21 +02002067#if defined(FEAT_EVAL) || defined(PROTO)
2068/*
h-east29b85712021-07-26 21:54:04 +02002069 * "digraph_get()" function
mityu61065042021-07-19 20:07:21 +02002070 */
2071 void
h-east29b85712021-07-26 21:54:04 +02002072f_digraph_get(typval_T *argvars, typval_T *rettv)
mityu61065042021-07-19 20:07:21 +02002073{
2074# ifdef FEAT_DIGRAPHS
2075 int code;
2076 char_u buf[NUMBUFLEN];
2077 char_u *digraphs;
2078
2079 rettv->v_type = VAR_STRING;
2080 rettv->vval.v_string = NULL; // Return empty string for failure
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02002081
2082 if (in_vim9script() && check_for_string_arg(argvars, 0) == FAIL)
2083 return;
2084
mityu61065042021-07-19 20:07:21 +02002085 digraphs = tv_get_string_chk(&argvars[0]);
2086
2087 if (digraphs == NULL)
2088 return;
2089 else if (STRLEN(digraphs) != 2)
2090 {
2091 semsg(_(e_digraph_must_be_just_two_characters_str), digraphs);
2092 return;
2093 }
h-east29b85712021-07-26 21:54:04 +02002094 code = digraph_get(digraphs[0], digraphs[1], FALSE);
mityu61065042021-07-19 20:07:21 +02002095
2096 if (has_mbyte)
2097 buf[(*mb_char2bytes)(code, buf)] = NUL;
Bram Moolenaarebfec1c2023-01-22 21:14:53 +00002098 else
2099 {
mityu61065042021-07-19 20:07:21 +02002100 buf[0] = code;
2101 buf[1] = NUL;
2102 }
2103
2104 rettv->vval.v_string = vim_strsave(buf);
2105# else
2106 emsg(_(e_no_digraphs_version));
2107# endif
2108}
2109
2110/*
h-east29b85712021-07-26 21:54:04 +02002111 * "digraph_getlist()" function
mityu61065042021-07-19 20:07:21 +02002112 */
2113 void
h-east29b85712021-07-26 21:54:04 +02002114f_digraph_getlist(typval_T *argvars, typval_T *rettv)
mityu61065042021-07-19 20:07:21 +02002115{
2116# ifdef FEAT_DIGRAPHS
2117 int flag_list_all;
2118
Yegappan Lakshmanan198ada32024-12-02 19:58:51 +01002119 if (check_for_opt_bool_arg(argvars, 0) == FAIL)
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02002120 return;
2121
mityu61065042021-07-19 20:07:21 +02002122 if (argvars[0].v_type == VAR_UNKNOWN)
2123 flag_list_all = FALSE;
2124 else
2125 {
Yegappan Lakshmanan198ada32024-12-02 19:58:51 +01002126 varnumber_T flag = tv_get_bool(&argvars[0]);
Bram Moolenaar6ed545e2022-05-09 20:09:23 +01002127
mityu61065042021-07-19 20:07:21 +02002128 flag_list_all = flag ? TRUE : FALSE;
2129 }
2130
h-east29b85712021-07-26 21:54:04 +02002131 digraph_getlist_common(flag_list_all, rettv);
mityu61065042021-07-19 20:07:21 +02002132# else
2133 emsg(_(e_no_digraphs_version));
2134# endif
2135}
2136
2137/*
h-east29b85712021-07-26 21:54:04 +02002138 * "digraph_set()" function
mityu61065042021-07-19 20:07:21 +02002139 */
2140 void
h-east29b85712021-07-26 21:54:04 +02002141f_digraph_set(typval_T *argvars, typval_T *rettv)
mityu61065042021-07-19 20:07:21 +02002142{
2143# ifdef FEAT_DIGRAPHS
2144 rettv->v_type = VAR_BOOL;
2145 rettv->vval.v_number = VVAL_FALSE;
2146
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02002147 if (in_vim9script()
2148 && (check_for_string_arg(argvars, 0) == FAIL
Yegappan Lakshmananfc3b7752021-09-08 14:57:42 +02002149 || check_for_string_arg(argvars, 1) == FAIL))
Yegappan Lakshmanan4490ec42021-07-27 22:00:44 +02002150 return;
2151
h-east29b85712021-07-26 21:54:04 +02002152 if (!digraph_set_common(&argvars[0], &argvars[1]))
mityu61065042021-07-19 20:07:21 +02002153 return;
2154
2155 rettv->vval.v_number = VVAL_TRUE;
2156# else
2157 emsg(_(e_no_digraphs_version));
2158# endif
2159}
2160
2161/*
h-east29b85712021-07-26 21:54:04 +02002162 * "digraph_setlist()" function
mityu61065042021-07-19 20:07:21 +02002163 */
2164 void
h-east29b85712021-07-26 21:54:04 +02002165f_digraph_setlist(typval_T * argvars, typval_T *rettv)
mityu61065042021-07-19 20:07:21 +02002166{
2167# ifdef FEAT_DIGRAPHS
2168 list_T *pl, *l;
2169 listitem_T *pli;
2170
2171 rettv->v_type = VAR_BOOL;
2172 rettv->vval.v_number = VVAL_FALSE;
2173
2174 if (argvars[0].v_type != VAR_LIST)
2175 {
h-east29b85712021-07-26 21:54:04 +02002176 emsg(_(e_digraph_setlist_argument_must_be_list_of_lists_with_two_items));
mityu61065042021-07-19 20:07:21 +02002177 return;
2178 }
2179
2180 pl = argvars[0].vval.v_list;
2181 if (pl == NULL)
2182 {
2183 // Empty list always results in success.
2184 rettv->vval.v_number = VVAL_TRUE;
2185 return;
2186 }
2187
2188 FOR_ALL_LIST_ITEMS(pl, pli)
2189 {
2190 if (pli->li_tv.v_type != VAR_LIST)
2191 {
h-east29b85712021-07-26 21:54:04 +02002192 emsg(_(e_digraph_setlist_argument_must_be_list_of_lists_with_two_items));
mityu61065042021-07-19 20:07:21 +02002193 return;
2194 }
2195
2196 l = pli->li_tv.vval.v_list;
2197 if (l == NULL || l->lv_len != 2)
2198 {
h-east29b85712021-07-26 21:54:04 +02002199 emsg(_(e_digraph_setlist_argument_must_be_list_of_lists_with_two_items));
mityu61065042021-07-19 20:07:21 +02002200 return;
2201 }
2202
h-east29b85712021-07-26 21:54:04 +02002203 if (!digraph_set_common(&l->lv_first->li_tv,
mityu61065042021-07-19 20:07:21 +02002204 &l->lv_first->li_next->li_tv))
2205 return;
2206 }
2207 rettv->vval.v_number = VVAL_TRUE;
2208# else
2209 emsg(_(e_no_digraphs_version));
2210# endif
2211}
2212
2213#endif // FEAT_EVAL
2214
2215
Bram Moolenaar071d4272004-06-13 20:20:40 +00002216#if defined(FEAT_KEYMAP) || defined(PROTO)
2217
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01002218// structure used for b_kmap_ga.ga_data
Bram Moolenaar071d4272004-06-13 20:20:40 +00002219typedef struct
2220{
2221 char_u *from;
2222 char_u *to;
2223} kmap_T;
2224
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01002225#define KMAP_MAXLEN 20 // maximum length of "from" or "to"
Bram Moolenaar071d4272004-06-13 20:20:40 +00002226
Bram Moolenaarf28dbce2016-01-29 22:03:47 +01002227static void keymap_unload(void);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002228
2229/*
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00002230 * Set up key mapping tables for the 'keymap' option.
2231 * Returns NULL if OK, an error message for failure. This only needs to be
2232 * used when setting the option, not later when the value has already been
2233 * checked.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002234 */
Bram Moolenaarf9e3e092019-01-13 23:38:42 +01002235 char *
Bram Moolenaar7454a062016-01-30 15:14:10 +01002236keymap_init(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002237{
2238 curbuf->b_kmap_state &= ~KEYMAP_INIT;
2239
2240 if (*curbuf->b_p_keymap == NUL)
2241 {
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01002242 // Stop any active keymap and clear the table. Also remove
2243 // b:keymap_name, as no keymap is active now.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002244 keymap_unload();
Bram Moolenaarbf444172007-07-07 11:58:28 +00002245 do_cmdline_cmd((char_u *)"unlet! b:keymap_name");
Bram Moolenaar071d4272004-06-13 20:20:40 +00002246 }
2247 else
2248 {
2249 char_u *buf;
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00002250 size_t buflen;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002251
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01002252 // Source the keymap file. It will contain a ":loadkeymap" command
2253 // which will call ex_loadkeymap() below.
Bram Moolenaar13505972019-01-24 15:04:48 +01002254 buflen = STRLEN(curbuf->b_p_keymap) + STRLEN(p_enc) + 14;
Bram Moolenaar964b3742019-05-24 18:54:09 +02002255 buf = alloc(buflen);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002256 if (buf == NULL)
Bram Moolenaare29a27f2021-07-20 21:07:36 +02002257 return e_out_of_memory;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002258
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01002259 // try finding "keymap/'keymap'_'encoding'.vim" in 'runtimepath'
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00002260 vim_snprintf((char *)buf, buflen, "keymap/%s_%s.vim",
2261 curbuf->b_p_keymap, p_enc);
Bram Moolenaar7f8989d2016-03-12 22:11:39 +01002262 if (source_runtime(buf, 0) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002263 {
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01002264 // try finding "keymap/'keymap'.vim" in 'runtimepath'
Bram Moolenaar0ab2a882009-05-13 10:51:08 +00002265 vim_snprintf((char *)buf, buflen, "keymap/%s.vim",
2266 curbuf->b_p_keymap);
Bram Moolenaar7f8989d2016-03-12 22:11:39 +01002267 if (source_runtime(buf, 0) == FAIL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002268 {
2269 vim_free(buf);
Bram Moolenaar1d423ef2022-01-02 21:26:16 +00002270 return N_(e_keymap_file_not_found);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002271 }
2272 }
2273 vim_free(buf);
2274 }
2275
2276 return NULL;
2277}
2278
2279/*
2280 * ":loadkeymap" command: load the following lines as the keymap.
2281 */
2282 void
Bram Moolenaar7454a062016-01-30 15:14:10 +01002283ex_loadkeymap(exarg_T *eap)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002284{
2285 char_u *line;
2286 char_u *p;
2287 char_u *s;
2288 kmap_T *kp;
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01002289#define KMAP_LLEN 200 // max length of "to" and "from" together
Bram Moolenaar071d4272004-06-13 20:20:40 +00002290 char_u buf[KMAP_LLEN + 11];
2291 int i;
2292 char_u *save_cpo = p_cpo;
2293
Yegappan Lakshmanan36a5b682022-03-19 12:56:51 +00002294 if (!sourcing_a_script(eap))
Bram Moolenaar071d4272004-06-13 20:20:40 +00002295 {
Bram Moolenaare1242042021-12-16 20:56:57 +00002296 emsg(_(e_using_loadkeymap_not_in_sourced_file));
Bram Moolenaar071d4272004-06-13 20:20:40 +00002297 return;
2298 }
2299
2300 /*
2301 * Stop any active keymap and clear the table.
2302 */
2303 keymap_unload();
2304
2305 curbuf->b_kmap_state = 0;
Bram Moolenaar04935fb2022-01-08 16:19:22 +00002306 ga_init2(&curbuf->b_kmap_ga, sizeof(kmap_T), 20);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002307
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01002308 // Set 'cpoptions' to "C" to avoid line continuation.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002309 p_cpo = (char_u *)"C";
2310
2311 /*
2312 * Get each line of the sourced file, break at the end.
2313 */
2314 for (;;)
2315 {
Zoltan Arpadffy6fdb6282023-12-19 20:53:07 +01002316 line = eap->ea_getline(0, eap->cookie, 0, TRUE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002317 if (line == NULL)
2318 break;
2319
2320 p = skipwhite(line);
2321 if (*p != '"' && *p != NUL && ga_grow(&curbuf->b_kmap_ga, 1) == OK)
2322 {
2323 kp = (kmap_T *)curbuf->b_kmap_ga.ga_data + curbuf->b_kmap_ga.ga_len;
2324 s = skiptowhite(p);
Bram Moolenaardf44a272020-06-07 20:49:05 +02002325 kp->from = vim_strnsave(p, s - p);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002326 p = skipwhite(s);
2327 s = skiptowhite(p);
Bram Moolenaardf44a272020-06-07 20:49:05 +02002328 kp->to = vim_strnsave(p, s - p);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002329
2330 if (kp->from == NULL || kp->to == NULL
Bram Moolenaar57657d82006-04-21 22:12:41 +00002331 || STRLEN(kp->from) + STRLEN(kp->to) >= KMAP_LLEN
2332 || *kp->from == NUL || *kp->to == NUL)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002333 {
Bram Moolenaar57657d82006-04-21 22:12:41 +00002334 if (kp->to != NULL && *kp->to == NUL)
Bram Moolenaar677658a2022-01-05 16:09:06 +00002335 emsg(_(e_empty_keymap_entry));
Bram Moolenaar071d4272004-06-13 20:20:40 +00002336 vim_free(kp->from);
2337 vim_free(kp->to);
2338 }
2339 else
Bram Moolenaar071d4272004-06-13 20:20:40 +00002340 ++curbuf->b_kmap_ga.ga_len;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002341 }
2342 vim_free(line);
2343 }
2344
2345 /*
2346 * setup ":lnoremap" to map the keys
2347 */
2348 for (i = 0; i < curbuf->b_kmap_ga.ga_len; ++i)
2349 {
Bram Moolenaar555b2802005-05-19 21:08:39 +00002350 vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s %s",
Bram Moolenaar071d4272004-06-13 20:20:40 +00002351 ((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].from,
2352 ((kmap_T *)curbuf->b_kmap_ga.ga_data)[i].to);
zeertzjq44068e92022-06-16 11:14:55 +01002353 (void)do_map(MAPTYPE_NOREMAP, buf, MODE_LANGMAP, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002354 }
2355
2356 p_cpo = save_cpo;
2357
2358 curbuf->b_kmap_state |= KEYMAP_LOADED;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002359 status_redraw_curbuf();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002360}
2361
2362/*
2363 * Stop using 'keymap'.
2364 */
2365 static void
Bram Moolenaar7454a062016-01-30 15:14:10 +01002366keymap_unload(void)
Bram Moolenaar071d4272004-06-13 20:20:40 +00002367{
2368 char_u buf[KMAP_MAXLEN + 10];
2369 int i;
2370 char_u *save_cpo = p_cpo;
Bram Moolenaar8c8de832008-06-24 22:58:06 +00002371 kmap_T *kp;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002372
2373 if (!(curbuf->b_kmap_state & KEYMAP_LOADED))
2374 return;
2375
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01002376 // Set 'cpoptions' to "C" to avoid line continuation.
Bram Moolenaar071d4272004-06-13 20:20:40 +00002377 p_cpo = (char_u *)"C";
2378
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01002379 // clear the ":lmap"s
Bram Moolenaar8c8de832008-06-24 22:58:06 +00002380 kp = (kmap_T *)curbuf->b_kmap_ga.ga_data;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002381 for (i = 0; i < curbuf->b_kmap_ga.ga_len; ++i)
2382 {
Bram Moolenaar8c8de832008-06-24 22:58:06 +00002383 vim_snprintf((char *)buf, sizeof(buf), "<buffer> %s", kp[i].from);
zeertzjq44068e92022-06-16 11:14:55 +01002384 (void)do_map(MAPTYPE_UNMAP, buf, MODE_LANGMAP, FALSE);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002385 }
Bram Moolenaar50138322018-01-28 17:05:16 +01002386 keymap_clear(&curbuf->b_kmap_ga);
Bram Moolenaar071d4272004-06-13 20:20:40 +00002387
2388 p_cpo = save_cpo;
2389
2390 ga_clear(&curbuf->b_kmap_ga);
2391 curbuf->b_kmap_state &= ~KEYMAP_LOADED;
Bram Moolenaar071d4272004-06-13 20:20:40 +00002392 status_redraw_curbuf();
Bram Moolenaar071d4272004-06-13 20:20:40 +00002393}
2394
Bram Moolenaar50138322018-01-28 17:05:16 +01002395 void
2396keymap_clear(garray_T *kmap)
2397{
2398 int i;
2399 kmap_T *kp = (kmap_T *)kmap->ga_data;
2400
2401 for (i = 0; i < kmap->ga_len; ++i)
2402 {
2403 vim_free(kp[i].from);
2404 vim_free(kp[i].to);
2405 }
2406}
Bram Moolenaar5d18efe2019-12-01 21:11:22 +01002407#endif // FEAT_KEYMAP