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.
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
106 if (p_ri
&& (curwin
->w_cursor
.col
+1 < STRLEN(ml_get_curline())))
110 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
115 if (!p_ri
&& STRLEN(ml_get_curline()))
119 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
131 ** Convert the given Farsi character into Farsi capital character .
179 /* I am not sure what it is !!! case _KAF_H: */
209 ** Is the character under the cursor+offset in the given buffer a join type.
210 ** That is a character that is combined with the others.
211 ** Note: the offset is used only for command line buffer.
214 F_is_TyB_TyC_TyD(src
, offset
)
222 c
= cmd_gchar(AT_CURSOR
+offset
);
263 ** Is the Farsi character one of the terminating only type.
287 ** Is the Farsi character one of the none leading type.
312 ** Convert a none leading Farsi char into a leading type.
320 case ALEF_
: return ALEF
;
321 case ALEF_U_H_
: return ALEF_U_H
;
322 case _AYN_
: return _AYN
;
323 case AYN_
: return AYN
; /* exception - there are many of them */
324 case _GHAYN_
: return _GHAYN
;
325 case GHAYN_
: return GHAYN
; /* exception - there are many of them */
326 case _HE_
: return _HE
;
329 case TEE_
: return TEE
;
330 case YEE_
: return YEE
;
336 ** Overwrite the current redo and cursor characters + left adjust
339 put_curr_and_l_to_X(c
)
344 if (curwin
->w_p_rl
&& p_ri
)
347 if ( (curwin
->w_cursor
.col
< STRLEN(ml_get_curline())))
349 if ((p_ri
&& curwin
->w_cursor
.col
) || !p_ri
)
356 if (F_is_TyC_TyD((tempc
= gchar_cursor())))
358 pchar_cursor(toF_TyB(tempc
));
359 AppendCharToRedobuff(K_BS
);
360 AppendCharToRedobuff(tempc
);
378 AppendCharToRedobuff(K_BS
);
379 AppendCharToRedobuff(c
);
383 ** Change the char. under the cursor to a X_ or X type
390 switch ((curc
= gchar_cursor()))
472 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
473 tempc
= (curc
== _YE
? YE_
:
474 (curc
== _IE
? IE_
: YEE_
));
476 tempc
= (curc
== _YE
? YE
:
477 (curc
== _IE
? IE
: YEE
));
482 if (curwin
->w_cursor
.col
)
485 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
486 tempc
= (curc
== _YE
? YE_
:
487 (curc
== _IE
? IE_
: YEE_
));
489 tempc
= (curc
== _YE
? YE
:
490 (curc
== _IE
? IE
: YEE
));
494 tempc
= (curc
== _YE
? YE
:
495 (curc
== _IE
? IE
: YEE
));
507 ** Change the char. under the cursor to a _X_ or X_ type
515 switch (gchar_cursor())
559 ** Change the char. under the cursor to a _X_ or _X type
566 tempc
= gchar_cursor();
568 if (curwin
->w_cursor
.col
+1 < STRLEN(ml_get_curline()))
572 if ((tempc
== F_HE
) && (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
)))
585 if ((tempc
= toF_Xor_X_(tempc
)) != 0)
590 ** Change the character left to the cursor to a _X_ or X_ type
597 if (!curwin
->w_cursor
.col
&&
598 (curwin
->w_cursor
.col
+1 == STRLEN(ml_get_curline())))
601 if (!curwin
->w_cursor
.col
&& p_ri
)
609 switch (gchar_cursor())
658 ** Change the character left to the cursor to a X or _X type
666 if (!curwin
->w_cursor
.col
&&
667 (curwin
->w_cursor
.col
+1 == STRLEN(ml_get_curline())))
670 if (!curwin
->w_cursor
.col
&& p_ri
)
678 switch (gchar_cursor())
727 ** Change the character right to the cursor to a _X or _X_ type
735 if (curwin
->w_cursor
.col
)
740 tempc
= gchar_cursor();
742 if ((c
= toF_Xor_X_(tempc
)) != 0)
752 ** Map Farsi keyboard when in fkmap mode.
765 if (VIM_ISDIGIT(c
) || ((c
== '.' || c
== '+' || c
== '-' ||
766 c
== '^' || c
== '%' || c
== '#' || c
== '=') && revins
))
770 if (curwin
->w_cursor
.col
)
786 if (!curwin
->w_p_rl
&& revins
)
802 while ((F_isdigit(gchar_cursor())
803 || (gchar_cursor() == F_PERIOD
804 || gchar_cursor() == F_PLUS
805 || gchar_cursor() == F_MINUS
806 || gchar_cursor() == F_MUL
807 || gchar_cursor() == F_DIVIDE
808 || gchar_cursor() == F_PERCENT
809 || gchar_cursor() == F_EQUALS
))
810 && gchar_cursor() != NUL
)
811 ++curwin
->w_cursor
.col
;
815 if (curwin
->w_cursor
.col
)
816 while ((F_isdigit(gchar_cursor())
817 || (gchar_cursor() == F_PERIOD
818 || gchar_cursor() == F_PLUS
819 || gchar_cursor() == F_MINUS
820 || gchar_cursor() == F_MUL
821 || gchar_cursor() == F_DIVIDE
822 || gchar_cursor() == F_PERCENT
823 || gchar_cursor() == F_EQUALS
))
824 && --curwin
->w_cursor
.col
)
827 if (!F_isdigit(gchar_cursor()))
828 ++curwin
->w_cursor
.col
;
841 if ((c
< 0x100) && (isalpha(c
) || c
== '&' || c
== '^' || c
== ';' ||
842 c
== '\''|| c
== ',' || c
== '[' ||
843 c
== ']' || c
== '{' || c
== '}' ))
907 if (p_ri
&& c
== NL
&& curwin
->w_cursor
.col
)
910 ** If the char before the cursor is _X_ or X_ do not change
911 ** the one under the cursor with X type.
916 if (F_isalpha(gchar_cursor()))
926 if (!curwin
->w_cursor
.col
)
930 case '0': return FARSI_0
;
931 case '1': return FARSI_1
;
932 case '2': return FARSI_2
;
933 case '3': return FARSI_3
;
934 case '4': return FARSI_4
;
935 case '5': return FARSI_5
;
936 case '6': return FARSI_6
;
937 case '7': return FARSI_7
;
938 case '8': return FARSI_8
;
939 case '9': return FARSI_9
;
940 case 'B': return F_PSP
;
941 case 'E': return JAZR_N
;
942 case 'F': return ALEF_D_H
;
943 case 'H': return ALEF_A
;
944 case 'I': return TASH
;
945 case 'K': return F_LQUOT
;
946 case 'L': return F_RQUOT
;
947 case 'M': return HAMZE
;
948 case 'O': return '[';
949 case 'P': return ']';
951 case 'R': return MAD_N
;
953 case 'U': return MAD
;
954 case 'W': return OW_OW
;
955 case 'Y': return JAZR
;
956 case '`': return F_PCN
;
957 case '!': return F_EXCL
;
958 case '@': return F_COMMA
;
959 case '#': return F_DIVIDE
;
960 case '$': return F_CURRENCY
;
961 case '%': return F_PERCENT
;
962 case '^': return F_MUL
;
963 case '&': return F_BCOMMA
;
964 case '*': return F_STAR
;
965 case '(': return F_LPARENT
;
966 case ')': return F_RPARENT
;
967 case '-': return F_MINUS
;
968 case '_': return F_UNDERLINE
;
969 case '=': return F_EQUALS
;
970 case '+': return F_PLUS
;
971 case '\\': return F_BSLASH
;
972 case '|': return F_PIPE
;
973 case ':': return F_DCOLON
;
974 case '"': return F_SEMICOLON
;
975 case '.': return F_PERIOD
;
976 case '/': return F_SLASH
;
977 case '<': return F_LESS
;
978 case '>': return F_GREATER
;
979 case '?': return F_QUESTION
;
980 case ' ': return F_BLANK
;
987 switch ((tempc
= gchar_cursor()))
1013 put_curr_and_l_to_X(toF_TyA(tempc
));
1019 if (!curwin
->w_cursor
.col
)
1021 put_curr_and_l_to_X(AYN
);
1030 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
1040 put_curr_and_l_to_X(tempc
);
1047 if (!curwin
->w_cursor
.col
)
1049 put_curr_and_l_to_X(GHAYN
);
1058 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
1068 put_curr_and_l_to_X(tempc
);
1074 if (!curwin
->w_cursor
.col
)
1076 put_curr_and_l_to_X((tempc
== _YE
? YE
:
1077 (tempc
== _IE
? IE
: YEE
)));
1086 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
1087 tempc
= (tempc
== _YE
? YE_
:
1088 (tempc
== _IE
? IE_
: YEE_
));
1090 tempc
= (tempc
== _YE
? YE
:
1091 (tempc
== _IE
? IE
: YEE
));
1098 put_curr_and_l_to_X(tempc
);
1109 case '0': return FARSI_0
;
1110 case '1': return FARSI_1
;
1111 case '2': return FARSI_2
;
1112 case '3': return FARSI_3
;
1113 case '4': return FARSI_4
;
1114 case '5': return FARSI_5
;
1115 case '6': return FARSI_6
;
1116 case '7': return FARSI_7
;
1117 case '8': return FARSI_8
;
1118 case '9': return FARSI_9
;
1119 case 'B': return F_PSP
;
1120 case 'E': return JAZR_N
;
1121 case 'F': return ALEF_D_H
;
1122 case 'H': return ALEF_A
;
1123 case 'I': return TASH
;
1124 case 'K': return F_LQUOT
;
1125 case 'L': return F_RQUOT
;
1126 case 'M': return HAMZE
;
1127 case 'O': return '[';
1128 case 'P': return ']';
1129 case 'Q': return OO
;
1130 case 'R': return MAD_N
;
1131 case 'T': return OW
;
1132 case 'U': return MAD
;
1133 case 'W': return OW_OW
;
1134 case 'Y': return JAZR
;
1135 case '`': return F_PCN
;
1136 case '!': return F_EXCL
;
1137 case '@': return F_COMMA
;
1138 case '#': return F_DIVIDE
;
1139 case '$': return F_CURRENCY
;
1140 case '%': return F_PERCENT
;
1141 case '^': return F_MUL
;
1142 case '&': return F_BCOMMA
;
1143 case '*': return F_STAR
;
1144 case '(': return F_LPARENT
;
1145 case ')': return F_RPARENT
;
1146 case '-': return F_MINUS
;
1147 case '_': return F_UNDERLINE
;
1148 case '=': return F_EQUALS
;
1149 case '+': return F_PLUS
;
1150 case '\\': return F_BSLASH
;
1151 case '|': return F_PIPE
;
1152 case ':': return F_DCOLON
;
1153 case '"': return F_SEMICOLON
;
1154 case '.': return F_PERIOD
;
1155 case '/': return F_SLASH
;
1156 case '<': return F_LESS
;
1157 case '>': return F_GREATER
;
1158 case '?': return F_QUESTION
;
1159 case ' ': return F_BLANK
;
1194 if (!curwin
->w_cursor
.col
&& STRLEN(ml_get_curline()))
1197 if (gchar_cursor() == _LAM
)
1205 if (!curwin
->w_cursor
.col
)
1211 if (gchar_cursor() == _LAM
)
1218 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
1231 if (!curwin
->w_cursor
.col
&& STRLEN(ml_get_curline()))
1239 if (!curwin
->w_cursor
.col
)
1245 if (gchar_cursor() == _LAM
)
1249 AppendCharToRedobuff(K_BS
);
1258 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
1272 if (!curwin
->w_cursor
.col
&& STRLEN(ml_get_curline()))
1274 if (!p_ri
&& !F_is_TyE(tempc
))
1281 if (!p_ri
&& !curwin
->w_cursor
.col
)
1287 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
1299 if (!curwin
->w_cursor
.col
&& STRLEN(ml_get_curline()))
1307 if (!curwin
->w_cursor
.col
)
1313 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
1360 if (!curwin
->w_cursor
.col
&& STRLEN(ml_get_curline()))
1362 if (!p_ri
&& !F_is_TyE(tempc
))
1369 if (!p_ri
&& !curwin
->w_cursor
.col
)
1375 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
1395 if (!curwin
->w_cursor
.col
&& STRLEN(ml_get_curline()))
1397 if (!p_ri
&& !F_is_TyE(tempc
))
1404 if (!p_ri
&& !curwin
->w_cursor
.col
)
1410 if (F_is_TyB_TyC_TyD(SRC_EDT
, AT_CURSOR
))
1442 if ((F_isalpha(tempc
) || F_isdigit(tempc
)))
1444 if (!curwin
->w_cursor
.col
&& STRLEN(ml_get_curline()))
1446 if (!p_ri
&& !F_is_TyE(tempc
))
1452 if (curwin
->w_cursor
.col
)
1457 if (F_is_TyE(tempc
))
1472 ** Convert a none leading Farsi char into a leading type.
1480 case ALEF_
: return ALEF
;
1481 case ALEF_U_H_
: return ALEF_U_H
;
1482 case BE
: return _BE
;
1483 case PE
: return _PE
;
1484 case TE
: return _TE
;
1485 case SE
: return _SE
;
1486 case JIM
: return _JIM
;
1487 case CHE
: return _CHE
;
1488 case HE_J
: return _HE_J
;
1489 case XE
: return _XE
;
1490 case SIN
: return _SIN
;
1491 case SHIN
: return _SHIN
;
1492 case SAD
: return _SAD
;
1493 case ZAD
: return _ZAD
;
1497 case _AYN_
: return _AYN
;
1501 case _GHAYN_
: return _GHAYN
;
1503 case FE
: return _FE
;
1504 case GHAF
: return _GHAF
;
1505 case KAF
: return _KAF
;
1506 case GAF
: return _GAF
;
1507 case LAM
: return _LAM
;
1508 case MIM
: return _MIM
;
1509 case NOON
: return _NOON
;
1512 case F_HE
: return _HE
;
1515 case YE_
: return _YE
;
1518 case IE
: return _IE
;
1521 case YEE_
: return _YEE
;
1527 ** Convert a given Farsi char into right joining type.
1535 case ALEF
: return ALEF_
;
1536 case ALEF_U_H
: return ALEF_U_H_
;
1537 case BE
: return _BE
;
1538 case PE
: return _PE
;
1539 case TE
: return _TE
;
1540 case SE
: return _SE
;
1541 case JIM
: return _JIM
;
1542 case CHE
: return _CHE
;
1543 case HE_J
: return _HE_J
;
1544 case XE
: return _XE
;
1545 case SIN
: return _SIN
;
1546 case SHIN
: return _SHIN
;
1547 case SAD
: return _SAD
;
1548 case ZAD
: return _ZAD
;
1552 case _AYN
: return _AYN_
;
1556 case _GHAYN_
: return _GHAYN_
;
1558 case FE
: return _FE
;
1559 case GHAF
: return _GHAF
;
1560 case KAF
: return _KAF
;
1561 case GAF
: return _GAF
;
1562 case LAM
: return _LAM
;
1563 case MIM
: return _MIM
;
1564 case NOON
: return _NOON
;
1567 case F_HE
: return _HE_
;
1570 case YE_
: return _YE
;
1573 case IE
: return _IE
;
1575 case TEE
: return TEE_
;
1578 case YEE_
: return _YEE
;
1584 ** Can a given Farsi character join via its left edj.
1659 ** Can a given Farsi character join via its right edj.
1683 return canF_Ljoin(c
);
1688 ** is a given Farsi character a terminating type.
1716 ** Convert the given Farsi character into a ending type .
1794 ** Convert the Farsi 3342 standard into Farsi VIM.
1802 for (lnum
= 1; lnum
<= curbuf
->b_ml
.ml_line_count
; ++lnum
)
1804 ptr
= ml_get((linenr_T
)lnum
);
1806 llen
= (int)STRLEN(ptr
);
1808 for ( i
= 0; i
< llen
-1; i
++)
1810 if (canF_Ljoin(ptr
[i
]) && canF_Rjoin(ptr
[i
+1]))
1812 ptr
[i
] = toF_leading(ptr
[i
]);
1815 while(canF_Rjoin(ptr
[i
]) && (i
< llen
))
1817 ptr
[i
] = toF_Rjoin(ptr
[i
]);
1818 if (F_isterm(ptr
[i
]) || !F_isalpha(ptr
[i
]))
1822 if (!F_isalpha(ptr
[i
]) || !canF_Rjoin(ptr
[i
]))
1823 ptr
[i
-1] = toF_ending(ptr
[i
-1]);
1826 ptr
[i
] = toF_TyA(ptr
[i
]);
1831 * Following lines contains Farsi encoded character.
1834 do_cmdline_cmd((char_u
*)"%s/\202\231/\232/g");
1835 do_cmdline_cmd((char_u
*)"%s/\201\231/\370\334/g");
1837 /* Assume the screen has been messed up: clear it and redraw. */
1838 redraw_later(CLEAR
);
1839 MSG_ATTR(farsi_text_1
, hl_attr(HLF_S
));
1843 * Convert the Farsi VIM into Farsi 3342 standad.
1852 * Following line contains Farsi encoded character.
1855 do_cmdline_cmd((char_u
*)"%s/\232/\202\231/g");
1857 for (lnum
= 1; lnum
<= curbuf
->b_ml
.ml_line_count
; ++lnum
)
1859 ptr
= ml_get((linenr_T
)lnum
);
1861 llen
= (int)STRLEN(ptr
);
1863 for ( i
= 0; i
< llen
; i
++)
1865 ptr
[i
] = toF_TyA(ptr
[i
]);
1870 /* Assume the screen has been messed up: clear it and redraw. */
1871 redraw_later(CLEAR
);
1872 MSG_ATTR(farsi_text_2
, hl_attr(HLF_S
));
1876 * left-right swap the characters in buf[len].
1900 * swap all the characters in reverse direction
1906 if (ibuf
!= NULL
&& *ibuf
!= NUL
)
1907 lrswapbuf(ibuf
, (int)STRLEN(ibuf
));
1912 * swap all the Farsi characters in reverse direction
1915 lrFswap(cmdbuf
, len
)
1924 if (len
== 0 && (len
= (int)STRLEN(cmdbuf
)) == 0)
1927 for (i
= 0; i
< len
; i
++)
1929 for (cnt
= 0; i
+ cnt
< len
1930 && (F_isalpha(cmdbuf
[i
+ cnt
])
1931 || F_isdigit(cmdbuf
[i
+ cnt
])
1932 || cmdbuf
[i
+ cnt
] == ' '); ++cnt
)
1935 lrswapbuf(cmdbuf
+ i
, cnt
);
1942 * Reverse the characters in the search path and substitute section accordingly
1953 /* Find the boundary of the search path */
1954 while (((p
= vim_strchr(p
+ 1, '/')) != NULL
) && p
[-1] == '\\')
1960 /* Reverse the Farsi characters in the search path. */
1961 lrFswap(ibuf
, (int)(p
-ibuf
));
1963 /* Now find the boundary of the substitute section */
1964 if ((ep
= (char_u
*)strrchr((char *)++p
, '/')) != NULL
)
1965 cnt
= (int)(ep
- p
);
1967 cnt
= (int)STRLEN(p
);
1969 /* Reverse the characters in the substitute section and take care of '\' */
1970 for (i
= 0; i
< cnt
-1; i
++)
1983 * Map Farsi keyboard when in cmd_fkmap mode.
2050 switch ((tempc
= cmd_gchar(AT_CURSOR
)))
2075 cmd_pchar(toF_TyA(tempc
), AT_CURSOR
);
2078 cmd_pchar(AYN_
, AT_CURSOR
);
2081 cmd_pchar(GHAYN_
, AT_CURSOR
);
2084 if (F_is_TyB_TyC_TyD(SRC_CMD
, AT_CURSOR
+1))
2085 cmd_pchar(IE_
, AT_CURSOR
);
2087 cmd_pchar(IE
, AT_CURSOR
);
2090 if (F_is_TyB_TyC_TyD(SRC_CMD
, AT_CURSOR
+1))
2091 cmd_pchar(YEE_
, AT_CURSOR
);
2093 cmd_pchar(YEE
, AT_CURSOR
);
2096 if (F_is_TyB_TyC_TyD(SRC_CMD
, AT_CURSOR
+1))
2097 cmd_pchar(YE_
, AT_CURSOR
);
2099 cmd_pchar(YE
, AT_CURSOR
);
2104 case '0': return FARSI_0
;
2105 case '1': return FARSI_1
;
2106 case '2': return FARSI_2
;
2107 case '3': return FARSI_3
;
2108 case '4': return FARSI_4
;
2109 case '5': return FARSI_5
;
2110 case '6': return FARSI_6
;
2111 case '7': return FARSI_7
;
2112 case '8': return FARSI_8
;
2113 case '9': return FARSI_9
;
2114 case 'B': return F_PSP
;
2115 case 'E': return JAZR_N
;
2116 case 'F': return ALEF_D_H
;
2117 case 'H': return ALEF_A
;
2118 case 'I': return TASH
;
2119 case 'K': return F_LQUOT
;
2120 case 'L': return F_RQUOT
;
2121 case 'M': return HAMZE
;
2122 case 'O': return '[';
2123 case 'P': return ']';
2124 case 'Q': return OO
;
2125 case 'R': return MAD_N
;
2126 case 'T': return OW
;
2127 case 'U': return MAD
;
2128 case 'W': return OW_OW
;
2129 case 'Y': return JAZR
;
2130 case '`': return F_PCN
;
2131 case '!': return F_EXCL
;
2132 case '@': return F_COMMA
;
2133 case '#': return F_DIVIDE
;
2134 case '$': return F_CURRENCY
;
2135 case '%': return F_PERCENT
;
2136 case '^': return F_MUL
;
2137 case '&': return F_BCOMMA
;
2138 case '*': return F_STAR
;
2139 case '(': return F_LPARENT
;
2140 case ')': return F_RPARENT
;
2141 case '-': return F_MINUS
;
2142 case '_': return F_UNDERLINE
;
2143 case '=': return F_EQUALS
;
2144 case '+': return F_PLUS
;
2145 case '\\': return F_BSLASH
;
2146 case '|': return F_PIPE
;
2147 case ':': return F_DCOLON
;
2148 case '"': return F_SEMICOLON
;
2149 case '.': return F_PERIOD
;
2150 case '/': return F_SLASH
;
2151 case '<': return F_LESS
;
2152 case '>': return F_GREATER
;
2153 case '?': return F_QUESTION
;
2154 case ' ': return F_BLANK
;
2159 case 'a': return _SHIN
;
2160 case 'A': return WAW_H
;
2161 case 'b': return ZAL
;
2162 case 'c': return ZE
;
2163 case 'C': return JE
;
2164 case 'd': return _YE
;
2165 case 'D': return _YEE
;
2166 case 'e': return _SE
;
2167 case 'f': return _BE
;
2168 case 'g': return _LAM
;
2170 if (cmd_gchar(AT_CURSOR
) == _LAM
)
2172 cmd_pchar(LAM
, AT_CURSOR
);
2176 if (F_is_TyB_TyC_TyD(SRC_CMD
, AT_CURSOR
))
2181 if (cmd_gchar(AT_CURSOR
) == _LAM
)
2183 cmd_pchar(LA
, AT_CURSOR
);
2188 if (F_is_TyB_TyC_TyD(SRC_CMD
, AT_CURSOR
))
2193 if (F_is_TyB_TyC_TyD(SRC_CMD
, AT_CURSOR
))
2197 case 'j': return _TE
;
2199 if (F_is_TyB_TyC_TyD(SRC_CMD
, AT_CURSOR
))
2203 case 'k': return _NOON
;
2204 case 'l': return _MIM
;
2205 case 'm': return _PE
;
2207 case 'N': return DAL
;
2208 case 'o': return _XE
;
2209 case 'p': return _HE_J
;
2210 case 'q': return _ZAD
;
2211 case 'r': return _GHAF
;
2212 case 's': return _SIN
;
2213 case 'S': return _IE
;
2214 case 't': return _FE
;
2216 if (F_is_TyB_TyC_TyD(SRC_CMD
, AT_CURSOR
))
2221 case 'V': return RE
;
2222 case 'w': return _SAD
;
2224 case 'X': return _TA
;
2226 if (F_is_TyB_TyC_TyD(SRC_CMD
, AT_CURSOR
))
2231 case 'Z': return _ZA
;
2232 case ';': return _KAF
;
2233 case '\'': return _GAF
;
2234 case ',': return WAW
;
2235 case '[': return _JIM
;
2236 case ']': return _CHE
;
2243 * F_isalpha returns TRUE if 'c' is a Farsi alphabet
2249 return (( c
>= TEE_
&& c
<= _YE
)
2250 || (c
>= ALEF_A
&& c
<= YE
)
2251 || (c
>= _IE
&& c
<= YE_
));
2255 * F_isdigit returns TRUE if 'c' is a Farsi digit
2261 return (c
>= FARSI_0
&& c
<= FARSI_9
);
2265 * F_ischar returns TRUE if 'c' is a Farsi character.
2271 return (c
>= TEE_
&& c
<= YE_
);
2278 int c
= cap
->cmdchar
;
2284 if (curwin
->w_farsi
& W_R_L
)
2287 do_cmdline_cmd((char_u
*)"set norl");
2293 do_cmdline_cmd((char_u
*)"set rl");
2297 curwin
->w_farsi
= curwin
->w_farsi
^ W_R_L
;
2303 if (p_altkeymap
&& curwin
->w_p_rl
)
2305 curwin
->w_farsi
= curwin
->w_farsi
^ W_CONV
;
2306 if (curwin
->w_farsi
& W_CONV
)