Compare commits

...

3 Commits

Author SHA1 Message Date
Bram Moolenaar
80627cf51f patch 8.0.0263: Farsi support is not tested enough
Problem:    Farsi support is not tested enough.
Solution:   Add more tests for Farsi.  Clean up the code.
2017-01-29 19:59:39 +01:00
Bram Moolenaar
ddf662a1c8 patch 8.0.0262: Farsi support is barely tested
Problem:    Farsi support is barely tested.
Solution:   Add more tests for Farsi.  Clean up the code.
2017-01-29 17:59:12 +01:00
Bram Moolenaar
24c2e48ef8 patch 8.0.0261: not enough test coverage for eval functions
Problem:    Not enough test coverage for eval functions.
Solution:   Add more tests. (Dominique Pelle, closes #1420)
2017-01-29 15:45:12 +01:00
5 changed files with 542 additions and 360 deletions

View File

@@ -6166,6 +6166,9 @@ insertchar(
&& (!has_mbyte || MB_BYTE2LEN_CHECK(c) == 1)
#endif
&& i < INPUT_BUFLEN
# ifdef FEAT_FKMAP
&& !(p_fkmap && KeyTyped) /* Farsi mode mapping moves cursor */
# endif
&& (textwidth == 0
|| (virtcol += byte2cells(buf[i - 1])) < (colnr_T)textwidth)
&& !(!no_abbr && !vim_iswordc(c) && vim_iswordc(buf[i - 1])))
@@ -6174,10 +6177,6 @@ insertchar(
c = vgetc();
if (p_hkmap && KeyTyped)
c = hkmap(c); /* Hebrew mode mapping */
# ifdef FEAT_FKMAP
if (p_fkmap && KeyTyped)
c = fkmap(c); /* Farsi mode mapping */
# endif
buf[i++] = c;
#else
buf[i++] = vgetc();

View File

@@ -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();
if (!curwin->w_p_rl && revins)
inc_cursor();
++revins;
p_ri = 1;
}
arrow_used = TRUE;
(void)stop_arrow();
if (!curwin->w_p_rl && revins)
inc_cursor();
++revins;
p_ri=1;
}
else
{
if (revins)
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)
dec_cursor();
if (!p_ri)
if (!curwin->w_cursor.col)
{
put_curr_and_l_to_X(AYN);
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)
inc_cursor();
else
dec_cursor();
if (!p_ri)
if (!curwin->w_cursor.col)
{
put_curr_and_l_to_X(AYN);
break;
}
if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
tempc = AYN_;
else
tempc = AYN;
if (p_ri)
inc_cursor();
else
dec_cursor();
if (p_ri)
dec_cursor();
else
inc_cursor();
if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
tempc = AYN_;
else
tempc = AYN;
put_curr_and_l_to_X(tempc);
if (p_ri)
dec_cursor();
else
inc_cursor();
break;
case _GHAYN:
case _GHAYN_:
put_curr_and_l_to_X(tempc);
if (!p_ri)
if (!curwin->w_cursor.col)
{
put_curr_and_l_to_X(GHAYN);
break;
}
break;
case _GHAYN:
case _GHAYN_:
if (p_ri)
inc_cursor();
else
dec_cursor();
if (!p_ri)
if (!curwin->w_cursor.col)
{
put_curr_and_l_to_X(GHAYN);
break;
}
if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
tempc = GHAYN_;
else
tempc = GHAYN;
if (p_ri)
inc_cursor();
else
dec_cursor();
if (p_ri)
dec_cursor();
else
inc_cursor();
if (F_is_TyB_TyC_TyD(SRC_EDT, AT_CURSOR))
tempc = GHAYN_;
else
tempc = GHAYN;
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)
dec_cursor();
else
inc_cursor();
if (p_ri)
inc_cursor();
else
dec_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 (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)
inc_cursor();
else
dec_cursor();
if (p_ri)
dec_cursor();
else
inc_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));
put_curr_and_l_to_X(tempc);
break;
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)
{
@@ -1936,56 +1920,56 @@ cmdl_fkmap(int c)
case NL:
case TAB:
switch ((tempc = cmd_gchar(AT_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 _AYN:
case _GHAYN:
case _FE:
case _GHAF:
case _KAF:
case _GAF:
case _LAM:
case _MIM:
case _NOON:
case _HE:
case _HE_:
cmd_pchar(toF_TyA(tempc), AT_CURSOR);
break;
case _AYN_:
cmd_pchar(AYN_, AT_CURSOR);
break;
case _GHAYN_:
cmd_pchar(GHAYN_, AT_CURSOR);
break;
case _IE:
if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
cmd_pchar(IE_, AT_CURSOR);
else
cmd_pchar(IE, AT_CURSOR);
break;
case _YEE:
if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
cmd_pchar(YEE_, AT_CURSOR);
else
cmd_pchar(YEE, AT_CURSOR);
break;
case _YE:
if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
cmd_pchar(YE_, AT_CURSOR);
else
cmd_pchar(YE, AT_CURSOR);
switch ((tempc = cmd_gchar(AT_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 _AYN:
case _GHAYN:
case _FE:
case _GHAF:
case _KAF:
case _GAF:
case _LAM:
case _MIM:
case _NOON:
case _HE:
case _HE_:
cmd_pchar(toF_TyA(tempc), AT_CURSOR);
break;
case _AYN_:
cmd_pchar(AYN_, AT_CURSOR);
break;
case _GHAYN_:
cmd_pchar(GHAYN_, AT_CURSOR);
break;
case _IE:
if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
cmd_pchar(IE_, AT_CURSOR);
else
cmd_pchar(IE, AT_CURSOR);
break;
case _YEE:
if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
cmd_pchar(YEE_, AT_CURSOR);
else
cmd_pchar(YEE, AT_CURSOR);
break;
case _YE:
if (F_is_TyB_TyC_TyD(SRC_CMD, AT_CURSOR+1))
cmd_pchar(YE_, AT_CURSOR);
else
cmd_pchar(YE, AT_CURSOR);
}
switch (c)

View File

@@ -1,4 +1,5 @@
" Simplistic testing of Farsi mode.
" Note: must be edited with latin1 encoding.
if !has('farsi')
finish
@@ -82,3 +83,51 @@ func Test_farsi_map()
set noaltkeymap
bwipe!
endfunc
func Test_input_farsi()
new
setlocal rightleft fkmap
" numbers switch input direction
call feedkeys("aabc0123456789.+-^%#=xyz\<Esc>", 'tx')
call assert_equal("\x8c<38>ν<EFBFBD><CEBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>\x93<39>", getline('.'))
" all non-number special chars with spaces
call feedkeys("oB E F H I K L M O P Q R T U W Y ` ! @ # $ % ^ & * () - _ = + \\ | : \" . / < > ? \<Esc>", 'tx')
call assert_equal("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD> [<5B>]<5D><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>񠢠<EFBFBD><F1A0A2A0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E8A0A8><EFBFBD><EFBFBD><EFBFBD><E9A0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EAA0BA><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", getline('.'))
" all non-number special chars without spaces
call feedkeys("oBEFHIKLMOPQRTUWY`!@#$%^&*()-_=+\\|:\"./<>?\<Esc>",'tx')
call assert_equal("<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>[]<5D><><EFBFBD><EFBFBD><EFBFBD>񢣧<EFBFBD><F1A2A3A7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EABABB><EFBFBD><EFBFBD><EFBFBD>", getline('.'))
" all letter chars with spaces
call feedkeys("oa A b c C d D e f g G h i j J k l m n N o p q r s S t u v V w x X y z Z ; \ , [ ] \<Esc>", 'tx')
call assert_equal(<><D1A0>̠ΠϠ<CEA0><CFA0><EFBFBD><EFBFBD>Ơàܠ<C3A0><DCA0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Š<EFBFBD><C5A0>ޠݠĠˠˠʠɠӠ٠Р<D9A0><D0A0>ؠ֠͠͠ҠԠԠנՠ<D7A0><D5A0>ڠ<EFBFBD>ߠǠȠ", getline('.'))
" all letter chars without spaces
call feedkeys("oaAbcCdDefgGhijJklmnNopqrsStuvVwxXyzZ;\,[]\<Esc>", 'tx')
call assert_equal("\x8c<38><63><EFBFBD><EFBFBD>\x9f<39>\x86\x83<38><33><EFBFBD>\x9d\x85\x80\x9c\x9b\x84<38><34>\x8a\x89\x8e\x96\x8b<38>\x95\x90<39><30>\x8d<38><64>\x93<39><33>\x97<39>\x87\x88", getline('.'))
bwipe!
endfunc
func Test_command_line_farsi()
set allowrevins altkeymap
" letter characters with spaces
call feedkeys(":\"\<C-_>a A b c C d D e f g G h i j J k l m n N o p q r s S t u v V w x X y z Z ; \\ , [ ]\<CR>", 'tx')
call assert_equal("\"\x88<38>Ǡߠ<C7A0><DFA0>ڠՠՠנԠԠҠ֠͠͠ؠ<D6A0><D8A0>Р٠ӠɠʠˠˠĠݠޠ<DDA0><DEA0>Š<EFBFBD><C5A0><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ܠàƠ<C3A0><C6A0><EFBFBD><EFBFBD>ϠΠ̠<CEA0><CCA0><EFBFBD>", getreg(':'))
" letter characters without spaces
call feedkeys(":\"\<C-_>aAbcCdDefgGhijJklmnNopqrsStuvVwxXyzZ;\\,[]\<CR>", 'tx')
call assert_equal("\"\x88\x87<38><37><EFBFBD><EFBFBD><EFBFBD>\x93<39><33>\x8d<38><64>\x90\x95<39>\x8b\x96\x8e\x89\x8a<38><61>\x84\x9b\x9c\x80\x85\x9d<39><64><EFBFBD>\x83\x86<38>\x9f<39><66><EFBFBD><EFBFBD>\x8c", getreg(':'))
" other characters with spaces
call feedkeys(":\"\<C-_>0 1 2 3 4 5 6 7 8 9 ` . ! \" $ % ^ & / () = \\ ? + - _ * : # ~ @ < > { } | B E F H I K L M O P Q R T U W Y\<CR>", 'tx')
call assert_equal("\"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>]<5D>[<5B> <EFBFBD><C2A0><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>}<7D>{<7B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>~<7E><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><E9A0AD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EBA0BD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", getreg(':'))
" other characters without spaces
call feedkeys(":\"\<C-_>0123456789`.!\"$%^&/()=\\?+-_*:#~@<>{}|BEFHIKLMOPQRTUWY\<CR>", 'tx')
call assert_equal("\"<22><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>][<5B><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>}{<7B><><EFBFBD>~<7E><><EFBFBD><EFBFBD><EFBFBD><EBBDA9><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>", getreg(':'))
set noallowrevins noaltkeymap
endfunc

View File

@@ -1,5 +1,78 @@
" Tests for various functions.
func Test_empty()
call assert_equal(1, empty(''))
call assert_equal(0, empty('a'))
call assert_equal(1, empty(0))
call assert_equal(1, empty(-0))
call assert_equal(0, empty(1))
call assert_equal(0, empty(-1))
call assert_equal(1, empty(0.0))
call assert_equal(1, empty(-0.0))
call assert_equal(0, empty(1.0))
call assert_equal(0, empty(-1.0))
call assert_equal(0, empty(1.0/0.0))
call assert_equal(0, empty(0.0/0.0))
call assert_equal(1, empty([]))
call assert_equal(0, empty(['a']))
call assert_equal(1, empty({}))
call assert_equal(0, empty({'a':1}))
call assert_equal(1, empty(v:null))
call assert_equal(1, empty(v:none))
call assert_equal(1, empty(v:false))
call assert_equal(0, empty(v:true))
call assert_equal(0, empty(function('Test_empty')))
endfunc
func Test_len()
call assert_equal(1, len(0))
call assert_equal(2, len(12))
call assert_equal(0, len(''))
call assert_equal(2, len('ab'))
call assert_equal(0, len([]))
call assert_equal(2, len([2, 1]))
call assert_equal(0, len({}))
call assert_equal(2, len({'a': 1, 'b': 2}))
call assert_fails('call len(v:none)', 'E701:')
call assert_fails('call len({-> 0})', 'E701:')
endfunc
func Test_max()
call assert_equal(0, max([]))
call assert_equal(2, max([2]))
call assert_equal(2, max([1, 2]))
call assert_equal(2, max([1, 2, v:null]))
call assert_equal(0, max({}))
call assert_equal(2, max({'a':1, 'b':2}))
call assert_fails('call max(1)', 'E712:')
call assert_fails('call max(v:none)', 'E712:')
endfunc
func Test_min()
call assert_equal(0, min([]))
call assert_equal(2, min([2]))
call assert_equal(1, min([1, 2]))
call assert_equal(0, min([1, 2, v:null]))
call assert_equal(0, min({}))
call assert_equal(1, min({'a':1, 'b':2}))
call assert_fails('call min(1)', 'E712:')
call assert_fails('call min(v:none)', 'E712:')
endfunc
func Test_str2nr()
call assert_equal(0, str2nr(''))
call assert_equal(1, str2nr('1'))
@@ -15,6 +88,77 @@ func Test_str2nr()
call assert_equal(123456789, str2nr('123456789'))
call assert_equal(-123456789, str2nr('-123456789'))
call assert_equal(5, str2nr('101', 2))
call assert_equal(5, str2nr('0b101', 2))
call assert_equal(5, str2nr('0B101', 2))
call assert_equal(-5, str2nr('-101', 2))
call assert_equal(-5, str2nr('-0b101', 2))
call assert_equal(-5, str2nr('-0B101', 2))
call assert_equal(65, str2nr('101', 8))
call assert_equal(65, str2nr('0101', 8))
call assert_equal(-65, str2nr('-101', 8))
call assert_equal(-65, str2nr('-0101', 8))
call assert_equal(11259375, str2nr('abcdef', 16))
call assert_equal(11259375, str2nr('ABCDEF', 16))
call assert_equal(-11259375, str2nr('-ABCDEF', 16))
call assert_equal(11259375, str2nr('0xabcdef', 16))
call assert_equal(11259375, str2nr('0Xabcdef', 16))
call assert_equal(11259375, str2nr('0XABCDEF', 16))
call assert_equal(-11259375, str2nr('-0xABCDEF', 16))
call assert_equal(0, str2nr('0x10'))
call assert_equal(0, str2nr('0b10'))
call assert_equal(1, str2nr('12', 2))
call assert_equal(1, str2nr('18', 8))
call assert_equal(1, str2nr('1g', 16))
call assert_equal(0, str2nr(v:null))
call assert_equal(0, str2nr(v:none))
call assert_fails('call str2nr([])', 'E730:')
call assert_fails('call str2nr({->2})', 'E729:')
call assert_fails('call str2nr(1.2)', 'E806:')
call assert_fails('call str2nr(10, [])', 'E474:')
endfunc
func Test_strftime()
if !exists('*strftime')
return
endif
" Format of strftime() depends on system. We assume
" that basic formats tested here are available and
" identical on all systems which support strftime().
"
" The 2nd parameter of strftime() is a local time, so the output day
" of strftime() can be 17 or 18, depending on timezone.
call assert_match('^2017-01-1[78]$', strftime('%Y-%m-%d', 1484695512))
"
call assert_match('^\d\d\d\d-\(0\d\|1[012]\)-\([012]\d\|3[01]\) \([01]\d\|2[0-3]\):[0-5]\d:\([0-5]\d\|60\)$', strftime('%Y-%m-%d %H:%M:%S'))
call assert_fails('call strftime([])', 'E730:')
call assert_fails('call strftime("%Y", [])', 'E745:')
endfunc
func Test_simplify()
call assert_equal('', simplify(''))
call assert_equal('/', simplify('/'))
call assert_equal('/', simplify('/.'))
call assert_equal('/', simplify('/..'))
call assert_equal('/...', simplify('/...'))
call assert_equal('./dir/file', simplify('./dir/file'))
call assert_equal('./dir/file', simplify('.///dir//file'))
call assert_equal('./dir/file', simplify('./dir/./file'))
call assert_equal('./file', simplify('./dir/../file'))
call assert_equal('../dir/file', simplify('dir/../../dir/file'))
call assert_equal('./file', simplify('dir/.././file'))
call assert_fails('call simplify({->0})', 'E729:')
call assert_fails('call simplify([])', 'E730:')
call assert_fails('call simplify({})', 'E731:')
call assert_fails('call simplify(1.2)', 'E806:')
endfunc
func Test_tolower()
@@ -157,7 +301,7 @@ func Test_toupper()
call assert_equal("YÝŶŸẎỲỶỸ", toupper("YÝŶŸẎỲỶỸ"))
call assert_equal("ZŹŻŽƵẐẔ", toupper("ZŹŻŽƵẐẔ"))
call assert_equal("ⱥ ⱦ", tolower("Ⱥ Ⱦ"))
call assert_equal("Ⱥ Ⱦ", toupper("ⱥ ⱦ"))
endfunc

View File

@@ -764,6 +764,12 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
263,
/**/
262,
/**/
261,
/**/
260,
/**/