Mercurial > vim
comparison src/farsi.c @ 7:3fc0f57ecb91 v7.0001
updated for version 7.0001
author | vimboss |
---|---|
date | Sun, 13 Jun 2004 20:20:40 +0000 |
parents | |
children | f92bb1845823 |
comparison
equal
deleted
inserted
replaced
6:c2daee826b8f | 7:3fc0f57ecb91 |
---|---|
1 /* vi:set ts=8 sts=4 sw=4: | |
2 * | |
3 * VIM - Vi IMproved by Bram Moolenaar | |
4 * | |
5 * Do ":help uganda" in Vim to read copying and usage conditions. | |
6 * Do ":help credits" in Vim to see a list of people who contributed. | |
7 * See README.txt for an overview of the Vim source code. | |
8 */ | |
9 | |
10 /* | |
11 * farsi.c: functions for Farsi language | |
12 * | |
13 * Included by main.c, when FEAT_FKMAP is defined. | |
14 */ | |
15 | |
16 static int toF_Xor_X_ __ARGS((int c)); | |
17 static int F_is_TyE __ARGS((int c)); | |
18 static int F_is_TyC_TyD __ARGS((int c)); | |
19 static int F_is_TyB_TyC_TyD __ARGS((int src, int offset)); | |
20 static int toF_TyB __ARGS((int c)); | |
21 static void put_curr_and_l_to_X __ARGS((int c)); | |
22 static void put_and_redo __ARGS((int c)); | |
23 static void chg_c_toX_orX __ARGS((void)); | |
24 static void chg_c_to_X_orX_ __ARGS((void)); | |
25 static void chg_c_to_X_or_X __ARGS((void)); | |
26 static void chg_l_to_X_orX_ __ARGS((void)); | |
27 static void chg_l_toXor_X __ARGS((void)); | |
28 static void chg_r_to_Xor_X_ __ARGS((void)); | |
29 static int toF_leading __ARGS((int c)); | |
30 static int toF_Rjoin __ARGS((int c)); | |
31 static int canF_Ljoin __ARGS((int c)); | |
32 static int canF_Rjoin __ARGS((int c)); | |
33 static int F_isterm __ARGS((int c)); | |
34 static int toF_ending __ARGS((int c)); | |
35 static void lrswapbuf __ARGS((char_u *buf, int len)); | |
36 | |
37 /* | |
38 ** Convert the given Farsi character into a _X or _X_ type | |
39 */ | |
40 static int | |
41 toF_Xor_X_(c) | |
42 int c; | |
43 { | |
44 int tempc; | |
45 | |
46 switch (c) | |
47 { | |
48 case BE: | |
49 return _BE; | |
50 case PE: | |
51 return _PE; | |
52 case TE: | |
53 return _TE; | |
54 case SE: | |
55 return _SE; | |
56 case JIM: | |
57 return _JIM; | |
58 case CHE: | |
59 return _CHE; | |
60 case HE_J: | |
61 return _HE_J; | |
62 case XE: | |
63 return _XE; | |
64 case SIN: | |
65 return _SIN; | |
66 case SHIN: | |
67 return _SHIN; | |
68 case SAD: | |
69 return _SAD; | |
70 case ZAD: | |
71 return _ZAD; | |
72 case AYN: | |
73 return _AYN; | |
74 case AYN_: | |
75 return _AYN_; | |
76 case GHAYN: | |
77 return _GHAYN; | |
78 case GHAYN_: | |
79 return _GHAYN_; | |
80 case FE: | |
81 return _FE; | |
82 case GHAF: | |
83 return _GHAF; | |
84 case KAF: | |
85 return _KAF; | |
86 case GAF: | |
87 return _GAF; | |
88 case LAM: | |
89 return _LAM; | |
90 case MIM: | |
91 return _MIM; | |
92 case NOON: | |
93 return _NOON; | |
94 case YE: | |
95 case YE_: | |
96 return _YE; | |
97 case YEE: | |
98 case YEE_: | |
99 return _YEE; | |
100 case IE: | |
101 case IE_: | |
102 return _IE; | |
103 case F_HE: | |
104 tempc = _HE; | |
105 | |
106 if (p_ri && (curwin->w_cursor.col+1 < STRLEN(ml_get_curline()))) | |
107 { | |
108 inc_cursor(); | |
109 | |
110 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
111 tempc = _HE_; | |
112 | |
113 dec_cursor(); | |
114 } | |
115 if (!p_ri && STRLEN(ml_get_curline())) | |
116 { | |
117 dec_cursor(); | |
118 | |
119 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
120 tempc = _HE_; | |
121 | |
122 inc_cursor(); | |
123 } | |
124 | |
125 return tempc; | |
126 } | |
127 return 0; | |
128 } | |
129 | |
130 /* | |
131 ** Convert the given Farsi character into Farsi capital character . | |
132 */ | |
133 int | |
134 toF_TyA(c) | |
135 int c ; | |
136 { | |
137 switch (c) | |
138 { | |
139 case ALEF_: | |
140 return ALEF; | |
141 case ALEF_U_H_: | |
142 return ALEF_U_H; | |
143 case _BE: | |
144 return BE; | |
145 case _PE: | |
146 return PE; | |
147 case _TE: | |
148 return TE; | |
149 case _SE: | |
150 return SE; | |
151 case _JIM: | |
152 return JIM; | |
153 case _CHE: | |
154 return CHE; | |
155 case _HE_J: | |
156 return HE_J; | |
157 case _XE: | |
158 return XE; | |
159 case _SIN: | |
160 return SIN; | |
161 case _SHIN: | |
162 return SHIN; | |
163 case _SAD: | |
164 return SAD; | |
165 case _ZAD: | |
166 return ZAD; | |
167 case _AYN: | |
168 case AYN_: | |
169 case _AYN_: | |
170 return AYN; | |
171 case _GHAYN: | |
172 case GHAYN_: | |
173 case _GHAYN_: | |
174 return GHAYN; | |
175 case _FE: | |
176 return FE; | |
177 case _GHAF: | |
178 return GHAF; | |
179 /* I am not sure what it is !!! case _KAF_H: */ | |
180 case _KAF: | |
181 return KAF; | |
182 case _GAF: | |
183 return GAF; | |
184 case _LAM: | |
185 return LAM; | |
186 case _MIM: | |
187 return MIM; | |
188 case _NOON: | |
189 return NOON; | |
190 case _YE: | |
191 case YE_: | |
192 return YE; | |
193 case _YEE: | |
194 case YEE_: | |
195 return YEE; | |
196 case TEE_: | |
197 return TEE; | |
198 case _IE: | |
199 case IE_: | |
200 return IE; | |
201 case _HE: | |
202 case _HE_: | |
203 return F_HE; | |
204 } | |
205 return c; | |
206 } | |
207 | |
208 /* | |
209 ** Is the character under the cursor+offset in the given buffer a join type. | |
210 ** That is a character that is combined with the others. | |
211 ** Note: the offset is used only for command line buffer. | |
212 */ | |
213 static int | |
214 F_is_TyB_TyC_TyD(src, offset) | |
215 int src, offset; | |
216 { | |
217 int c; | |
218 | |
219 if (src == SRC_EDT) | |
220 c = gchar_cursor(); | |
221 else | |
222 c = cmd_gchar(AT_CURSOR+offset); | |
223 | |
224 switch (c) | |
225 { | |
226 case _LAM: | |
227 case _BE: | |
228 case _PE: | |
229 case _TE: | |
230 case _SE: | |
231 case _JIM: | |
232 case _CHE: | |
233 case _HE_J: | |
234 case _XE: | |
235 case _SIN: | |
236 case _SHIN: | |
237 case _SAD: | |
238 case _ZAD: | |
239 case _TA: | |
240 case _ZA: | |
241 case _AYN: | |
242 case _AYN_: | |
243 case _GHAYN: | |
244 case _GHAYN_: | |
245 case _FE: | |
246 case _GHAF: | |
247 case _KAF: | |
248 case _KAF_H: | |
249 case _GAF: | |
250 case _MIM: | |
251 case _NOON: | |
252 case _YE: | |
253 case _YEE: | |
254 case _IE: | |
255 case _HE_: | |
256 case _HE: | |
257 return TRUE; | |
258 } | |
259 return FALSE; | |
260 } | |
261 | |
262 /* | |
263 ** Is the Farsi character one of the terminating only type. | |
264 */ | |
265 static int | |
266 F_is_TyE(c) | |
267 int c; | |
268 { | |
269 switch (c) | |
270 { | |
271 case ALEF_A: | |
272 case ALEF_D_H: | |
273 case DAL: | |
274 case ZAL: | |
275 case RE: | |
276 case ZE: | |
277 case JE: | |
278 case WAW: | |
279 case WAW_H: | |
280 case HAMZE: | |
281 return TRUE; | |
282 } | |
283 return FALSE; | |
284 } | |
285 | |
286 /* | |
287 ** Is the Farsi character one of the none leading type. | |
288 */ | |
289 static int | |
290 F_is_TyC_TyD(c) | |
291 int c; | |
292 { | |
293 switch (c) | |
294 { | |
295 case ALEF_: | |
296 case ALEF_U_H_: | |
297 case _AYN_: | |
298 case AYN_: | |
299 case _GHAYN_: | |
300 case GHAYN_: | |
301 case _HE_: | |
302 case YE_: | |
303 case IE_: | |
304 case TEE_: | |
305 case YEE_: | |
306 return TRUE; | |
307 } | |
308 return FALSE; | |
309 } | |
310 | |
311 /* | |
312 ** Convert a none leading Farsi char into a leading type. | |
313 */ | |
314 static int | |
315 toF_TyB(c) | |
316 int c; | |
317 { | |
318 switch (c) | |
319 { | |
320 case ALEF_: return ALEF; | |
321 case ALEF_U_H_: return ALEF_U_H; | |
322 case _AYN_: return _AYN; | |
323 case AYN_: return AYN; /* exception - there are many of them */ | |
324 case _GHAYN_: return _GHAYN; | |
325 case GHAYN_: return GHAYN; /* exception - there are many of them */ | |
326 case _HE_: return _HE; | |
327 case YE_: return YE; | |
328 case IE_: return IE; | |
329 case TEE_: return TEE; | |
330 case YEE_: return YEE; | |
331 } | |
332 return c; | |
333 } | |
334 | |
335 /* | |
336 ** Overwrite the current redo and cursor characters + left adjust | |
337 */ | |
338 static void | |
339 put_curr_and_l_to_X(c) | |
340 int c; | |
341 { | |
342 int tempc; | |
343 | |
344 if (curwin->w_p_rl && p_ri) | |
345 return; | |
346 | |
347 if ( (curwin->w_cursor.col < STRLEN(ml_get_curline()))) | |
348 { | |
349 if ((p_ri && curwin->w_cursor.col) || !p_ri) | |
350 { | |
351 if (p_ri) | |
352 dec_cursor(); | |
353 else | |
354 inc_cursor(); | |
355 | |
356 if (F_is_TyC_TyD((tempc = gchar_cursor()))) | |
357 { | |
358 pchar_cursor(toF_TyB(tempc)); | |
359 AppendCharToRedobuff(K_BS); | |
360 AppendCharToRedobuff(tempc); | |
361 } | |
362 | |
363 if (p_ri) | |
364 inc_cursor(); | |
365 else | |
366 dec_cursor(); | |
367 } | |
368 } | |
369 | |
370 put_and_redo(c); | |
371 } | |
372 | |
373 static void | |
374 put_and_redo(c) | |
375 int c; | |
376 { | |
377 pchar_cursor(c); | |
378 AppendCharToRedobuff(K_BS); | |
379 AppendCharToRedobuff(c); | |
380 } | |
381 | |
382 /* | |
383 ** Change the char. under the cursor to a X_ or X type | |
384 */ | |
385 static void | |
386 chg_c_toX_orX() | |
387 { | |
388 int tempc, curc; | |
389 | |
390 switch ((curc = gchar_cursor())) | |
391 { | |
392 case _BE: | |
393 tempc = BE; | |
394 break; | |
395 case _PE: | |
396 tempc = PE; | |
397 break; | |
398 case _TE: | |
399 tempc = TE; | |
400 break; | |
401 case _SE: | |
402 tempc = SE; | |
403 break; | |
404 case _JIM: | |
405 tempc = JIM; | |
406 break; | |
407 case _CHE: | |
408 tempc = CHE; | |
409 break; | |
410 case _HE_J: | |
411 tempc = HE_J; | |
412 break; | |
413 case _XE: | |
414 tempc = XE; | |
415 break; | |
416 case _SIN: | |
417 tempc = SIN; | |
418 break; | |
419 case _SHIN: | |
420 tempc = SHIN; | |
421 break; | |
422 case _SAD: | |
423 tempc = SAD; | |
424 break; | |
425 case _ZAD: | |
426 tempc = ZAD; | |
427 break; | |
428 case _FE: | |
429 tempc = FE; | |
430 break; | |
431 case _GHAF: | |
432 tempc = GHAF; | |
433 break; | |
434 case _KAF_H: | |
435 case _KAF: | |
436 tempc = KAF; | |
437 break; | |
438 case _GAF: | |
439 tempc = GAF; | |
440 break; | |
441 case _AYN: | |
442 tempc = AYN; | |
443 break; | |
444 case _AYN_: | |
445 tempc = AYN_; | |
446 break; | |
447 case _GHAYN: | |
448 tempc = GHAYN; | |
449 break; | |
450 case _GHAYN_: | |
451 tempc = GHAYN_; | |
452 break; | |
453 case _LAM: | |
454 tempc = LAM; | |
455 break; | |
456 case _MIM: | |
457 tempc = MIM; | |
458 break; | |
459 case _NOON: | |
460 tempc = NOON; | |
461 break; | |
462 case _HE: | |
463 case _HE_: | |
464 tempc = F_HE; | |
465 break; | |
466 case _YE: | |
467 case _IE: | |
468 case _YEE: | |
469 if (p_ri) | |
470 { | |
471 inc_cursor(); | |
472 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
473 tempc = (curc == _YE ? YE_ : | |
474 (curc == _IE ? IE_ : YEE_)); | |
475 else | |
476 tempc = (curc == _YE ? YE : | |
477 (curc == _IE ? IE : YEE)); | |
478 dec_cursor(); | |
479 } | |
480 else | |
481 { | |
482 if (curwin->w_cursor.col) | |
483 { | |
484 dec_cursor(); | |
485 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
486 tempc = (curc == _YE ? YE_ : | |
487 (curc == _IE ? IE_ : YEE_)); | |
488 else | |
489 tempc = (curc == _YE ? YE : | |
490 (curc == _IE ? IE : YEE)); | |
491 inc_cursor(); | |
492 } | |
493 else | |
494 tempc = (curc == _YE ? YE : | |
495 (curc == _IE ? IE : YEE)); | |
496 } | |
497 break; | |
498 default: | |
499 tempc = 0; | |
500 } | |
501 | |
502 if (tempc) | |
503 put_and_redo(tempc); | |
504 } | |
505 | |
506 /* | |
507 ** Change the char. under the cursor to a _X_ or X_ type | |
508 */ | |
509 | |
510 static void | |
511 chg_c_to_X_orX_() | |
512 { | |
513 int tempc; | |
514 | |
515 switch (gchar_cursor()) | |
516 { | |
517 case ALEF: | |
518 tempc = ALEF_; | |
519 break; | |
520 case ALEF_U_H: | |
521 tempc = ALEF_U_H_; | |
522 break; | |
523 case _AYN: | |
524 tempc = _AYN_; | |
525 break; | |
526 case AYN: | |
527 tempc = AYN_; | |
528 break; | |
529 case _GHAYN: | |
530 tempc = _GHAYN_; | |
531 break; | |
532 case GHAYN: | |
533 tempc = GHAYN_; | |
534 break; | |
535 case _HE: | |
536 tempc = _HE_; | |
537 break; | |
538 case YE: | |
539 tempc = YE_; | |
540 break; | |
541 case IE: | |
542 tempc = IE_; | |
543 break; | |
544 case TEE: | |
545 tempc = TEE_; | |
546 break; | |
547 case YEE: | |
548 tempc = YEE_; | |
549 break; | |
550 default: | |
551 tempc = 0; | |
552 } | |
553 | |
554 if (tempc) | |
555 put_and_redo(tempc); | |
556 } | |
557 | |
558 /* | |
559 ** Change the char. under the cursor to a _X_ or _X type | |
560 */ | |
561 static void | |
562 chg_c_to_X_or_X () | |
563 { | |
564 int tempc; | |
565 | |
566 tempc = gchar_cursor(); | |
567 | |
568 if (curwin->w_cursor.col+1 < STRLEN(ml_get_curline())) | |
569 { | |
570 inc_cursor(); | |
571 | |
572 if ((tempc == F_HE) && (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))) | |
573 { | |
574 tempc = _HE_; | |
575 | |
576 dec_cursor(); | |
577 | |
578 put_and_redo(tempc); | |
579 return; | |
580 } | |
581 | |
582 dec_cursor(); | |
583 } | |
584 | |
585 if ((tempc = toF_Xor_X_(tempc)) != 0) | |
586 put_and_redo(tempc); | |
587 } | |
588 | |
589 /* | |
590 ** Change the character left to the cursor to a _X_ or X_ type | |
591 */ | |
592 static void | |
593 chg_l_to_X_orX_ () | |
594 { | |
595 int tempc; | |
596 | |
597 if (!curwin->w_cursor.col && | |
598 (curwin->w_cursor.col+1 == STRLEN(ml_get_curline()))) | |
599 return; | |
600 | |
601 if (!curwin->w_cursor.col && p_ri) | |
602 return; | |
603 | |
604 if (p_ri) | |
605 dec_cursor(); | |
606 else | |
607 inc_cursor(); | |
608 | |
609 switch (gchar_cursor()) | |
610 { | |
611 case ALEF: | |
612 tempc = ALEF_; | |
613 break; | |
614 case ALEF_U_H: | |
615 tempc = ALEF_U_H_; | |
616 break; | |
617 case _AYN: | |
618 tempc = _AYN_; | |
619 break; | |
620 case AYN: | |
621 tempc = AYN_; | |
622 break; | |
623 case _GHAYN: | |
624 tempc = _GHAYN_; | |
625 break; | |
626 case GHAYN: | |
627 tempc = GHAYN_; | |
628 break; | |
629 case _HE: | |
630 tempc = _HE_; | |
631 break; | |
632 case YE: | |
633 tempc = YE_; | |
634 break; | |
635 case IE: | |
636 tempc = IE_; | |
637 break; | |
638 case TEE: | |
639 tempc = TEE_; | |
640 break; | |
641 case YEE: | |
642 tempc = YEE_; | |
643 break; | |
644 default: | |
645 tempc = 0; | |
646 } | |
647 | |
648 if (tempc) | |
649 put_and_redo(tempc); | |
650 | |
651 if (p_ri) | |
652 inc_cursor(); | |
653 else | |
654 dec_cursor(); | |
655 } | |
656 | |
657 /* | |
658 ** Change the charcter left to the cursor to a X or _X type | |
659 */ | |
660 | |
661 static void | |
662 chg_l_toXor_X () | |
663 { | |
664 int tempc; | |
665 | |
666 if (!curwin->w_cursor.col && | |
667 (curwin->w_cursor.col+1 == STRLEN(ml_get_curline()))) | |
668 return; | |
669 | |
670 if (!curwin->w_cursor.col && p_ri) | |
671 return; | |
672 | |
673 if (p_ri) | |
674 dec_cursor(); | |
675 else | |
676 inc_cursor(); | |
677 | |
678 switch (gchar_cursor()) | |
679 { | |
680 case ALEF_: | |
681 tempc = ALEF; | |
682 break; | |
683 case ALEF_U_H_: | |
684 tempc = ALEF_U_H; | |
685 break; | |
686 case _AYN_: | |
687 tempc = _AYN; | |
688 break; | |
689 case AYN_: | |
690 tempc = AYN; | |
691 break; | |
692 case _GHAYN_: | |
693 tempc = _GHAYN; | |
694 break; | |
695 case GHAYN_: | |
696 tempc = GHAYN; | |
697 break; | |
698 case _HE_: | |
699 tempc = _HE; | |
700 break; | |
701 case YE_: | |
702 tempc = YE; | |
703 break; | |
704 case IE_: | |
705 tempc = IE; | |
706 break; | |
707 case TEE_: | |
708 tempc = TEE; | |
709 break; | |
710 case YEE_: | |
711 tempc = YEE; | |
712 break; | |
713 default: | |
714 tempc = 0; | |
715 } | |
716 | |
717 if (tempc) | |
718 put_and_redo(tempc); | |
719 | |
720 if (p_ri) | |
721 inc_cursor(); | |
722 else | |
723 dec_cursor(); | |
724 } | |
725 | |
726 /* | |
727 ** Change the charcter right to the cursor to a _X or _X_ type | |
728 */ | |
729 | |
730 static void | |
731 chg_r_to_Xor_X_() | |
732 { | |
733 int tempc, c; | |
734 | |
735 if (curwin->w_cursor.col) | |
736 { | |
737 if (!p_ri) | |
738 dec_cursor(); | |
739 | |
740 tempc = gchar_cursor(); | |
741 | |
742 if ((c = toF_Xor_X_(tempc)) != 0) | |
743 put_and_redo(c); | |
744 | |
745 if (!p_ri) | |
746 inc_cursor(); | |
747 | |
748 } | |
749 } | |
750 | |
751 /* | |
752 ** Map Farsi keyboard when in fkmap mode. | |
753 */ | |
754 | |
755 int | |
756 fkmap(c) | |
757 int c; | |
758 { | |
759 int tempc; | |
760 static int revins; | |
761 | |
762 if (IS_SPECIAL(c)) | |
763 return c; | |
764 | |
765 if (VIM_ISDIGIT(c) || ((c == '.' || c == '+' || c == '-' || | |
766 c == '^' || c == '%' || c == '#' || c == '=') && revins)) | |
767 { | |
768 if (!revins) | |
769 { | |
770 if (curwin->w_cursor.col) | |
771 { | |
772 if (!p_ri) | |
773 dec_cursor(); | |
774 | |
775 chg_c_toX_orX (); | |
776 chg_l_toXor_X (); | |
777 | |
778 if (!p_ri) | |
779 inc_cursor(); | |
780 } | |
781 } | |
782 | |
783 arrow_used = TRUE; | |
784 (void)stop_arrow(); | |
785 | |
786 if (!curwin->w_p_rl && revins) | |
787 inc_cursor(); | |
788 | |
789 ++revins; | |
790 p_ri=1; | |
791 } | |
792 else | |
793 { | |
794 if (revins) | |
795 { | |
796 arrow_used = TRUE; | |
797 (void)stop_arrow(); | |
798 | |
799 revins = 0; | |
800 if (curwin->w_p_rl) | |
801 { | |
802 while ((F_isdigit(gchar_cursor()) | |
803 || (gchar_cursor() == F_PERIOD | |
804 || gchar_cursor() == F_PLUS | |
805 || gchar_cursor() == F_MINUS | |
806 || gchar_cursor() == F_MUL | |
807 || gchar_cursor() == F_DIVIDE | |
808 || gchar_cursor() == F_PERCENT | |
809 || gchar_cursor() == F_EQUALS)) | |
810 && gchar_cursor() != NUL) | |
811 ++curwin->w_cursor.col; | |
812 } | |
813 else | |
814 { | |
815 if (curwin->w_cursor.col) | |
816 while ((F_isdigit(gchar_cursor()) | |
817 || (gchar_cursor() == F_PERIOD | |
818 || gchar_cursor() == F_PLUS | |
819 || gchar_cursor() == F_MINUS | |
820 || gchar_cursor() == F_MUL | |
821 || gchar_cursor() == F_DIVIDE | |
822 || gchar_cursor() == F_PERCENT | |
823 || gchar_cursor() == F_EQUALS)) | |
824 && --curwin->w_cursor.col) | |
825 ; | |
826 | |
827 if (!F_isdigit(gchar_cursor())) | |
828 ++curwin->w_cursor.col; | |
829 } | |
830 } | |
831 } | |
832 | |
833 if (!revins) | |
834 { | |
835 if (curwin->w_p_rl) | |
836 p_ri=0; | |
837 if (!curwin->w_p_rl) | |
838 p_ri=1; | |
839 } | |
840 | |
841 if ((c < 0x100) && (isalpha(c) || c == '&' || c == '^' || c == ';' || | |
842 c == '\''|| c == ',' || c == '[' || | |
843 c == ']' || c == '{' || c == '}' )) | |
844 chg_r_to_Xor_X_(); | |
845 | |
846 tempc = 0; | |
847 | |
848 switch (c) | |
849 { | |
850 case '`': | |
851 case ' ': | |
852 case '.': | |
853 case '!': | |
854 case '"': | |
855 case '$': | |
856 case '%': | |
857 case '^': | |
858 case '&': | |
859 case '/': | |
860 case '(': | |
861 case ')': | |
862 case '=': | |
863 case '\\': | |
864 case '?': | |
865 case '+': | |
866 case '-': | |
867 case '_': | |
868 case '*': | |
869 case ':': | |
870 case '#': | |
871 case '~': | |
872 case '@': | |
873 case '<': | |
874 case '>': | |
875 case '{': | |
876 case '}': | |
877 case '|': | |
878 case '0': | |
879 case '1': | |
880 case '2': | |
881 case '3': | |
882 case '4': | |
883 case '5': | |
884 case '6': | |
885 case '7': | |
886 case '8': | |
887 case '9': | |
888 case 'B': | |
889 case 'E': | |
890 case 'F': | |
891 case 'H': | |
892 case 'I': | |
893 case 'K': | |
894 case 'L': | |
895 case 'M': | |
896 case 'O': | |
897 case 'P': | |
898 case 'Q': | |
899 case 'R': | |
900 case 'T': | |
901 case 'U': | |
902 case 'W': | |
903 case 'Y': | |
904 case NL: | |
905 case TAB: | |
906 | |
907 if (p_ri && c == NL && curwin->w_cursor.col) | |
908 { | |
909 /* | |
910 ** If the char before the cursor is _X_ or X_ do not change | |
911 ** the one under the cursor with X type. | |
912 */ | |
913 | |
914 dec_cursor(); | |
915 | |
916 if (F_isalpha(gchar_cursor())) | |
917 { | |
918 inc_cursor(); | |
919 return NL; | |
920 } | |
921 | |
922 inc_cursor(); | |
923 } | |
924 | |
925 if (!p_ri) | |
926 if (!curwin->w_cursor.col) | |
927 { | |
928 switch (c) | |
929 { | |
930 case '0': return FARSI_0; | |
931 case '1': return FARSI_1; | |
932 case '2': return FARSI_2; | |
933 case '3': return FARSI_3; | |
934 case '4': return FARSI_4; | |
935 case '5': return FARSI_5; | |
936 case '6': return FARSI_6; | |
937 case '7': return FARSI_7; | |
938 case '8': return FARSI_8; | |
939 case '9': return FARSI_9; | |
940 case 'B': return F_PSP; | |
941 case 'E': return JAZR_N; | |
942 case 'F': return ALEF_D_H; | |
943 case 'H': return ALEF_A; | |
944 case 'I': return TASH; | |
945 case 'K': return F_LQUOT; | |
946 case 'L': return F_RQUOT; | |
947 case 'M': return HAMZE; | |
948 case 'O': return '['; | |
949 case 'P': return ']'; | |
950 case 'Q': return OO; | |
951 case 'R': return MAD_N; | |
952 case 'T': return OW; | |
953 case 'U': return MAD; | |
954 case 'W': return OW_OW; | |
955 case 'Y': return JAZR; | |
956 case '`': return F_PCN; | |
957 case '!': return F_EXCL; | |
958 case '@': return F_COMMA; | |
959 case '#': return F_DIVIDE; | |
960 case '$': return F_CURRENCY; | |
961 case '%': return F_PERCENT; | |
962 case '^': return F_MUL; | |
963 case '&': return F_BCOMMA; | |
964 case '*': return F_STAR; | |
965 case '(': return F_LPARENT; | |
966 case ')': return F_RPARENT; | |
967 case '-': return F_MINUS; | |
968 case '_': return F_UNDERLINE; | |
969 case '=': return F_EQUALS; | |
970 case '+': return F_PLUS; | |
971 case '\\': return F_BSLASH; | |
972 case '|': return F_PIPE; | |
973 case ':': return F_DCOLON; | |
974 case '"': return F_SEMICOLON; | |
975 case '.': return F_PERIOD; | |
976 case '/': return F_SLASH; | |
977 case '<': return F_LESS; | |
978 case '>': return F_GREATER; | |
979 case '?': return F_QUESTION; | |
980 case ' ': return F_BLANK; | |
981 } | |
982 break; | |
983 } | |
984 if (!p_ri) | |
985 dec_cursor(); | |
986 | |
987 switch ((tempc = gchar_cursor())) | |
988 { | |
989 case _BE: | |
990 case _PE: | |
991 case _TE: | |
992 case _SE: | |
993 case _JIM: | |
994 case _CHE: | |
995 case _HE_J: | |
996 case _XE: | |
997 case _SIN: | |
998 case _SHIN: | |
999 case _SAD: | |
1000 case _ZAD: | |
1001 case _FE: | |
1002 case _GHAF: | |
1003 case _KAF: | |
1004 case _KAF_H: | |
1005 case _GAF: | |
1006 case _LAM: | |
1007 case _MIM: | |
1008 case _NOON: | |
1009 case _HE: | |
1010 case _HE_: | |
1011 case _TA: | |
1012 case _ZA: | |
1013 put_curr_and_l_to_X(toF_TyA(tempc)); | |
1014 break; | |
1015 case _AYN: | |
1016 case _AYN_: | |
1017 | |
1018 if (!p_ri) | |
1019 if (!curwin->w_cursor.col) | |
1020 { | |
1021 put_curr_and_l_to_X(AYN); | |
1022 break; | |
1023 } | |
1024 | |
1025 if (p_ri) | |
1026 inc_cursor(); | |
1027 else | |
1028 dec_cursor(); | |
1029 | |
1030 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
1031 tempc = AYN_; | |
1032 else | |
1033 tempc = AYN; | |
1034 | |
1035 if (p_ri) | |
1036 dec_cursor(); | |
1037 else | |
1038 inc_cursor(); | |
1039 | |
1040 put_curr_and_l_to_X(tempc); | |
1041 | |
1042 break; | |
1043 case _GHAYN: | |
1044 case _GHAYN_: | |
1045 | |
1046 if (!p_ri) | |
1047 if (!curwin->w_cursor.col) | |
1048 { | |
1049 put_curr_and_l_to_X(GHAYN); | |
1050 break; | |
1051 } | |
1052 | |
1053 if (p_ri) | |
1054 inc_cursor(); | |
1055 else | |
1056 dec_cursor(); | |
1057 | |
1058 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
1059 tempc = GHAYN_; | |
1060 else | |
1061 tempc = GHAYN; | |
1062 | |
1063 if (p_ri) | |
1064 dec_cursor(); | |
1065 else | |
1066 inc_cursor(); | |
1067 | |
1068 put_curr_and_l_to_X(tempc); | |
1069 break; | |
1070 case _YE: | |
1071 case _IE: | |
1072 case _YEE: | |
1073 if (!p_ri) | |
1074 if (!curwin->w_cursor.col) | |
1075 { | |
1076 put_curr_and_l_to_X((tempc == _YE ? YE : | |
1077 (tempc == _IE ? IE : YEE))); | |
1078 break; | |
1079 } | |
1080 | |
1081 if (p_ri) | |
1082 inc_cursor(); | |
1083 else | |
1084 dec_cursor(); | |
1085 | |
1086 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
1087 tempc = (tempc == _YE ? YE_ : | |
1088 (tempc == _IE ? IE_ : YEE_)); | |
1089 else | |
1090 tempc = (tempc == _YE ? YE : | |
1091 (tempc == _IE ? IE : YEE)); | |
1092 | |
1093 if (p_ri) | |
1094 dec_cursor(); | |
1095 else | |
1096 inc_cursor(); | |
1097 | |
1098 put_curr_and_l_to_X(tempc); | |
1099 break; | |
1100 } | |
1101 | |
1102 if (!p_ri) | |
1103 inc_cursor(); | |
1104 | |
1105 tempc = 0; | |
1106 | |
1107 switch (c) | |
1108 { | |
1109 case '0': return FARSI_0; | |
1110 case '1': return FARSI_1; | |
1111 case '2': return FARSI_2; | |
1112 case '3': return FARSI_3; | |
1113 case '4': return FARSI_4; | |
1114 case '5': return FARSI_5; | |
1115 case '6': return FARSI_6; | |
1116 case '7': return FARSI_7; | |
1117 case '8': return FARSI_8; | |
1118 case '9': return FARSI_9; | |
1119 case 'B': return F_PSP; | |
1120 case 'E': return JAZR_N; | |
1121 case 'F': return ALEF_D_H; | |
1122 case 'H': return ALEF_A; | |
1123 case 'I': return TASH; | |
1124 case 'K': return F_LQUOT; | |
1125 case 'L': return F_RQUOT; | |
1126 case 'M': return HAMZE; | |
1127 case 'O': return '['; | |
1128 case 'P': return ']'; | |
1129 case 'Q': return OO; | |
1130 case 'R': return MAD_N; | |
1131 case 'T': return OW; | |
1132 case 'U': return MAD; | |
1133 case 'W': return OW_OW; | |
1134 case 'Y': return JAZR; | |
1135 case '`': return F_PCN; | |
1136 case '!': return F_EXCL; | |
1137 case '@': return F_COMMA; | |
1138 case '#': return F_DIVIDE; | |
1139 case '$': return F_CURRENCY; | |
1140 case '%': return F_PERCENT; | |
1141 case '^': return F_MUL; | |
1142 case '&': return F_BCOMMA; | |
1143 case '*': return F_STAR; | |
1144 case '(': return F_LPARENT; | |
1145 case ')': return F_RPARENT; | |
1146 case '-': return F_MINUS; | |
1147 case '_': return F_UNDERLINE; | |
1148 case '=': return F_EQUALS; | |
1149 case '+': return F_PLUS; | |
1150 case '\\': return F_BSLASH; | |
1151 case '|': return F_PIPE; | |
1152 case ':': return F_DCOLON; | |
1153 case '"': return F_SEMICOLON; | |
1154 case '.': return F_PERIOD; | |
1155 case '/': return F_SLASH; | |
1156 case '<': return F_LESS; | |
1157 case '>': return F_GREATER; | |
1158 case '?': return F_QUESTION; | |
1159 case ' ': return F_BLANK; | |
1160 } | |
1161 break; | |
1162 | |
1163 case 'a': | |
1164 tempc = _SHIN; | |
1165 break; | |
1166 case 'A': | |
1167 tempc = WAW_H; | |
1168 break; | |
1169 case 'b': | |
1170 tempc = ZAL; | |
1171 break; | |
1172 case 'c': | |
1173 tempc = ZE; | |
1174 break; | |
1175 case 'C': | |
1176 tempc = JE; | |
1177 break; | |
1178 case 'd': | |
1179 tempc = _YE; | |
1180 break; | |
1181 case 'D': | |
1182 tempc = _YEE; | |
1183 break; | |
1184 case 'e': | |
1185 tempc = _SE; | |
1186 break; | |
1187 case 'f': | |
1188 tempc = _BE; | |
1189 break; | |
1190 case 'g': | |
1191 tempc = _LAM; | |
1192 break; | |
1193 case 'G': | |
1194 if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) | |
1195 { | |
1196 | |
1197 if (gchar_cursor() == _LAM) | |
1198 chg_c_toX_orX (); | |
1199 else | |
1200 if (p_ri) | |
1201 chg_c_to_X_or_X (); | |
1202 } | |
1203 | |
1204 if (!p_ri) | |
1205 if (!curwin->w_cursor.col) | |
1206 return ALEF_U_H; | |
1207 | |
1208 if (!p_ri) | |
1209 dec_cursor(); | |
1210 | |
1211 if (gchar_cursor() == _LAM) | |
1212 { | |
1213 chg_c_toX_orX (); | |
1214 chg_l_toXor_X (); | |
1215 tempc = ALEF_U_H; | |
1216 } | |
1217 else | |
1218 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
1219 { | |
1220 tempc = ALEF_U_H_; | |
1221 chg_l_toXor_X (); | |
1222 } | |
1223 else | |
1224 tempc = ALEF_U_H; | |
1225 | |
1226 if (!p_ri) | |
1227 inc_cursor(); | |
1228 | |
1229 return tempc; | |
1230 case 'h': | |
1231 if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) | |
1232 { | |
1233 if (p_ri) | |
1234 chg_c_to_X_or_X (); | |
1235 | |
1236 } | |
1237 | |
1238 if (!p_ri) | |
1239 if (!curwin->w_cursor.col) | |
1240 return ALEF; | |
1241 | |
1242 if (!p_ri) | |
1243 dec_cursor(); | |
1244 | |
1245 if (gchar_cursor() == _LAM) | |
1246 { | |
1247 chg_l_toXor_X(); | |
1248 del_char(FALSE); | |
1249 AppendCharToRedobuff(K_BS); | |
1250 | |
1251 if (!p_ri) | |
1252 dec_cursor(); | |
1253 | |
1254 tempc = LA; | |
1255 } | |
1256 else | |
1257 { | |
1258 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
1259 { | |
1260 tempc = ALEF_; | |
1261 chg_l_toXor_X (); | |
1262 } | |
1263 else | |
1264 tempc = ALEF; | |
1265 } | |
1266 | |
1267 if (!p_ri) | |
1268 inc_cursor(); | |
1269 | |
1270 return tempc; | |
1271 case 'i': | |
1272 if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) | |
1273 { | |
1274 if (!p_ri && !F_is_TyE(tempc)) | |
1275 chg_c_to_X_orX_ (); | |
1276 if (p_ri) | |
1277 chg_c_to_X_or_X (); | |
1278 | |
1279 } | |
1280 | |
1281 if (!p_ri && !curwin->w_cursor.col) | |
1282 return _HE; | |
1283 | |
1284 if (!p_ri) | |
1285 dec_cursor(); | |
1286 | |
1287 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
1288 tempc = _HE_; | |
1289 else | |
1290 tempc = _HE; | |
1291 | |
1292 if (!p_ri) | |
1293 inc_cursor(); | |
1294 break; | |
1295 case 'j': | |
1296 tempc = _TE; | |
1297 break; | |
1298 case 'J': | |
1299 if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) | |
1300 { | |
1301 if (p_ri) | |
1302 chg_c_to_X_or_X (); | |
1303 | |
1304 } | |
1305 | |
1306 if (!p_ri) | |
1307 if (!curwin->w_cursor.col) | |
1308 return TEE; | |
1309 | |
1310 if (!p_ri) | |
1311 dec_cursor(); | |
1312 | |
1313 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
1314 { | |
1315 tempc = TEE_; | |
1316 chg_l_toXor_X (); | |
1317 } | |
1318 else | |
1319 tempc = TEE; | |
1320 | |
1321 if (!p_ri) | |
1322 inc_cursor(); | |
1323 | |
1324 return tempc; | |
1325 case 'k': | |
1326 tempc = _NOON; | |
1327 break; | |
1328 case 'l': | |
1329 tempc = _MIM; | |
1330 break; | |
1331 case 'm': | |
1332 tempc = _PE; | |
1333 break; | |
1334 case 'n': | |
1335 case 'N': | |
1336 tempc = DAL; | |
1337 break; | |
1338 case 'o': | |
1339 tempc = _XE; | |
1340 break; | |
1341 case 'p': | |
1342 tempc = _HE_J; | |
1343 break; | |
1344 case 'q': | |
1345 tempc = _ZAD; | |
1346 break; | |
1347 case 'r': | |
1348 tempc = _GHAF; | |
1349 break; | |
1350 case 's': | |
1351 tempc = _SIN; | |
1352 break; | |
1353 case 'S': | |
1354 tempc = _IE; | |
1355 break; | |
1356 case 't': | |
1357 tempc = _FE; | |
1358 break; | |
1359 case 'u': | |
1360 if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) | |
1361 { | |
1362 if (!p_ri && !F_is_TyE(tempc)) | |
1363 chg_c_to_X_orX_ (); | |
1364 if (p_ri) | |
1365 chg_c_to_X_or_X (); | |
1366 | |
1367 } | |
1368 | |
1369 if (!p_ri && !curwin->w_cursor.col) | |
1370 return _AYN; | |
1371 | |
1372 if (!p_ri) | |
1373 dec_cursor(); | |
1374 | |
1375 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
1376 tempc = _AYN_; | |
1377 else | |
1378 tempc = _AYN; | |
1379 | |
1380 if (!p_ri) | |
1381 inc_cursor(); | |
1382 break; | |
1383 case 'v': | |
1384 case 'V': | |
1385 tempc = RE; | |
1386 break; | |
1387 case 'w': | |
1388 tempc = _SAD; | |
1389 break; | |
1390 case 'x': | |
1391 case 'X': | |
1392 tempc = _TA; | |
1393 break; | |
1394 case 'y': | |
1395 if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) | |
1396 { | |
1397 if (!p_ri && !F_is_TyE(tempc)) | |
1398 chg_c_to_X_orX_ (); | |
1399 if (p_ri) | |
1400 chg_c_to_X_or_X (); | |
1401 | |
1402 } | |
1403 | |
1404 if (!p_ri && !curwin->w_cursor.col) | |
1405 return _GHAYN; | |
1406 | |
1407 if (!p_ri) | |
1408 dec_cursor(); | |
1409 | |
1410 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)) | |
1411 tempc = _GHAYN_; | |
1412 else | |
1413 tempc = _GHAYN; | |
1414 | |
1415 if (!p_ri) | |
1416 inc_cursor(); | |
1417 | |
1418 break; | |
1419 case 'z': | |
1420 tempc = _ZA; | |
1421 break; | |
1422 case 'Z': | |
1423 tempc = _KAF_H; | |
1424 break; | |
1425 case ';': | |
1426 tempc = _KAF; | |
1427 break; | |
1428 case '\'': | |
1429 tempc = _GAF; | |
1430 break; | |
1431 case ',': | |
1432 tempc = WAW; | |
1433 break; | |
1434 case '[': | |
1435 tempc = _JIM; | |
1436 break; | |
1437 case ']': | |
1438 tempc = _CHE; | |
1439 break; | |
1440 } | |
1441 | |
1442 if ((F_isalpha(tempc) || F_isdigit(tempc))) | |
1443 { | |
1444 if (!curwin->w_cursor.col && STRLEN(ml_get_curline())) | |
1445 { | |
1446 if (!p_ri && !F_is_TyE(tempc)) | |
1447 chg_c_to_X_orX_ (); | |
1448 if (p_ri) | |
1449 chg_c_to_X_or_X (); | |
1450 } | |
1451 | |
1452 if (curwin->w_cursor.col) | |
1453 { | |
1454 if (!p_ri) | |
1455 dec_cursor(); | |
1456 | |
1457 if (F_is_TyE(tempc)) | |
1458 chg_l_toXor_X (); | |
1459 else | |
1460 chg_l_to_X_orX_ (); | |
1461 | |
1462 if (!p_ri) | |
1463 inc_cursor(); | |
1464 } | |
1465 } | |
1466 if (tempc) | |
1467 return tempc; | |
1468 return c; | |
1469 } | |
1470 | |
1471 /* | |
1472 ** Convert a none leading Farsi char into a leading type. | |
1473 */ | |
1474 static int | |
1475 toF_leading(c) | |
1476 int c; | |
1477 { | |
1478 switch (c) | |
1479 { | |
1480 case ALEF_: return ALEF; | |
1481 case ALEF_U_H_: return ALEF_U_H; | |
1482 case BE: return _BE; | |
1483 case PE: return _PE; | |
1484 case TE: return _TE; | |
1485 case SE: return _SE; | |
1486 case JIM: return _JIM; | |
1487 case CHE: return _CHE; | |
1488 case HE_J: return _HE_J; | |
1489 case XE: return _XE; | |
1490 case SIN: return _SIN; | |
1491 case SHIN: return _SHIN; | |
1492 case SAD: return _SAD; | |
1493 case ZAD: return _ZAD; | |
1494 | |
1495 case AYN: | |
1496 case AYN_: | |
1497 case _AYN_: return _AYN; | |
1498 | |
1499 case GHAYN: | |
1500 case GHAYN_: | |
1501 case _GHAYN_: return _GHAYN; | |
1502 | |
1503 case FE: return _FE; | |
1504 case GHAF: return _GHAF; | |
1505 case KAF: return _KAF; | |
1506 case GAF: return _GAF; | |
1507 case LAM: return _LAM; | |
1508 case MIM: return _MIM; | |
1509 case NOON: return _NOON; | |
1510 | |
1511 case _HE_: | |
1512 case F_HE: return _HE; | |
1513 | |
1514 case YE: | |
1515 case YE_: return _YE; | |
1516 | |
1517 case IE_: | |
1518 case IE: return _IE; | |
1519 | |
1520 case YEE: | |
1521 case YEE_: return _YEE; | |
1522 } | |
1523 return c; | |
1524 } | |
1525 | |
1526 /* | |
1527 ** Convert a given Farsi char into right joining type. | |
1528 */ | |
1529 static int | |
1530 toF_Rjoin(c) | |
1531 int c; | |
1532 { | |
1533 switch (c) | |
1534 { | |
1535 case ALEF: return ALEF_; | |
1536 case ALEF_U_H: return ALEF_U_H_; | |
1537 case BE: return _BE; | |
1538 case PE: return _PE; | |
1539 case TE: return _TE; | |
1540 case SE: return _SE; | |
1541 case JIM: return _JIM; | |
1542 case CHE: return _CHE; | |
1543 case HE_J: return _HE_J; | |
1544 case XE: return _XE; | |
1545 case SIN: return _SIN; | |
1546 case SHIN: return _SHIN; | |
1547 case SAD: return _SAD; | |
1548 case ZAD: return _ZAD; | |
1549 | |
1550 case AYN: | |
1551 case AYN_: | |
1552 case _AYN: return _AYN_; | |
1553 | |
1554 case GHAYN: | |
1555 case GHAYN_: | |
1556 case _GHAYN_: return _GHAYN_; | |
1557 | |
1558 case FE: return _FE; | |
1559 case GHAF: return _GHAF; | |
1560 case KAF: return _KAF; | |
1561 case GAF: return _GAF; | |
1562 case LAM: return _LAM; | |
1563 case MIM: return _MIM; | |
1564 case NOON: return _NOON; | |
1565 | |
1566 case _HE: | |
1567 case F_HE: return _HE_; | |
1568 | |
1569 case YE: | |
1570 case YE_: return _YE; | |
1571 | |
1572 case IE_: | |
1573 case IE: return _IE; | |
1574 | |
1575 case TEE: return TEE_; | |
1576 | |
1577 case YEE: | |
1578 case YEE_: return _YEE; | |
1579 } | |
1580 return c; | |
1581 } | |
1582 | |
1583 /* | |
1584 ** Can a given Farsi character join via its left edj. | |
1585 */ | |
1586 static int | |
1587 canF_Ljoin(c) | |
1588 int c; | |
1589 { | |
1590 switch (c) | |
1591 { | |
1592 case _BE: | |
1593 case BE: | |
1594 case PE: | |
1595 case _PE: | |
1596 case TE: | |
1597 case _TE: | |
1598 case SE: | |
1599 case _SE: | |
1600 case JIM: | |
1601 case _JIM: | |
1602 case CHE: | |
1603 case _CHE: | |
1604 case HE_J: | |
1605 case _HE_J: | |
1606 case XE: | |
1607 case _XE: | |
1608 case SIN: | |
1609 case _SIN: | |
1610 case SHIN: | |
1611 case _SHIN: | |
1612 case SAD: | |
1613 case _SAD: | |
1614 case ZAD: | |
1615 case _ZAD: | |
1616 case _TA: | |
1617 case _ZA: | |
1618 case AYN: | |
1619 case _AYN: | |
1620 case _AYN_: | |
1621 case AYN_: | |
1622 case GHAYN: | |
1623 case GHAYN_: | |
1624 case _GHAYN_: | |
1625 case _GHAYN: | |
1626 case FE: | |
1627 case _FE: | |
1628 case GHAF: | |
1629 case _GHAF: | |
1630 case _KAF_H: | |
1631 case KAF: | |
1632 case _KAF: | |
1633 case GAF: | |
1634 case _GAF: | |
1635 case LAM: | |
1636 case _LAM: | |
1637 case MIM: | |
1638 case _MIM: | |
1639 case NOON: | |
1640 case _NOON: | |
1641 case IE: | |
1642 case _IE: | |
1643 case IE_: | |
1644 case YE: | |
1645 case _YE: | |
1646 case YE_: | |
1647 case YEE: | |
1648 case _YEE: | |
1649 case YEE_: | |
1650 case F_HE: | |
1651 case _HE: | |
1652 case _HE_: | |
1653 return TRUE; | |
1654 } | |
1655 return FALSE; | |
1656 } | |
1657 | |
1658 /* | |
1659 ** Can a given Farsi character join via its right edj. | |
1660 */ | |
1661 static int | |
1662 canF_Rjoin(c) | |
1663 int c; | |
1664 { | |
1665 switch (c) | |
1666 { | |
1667 case ALEF: | |
1668 case ALEF_: | |
1669 case ALEF_U_H: | |
1670 case ALEF_U_H_: | |
1671 case DAL: | |
1672 case ZAL: | |
1673 case RE: | |
1674 case JE: | |
1675 case ZE: | |
1676 case TEE: | |
1677 case TEE_: | |
1678 case WAW: | |
1679 case WAW_H: | |
1680 return TRUE; | |
1681 } | |
1682 | |
1683 return canF_Ljoin(c); | |
1684 | |
1685 } | |
1686 | |
1687 /* | |
1688 ** is a given Farsi character a terminating type. | |
1689 */ | |
1690 static int | |
1691 F_isterm(c) | |
1692 int c; | |
1693 { | |
1694 switch (c) | |
1695 { | |
1696 case ALEF: | |
1697 case ALEF_: | |
1698 case ALEF_U_H: | |
1699 case ALEF_U_H_: | |
1700 case DAL: | |
1701 case ZAL: | |
1702 case RE: | |
1703 case JE: | |
1704 case ZE: | |
1705 case WAW: | |
1706 case WAW_H: | |
1707 case TEE: | |
1708 case TEE_: | |
1709 return TRUE; | |
1710 } | |
1711 | |
1712 return FALSE; | |
1713 } | |
1714 | |
1715 /* | |
1716 ** Convert the given Farsi character into a ending type . | |
1717 */ | |
1718 static int | |
1719 toF_ending(c) | |
1720 int c; | |
1721 { | |
1722 | |
1723 switch (c) | |
1724 { | |
1725 case _BE: | |
1726 return BE; | |
1727 case _PE: | |
1728 return PE; | |
1729 case _TE: | |
1730 return TE; | |
1731 case _SE: | |
1732 return SE; | |
1733 case _JIM: | |
1734 return JIM; | |
1735 case _CHE: | |
1736 return CHE; | |
1737 case _HE_J: | |
1738 return HE_J; | |
1739 case _XE: | |
1740 return XE; | |
1741 case _SIN: | |
1742 return SIN; | |
1743 case _SHIN: | |
1744 return SHIN; | |
1745 case _SAD: | |
1746 return SAD; | |
1747 case _ZAD: | |
1748 return ZAD; | |
1749 case _AYN: | |
1750 return AYN; | |
1751 case _AYN_: | |
1752 return AYN_; | |
1753 case _GHAYN: | |
1754 return GHAYN; | |
1755 case _GHAYN_: | |
1756 return GHAYN_; | |
1757 case _FE: | |
1758 return FE; | |
1759 case _GHAF: | |
1760 return GHAF; | |
1761 case _KAF_H: | |
1762 case _KAF: | |
1763 return KAF; | |
1764 case _GAF: | |
1765 return GAF; | |
1766 case _LAM: | |
1767 return LAM; | |
1768 case _MIM: | |
1769 return MIM; | |
1770 case _NOON: | |
1771 return NOON; | |
1772 case _YE: | |
1773 return YE_; | |
1774 case YE_: | |
1775 return YE; | |
1776 case _YEE: | |
1777 return YEE_; | |
1778 case YEE_: | |
1779 return YEE; | |
1780 case TEE: | |
1781 return TEE_; | |
1782 case _IE: | |
1783 return IE_; | |
1784 case IE_: | |
1785 return IE; | |
1786 case _HE: | |
1787 case _HE_: | |
1788 return F_HE; | |
1789 } | |
1790 return c; | |
1791 } | |
1792 | |
1793 /* | |
1794 ** Convert the Farsi 3342 standard into Farsi VIM. | |
1795 */ | |
1796 void | |
1797 conv_to_pvim() | |
1798 { | |
1799 char_u *ptr; | |
1800 int lnum, llen, i; | |
1801 | |
1802 for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) | |
1803 { | |
1804 ptr = ml_get((linenr_T)lnum); | |
1805 | |
1806 llen = (int)STRLEN(ptr); | |
1807 | |
1808 for ( i = 0; i < llen-1; i++) | |
1809 { | |
1810 if (canF_Ljoin(ptr[i]) && canF_Rjoin(ptr[i+1])) | |
1811 { | |
1812 ptr[i] = toF_leading(ptr[i]); | |
1813 ++i; | |
1814 | |
1815 while(canF_Rjoin(ptr[i]) && (i < llen)) | |
1816 { | |
1817 ptr[i] = toF_Rjoin(ptr[i]); | |
1818 if (F_isterm(ptr[i]) || !F_isalpha(ptr[i])) | |
1819 break; | |
1820 ++i; | |
1821 } | |
1822 if (!F_isalpha(ptr[i]) || !canF_Rjoin(ptr[i])) | |
1823 ptr[i-1] = toF_ending(ptr[i-1]); | |
1824 } | |
1825 else | |
1826 ptr[i] = toF_TyA(ptr[i]); | |
1827 } | |
1828 } | |
1829 | |
1830 /* | |
1831 * Following lines contains Farsi encoded character. | |
1832 */ | |
1833 | |
1834 do_cmdline_cmd((char_u *)"%s/\202\231/\232/g"); | |
1835 do_cmdline_cmd((char_u *)"%s/\201\231/\370\334/g"); | |
1836 | |
1837 /* Assume the screen has been messed up: clear it and redraw. */ | |
1838 redraw_later(CLEAR); | |
1839 MSG_ATTR(farsi_text_1, hl_attr(HLF_S)); | |
1840 } | |
1841 | |
1842 /* | |
1843 * Convert the Farsi VIM into Farsi 3342 standad. | |
1844 */ | |
1845 void | |
1846 conv_to_pstd() | |
1847 { | |
1848 char_u *ptr; | |
1849 int lnum, llen, i; | |
1850 | |
1851 /* | |
1852 * Following line contains Farsi encoded character. | |
1853 */ | |
1854 | |
1855 do_cmdline_cmd((char_u *)"%s/\232/\202\231/g"); | |
1856 | |
1857 for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum) | |
1858 { | |
1859 ptr = ml_get((linenr_T)lnum); | |
1860 | |
1861 llen = (int)STRLEN(ptr); | |
1862 | |
1863 for ( i = 0; i < llen; i++) | |
1864 { | |
1865 ptr[i] = toF_TyA(ptr[i]); | |
1866 | |
1867 } | |
1868 } | |
1869 | |
1870 /* Assume the screen has been messed up: clear it and redraw. */ | |
1871 redraw_later(CLEAR); | |
1872 MSG_ATTR(farsi_text_2, hl_attr(HLF_S)); | |
1873 } | |
1874 | |
1875 /* | |
1876 * left-right swap the characters in buf[len]. | |
1877 */ | |
1878 static void | |
1879 lrswapbuf(buf, len) | |
1880 char_u *buf; | |
1881 int len; | |
1882 { | |
1883 char_u *s, *e; | |
1884 int c; | |
1885 | |
1886 s = buf; | |
1887 e = buf + len - 1; | |
1888 | |
1889 while (e > s) | |
1890 { | |
1891 c = *s; | |
1892 *s = *e; | |
1893 *e = c; | |
1894 ++s; | |
1895 --e; | |
1896 } | |
1897 } | |
1898 | |
1899 /* | |
1900 * swap all the characters in reverse direction | |
1901 */ | |
1902 char_u * | |
1903 lrswap(ibuf) | |
1904 char_u *ibuf; | |
1905 { | |
1906 if (ibuf != NULL && *ibuf != NUL) | |
1907 lrswapbuf(ibuf, (int)STRLEN(ibuf)); | |
1908 return ibuf; | |
1909 } | |
1910 | |
1911 /* | |
1912 * swap all the Farsi characters in reverse direction | |
1913 */ | |
1914 char_u * | |
1915 lrFswap(cmdbuf, len) | |
1916 char_u *cmdbuf; | |
1917 int len; | |
1918 { | |
1919 int i, cnt; | |
1920 | |
1921 if (cmdbuf == NULL) | |
1922 return cmdbuf; | |
1923 | |
1924 if (len == 0 && (len = (int)STRLEN(cmdbuf)) == 0) | |
1925 return cmdbuf; | |
1926 | |
1927 for (i = 0; i < len; i++) | |
1928 { | |
1929 for (cnt = 0; i + cnt < len | |
1930 && (F_isalpha(cmdbuf[i + cnt]) | |
1931 || F_isdigit(cmdbuf[i + cnt]) | |
1932 || cmdbuf[i + cnt] == ' '); ++cnt) | |
1933 ; | |
1934 | |
1935 lrswapbuf(cmdbuf + i, cnt); | |
1936 i += cnt; | |
1937 } | |
1938 return cmdbuf; | |
1939 } | |
1940 | |
1941 /* | |
1942 * Reverse the characters in the seach path and substitude section accordingly | |
1943 */ | |
1944 char_u * | |
1945 lrF_sub(ibuf) | |
1946 char_u *ibuf; | |
1947 { | |
1948 char_u *p, *ep; | |
1949 int i, cnt; | |
1950 | |
1951 p = ibuf; | |
1952 | |
1953 /* Find the boundry of the search path */ | |
1954 while (((p = vim_strchr(++p, '/')) != NULL) && p[-1] == '\\') | |
1955 ; | |
1956 | |
1957 if (p == NULL) | |
1958 return ibuf; | |
1959 | |
1960 /* Reverse the Farsi characters in the search path. */ | |
1961 lrFswap(ibuf, (int)(p-ibuf)); | |
1962 | |
1963 /* Now find the boundry of the substitute section */ | |
1964 if ((ep = (char_u *)strrchr((char *)++p, '/')) != NULL) | |
1965 cnt = (int)(ep - p); | |
1966 else | |
1967 cnt = (int)STRLEN(p); | |
1968 | |
1969 /* Reverse the characters in the substitute section and take care of '\' */ | |
1970 for (i = 0; i < cnt-1; i++) | |
1971 if (p[i] == '\\') | |
1972 { | |
1973 p[i] = p[i+1] ; | |
1974 p[++i] = '\\'; | |
1975 } | |
1976 | |
1977 lrswapbuf(p, cnt); | |
1978 | |
1979 return ibuf; | |
1980 } | |
1981 | |
1982 /* | |
1983 * Map Farsi keyboard when in cmd_fkmap mode. | |
1984 */ | |
1985 int | |
1986 cmdl_fkmap(c) | |
1987 int c; | |
1988 { | |
1989 int tempc; | |
1990 | |
1991 switch (c) | |
1992 { | |
1993 case '0': | |
1994 case '1': | |
1995 case '2': | |
1996 case '3': | |
1997 case '4': | |
1998 case '5': | |
1999 case '6': | |
2000 case '7': | |
2001 case '8': | |
2002 case '9': | |
2003 case '`': | |
2004 case ' ': | |
2005 case '.': | |
2006 case '!': | |
2007 case '"': | |
2008 case '$': | |
2009 case '%': | |
2010 case '^': | |
2011 case '&': | |
2012 case '/': | |
2013 case '(': | |
2014 case ')': | |
2015 case '=': | |
2016 case '\\': | |
2017 case '?': | |
2018 case '+': | |
2019 case '-': | |
2020 case '_': | |
2021 case '*': | |
2022 case ':': | |
2023 case '#': | |
2024 case '~': | |
2025 case '@': | |
2026 case '<': | |
2027 case '>': | |
2028 case '{': | |
2029 case '}': | |
2030 case '|': | |
2031 case 'B': | |
2032 case 'E': | |
2033 case 'F': | |
2034 case 'H': | |
2035 case 'I': | |
2036 case 'K': | |
2037 case 'L': | |
2038 case 'M': | |
2039 case 'O': | |
2040 case 'P': | |
2041 case 'Q': | |
2042 case 'R': | |
2043 case 'T': | |
2044 case 'U': | |
2045 case 'W': | |
2046 case 'Y': | |
2047 case NL: | |
2048 case TAB: | |
2049 | |
2050 switch ((tempc = cmd_gchar(AT_CURSOR))) | |
2051 { | |
2052 case _BE: | |
2053 case _PE: | |
2054 case _TE: | |
2055 case _SE: | |
2056 case _JIM: | |
2057 case _CHE: | |
2058 case _HE_J: | |
2059 case _XE: | |
2060 case _SIN: | |
2061 case _SHIN: | |
2062 case _SAD: | |
2063 case _ZAD: | |
2064 case _AYN: | |
2065 case _GHAYN: | |
2066 case _FE: | |
2067 case _GHAF: | |
2068 case _KAF: | |
2069 case _GAF: | |
2070 case _LAM: | |
2071 case _MIM: | |
2072 case _NOON: | |
2073 case _HE: | |
2074 case _HE_: | |
2075 cmd_pchar(toF_TyA(tempc), AT_CURSOR); | |
2076 break; | |
2077 case _AYN_: | |
2078 cmd_pchar(AYN_, AT_CURSOR); | |
2079 break; | |
2080 case _GHAYN_: | |
2081 cmd_pchar(GHAYN_, AT_CURSOR); | |
2082 break; | |
2083 case _IE: | |
2084 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1)) | |
2085 cmd_pchar(IE_, AT_CURSOR); | |
2086 else | |
2087 cmd_pchar(IE, AT_CURSOR); | |
2088 break; | |
2089 case _YEE: | |
2090 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1)) | |
2091 cmd_pchar(YEE_, AT_CURSOR); | |
2092 else | |
2093 cmd_pchar(YEE, AT_CURSOR); | |
2094 break; | |
2095 case _YE: | |
2096 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1)) | |
2097 cmd_pchar(YE_, AT_CURSOR); | |
2098 else | |
2099 cmd_pchar(YE, AT_CURSOR); | |
2100 } | |
2101 | |
2102 switch (c) | |
2103 { | |
2104 case '0': return FARSI_0; | |
2105 case '1': return FARSI_1; | |
2106 case '2': return FARSI_2; | |
2107 case '3': return FARSI_3; | |
2108 case '4': return FARSI_4; | |
2109 case '5': return FARSI_5; | |
2110 case '6': return FARSI_6; | |
2111 case '7': return FARSI_7; | |
2112 case '8': return FARSI_8; | |
2113 case '9': return FARSI_9; | |
2114 case 'B': return F_PSP; | |
2115 case 'E': return JAZR_N; | |
2116 case 'F': return ALEF_D_H; | |
2117 case 'H': return ALEF_A; | |
2118 case 'I': return TASH; | |
2119 case 'K': return F_LQUOT; | |
2120 case 'L': return F_RQUOT; | |
2121 case 'M': return HAMZE; | |
2122 case 'O': return '['; | |
2123 case 'P': return ']'; | |
2124 case 'Q': return OO; | |
2125 case 'R': return MAD_N; | |
2126 case 'T': return OW; | |
2127 case 'U': return MAD; | |
2128 case 'W': return OW_OW; | |
2129 case 'Y': return JAZR; | |
2130 case '`': return F_PCN; | |
2131 case '!': return F_EXCL; | |
2132 case '@': return F_COMMA; | |
2133 case '#': return F_DIVIDE; | |
2134 case '$': return F_CURRENCY; | |
2135 case '%': return F_PERCENT; | |
2136 case '^': return F_MUL; | |
2137 case '&': return F_BCOMMA; | |
2138 case '*': return F_STAR; | |
2139 case '(': return F_LPARENT; | |
2140 case ')': return F_RPARENT; | |
2141 case '-': return F_MINUS; | |
2142 case '_': return F_UNDERLINE; | |
2143 case '=': return F_EQUALS; | |
2144 case '+': return F_PLUS; | |
2145 case '\\': return F_BSLASH; | |
2146 case '|': return F_PIPE; | |
2147 case ':': return F_DCOLON; | |
2148 case '"': return F_SEMICOLON; | |
2149 case '.': return F_PERIOD; | |
2150 case '/': return F_SLASH; | |
2151 case '<': return F_LESS; | |
2152 case '>': return F_GREATER; | |
2153 case '?': return F_QUESTION; | |
2154 case ' ': return F_BLANK; | |
2155 } | |
2156 | |
2157 break; | |
2158 | |
2159 case 'a': return _SHIN; | |
2160 case 'A': return WAW_H; | |
2161 case 'b': return ZAL; | |
2162 case 'c': return ZE; | |
2163 case 'C': return JE; | |
2164 case 'd': return _YE; | |
2165 case 'D': return _YEE; | |
2166 case 'e': return _SE; | |
2167 case 'f': return _BE; | |
2168 case 'g': return _LAM; | |
2169 case 'G': | |
2170 if (cmd_gchar(AT_CURSOR) == _LAM ) | |
2171 { | |
2172 cmd_pchar(LAM, AT_CURSOR); | |
2173 return ALEF_U_H; | |
2174 } | |
2175 | |
2176 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR)) | |
2177 return ALEF_U_H_; | |
2178 else | |
2179 return ALEF_U_H; | |
2180 case 'h': | |
2181 if (cmd_gchar(AT_CURSOR) == _LAM ) | |
2182 { | |
2183 cmd_pchar(LA, AT_CURSOR); | |
2184 redrawcmdline(); | |
2185 return K_IGNORE; | |
2186 } | |
2187 | |
2188 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR)) | |
2189 return ALEF_; | |
2190 else | |
2191 return ALEF; | |
2192 case 'i': | |
2193 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR)) | |
2194 return _HE_; | |
2195 else | |
2196 return _HE; | |
2197 case 'j': return _TE; | |
2198 case 'J': | |
2199 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR)) | |
2200 return TEE_; | |
2201 else | |
2202 return TEE; | |
2203 case 'k': return _NOON; | |
2204 case 'l': return _MIM; | |
2205 case 'm': return _PE; | |
2206 case 'n': | |
2207 case 'N': return DAL; | |
2208 case 'o': return _XE; | |
2209 case 'p': return _HE_J; | |
2210 case 'q': return _ZAD; | |
2211 case 'r': return _GHAF; | |
2212 case 's': return _SIN; | |
2213 case 'S': return _IE; | |
2214 case 't': return _FE; | |
2215 case 'u': | |
2216 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR)) | |
2217 return _AYN_; | |
2218 else | |
2219 return _AYN; | |
2220 case 'v': | |
2221 case 'V': return RE; | |
2222 case 'w': return _SAD; | |
2223 case 'x': | |
2224 case 'X': return _TA; | |
2225 case 'y': | |
2226 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR)) | |
2227 return _GHAYN_; | |
2228 else | |
2229 return _GHAYN; | |
2230 case 'z': | |
2231 case 'Z': return _ZA; | |
2232 case ';': return _KAF; | |
2233 case '\'': return _GAF; | |
2234 case ',': return WAW; | |
2235 case '[': return _JIM; | |
2236 case ']': return _CHE; | |
2237 } | |
2238 | |
2239 return c; | |
2240 } | |
2241 | |
2242 /* | |
2243 * F_isalpha returns TRUE if 'c' is a Farsi alphabet | |
2244 */ | |
2245 int | |
2246 F_isalpha(c) | |
2247 int c; | |
2248 { | |
2249 return (( c >= TEE_ && c <= _YE) | |
2250 || (c >= ALEF_A && c <= YE) | |
2251 || (c >= _IE && c <= YE_)); | |
2252 } | |
2253 | |
2254 /* | |
2255 * F_isdigit returns TRUE if 'c' is a Farsi digit | |
2256 */ | |
2257 int | |
2258 F_isdigit(c) | |
2259 int c; | |
2260 { | |
2261 return (c >= FARSI_0 && c <= FARSI_9); | |
2262 } | |
2263 | |
2264 /* | |
2265 * F_ischar returns TRUE if 'c' is a Farsi character. | |
2266 */ | |
2267 int | |
2268 F_ischar(c) | |
2269 int c; | |
2270 { | |
2271 return (c >= TEE_ && c <= YE_); | |
2272 } | |
2273 | |
2274 void | |
2275 farsi_fkey(cap) | |
2276 cmdarg_T *cap; | |
2277 { | |
2278 int c = cap->cmdchar; | |
2279 | |
2280 if (c == K_F8) | |
2281 { | |
2282 if (p_altkeymap) | |
2283 { | |
2284 if (curwin->w_farsi & W_R_L) | |
2285 { | |
2286 p_fkmap = 0; | |
2287 do_cmdline_cmd((char_u *)"set norl"); | |
2288 MSG(""); | |
2289 } | |
2290 else | |
2291 { | |
2292 p_fkmap = 1; | |
2293 do_cmdline_cmd((char_u *)"set rl"); | |
2294 MSG(""); | |
2295 } | |
2296 | |
2297 curwin->w_farsi = curwin->w_farsi ^ W_R_L; | |
2298 } | |
2299 } | |
2300 | |
2301 if (c == K_F9) | |
2302 { | |
2303 if (p_altkeymap && curwin->w_p_rl) | |
2304 { | |
2305 curwin->w_farsi = curwin->w_farsi ^ W_CONV; | |
2306 if (curwin->w_farsi & W_CONV) | |
2307 conv_to_pvim(); | |
2308 else | |
2309 conv_to_pstd(); | |
2310 } | |
2311 } | |
2312 } |