blob: 253d7b5c9eb969a390640e8a7c629281d4c0d8f0 [file] [log] [blame]
Bram Moolenaar071d4272004-06-13 20:20:40 +00001/* 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
Bram Moolenaard25c16e2016-01-29 22:13:30 +010016static int toF_Xor_X_(int c);
17static int F_is_TyE(int c);
18static int F_is_TyC_TyD(int c);
19static int F_is_TyB_TyC_TyD(int src, int offset);
20static int toF_TyB(int c);
21static void put_curr_and_l_to_X(int c);
22static void put_and_redo(int c);
23static void chg_c_toX_orX(void);
24static void chg_c_to_X_orX_(void);
25static void chg_c_to_X_or_X(void);
26static void chg_l_to_X_orX_(void);
27static void chg_l_toXor_X(void);
28static void chg_r_to_Xor_X_(void);
29static int toF_leading(int c);
30static int toF_Rjoin(int c);
31static int canF_Ljoin(int c);
32static int canF_Rjoin(int c);
33static int F_isterm(int c);
34static int toF_ending(int c);
35static void lrswapbuf(char_u *buf, int len);
Bram Moolenaar071d4272004-06-13 20:20:40 +000036
37/*
38** Convert the given Farsi character into a _X or _X_ type
39*/
40 static int
41toF_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
Bram Moolenaaraf0167f2009-05-16 15:31:32 +0000106 if (p_ri && (curwin->w_cursor.col + 1
107 < (colnr_T)STRLEN(ml_get_curline())))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000108 {
109 inc_cursor();
110
111 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
112 tempc = _HE_;
113
114 dec_cursor();
115 }
116 if (!p_ri && STRLEN(ml_get_curline()))
117 {
118 dec_cursor();
119
120 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
121 tempc = _HE_;
122
123 inc_cursor();
124 }
125
126 return tempc;
127 }
128 return 0;
129}
130
131/*
132** Convert the given Farsi character into Farsi capital character .
133*/
134 int
135toF_TyA(c)
136 int c ;
137{
138 switch (c)
139 {
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;
205 }
206 return c;
207}
208
209/*
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.
213*/
214 static int
215F_is_TyB_TyC_TyD(src, offset)
216 int src, offset;
217{
218 int c;
219
220 if (src == SRC_EDT)
221 c = gchar_cursor();
222 else
223 c = cmd_gchar(AT_CURSOR+offset);
224
225 switch (c)
226 {
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;
259 }
260 return FALSE;
261}
262
263/*
264** Is the Farsi character one of the terminating only type.
265*/
266 static int
267F_is_TyE(c)
268 int c;
269{
270 switch (c)
271 {
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;
283 }
284 return FALSE;
285}
286
287/*
288** Is the Farsi character one of the none leading type.
289*/
290 static int
291F_is_TyC_TyD(c)
292 int c;
293{
294 switch (c)
295 {
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;
308 }
309 return FALSE;
310}
311
312/*
313** Convert a none leading Farsi char into a leading type.
314*/
315 static int
316toF_TyB(c)
317 int c;
318{
319 switch (c)
320 {
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;
332 }
333 return c;
334}
335
336/*
337** Overwrite the current redo and cursor characters + left adjust
338*/
339 static void
340put_curr_and_l_to_X(c)
341 int c;
342{
343 int tempc;
344
345 if (curwin->w_p_rl && p_ri)
346 return;
347
Bram Moolenaaraf0167f2009-05-16 15:31:32 +0000348 if ((curwin->w_cursor.col < (colnr_T)STRLEN(ml_get_curline())))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000349 {
350 if ((p_ri && curwin->w_cursor.col) || !p_ri)
351 {
352 if (p_ri)
353 dec_cursor();
354 else
355 inc_cursor();
356
357 if (F_is_TyC_TyD((tempc = gchar_cursor())))
358 {
359 pchar_cursor(toF_TyB(tempc));
360 AppendCharToRedobuff(K_BS);
361 AppendCharToRedobuff(tempc);
362 }
363
364 if (p_ri)
365 inc_cursor();
366 else
367 dec_cursor();
368 }
369 }
370
371 put_and_redo(c);
372}
373
374 static void
375put_and_redo(c)
376 int c;
377{
378 pchar_cursor(c);
379 AppendCharToRedobuff(K_BS);
380 AppendCharToRedobuff(c);
381}
382
383/*
384** Change the char. under the cursor to a X_ or X type
385*/
386 static void
387chg_c_toX_orX()
388{
389 int tempc, curc;
390
391 switch ((curc = gchar_cursor()))
392 {
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)
471 {
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();
480 }
481 else
482 {
483 if (curwin->w_cursor.col)
484 {
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();
493 }
494 else
495 tempc = (curc == _YE ? YE :
496 (curc == _IE ? IE : YEE));
497 }
498 break;
499 default:
500 tempc = 0;
501 }
502
503 if (tempc)
504 put_and_redo(tempc);
505}
506
507/*
508** Change the char. under the cursor to a _X_ or X_ type
509*/
510
511 static void
512chg_c_to_X_orX_()
513{
514 int tempc;
515
516 switch (gchar_cursor())
517 {
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;
553 }
554
555 if (tempc)
556 put_and_redo(tempc);
557}
558
559/*
560** Change the char. under the cursor to a _X_ or _X type
561*/
562 static void
563chg_c_to_X_or_X ()
564{
565 int tempc;
566
567 tempc = gchar_cursor();
568
Bram Moolenaaraf0167f2009-05-16 15:31:32 +0000569 if (curwin->w_cursor.col + 1 < (colnr_T)STRLEN(ml_get_curline()))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000570 {
571 inc_cursor();
572
573 if ((tempc == F_HE) && (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)))
574 {
575 tempc = _HE_;
576
577 dec_cursor();
578
579 put_and_redo(tempc);
580 return;
581 }
582
583 dec_cursor();
584 }
585
586 if ((tempc = toF_Xor_X_(tempc)) != 0)
587 put_and_redo(tempc);
588}
589
590/*
591** Change the character left to the cursor to a _X_ or X_ type
592*/
593 static void
594chg_l_to_X_orX_ ()
595{
596 int tempc;
597
Bram Moolenaaraf0167f2009-05-16 15:31:32 +0000598 if (curwin->w_cursor.col != 0 &&
599 (curwin->w_cursor.col + 1 == (colnr_T)STRLEN(ml_get_curline())))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000600 return;
601
602 if (!curwin->w_cursor.col && p_ri)
603 return;
604
605 if (p_ri)
606 dec_cursor();
607 else
608 inc_cursor();
609
610 switch (gchar_cursor())
611 {
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;
647 }
648
649 if (tempc)
650 put_and_redo(tempc);
651
652 if (p_ri)
653 inc_cursor();
654 else
655 dec_cursor();
656}
657
658/*
Bram Moolenaar25394022007-05-10 19:06:20 +0000659** Change the character left to the cursor to a X or _X type
Bram Moolenaar071d4272004-06-13 20:20:40 +0000660*/
661
662 static void
663chg_l_toXor_X ()
664{
665 int tempc;
666
Bram Moolenaaraf0167f2009-05-16 15:31:32 +0000667 if (curwin->w_cursor.col != 0 &&
668 (curwin->w_cursor.col + 1 == (colnr_T)STRLEN(ml_get_curline())))
Bram Moolenaar071d4272004-06-13 20:20:40 +0000669 return;
670
671 if (!curwin->w_cursor.col && p_ri)
672 return;
673
674 if (p_ri)
675 dec_cursor();
676 else
677 inc_cursor();
678
679 switch (gchar_cursor())
680 {
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;
716 }
717
718 if (tempc)
719 put_and_redo(tempc);
720
721 if (p_ri)
722 inc_cursor();
723 else
724 dec_cursor();
725}
726
727/*
Bram Moolenaar25394022007-05-10 19:06:20 +0000728** Change the character right to the cursor to a _X or _X_ type
Bram Moolenaar071d4272004-06-13 20:20:40 +0000729*/
730
731 static void
732chg_r_to_Xor_X_()
733{
734 int tempc, c;
735
736 if (curwin->w_cursor.col)
737 {
738 if (!p_ri)
739 dec_cursor();
740
741 tempc = gchar_cursor();
742
743 if ((c = toF_Xor_X_(tempc)) != 0)
744 put_and_redo(c);
745
746 if (!p_ri)
747 inc_cursor();
748
749 }
750}
751
752/*
753** Map Farsi keyboard when in fkmap mode.
754*/
755
756 int
757fkmap(c)
758 int c;
759{
760 int tempc;
761 static int revins;
762
763 if (IS_SPECIAL(c))
764 return c;
765
766 if (VIM_ISDIGIT(c) || ((c == '.' || c == '+' || c == '-' ||
767 c == '^' || c == '%' || c == '#' || c == '=') && revins))
768 {
769 if (!revins)
770 {
771 if (curwin->w_cursor.col)
772 {
773 if (!p_ri)
774 dec_cursor();
775
776 chg_c_toX_orX ();
777 chg_l_toXor_X ();
778
779 if (!p_ri)
780 inc_cursor();
781 }
782 }
783
784 arrow_used = TRUE;
785 (void)stop_arrow();
786
787 if (!curwin->w_p_rl && revins)
788 inc_cursor();
789
790 ++revins;
791 p_ri=1;
792 }
793 else
794 {
795 if (revins)
796 {
797 arrow_used = TRUE;
798 (void)stop_arrow();
799
800 revins = 0;
801 if (curwin->w_p_rl)
802 {
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;
813 }
814 else
815 {
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)
826 ;
827
828 if (!F_isdigit(gchar_cursor()))
829 ++curwin->w_cursor.col;
830 }
831 }
832 }
833
834 if (!revins)
835 {
836 if (curwin->w_p_rl)
837 p_ri=0;
838 if (!curwin->w_p_rl)
839 p_ri=1;
840 }
841
842 if ((c < 0x100) && (isalpha(c) || c == '&' || c == '^' || c == ';' ||
843 c == '\''|| c == ',' || c == '[' ||
844 c == ']' || c == '{' || c == '}' ))
845 chg_r_to_Xor_X_();
846
847 tempc = 0;
848
849 switch (c)
850 {
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:
907
908 if (p_ri && c == NL && curwin->w_cursor.col)
909 {
910 /*
911 ** If the char before the cursor is _X_ or X_ do not change
912 ** the one under the cursor with X type.
913 */
914
915 dec_cursor();
916
917 if (F_isalpha(gchar_cursor()))
918 {
919 inc_cursor();
920 return NL;
921 }
922
923 inc_cursor();
924 }
925
926 if (!p_ri)
927 if (!curwin->w_cursor.col)
928 {
929 switch (c)
930 {
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;
982 }
983 break;
984 }
985 if (!p_ri)
986 dec_cursor();
987
988 switch ((tempc = gchar_cursor()))
989 {
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_:
1018
1019 if (!p_ri)
1020 if (!curwin->w_cursor.col)
1021 {
1022 put_curr_and_l_to_X(AYN);
1023 break;
1024 }
1025
1026 if (p_ri)
1027 inc_cursor();
1028 else
1029 dec_cursor();
1030
1031 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1032 tempc = AYN_;
1033 else
1034 tempc = AYN;
1035
1036 if (p_ri)
1037 dec_cursor();
1038 else
1039 inc_cursor();
1040
1041 put_curr_and_l_to_X(tempc);
1042
1043 break;
1044 case _GHAYN:
1045 case _GHAYN_:
1046
1047 if (!p_ri)
1048 if (!curwin->w_cursor.col)
1049 {
1050 put_curr_and_l_to_X(GHAYN);
1051 break;
1052 }
1053
1054 if (p_ri)
1055 inc_cursor();
1056 else
1057 dec_cursor();
1058
1059 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1060 tempc = GHAYN_;
1061 else
1062 tempc = GHAYN;
1063
1064 if (p_ri)
1065 dec_cursor();
1066 else
1067 inc_cursor();
1068
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)
1076 {
1077 put_curr_and_l_to_X((tempc == _YE ? YE :
1078 (tempc == _IE ? IE : YEE)));
1079 break;
1080 }
1081
1082 if (p_ri)
1083 inc_cursor();
1084 else
1085 dec_cursor();
1086
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));
1093
1094 if (p_ri)
1095 dec_cursor();
1096 else
1097 inc_cursor();
1098
1099 put_curr_and_l_to_X(tempc);
1100 break;
1101 }
1102
1103 if (!p_ri)
1104 inc_cursor();
1105
1106 tempc = 0;
1107
1108 switch (c)
1109 {
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;
1161 }
1162 break;
1163
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()))
1196 {
1197
1198 if (gchar_cursor() == _LAM)
1199 chg_c_toX_orX ();
1200 else
1201 if (p_ri)
1202 chg_c_to_X_or_X ();
1203 }
1204
1205 if (!p_ri)
1206 if (!curwin->w_cursor.col)
1207 return ALEF_U_H;
1208
1209 if (!p_ri)
1210 dec_cursor();
1211
1212 if (gchar_cursor() == _LAM)
1213 {
1214 chg_c_toX_orX ();
1215 chg_l_toXor_X ();
1216 tempc = ALEF_U_H;
1217 }
1218 else
1219 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1220 {
1221 tempc = ALEF_U_H_;
1222 chg_l_toXor_X ();
1223 }
1224 else
1225 tempc = ALEF_U_H;
1226
1227 if (!p_ri)
1228 inc_cursor();
1229
1230 return tempc;
1231 case 'h':
1232 if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
1233 {
1234 if (p_ri)
1235 chg_c_to_X_or_X ();
1236
1237 }
1238
1239 if (!p_ri)
1240 if (!curwin->w_cursor.col)
1241 return ALEF;
1242
1243 if (!p_ri)
1244 dec_cursor();
1245
1246 if (gchar_cursor() == _LAM)
1247 {
1248 chg_l_toXor_X();
1249 del_char(FALSE);
1250 AppendCharToRedobuff(K_BS);
1251
1252 if (!p_ri)
1253 dec_cursor();
1254
1255 tempc = LA;
1256 }
1257 else
1258 {
1259 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1260 {
1261 tempc = ALEF_;
1262 chg_l_toXor_X ();
1263 }
1264 else
1265 tempc = ALEF;
1266 }
1267
1268 if (!p_ri)
1269 inc_cursor();
1270
1271 return tempc;
1272 case 'i':
1273 if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
1274 {
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 ();
1279
1280 }
1281
1282 if (!p_ri && !curwin->w_cursor.col)
1283 return _HE;
1284
1285 if (!p_ri)
1286 dec_cursor();
1287
1288 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1289 tempc = _HE_;
1290 else
1291 tempc = _HE;
1292
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()))
1301 {
1302 if (p_ri)
1303 chg_c_to_X_or_X ();
1304
1305 }
1306
1307 if (!p_ri)
1308 if (!curwin->w_cursor.col)
1309 return TEE;
1310
1311 if (!p_ri)
1312 dec_cursor();
1313
1314 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1315 {
1316 tempc = TEE_;
1317 chg_l_toXor_X ();
1318 }
1319 else
1320 tempc = TEE;
1321
1322 if (!p_ri)
1323 inc_cursor();
1324
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()))
1362 {
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 ();
1367
1368 }
1369
1370 if (!p_ri && !curwin->w_cursor.col)
1371 return _AYN;
1372
1373 if (!p_ri)
1374 dec_cursor();
1375
1376 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1377 tempc = _AYN_;
1378 else
1379 tempc = _AYN;
1380
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()))
1397 {
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 ();
1402
1403 }
1404
1405 if (!p_ri && !curwin->w_cursor.col)
1406 return _GHAYN;
1407
1408 if (!p_ri)
1409 dec_cursor();
1410
1411 if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
1412 tempc = _GHAYN_;
1413 else
1414 tempc = _GHAYN;
1415
1416 if (!p_ri)
1417 inc_cursor();
1418
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;
1441 }
1442
1443 if ((F_isalpha(tempc) || F_isdigit(tempc)))
1444 {
1445 if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
1446 {
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 ();
1451 }
1452
1453 if (curwin->w_cursor.col)
1454 {
1455 if (!p_ri)
1456 dec_cursor();
1457
1458 if (F_is_TyE(tempc))
1459 chg_l_toXor_X ();
1460 else
1461 chg_l_to_X_orX_ ();
1462
1463 if (!p_ri)
1464 inc_cursor();
1465 }
1466 }
1467 if (tempc)
1468 return tempc;
1469 return c;
1470}
1471
1472/*
1473** Convert a none leading Farsi char into a leading type.
1474*/
1475 static int
1476toF_leading(c)
1477 int c;
1478{
1479 switch (c)
1480 {
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;
1495
1496 case AYN:
1497 case AYN_:
1498 case _AYN_: return _AYN;
1499
1500 case GHAYN:
1501 case GHAYN_:
1502 case _GHAYN_: return _GHAYN;
1503
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;
1511
1512 case _HE_:
1513 case F_HE: return _HE;
1514
1515 case YE:
1516 case YE_: return _YE;
1517
1518 case IE_:
1519 case IE: return _IE;
1520
1521 case YEE:
1522 case YEE_: return _YEE;
1523 }
1524 return c;
1525}
1526
1527/*
1528** Convert a given Farsi char into right joining type.
1529*/
1530 static int
1531toF_Rjoin(c)
1532 int c;
1533{
1534 switch (c)
1535 {
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;
1550
1551 case AYN:
1552 case AYN_:
1553 case _AYN: return _AYN_;
1554
1555 case GHAYN:
1556 case GHAYN_:
1557 case _GHAYN_: return _GHAYN_;
1558
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;
1566
1567 case _HE:
1568 case F_HE: return _HE_;
1569
1570 case YE:
1571 case YE_: return _YE;
1572
1573 case IE_:
1574 case IE: return _IE;
1575
1576 case TEE: return TEE_;
1577
1578 case YEE:
1579 case YEE_: return _YEE;
1580 }
1581 return c;
1582}
1583
1584/*
1585** Can a given Farsi character join via its left edj.
1586*/
1587 static int
1588canF_Ljoin(c)
1589 int c;
1590{
1591 switch (c)
1592 {
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;
1655 }
1656 return FALSE;
1657}
1658
1659/*
1660** Can a given Farsi character join via its right edj.
1661*/
1662 static int
1663canF_Rjoin(c)
1664 int c;
1665{
1666 switch (c)
1667 {
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;
1682 }
1683
1684 return canF_Ljoin(c);
1685
1686}
1687
1688/*
1689** is a given Farsi character a terminating type.
1690*/
1691 static int
1692F_isterm(c)
1693 int c;
1694{
1695 switch (c)
1696 {
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;
1711 }
1712
1713 return FALSE;
1714}
1715
1716/*
1717** Convert the given Farsi character into a ending type .
1718*/
1719 static int
1720toF_ending(c)
1721 int c;
1722{
1723
1724 switch (c)
1725 {
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;
1790 }
1791 return c;
1792}
1793
1794/*
1795** Convert the Farsi 3342 standard into Farsi VIM.
1796*/
1797 void
1798conv_to_pvim()
1799{
1800 char_u *ptr;
1801 int lnum, llen, i;
1802
1803 for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
1804 {
1805 ptr = ml_get((linenr_T)lnum);
1806
1807 llen = (int)STRLEN(ptr);
1808
1809 for ( i = 0; i < llen-1; i++)
1810 {
1811 if (canF_Ljoin(ptr[i]) && canF_Rjoin(ptr[i+1]))
1812 {
1813 ptr[i] = toF_leading(ptr[i]);
1814 ++i;
1815
Bram Moolenaar97f38d92012-07-16 17:26:22 +02001816 while (canF_Rjoin(ptr[i]) && i < llen)
Bram Moolenaar071d4272004-06-13 20:20:40 +00001817 {
1818 ptr[i] = toF_Rjoin(ptr[i]);
1819 if (F_isterm(ptr[i]) || !F_isalpha(ptr[i]))
1820 break;
1821 ++i;
1822 }
1823 if (!F_isalpha(ptr[i]) || !canF_Rjoin(ptr[i]))
1824 ptr[i-1] = toF_ending(ptr[i-1]);
1825 }
1826 else
1827 ptr[i] = toF_TyA(ptr[i]);
1828 }
1829 }
1830
1831 /*
1832 * Following lines contains Farsi encoded character.
1833 */
1834
1835 do_cmdline_cmd((char_u *)"%s/\202\231/\232/g");
1836 do_cmdline_cmd((char_u *)"%s/\201\231/\370\334/g");
1837
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));
1841}
1842
1843/*
Bram Moolenaar84a05ac2013-05-06 04:24:17 +02001844 * Convert the Farsi VIM into Farsi 3342 standard.
Bram Moolenaar071d4272004-06-13 20:20:40 +00001845 */
1846 void
1847conv_to_pstd()
1848{
1849 char_u *ptr;
1850 int lnum, llen, i;
1851
1852 /*
1853 * Following line contains Farsi encoded character.
1854 */
1855
1856 do_cmdline_cmd((char_u *)"%s/\232/\202\231/g");
1857
1858 for (lnum = 1; lnum <= curbuf->b_ml.ml_line_count; ++lnum)
1859 {
1860 ptr = ml_get((linenr_T)lnum);
1861
1862 llen = (int)STRLEN(ptr);
1863
1864 for ( i = 0; i < llen; i++)
1865 {
1866 ptr[i] = toF_TyA(ptr[i]);
1867
1868 }
1869 }
1870
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));
1874}
1875
1876/*
1877 * left-right swap the characters in buf[len].
1878 */
1879 static void
1880lrswapbuf(buf, len)
1881 char_u *buf;
1882 int len;
1883{
1884 char_u *s, *e;
1885 int c;
1886
1887 s = buf;
1888 e = buf + len - 1;
1889
1890 while (e > s)
1891 {
1892 c = *s;
1893 *s = *e;
1894 *e = c;
1895 ++s;
1896 --e;
1897 }
1898}
1899
1900/*
1901 * swap all the characters in reverse direction
1902 */
1903 char_u *
1904lrswap(ibuf)
1905 char_u *ibuf;
1906{
1907 if (ibuf != NULL && *ibuf != NUL)
1908 lrswapbuf(ibuf, (int)STRLEN(ibuf));
1909 return ibuf;
1910}
1911
1912/*
1913 * swap all the Farsi characters in reverse direction
1914 */
1915 char_u *
1916lrFswap(cmdbuf, len)
1917 char_u *cmdbuf;
1918 int len;
1919{
1920 int i, cnt;
1921
1922 if (cmdbuf == NULL)
1923 return cmdbuf;
1924
1925 if (len == 0 && (len = (int)STRLEN(cmdbuf)) == 0)
1926 return cmdbuf;
1927
1928 for (i = 0; i < len; i++)
1929 {
1930 for (cnt = 0; i + cnt < len
1931 && (F_isalpha(cmdbuf[i + cnt])
1932 || F_isdigit(cmdbuf[i + cnt])
1933 || cmdbuf[i + cnt] == ' '); ++cnt)
1934 ;
1935
1936 lrswapbuf(cmdbuf + i, cnt);
1937 i += cnt;
1938 }
1939 return cmdbuf;
1940}
1941
1942/*
Bram Moolenaar8c8de832008-06-24 22:58:06 +00001943 * Reverse the characters in the search path and substitute section
1944 * accordingly.
1945 * TODO: handle different separator characters. Use skip_regexp().
Bram Moolenaar071d4272004-06-13 20:20:40 +00001946 */
1947 char_u *
1948lrF_sub(ibuf)
1949 char_u *ibuf;
1950{
1951 char_u *p, *ep;
1952 int i, cnt;
1953
1954 p = ibuf;
1955
Bram Moolenaar7d1f5db2005-07-03 21:39:27 +00001956 /* Find the boundary of the search path */
Bram Moolenaar42332f52005-07-06 22:38:49 +00001957 while (((p = vim_strchr(p + 1, '/')) != NULL) && p[-1] == '\\')
Bram Moolenaar071d4272004-06-13 20:20:40 +00001958 ;
1959
1960 if (p == NULL)
1961 return ibuf;
1962
1963 /* Reverse the Farsi characters in the search path. */
1964 lrFswap(ibuf, (int)(p-ibuf));
1965
Bram Moolenaar7d1f5db2005-07-03 21:39:27 +00001966 /* Now find the boundary of the substitute section */
Bram Moolenaar071d4272004-06-13 20:20:40 +00001967 if ((ep = (char_u *)strrchr((char *)++p, '/')) != NULL)
1968 cnt = (int)(ep - p);
1969 else
1970 cnt = (int)STRLEN(p);
1971
1972 /* Reverse the characters in the substitute section and take care of '\' */
1973 for (i = 0; i < cnt-1; i++)
1974 if (p[i] == '\\')
1975 {
1976 p[i] = p[i+1] ;
1977 p[++i] = '\\';
1978 }
1979
1980 lrswapbuf(p, cnt);
1981
1982 return ibuf;
1983}
1984
1985/*
1986 * Map Farsi keyboard when in cmd_fkmap mode.
1987 */
1988 int
1989cmdl_fkmap(c)
1990 int c;
1991{
1992 int tempc;
1993
1994 switch (c)
1995 {
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:
2052
2053 switch ((tempc = cmd_gchar(AT_CURSOR)))
2054 {
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);
2103 }
2104
2105 switch (c)
2106 {
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;
2158 }
2159
2160 break;
2161
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 )
2174 {
2175 cmd_pchar(LAM, AT_CURSOR);
2176 return ALEF_U_H;
2177 }
2178
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 )
2185 {
2186 cmd_pchar(LA, AT_CURSOR);
2187 redrawcmdline();
2188 return K_IGNORE;
2189 }
2190
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;
2240 }
2241
2242 return c;
2243}
2244
2245/*
2246 * F_isalpha returns TRUE if 'c' is a Farsi alphabet
2247 */
2248 int
2249F_isalpha(c)
2250 int c;
2251{
2252 return (( c >= TEE_ && c <= _YE)
2253 || (c >= ALEF_A && c <= YE)
2254 || (c >= _IE && c <= YE_));
2255}
2256
2257/*
2258 * F_isdigit returns TRUE if 'c' is a Farsi digit
2259 */
2260 int
2261F_isdigit(c)
2262 int c;
2263{
2264 return (c >= FARSI_0 && c <= FARSI_9);
2265}
2266
2267/*
2268 * F_ischar returns TRUE if 'c' is a Farsi character.
2269 */
2270 int
2271F_ischar(c)
2272 int c;
2273{
2274 return (c >= TEE_ && c <= YE_);
2275}
2276
2277 void
2278farsi_fkey(cap)
2279 cmdarg_T *cap;
2280{
2281 int c = cap->cmdchar;
2282
2283 if (c == K_F8)
2284 {
2285 if (p_altkeymap)
2286 {
2287 if (curwin->w_farsi & W_R_L)
2288 {
2289 p_fkmap = 0;
2290 do_cmdline_cmd((char_u *)"set norl");
2291 MSG("");
2292 }
2293 else
2294 {
2295 p_fkmap = 1;
2296 do_cmdline_cmd((char_u *)"set rl");
2297 MSG("");
2298 }
2299
2300 curwin->w_farsi = curwin->w_farsi ^ W_R_L;
2301 }
2302 }
2303
2304 if (c == K_F9)
2305 {
2306 if (p_altkeymap && curwin->w_p_rl)
2307 {
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();
2313 }
2314 }
2315}