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 16static int toF_Xor_X_ __ARGS((int c)); 17static int F_is_TyE __ARGS((int c)); 18static int F_is_TyC_TyD __ARGS((int c)); 19static int F_is_TyB_TyC_TyD __ARGS((int src, int offset)); 20static int toF_TyB __ARGS((int c)); 21static void put_curr_and_l_to_X __ARGS((int c)); 22static void put_and_redo __ARGS((int c)); 23static void chg_c_toX_orX __ARGS((void)); 24static void chg_c_to_X_orX_ __ARGS((void)); 25static void chg_c_to_X_or_X __ARGS((void)); 26static void chg_l_to_X_orX_ __ARGS((void)); 27static void chg_l_toXor_X __ARGS((void)); 28static void chg_r_to_Xor_X_ __ARGS((void)); 29static int toF_leading __ARGS((int c)); 30static int toF_Rjoin __ARGS((int c)); 31static int canF_Ljoin __ARGS((int c)); 32static int canF_Rjoin __ARGS((int c)); 33static int F_isterm __ARGS((int c)); 34static int toF_ending __ARGS((int c)); 35static 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 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 106 if (p_ri && (curwin->w_cursor.col + 1 107 < (colnr_T)STRLEN(ml_get_curline()))) 108 { 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 348 if ((curwin->w_cursor.col < (colnr_T)STRLEN(ml_get_curline()))) 349 { 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 569 if (curwin->w_cursor.col + 1 < (colnr_T)STRLEN(ml_get_curline())) 570 { 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 598 if (curwin->w_cursor.col != 0 && 599 (curwin->w_cursor.col + 1 == (colnr_T)STRLEN(ml_get_curline()))) 600 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/* 659** Change the character left to the cursor to a X or _X type 660*/ 661 662 static void 663chg_l_toXor_X () 664{ 665 int tempc; 666 667 if (curwin->w_cursor.col != 0 && 668 (curwin->w_cursor.col + 1 == (colnr_T)STRLEN(ml_get_curline()))) 669 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/* 728** Change the character right to the cursor to a _X or _X_ type 729*/ 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 1816 while(canF_Rjoin(ptr[i]) && (i < llen)) 1817 { 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/* 1844 * Convert the Farsi VIM into Farsi 3342 standad. 1845 */ 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/* 1943 * Reverse the characters in the search path and substitute section 1944 * accordingly. 1945 * TODO: handle different separator characters. Use skip_regexp(). 1946 */ 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 1956 /* Find the boundary of the search path */ 1957 while (((p = vim_strchr(p + 1, '/')) != NULL) && p[-1] == '\\') 1958 ; 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 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); 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} 2316