summaryrefslogtreecommitdiff
path: root/src/farsi.c
diff options
context:
space:
mode:
authorBram Moolenaar <Bram@vim.org>2017-01-29 17:59:12 +0100
committerBram Moolenaar <Bram@vim.org>2017-01-29 17:59:12 +0100
commitddf662a1c86ef0b4bd0c55c5f0aa192ebd6d9a5e (patch)
tree70e917e0c60dffd51b2a037c039a8fd5d3bfa3b5 /src/farsi.c
parent24c2e48ef8b8b9053fa18039e6f6118337f908f8 (diff)
downloadvim-git-ddf662a1c86ef0b4bd0c55c5f0aa192ebd6d9a5e.tar.gz
patch 8.0.0262: Farsi support is barely testedv8.0.0262
Problem: Farsi support is barely tested. Solution: Add more tests for Farsi. Clean up the code.
Diffstat (limited to 'src/farsi.c')
-rw-r--r--src/farsi.c618
1 files changed, 301 insertions, 317 deletions
diff --git a/src/farsi.c b/src/farsi.c
index 1c5d2fd72..682dd4630 100644
--- a/src/farsi.c
+++ b/src/farsi.c
@@ -15,30 +15,11 @@
#if defined(FEAT_FKMAP) || defined(PROTO)
-static int toF_Xor_X_(int c);
-static int F_is_TyE(int c);
-static int F_is_TyC_TyD(int c);
static int F_is_TyB_TyC_TyD(int src, int offset);
-static int toF_TyB(int c);
-static void put_curr_and_l_to_X(int c);
-static void put_and_redo(int c);
-static void chg_c_toX_orX(void);
-static void chg_c_to_X_orX_(void);
-static void chg_c_to_X_or_X(void);
-static void chg_l_to_X_orX_(void);
-static void chg_l_toXor_X(void);
-static void chg_r_to_Xor_X_(void);
-static int toF_leading(int c);
-static int toF_Rjoin(int c);
-static int canF_Ljoin(int c);
-static int canF_Rjoin(int c);
-static int F_isterm(int c);
-static int toF_ending(int c);
-static void lrswapbuf(char_u *buf, int len);
/*
* Convert the given Farsi character into a _X or _X_ type
-*/
+ */
static int
toF_Xor_X_(int c)
{
@@ -105,7 +86,7 @@ toF_Xor_X_(int c)
/*
* Convert the given Farsi character into Farsi capital character.
-*/
+ */
static int
toF_TyA(int c)
{
@@ -156,7 +137,7 @@ toF_TyA(int 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(int src, int offset)
{
@@ -207,7 +188,7 @@ F_is_TyB_TyC_TyD(int src, int offset)
/*
* Is the Farsi character one of the terminating only type.
-*/
+ */
static int
F_is_TyE(int c)
{
@@ -230,7 +211,7 @@ F_is_TyE(int c)
/*
* Is the Farsi character one of the none leading type.
-*/
+ */
static int
F_is_TyC_TyD(int c)
{
@@ -254,7 +235,7 @@ F_is_TyC_TyD(int c)
/*
* Convert a none leading Farsi char into a leading type.
-*/
+ */
static int
toF_TyB(int c)
{
@@ -275,9 +256,18 @@ toF_TyB(int c)
return c;
}
+
+ static void
+put_and_redo(int c)
+{
+ pchar_cursor(c);
+ AppendCharToRedobuff(K_BS);
+ AppendCharToRedobuff(c);
+}
+
/*
* Overwrite the current redo and cursor characters + left adjust.
-*/
+ */
static void
put_curr_and_l_to_X(int c)
{
@@ -312,17 +302,9 @@ put_curr_and_l_to_X(int c)
put_and_redo(c);
}
- static void
-put_and_redo(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(void)
{
@@ -446,8 +428,7 @@ chg_c_toX_orX(void)
/*
* Change the char. under the cursor to a _X_ or X_ type
-*/
-
+ */
static void
chg_c_to_X_orX_(void)
{
@@ -498,9 +479,9 @@ chg_c_to_X_orX_(void)
/*
* Change the char. under the cursor to a _X_ or _X type
-*/
+ */
static void
-chg_c_to_X_or_X (void)
+chg_c_to_X_or_X(void)
{
int tempc;
@@ -529,7 +510,7 @@ chg_c_to_X_or_X (void)
/*
* Change the character left to the cursor to a _X_ or X_ type
-*/
+ */
static void
chg_l_to_X_orX_(void)
{
@@ -597,10 +578,9 @@ chg_l_to_X_orX_(void)
/*
* Change the character left to the cursor to a X or _X type
-*/
-
+ */
static void
-chg_l_toXor_X (void)
+chg_l_toXor_X(void)
{
int tempc;
@@ -666,8 +646,7 @@ chg_l_toXor_X (void)
/*
* Change the character right to the cursor to a _X or _X_ type
-*/
-
+ */
static void
chg_r_to_Xor_X_(void)
{
@@ -691,48 +670,50 @@ chg_r_to_Xor_X_(void)
/*
* Map Farsi keyboard when in fkmap mode.
-*/
-
+ */
int
fkmap(int c)
{
int tempc;
- static int revins;
+ int insert_mode = (State & INSERT);
+ static int revins = 0;
if (IS_SPECIAL(c))
return c;
- if (VIM_ISDIGIT(c) || ((c == '.' || c == '+' || c == '-' ||
- c == '^' || c == '%' || c == '#' || c == '=') && revins))
+ if (insert_mode)
{
- if (!revins)
+ if (VIM_ISDIGIT(c) || ((c == '.' || c == '+' || c == '-' ||
+ c == '^' || c == '%' || c == '#' || c == '=') && revins))
{
- if (curwin->w_cursor.col)
+ /* Numbers are entered left-to-right. */
+ if (!revins)
{
- if (!p_ri)
- dec_cursor();
+ if (curwin->w_cursor.col)
+ {
+ if (!p_ri)
+ dec_cursor();
- chg_c_toX_orX ();
- chg_l_toXor_X ();
+ chg_c_toX_orX ();
+ chg_l_toXor_X ();
- if (!p_ri)
- inc_cursor();
+ if (!p_ri)
+ inc_cursor();
+ }
}
- }
- arrow_used = TRUE;
- (void)stop_arrow();
+ arrow_used = TRUE;
+ (void)stop_arrow();
- if (!curwin->w_p_rl && revins)
- inc_cursor();
+ if (!curwin->w_p_rl && revins)
+ inc_cursor();
- ++revins;
- p_ri=1;
- }
- else
- {
- if (revins)
+ ++revins;
+ p_ri = 1;
+ }
+ else if (revins)
{
+ /* Stop entering number. */
arrow_used = TRUE;
(void)stop_arrow();
@@ -773,14 +754,14 @@ fkmap(int c)
if (!revins)
{
if (curwin->w_p_rl)
- p_ri=0;
+ p_ri = 0;
if (!curwin->w_p_rl)
- p_ri=1;
+ p_ri = 1;
}
- if ((c < 0x100) && (isalpha(c) || c == '&' || c == '^' || c == ';' ||
+ if ((c < 0x100) && (isalpha(c) || c == '&' || c == '^' || c == ';' ||
c == '\''|| c == ',' || c == '[' ||
- c == ']' || c == '{' || c == '}' ))
+ c == ']' || c == '{' || c == '}'))
chg_r_to_Xor_X_();
tempc = 0;
@@ -844,13 +825,12 @@ fkmap(int c)
case NL:
case TAB:
- if (p_ri && c == NL && curwin->w_cursor.col)
+ if (p_ri && c == NL && curwin->w_cursor.col && insert_mode)
{
/*
* 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()))
@@ -920,215 +900,219 @@ fkmap(int c)
}
break;
}
- if (!p_ri)
- dec_cursor();
- switch ((tempc = gchar_cursor()))
+ if (insert_mode)
{
- 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();
+ if (!p_ri)
+ dec_cursor();
- put_curr_and_l_to_X(tempc);
- break;
+ 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;
+ 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;
+ 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;
+ tempc = _SHIN;
+ break;
case 'A':
- tempc = WAW_H;
- break;
+ tempc = WAW_H;
+ break;
case 'b':
- tempc = ZAL;
- break;
+ tempc = ZAL;
+ break;
case 'c':
- tempc = ZE;
- break;
+ tempc = ZE;
+ break;
case 'C':
- tempc = JE;
- break;
+ tempc = JE;
+ break;
case 'd':
- tempc = _YE;
- break;
+ tempc = _YE;
+ break;
case 'D':
- tempc = _YEE;
- break;
+ tempc = _YEE;
+ break;
case 'e':
- tempc = _SE;
- break;
+ tempc = _SE;
+ break;
case 'f':
- tempc = _BE;
- break;
+ tempc = _BE;
+ break;
case 'g':
- tempc = _LAM;
- break;
+ tempc = _LAM;
+ break;
case 'G':
if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
{
@@ -1230,7 +1214,7 @@ fkmap(int c)
inc_cursor();
break;
case 'j':
- tempc = _TE;
+ tempc = _TE;
break;
case 'J':
if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
@@ -1260,73 +1244,73 @@ fkmap(int c)
return tempc;
case 'k':
- tempc = _NOON;
+ tempc = _NOON;
break;
case 'l':
- tempc = _MIM;
+ tempc = _MIM;
break;
case 'm':
- tempc = _PE;
+ tempc = _PE;
break;
case 'n':
case 'N':
- tempc = DAL;
+ tempc = DAL;
break;
case 'o':
- tempc = _XE;
+ tempc = _XE;
break;
case 'p':
- tempc = _HE_J;
+ tempc = _HE_J;
break;
case 'q':
- tempc = _ZAD;
+ tempc = _ZAD;
break;
case 'r':
- tempc = _GHAF;
+ tempc = _GHAF;
break;
case 's':
- tempc = _SIN;
+ tempc = _SIN;
break;
case 'S':
- tempc = _IE;
+ tempc = _IE;
break;
case 't':
- tempc = _FE;
+ 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 (!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 && !curwin->w_cursor.col)
+ return _AYN;
- if (!p_ri)
- dec_cursor();
+ if (!p_ri)
+ dec_cursor();
- if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
- tempc = _AYN_;
- else
- tempc = _AYN;
+ if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
+ tempc = _AYN_;
+ else
+ tempc = _AYN;
- if (!p_ri)
- inc_cursor();
+ if (!p_ri)
+ inc_cursor();
break;
case 'v':
case 'V':
- tempc = RE;
+ tempc = RE;
break;
case 'w':
- tempc = _SAD;
+ tempc = _SAD;
break;
case 'x':
case 'X':
- tempc = _TA;
+ tempc = _TA;
break;
case 'y':
if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
@@ -1354,36 +1338,36 @@ fkmap(int c)
break;
case 'z':
- tempc = _ZA;
+ tempc = _ZA;
break;
case 'Z':
- tempc = _KAF_H;
+ tempc = _KAF_H;
break;
case ';':
- tempc = _KAF;
+ tempc = _KAF;
break;
case '\'':
- tempc = _GAF;
+ tempc = _GAF;
break;
case ',':
- tempc = WAW;
+ tempc = WAW;
break;
case '[':
- tempc = _JIM;
+ tempc = _JIM;
break;
case ']':
- tempc = _CHE;
+ tempc = _CHE;
break;
}
- if ((F_isalpha(tempc) || F_isdigit(tempc)))
+ if (F_isalpha(tempc) || F_isdigit(tempc))
{
- if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
+ if (!curwin->w_cursor.col && STRLEN(ml_get_curline()))
{
if (!p_ri && !F_is_TyE(tempc))
- chg_c_to_X_orX_ ();
+ chg_c_to_X_orX_();
if (p_ri)
- chg_c_to_X_or_X ();
+ chg_c_to_X_or_X();
}
if (curwin->w_cursor.col)
@@ -1392,9 +1376,9 @@ fkmap(int c)
dec_cursor();
if (F_is_TyE(tempc))
- chg_l_toXor_X ();
+ chg_l_toXor_X();
else
- chg_l_to_X_orX_ ();
+ chg_l_to_X_orX_();
if (!p_ri)
inc_cursor();
@@ -1407,7 +1391,7 @@ fkmap(int c)
/*
* Convert a none leading Farsi char into a leading type.
-*/
+ */
static int
toF_leading(int c)
{
@@ -1461,7 +1445,7 @@ toF_leading(int c)
/*
* Convert a given Farsi char into right joining type.
-*/
+ */
static int
toF_Rjoin(int c)
{
@@ -1517,7 +1501,7 @@ toF_Rjoin(int c)
/*
* Can a given Farsi character join via its left edj.
-*/
+ */
static int
canF_Ljoin(int c)
{
@@ -1591,7 +1575,7 @@ canF_Ljoin(int c)
/*
* Can a given Farsi character join via its right edj.
-*/
+ */
static int
canF_Rjoin(int c)
{
@@ -1619,7 +1603,7 @@ canF_Rjoin(int c)
/*
* is a given Farsi character a terminating type.
-*/
+ */
static int
F_isterm(int c)
{
@@ -1646,7 +1630,7 @@ F_isterm(int c)
/*
* Convert the given Farsi character into a ending type .
-*/
+ */
static int
toF_ending(int c)
{
@@ -1691,7 +1675,7 @@ toF_ending(int c)
/*
* Convert the Farsi 3342 standard into Farsi VIM.
-*/
+ */
static void
conv_to_pvim(void)
{