]>
Commit | Line | Data |
---|---|---|
9512a71a AG |
1 | To: vim-dev@vim.org |
2 | Subject: Patch 7.2.109 | |
3 | Fcc: outbox | |
4 | From: Bram Moolenaar <Bram@moolenaar.net> | |
5 | Mime-Version: 1.0 | |
6 | Content-Type: text/plain; charset=ISO-8859-1 | |
7 | Content-Transfer-Encoding: 8bit | |
8 | ------------ | |
9 | ||
10 | Patch 7.2.109 | |
11 | Problem: 'langmap' does not work for multi-byte characters. | |
12 | Solution: Add a list of mapped multi-byte characters. (based on work by | |
13 | Konstantin Korikov, Agathoklis Hatzimanikas) | |
14 | Files: runtime/doc/options.txt, src/edit.c, src/getchar.c, src/macros.h, | |
15 | src/normal.c, src/option.c, src/proto/option.pro, src/window.c | |
16 | ||
17 | ||
18 | *** ../vim-7.2.108/runtime/doc/options.txt Fri Nov 28 10:59:57 2008 | |
19 | --- runtime/doc/options.txt Wed Feb 11 18:59:34 2009 | |
20 | *************** | |
21 | *** 4175,4183 **** | |
22 | be able to execute Normal mode commands. | |
23 | This is the opposite of the 'keymap' option, where characters are | |
24 | mapped in Insert mode. | |
25 | - This only works for 8-bit characters. The value of 'langmap' may be | |
26 | - specified with multi-byte characters (e.g., UTF-8), but only the lower | |
27 | - 8 bits of each character will be used. | |
28 | ||
29 | Example (for Greek, in UTF-8): *greek* > | |
30 | :set langmap=ΑA,ΒB,ΨC,ΔD,ΕE,ΦF,ΓG,ΗH,ΙI,ΞJ,ΚK,ΛL,ΜM,ΝN,ΟO,ΠP,QQ,ΡR,ΣS,ΤT,ΘU,ΩV,WW,ΧX,ΥY,ΖZ,αa,βb,ψc,δd,εe,φf,γg,ηh,ιi,ξj,κk,λl,μm,νn,οo,πp,qq,ρr,σs,τt,θu,ωv,ςw,χx,υy,ζz | |
31 | --- 4188,4193 ---- | |
32 | *** ../vim-7.2.108/src/edit.c Wed Feb 4 11:19:40 2009 | |
33 | --- src/edit.c Sat Feb 21 19:54:03 2009 | |
34 | *************** | |
35 | *** 7703,7711 **** | |
36 | */ | |
37 | ++no_mapping; | |
38 | regname = plain_vgetc(); | |
39 | - #ifdef FEAT_LANGMAP | |
40 | LANGMAP_ADJUST(regname, TRUE); | |
41 | - #endif | |
42 | if (regname == Ctrl_R || regname == Ctrl_O || regname == Ctrl_P) | |
43 | { | |
44 | /* Get a third key for literal register insertion */ | |
45 | --- 7703,7709 ---- | |
46 | *************** | |
47 | *** 7714,7722 **** | |
48 | add_to_showcmd_c(literally); | |
49 | #endif | |
50 | regname = plain_vgetc(); | |
51 | - #ifdef FEAT_LANGMAP | |
52 | LANGMAP_ADJUST(regname, TRUE); | |
53 | - #endif | |
54 | } | |
55 | --no_mapping; | |
56 | ||
57 | --- 7712,7718 ---- | |
58 | *** ../vim-7.2.108/src/macros.h Wed Aug 15 20:41:07 2007 | |
59 | --- src/macros.h Sat Feb 21 19:55:38 2009 | |
60 | *************** | |
61 | *** 127,141 **** | |
62 | #ifdef FEAT_LANGMAP | |
63 | /* | |
64 | * Adjust chars in a language according to 'langmap' option. | |
65 | ! * NOTE that there is NO overhead if 'langmap' is not set; but even | |
66 | ! * when set we only have to do 2 ifs and an array lookup. | |
67 | * Don't apply 'langmap' if the character comes from the Stuff buffer. | |
68 | * The do-while is just to ignore a ';' after the macro. | |
69 | */ | |
70 | ! # define LANGMAP_ADJUST(c, condition) do { \ | |
71 | ! if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \ | |
72 | ! c = langmap_mapchar[c]; \ | |
73 | } while (0) | |
74 | #endif | |
75 | ||
76 | /* | |
77 | --- 127,157 ---- | |
78 | #ifdef FEAT_LANGMAP | |
79 | /* | |
80 | * Adjust chars in a language according to 'langmap' option. | |
81 | ! * NOTE that there is no noticeable overhead if 'langmap' is not set. | |
82 | ! * When set the overhead for characters < 256 is small. | |
83 | * Don't apply 'langmap' if the character comes from the Stuff buffer. | |
84 | * The do-while is just to ignore a ';' after the macro. | |
85 | */ | |
86 | ! # ifdef FEAT_MBYTE | |
87 | ! # define LANGMAP_ADJUST(c, condition) \ | |
88 | ! do { \ | |
89 | ! if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0) \ | |
90 | ! { \ | |
91 | ! if ((c) < 256) \ | |
92 | ! c = langmap_mapchar[c]; \ | |
93 | ! else \ | |
94 | ! c = langmap_adjust_mb(c); \ | |
95 | ! } \ | |
96 | } while (0) | |
97 | + # else | |
98 | + # define LANGMAP_ADJUST(c, condition) \ | |
99 | + do { \ | |
100 | + if (*p_langmap && (condition) && !KeyStuffed && (c) >= 0 && (c) < 256) \ | |
101 | + c = langmap_mapchar[c]; \ | |
102 | + } while (0) | |
103 | + # endif | |
104 | + #else | |
105 | + # define LANGMAP_ADJUST(c, condition) /* nop */ | |
106 | #endif | |
107 | ||
108 | /* | |
109 | *** ../vim-7.2.108/src/normal.c Wed Feb 4 11:45:28 2009 | |
110 | --- src/normal.c Sat Feb 21 19:55:17 2009 | |
111 | *************** | |
112 | *** 651,660 **** | |
113 | * Get the command character from the user. | |
114 | */ | |
115 | c = safe_vgetc(); | |
116 | - | |
117 | - #ifdef FEAT_LANGMAP | |
118 | LANGMAP_ADJUST(c, TRUE); | |
119 | - #endif | |
120 | ||
121 | #ifdef FEAT_VISUAL | |
122 | /* | |
123 | --- 651,657 ---- | |
124 | *************** | |
125 | *** 744,752 **** | |
126 | } | |
127 | ++no_zero_mapping; /* don't map zero here */ | |
128 | c = plain_vgetc(); | |
129 | - #ifdef FEAT_LANGMAP | |
130 | LANGMAP_ADJUST(c, TRUE); | |
131 | - #endif | |
132 | --no_zero_mapping; | |
133 | if (ctrl_w) | |
134 | { | |
135 | --- 741,747 ---- | |
136 | *************** | |
137 | *** 769,777 **** | |
138 | ++no_mapping; | |
139 | ++allow_keys; /* no mapping for nchar, but keys */ | |
140 | c = plain_vgetc(); /* get next character */ | |
141 | - #ifdef FEAT_LANGMAP | |
142 | LANGMAP_ADJUST(c, TRUE); | |
143 | - #endif | |
144 | --no_mapping; | |
145 | --allow_keys; | |
146 | #ifdef FEAT_CMDL_INFO | |
147 | --- 764,770 ---- | |
148 | *************** | |
149 | *** 959,967 **** | |
150 | * "gr", "g'" and "g`". | |
151 | */ | |
152 | ca.nchar = plain_vgetc(); | |
153 | - #ifdef FEAT_LANGMAP | |
154 | LANGMAP_ADJUST(ca.nchar, TRUE); | |
155 | - #endif | |
156 | #ifdef FEAT_CMDL_INFO | |
157 | need_flushbuf |= add_to_showcmd(ca.nchar); | |
158 | #endif | |
159 | --- 952,958 ---- | |
160 | *************** | |
161 | *** 1062,1071 **** | |
162 | } | |
163 | #endif | |
164 | ||
165 | - #ifdef FEAT_LANGMAP | |
166 | /* adjust chars > 127, except after "tTfFr" commands */ | |
167 | LANGMAP_ADJUST(*cp, !lang); | |
168 | - #endif | |
169 | #ifdef FEAT_RIGHTLEFT | |
170 | /* adjust Hebrew mapped char */ | |
171 | if (p_hkmap && lang && KeyTyped) | |
172 | --- 1053,1060 ---- | |
173 | *************** | |
174 | *** 4630,4638 **** | |
175 | ++no_mapping; | |
176 | ++allow_keys; /* no mapping for nchar, but allow key codes */ | |
177 | nchar = plain_vgetc(); | |
178 | - #ifdef FEAT_LANGMAP | |
179 | LANGMAP_ADJUST(nchar, TRUE); | |
180 | - #endif | |
181 | --no_mapping; | |
182 | --allow_keys; | |
183 | #ifdef FEAT_CMDL_INFO | |
184 | --- 4619,4625 ---- | |
185 | *************** | |
186 | *** 4988,4996 **** | |
187 | ++no_mapping; | |
188 | ++allow_keys; /* no mapping for nchar, but allow key codes */ | |
189 | nchar = plain_vgetc(); | |
190 | - #ifdef FEAT_LANGMAP | |
191 | LANGMAP_ADJUST(nchar, TRUE); | |
192 | - #endif | |
193 | --no_mapping; | |
194 | --allow_keys; | |
195 | #ifdef FEAT_CMDL_INFO | |
196 | --- 4975,4981 ---- | |
197 | *** ../vim-7.2.108/src/option.c Wed Feb 11 22:47:32 2009 | |
198 | --- src/option.c Sat Feb 21 19:46:13 2009 | |
199 | *************** | |
200 | *** 10153,10177 **** | |
201 | ||
202 | #ifdef FEAT_LANGMAP | |
203 | /* | |
204 | ! * Any character has an equivalent character. This is used for keyboards that | |
205 | ! * have a special language mode that sends characters above 128 (although | |
206 | ! * other characters can be translated too). | |
207 | */ | |
208 | ||
209 | /* | |
210 | ! * char_u langmap_mapchar[256]; | |
211 | ! * Normally maps each of the 128 upper chars to an <128 ascii char; used to | |
212 | ! * "translate" native lang chars in normal mode or some cases of | |
213 | ! * insert mode without having to tediously switch lang mode back&forth. | |
214 | */ | |
215 | ||
216 | static void | |
217 | langmap_init() | |
218 | { | |
219 | int i; | |
220 | ||
221 | ! for (i = 0; i < 256; i++) /* we init with a-one-to one map */ | |
222 | ! langmap_mapchar[i] = i; | |
223 | } | |
224 | ||
225 | /* | |
226 | --- 10153,10262 ---- | |
227 | ||
228 | #ifdef FEAT_LANGMAP | |
229 | /* | |
230 | ! * Any character has an equivalent 'langmap' character. This is used for | |
231 | ! * keyboards that have a special language mode that sends characters above | |
232 | ! * 128 (although other characters can be translated too). The "to" field is a | |
233 | ! * Vim command character. This avoids having to switch the keyboard back to | |
234 | ! * ASCII mode when leaving Insert mode. | |
235 | ! * | |
236 | ! * langmap_mapchar[] maps any of 256 chars to an ASCII char used for Vim | |
237 | ! * commands. | |
238 | ! * When FEAT_MBYTE is defined langmap_mapga.ga_data is a sorted table of | |
239 | ! * langmap_entry_T. This does the same as langmap_mapchar[] for characters >= | |
240 | ! * 256. | |
241 | ! */ | |
242 | ! # ifdef FEAT_MBYTE | |
243 | ! /* | |
244 | ! * With multi-byte support use growarray for 'langmap' chars >= 256 | |
245 | */ | |
246 | + typedef struct | |
247 | + { | |
248 | + int from; | |
249 | + int to; | |
250 | + } langmap_entry_T; | |
251 | + | |
252 | + static garray_T langmap_mapga; | |
253 | + static void langmap_set_entry __ARGS((int from, int to)); | |
254 | + | |
255 | + /* | |
256 | + * Search for an entry in "langmap_mapga" for "from". If found set the "to" | |
257 | + * field. If not found insert a new entry at the appropriate location. | |
258 | + */ | |
259 | + static void | |
260 | + langmap_set_entry(from, to) | |
261 | + int from; | |
262 | + int to; | |
263 | + { | |
264 | + langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); | |
265 | + int a = 0; | |
266 | + int b = langmap_mapga.ga_len; | |
267 | + | |
268 | + /* Do a binary search for an existing entry. */ | |
269 | + while (a != b) | |
270 | + { | |
271 | + int i = (a + b) / 2; | |
272 | + int d = entries[i].from - from; | |
273 | + | |
274 | + if (d == 0) | |
275 | + { | |
276 | + entries[i].to = to; | |
277 | + return; | |
278 | + } | |
279 | + if (d < 0) | |
280 | + a = i + 1; | |
281 | + else | |
282 | + b = i; | |
283 | + } | |
284 | + | |
285 | + if (ga_grow(&langmap_mapga, 1) != OK) | |
286 | + return; /* out of memory */ | |
287 | + | |
288 | + /* insert new entry at position "a" */ | |
289 | + entries = (langmap_entry_T *)(langmap_mapga.ga_data) + a; | |
290 | + mch_memmove(entries + 1, entries, | |
291 | + (langmap_mapga.ga_len - a) * sizeof(langmap_entry_T)); | |
292 | + ++langmap_mapga.ga_len; | |
293 | + entries[0].from = from; | |
294 | + entries[0].to = to; | |
295 | + } | |
296 | ||
297 | /* | |
298 | ! * Apply 'langmap' to multi-byte character "c" and return the result. | |
299 | */ | |
300 | + int | |
301 | + langmap_adjust_mb(c) | |
302 | + int c; | |
303 | + { | |
304 | + langmap_entry_T *entries = (langmap_entry_T *)(langmap_mapga.ga_data); | |
305 | + int a = 0; | |
306 | + int b = langmap_mapga.ga_len; | |
307 | + | |
308 | + while (a != b) | |
309 | + { | |
310 | + int i = (a + b) / 2; | |
311 | + int d = entries[i].from - c; | |
312 | + | |
313 | + if (d == 0) | |
314 | + return entries[i].to; /* found matching entry */ | |
315 | + if (d < 0) | |
316 | + a = i + 1; | |
317 | + else | |
318 | + b = i; | |
319 | + } | |
320 | + return c; /* no entry found, return "c" unmodified */ | |
321 | + } | |
322 | + # endif | |
323 | ||
324 | static void | |
325 | langmap_init() | |
326 | { | |
327 | int i; | |
328 | ||
329 | ! for (i = 0; i < 256; i++) | |
330 | ! langmap_mapchar[i] = i; /* we init with a one-to-one map */ | |
331 | ! # ifdef FEAT_MBYTE | |
332 | ! ga_init2(&langmap_mapga, sizeof(langmap_entry_T), 8); | |
333 | ! # endif | |
334 | } | |
335 | ||
336 | /* | |
337 | *************** | |
338 | *** 10185,10191 **** | |
339 | char_u *p2; | |
340 | int from, to; | |
341 | ||
342 | ! langmap_init(); /* back to one-to-one map first */ | |
343 | ||
344 | for (p = p_langmap; p[0] != NUL; ) | |
345 | { | |
346 | --- 10270,10279 ---- | |
347 | char_u *p2; | |
348 | int from, to; | |
349 | ||
350 | ! #ifdef FEAT_MBYTE | |
351 | ! ga_clear(&langmap_mapga); /* clear the previous map first */ | |
352 | ! #endif | |
353 | ! langmap_init(); /* back to one-to-one map */ | |
354 | ||
355 | for (p = p_langmap; p[0] != NUL; ) | |
356 | { | |
357 | *************** | |
358 | *** 10235,10241 **** | |
359 | transchar(from)); | |
360 | return; | |
361 | } | |
362 | ! langmap_mapchar[from & 255] = to; | |
363 | ||
364 | /* Advance to next pair */ | |
365 | mb_ptr_adv(p); | |
366 | --- 10323,10335 ---- | |
367 | transchar(from)); | |
368 | return; | |
369 | } | |
370 | ! | |
371 | ! #ifdef FEAT_MBYTE | |
372 | ! if (from >= 256) | |
373 | ! langmap_set_entry(from, to); | |
374 | ! else | |
375 | ! #endif | |
376 | ! langmap_mapchar[from & 255] = to; | |
377 | ||
378 | /* Advance to next pair */ | |
379 | mb_ptr_adv(p); | |
380 | *** ../vim-7.2.108/src/proto/option.pro Sat May 5 19:28:04 2007 | |
381 | --- src/proto/option.pro Wed Feb 11 21:21:05 2009 | |
382 | *************** | |
383 | *** 44,49 **** | |
384 | --- 44,50 ---- | |
385 | void set_context_in_set_cmd __ARGS((expand_T *xp, char_u *arg, int opt_flags)); | |
386 | int ExpandSettings __ARGS((expand_T *xp, regmatch_T *regmatch, int *num_file, char_u ***file)); | |
387 | int ExpandOldSetting __ARGS((int *num_file, char_u ***file)); | |
388 | + int langmap_adjust_mb __ARGS((int c)); | |
389 | int has_format_option __ARGS((int x)); | |
390 | int shortmess __ARGS((int x)); | |
391 | void vimrc_found __ARGS((char_u *fname, char_u *envname)); | |
392 | *** ../vim-7.2.108/src/window.c Fri Nov 28 21:26:50 2008 | |
393 | --- src/window.c Sat Feb 21 19:55:25 2009 | |
394 | *************** | |
395 | *** 594,602 **** | |
396 | ++allow_keys; /* no mapping for xchar, but allow key codes */ | |
397 | if (xchar == NUL) | |
398 | xchar = plain_vgetc(); | |
399 | - #ifdef FEAT_LANGMAP | |
400 | LANGMAP_ADJUST(xchar, TRUE); | |
401 | - #endif | |
402 | --no_mapping; | |
403 | --allow_keys; | |
404 | #ifdef FEAT_CMDL_INFO | |
405 | --- 594,600 ---- | |
406 | *** ../vim-7.2.108/src/version.c Wed Feb 11 22:47:32 2009 | |
407 | --- src/version.c Sat Feb 21 19:34:28 2009 | |
408 | *************** | |
409 | *** 678,679 **** | |
410 | --- 678,681 ---- | |
411 | { /* Add new patch number below this line */ | |
412 | + /**/ | |
413 | + 109, | |
414 | /**/ | |
415 | ||
416 | -- | |
417 | hundred-and-one symptoms of being an internet addict: | |
418 | 99. The hum of a cooling fan and the click of keys is comforting to you. | |
419 | ||
420 | /// Bram Moolenaar -- Bram@Moolenaar.net -- http://www.Moolenaar.net \\\ | |
421 | /// sponsor Vim, vote for features -- http://www.Vim.org/sponsor/ \\\ | |
422 | \\\ download, build and distribute -- http://www.A-A-P.org /// | |
423 | \\\ help me help AIDS victims -- http://ICCF-Holland.org /// |