summaryrefslogtreecommitdiffstats
path: root/src/farsi.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2004-06-13 20:20:40 +0000
committerBram Moolenaar <Bram@vim.org>2004-06-13 20:20:40 +0000
commit071d4279d6ab81b7187b48f3a0fc61e587b6db6c (patch)
tree221cbe3c40e043163c06f61c52a7ba2eb41e12ce /src/farsi.c
parentb4210b3bc14e2918f153a7307530fbe6eba659e1 (diff)
updated for version 7.0001v7.0001
Diffstat (limited to 'src/farsi.c')
-rw-r--r--src/farsi.c2312
1 files changed, 2312 insertions, 0 deletions
diff --git a/src/farsi.c b/src/farsi.c
new file mode 100644
index 0000000000..f74447f76e
--- /dev/null
+++ b/src/farsi.c
@@ -0,0 +1,2312 @@
+/* vi:set ts=8 sts=4 sw=4:
+ *
+ * VIM - Vi IMproved by Bram Moolenaar
+ *
+ * Do ":help uganda" in Vim to read copying and usage conditions.
+ * Do ":help credits" in Vim to see a list of people who contributed.
+ * See README.txt for an overview of the Vim source code.
+ */
+
+/*
+ * farsi.c: functions for Farsi language
+ *
+ * Included by main.c, when FEAT_FKMAP is defined.
+ */
+
+static int toF_Xor_X_ __ARGS((int c));
+static int F_is_TyE __ARGS((int c));
+static int F_is_TyC_TyD __ARGS((int c));
+static int F_is_TyB_TyC_TyD __ARGS((int src, int offset));
+static int toF_TyB __ARGS((int c));
+static void put_curr_and_l_to_X __ARGS((int c));
+static void put_and_redo __ARGS((int c));
+static void chg_c_toX_orX __ARGS((void));
+static void chg_c_to_X_orX_ __ARGS((void));
+static void chg_c_to_X_or_X __ARGS((void));
+static void chg_l_to_X_orX_ __ARGS((void));
+static void chg_l_toXor_X __ARGS((void));
+static void chg_r_to_Xor_X_ __ARGS((void));
+static int toF_leading __ARGS((int c));
+static int toF_Rjoin __ARGS((int c));
+static int canF_Ljoin __ARGS((int c));
+static int canF_Rjoin __ARGS((int c));
+static int F_isterm __ARGS((int c));
+static int toF_ending __ARGS((int c));
+static void lrswapbuf __ARGS((char_u *buf, int len));
+
+/*
+** Convert the given Farsi character into a _X or _X_ type
+*/
+ static int
+toF_Xor_X_(c)
+ int c;
+{
+ int tempc;
+
+ switch (c)
+ {
+ case BE:
+ return _BE;
+ case PE:
+ return _PE;
+ case TE:
+ return _TE;
+ case SE:
+ return _SE;
+ case JIM:
+ return _JIM;
+ case CHE:
+ return _CHE;
+ case HE_J:
+ return _HE_J;
+ case XE:
+ return _XE;
+ case SIN:
+ return _SIN;
+ case SHIN:
+ return _SHIN;
+ case SAD:
+ return _SAD;
+ case ZAD:
+ return _ZAD;
+ case AYN:
+ return _AYN;
+ case AYN_:
+ return _AYN_;
+ case GHAYN:
+ return _GHAYN;
+ case GHAYN_:
+ return _GHAYN_;
+ case FE:
+ return _FE;
+ case GHAF:
+ return _GHAF;
+ case KAF:
+ return _KAF;
+ case GAF:
+ return _GAF;
+ case LAM:
+ return _LAM;
+ case MIM:
+ return _MIM;
+ case NOON:
+ return _NOON;
+ case YE:
+ case YE_:
+ return _YE;
+ case YEE:
+ case YEE_:
+ return _YEE;
+ case IE:
+ case IE_:
+ return _IE;
+ case F_HE:
+ tempc = _HE;
+
+ if (p_ri && (curwin->w_cursor.col+1 < STRLEN(ml_get_curline())))
+ {
+ inc_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = _HE_;
+
+ dec_cursor();
+ }
+ if (!p_ri && STRLEN(ml_get_curline()))
+ {
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = _HE_;
+
+ inc_cursor();
+ }
+
+ return tempc;
+ }
+ return 0;
+}
+
+/*
+** Convert the given Farsi character into Farsi capital character .
+*/
+ int
+toF_TyA(c)
+ int c ;
+{
+ switch (c)
+ {
+ case ALEF_:
+ return ALEF;
+ case ALEF_U_H_:
+ return ALEF_U_H;
+ case _BE:
+ return BE;
+ case _PE:
+ return PE;
+ case _TE:
+ return TE;
+ case _SE:
+ return SE;
+ case _JIM:
+ return JIM;
+ case _CHE:
+ return CHE;
+ case _HE_J:
+ return HE_J;
+ case _XE:
+ return XE;
+ case _SIN:
+ return SIN;
+ case _SHIN:
+ return SHIN;
+ case _SAD:
+ return SAD;
+ case _ZAD:
+ return ZAD;
+ case _AYN:
+ case AYN_:
+ case _AYN_:
+ return AYN;
+ case _GHAYN:
+ case GHAYN_:
+ case _GHAYN_:
+ return GHAYN;
+ case _FE:
+ return FE;
+ case _GHAF:
+ return GHAF;
+/* I am not sure what it is !!! case _KAF_H: */
+ case _KAF:
+ return KAF;
+ case _GAF:
+ return GAF;
+ case _LAM:
+ return LAM;
+ case _MIM:
+ return MIM;
+ case _NOON:
+ return NOON;
+ case _YE:
+ case YE_:
+ return YE;
+ case _YEE:
+ case YEE_:
+ return YEE;
+ case TEE_:
+ return TEE;
+ case _IE:
+ case IE_:
+ return IE;
+ case _HE:
+ case _HE_:
+ return F_HE;
+ }
+ return c;
+}
+
+/*
+** Is the character under the cursor+offset in the given buffer a join type.
+** That is a character that is combined with the others.
+** Note: the offset is used only for command line buffer.
+*/
+ static int
+F_is_TyB_TyC_TyD(src, offset)
+ int src, offset;
+{
+ int c;
+
+ if (src == SRC_EDT)
+ c = gchar_cursor();
+ else
+ c = cmd_gchar(AT_CURSOR+offset);
+
+ switch (c)
+ {
+ case _LAM:
+ case _BE:
+ case _PE:
+ case _TE:
+ case _SE:
+ case _JIM:
+ case _CHE:
+ case _HE_J:
+ case _XE:
+ case _SIN:
+ case _SHIN:
+ case _SAD:
+ case _ZAD:
+ case _TA:
+ case _ZA:
+ case _AYN:
+ case _AYN_:
+ case _GHAYN:
+ case _GHAYN_:
+ case _FE:
+ case _GHAF:
+ case _KAF:
+ case _KAF_H:
+ case _GAF:
+ case _MIM:
+ case _NOON:
+ case _YE:
+ case _YEE:
+ case _IE:
+ case _HE_:
+ case _HE:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+** Is the Farsi character one of the terminating only type.
+*/
+ static int
+F_is_TyE(c)
+ int c;
+{
+ switch (c)
+ {
+ case ALEF_A:
+ case ALEF_D_H:
+ case DAL:
+ case ZAL:
+ case RE:
+ case ZE:
+ case JE:
+ case WAW:
+ case WAW_H:
+ case HAMZE:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+** Is the Farsi character one of the none leading type.
+*/
+ static int
+F_is_TyC_TyD(c)
+ int c;
+{
+ switch (c)
+ {
+ case ALEF_:
+ case ALEF_U_H_:
+ case _AYN_:
+ case AYN_:
+ case _GHAYN_:
+ case GHAYN_:
+ case _HE_:
+ case YE_:
+ case IE_:
+ case TEE_:
+ case YEE_:
+ return TRUE;
+ }
+ return FALSE;
+}
+
+/*
+** Convert a none leading Farsi char into a leading type.
+*/
+ static int
+toF_TyB(c)
+ int c;
+{
+ switch (c)
+ {
+ case ALEF_: return ALEF;
+ case ALEF_U_H_: return ALEF_U_H;
+ case _AYN_: return _AYN;
+ case AYN_: return AYN; /* exception - there are many of them */
+ case _GHAYN_: return _GHAYN;
+ case GHAYN_: return GHAYN; /* exception - there are many of them */
+ case _HE_: return _HE;
+ case YE_: return YE;
+ case IE_: return IE;
+ case TEE_: return TEE;
+ case YEE_: return YEE;
+ }
+ return c;
+}
+
+/*
+** Overwrite the current redo and cursor characters + left adjust
+*/
+ static void
+put_curr_and_l_to_X(c)
+ int c;
+{
+ int tempc;
+
+ if (curwin->w_p_rl && p_ri)
+ return;
+
+ if ( (curwin->w_cursor.col < STRLEN(ml_get_curline())))
+ {
+ if ((p_ri && curwin->w_cursor.col) || !p_ri)
+ {
+ if (p_ri)
+ dec_cursor();
+ else
+ inc_cursor();
+
+ if (F_is_TyC_TyD((tempc = gchar_cursor())))
+ {
+ pchar_cursor(toF_TyB(tempc));
+ AppendCharToRedobuff(K_BS);
+ AppendCharToRedobuff(tempc);
+ }
+
+ if (p_ri)
+ inc_cursor();
+ else
+ dec_cursor();
+ }
+ }
+
+ put_and_redo(c);
+}
+
+ static void
+put_and_redo(c)
+ int c;
+{
+ pchar_cursor(c);
+ AppendCharToRedobuff(K_BS);
+ AppendCharToRedobuff(c);
+}
+
+/*
+** Change the char. under the cursor to a X_ or X type
+*/
+ static void
+chg_c_toX_orX()
+{
+ int tempc, curc;
+
+ switch ((curc = gchar_cursor()))
+ {
+ case _BE:
+ tempc = BE;
+ break;
+ case _PE:
+ tempc = PE;
+ break;
+ case _TE:
+ tempc = TE;
+ break;
+ case _SE:
+ tempc = SE;
+ break;
+ case _JIM:
+ tempc = JIM;
+ break;
+ case _CHE:
+ tempc = CHE;
+ break;
+ case _HE_J:
+ tempc = HE_J;
+ break;
+ case _XE:
+ tempc = XE;
+ break;
+ case _SIN:
+ tempc = SIN;
+ break;
+ case _SHIN:
+ tempc = SHIN;
+ break;
+ case _SAD:
+ tempc = SAD;
+ break;
+ case _ZAD:
+ tempc = ZAD;
+ break;
+ case _FE:
+ tempc = FE;
+ break;
+ case _GHAF:
+ tempc = GHAF;
+ break;
+ case _KAF_H:
+ case _KAF:
+ tempc = KAF;
+ break;
+ case _GAF:
+ tempc = GAF;
+ break;
+ case _AYN:
+ tempc = AYN;
+ break;
+ case _AYN_:
+ tempc = AYN_;
+ break;
+ case _GHAYN:
+ tempc = GHAYN;
+ break;
+ case _GHAYN_:
+ tempc = GHAYN_;
+ break;
+ case _LAM:
+ tempc = LAM;
+ break;
+ case _MIM:
+ tempc = MIM;
+ break;
+ case _NOON:
+ tempc = NOON;
+ break;
+ case _HE:
+ case _HE_:
+ tempc = F_HE;
+ break;
+ case _YE:
+ case _IE:
+ case _YEE:
+ if (p_ri)
+ {
+ inc_cursor();
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = (curc == _YE ? YE_ :
+ (curc == _IE ? IE_ : YEE_));
+ else
+ tempc = (curc == _YE ? YE :
+ (curc == _IE ? IE : YEE));
+ dec_cursor();
+ }
+ else
+ {
+ if (curwin->w_cursor.col)
+ {
+ dec_cursor();
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = (curc == _YE ? YE_ :
+ (curc == _IE ? IE_ : YEE_));
+ else
+ tempc = (curc == _YE ? YE :
+ (curc == _IE ? IE : YEE));
+ inc_cursor();
+ }
+ else
+ tempc = (curc == _YE ? YE :
+ (curc == _IE ? IE : YEE));
+ }
+ break;
+ default:
+ tempc = 0;
+ }
+
+ if (tempc)
+ put_and_redo(tempc);
+}
+
+/*
+** Change the char. under the cursor to a _X_ or X_ type
+*/
+
+ static void
+chg_c_to_X_orX_()
+{
+ int tempc;
+
+ switch (gchar_cursor())
+ {
+ case ALEF:
+ tempc = ALEF_;
+ break;
+ case ALEF_U_H:
+ tempc = ALEF_U_H_;
+ break;
+ case _AYN:
+ tempc = _AYN_;
+ break;
+ case AYN:
+ tempc = AYN_;
+ break;
+ case _GHAYN:
+ tempc = _GHAYN_;
+ break;
+ case GHAYN:
+ tempc = GHAYN_;
+ break;
+ case _HE:
+ tempc = _HE_;
+ break;
+ case YE:
+ tempc = YE_;
+ break;
+ case IE:
+ tempc = IE_;
+ break;
+ case TEE:
+ tempc = TEE_;
+ break;
+ case YEE:
+ tempc = YEE_;
+ break;
+ default:
+ tempc = 0;
+ }
+
+ if (tempc)
+ put_and_redo(tempc);
+}
+
+/*
+** Change the char. under the cursor to a _X_ or _X type
+*/
+ static void
+chg_c_to_X_or_X ()
+{
+ int tempc;
+
+ tempc = gchar_cursor();
+
+ if (curwin->w_cursor.col+1 < STRLEN(ml_get_curline()))
+ {
+ inc_cursor();
+
+ if ((tempc == F_HE) && (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR)))
+ {
+ tempc = _HE_;
+
+ dec_cursor();
+
+ put_and_redo(tempc);
+ return;
+ }
+
+ dec_cursor();
+ }
+
+ if ((tempc = toF_Xor_X_(tempc)) != 0)
+ put_and_redo(tempc);
+}
+
+/*
+** Change the character left to the cursor to a _X_ or X_ type
+*/
+ static void
+chg_l_to_X_orX_ ()
+{
+ int tempc;
+
+ if (!curwin->w_cursor.col &&
+ (curwin->w_cursor.col+1 == STRLEN(ml_get_curline())))
+ return;
+
+ if (!curwin->w_cursor.col && p_ri)
+ return;
+
+ if (p_ri)
+ dec_cursor();
+ else
+ inc_cursor();
+
+ switch (gchar_cursor())
+ {
+ case ALEF:
+ tempc = ALEF_;
+ break;
+ case ALEF_U_H:
+ tempc = ALEF_U_H_;
+ break;
+ case _AYN:
+ tempc = _AYN_;
+ break;
+ case AYN:
+ tempc = AYN_;
+ break;
+ case _GHAYN:
+ tempc = _GHAYN_;
+ break;
+ case GHAYN:
+ tempc = GHAYN_;
+ break;
+ case _HE:
+ tempc = _HE_;
+ break;
+ case YE:
+ tempc = YE_;
+ break;
+ case IE:
+ tempc = IE_;
+ break;
+ case TEE:
+ tempc = TEE_;
+ break;
+ case YEE:
+ tempc = YEE_;
+ break;
+ default:
+ tempc = 0;
+ }
+
+ if (tempc)
+ put_and_redo(tempc);
+
+ if (p_ri)
+ inc_cursor();
+ else
+ dec_cursor();
+}
+
+/*
+** Change the charcter left to the cursor to a X or _X type
+*/
+
+ static void
+chg_l_toXor_X ()
+{
+ int tempc;
+
+ if (!curwin->w_cursor.col &&
+ (curwin->w_cursor.col+1 == STRLEN(ml_get_curline())))
+ return;
+
+ if (!curwin->w_cursor.col && p_ri)
+ return;
+
+ if (p_ri)
+ dec_cursor();
+ else
+ inc_cursor();
+
+ switch (gchar_cursor())
+ {
+ case ALEF_:
+ tempc = ALEF;
+ break;
+ case ALEF_U_H_:
+ tempc = ALEF_U_H;
+ break;
+ case _AYN_:
+ tempc = _AYN;
+ break;
+ case AYN_:
+ tempc = AYN;
+ break;
+ case _GHAYN_:
+ tempc = _GHAYN;
+ break;
+ case GHAYN_:
+ tempc = GHAYN;
+ break;
+ case _HE_:
+ tempc = _HE;
+ break;
+ case YE_:
+ tempc = YE;
+ break;
+ case IE_:
+ tempc = IE;
+ break;
+ case TEE_:
+ tempc = TEE;
+ break;
+ case YEE_:
+ tempc = YEE;
+ break;
+ default:
+ tempc = 0;
+ }
+
+ if (tempc)
+ put_and_redo(tempc);
+
+ if (p_ri)
+ inc_cursor();
+ else
+ dec_cursor();
+}
+
+/*
+** Change the charcter right to the cursor to a _X or _X_ type
+*/
+
+ static void
+chg_r_to_Xor_X_()
+{
+ int tempc, c;
+
+ if (curwin->w_cursor.col)
+ {
+ if (!p_ri)
+ dec_cursor();
+
+ tempc = gchar_cursor();
+
+ if ((c = toF_Xor_X_(tempc)) != 0)
+ put_and_redo(c);
+
+ if (!p_ri)
+ inc_cursor();
+
+ }
+}
+
+/*
+** Map Farsi keyboard when in fkmap mode.
+*/
+
+ int
+fkmap(c)
+ int c;
+{
+ int tempc;
+ static int revins;
+
+ if (IS_SPECIAL(c))
+ return c;
+
+ if (VIM_ISDIGIT(c) || ((c == '.' || c == '+' || c == '-' ||
+ c == '^' || c == '%' || c == '#' || c == '=') && revins))
+ {
+ if (!revins)
+ {
+ if (curwin->w_cursor.col)
+ {
+ if (!p_ri)
+ dec_cursor();
+
+ chg_c_toX_orX ();
+ chg_l_toXor_X ();
+
+ if (!p_ri)
+ inc_cursor();
+ }
+ }
+
+ arrow_used = TRUE;
+ (void)stop_arrow();
+
+ if (!curwin->w_p_rl && revins)
+ inc_cursor();
+
+ ++revins;
+ p_ri=1;
+ }
+ else
+ {
+ if (revins)
+ {
+ arrow_used = TRUE;
+ (void)stop_arrow();
+
+ revins = 0;
+ if (curwin->w_p_rl)
+ {
+ while ((F_isdigit(gchar_cursor())
+ || (gchar_cursor() == F_PERIOD
+ || gchar_cursor() == F_PLUS
+ || gchar_cursor() == F_MINUS
+ || gchar_cursor() == F_MUL
+ || gchar_cursor() == F_DIVIDE
+ || gchar_cursor() == F_PERCENT
+ || gchar_cursor() == F_EQUALS))
+ && gchar_cursor() != NUL)
+ ++curwin->w_cursor.col;
+ }
+ else
+ {
+ if (curwin->w_cursor.col)
+ while ((F_isdigit(gchar_cursor())
+ || (gchar_cursor() == F_PERIOD
+ || gchar_cursor() == F_PLUS
+ || gchar_cursor() == F_MINUS
+ || gchar_cursor() == F_MUL
+ || gchar_cursor() == F_DIVIDE
+ || gchar_cursor() == F_PERCENT
+ || gchar_cursor() == F_EQUALS))
+ && --curwin->w_cursor.col)
+ ;
+
+ if (!F_isdigit(gchar_cursor()))
+ ++curwin->w_cursor.col;
+ }
+ }
+ }
+
+ if (!revins)
+ {
+ if (curwin->w_p_rl)
+ p_ri=0;
+ if (!curwin->w_p_rl)
+ p_ri=1;
+ }
+
+ if ((c < 0x100) && (isalpha(c) || c == '&' || c == '^' || c == ';' ||
+ c == '\''|| c == ',' || c == '[' ||
+ c == ']' || c == '{' || c == '}' ))
+ chg_r_to_Xor_X_();
+
+ tempc = 0;
+
+ switch (c)
+ {
+ case '`':
+ case ' ':
+ case '.':
+ case '!':
+ case '"':
+ case '$':
+ case '%':
+ case '^':
+ case '&':
+ case '/':
+ case '(':
+ case ')':
+ case '=':
+ case '\\':
+ case '?':
+ case '+':
+ case '-':
+ case '_':
+ case '*':
+ case ':':
+ case '#':
+ case '~':
+ case '@':
+ case '<':
+ case '>':
+ case '{':
+ case '}':
+ case '|':
+ case '0':
+ case '1':
+ case '2':
+ case '3':
+ case '4':
+ case '5':
+ case '6':
+ case '7':
+ case '8':
+ case '9':
+ case 'B':
+ case 'E':
+ case 'F':
+ case 'H':
+ case 'I':
+ case 'K':
+ case 'L':
+ case 'M':
+ case 'O':
+ case 'P':
+ case 'Q':
+ case 'R':
+ case 'T':
+ case 'U':
+ case 'W':
+ case 'Y':
+ case NL:
+ case TAB:
+
+ if (p_ri && c == NL && curwin->w_cursor.col)
+ {
+ /*
+ ** If the char before the cursor is _X_ or X_ do not change
+ ** the one under the cursor with X type.
+ */
+
+ dec_cursor();
+
+ if (F_isalpha(gchar_cursor()))
+ {
+ inc_cursor();
+ return NL;
+ }
+
+ inc_cursor();
+ }
+
+ if (!p_ri)
+ if (!curwin->w_cursor.col)
+ {
+ switch (c)
+ {
+ case '0': return FARSI_0;
+ case '1': return FARSI_1;
+ case '2': return FARSI_2;
+ case '3': return FARSI_3;
+ case '4': return FARSI_4;
+ case '5': return FARSI_5;
+ case '6': return FARSI_6;
+ case '7': return FARSI_7;
+ case '8': return FARSI_8;
+ case '9': return FARSI_9;
+ case 'B': return F_PSP;
+ case 'E': return JAZR_N;
+ case 'F': return ALEF_D_H;
+ case 'H': return ALEF_A;
+ case 'I': return TASH;
+ case 'K': return F_LQUOT;
+ case 'L': return F_RQUOT;
+ case 'M': return HAMZE;
+ case 'O': return '[';
+ case 'P': return ']';
+ case 'Q': return OO;
+ case 'R': return MAD_N;
+ case 'T': return OW;
+ case 'U': return MAD;
+ case 'W': return OW_OW;
+ case 'Y': return JAZR;
+ case '`': return F_PCN;
+ case '!': return F_EXCL;
+ case '@': return F_COMMA;
+ case '#': return F_DIVIDE;
+ case '$': return F_CURRENCY;
+ case '%': return F_PERCENT;
+ case '^': return F_MUL;
+ case '&': return F_BCOMMA;
+ case '*': return F_STAR;
+ case '(': return F_LPARENT;
+ case ')': return F_RPARENT;
+ case '-': return F_MINUS;
+ case '_': return F_UNDERLINE;
+ case '=': return F_EQUALS;
+ case '+': return F_PLUS;
+ case '\\': return F_BSLASH;
+ case '|': return F_PIPE;
+ case ':': return F_DCOLON;
+ case '"': return F_SEMICOLON;
+ case '.': return F_PERIOD;
+ case '/': return F_SLASH;
+ case '<': return F_LESS;
+ case '>': return F_GREATER;
+ case '?': return F_QUESTION;
+ case ' ': return F_BLANK;
+ }
+ break;
+ }
+ if (!p_ri)
+ dec_cursor();
+
+ switch ((tempc = gchar_cursor()))
+ {
+ case _BE:
+ case _PE:
+ case _TE:
+ case _SE:
+ case _JIM:
+ case _CHE:
+ case _HE_J:
+ case _XE:
+ case _SIN:
+ case _SHIN:
+ case _SAD:
+ case _ZAD:
+ case _FE:
+ case _GHAF:
+ case _KAF:
+ case _KAF_H:
+ case _GAF:
+ case _LAM:
+ case _MIM:
+ case _NOON:
+ case _HE:
+ case _HE_:
+ case _TA:
+ case _ZA:
+ put_curr_and_l_to_X(toF_TyA(tempc));
+ break;
+ case _AYN:
+ case _AYN_:
+
+ if (!p_ri)
+ if (!curwin->w_cursor.col)
+ {
+ put_curr_and_l_to_X(AYN);
+ break;
+ }
+
+ if (p_ri)
+ inc_cursor();
+ else
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = AYN_;
+ else
+ tempc = AYN;
+
+ if (p_ri)
+ dec_cursor();
+ else
+ inc_cursor();
+
+ put_curr_and_l_to_X(tempc);
+
+ break;
+ case _GHAYN:
+ case _GHAYN_:
+
+ if (!p_ri)
+ if (!curwin->w_cursor.col)
+ {
+ put_curr_and_l_to_X(GHAYN);
+ break;
+ }
+
+ if (p_ri)
+ inc_cursor();
+ else
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = GHAYN_;
+ else
+ tempc = GHAYN;
+
+ if (p_ri)
+ dec_cursor();
+ else
+ inc_cursor();
+
+ put_curr_and_l_to_X(tempc);
+ break;
+ case _YE:
+ case _IE:
+ case _YEE:
+ if (!p_ri)
+ if (!curwin->w_cursor.col)
+ {
+ put_curr_and_l_to_X((tempc == _YE ? YE :
+ (tempc == _IE ? IE : YEE)));
+ break;
+ }
+
+ if (p_ri)
+ inc_cursor();
+ else
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = (tempc == _YE ? YE_ :
+ (tempc == _IE ? IE_ : YEE_));
+ else
+ tempc = (tempc == _YE ? YE :
+ (tempc == _IE ? IE : YEE));
+
+ if (p_ri)
+ dec_cursor();
+ else
+ inc_cursor();
+
+ put_curr_and_l_to_X(tempc);
+ break;
+ }
+
+ if (!p_ri)
+ inc_cursor();
+
+ tempc = 0;
+
+ switch (c)
+ {
+ case '0': return FARSI_0;
+ case '1': return FARSI_1;
+ case '2': return FARSI_2;
+ case '3': return FARSI_3;
+ case '4': return FARSI_4;
+ case '5': return FARSI_5;
+ case '6': return FARSI_6;
+ case '7': return FARSI_7;
+ case '8': return FARSI_8;
+ case '9': return FARSI_9;
+ case 'B': return F_PSP;
+ case 'E': return JAZR_N;
+ case 'F': return ALEF_D_H;
+ case 'H': return ALEF_A;
+ case 'I': return TASH;
+ case 'K': return F_LQUOT;
+ case 'L': return F_RQUOT;
+ case 'M': return HAMZE;
+ case 'O': return '[';
+ case 'P': return ']';
+ case 'Q': return OO;
+ case 'R': return MAD_N;
+ case 'T': return OW;
+ case 'U': return MAD;
+ case 'W': return OW_OW;
+ case 'Y': return JAZR;
+ case '`': return F_PCN;
+ case '!': return F_EXCL;
+ case '@': return F_COMMA;
+ case '#': return F_DIVIDE;
+ case '$': return F_CURRENCY;
+ case '%': return F_PERCENT;
+ case '^': return F_MUL;
+ case '&': return F_BCOMMA;
+ case '*': return F_STAR;
+ case '(': return F_LPARENT;
+ case ')': return F_RPARENT;
+ case '-': return F_MINUS;
+ case '_': return F_UNDERLINE;
+ case '=': return F_EQUALS;
+ case '+': return F_PLUS;
+ case '\\': return F_BSLASH;
+ case '|': return F_PIPE;
+ case ':': return F_DCOLON;
+ case '"': return F_SEMICOLON;
+ case '.': return F_PERIOD;
+ case '/': return F_SLASH;
+ case '<': return F_LESS;
+ case '>': return F_GREATER;
+ case '?': return F_QUESTION;
+ case ' ': return F_BLANK;
+ }
+ break;
+
+ case 'a':
+ tempc = _SHIN;
+ break;
+ case 'A':
+ tempc = WAW_H;
+ break;
+ case 'b':
+ tempc = ZAL;
+ break;
+ case 'c':
+ tempc = ZE;
+ break;
+ case 'C':
+ tempc = JE;
+ break;
+ case 'd':
+ tempc = _YE;
+ break;
+ case 'D':
+ tempc = _YEE;
+ break;
+ case 'e':
+ tempc = _SE;
+ break;
+ case 'f':
+ tempc = _BE;
+ break;
+ case 'g':
+ tempc = _LAM;
+ break;
+ case 'G':
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
+ {
+
+ if (gchar_cursor() == _LAM)
+ chg_c_toX_orX ();
+ else
+ if (p_ri)
+ chg_c_to_X_or_X ();
+ }
+
+ if (!p_ri)
+ if (!curwin->w_cursor.col)
+ return ALEF_U_H;
+
+ if (!p_ri)
+ dec_cursor();
+
+ if (gchar_cursor() == _LAM)
+ {
+ chg_c_toX_orX ();
+ chg_l_toXor_X ();
+ tempc = ALEF_U_H;
+ }
+ else
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ {
+ tempc = ALEF_U_H_;
+ chg_l_toXor_X ();
+ }
+ else
+ tempc = ALEF_U_H;
+
+ if (!p_ri)
+ inc_cursor();
+
+ return tempc;
+ case 'h':
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
+ {
+ if (p_ri)
+ chg_c_to_X_or_X ();
+
+ }
+
+ if (!p_ri)
+ if (!curwin->w_cursor.col)
+ return ALEF;
+
+ if (!p_ri)
+ dec_cursor();
+
+ if (gchar_cursor() == _LAM)
+ {
+ chg_l_toXor_X();
+ del_char(FALSE);
+ AppendCharToRedobuff(K_BS);
+
+ if (!p_ri)
+ dec_cursor();
+
+ tempc = LA;
+ }
+ else
+ {
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ {
+ tempc = ALEF_;
+ chg_l_toXor_X ();
+ }
+ else
+ tempc = ALEF;
+ }
+
+ if (!p_ri)
+ inc_cursor();
+
+ return tempc;
+ case 'i':
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
+ {
+ if (!p_ri && !F_is_TyE(tempc))
+ chg_c_to_X_orX_ ();
+ if (p_ri)
+ chg_c_to_X_or_X ();
+
+ }
+
+ if (!p_ri && !curwin->w_cursor.col)
+ return _HE;
+
+ if (!p_ri)
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = _HE_;
+ else
+ tempc = _HE;
+
+ if (!p_ri)
+ inc_cursor();
+ break;
+ case 'j':
+ tempc = _TE;
+ break;
+ case 'J':
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
+ {
+ if (p_ri)
+ chg_c_to_X_or_X ();
+
+ }
+
+ if (!p_ri)
+ if (!curwin->w_cursor.col)
+ return TEE;
+
+ if (!p_ri)
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ {
+ tempc = TEE_;
+ chg_l_toXor_X ();
+ }
+ else
+ tempc = TEE;
+
+ if (!p_ri)
+ inc_cursor();
+
+ return tempc;
+ case 'k':
+ tempc = _NOON;
+ break;
+ case 'l':
+ tempc = _MIM;
+ break;
+ case 'm':
+ tempc = _PE;
+ break;
+ case 'n':
+ case 'N':
+ tempc = DAL;
+ break;
+ case 'o':
+ tempc = _XE;
+ break;
+ case 'p':
+ tempc = _HE_J;
+ break;
+ case 'q':
+ tempc = _ZAD;
+ break;
+ case 'r':
+ tempc = _GHAF;
+ break;
+ case 's':
+ tempc = _SIN;
+ break;
+ case 'S':
+ tempc = _IE;
+ break;
+ case 't':
+ tempc = _FE;
+ break;
+ case 'u':
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
+ {
+ if (!p_ri && !F_is_TyE(tempc))
+ chg_c_to_X_orX_ ();
+ if (p_ri)
+ chg_c_to_X_or_X ();
+
+ }
+
+ if (!p_ri && !curwin->w_cursor.col)
+ return _AYN;
+
+ if (!p_ri)
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = _AYN_;
+ else
+ tempc = _AYN;
+
+ if (!p_ri)
+ inc_cursor();
+ break;
+ case 'v':
+ case 'V':
+ tempc = RE;
+ break;
+ case 'w':
+ tempc = _SAD;
+ break;
+ case 'x':
+ case 'X':
+ tempc = _TA;
+ break;
+ case 'y':
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
+ {
+ if (!p_ri && !F_is_TyE(tempc))
+ chg_c_to_X_orX_ ();
+ if (p_ri)
+ chg_c_to_X_or_X ();
+
+ }
+
+ if (!p_ri && !curwin->w_cursor.col)
+ return _GHAYN;
+
+ if (!p_ri)
+ dec_cursor();
+
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = _GHAYN_;
+ else
+ tempc = _GHAYN;
+
+ if (!p_ri)
+ inc_cursor();
+
+ break;
+ case 'z':
+ tempc = _ZA;
+ break;
+ case 'Z':
+ tempc = _KAF_H;
+ break;
+ case ';':
+ tempc = _KAF;
+ break;
+ case '\'':
+ tempc = _GAF;
+ break;
+ case ',':
+ tempc = WAW;
+ break;
+ case '[':
+ tempc = _JIM;
+ break;
+ case ']':
+ tempc = _CHE;
+ break;
+ }
+
+ if ((F_isalpha(tempc) || F_isdigit(tempc)))
+ {
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
+ {
+ if (!p_ri && !F_is_TyE(tempc))
+ chg_c_to_X_orX_ ();
+ if (p_ri)
+ chg_c_to_X_or_X ();
+ }
+
+ if (curwin->w_cursor.col)
+ {
+ if (!p_ri)
+ dec_cursor();
+
+ if (F_is_TyE(tempc))
+ chg_l_toXor_X ();
+ else
+ chg_l_to_X_orX_ ();
+
+ if (!p_ri)
+ inc_cursor();
+ }
+ }
+ if (tempc)
+ return tempc;
+ return c;
+}
+
+/*
+** Convert a none leading Farsi char into a leading type.
+*/
+ static int
+toF_leading(c)
+ int c;
+{
+ switch (c)
+ {
+ case ALEF_: return ALEF;
+ case ALEF_U_H_: return ALEF_U_H;
+ case BE: return _BE;
+ case PE: return _PE;
+ case TE: return _TE;
+ case SE: return _SE;
+ case JIM: return _JIM;
+ case CHE: return _CHE;
+ case HE_J: r