Merge remote-tracking branch 'vim/master'

This commit is contained in:
Kazuki Sakamoto
2017-03-01 07:54:32 -08:00
15 changed files with 702 additions and 416 deletions
+10
View File
@@ -2358,6 +2358,7 @@ test_alloc_fail({id}, {countdown}, {repeat})
test_autochdir() none enable 'autochdir' during startup
test_disable_char_avail({expr}) none test without typeahead
test_garbagecollect_now() none free memory right now for testing
test_ignore_error({expr}) none ignore a specific error
test_null_channel() Channel null value for testing
test_null_dict() Dict null value for testing
test_null_job() Job null value for testing
@@ -7784,6 +7785,15 @@ test_garbagecollect_now() *test_garbagecollect_now()*
internally, and |v:testing| must have been set before calling
any function.
test_ignore_error({expr}) *test_ignore_error()*
Ignore any error containing {expr}. A normal message is given
instead.
This is only meant to be used in tests, where catching the
error with try/catch cannot be used (because it skips over
following code).
{expr} is used literally, not as a pattern.
There is currently no way to revert this.
test_null_channel() *test_null_channel()*
Return a Channel that is null. Only useful for testing.
{only available when compiled with the +channel feature}
+114 -334
View File
@@ -200,126 +200,48 @@ A_is_f(int cur_c)
static int
chg_c_a2s(int cur_c)
{
int tempc;
switch (cur_c)
{
case a_HAMZA:
tempc = a_s_HAMZA;
break;
case a_ALEF_MADDA:
tempc = a_s_ALEF_MADDA;
break;
case a_ALEF_HAMZA_ABOVE:
tempc = a_s_ALEF_HAMZA_ABOVE;
break;
case a_WAW_HAMZA:
tempc = a_s_WAW_HAMZA;
break;
case a_ALEF_HAMZA_BELOW:
tempc = a_s_ALEF_HAMZA_BELOW;
break;
case a_YEH_HAMZA:
tempc = a_s_YEH_HAMZA;
break;
case a_ALEF:
tempc = a_s_ALEF;
break;
case a_TEH_MARBUTA:
tempc = a_s_TEH_MARBUTA;
break;
case a_DAL:
tempc = a_s_DAL;
break;
case a_THAL:
tempc = a_s_THAL;
break;
case a_REH:
tempc = a_s_REH;
break;
case a_ZAIN:
tempc = a_s_ZAIN;
break;
case a_TATWEEL: /* exceptions */
tempc = cur_c;
break;
case a_WAW:
tempc = a_s_WAW;
break;
case a_ALEF_MAKSURA:
tempc = a_s_ALEF_MAKSURA;
break;
case a_BEH:
tempc = a_s_BEH;
break;
case a_TEH:
tempc = a_s_TEH;
break;
case a_THEH:
tempc = a_s_THEH;
break;
case a_JEEM:
tempc = a_s_JEEM;
break;
case a_HAH:
tempc = a_s_HAH;
break;
case a_KHAH:
tempc = a_s_KHAH;
break;
case a_SEEN:
tempc = a_s_SEEN;
break;
case a_SHEEN:
tempc = a_s_SHEEN;
break;
case a_SAD:
tempc = a_s_SAD;
break;
case a_DAD:
tempc = a_s_DAD;
break;
case a_TAH:
tempc = a_s_TAH;
break;
case a_ZAH:
tempc = a_s_ZAH;
break;
case a_AIN:
tempc = a_s_AIN;
break;
case a_GHAIN:
tempc = a_s_GHAIN;
break;
case a_FEH:
tempc = a_s_FEH;
break;
case a_QAF:
tempc = a_s_QAF;
break;
case a_KAF:
tempc = a_s_KAF;
break;
case a_LAM:
tempc = a_s_LAM;
break;
case a_MEEM:
tempc = a_s_MEEM;
break;
case a_NOON:
tempc = a_s_NOON;
break;
case a_HEH:
tempc = a_s_HEH;
break;
case a_YEH:
tempc = a_s_YEH;
break;
default:
tempc = 0;
case a_HAMZA: return a_s_HAMZA;
case a_ALEF_MADDA: return a_s_ALEF_MADDA;
case a_ALEF_HAMZA_ABOVE: return a_s_ALEF_HAMZA_ABOVE;
case a_WAW_HAMZA: return a_s_WAW_HAMZA;
case a_ALEF_HAMZA_BELOW: return a_s_ALEF_HAMZA_BELOW;
case a_YEH_HAMZA: return a_s_YEH_HAMZA;
case a_ALEF: return a_s_ALEF;
case a_TEH_MARBUTA: return a_s_TEH_MARBUTA;
case a_DAL: return a_s_DAL;
case a_THAL: return a_s_THAL;
case a_REH: return a_s_REH;
case a_ZAIN: return a_s_ZAIN;
case a_TATWEEL: return cur_c; /* exceptions */
case a_WAW: return a_s_WAW;
case a_ALEF_MAKSURA: return a_s_ALEF_MAKSURA;
case a_BEH: return a_s_BEH;
case a_TEH: return a_s_TEH;
case a_THEH: return a_s_THEH;
case a_JEEM: return a_s_JEEM;
case a_HAH: return a_s_HAH;
case a_KHAH: return a_s_KHAH;
case a_SEEN: return a_s_SEEN;
case a_SHEEN: return a_s_SHEEN;
case a_SAD: return a_s_SAD;
case a_DAD: return a_s_DAD;
case a_TAH: return a_s_TAH;
case a_ZAH: return a_s_ZAH;
case a_AIN: return a_s_AIN;
case a_GHAIN: return a_s_GHAIN;
case a_FEH: return a_s_FEH;
case a_QAF: return a_s_QAF;
case a_KAF: return a_s_KAF;
case a_LAM: return a_s_LAM;
case a_MEEM: return a_s_MEEM;
case a_NOON: return a_s_NOON;
case a_HEH: return a_s_HEH;
case a_YEH: return a_s_YEH;
}
return tempc;
return 0;
}
@@ -329,126 +251,62 @@ chg_c_a2s(int cur_c)
static int
chg_c_a2i(int cur_c)
{
int tempc;
switch (cur_c)
{
case a_YEH_HAMZA:
tempc = a_i_YEH_HAMZA;
break;
case a_YEH_HAMZA: return a_i_YEH_HAMZA;
case a_HAMZA: /* exceptions */
tempc = a_s_HAMZA;
break;
return a_s_HAMZA;
case a_ALEF_MADDA: /* exceptions */
tempc = a_s_ALEF_MADDA;
break;
return a_s_ALEF_MADDA;
case a_ALEF_HAMZA_ABOVE: /* exceptions */
tempc = a_s_ALEF_HAMZA_ABOVE;
break;
return a_s_ALEF_HAMZA_ABOVE;
case a_WAW_HAMZA: /* exceptions */
tempc = a_s_WAW_HAMZA;
break;
return a_s_WAW_HAMZA;
case a_ALEF_HAMZA_BELOW: /* exceptions */
tempc = a_s_ALEF_HAMZA_BELOW;
break;
return a_s_ALEF_HAMZA_BELOW;
case a_ALEF: /* exceptions */
tempc = a_s_ALEF;
break;
return a_s_ALEF;
case a_TEH_MARBUTA: /* exceptions */
tempc = a_s_TEH_MARBUTA;
break;
return a_s_TEH_MARBUTA;
case a_DAL: /* exceptions */
tempc = a_s_DAL;
break;
return a_s_DAL;
case a_THAL: /* exceptions */
tempc = a_s_THAL;
break;
return a_s_THAL;
case a_REH: /* exceptions */
tempc = a_s_REH;
break;
return a_s_REH;
case a_ZAIN: /* exceptions */
tempc = a_s_ZAIN;
break;
return a_s_ZAIN;
case a_TATWEEL: /* exceptions */
tempc = cur_c;
break;
return cur_c;
case a_WAW: /* exceptions */
tempc = a_s_WAW;
break;
return a_s_WAW;
case a_ALEF_MAKSURA: /* exceptions */
tempc = a_s_ALEF_MAKSURA;
break;
case a_BEH:
tempc = a_i_BEH;
break;
case a_TEH:
tempc = a_i_TEH;
break;
case a_THEH:
tempc = a_i_THEH;
break;
case a_JEEM:
tempc = a_i_JEEM;
break;
case a_HAH:
tempc = a_i_HAH;
break;
case a_KHAH:
tempc = a_i_KHAH;
break;
case a_SEEN:
tempc = a_i_SEEN;
break;
case a_SHEEN:
tempc = a_i_SHEEN;
break;
case a_SAD:
tempc = a_i_SAD;
break;
case a_DAD:
tempc = a_i_DAD;
break;
case a_TAH:
tempc = a_i_TAH;
break;
case a_ZAH:
tempc = a_i_ZAH;
break;
case a_AIN:
tempc = a_i_AIN;
break;
case a_GHAIN:
tempc = a_i_GHAIN;
break;
case a_FEH:
tempc = a_i_FEH;
break;
case a_QAF:
tempc = a_i_QAF;
break;
case a_KAF:
tempc = a_i_KAF;
break;
case a_LAM:
tempc = a_i_LAM;
break;
case a_MEEM:
tempc = a_i_MEEM;
break;
case a_NOON:
tempc = a_i_NOON;
break;
case a_HEH:
tempc = a_i_HEH;
break;
case a_YEH:
tempc = a_i_YEH;
break;
default:
tempc = 0;
return a_s_ALEF_MAKSURA;
case a_BEH: return a_i_BEH;
case a_TEH: return a_i_TEH;
case a_THEH: return a_i_THEH;
case a_JEEM: return a_i_JEEM;
case a_HAH: return a_i_HAH;
case a_KHAH: return a_i_KHAH;
case a_SEEN: return a_i_SEEN;
case a_SHEEN: return a_i_SHEEN;
case a_SAD: return a_i_SAD;
case a_DAD: return a_i_DAD;
case a_TAH: return a_i_TAH;
case a_ZAH: return a_i_ZAH;
case a_AIN: return a_i_AIN;
case a_GHAIN: return a_i_GHAIN;
case a_FEH: return a_i_FEH;
case a_QAF: return a_i_QAF;
case a_KAF: return a_i_KAF;
case a_LAM: return a_i_LAM;
case a_MEEM: return a_i_MEEM;
case a_NOON: return a_i_NOON;
case a_HEH: return a_i_HEH;
case a_YEH: return a_i_YEH;
}
return tempc;
return 0;
}
@@ -458,126 +316,48 @@ chg_c_a2i(int cur_c)
static int
chg_c_a2m(int cur_c)
{
int tempc;
switch (cur_c)
{
case a_HAMZA: /* exception */
tempc = a_s_HAMZA;
break;
case a_ALEF_MADDA: /* exception */
tempc = a_f_ALEF_MADDA;
break;
case a_ALEF_HAMZA_ABOVE: /* exception */
tempc = a_f_ALEF_HAMZA_ABOVE;
break;
case a_WAW_HAMZA: /* exception */
tempc = a_f_WAW_HAMZA;
break;
case a_ALEF_HAMZA_BELOW: /* exception */
tempc = a_f_ALEF_HAMZA_BELOW;
break;
case a_YEH_HAMZA:
tempc = a_m_YEH_HAMZA;
break;
case a_ALEF: /* exception */
tempc = a_f_ALEF;
break;
case a_BEH:
tempc = a_m_BEH;
break;
case a_TEH_MARBUTA: /* exception */
tempc = a_f_TEH_MARBUTA;
break;
case a_TEH:
tempc = a_m_TEH;
break;
case a_THEH:
tempc = a_m_THEH;
break;
case a_JEEM:
tempc = a_m_JEEM;
break;
case a_HAH:
tempc = a_m_HAH;
break;
case a_KHAH:
tempc = a_m_KHAH;
break;
case a_DAL: /* exception */
tempc = a_f_DAL;
break;
case a_THAL: /* exception */
tempc = a_f_THAL;
break;
case a_REH: /* exception */
tempc = a_f_REH;
break;
case a_ZAIN: /* exception */
tempc = a_f_ZAIN;
break;
case a_SEEN:
tempc = a_m_SEEN;
break;
case a_SHEEN:
tempc = a_m_SHEEN;
break;
case a_SAD:
tempc = a_m_SAD;
break;
case a_DAD:
tempc = a_m_DAD;
break;
case a_TAH:
tempc = a_m_TAH;
break;
case a_ZAH:
tempc = a_m_ZAH;
break;
case a_AIN:
tempc = a_m_AIN;
break;
case a_GHAIN:
tempc = a_m_GHAIN;
break;
case a_TATWEEL: /* exception */
tempc = cur_c;
break;
case a_FEH:
tempc = a_m_FEH;
break;
case a_QAF:
tempc = a_m_QAF;
break;
case a_KAF:
tempc = a_m_KAF;
break;
case a_LAM:
tempc = a_m_LAM;
break;
case a_MEEM:
tempc = a_m_MEEM;
break;
case a_NOON:
tempc = a_m_NOON;
break;
case a_HEH:
tempc = a_m_HEH;
break;
case a_WAW: /* exception */
tempc = a_f_WAW;
break;
case a_ALEF_MAKSURA: /* exception */
tempc = a_f_ALEF_MAKSURA;
break;
case a_YEH:
tempc = a_m_YEH;
break;
default:
tempc = 0;
case a_HAMZA: return a_s_HAMZA; /* exception */
case a_ALEF_MADDA: return a_f_ALEF_MADDA; /* exception */
case a_ALEF_HAMZA_ABOVE: return a_f_ALEF_HAMZA_ABOVE; /* exception */
case a_WAW_HAMZA: return a_f_WAW_HAMZA; /* exception */
case a_ALEF_HAMZA_BELOW: return a_f_ALEF_HAMZA_BELOW; /* exception */
case a_YEH_HAMZA: return a_m_YEH_HAMZA;
case a_ALEF: return a_f_ALEF; /* exception */
case a_BEH: return a_m_BEH;
case a_TEH_MARBUTA: return a_f_TEH_MARBUTA; /* exception */
case a_TEH: return a_m_TEH;
case a_THEH: return a_m_THEH;
case a_JEEM: return a_m_JEEM;
case a_HAH: return a_m_HAH;
case a_KHAH: return a_m_KHAH;
case a_DAL: return a_f_DAL; /* exception */
case a_THAL: return a_f_THAL; /* exception */
case a_REH: return a_f_REH; /* exception */
case a_ZAIN: return a_f_ZAIN; /* exception */
case a_SEEN: return a_m_SEEN;
case a_SHEEN: return a_m_SHEEN;
case a_SAD: return a_m_SAD;
case a_DAD: return a_m_DAD;
case a_TAH: return a_m_TAH;
case a_ZAH: return a_m_ZAH;
case a_AIN: return a_m_AIN;
case a_GHAIN: return a_m_GHAIN;
case a_TATWEEL: return cur_c; /* exception */
case a_FEH: return a_m_FEH;
case a_QAF: return a_m_QAF;
case a_KAF: return a_m_KAF;
case a_LAM: return a_m_LAM;
case a_MEEM: return a_m_MEEM;
case a_NOON: return a_m_NOON;
case a_HEH: return a_m_HEH;
case a_WAW: return a_f_WAW; /* exception */
case a_ALEF_MAKSURA: return a_f_ALEF_MAKSURA; /* exception */
case a_YEH: return a_m_YEH;
}
return tempc;
return 0;
}
+2 -1
View File
@@ -1987,7 +1987,7 @@ channel_parse_json(channel_T *channel, ch_part_T part)
* more (but still incomplete): set a deadline of 100 msec. */
ch_logn(channel,
"Incomplete message (%d bytes) - wait 100 msec for more",
buflen);
(int)buflen);
reader.js_used = 0;
chanpart->ch_wait_len = buflen;
#ifdef WIN32
@@ -3324,6 +3324,7 @@ channel_read_block(channel_T *channel, ch_part_T part, int timeout)
channel_read(channel, part, "channel_read_block");
}
/* We have a complete message now. */
if (mode == MODE_RAW)
{
msg = channel_get_all(channel, part);
+19 -16
View File
@@ -186,7 +186,7 @@ static int ins_compl_pum_key(int c);
static int ins_compl_key2count(int c);
static int ins_compl_use_match(int c);
static int ins_complete(int c, int enable_pum);
static void show_pum(int save_w_wrow);
static void show_pum(int prev_w_wrow, int prev_w_leftcol);
static unsigned quote_meta(char_u *dest, char_u *str, int len);
#endif /* FEAT_INS_EXPAND */
@@ -2827,6 +2827,7 @@ completeopt_was_set(void)
set_completion(colnr_T startcol, list_T *list)
{
int save_w_wrow = curwin->w_wrow;
int save_w_leftcol = curwin->w_leftcol;
/* If already doing completions stop it. */
if (ctrl_x_mode != 0)
@@ -2867,7 +2868,7 @@ set_completion(colnr_T startcol, list_T *list)
/* Lazily show the popup menu, unless we got interrupted. */
if (!compl_interrupted)
show_pum(save_w_wrow);
show_pum(save_w_wrow, save_w_leftcol);
out_flush();
}
@@ -5110,6 +5111,7 @@ ins_complete(int c, int enable_pum)
colnr_T curs_col; /* cursor column */
int n;
int save_w_wrow;
int save_w_leftcol;
int insert_match;
int save_did_ai = did_ai;
@@ -5553,6 +5555,7 @@ ins_complete(int c, int enable_pum)
* Find next match (and following matches).
*/
save_w_wrow = curwin->w_wrow;
save_w_leftcol = curwin->w_leftcol;
n = ins_compl_next(TRUE, ins_compl_key2count(c), insert_match, FALSE);
/* may undisplay the popup menu */
@@ -5705,9 +5708,8 @@ ins_complete(int c, int enable_pum)
/* Show the popup menu, unless we got interrupted. */
if (enable_pum && !compl_interrupted)
{
show_pum(save_w_wrow);
}
show_pum(save_w_wrow, save_w_leftcol);
compl_was_interrupted = compl_interrupted;
compl_interrupted = FALSE;
@@ -5715,21 +5717,22 @@ ins_complete(int c, int enable_pum)
}
static void
show_pum(int save_w_wrow)
show_pum(int prev_w_wrow, int prev_w_leftcol)
{
/* RedrawingDisabled may be set when invoked through complete(). */
int n = RedrawingDisabled;
/* RedrawingDisabled may be set when invoked through complete(). */
int n = RedrawingDisabled;
RedrawingDisabled = 0;
RedrawingDisabled = 0;
/* If the cursor moved we need to remove the pum first. */
setcursor();
if (save_w_wrow != curwin->w_wrow)
ins_compl_del_pum();
/* If the cursor moved or the display scrolled we need to remove the pum
* first. */
setcursor();
if (prev_w_wrow != curwin->w_wrow || prev_w_leftcol != curwin->w_leftcol)
ins_compl_del_pum();
ins_compl_show_pum();
setcursor();
RedrawingDisabled = n;
ins_compl_show_pum();
setcursor();
RedrawingDisabled = n;
}
/*
+11
View File
@@ -389,6 +389,7 @@ static void f_test_alloc_fail(typval_T *argvars, typval_T *rettv);
static void f_test_autochdir(typval_T *argvars, typval_T *rettv);
static void f_test_disable_char_avail(typval_T *argvars, typval_T *rettv);
static void f_test_garbagecollect_now(typval_T *argvars, typval_T *rettv);
static void f_test_ignore_error(typval_T *argvars, typval_T *rettv);
#ifdef FEAT_JOB_CHANNEL
static void f_test_null_channel(typval_T *argvars, typval_T *rettv);
#endif
@@ -823,6 +824,7 @@ static struct fst
{"test_autochdir", 0, 0, f_test_autochdir},
{"test_disable_char_avail", 1, 1, f_test_disable_char_avail},
{"test_garbagecollect_now", 0, 0, f_test_garbagecollect_now},
{"test_ignore_error", 1, 1, f_test_ignore_error},
#ifdef FEAT_JOB_CHANNEL
{"test_null_channel", 0, 0, f_test_null_channel},
#endif
@@ -12352,6 +12354,15 @@ f_test_garbagecollect_now(typval_T *argvars UNUSED, typval_T *rettv UNUSED)
garbage_collect(TRUE);
}
/*
* "test_ignore_error()" function
*/
static void
f_test_ignore_error(typval_T *argvars, typval_T *rettv UNUSED)
{
ignore_error_for_testing(get_tv_string(&argvars[0]));
}
#ifdef FEAT_JOB_CHANNEL
static void
f_test_null_channel(typval_T *argvars UNUSED, typval_T *rettv)
+10 -3
View File
@@ -1576,16 +1576,23 @@ foldMarkAdjustRecurse(
{
/* 5. fold is below line1 and contains line2; need to
* correct nested folds too */
foldMarkAdjustRecurse(&fp->fd_nested, line1 - fp->fd_top,
line2 - fp->fd_top, amount,
amount_after + (fp->fd_top - top));
if (amount == MAXLNUM)
{
foldMarkAdjustRecurse(&fp->fd_nested,
line1 - fp->fd_top,
line2 - fp->fd_top,
amount,
amount_after + (fp->fd_top - top));
fp->fd_len -= line2 - fp->fd_top + 1;
fp->fd_top = line1;
}
else
{
foldMarkAdjustRecurse(&fp->fd_nested,
line1 - fp->fd_top,
line2 - fp->fd_top,
amount,
amount_after - amount);
fp->fd_len += amount_after - amount;
fp->fd_top += amount;
}
+2 -2
View File
@@ -1863,7 +1863,7 @@ recover_names(
else
{
#if defined(UNIX) || defined(WIN3264)
int len = STRLEN(dir_name);
int len = (int)STRLEN(dir_name);
p = dir_name + len;
if (after_pathsep(dir_name, p) && len > 1 && p[-1] == p[-2])
@@ -3924,7 +3924,7 @@ makeswapname(
#endif
#if defined(UNIX) || defined(WIN3264) /* Need _very_ long file names */
int len = STRLEN(dir_name);
int len = (int)STRLEN(dir_name);
s = dir_name + len;
if (after_pathsep(dir_name, s) && len > 1 && s[-1] == s[-2])
+31
View File
@@ -539,6 +539,31 @@ emsg_not_now(void)
return FALSE;
}
#ifdef FEAT_EVAL
static garray_T ignore_error_list = GA_EMPTY;
void
ignore_error_for_testing(char_u *error)
{
if (ignore_error_list.ga_itemsize == 0)
ga_init2(&ignore_error_list, sizeof(char_u *), 1);
ga_add_string(&ignore_error_list, error);
}
static int
ignore_error(char_u *msg)
{
int i;
for (i = 0; i < ignore_error_list.ga_len; ++i)
if (strstr((char *)msg,
(char *)((char_u **)(ignore_error_list.ga_data))[i]) != NULL)
return TRUE;
return FALSE;
}
#endif
#if !defined(HAVE_STRERROR) || defined(PROTO)
/*
* Replacement for perror() that behaves more or less like emsg() was called.
@@ -577,6 +602,12 @@ emsg(char_u *s)
if (emsg_not_now())
return TRUE;
#ifdef FEAT_EVAL
/* When testing some errors are turned into a normal message. */
if (ignore_error(s))
return msg(s);
#endif
called_emsg = TRUE;
/*
+1
View File
@@ -8,6 +8,7 @@ void trunc_string(char_u *s, char_u *buf, int room_in, int buflen);
void reset_last_sourcing(void);
void msg_source(int attr);
int emsg_not_now(void);
void ignore_error_for_testing(char_u *error);
void do_perror(char *msg);
int emsg(char_u *s);
int emsg2(char_u *s, char_u *a1);
+32 -28
View File
@@ -35,9 +35,10 @@ typedef struct tag_pointers
} tagptrs_T;
/*
* The matching tags are first stored in one of the ht_match[] hash tables. In
* The matching tags are first stored in one of the hash tables. In
* which one depends on the priority of the match.
* At the end, all the matches from ht_match[] are concatenated, to make a list
* ht_match[] is used to find duplicates, ga_match[] to keep them in sequence.
* At the end, all the matches from ga_match[] are concatenated, to make a list
* sorted on priority.
*/
#define MT_ST_CUR 0 /* static match in current file */
@@ -1339,7 +1340,8 @@ find_tags(
#endif
char_u *mfp;
hashtab_T ht_match[MT_COUNT];
garray_T ga_match[MT_COUNT]; /* stores matches in sequence */
hashtab_T ht_match[MT_COUNT]; /* stores matches by key */
hash_T hash = 0;
int match_count = 0; /* number of matches found */
char_u **matches;
@@ -1405,7 +1407,10 @@ find_tags(
ebuf = alloc(LSIZE);
#endif
for (mtt = 0; mtt < MT_COUNT; ++mtt)
{
ga_init2(&ga_match[mtt], (int)sizeof(char_u *), 100);
hash_init(&ht_match[mtt]);
}
/* check for out of memory situation */
if (lbuf == NULL || tag_fname == NULL
@@ -2213,7 +2218,7 @@ parse_line:
}
/*
* If a match is found, add it to ht_match[].
* If a match is found, add it to ht_match[] and ga_match[].
*/
if (match)
{
@@ -2271,7 +2276,7 @@ parse_line:
}
/*
* Add the found match in ht_match[mtt].
* Add the found match in ht_match[mtt] and ga_match[mtt].
* Store the info we need later, which depends on the kind of
* tags we are dealing with.
*/
@@ -2423,7 +2428,8 @@ parse_line:
if (HASHITEM_EMPTY(hi))
{
if (hash_add_item(&ht_match[mtt], hi, mfp, hash)
== FAIL)
== FAIL
|| ga_grow(&ga_match[mtt], 1) != OK)
{
/* Out of memory! Just forget about the rest. */
retval = OK;
@@ -2431,7 +2437,11 @@ parse_line:
break;
}
else
{
((char_u **)(ga_match[mtt].ga_data))
[ga_match[mtt].ga_len++] = mfp;
++match_count;
}
}
else
/* duplicate tag, drop it */
@@ -2533,7 +2543,7 @@ findtag_end:
#endif
/*
* Move the matches from the ht_match[] arrays into one list of
* Move the matches from the ga_match[] arrays into one list of
* matches. When retval == FAIL, free the matches.
*/
if (retval == FAIL)
@@ -2547,34 +2557,28 @@ findtag_end:
match_count = 0;
for (mtt = 0; mtt < MT_COUNT; ++mtt)
{
hashitem_T *hi;
long_u todo;
todo = (long)ht_match[mtt].ht_used;
for (hi = ht_match[mtt].ht_array; todo > 0; ++hi)
for (i = 0; i < ga_match[mtt].ga_len; ++i)
{
if (!HASHITEM_EMPTY(hi))
mfp = ((char_u **)(ga_match[mtt].ga_data))[i];
if (matches == NULL)
vim_free(mfp);
else
{
mfp = hi->hi_key;
if (matches == NULL)
vim_free(mfp);
else
if (!name_only)
{
if (!name_only)
{
/* Change mtt back to zero-based. */
*mfp = *mfp - 1;
/* Change mtt back to zero-based. */
*mfp = *mfp - 1;
/* change the TAG_SEP back to NUL */
for (p = mfp + 1; *p != NUL; ++p)
if (*p == TAG_SEP)
*p = NUL;
}
matches[match_count++] = (char_u *)mfp;
/* change the TAG_SEP back to NUL */
for (p = mfp + 1; *p != NUL; ++p)
if (*p == TAG_SEP)
*p = NUL;
}
todo--;
matches[match_count++] = (char_u *)mfp;
}
}
ga_clear(&ga_match[mtt]);
hash_clear(&ht_match[mtt]);
}
+404 -24
View File
@@ -1,21 +1,23 @@
" Simplistic testing of Arabic mode.
if !has('arabic')
if !has('arabic') || !has('multi_byte')
finish
endif
set encoding=utf-8
scriptencoding utf-8
source view_util.vim
" Return list of utf8 sequences of each character at line lnum.
" Return list of Unicode characters at line lnum.
" Combining characters are treated as a single item.
func GetCharsUtf8(lnum)
func s:get_chars(lnum)
call cursor(a:lnum, 1)
let chars = []
let numchars = strchars(getline('.'), 1)
for i in range(1, numchars)
exe 'norm ' i . '|'
call add(chars, execute('norm g8'))
let c=execute('ascii')
let c=substitute(c, '\n\?<.\{-}Hex\s*', 'U+', 'g')
let c=substitute(c, ',\s*Octal\s*\d*', '', 'g')
call add(chars, c)
endfor
return chars
endfunc
@@ -43,25 +45,28 @@ func Test_arabic_input()
new
set arabic
" Typing sghl in Arabic insert mode should show the
" Arabic word 'Salaam' i.e. 'peace'.
call feedkeys('isghl', 'tx')
redraw
" Arabic word 'Salaam' i.e. 'peace', spelled:
" SEEN, LAM, ALEF, MEEM.
" See: https://www.mediawiki.org/wiki/VisualEditor/Typing/Right-to-left
call feedkeys('isghl!', 'tx')
call assert_match("^ *!\uFEE1\uFEFC\uFEB3$", ScreenLines(1, &columns)[0])
call assert_equal([
\ "\nd8 b3 ",
\ "\nd9 84 + d8 a7 ",
\ "\nd9 85 "], GetCharsUtf8(1))
\ 'U+0633',
\ 'U+0644 U+0627',
\ 'U+0645',
\ 'U+21'], s:get_chars(1))
" Without shaping, it should give individual Arabic letters.
set noarabicshape
redraw
call assert_match("^ *!\u0645\u0627\u0644\u0633$", ScreenLines(1, &columns)[0])
call assert_equal([
\ "\nd8 b3 ",
\ "\nd9 84 ",
\ "\nd8 a7 ",
\ "\nd9 85 "], GetCharsUtf8(1))
\ 'U+0633',
\ 'U+0644',
\ 'U+0627',
\ 'U+0645',
\ 'U+21'], s:get_chars(1))
set arabicshape&
set arabic&
set arabic& arabicshape&
bwipe!
endfunc
@@ -69,7 +74,7 @@ func Test_arabic_toggle_keymap()
new
set arabic
call feedkeys("i12\<C-^>12\<C-^>12", 'tx')
redraw
call assert_match("^ *٢١21٢١$", ScreenLines(1, &columns)[0])
call assert_equal('١٢12١٢', getline('.'))
set arabic&
bwipe!
@@ -79,14 +84,389 @@ func Test_delcombine()
new
set arabic
call feedkeys("isghl\<BS>\<BS>", 'tx')
redraw
call assert_equal(["\nd8 b3 ", "\nd9 84 "], GetCharsUtf8(1))
call assert_match("^ *\uFEDE\uFEB3$", ScreenLines(1, &columns)[0])
call assert_equal(['U+0633', 'U+0644'], s:get_chars(1))
" Now the same with nodelcombine
" Now the same with 'nodelcombine'
set nodelcombine
%d
call feedkeys("isghl\<BS>\<BS>", 'tx')
call assert_equal(["\nd8 b3 "], GetCharsUtf8(1))
call assert_match("^ *\uFEB1$", ScreenLines(1, &columns)[0])
call assert_equal(['U+0633'], s:get_chars(1))
set arabic&
bwipe!
endfunc
" Values from src/arabic.h (not all used yet)
let s:a_COMMA = "\u060C"
let s:a_SEMICOLON = "\u061B"
let s:a_QUESTION = "\u061F"
let s:a_HAMZA = "\u0621"
let s:a_ALEF_MADDA = "\u0622"
let s:a_ALEF_HAMZA_ABOVE = "\u0623"
let s:a_WAW_HAMZA = "\u0624"
let s:a_ALEF_HAMZA_BELOW = "\u0625"
let s:a_YEH_HAMZA = "\u0626"
let s:a_ALEF = "\u0627"
let s:a_BEH = "\u0628"
let s:a_TEH_MARBUTA = "\u0629"
let s:a_TEH = "\u062a"
let s:a_THEH = "\u062b"
let s:a_JEEM = "\u062c"
let s:a_HAH = "\u062d"
let s:a_KHAH = "\u062e"
let s:a_DAL = "\u062f"
let s:a_THAL = "\u0630"
let s:a_REH = "\u0631"
let s:a_ZAIN = "\u0632"
let s:a_SEEN = "\u0633"
let s:a_SHEEN = "\u0634"
let s:a_SAD = "\u0635"
let s:a_DAD = "\u0636"
let s:a_TAH = "\u0637"
let s:a_ZAH = "\u0638"
let s:a_AIN = "\u0639"
let s:a_GHAIN = "\u063a"
let s:a_TATWEEL = "\u0640"
let s:a_FEH = "\u0641"
let s:a_QAF = "\u0642"
let s:a_KAF = "\u0643"
let s:a_LAM = "\u0644"
let s:a_MEEM = "\u0645"
let s:a_NOON = "\u0646"
let s:a_HEH = "\u0647"
let s:a_WAW = "\u0648"
let s:a_ALEF_MAKSURA = "\u0649"
let s:a_YEH = "\u064a"
let s:a_FATHATAN = "\u064b"
let s:a_DAMMATAN = "\u064c"
let s:a_KASRATAN = "\u064d"
let s:a_FATHA = "\u064e"
let s:a_DAMMA = "\u064f"
let s:a_KASRA = "\u0650"
let s:a_SHADDA = "\u0651"
let s:a_SUKUN = "\u0652"
let s:a_MADDA_ABOVE = "\u0653"
let s:a_HAMZA_ABOVE = "\u0654"
let s:a_HAMZA_BELOW = "\u0655"
let s:a_ZERO = "\u0660"
let s:a_ONE = "\u0661"
let s:a_TWO = "\u0662"
let s:a_THREE = "\u0663"
let s:a_FOUR = "\u0664"
let s:a_FIVE = "\u0665"
let s:a_SIX = "\u0666"
let s:a_SEVEN = "\u0667"
let s:a_EIGHT = "\u0668"
let s:a_NINE = "\u0669"
let s:a_PERCENT = "\u066a"
let s:a_DECIMAL = "\u066b"
let s:a_THOUSANDS = "\u066c"
let s:a_STAR = "\u066d"
let s:a_MINI_ALEF = "\u0670"
let s:a_s_FATHATAN = "\ufe70"
let s:a_m_TATWEEL_FATHATAN = "\ufe71"
let s:a_s_DAMMATAN = "\ufe72"
let s:a_s_KASRATAN = "\ufe74"
let s:a_s_FATHA = "\ufe76"
let s:a_m_FATHA = "\ufe77"
let s:a_s_DAMMA = "\ufe78"
let s:a_m_DAMMA = "\ufe79"
let s:a_s_KASRA = "\ufe7a"
let s:a_m_KASRA = "\ufe7b"
let s:a_s_SHADDA = "\ufe7c"
let s:a_m_SHADDA = "\ufe7d"
let s:a_s_SUKUN = "\ufe7e"
let s:a_m_SUKUN = "\ufe7f"
let s:a_s_HAMZA = "\ufe80"
let s:a_s_ALEF_MADDA = "\ufe81"
let s:a_f_ALEF_MADDA = "\ufe82"
let s:a_s_ALEF_HAMZA_ABOVE = "\ufe83"
let s:a_f_ALEF_HAMZA_ABOVE = "\ufe84"
let s:a_s_WAW_HAMZA = "\ufe85"
let s:a_f_WAW_HAMZA = "\ufe86"
let s:a_s_ALEF_HAMZA_BELOW = "\ufe87"
let s:a_f_ALEF_HAMZA_BELOW = "\ufe88"
let s:a_s_YEH_HAMZA = "\ufe89"
let s:a_f_YEH_HAMZA = "\ufe8a"
let s:a_i_YEH_HAMZA = "\ufe8b"
let s:a_m_YEH_HAMZA = "\ufe8c"
let s:a_s_ALEF = "\ufe8d"
let s:a_f_ALEF = "\ufe8e"
let s:a_s_BEH = "\ufe8f"
let s:a_f_BEH = "\ufe90"
let s:a_i_BEH = "\ufe91"
let s:a_m_BEH = "\ufe92"
let s:a_s_TEH_MARBUTA = "\ufe93"
let s:a_f_TEH_MARBUTA = "\ufe94"
let s:a_s_TEH = "\ufe95"
let s:a_f_TEH = "\ufe96"
let s:a_i_TEH = "\ufe97"
let s:a_m_TEH = "\ufe98"
let s:a_s_THEH = "\ufe99"
let s:a_f_THEH = "\ufe9a"
let s:a_i_THEH = "\ufe9b"
let s:a_m_THEH = "\ufe9c"
let s:a_s_JEEM = "\ufe9d"
let s:a_f_JEEM = "\ufe9e"
let s:a_i_JEEM = "\ufe9f"
let s:a_m_JEEM = "\ufea0"
let s:a_s_HAH = "\ufea1"
let s:a_f_HAH = "\ufea2"
let s:a_i_HAH = "\ufea3"
let s:a_m_HAH = "\ufea4"
let s:a_s_KHAH = "\ufea5"
let s:a_f_KHAH = "\ufea6"
let s:a_i_KHAH = "\ufea7"
let s:a_m_KHAH = "\ufea8"
let s:a_s_DAL = "\ufea9"
let s:a_f_DAL = "\ufeaa"
let s:a_s_THAL = "\ufeab"
let s:a_f_THAL = "\ufeac"
let s:a_s_REH = "\ufead"
let s:a_f_REH = "\ufeae"
let s:a_s_ZAIN = "\ufeaf"
let s:a_f_ZAIN = "\ufeb0"
let s:a_s_SEEN = "\ufeb1"
let s:a_f_SEEN = "\ufeb2"
let s:a_i_SEEN = "\ufeb3"
let s:a_m_SEEN = "\ufeb4"
let s:a_s_SHEEN = "\ufeb5"
let s:a_f_SHEEN = "\ufeb6"
let s:a_i_SHEEN = "\ufeb7"
let s:a_m_SHEEN = "\ufeb8"
let s:a_s_SAD = "\ufeb9"
let s:a_f_SAD = "\ufeba"
let s:a_i_SAD = "\ufebb"
let s:a_m_SAD = "\ufebc"
let s:a_s_DAD = "\ufebd"
let s:a_f_DAD = "\ufebe"
let s:a_i_DAD = "\ufebf"
let s:a_m_DAD = "\ufec0"
let s:a_s_TAH = "\ufec1"
let s:a_f_TAH = "\ufec2"
let s:a_i_TAH = "\ufec3"
let s:a_m_TAH = "\ufec4"
let s:a_s_ZAH = "\ufec5"
let s:a_f_ZAH = "\ufec6"
let s:a_i_ZAH = "\ufec7"
let s:a_m_ZAH = "\ufec8"
let s:a_s_AIN = "\ufec9"
let s:a_f_AIN = "\ufeca"
let s:a_i_AIN = "\ufecb"
let s:a_m_AIN = "\ufecc"
let s:a_s_GHAIN = "\ufecd"
let s:a_f_GHAIN = "\ufece"
let s:a_i_GHAIN = "\ufecf"
let s:a_m_GHAIN = "\ufed0"
let s:a_s_FEH = "\ufed1"
let s:a_f_FEH = "\ufed2"
let s:a_i_FEH = "\ufed3"
let s:a_m_FEH = "\ufed4"
let s:a_s_QAF = "\ufed5"
let s:a_f_QAF = "\ufed6"
let s:a_i_QAF = "\ufed7"
let s:a_m_QAF = "\ufed8"
let s:a_s_KAF = "\ufed9"
let s:a_f_KAF = "\ufeda"
let s:a_i_KAF = "\ufedb"
let s:a_m_KAF = "\ufedc"
let s:a_s_LAM = "\ufedd"
let s:a_f_LAM = "\ufede"
let s:a_i_LAM = "\ufedf"
let s:a_m_LAM = "\ufee0"
let s:a_s_MEEM = "\ufee1"
let s:a_f_MEEM = "\ufee2"
let s:a_i_MEEM = "\ufee3"
let s:a_m_MEEM = "\ufee4"
let s:a_s_NOON = "\ufee5"
let s:a_f_NOON = "\ufee6"
let s:a_i_NOON = "\ufee7"
let s:a_m_NOON = "\ufee8"
let s:a_s_HEH = "\ufee9"
let s:a_f_HEH = "\ufeea"
let s:a_i_HEH = "\ufeeb"
let s:a_m_HEH = "\ufeec"
let s:a_s_WAW = "\ufeed"
let s:a_f_WAW = "\ufeee"
let s:a_s_ALEF_MAKSURA = "\ufeef"
let s:a_f_ALEF_MAKSURA = "\ufef0"
let s:a_s_YEH = "\ufef1"
let s:a_f_YEH = "\ufef2"
let s:a_i_YEH = "\ufef3"
let s:a_m_YEH = "\ufef4"
let s:a_s_LAM_ALEF_MADDA_ABOVE = "\ufef5"
let s:a_f_LAM_ALEF_MADDA_ABOVE = "\ufef6"
let s:a_s_LAM_ALEF_HAMZA_ABOVE = "\ufef7"
let s:a_f_LAM_ALEF_HAMZA_ABOVE = "\ufef8"
let s:a_s_LAM_ALEF_HAMZA_BELOW = "\ufef9"
let s:a_f_LAM_ALEF_HAMZA_BELOW = "\ufefa"
let s:a_s_LAM_ALEF = "\ufefb"
let s:a_f_LAM_ALEF = "\ufefc"
let s:a_BYTE_ORDER_MARK = "\ufeff"
func Test_shape_initial()
new
set arabicshape
" Shaping arabic {testchar} non-arabic Tests chg_c_a2i().
" pair[0] = testchar, pair[1] = next-result, pair[2] = current-result
for pair in [[s:a_YEH_HAMZA, s:a_f_GHAIN, s:a_i_YEH_HAMZA],
\ [s:a_HAMZA, s:a_s_GHAIN, s:a_s_HAMZA],
\ [s:a_ALEF_MADDA, s:a_s_GHAIN, s:a_s_ALEF_MADDA],
\ [s:a_ALEF_HAMZA_ABOVE, s:a_s_GHAIN, s:a_s_ALEF_HAMZA_ABOVE],
\ [s:a_WAW_HAMZA, s:a_s_GHAIN, s:a_s_WAW_HAMZA],
\ [s:a_ALEF_HAMZA_BELOW, s:a_s_GHAIN, s:a_s_ALEF_HAMZA_BELOW],
\ [s:a_ALEF, s:a_s_GHAIN, s:a_s_ALEF],
\ [s:a_TEH_MARBUTA, s:a_s_GHAIN, s:a_s_TEH_MARBUTA],
\ [s:a_DAL, s:a_s_GHAIN, s:a_s_DAL],
\ [s:a_THAL, s:a_s_GHAIN, s:a_s_THAL],
\ [s:a_REH, s:a_s_GHAIN, s:a_s_REH],
\ [s:a_ZAIN, s:a_s_GHAIN, s:a_s_ZAIN],
\ [s:a_TATWEEL, s:a_f_GHAIN, s:a_TATWEEL],
\ [s:a_WAW, s:a_s_GHAIN, s:a_s_WAW],
\ [s:a_ALEF_MAKSURA, s:a_s_GHAIN, s:a_s_ALEF_MAKSURA],
\ [s:a_BEH, s:a_f_GHAIN, s:a_i_BEH],
\ [s:a_TEH, s:a_f_GHAIN, s:a_i_TEH],
\ [s:a_THEH, s:a_f_GHAIN, s:a_i_THEH],
\ [s:a_JEEM, s:a_f_GHAIN, s:a_i_JEEM],
\ [s:a_HAH, s:a_f_GHAIN, s:a_i_HAH],
\ [s:a_KHAH, s:a_f_GHAIN, s:a_i_KHAH],
\ [s:a_SEEN, s:a_f_GHAIN, s:a_i_SEEN],
\ [s:a_SHEEN, s:a_f_GHAIN, s:a_i_SHEEN],
\ [s:a_SAD, s:a_f_GHAIN, s:a_i_SAD],
\ [s:a_DAD, s:a_f_GHAIN, s:a_i_DAD],
\ [s:a_TAH, s:a_f_GHAIN, s:a_i_TAH],
\ [s:a_ZAH, s:a_f_GHAIN, s:a_i_ZAH],
\ [s:a_AIN, s:a_f_GHAIN, s:a_i_AIN],
\ [s:a_GHAIN, s:a_f_GHAIN, s:a_i_GHAIN],
\ [s:a_FEH, s:a_f_GHAIN, s:a_i_FEH],
\ [s:a_QAF, s:a_f_GHAIN, s:a_i_QAF],
\ [s:a_KAF, s:a_f_GHAIN, s:a_i_KAF],
\ [s:a_LAM, s:a_f_GHAIN, s:a_i_LAM],
\ [s:a_MEEM, s:a_f_GHAIN, s:a_i_MEEM],
\ [s:a_NOON, s:a_f_GHAIN, s:a_i_NOON],
\ [s:a_HEH, s:a_f_GHAIN, s:a_i_HEH],
\ [s:a_YEH, s:a_f_GHAIN, s:a_i_YEH],
\ ]
call setline(1, s:a_GHAIN . pair[0] . ' ')
call assert_equal([pair[1] . pair[2] . ' '], ScreenLines(1, 3))
endfor
set arabicshape&
bwipe!
endfunc
func Test_shape_isolated()
new
set arabicshape
" Shaping non-arabic {testchar} non-arabic Tests chg_c_a2s().
" pair[0] = testchar, pair[1] = current-result
for pair in [[s:a_HAMZA, s:a_s_HAMZA],
\ [s:a_ALEF_MADDA, s:a_s_ALEF_MADDA],
\ [s:a_ALEF_HAMZA_ABOVE, s:a_s_ALEF_HAMZA_ABOVE],
\ [s:a_WAW_HAMZA, s:a_s_WAW_HAMZA],
\ [s:a_ALEF_HAMZA_BELOW, s:a_s_ALEF_HAMZA_BELOW],
\ [s:a_YEH_HAMZA, s:a_s_YEH_HAMZA],
\ [s:a_ALEF, s:a_s_ALEF],
\ [s:a_TEH_MARBUTA, s:a_s_TEH_MARBUTA],
\ [s:a_DAL, s:a_s_DAL],
\ [s:a_THAL, s:a_s_THAL],
\ [s:a_REH, s:a_s_REH],
\ [s:a_ZAIN, s:a_s_ZAIN],
\ [s:a_TATWEEL, s:a_TATWEEL],
\ [s:a_WAW, s:a_s_WAW],
\ [s:a_ALEF_MAKSURA, s:a_s_ALEF_MAKSURA],
\ [s:a_BEH, s:a_s_BEH],
\ [s:a_TEH, s:a_s_TEH],
\ [s:a_THEH, s:a_s_THEH],
\ [s:a_JEEM, s:a_s_JEEM],
\ [s:a_HAH, s:a_s_HAH],
\ [s:a_KHAH, s:a_s_KHAH],
\ [s:a_SEEN, s:a_s_SEEN],
\ [s:a_SHEEN, s:a_s_SHEEN],
\ [s:a_SAD, s:a_s_SAD],
\ [s:a_DAD, s:a_s_DAD],
\ [s:a_TAH, s:a_s_TAH],
\ [s:a_ZAH, s:a_s_ZAH],
\ [s:a_AIN, s:a_s_AIN],
\ [s:a_GHAIN, s:a_s_GHAIN],
\ [s:a_FEH, s:a_s_FEH],
\ [s:a_QAF, s:a_s_QAF],
\ [s:a_KAF, s:a_s_KAF],
\ [s:a_LAM, s:a_s_LAM],
\ [s:a_MEEM, s:a_s_MEEM],
\ [s:a_NOON, s:a_s_NOON],
\ [s:a_HEH, s:a_s_HEH],
\ [s:a_YEH, s:a_s_YEH],
\ ]
call setline(1, ' ' . pair[0] . ' ')
call assert_equal([' ' . pair[1] . ' '], ScreenLines(1, 3))
endfor
set arabicshape&
bwipe!
endfunc
func Test_shape_medial()
new
set arabicshape
" Shaping arabic {testchar} arabic Tests chg_c_a2m().
" pair[0] = testchar, pair[1] = next-result, pair[2] = current-result,
" pair[3] = previous-result
for pair in [[s:a_HAMZA, s:a_s_GHAIN, s:a_s_HAMZA, s:a_s_BEH],
\[s:a_ALEF_MADDA, s:a_s_GHAIN, s:a_f_ALEF_MADDA, s:a_i_BEH],
\[s:a_ALEF_HAMZA_ABOVE, s:a_s_GHAIN, s:a_f_ALEF_HAMZA_ABOVE, s:a_i_BEH],
\[s:a_WAW_HAMZA, s:a_s_GHAIN, s:a_f_WAW_HAMZA, s:a_i_BEH],
\[s:a_ALEF_HAMZA_BELOW, s:a_s_GHAIN, s:a_f_ALEF_HAMZA_BELOW, s:a_i_BEH],
\[s:a_YEH_HAMZA, s:a_f_GHAIN, s:a_m_YEH_HAMZA, s:a_i_BEH],
\[s:a_ALEF, s:a_s_GHAIN, s:a_f_ALEF, s:a_i_BEH],
\[s:a_BEH, s:a_f_GHAIN, s:a_m_BEH, s:a_i_BEH],
\[s:a_TEH_MARBUTA, s:a_s_GHAIN, s:a_f_TEH_MARBUTA, s:a_i_BEH],
\[s:a_TEH, s:a_f_GHAIN, s:a_m_TEH, s:a_i_BEH],
\[s:a_THEH, s:a_f_GHAIN, s:a_m_THEH, s:a_i_BEH],
\[s:a_JEEM, s:a_f_GHAIN, s:a_m_JEEM, s:a_i_BEH],
\[s:a_HAH, s:a_f_GHAIN, s:a_m_HAH, s:a_i_BEH],
\[s:a_KHAH, s:a_f_GHAIN, s:a_m_KHAH, s:a_i_BEH],
\[s:a_DAL, s:a_s_GHAIN, s:a_f_DAL, s:a_i_BEH],
\[s:a_THAL, s:a_s_GHAIN, s:a_f_THAL, s:a_i_BEH],
\[s:a_REH, s:a_s_GHAIN, s:a_f_REH, s:a_i_BEH],
\[s:a_ZAIN, s:a_s_GHAIN, s:a_f_ZAIN, s:a_i_BEH],
\[s:a_SEEN, s:a_f_GHAIN, s:a_m_SEEN, s:a_i_BEH],
\[s:a_SHEEN, s:a_f_GHAIN, s:a_m_SHEEN, s:a_i_BEH],
\[s:a_SAD, s:a_f_GHAIN, s:a_m_SAD, s:a_i_BEH],
\[s:a_DAD, s:a_f_GHAIN, s:a_m_DAD, s:a_i_BEH],
\[s:a_TAH, s:a_f_GHAIN, s:a_m_TAH, s:a_i_BEH],
\[s:a_ZAH, s:a_f_GHAIN, s:a_m_ZAH, s:a_i_BEH],
\[s:a_AIN, s:a_f_GHAIN, s:a_m_AIN, s:a_i_BEH],
\[s:a_GHAIN, s:a_f_GHAIN, s:a_m_GHAIN, s:a_i_BEH],
\[s:a_TATWEEL, s:a_f_GHAIN, s:a_TATWEEL, s:a_i_BEH],
\[s:a_FEH, s:a_f_GHAIN, s:a_m_FEH, s:a_i_BEH],
\[s:a_QAF, s:a_f_GHAIN, s:a_m_QAF, s:a_i_BEH],
\[s:a_KAF, s:a_f_GHAIN, s:a_m_KAF, s:a_i_BEH],
\[s:a_LAM, s:a_f_GHAIN, s:a_m_LAM, s:a_i_BEH],
\[s:a_MEEM, s:a_f_GHAIN, s:a_m_MEEM, s:a_i_BEH],
\[s:a_NOON, s:a_f_GHAIN, s:a_m_NOON, s:a_i_BEH],
\[s:a_HEH, s:a_f_GHAIN, s:a_m_HEH, s:a_i_BEH],
\[s:a_WAW, s:a_s_GHAIN, s:a_f_WAW, s:a_i_BEH],
\[s:a_ALEF_MAKSURA, s:a_s_GHAIN, s:a_f_ALEF_MAKSURA, s:a_i_BEH],
\[s:a_YEH, s:a_f_GHAIN, s:a_m_YEH, s:a_i_BEH],
\ ]
call setline(1, s:a_GHAIN . pair[0] . s:a_BEH)
call assert_equal([pair[1] . pair[2] . pair[3]], ScreenLines(1, 3))
endfor
set arabicshape&
bwipe!
endfunc
+25 -8
View File
@@ -1,6 +1,6 @@
" Test for folding
function! Test_address_fold()
func! Test_address_fold()
new
call setline(1, ['int FuncName() {/*{{{*/', 1, 2, 3, 4, 5, '}/*}}}*/',
\ 'after fold 1', 'after fold 2', 'after fold 3'])
@@ -62,9 +62,9 @@ function! Test_address_fold()
call assert_equal(['4', '5', '}/*}}}*/'], getreg(0,1,1))
quit!
endfunction
endfunc
function! Test_indent_fold()
func! Test_indent_fold()
new
call setline(1, ['', 'a', ' b', ' c'])
setl fen fdm=indent
@@ -72,9 +72,9 @@ function! Test_indent_fold()
norm! >>
let a=map(range(1,4), 'foldclosed(v:val)')
call assert_equal([-1,-1,-1,-1], a)
endfu
endfunc
function! Test_indent_fold()
func! Test_indent_fold()
new
call setline(1, ['', 'a', ' b', ' c'])
setl fen fdm=indent
@@ -83,9 +83,9 @@ function! Test_indent_fold()
let a=map(range(1,4), 'foldclosed(v:val)')
call assert_equal([-1,-1,-1,-1], a)
bw!
endfu
endfunc
function! Test_indent_fold2()
func! Test_indent_fold2()
new
call setline(1, ['', '{{{', '}}}', '{{{', '}}}'])
setl fen fdm=marker
@@ -94,4 +94,21 @@ function! Test_indent_fold2()
let a=map(range(1,5), 'foldclosed(v:val)')
call assert_equal([-1,-1,-1,4,4], a)
bw!
endfu
endfunc
func Test_manual_fold_with_filter()
if !executable('cat')
return
endif
new
call setline(1, range(1, 20))
4,$fold
%foldopen
10,$fold
%foldopen
" This filter command should not have an effect
1,8! cat
call feedkeys('5ggzdzMGdd', 'xt')
call assert_equal(['1', '2', '3', '4', '5', '6', '7', '8', '9'], getline(1, '$'))
bwipe!
endfunc
+3
View File
@@ -17,6 +17,9 @@ endfunc
" Test for resetting "secure" flag after GUI has started.
" Must be run first.
func Test_1_set_secure()
" Ignore the "failed to create input context" error.
call test_ignore_error('E285')
set exrc secure
gui -f
call assert_equal(1, has('gui_running'))
+24
View File
@@ -35,10 +35,34 @@ func Test_static_tagjump()
tag one
call assert_equal(2, line('.'))
bwipe!
set tags&
call delete('Xtags')
call delete('Xfile1')
endfunc
func Test_duplicate_tagjump()
set tags=Xtags
call writefile(["!_TAG_FILE_ENCODING\tutf-8\t//",
\ "thesame\tXfile1\t1;\"\td\tfile:",
\ "thesame\tXfile1\t2;\"\td\tfile:",
\ "thesame\tXfile1\t3;\"\td\tfile:",
\ ],
\ 'Xtags')
new Xfile1
call setline(1, ['thesame one', 'thesame two', 'thesame three'])
write
tag thesame
call assert_equal(1, line('.'))
tnext
call assert_equal(2, line('.'))
tnext
call assert_equal(3, line('.'))
bwipe!
set tags&
call delete('Xtags')
call delete('Xfile1')
endfunc
" Tests for [ CTRL-I and CTRL-W CTRL-I commands
+14
View File
@@ -779,6 +779,20 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
393,
/**/
392,
/**/
391,
/**/
390,
/**/
389,
/**/
388,
/**/
387,
/**/
386,
/**/