Merge branch 'vim' into feat/emb-common-lisp
[vim_extended.git] / src / farsi.c
blob271e1a720e0451794de810b6257ce1e0f92482f6
1 /* vi:set ts=8 sts=4 sw=4:
3 * VIM - Vi IMproved by Bram Moolenaar
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 */
11 * farsi.c: functions for Farsi language
13 * Included by main.c, when FEAT_FKMAP is defined.
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));
38 ** Convert the given Farsi character into a _X or _X_ type
40 static int
41 toF_Xor_X_(c)
42 int c;
44 int tempc;
46 switch (c)
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;
106 if (p_ri && (curwin->w_cursor.col + 1
107 < (colnr_T)STRLEN(ml_get_curline())))
109 inc_cursor();
111 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
112 tempc = _HE_;
114 dec_cursor();
116 if (!p_ri && STRLEN(ml_get_curline()))
118 dec_cursor();
120 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
121 tempc = _HE_;
123 inc_cursor();
126 return tempc;
128 return 0;
132 ** Convert the given Farsi character into Farsi capital character .
135 toF_TyA(c)
136 int c ;
138 switch (c)
140 case ALEF_:
141 return ALEF;
142 case ALEF_U_H_:
143 return ALEF_U_H;
144 case _BE:
145 return BE;
146 case _PE:
147 return PE;
148 case _TE:
149 return TE;
150 case _SE:
151 return SE;
152 case _JIM:
153 return JIM;
154 case _CHE:
155 return CHE;
156 case _HE_J:
157 return HE_J;
158 case _XE:
159 return XE;
160 case _SIN:
161 return SIN;
162 case _SHIN:
163 return SHIN;
164 case _SAD:
165 return SAD;
166 case _ZAD:
167 return ZAD;
168 case _AYN:
169 case AYN_:
170 case _AYN_:
171 return AYN;
172 case _GHAYN:
173 case GHAYN_:
174 case _GHAYN_:
175 return GHAYN;
176 case _FE:
177 return FE;
178 case _GHAF:
179 return GHAF;
180 /* I am not sure what it is !!! case _KAF_H: */
181 case _KAF:
182 return KAF;
183 case _GAF:
184 return GAF;
185 case _LAM:
186 return LAM;
187 case _MIM:
188 return MIM;
189 case _NOON:
190 return NOON;
191 case _YE:
192 case YE_:
193 return YE;
194 case _YEE:
195 case YEE_:
196 return YEE;
197 case TEE_:
198 return TEE;
199 case _IE:
200 case IE_:
201 return IE;
202 case _HE:
203 case _HE_:
204 return F_HE;
206 return c;
210 ** Is the character under the cursor+offset in the given buffer a join type.
211 ** That is a character that is combined with the others.
212 ** Note: the offset is used only for command line buffer.
214 static int
215 F_is_TyB_TyC_TyD(src, offset)
216 int src, offset;
218 int c;
220 if (src == SRC_EDT)
221 c = gchar_cursor();
222 else
223 c = cmd_gchar(AT_CURSOR+offset);
225 switch (c)
227 case _LAM:
228 case _BE:
229 case _PE:
230 case _TE:
231 case _SE:
232 case _JIM:
233 case _CHE:
234 case _HE_J:
235 case _XE:
236 case _SIN:
237 case _SHIN:
238 case _SAD:
239 case _ZAD:
240 case _TA:
241 case _ZA:
242 case _AYN:
243 case _AYN_:
244 case _GHAYN:
245 case _GHAYN_:
246 case _FE:
247 case _GHAF:
248 case _KAF:
249 case _KAF_H:
250 case _GAF:
251 case _MIM:
252 case _NOON:
253 case _YE:
254 case _YEE:
255 case _IE:
256 case _HE_:
257 case _HE:
258 return TRUE;
260 return FALSE;
264 ** Is the Farsi character one of the terminating only type.
266 static int
267 F_is_TyE(c)
268 int c;
270 switch (c)
272 case ALEF_A:
273 case ALEF_D_H:
274 case DAL:
275 case ZAL:
276 case RE:
277 case ZE:
278 case JE:
279 case WAW:
280 case WAW_H:
281 case HAMZE:
282 return TRUE;
284 return FALSE;
288 ** Is the Farsi character one of the none leading type.
290 static int
291 F_is_TyC_TyD(c)
292 int c;
294 switch (c)
296 case ALEF_:
297 case ALEF_U_H_:
298 case _AYN_:
299 case AYN_:
300 case _GHAYN_:
301 case GHAYN_:
302 case _HE_:
303 case YE_:
304 case IE_:
305 case TEE_:
306 case YEE_:
307 return TRUE;
309 return FALSE;
313 ** Convert a none leading Farsi char into a leading type.
315 static int
316 toF_TyB(c)
317 int c;
319 switch (c)
321 case ALEF_: return ALEF;
322 case ALEF_U_H_: return ALEF_U_H;
323 case _AYN_: return _AYN;
324 case AYN_: return AYN; /* exception - there are many of them */
325 case _GHAYN_: return _GHAYN;
326 case GHAYN_: return GHAYN; /* exception - there are many of them */
327 case _HE_: return _HE;
328 case YE_: return YE;
329 case IE_: return IE;
330 case TEE_: return TEE;
331 case YEE_: return YEE;
333 return c;
337 ** Overwrite the current redo and cursor characters + left adjust
339 static void
340 put_curr_and_l_to_X(c)
341 int c;
343 int tempc;
345 if (curwin->w_p_rl && p_ri)
346 return;
348 if ((curwin->w_cursor.col < (colnr_T)STRLEN(ml_get_curline())))
350 if ((p_ri && curwin->w_cursor.col) || !p_ri)
352 if (p_ri)
353 dec_cursor();
354 else
355 inc_cursor();
357 if (F_is_TyC_TyD((tempc = gchar_cursor())))
359 pchar_cursor(toF_TyB(tempc));
360 AppendCharToRedobuff(K_BS);
361 AppendCharToRedobuff(tempc);
364 if (p_ri)
365 inc_cursor();
366 else
367 dec_cursor();
371 put_and_redo(c);
374 static void
375 put_and_redo(c)
376 int c;
378 pchar_cursor(c);
379 AppendCharToRedobuff(K_BS);
380 AppendCharToRedobuff(c);
384 ** Change the char. under the cursor to a X_ or X type
386 static void
387 chg_c_toX_orX()
389 int tempc, curc;
391 switch ((curc = gchar_cursor()))
393 case _BE:
394 tempc = BE;
395 break;
396 case _PE:
397 tempc = PE;
398 break;
399 case _TE:
400 tempc = TE;
401 break;
402 case _SE:
403 tempc = SE;
404 break;
405 case _JIM:
406 tempc = JIM;
407 break;
408 case _CHE:
409 tempc = CHE;
410 break;
411 case _HE_J:
412 tempc = HE_J;
413 break;
414 case _XE:
415 tempc = XE;
416 break;
417 case _SIN:
418 tempc = SIN;
419 break;
420 case _SHIN:
421 tempc = SHIN;
422 break;
423 case _SAD:
424 tempc = SAD;
425 break;
426 case _ZAD:
427 tempc = ZAD;
428 break;
429 case _FE:
430 tempc = FE;
431 break;
432 case _GHAF:
433 tempc = GHAF;
434 break;
435 case _KAF_H:
436 case _KAF:
437 tempc = KAF;
438 break;
439 case _GAF:
440 tempc = GAF;
441 break;
442 case _AYN:
443 tempc = AYN;
444 break;
445 case _AYN_:
446 tempc = AYN_;
447 break;
448 case _GHAYN:
449 tempc = GHAYN;
450 break;
451 case _GHAYN_:
452 tempc = GHAYN_;
453 break;
454 case _LAM:
455 tempc = LAM;
456 break;
457 case _MIM:
458 tempc = MIM;
459 break;
460 case _NOON:
461 tempc = NOON;
462 break;
463 case _HE:
464 case _HE_:
465 tempc = F_HE;
466 break;
467 case _YE:
468 case _IE:
469 case _YEE:
470 if (p_ri)
472 inc_cursor();
473 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
474 tempc = (curc == _YE ? YE_ :
475 (curc == _IE ? IE_ : YEE_));
476 else
477 tempc = (curc == _YE ? YE :
478 (curc == _IE ? IE : YEE));
479 dec_cursor();
481 else
483 if (curwin->w_cursor.col)
485 dec_cursor();
486 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
487 tempc = (curc == _YE ? YE_ :
488 (curc == _IE ? IE_ : YEE_));
489 else
490 tempc = (curc == _YE ? YE :
491 (curc == _IE ? IE : YEE));
492 inc_cursor();
494 else
495 tempc = (curc == _YE ? YE :
496 (curc == _IE ? IE : YEE));
498 break;
499 default:
500 tempc = 0;
503 if (tempc)
504 put_and_redo(tempc);
508 ** Change the char. under the cursor to a _X_ or X_ type
511 static void
512 chg_c_to_X_orX_()
514 int tempc;
516 switch (gchar_cursor())
518 case ALEF:
519 tempc = ALEF_;
520 break;
521 case ALEF_U_H:
522 tempc = ALEF_U_H_;
523 break;
524 case _AYN:
525 tempc = _AYN_;
526 break;
527 case AYN:
528 tempc = AYN_;
529 break;
530 case _GHAYN:
531 tempc = _GHAYN_;
532 break;
533 case GHAYN:
534 tempc = GHAYN_;
535 break;
536 case _HE:
537 tempc = _HE_;
538 break;
539 case YE:
540 tempc = YE_;
541 break;
542 case IE:
543 tempc = IE_;
544 break;
545 case TEE:
546 tempc = TEE_;
547 break;
548 case YEE:
549 tempc = YEE_;
550 break;
551 default:
552 tempc = 0;
555 if (tempc)
556 put_and_redo(tempc);
560 ** Change the char. under the cursor to a _X_ or _X type
562 static void
563 chg_c_to_X_or_X ()
565 int tempc;
567 tempc = gchar_cursor();
569 if (curwin->w_cursor.col + 1 < (colnr_T)STRLEN(ml_get_curline()))
571 inc_cursor();
573 if ((tempc == F_HE) && (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)))
575 tempc = _HE_;
577 dec_cursor();
579 put_and_redo(tempc);
580 return;
583 dec_cursor();
586 if ((tempc = toF_Xor_X_(tempc)) != 0)
587 put_and_redo(tempc);
591 ** Change the character left to the cursor to a _X_ or X_ type
593 static void
594 chg_l_to_X_orX_ ()
596 int tempc;
598 if (curwin->w_cursor.col != 0 &&
599 (curwin->w_cursor.col + 1 == (colnr_T)STRLEN(ml_get_curline())))
600 return;
602 if (!curwin->w_cursor.col && p_ri)
603 return;
605 if (p_ri)
606 dec_cursor();
607 else
608 inc_cursor();
610 switch (gchar_cursor())
612 case ALEF:
613 tempc = ALEF_;
614 break;
615 case ALEF_U_H:
616 tempc = ALEF_U_H_;
617 break;
618 case _AYN:
619 tempc = _AYN_;
620 break;
621 case AYN:
622 tempc = AYN_;
623 break;
624 case _GHAYN:
625 tempc = _GHAYN_;
626 break;
627 case GHAYN:
628 tempc = GHAYN_;
629 break;
630 case _HE:
631 tempc = _HE_;
632 break;
633 case YE:
634 tempc = YE_;
635 break;
636 case IE:
637 tempc = IE_;
638 break;
639 case TEE:
640 tempc = TEE_;
641 break;
642 case YEE:
643 tempc = YEE_;
644 break;
645 default:
646 tempc = 0;
649 if (tempc)
650 put_and_redo(tempc);
652 if (p_ri)
653 inc_cursor();
654 else
655 dec_cursor();
659 ** Change the character left to the cursor to a X or _X type
662 static void
663 chg_l_toXor_X ()
665 int tempc;
667 if (curwin->w_cursor.col != 0 &&
668 (curwin->w_cursor.col + 1 == (colnr_T)STRLEN(ml_get_curline())))
669 return;
671 if (!curwin->w_cursor.col && p_ri)
672 return;
674 if (p_ri)
675 dec_cursor();
676 else
677 inc_cursor();
679 switch (gchar_cursor())
681 case ALEF_:
682 tempc = ALEF;
683 break;
684 case ALEF_U_H_:
685 tempc = ALEF_U_H;
686 break;
687 case _AYN_:
688 tempc = _AYN;
689 break;
690 case AYN_:
691 tempc = AYN;
692 break;
693 case _GHAYN_:
694 tempc = _GHAYN;
695 break;
696 case GHAYN_:
697 tempc = GHAYN;
698 break;
699 case _HE_:
700 tempc = _HE;
701 break;
702 case YE_:
703 tempc = YE;
704 break;
705 case IE_:
706 tempc = IE;
707 break;
708 case TEE_:
709 tempc = TEE;
710 break;
711 case YEE_:
712 tempc = YEE;
713 break;
714 default:
715 tempc = 0;
718 if (tempc)
719 put_and_redo(tempc);
721 if (p_ri)
722 inc_cursor();
723 else
724 dec_cursor();
728 ** Change the character right to the cursor to a _X or _X_ type
731 static void
732 chg_r_to_Xor_X_()
734 int tempc, c;
736 if (curwin->w_cursor.col)
738 if (!p_ri)
739 dec_cursor();
741 tempc = gchar_cursor();
743 if ((c = toF_Xor_X_(tempc)) != 0)
744 put_and_redo(c);
746 if (!p_ri)
747 inc_cursor();
753 ** Map Farsi keyboard when in fkmap mode.
757 fkmap(c)
758 int c;
760 int tempc;
761 static int revins;
763 if (IS_SPECIAL(c))
764 return c;
766 if (VIM_ISDIGIT(c) || ((c == '.' || c == '+' || c == '-' ||
767 c == '^' || c == '%' || c == '#' || c == '=') && revins))
769 if (!revins)
771 if (curwin->w_cursor.col)
773 if (!p_ri)
774 dec_cursor();
776 chg_c_toX_orX ();
777 chg_l_toXor_X ();
779 if (!p_ri)
780 inc_cursor();
784 arrow_used = TRUE;
785 (void)stop_arrow();
787 if (!curwin->w_p_rl && revins)
788 inc_cursor();
790 ++revins;
791 p_ri=1;
793 else
795 if (revins)
797 arrow_used = TRUE;
798 (void)stop_arrow();
800 revins = 0;
801 if (curwin->w_p_rl)
803 while ((F_isdigit(gchar_cursor())
804 || (gchar_cursor() == F_PERIOD
805 || gchar_cursor() == F_PLUS
806 || gchar_cursor() == F_MINUS
807 || gchar_cursor() == F_MUL
808 || gchar_cursor() == F_DIVIDE
809 || gchar_cursor() == F_PERCENT
810 || gchar_cursor() == F_EQUALS))
811 && gchar_cursor() != NUL)
812 ++curwin->w_cursor.col;
814 else
816 if (curwin->w_cursor.col)
817 while ((F_isdigit(gchar_cursor())
818 || (gchar_cursor() == F_PERIOD
819 || gchar_cursor() == F_PLUS
820 || gchar_cursor() == F_MINUS
821 || gchar_cursor() == F_MUL
822 || gchar_cursor() == F_DIVIDE
823 || gchar_cursor() == F_PERCENT
824 || gchar_cursor() == F_EQUALS))
825 && --curwin->w_cursor.col)
828 if (!F_isdigit(gchar_cursor()))
829 ++curwin->w_cursor.col;
834 if (!revins)
836 if (curwin->w_p_rl)
837 p_ri=0;
838 if (!curwin->w_p_rl)
839 p_ri=1;
842 if ((c < 0x100) && (isalpha(c) || c == '&' || c == '^' || c == ';' ||
843 c == '\''|| c == ',' || c == '[' ||
844 c == ']' || c == '{' || c == '}' ))
845 chg_r_to_Xor_X_();
847 tempc = 0;
849 switch (c)
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 '|':
879 case '0':
880 case '1':
881 case '2':
882 case '3':
883 case '4':
884 case '5':
885 case '6':
886 case '7':
887 case '8':
888 case '9':
889 case 'B':
890 case 'E':
891 case 'F':
892 case 'H':
893 case 'I':
894 case 'K':
895 case 'L':
896 case 'M':
897 case 'O':
898 case 'P':
899 case 'Q':
900 case 'R':
901 case 'T':
902 case 'U':
903 case 'W':
904 case 'Y':
905 case NL:
906 case TAB:
908 if (p_ri && c == NL && curwin->w_cursor.col)
911 ** If the char before the cursor is _X_ or X_ do not change
912 ** the one under the cursor with X type.
915 dec_cursor();
917 if (F_isalpha(gchar_cursor()))
919 inc_cursor();
920 return NL;
923 inc_cursor();
926 if (!p_ri)
927 if (!curwin->w_cursor.col)
929 switch (c)
931 case '0': return FARSI_0;
932 case '1': return FARSI_1;
933 case '2': return FARSI_2;
934 case '3': return FARSI_3;
935 case '4': return FARSI_4;
936 case '5': return FARSI_5;
937 case '6': return FARSI_6;
938 case '7': return FARSI_7;
939 case '8': return FARSI_8;
940 case '9': return FARSI_9;
941 case 'B': return F_PSP;
942 case 'E': return JAZR_N;
943 case 'F': return ALEF_D_H;
944 case 'H': return ALEF_A;
945 case 'I': return TASH;
946 case 'K': return F_LQUOT;
947 case 'L': return F_RQUOT;
948 case 'M': return HAMZE;
949 case 'O': return '[';
950 case 'P': return ']';
951 case 'Q': return OO;
952 case 'R': return MAD_N;
953 case 'T': return OW;
954 case 'U': return MAD;
955 case 'W': return OW_OW;
956 case 'Y': return JAZR;
957 case '`': return F_PCN;
958 case '!': return F_EXCL;
959 case '@': return F_COMMA;
960 case '#': return F_DIVIDE;
961 case '$': return F_CURRENCY;
962 case '%': return F_PERCENT;
963 case '^': return F_MUL;
964 case '&': return F_BCOMMA;
965 case '*': return F_STAR;
966 case '(': return F_LPARENT;
967 case ')': return F_RPARENT;
968 case '-': return F_MINUS;
969 case '_': return F_UNDERLINE;
970 case '=': return F_EQUALS;
971 case '+': return F_PLUS;
972 case '\\': return F_BSLASH;
973 case '|': return F_PIPE;
974 case ':': return F_DCOLON;
975 case '"': return F_SEMICOLON;
976 case '.': return F_PERIOD;
977 case '/': return F_SLASH;
978 case '<': return F_LESS;
979 case '>': return F_GREATER;
980 case '?': return F_QUESTION;
981 case ' ': return F_BLANK;
983 break;
985 if (!p_ri)
986 dec_cursor();
988 switch ((tempc = gchar_cursor()))
990 case _BE:
991 case _PE:
992 case _TE:
993 case _SE:
994 case _JIM:
995 case _CHE:
996 case _HE_J:
997 case _XE:
998 case _SIN:
999 case _SHIN:
1000 case _SAD:
1001 case _ZAD:
1002 case _FE:
1003 case _GHAF:
1004 case _KAF:
1005 case _KAF_H:
1006 case _GAF:
1007 case _LAM:
1008 case _MIM:
1009 case _NOON:
1010 case _HE:
1011 case _HE_:
1012 case _TA:
1013 case _ZA:
1014 put_curr_and_l_to_X(toF_TyA(tempc));
1015 break;
1016 case _AYN:
1017 case _AYN_:
1019 if (!p_ri)
1020 if (!curwin->w_cursor.col)
1022 put_curr_and_l_to_X(AYN);
1023 break;
1026 if (p_ri)
1027 inc_cursor();
1028 else
1029 dec_cursor();
1031 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1032 tempc = AYN_;
1033 else
1034 tempc = AYN;
1036 if (p_ri)
1037 dec_cursor();
1038 else
1039 inc_cursor();
1041 put_curr_and_l_to_X(tempc);
1043 break;
1044 case _GHAYN:
1045 case _GHAYN_:
1047 if (!p_ri)
1048 if (!curwin->w_cursor.col)
1050 put_curr_and_l_to_X(GHAYN);
1051 break;
1054 if (p_ri)
1055 inc_cursor();
1056 else
1057 dec_cursor();
1059 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1060 tempc = GHAYN_;
1061 else
1062 tempc = GHAYN;
1064 if (p_ri)
1065 dec_cursor();
1066 else
1067 inc_cursor();
1069 put_curr_and_l_to_X(tempc);
1070 break;
1071 case _YE:
1072 case _IE:
1073 case _YEE:
1074 if (!p_ri)
1075 if (!curwin->w_cursor.col)
1077 put_curr_and_l_to_X((tempc == _YE ? YE :
1078 (tempc == _IE ? IE : YEE)));
1079 break;
1082 if (p_ri)
1083 inc_cursor();
1084 else
1085 dec_cursor();
1087 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1088 tempc = (tempc == _YE ? YE_ :
1089 (tempc == _IE ? IE_ : YEE_));
1090 else
1091 tempc = (tempc == _YE ? YE :
1092 (tempc == _IE ? IE : YEE));
1094 if (p_ri)
1095 dec_cursor();
1096 else
1097 inc_cursor();
1099 put_curr_and_l_to_X(tempc);
1100 break;
1103 if (!p_ri)
1104 inc_cursor();
1106 tempc = 0;
1108 switch (c)
1110 case '0': return FARSI_0;
1111 case '1': return FARSI_1;
1112 case '2': return FARSI_2;
1113 case '3': return FARSI_3;
1114 case '4': return FARSI_4;
1115 case '5': return FARSI_5;
1116 case '6': return FARSI_6;
1117 case '7': return FARSI_7;
1118 case '8': return FARSI_8;
1119 case '9': return FARSI_9;
1120 case 'B': return F_PSP;
1121 case 'E': return JAZR_N;
1122 case 'F': return ALEF_D_H;
1123 case 'H': return ALEF_A;
1124 case 'I': return TASH;
1125 case 'K': return F_LQUOT;
1126 case 'L': return F_RQUOT;
1127 case 'M': return HAMZE;
1128 case 'O': return '[';
1129 case 'P': return ']';
1130 case 'Q': return OO;
1131 case 'R': return MAD_N;
1132 case 'T': return OW;
1133 case 'U': return MAD;
1134 case 'W': return OW_OW;
1135 case 'Y': return JAZR;
1136 case '`': return F_PCN;
1137 case '!': return F_EXCL;
1138 case '@': return F_COMMA;
1139 case '#': return F_DIVIDE;
1140 case '$': return F_CURRENCY;
1141 case '%': return F_PERCENT;
1142 case '^': return F_MUL;
1143 case '&': return F_BCOMMA;
1144 case '*': return F_STAR;
1145 case '(': return F_LPARENT;
1146 case ')': return F_RPARENT;
1147 case '-': return F_MINUS;
1148 case '_': return F_UNDERLINE;
1149 case '=': return F_EQUALS;
1150 case '+': return F_PLUS;
1151 case '\\': return F_BSLASH;
1152 case '|': return F_PIPE;
1153 case ':': return F_DCOLON;
1154 case '"': return F_SEMICOLON;
1155 case '.': return F_PERIOD;
1156 case '/': return F_SLASH;
1157 case '<': return F_LESS;
1158 case '>': return F_GREATER;
1159 case '?': return F_QUESTION;
1160 case ' ': return F_BLANK;
1162 break;
1164 case 'a':
1165 tempc = _SHIN;
1166 break;
1167 case 'A':
1168 tempc = WAW_H;
1169 break;
1170 case 'b':
1171 tempc = ZAL;
1172 break;
1173 case 'c':
1174 tempc = ZE;
1175 break;
1176 case 'C':
1177 tempc = JE;
1178 break;
1179 case 'd':
1180 tempc = _YE;
1181 break;
1182 case 'D':
1183 tempc = _YEE;
1184 break;
1185 case 'e':
1186 tempc = _SE;
1187 break;
1188 case 'f':
1189 tempc = _BE;
1190 break;
1191 case 'g':
1192 tempc = _LAM;
1193 break;
1194 case 'G':
1195 if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
1198 if (gchar_cursor() == _LAM)
1199 chg_c_toX_orX ();
1200 else
1201 if (p_ri)
1202 chg_c_to_X_or_X ();
1205 if (!p_ri)
1206 if (!curwin->w_cursor.col)
1207 return ALEF_U_H;
1209 if (!p_ri)
1210 dec_cursor();
1212 if (gchar_cursor() == _LAM)
1214 chg_c_toX_orX ();
1215 chg_l_toXor_X ();
1216 tempc = ALEF_U_H;
1218 else
1219 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1221 tempc = ALEF_U_H_;
1222 chg_l_toXor_X ();
1224 else
1225 tempc = ALEF_U_H;
1227 if (!p_ri)
1228 inc_cursor();
1230 return tempc;
1231 case 'h':
1232 if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
1234 if (p_ri)
1235 chg_c_to_X_or_X ();
1239 if (!p_ri)
1240 if (!curwin->w_cursor.col)
1241 return ALEF;
1243 if (!p_ri)
1244 dec_cursor();
1246 if (gchar_cursor() == _LAM)
1248 chg_l_toXor_X();
1249 del_char(FALSE);
1250 AppendCharToRedobuff(K_BS);
1252 if (!p_ri)
1253 dec_cursor();
1255 tempc = LA;
1257 else
1259 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1261 tempc = ALEF_;
1262 chg_l_toXor_X ();
1264 else
1265 tempc = ALEF;
1268 if (!p_ri)
1269 inc_cursor();
1271 return tempc;
1272 case 'i':
1273 if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
1275 if (!p_ri && !F_is_TyE(tempc))
1276 chg_c_to_X_orX_ ();
1277 if (p_ri)
1278 chg_c_to_X_or_X ();
1282 if (!p_ri && !curwin->w_cursor.col)
1283 return _HE;
1285 if (!p_ri)
1286 dec_cursor();
1288 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1289 tempc = _HE_;
1290 else
1291 tempc = _HE;
1293 if (!p_ri)
1294 inc_cursor();
1295 break;
1296 case 'j':
1297 tempc = _TE;
1298 break;
1299 case 'J':
1300 if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
1302 if (p_ri)
1303 chg_c_to_X_or_X ();
1307 if (!p_ri)
1308 if (!curwin->w_cursor.col)
1309 return TEE;
1311 if (!p_ri)
1312 dec_cursor();
1314 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1316 tempc = TEE_;
1317 chg_l_toXor_X ();
1319 else
1320 tempc = TEE;
1322 if (!p_ri)
1323 inc_cursor();
1325 return tempc;
1326 case 'k':
1327 tempc = _NOON;
1328 break;
1329 case 'l':
1330 tempc = _MIM;
1331 break;
1332 case 'm':
1333 tempc = _PE;
1334 break;
1335 case 'n':
1336 case 'N':
1337 tempc = DAL;
1338 break;
1339 case 'o':
1340 tempc = _XE;
1341 break;
1342 case 'p':
1343 tempc = _HE_J;
1344 break;
1345 case 'q':
1346 tempc = _ZAD;
1347 break;
1348 case 'r':
1349 tempc = _GHAF;
1350 break;
1351 case 's':
1352 tempc = _SIN;
1353 break;
1354 case 'S':
1355 tempc = _IE;
1356 break;
1357 case 't':
1358 tempc = _FE;
1359 break;
1360 case 'u':
1361 if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
1363 if (!p_ri && !F_is_TyE(tempc))
1364 chg_c_to_X_orX_ ();
1365 if (p_ri)
1366 chg_c_to_X_or_X ();
1370 if (!p_ri && !curwin->w_cursor.col)
1371 return _AYN;
1373 if (!p_ri)
1374 dec_cursor();
1376 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1377 tempc = _AYN_;
1378 else
1379 tempc = _AYN;
1381 if (!p_ri)
1382 inc_cursor();
1383 break;
1384 case 'v':
1385 case 'V':
1386 tempc = RE;
1387 break;
1388 case 'w':
1389 tempc = _SAD;
1390 break;
1391 case 'x':
1392 case 'X':
1393 tempc = _TA;
1394 break;
1395 case 'y':
1396 if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
1398 if (!p_ri && !F_is_TyE(tempc))
1399 chg_c_to_X_orX_ ();
1400 if (p_ri)
1401 chg_c_to_X_or_X ();
1405 if (!p_ri && !curwin->w_cursor.col)
1406 return _GHAYN;
1408 if (!p_ri)
1409 dec_cursor();
1411 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1412 tempc = _GHAYN_;
1413 else
1414 tempc = _GHAYN;
1416 if (!p_ri)
1417 inc_cursor();
1419 break;
1420 case 'z':
1421 tempc = _ZA;
1422 break;
1423 case 'Z':
1424 tempc = _KAF_H;
1425 break;
1426 case ';':
1427 tempc = _KAF;
1428 break;
1429 case '\'':
1430 tempc = _GAF;
1431 break;
1432 case ',':
1433 tempc = WAW;
1434 break;
1435 case '[':
1436 tempc = _JIM;
1437 break;
1438 case ']':
1439 tempc = _CHE;
1440 break;
1443 if ((F_isalpha(tempc) || F_isdigit(tempc)))
1445 if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
1447 if (!p_ri && !F_is_TyE(tempc))
1448 chg_c_to_X_orX_ ();
1449 if (p_ri)
1450 chg_c_to_X_or_X ();
1453 if (curwin->w_cursor.col)
1455 if (!p_ri)
1456 dec_cursor();
1458 if (F_is_TyE(tempc))
1459 chg_l_toXor_X ();
1460 else
1461 chg_l_to_X_orX_ ();
1463 if (!p_ri)
1464 inc_cursor();
1467 if (tempc)
1468 return tempc;
1469 return c;
1473 ** Convert a none leading Farsi char into a leading type.
1475 static int
1476 toF_leading(c)
1477 int c;
1479 switch (c)
1481 case ALEF_: return ALEF;
1482 case ALEF_U_H_: return ALEF_U_H;
1483 case BE: return _BE;
1484 case PE: return _PE;
1485 case TE: return _TE;
1486 case SE: return _SE;
1487 case JIM: return _JIM;
1488 case CHE: return _CHE;
1489 case HE_J: return _HE_J;
1490 case XE: return _XE;
1491 case SIN: return _SIN;
1492 case SHIN: return _SHIN;
1493 case SAD: return _SAD;
1494 case ZAD: return _ZAD;
1496 case AYN:
1497 case AYN_:
1498 case _AYN_: return _AYN;
1500 case GHAYN:
1501 case GHAYN_:
1502 case _GHAYN_: return _GHAYN;
1504 case FE: return _FE;
1505 case GHAF: return _GHAF;
1506 case KAF: return _KAF;
1507 case GAF: return _GAF;
1508 case LAM: return _LAM;
1509 case MIM: return _MIM;
1510 case NOON: return _NOON;
1512 case _HE_:
1513 case F_HE: return _HE;
1515 case YE:
1516 case YE_: return _YE;
1518 case IE_:
1519 case IE: return _IE;
1521 case YEE:
1522 case YEE_: return _YEE;
1524 return c;
1528 ** Convert a given Farsi char into right joining type.
1530 static int
1531 toF_Rjoin(c)
1532 int c;
1534 switch (c)
1536 case ALEF: return ALEF_;
1537 case ALEF_U_H: return ALEF_U_H_;
1538 case BE: return _BE;
1539 case PE: return _PE;
1540 case TE: return _TE;
1541 case SE: return _SE;
1542 case JIM: return _JIM;
1543 case CHE: return _CHE;
1544 case HE_J: return _HE_J;
1545 case XE: return _XE;
1546 case SIN: return _SIN;
1547 case SHIN: return _SHIN;
1548 case SAD: return _SAD;
1549 case ZAD: return _ZAD;
1551 case AYN:
1552 case AYN_:
1553 case _AYN: return _AYN_;
1555 case GHAYN:
1556 case GHAYN_:
1557 case _GHAYN_: return _GHAYN_;
1559 case FE: return _FE;
1560 case GHAF: return _GHAF;
1561 case KAF: return _KAF;
1562 case GAF: return _GAF;
1563 case LAM: return _LAM;
1564 case MIM: return _MIM;
1565 case NOON: return _NOON;
1567 case _HE:
1568 case F_HE: return _HE_;
1570 case YE:
1571 case YE_: return _YE;
1573 case IE_:
1574 case IE: return _IE;
1576 case TEE: return TEE_;
1578 case YEE:
1579 case YEE_: return _YEE;
1581 return c;
1585 ** Can a given Farsi character join via its left edj.
1587 static int
1588 canF_Ljoin(c)
1589 int c;
1591 switch (c)
1593 case _BE:
1594 case BE:
1595 case PE:
1596 case _PE:
1597 case TE:
1598 case _TE:
1599 case SE:
1600 case _SE:
1601 case JIM:
1602 case _JIM:
1603 case CHE:
1604 case _CHE:
1605 case HE_J:
1606 case _HE_J:
1607 case XE:
1608 case _XE:
1609 case SIN:
1610 case _SIN:
1611 case SHIN:
1612 case _SHIN:
1613 case SAD:
1614 case _SAD:
1615 case ZAD:
1616 case _ZAD:
1617 case _TA:
1618 case _ZA:
1619 case AYN:
1620 case _AYN:
1621 case _AYN_:
1622 case AYN_:
1623 case GHAYN:
1624 case GHAYN_:
1625 case _GHAYN_:
1626 case _GHAYN:
1627 case FE:
1628 case _FE:
1629 case GHAF:
1630 case _GHAF:
1631 case _KAF_H:
1632 case KAF:
1633 case _KAF:
1634 case GAF:
1635 case _GAF:
1636 case LAM:
1637 case _LAM:
1638 case MIM:
1639 case _MIM:
1640 case NOON:
1641 case _NOON:
1642 case IE:
1643 case _IE:
1644 case IE_:
1645 case YE:
1646 case _YE:
1647 case YE_:
1648 case YEE:
1649 case _YEE:
1650 case YEE_:
1651 case F_HE:
1652 case _HE:
1653 case _HE_:
1654 return TRUE;
1656 return FALSE;
1660 ** Can a given Farsi character join via its right edj.
1662 static int
1663 canF_Rjoin(c)
1664 int c;
1666 switch (c)
1668 case ALEF:
1669 case ALEF_:
1670 case ALEF_U_H:
1671 case ALEF_U_H_:
1672 case DAL:
1673 case ZAL:
1674 case RE:
1675 case JE:
1676 case ZE:
1677 case TEE:
1678 case TEE_:
1679 case WAW:
1680 case WAW_H:
1681 return TRUE;
1684 return canF_Ljoin(c);
1689 ** is a given Farsi character a terminating type.
1691 static int
1692 F_isterm(c)
1693 int c;
1695 switch (c)
1697 case ALEF:
1698 case ALEF_:
1699 case ALEF_U_H:
1700 case ALEF_U_H_:
1701 case DAL:
1702 case ZAL:
1703 case RE:
1704 case JE:
1705 case ZE:
1706 case WAW:
1707 case WAW_H:
1708 case TEE:
1709 case TEE_:
1710 return TRUE;
1713 return FALSE;
1717 ** Convert the given Farsi character into a ending type .
1719 static int
1720 toF_ending(c)
1721 int c;
1724 switch (c)
1726 case _BE:
1727 return BE;
1728 case _PE:
1729 return PE;
1730 case _TE:
1731 return TE;
1732 case _SE:
1733 return SE;
1734 case _JIM:
1735 return JIM;
1736 case _CHE:
1737 return CHE;
1738 case _HE_J:
1739 return HE_J;
1740 case _XE:
1741 return XE;
1742 case _SIN:
1743 return SIN;
1744 case _SHIN:
1745 return SHIN;
1746 case _SAD:
1747 return SAD;
1748 case _ZAD:
1749 return ZAD;
1750 case _AYN:
1751 return AYN;
1752 case _AYN_:
1753 return AYN_;
1754 case _GHAYN:
1755 return GHAYN;
1756 case _GHAYN_:
1757 return GHAYN_;
1758 case _FE:
1759 return FE;
1760 case _GHAF:
1761 return GHAF;
1762 case _KAF_H:
1763 case _KAF:
1764 return KAF;
1765 case _GAF:
1766 return GAF;
1767 case _LAM:
1768 return LAM;
1769 case _MIM:
1770 return MIM;
1771 case _NOON:
1772 return NOON;
1773 case _YE:
1774 return YE_;
1775 case YE_:
1776 return YE;
1777 case _YEE:
1778 return YEE_;
1779 case YEE_:
1780 return YEE;
1781 case TEE:
1782 return TEE_;
1783 case _IE:
1784 return IE_;
1785 case IE_:
1786 return IE;
1787 case _HE:
1788 case _HE_:
1789 return F_HE;
1791 return c;
1795 ** Convert the Farsi 3342 standard into Farsi VIM.
1797 void
1798 conv_to_pvim()
1800 char_u *ptr;
1801 int lnum, llen, i;
1803 for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
1805 ptr = ml_get((linenr_T)lnum);
1807 llen = (int)STRLEN(ptr);
1809 for ( i = 0; i < llen-1; i++)
1811 if (canF_Ljoin(ptr[i]) && canF_Rjoin(ptr[i+1]))
1813 ptr[i] = toF_leading(ptr[i]);
1814 ++i;
1816 while(canF_Rjoin(ptr[i]) && (i < llen))
1818 ptr[i] = toF_Rjoin(ptr[i]);
1819 if (F_isterm(ptr[i]) || !F_isalpha(ptr[i]))
1820 break;
1821 ++i;
1823 if (!F_isalpha(ptr[i]) || !canF_Rjoin(ptr[i]))
1824 ptr[i-1] = toF_ending(ptr[i-1]);
1826 else
1827 ptr[i] = toF_TyA(ptr[i]);
1832 * Following lines contains Farsi encoded character.
1835 do_cmdline_cmd((char_u *)"%s/\202\231/\232/g");
1836 do_cmdline_cmd((char_u *)"%s/\201\231/\370\334/g");
1838 /* Assume the screen has been messed up: clear it and redraw. */
1839 redraw_later(CLEAR);
1840 MSG_ATTR(farsi_text_1, hl_attr(HLF_S));
1844 * Convert the Farsi VIM into Farsi 3342 standad.
1846 void
1847 conv_to_pstd()
1849 char_u *ptr;
1850 int lnum, llen, i;
1853 * Following line contains Farsi encoded character.
1856 do_cmdline_cmd((char_u *)"%s/\232/\202\231/g");
1858 for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
1860 ptr = ml_get((linenr_T)lnum);
1862 llen = (int)STRLEN(ptr);
1864 for ( i = 0; i < llen; i++)
1866 ptr[i] = toF_TyA(ptr[i]);
1871 /* Assume the screen has been messed up: clear it and redraw. */
1872 redraw_later(CLEAR);
1873 MSG_ATTR(farsi_text_2, hl_attr(HLF_S));
1877 * left-right swap the characters in buf[len].
1879 static void
1880 lrswapbuf(buf, len)
1881 char_u *buf;
1882 int len;
1884 char_u *s, *e;
1885 int c;
1887 s = buf;
1888 e = buf + len - 1;
1890 while (e > s)
1892 c = *s;
1893 *s = *e;
1894 *e = c;
1895 ++s;
1896 --e;
1901 * swap all the characters in reverse direction
1903 char_u *
1904 lrswap(ibuf)
1905 char_u *ibuf;
1907 if (ibuf != NULL && *ibuf != NUL)
1908 lrswapbuf(ibuf, (int)STRLEN(ibuf));
1909 return ibuf;
1913 * swap all the Farsi characters in reverse direction
1915 char_u *
1916 lrFswap(cmdbuf, len)
1917 char_u *cmdbuf;
1918 int len;
1920 int i, cnt;
1922 if (cmdbuf == NULL)
1923 return cmdbuf;
1925 if (len == 0 && (len = (int)STRLEN(cmdbuf)) == 0)
1926 return cmdbuf;
1928 for (i = 0; i < len; i++)
1930 for (cnt = 0; i + cnt < len
1931 && (F_isalpha(cmdbuf[i + cnt])
1932 || F_isdigit(cmdbuf[i + cnt])
1933 || cmdbuf[i + cnt] == ' '); ++cnt)
1936 lrswapbuf(cmdbuf + i, cnt);
1937 i += cnt;
1939 return cmdbuf;
1943 * Reverse the characters in the search path and substitute section
1944 * accordingly.
1945 * TODO: handle different separator characters. Use skip_regexp().
1947 char_u *
1948 lrF_sub(ibuf)
1949 char_u *ibuf;
1951 char_u *p, *ep;
1952 int i, cnt;
1954 p = ibuf;
1956 /* Find the boundary of the search path */
1957 while (((p = vim_strchr(p + 1, '/')) != NULL) && p[-1] == '\\')
1960 if (p == NULL)
1961 return ibuf;
1963 /* Reverse the Farsi characters in the search path. */
1964 lrFswap(ibuf, (int)(p-ibuf));
1966 /* Now find the boundary of the substitute section */
1967 if ((ep = (char_u *)strrchr((char *)++p, '/')) != NULL)
1968 cnt = (int)(ep - p);
1969 else
1970 cnt = (int)STRLEN(p);
1972 /* Reverse the characters in the substitute section and take care of '\' */
1973 for (i = 0; i < cnt-1; i++)
1974 if (p[i] == '\\')
1976 p[i] = p[i+1] ;
1977 p[++i] = '\\';
1980 lrswapbuf(p, cnt);
1982 return ibuf;
1986 * Map Farsi keyboard when in cmd_fkmap mode.
1989 cmdl_fkmap(c)
1990 int c;
1992 int tempc;
1994 switch (c)
1996 case '0':
1997 case '1':
1998 case '2':
1999 case '3':
2000 case '4':
2001 case '5':
2002 case '6':
2003 case '7':
2004 case '8':
2005 case '9':
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 '{':
2032 case '}':
2033 case '|':
2034 case 'B':
2035 case 'E':
2036 case 'F':
2037 case 'H':
2038 case 'I':
2039 case 'K':
2040 case 'L':
2041 case 'M':
2042 case 'O':
2043 case 'P':
2044 case 'Q':
2045 case 'R':
2046 case 'T':
2047 case 'U':
2048 case 'W':
2049 case 'Y':
2050 case NL:
2051 case TAB:
2053 switch ((tempc = cmd_gchar(AT_CURSOR)))
2055 case _BE:
2056 case _PE:
2057 case _TE:
2058 case _SE:
2059 case _JIM:
2060 case _CHE:
2061 case _HE_J:
2062 case _XE:
2063 case _SIN:
2064 case _SHIN:
2065 case _SAD:
2066 case _ZAD:
2067 case _AYN:
2068 case _GHAYN:
2069 case _FE:
2070 case _GHAF:
2071 case _KAF:
2072 case _GAF:
2073 case _LAM:
2074 case _MIM:
2075 case _NOON:
2076 case _HE:
2077 case _HE_:
2078 cmd_pchar(toF_TyA(tempc), AT_CURSOR);
2079 break;
2080 case _AYN_:
2081 cmd_pchar(AYN_, AT_CURSOR);
2082 break;
2083 case _GHAYN_:
2084 cmd_pchar(GHAYN_, AT_CURSOR);
2085 break;
2086 case _IE:
2087 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
2088 cmd_pchar(IE_, AT_CURSOR);
2089 else
2090 cmd_pchar(IE, AT_CURSOR);
2091 break;
2092 case _YEE:
2093 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
2094 cmd_pchar(YEE_, AT_CURSOR);
2095 else
2096 cmd_pchar(YEE, AT_CURSOR);
2097 break;
2098 case _YE:
2099 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
2100 cmd_pchar(YE_, AT_CURSOR);
2101 else
2102 cmd_pchar(YE, AT_CURSOR);
2105 switch (c)
2107 case '0': return FARSI_0;
2108 case '1': return FARSI_1;
2109 case '2': return FARSI_2;
2110 case '3': return FARSI_3;
2111 case '4': return FARSI_4;
2112 case '5': return FARSI_5;
2113 case '6': return FARSI_6;
2114 case '7': return FARSI_7;
2115 case '8': return FARSI_8;
2116 case '9': return FARSI_9;
2117 case 'B': return F_PSP;
2118 case 'E': return JAZR_N;
2119 case 'F': return ALEF_D_H;
2120 case 'H': return ALEF_A;
2121 case 'I': return TASH;
2122 case 'K': return F_LQUOT;
2123 case 'L': return F_RQUOT;
2124 case 'M': return HAMZE;
2125 case 'O': return '[';
2126 case 'P': return ']';
2127 case 'Q': return OO;
2128 case 'R': return MAD_N;
2129 case 'T': return OW;
2130 case 'U': return MAD;
2131 case 'W': return OW_OW;
2132 case 'Y': return JAZR;
2133 case '`': return F_PCN;
2134 case '!': return F_EXCL;
2135 case '@': return F_COMMA;
2136 case '#': return F_DIVIDE;
2137 case '$': return F_CURRENCY;
2138 case '%': return F_PERCENT;
2139 case '^': return F_MUL;
2140 case '&': return F_BCOMMA;
2141 case '*': return F_STAR;
2142 case '(': return F_LPARENT;
2143 case ')': return F_RPARENT;
2144 case '-': return F_MINUS;
2145 case '_': return F_UNDERLINE;
2146 case '=': return F_EQUALS;
2147 case '+': return F_PLUS;
2148 case '\\': return F_BSLASH;
2149 case '|': return F_PIPE;
2150 case ':': return F_DCOLON;
2151 case '"': return F_SEMICOLON;
2152 case '.': return F_PERIOD;
2153 case '/': return F_SLASH;
2154 case '<': return F_LESS;
2155 case '>': return F_GREATER;
2156 case '?': return F_QUESTION;
2157 case ' ': return F_BLANK;
2160 break;
2162 case 'a': return _SHIN;
2163 case 'A': return WAW_H;
2164 case 'b': return ZAL;
2165 case 'c': return ZE;
2166 case 'C': return JE;
2167 case 'd': return _YE;
2168 case 'D': return _YEE;
2169 case 'e': return _SE;
2170 case 'f': return _BE;
2171 case 'g': return _LAM;
2172 case 'G':
2173 if (cmd_gchar(AT_CURSOR) == _LAM )
2175 cmd_pchar(LAM, AT_CURSOR);
2176 return ALEF_U_H;
2179 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
2180 return ALEF_U_H_;
2181 else
2182 return ALEF_U_H;
2183 case 'h':
2184 if (cmd_gchar(AT_CURSOR) == _LAM )
2186 cmd_pchar(LA, AT_CURSOR);
2187 redrawcmdline();
2188 return K_IGNORE;
2191 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
2192 return ALEF_;
2193 else
2194 return ALEF;
2195 case 'i':
2196 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
2197 return _HE_;
2198 else
2199 return _HE;
2200 case 'j': return _TE;
2201 case 'J':
2202 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
2203 return TEE_;
2204 else
2205 return TEE;
2206 case 'k': return _NOON;
2207 case 'l': return _MIM;
2208 case 'm': return _PE;
2209 case 'n':
2210 case 'N': return DAL;
2211 case 'o': return _XE;
2212 case 'p': return _HE_J;
2213 case 'q': return _ZAD;
2214 case 'r': return _GHAF;
2215 case 's': return _SIN;
2216 case 'S': return _IE;
2217 case 't': return _FE;
2218 case 'u':
2219 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
2220 return _AYN_;
2221 else
2222 return _AYN;
2223 case 'v':
2224 case 'V': return RE;
2225 case 'w': return _SAD;
2226 case 'x':
2227 case 'X': return _TA;
2228 case 'y':
2229 if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR))
2230 return _GHAYN_;
2231 else
2232 return _GHAYN;
2233 case 'z':
2234 case 'Z': return _ZA;
2235 case ';': return _KAF;
2236 case '\'': return _GAF;
2237 case ',': return WAW;
2238 case '[': return _JIM;
2239 case ']': return _CHE;
2242 return c;
2246 * F_isalpha returns TRUE if 'c' is a Farsi alphabet
2249 F_isalpha(c)
2250 int c;
2252 return (( c >= TEE_ && c <= _YE)
2253 || (c >= ALEF_A && c <= YE)
2254 || (c >= _IE && c <= YE_));
2258 * F_isdigit returns TRUE if 'c' is a Farsi digit
2261 F_isdigit(c)
2262 int c;
2264 return (c >= FARSI_0 && c <= FARSI_9);
2268 * F_ischar returns TRUE if 'c' is a Farsi character.
2271 F_ischar(c)
2272 int c;
2274 return (c >= TEE_ && c <= YE_);
2277 void
2278 farsi_fkey(cap)
2279 cmdarg_T *cap;
2281 int c = cap->cmdchar;
2283 if (c == K_F8)
2285 if (p_altkeymap)
2287 if (curwin->w_farsi & W_R_L)
2289 p_fkmap = 0;
2290 do_cmdline_cmd((char_u *)"set norl");
2291 MSG("");
2293 else
2295 p_fkmap = 1;
2296 do_cmdline_cmd((char_u *)"set rl");
2297 MSG("");
2300 curwin->w_farsi = curwin->w_farsi ^ W_R_L;
2304 if (c == K_F9)
2306 if (p_altkeymap && curwin->w_p_rl)
2308 curwin->w_farsi = curwin->w_farsi ^ W_CONV;
2309 if (curwin->w_farsi & W_CONV)
2310 conv_to_pvim();
2311 else
2312 conv_to_pstd();