mirror of
https://github.com/zoriya/vim.git
synced 2025-12-10 01:06:16 +00:00
Compare commits
31 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
08cab96087 | ||
|
|
391b1dd040 | ||
|
|
24d7636e98 | ||
|
|
cf5fdf7d16 | ||
|
|
a0107bdf87 | ||
|
|
358f6b0a36 | ||
|
|
caf6434ac9 | ||
|
|
66727e1607 | ||
|
|
5a66dfb25e | ||
|
|
59716a27bd | ||
|
|
f8ab1b14fd | ||
|
|
abc39ab642 | ||
|
|
98e83b2956 | ||
|
|
e0c31f6a30 | ||
|
|
5f53dd3f74 | ||
|
|
cb03642399 | ||
|
|
5342f00ff9 | ||
|
|
1159b168dd | ||
|
|
b113c3a618 | ||
|
|
5b3af14b34 | ||
|
|
b5e8377364 | ||
|
|
d512e17ea4 | ||
|
|
10a8da0594 | ||
|
|
88e7688eda | ||
|
|
aeb661e1f4 | ||
|
|
38632faf63 | ||
|
|
74a47162a0 | ||
|
|
0c8485f0e4 | ||
|
|
3eb1637b1b | ||
|
|
6d3c8586fc | ||
|
|
5074a0e033 |
@@ -1789,8 +1789,11 @@ v:progpath Contains the command with which Vim was invoked, including the
|
||||
|--remote-expr|.
|
||||
To get the full path use: >
|
||||
echo exepath(v:progpath)
|
||||
< NOTE: This does not work when the command is a relative path
|
||||
and the current directory has changed.
|
||||
< If the path is relative it will be expanded to the full path,
|
||||
so that it still works after `:cd`. Thus starting "./vim"
|
||||
results in "/home/user/path/to/vim/src/vim".
|
||||
On MS-Windows the executable may be called "vim.exe", but the
|
||||
".exe" is not added to v:progpath.
|
||||
Read-only.
|
||||
|
||||
*v:register* *register-variable*
|
||||
@@ -1981,19 +1984,20 @@ argidx() Number current index in the argument list
|
||||
arglistid([{winnr} [, {tabnr}]]) Number argument list id
|
||||
argv({nr}) String {nr} entry of the argument list
|
||||
argv() List the argument list
|
||||
assert_equal({exp}, {act} [, {msg}]) none assert {exp} is equal to {act}
|
||||
assert_exception({error} [, {msg}]) none assert {error} is in v:exception
|
||||
assert_fails({cmd} [, {error}]) none assert {cmd} fails
|
||||
assert_false({actual} [, {msg}]) none assert {actual} is false
|
||||
assert_equal({exp}, {act} [, {msg}]) none assert {exp} is equal to {act}
|
||||
assert_exception({error} [, {msg}]) none assert {error} is in v:exception
|
||||
assert_fails({cmd} [, {error}]) none assert {cmd} fails
|
||||
assert_false({actual} [, {msg}]) none assert {actual} is false
|
||||
assert_inrange({lower}, {upper}, {actual} [, {msg}])
|
||||
none assert {actual} is inside the range
|
||||
assert_match({pat}, {text} [, {msg}]) none assert {pat} matches {text}
|
||||
assert_match({pat}, {text} [, {msg}]) none assert {pat} matches {text}
|
||||
assert_notequal({exp}, {act} [, {msg}]) none assert {exp} is not equal {act}
|
||||
assert_notmatch({pat}, {text} [, {msg}]) none assert {pat} not matches {text}
|
||||
assert_true({actual} [, {msg}]) none assert {actual} is true
|
||||
assert_true({actual} [, {msg}]) none assert {actual} is true
|
||||
asin({expr}) Float arc sine of {expr}
|
||||
atan({expr}) Float arc tangent of {expr}
|
||||
atan2({expr1}, {expr2}) Float arc tangent of {expr1} / {expr2}
|
||||
balloon_show({msg}) none show {msg} inside the balloon
|
||||
browse({save}, {title}, {initdir}, {default})
|
||||
String put up a file requester
|
||||
browsedir({title}, {initdir}) String put up a directory requester
|
||||
@@ -2358,6 +2362,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
|
||||
@@ -2618,6 +2623,25 @@ atan2({expr1}, {expr2}) *atan2()*
|
||||
< 2.356194
|
||||
{only available when compiled with the |+float| feature}
|
||||
|
||||
balloon_show({msg}) *balloon_show()*
|
||||
Show {msg} inside the balloon.
|
||||
Example: >
|
||||
func GetBalloonContent()
|
||||
" initiate getting the content
|
||||
return ''
|
||||
endfunc
|
||||
set balloonexpr=GetBalloonContent()
|
||||
|
||||
func BalloonCallback(result)
|
||||
call balloon_show(a:result)
|
||||
endfunc
|
||||
<
|
||||
The intended use is that fetching the content of the balloon
|
||||
is initiated from 'balloonexpr'. It will invoke an
|
||||
asynchronous method, in which a callback invokes
|
||||
balloon_show(). The 'balloonexpr' itself can return an
|
||||
empty string or a placeholder.
|
||||
{only available when compiled with the +beval feature}
|
||||
|
||||
*browse()*
|
||||
browse({save}, {title}, {initdir}, {default})
|
||||
@@ -7784,6 +7808,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}
|
||||
|
||||
@@ -2092,6 +2092,7 @@ test1 \
|
||||
|
||||
# Run individual NEW style test, assuming that Vim was already compiled.
|
||||
test_arglist \
|
||||
test_arabic \
|
||||
test_assert \
|
||||
test_assign \
|
||||
test_autochdir \
|
||||
|
||||
448
src/arabic.c
448
src/arabic.c
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
@@ -1966,7 +1966,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
|
||||
@@ -3299,6 +3299,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);
|
||||
|
||||
41
src/edit.c
41
src/edit.c
@@ -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 */
|
||||
|
||||
@@ -1038,8 +1038,10 @@ doESCkey:
|
||||
if (!p_im)
|
||||
goto normalchar; /* insert CTRL-Z as normal char */
|
||||
do_cmdline_cmd((char_u *)"stop");
|
||||
c = Ctrl_O;
|
||||
/*FALLTHROUGH*/
|
||||
#ifdef CURSOR_SHAPE
|
||||
ui_cursor_shape(); /* may need to update cursor shape */
|
||||
#endif
|
||||
continue;
|
||||
|
||||
case Ctrl_O: /* execute one command */
|
||||
#ifdef FEAT_COMPL_FUNC
|
||||
@@ -2816,6 +2818,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)
|
||||
@@ -2856,7 +2859,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();
|
||||
}
|
||||
|
||||
@@ -5094,6 +5097,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;
|
||||
|
||||
@@ -5537,6 +5541,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 */
|
||||
@@ -5689,9 +5694,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;
|
||||
|
||||
@@ -5699,21 +5703,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;
|
||||
}
|
||||
|
||||
/*
|
||||
|
||||
@@ -58,6 +58,9 @@ static void f_asin(typval_T *argvars, typval_T *rettv);
|
||||
static void f_atan(typval_T *argvars, typval_T *rettv);
|
||||
static void f_atan2(typval_T *argvars, typval_T *rettv);
|
||||
#endif
|
||||
#ifdef FEAT_BEVAL
|
||||
static void f_balloon_show(typval_T *argvars, typval_T *rettv);
|
||||
#endif
|
||||
static void f_browse(typval_T *argvars, typval_T *rettv);
|
||||
static void f_browsedir(typval_T *argvars, typval_T *rettv);
|
||||
static void f_bufexists(typval_T *argvars, typval_T *rettv);
|
||||
@@ -389,6 +392,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
|
||||
@@ -482,6 +486,9 @@ static struct fst
|
||||
#ifdef FEAT_FLOAT
|
||||
{"atan", 1, 1, f_atan},
|
||||
{"atan2", 2, 2, f_atan2},
|
||||
#endif
|
||||
#ifdef FEAT_BEVAL
|
||||
{"balloon_show", 1, 1, f_balloon_show},
|
||||
#endif
|
||||
{"browse", 4, 4, f_browse},
|
||||
{"browsedir", 2, 2, f_browsedir},
|
||||
@@ -823,6 +830,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
|
||||
@@ -1360,6 +1368,18 @@ f_atan2(typval_T *argvars, typval_T *rettv)
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "balloon_show()" function
|
||||
*/
|
||||
#ifdef FEAT_BEVAL
|
||||
static void
|
||||
f_balloon_show(typval_T *argvars, typval_T *rettv UNUSED)
|
||||
{
|
||||
if (balloonEval != NULL)
|
||||
gui_mch_post_balloon(balloonEval, get_tv_string_chk(&argvars[0]));
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
* "browse(save, title, initdir, default)" function
|
||||
*/
|
||||
@@ -12325,6 +12345,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)
|
||||
|
||||
@@ -9812,6 +9812,7 @@ ex_redraw(exarg_T *eap)
|
||||
|
||||
RedrawingDisabled = 0;
|
||||
p_lz = FALSE;
|
||||
validate_cursor();
|
||||
update_topline();
|
||||
update_screen(eap->forceit ? CLEAR : VIsual_active ? INVERTED : 0);
|
||||
#ifdef FEAT_TITLE
|
||||
|
||||
13
src/fold.c
13
src/fold.c
@@ -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;
|
||||
}
|
||||
|
||||
@@ -1,10 +1,10 @@
|
||||
" Script to generate testdir/opt_test.vim from option.c
|
||||
|
||||
if 0
|
||||
finish
|
||||
endif
|
||||
|
||||
set cpo=&vim
|
||||
|
||||
" Only do this when build with the +eval feature.
|
||||
if 1
|
||||
|
||||
set nomore
|
||||
|
||||
let script = [
|
||||
@@ -130,7 +130,6 @@ let test_values = {
|
||||
\ 'winaltkeys': [['menu', 'no'], ['', 'xxx']],
|
||||
\
|
||||
\ 'luadll': [[], []],
|
||||
\ 'macatsui': [[], []],
|
||||
\ 'perldll': [[], []],
|
||||
\ 'pythondll': [[], []],
|
||||
\ 'pythonthreedll': [[], []],
|
||||
@@ -192,4 +191,6 @@ call add(script, 'let &lines = save_lines')
|
||||
|
||||
call writefile(script, 'testdir/opt_test.vim')
|
||||
|
||||
endif
|
||||
|
||||
qa!
|
||||
|
||||
@@ -4216,6 +4216,11 @@ set_context_in_map_cmd(
|
||||
arg = skipwhite(arg + 8);
|
||||
continue;
|
||||
}
|
||||
if (STRNCMP(arg, "<special>", 9) == 0)
|
||||
{
|
||||
arg = skipwhite(arg + 9);
|
||||
continue;
|
||||
}
|
||||
#ifdef FEAT_EVAL
|
||||
if (STRNCMP(arg, "<script>", 8) == 0)
|
||||
{
|
||||
@@ -4267,7 +4272,7 @@ ExpandMappings(
|
||||
{
|
||||
count = 0;
|
||||
|
||||
for (i = 0; i < 6; ++i)
|
||||
for (i = 0; i < 7; ++i)
|
||||
{
|
||||
if (i == 0)
|
||||
p = (char_u *)"<silent>";
|
||||
@@ -4285,6 +4290,8 @@ ExpandMappings(
|
||||
#endif
|
||||
else if (i == 5)
|
||||
p = (char_u *)"<nowait>";
|
||||
else if (i == 6)
|
||||
p = (char_u *)"<special>";
|
||||
else
|
||||
continue;
|
||||
|
||||
|
||||
31
src/main.c
31
src/main.c
@@ -57,6 +57,9 @@ static void main_start_gui(void);
|
||||
# if defined(HAS_SWAP_EXISTS_ACTION)
|
||||
static void check_swap_exists_action(void);
|
||||
# endif
|
||||
# ifdef FEAT_EVAL
|
||||
static void set_progpath(char_u *argv0);
|
||||
# endif
|
||||
# if defined(FEAT_CLIENTSERVER) || defined(PROTO)
|
||||
static void exec_on_server(mparm_T *parmp);
|
||||
static void prepare_server(mparm_T *parmp);
|
||||
@@ -1694,7 +1697,7 @@ parse_command_name(mparm_T *parmp)
|
||||
|
||||
#ifdef FEAT_EVAL
|
||||
set_vim_var_string(VV_PROGNAME, initstr, -1);
|
||||
set_vim_var_string(VV_PROGPATH, (char_u *)parmp->argv[0], -1);
|
||||
set_progpath((char_u *)parmp->argv[0]);
|
||||
#endif
|
||||
|
||||
if (TOLOWER_ASC(initstr[0]) == 'r')
|
||||
@@ -3417,7 +3420,7 @@ check_swap_exists_action(void)
|
||||
}
|
||||
#endif
|
||||
|
||||
#endif
|
||||
#endif /* NO_VIM_MAIN */
|
||||
|
||||
#if defined(STARTUPTIME) || defined(PROTO)
|
||||
static void time_diff(struct timeval *then, struct timeval *now);
|
||||
@@ -3525,6 +3528,30 @@ time_msg(
|
||||
|
||||
#endif
|
||||
|
||||
#ifndef NO_VIM_MAIN
|
||||
static void
|
||||
set_progpath(char_u *argv0)
|
||||
{
|
||||
char_u *val = argv0;
|
||||
char_u buf[MAXPATHL];
|
||||
|
||||
/* A relative path containing a "/" will become invalid when using ":cd",
|
||||
* turn it into a full path.
|
||||
* On MS-Windows "vim.exe" is found in the current directory, thus also do
|
||||
* it when there is no path and the file exists. */
|
||||
if ( !mch_isFullName(argv0)
|
||||
# ifdef WIN32
|
||||
&& mch_can_exe(argv0, NULL, TRUE)
|
||||
# else
|
||||
&& gettail(argv0) != argv0
|
||||
# endif
|
||||
&& vim_FullName(argv0, buf, MAXPATHL, TRUE) != FAIL)
|
||||
val = buf;
|
||||
set_vim_var_string(VV_PROGPATH, val, -1);
|
||||
}
|
||||
|
||||
#endif /* NO_VIM_MAIN */
|
||||
|
||||
#if (defined(FEAT_CLIENTSERVER) && !defined(NO_VIM_MAIN)) || defined(PROTO)
|
||||
|
||||
/*
|
||||
|
||||
@@ -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])
|
||||
|
||||
@@ -539,6 +539,31 @@ emsg_not_now(void)
|
||||
return FALSE;
|
||||
}
|
||||
|
||||
#if defined(FEAT_EVAL) || defined(PROTO)
|
||||
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,13 @@ 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))
|
||||
/* don't call msg() if it results in a dialog */
|
||||
return msg_use_printf() ? FALSE : msg(s);
|
||||
#endif
|
||||
|
||||
called_emsg = TRUE;
|
||||
|
||||
/*
|
||||
|
||||
@@ -2099,7 +2099,7 @@ ga_concat_strings(garray_T *gap, char *sep)
|
||||
return s;
|
||||
}
|
||||
|
||||
#if defined(FEAT_VIMINFO) || defined(PROTO)
|
||||
#if defined(FEAT_VIMINFO) || defined(FEAT_EVAL) || defined(PROTO)
|
||||
/*
|
||||
* Make a copy of string "p" and add it to "gap".
|
||||
* When out of memory nothing changes.
|
||||
|
||||
@@ -2982,8 +2982,6 @@ do_mouse(
|
||||
|| (mod_mask & MOD_MASK_MULTI_CLICK) == MOD_MASK_2CLICK)
|
||||
&& bt_quickfix(curbuf))
|
||||
{
|
||||
if (State & INSERT)
|
||||
stuffcharReadbuff(Ctrl_O);
|
||||
if (curwin->w_llist_ref == NULL) /* quickfix window */
|
||||
do_cmdline_cmd((char_u *)".cc");
|
||||
else /* location list window */
|
||||
@@ -6193,10 +6191,12 @@ nv_down(cmdarg_T *cap)
|
||||
#if defined(FEAT_WINDOWS) && defined(FEAT_QUICKFIX)
|
||||
/* In a quickfix window a <CR> jumps to the error under the cursor. */
|
||||
if (bt_quickfix(curbuf) && cap->cmdchar == CAR)
|
||||
{
|
||||
if (curwin->w_llist_ref == NULL)
|
||||
do_cmdline_cmd((char_u *)".cc"); /* quickfix window */
|
||||
else
|
||||
do_cmdline_cmd((char_u *)".ll"); /* location list window */
|
||||
}
|
||||
else
|
||||
#endif
|
||||
{
|
||||
|
||||
@@ -467,6 +467,12 @@ mch_inchar(
|
||||
if ((wait_time < 0 || wait_time > 100L) && channel_any_readahead())
|
||||
wait_time = 10L;
|
||||
#endif
|
||||
#ifdef FEAT_BEVAL
|
||||
if (p_beval && wait_time > 100L)
|
||||
/* The 'balloonexpr' may indirectly invoke a callback while waiting
|
||||
* for a character, need to check often. */
|
||||
wait_time = 100L;
|
||||
#endif
|
||||
|
||||
/*
|
||||
* We want to be interrupted by the winch signal
|
||||
|
||||
@@ -1467,6 +1467,12 @@ WaitForChar(long msec)
|
||||
dwWaitTime = 10;
|
||||
}
|
||||
#endif
|
||||
#ifdef FEAT_BEVAL
|
||||
if (p_beval && dwWaitTime > 100)
|
||||
/* The 'balloonexpr' may indirectly invoke a callback while
|
||||
* waiting for a character, need to check often. */
|
||||
dwWaitTime = 100;
|
||||
#endif
|
||||
#ifdef FEAT_MZSCHEME
|
||||
if (mzthreads_allowed() && p_mzq > 0
|
||||
&& (msec < 0 || (long)dwWaitTime > p_mzq))
|
||||
|
||||
@@ -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);
|
||||
|
||||
22
src/screen.c
22
src/screen.c
@@ -3429,10 +3429,13 @@ win_line(
|
||||
#else
|
||||
--ptr;
|
||||
#endif
|
||||
/* If the character fits on the screen, don't need to skip it.
|
||||
* Except for a TAB. */
|
||||
if ((
|
||||
#ifdef FEAT_MBYTE
|
||||
/* character fits on the screen, don't need to skip it */
|
||||
if ((*mb_ptr2cells)(ptr) >= c && col == 0)
|
||||
(*mb_ptr2cells)(ptr) >= c ||
|
||||
#endif
|
||||
*ptr == TAB) && col == 0)
|
||||
n_skip = v - vcol;
|
||||
}
|
||||
|
||||
@@ -4189,6 +4192,10 @@ win_line(
|
||||
}
|
||||
else
|
||||
{
|
||||
#ifdef FEAT_LINEBREAK
|
||||
int c0;
|
||||
#endif
|
||||
|
||||
if (p_extra_free != NULL)
|
||||
{
|
||||
vim_free(p_extra_free);
|
||||
@@ -4198,6 +4205,9 @@ win_line(
|
||||
* Get a character from the line itself.
|
||||
*/
|
||||
c = *ptr;
|
||||
#ifdef FEAT_LINEBREAK
|
||||
c0 = *ptr;
|
||||
#endif
|
||||
#ifdef FEAT_MBYTE
|
||||
if (has_mbyte)
|
||||
{
|
||||
@@ -4214,7 +4224,12 @@ win_line(
|
||||
/* Overlong encoded ASCII or ASCII with composing char
|
||||
* is displayed normally, except a NUL. */
|
||||
if (mb_c < 0x80)
|
||||
{
|
||||
c = mb_c;
|
||||
# ifdef FEAT_LINEBREAK
|
||||
c0 = mb_c;
|
||||
# endif
|
||||
}
|
||||
mb_utf8 = TRUE;
|
||||
|
||||
/* At start of the line we can have a composing char.
|
||||
@@ -4538,7 +4553,8 @@ win_line(
|
||||
/*
|
||||
* Found last space before word: check for line break.
|
||||
*/
|
||||
if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(*ptr))
|
||||
if (wp->w_p_lbr && c0 == c
|
||||
&& vim_isbreak(c) && !vim_isbreak(*ptr))
|
||||
{
|
||||
# ifdef FEAT_MBYTE
|
||||
int mb_off = has_mbyte ? (*mb_head_off)(line, ptr - 1) : 0;
|
||||
|
||||
@@ -1693,12 +1693,9 @@ searchc(cmdarg_T *cap, int t_cmd)
|
||||
if (p[col] == c && stop)
|
||||
break;
|
||||
}
|
||||
else
|
||||
{
|
||||
if (memcmp(p + col, lastc_bytes, lastc_bytelen) == 0
|
||||
else if (STRNCMP(p + col, lastc_bytes, lastc_bytelen) == 0
|
||||
&& stop)
|
||||
break;
|
||||
}
|
||||
break;
|
||||
stop = TRUE;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1585,7 +1585,7 @@ spell_read_tree(
|
||||
int prefixtree, /* TRUE for the prefix tree */
|
||||
int prefixcnt) /* when "prefixtree" is TRUE: prefix count */
|
||||
{
|
||||
int len;
|
||||
long len;
|
||||
int idx;
|
||||
char_u *bp;
|
||||
idx_T *ip;
|
||||
@@ -1595,7 +1595,7 @@ spell_read_tree(
|
||||
len = get4c(fd);
|
||||
if (len < 0)
|
||||
return SP_TRUNCERROR;
|
||||
if (len >= 0x3ffffff)
|
||||
if (len >= LONG_MAX / (long)sizeof(int))
|
||||
/* Invalid length, multiply with sizeof(int) would overflow. */
|
||||
return SP_FORMERROR;
|
||||
if (len > 0)
|
||||
|
||||
60
src/tag.c
60
src/tag.c
@@ -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]);
|
||||
}
|
||||
|
||||
|
||||
@@ -133,7 +133,8 @@ SCRIPTS_GUI =
|
||||
|
||||
# Tests using runtest.vim.vim.
|
||||
# Keep test_alot*.res as the last one, sort the others.
|
||||
NEW_TESTS = test_arglist.res \
|
||||
NEW_TESTS = test_arabic.res \
|
||||
test_arglist.res \
|
||||
test_assert.res \
|
||||
test_autochdir.res \
|
||||
test_backspace_opt.res \
|
||||
|
||||
@@ -165,6 +165,7 @@ let s:flaky = [
|
||||
\ 'Test_collapse_buffers()',
|
||||
\ 'Test_communicate()',
|
||||
\ 'Test_nb_basic()',
|
||||
\ 'Test_oneshot()',
|
||||
\ 'Test_pipe_through_sort_all()',
|
||||
\ 'Test_pipe_through_sort_some()',
|
||||
\ 'Test_reltime()',
|
||||
|
||||
@@ -27,3 +27,6 @@ endfunc
|
||||
func GUITearDownCommon()
|
||||
call delete('Xhome', 'rf')
|
||||
endfunc
|
||||
|
||||
" Ignore the "failed to create input context" error.
|
||||
call test_ignore_error('E285')
|
||||
|
||||
@@ -192,6 +192,7 @@ func RunVimPiped(before, after, arguments, pipecmd)
|
||||
if cmd !~ '-u NONE'
|
||||
let cmd = cmd . ' -u NONE'
|
||||
endif
|
||||
let cmd .= ' --not-a-term'
|
||||
|
||||
" With pipecmd we can't set VIMRUNTIME.
|
||||
if a:pipecmd != ''
|
||||
|
||||
472
src/testdir/test_arabic.vim
Normal file
472
src/testdir/test_arabic.vim
Normal file
@@ -0,0 +1,472 @@
|
||||
" Simplistic testing of Arabic mode.
|
||||
|
||||
if !has('arabic') || !has('multi_byte')
|
||||
finish
|
||||
endif
|
||||
|
||||
source view_util.vim
|
||||
|
||||
" Return list of Unicode characters at line lnum.
|
||||
" Combining characters are treated as a single item.
|
||||
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 . '|'
|
||||
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
|
||||
|
||||
func Test_arabic_toggle()
|
||||
set arabic
|
||||
call assert_equal(1, &rightleft)
|
||||
call assert_equal(1, &arabicshape)
|
||||
call assert_equal('arabic', &keymap)
|
||||
call assert_equal(1, &delcombine)
|
||||
|
||||
set iminsert=1 imsearch=1
|
||||
set arabic&
|
||||
call assert_equal(0, &rightleft)
|
||||
call assert_equal(1, &arabicshape)
|
||||
call assert_equal('arabic', &keymap)
|
||||
call assert_equal(1, &delcombine)
|
||||
call assert_equal(0, &iminsert)
|
||||
call assert_equal(-1, &imsearch)
|
||||
|
||||
set arabicshape& keymap= delcombine&
|
||||
endfunc
|
||||
|
||||
func Test_arabic_input()
|
||||
new
|
||||
set arabic
|
||||
" Typing sghl in Arabic insert mode should show the
|
||||
" 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([
|
||||
\ 'U+0633',
|
||||
\ 'U+0644 U+0627',
|
||||
\ 'U+0645',
|
||||
\ 'U+21'], s:get_chars(1))
|
||||
|
||||
" Without shaping, it should give individual Arabic letters.
|
||||
set noarabicshape
|
||||
call assert_match("^ *!\u0645\u0627\u0644\u0633$", ScreenLines(1, &columns)[0])
|
||||
call assert_equal([
|
||||
\ 'U+0633',
|
||||
\ 'U+0644',
|
||||
\ 'U+0627',
|
||||
\ 'U+0645',
|
||||
\ 'U+21'], s:get_chars(1))
|
||||
|
||||
set arabic& arabicshape&
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_arabic_toggle_keymap()
|
||||
new
|
||||
set arabic
|
||||
call feedkeys("i12\<C-^>12\<C-^>12", 'tx')
|
||||
call assert_match("^ *٢١21٢١$", ScreenLines(1, &columns)[0])
|
||||
call assert_equal('١٢12١٢', getline('.'))
|
||||
set arabic&
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_delcombine()
|
||||
new
|
||||
set arabic
|
||||
call feedkeys("isghl\<BS>\<BS>", 'tx')
|
||||
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'
|
||||
set nodelcombine
|
||||
%d
|
||||
call feedkeys("isghl\<BS>\<BS>", 'tx')
|
||||
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
|
||||
|
||||
@@ -274,7 +274,6 @@ endfunction
|
||||
|
||||
function Test_breakindent16()
|
||||
" Check that overlong lines are indented correctly.
|
||||
" TODO: currently it does not fail even when the bug is not fixed.
|
||||
let s:input=""
|
||||
call s:test_windows('setl breakindent briopt=min:0 ts=4')
|
||||
call setline(1, "\t".repeat("1234567890", 10))
|
||||
@@ -283,16 +282,16 @@ function Test_breakindent16()
|
||||
redraw!
|
||||
let lines=s:screen_lines(1,10)
|
||||
let expect=[
|
||||
\ " 123456",
|
||||
\ " 789012",
|
||||
\ " 345678",
|
||||
\ " 901234",
|
||||
\ ]
|
||||
call s:compare_lines(expect, lines)
|
||||
let lines=s:screen_lines(4,10)
|
||||
let expect=[
|
||||
\ " 901234",
|
||||
\ " 567890",
|
||||
\ " 123456",
|
||||
\ " 7890 ",
|
||||
\ ]
|
||||
call s:compare_lines(expect, lines)
|
||||
call s:close_windows()
|
||||
|
||||
@@ -25,6 +25,26 @@ func Test_complete_wildmenu()
|
||||
set nowildmenu
|
||||
endfunc
|
||||
|
||||
func Test_map_completion()
|
||||
if !has('cmdline_compl')
|
||||
return
|
||||
endif
|
||||
call feedkeys(":map <unique> <si\<Tab>\<Home>\"\<CR>", 'xt')
|
||||
call assert_equal('"map <unique> <silent>', getreg(':'))
|
||||
call feedkeys(":map <script> <un\<Tab>\<Home>\"\<CR>", 'xt')
|
||||
call assert_equal('"map <script> <unique>', getreg(':'))
|
||||
call feedkeys(":map <expr> <sc\<Tab>\<Home>\"\<CR>", 'xt')
|
||||
call assert_equal('"map <expr> <script>', getreg(':'))
|
||||
call feedkeys(":map <buffer> <e\<Tab>\<Home>\"\<CR>", 'xt')
|
||||
call assert_equal('"map <buffer> <expr>', getreg(':'))
|
||||
call feedkeys(":map <nowait> <b\<Tab>\<Home>\"\<CR>", 'xt')
|
||||
call assert_equal('"map <nowait> <buffer>', getreg(':'))
|
||||
call feedkeys(":map <special> <no\<Tab>\<Home>\"\<CR>", 'xt')
|
||||
call assert_equal('"map <special> <nowait>', getreg(':'))
|
||||
call feedkeys(":map <silent> <sp\<Tab>\<Home>\"\<CR>", 'xt')
|
||||
call assert_equal('"map <silent> <special>', getreg(':'))
|
||||
endfunc
|
||||
|
||||
func Test_match_completion()
|
||||
if !has('cmdline_compl')
|
||||
return
|
||||
|
||||
@@ -272,3 +272,78 @@ func Test_setting_cursor()
|
||||
call delete('Xtest1')
|
||||
call delete('Xtest2')
|
||||
endfunc
|
||||
|
||||
func Test_diff_move_to()
|
||||
new
|
||||
call setline(1, [1, 2, 3, 4, 5, 6, 7, 8, 9, 10])
|
||||
diffthis
|
||||
vnew
|
||||
call setline(1, [1, '2x', 3, 4, 4, 5, '6x', 7, '8x', 9, '10x'])
|
||||
diffthis
|
||||
norm ]c
|
||||
call assert_equal(2, line('.'))
|
||||
norm 3]c
|
||||
call assert_equal(9, line('.'))
|
||||
norm 10]c
|
||||
call assert_equal(11, line('.'))
|
||||
norm [c
|
||||
call assert_equal(9, line('.'))
|
||||
norm 2[c
|
||||
call assert_equal(5, line('.'))
|
||||
norm 10[c
|
||||
call assert_equal(2, line('.'))
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_diffpatch()
|
||||
" The patch program on MS-Windows may fail or hang.
|
||||
if !executable('patch') || !has('unix')
|
||||
return
|
||||
endif
|
||||
new
|
||||
insert
|
||||
***************
|
||||
*** 1,3 ****
|
||||
1
|
||||
! 2
|
||||
3
|
||||
--- 1,4 ----
|
||||
1
|
||||
! 2x
|
||||
3
|
||||
+ 4
|
||||
.
|
||||
saveas Xpatch
|
||||
bwipe!
|
||||
new
|
||||
call assert_fails('diffpatch Xpatch', 'E816:')
|
||||
call setline(1, ['1', '2', '3'])
|
||||
diffpatch Xpatch
|
||||
call assert_equal(['1', '2x', '3', '4'], getline(1, '$'))
|
||||
call delete('Xpatch')
|
||||
bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_diff_too_many_buffers()
|
||||
for i in range(1, 8)
|
||||
exe "new Xtest" . i
|
||||
diffthis
|
||||
endfor
|
||||
new Xtest9
|
||||
call assert_fails('diffthis', 'E96:')
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
func Test_diff_nomodifiable()
|
||||
new
|
||||
call setline(1, [1, 2, 3, 4])
|
||||
setl nomodifiable
|
||||
diffthis
|
||||
vnew
|
||||
call setline(1, ['1x', 2, 3, 3, 4])
|
||||
diffthis
|
||||
call assert_fails('norm dp', 'E793:')
|
||||
setl nomodifiable
|
||||
call assert_fails('norm do', 'E21:')
|
||||
%bwipe!
|
||||
endfunc
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -466,3 +466,10 @@ func Test_getbufvar()
|
||||
|
||||
set fileformats&
|
||||
endfunc
|
||||
|
||||
func Test_balloon_show()
|
||||
if has('balloon_eval')
|
||||
" This won't do anything but must not crash either.
|
||||
call balloon_show('hi!')
|
||||
endif
|
||||
endfunc
|
||||
|
||||
@@ -72,6 +72,51 @@ func Test_getfontname_without_arg()
|
||||
endif
|
||||
endfunc
|
||||
|
||||
func Test_quoteplus()
|
||||
let skipped = ''
|
||||
|
||||
if !g:x11_based_gui
|
||||
let skipped = g:not_supported . 'quoteplus'
|
||||
else
|
||||
let quoteplus_saved = @+
|
||||
|
||||
let test_call = 'Can you hear me?'
|
||||
let test_response = 'Yes, I can.'
|
||||
let vim_exe = exepath(v:progpath)
|
||||
let testee = 'VIMRUNTIME=' . $VIMRUNTIME . '; export VIMRUNTIME;'
|
||||
\ . vim_exe
|
||||
\ . ' -u NONE -U NONE --noplugin --not-a-term -c ''%s'''
|
||||
" Ignore the "failed to create input context" error.
|
||||
let cmd = 'call test_ignore_error("E285") | '
|
||||
\ . 'gui -f | '
|
||||
\ . 'call feedkeys("'
|
||||
\ . '\"+p'
|
||||
\ . ':s/' . test_call . '/' . test_response . '/\<CR>'
|
||||
\ . '\"+yis'
|
||||
\ . ':q!\<CR>", "tx")'
|
||||
let run_vimtest = printf(testee, cmd)
|
||||
|
||||
" Set the quoteplus register to test_call, and another gvim will launched.
|
||||
" Then, it first tries to paste the content of its own quotedplus register
|
||||
" onto it. Second, it tries to substitute test_responce for the pasted
|
||||
" sentence. If the sentence is identical to test_call, the substitution
|
||||
" should succeed. Third, it tries to yank the result of the substitution
|
||||
" to its own quoteplus register, and last it quits. When system()
|
||||
" returns, the content of the quoteplus register should be identical to
|
||||
" test_response if those quoteplus registers are synchronized properly
|
||||
" with/through the X11 clipboard.
|
||||
let @+ = test_call
|
||||
call system(run_vimtest)
|
||||
call assert_equal(test_response, @+)
|
||||
|
||||
let @+ = quoteplus_saved
|
||||
endif
|
||||
|
||||
if !empty(skipped)
|
||||
throw skipped
|
||||
endif
|
||||
endfunc
|
||||
|
||||
func Test_set_guifont()
|
||||
let skipped = ''
|
||||
|
||||
|
||||
@@ -15,7 +15,10 @@ func TearDown()
|
||||
call GUITearDownCommon()
|
||||
endfunc
|
||||
|
||||
" Make sure that the tests will be done with the GUI activated.
|
||||
" Ignore the "failed to create input context" error.
|
||||
call test_ignore_error('E285')
|
||||
|
||||
" Start the GUI now, in the foreground.
|
||||
gui -f
|
||||
|
||||
func Test_set_guiheadroom()
|
||||
|
||||
@@ -217,3 +217,19 @@ func Test_list_with_listchars()
|
||||
call s:compare_lines(expect, lines)
|
||||
call s:close_windows()
|
||||
endfunc
|
||||
|
||||
func Test_list_with_tab_and_skipping_first_chars()
|
||||
call s:test_windows('setl list listchars=tab:>- ts=70 nowrap')
|
||||
call setline(1, ["iiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa", "iiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiiii\taaaaaaaaaaaaaaaaaa"])
|
||||
call cursor(4,64)
|
||||
norm! 2zl
|
||||
let lines = s:screen_lines([1, 4], winwidth(0))
|
||||
let expect = [
|
||||
\ "---------------aaaaa",
|
||||
\ "---------------aaaaa",
|
||||
\ "---------------aaaaa",
|
||||
\ "iiiiiiiii>-----aaaaa",
|
||||
\ ]
|
||||
call s:compare_lines(expect, lines)
|
||||
call s:close_windows()
|
||||
endfu
|
||||
|
||||
@@ -193,3 +193,64 @@ func Test_multibyte_sign_and_colorcolumn()
|
||||
call s:compare_lines(expect, lines)
|
||||
call s:close_windows()
|
||||
endfunc
|
||||
|
||||
func Test_illegal_byte_and_breakat()
|
||||
call s:test_windows("setl sbr= brk+=<")
|
||||
vert resize 18
|
||||
call setline(1, repeat("\x80", 6))
|
||||
redraw!
|
||||
let lines = s:screen_lines([1, 2], winwidth(0))
|
||||
let expect = [
|
||||
\ "<80><80><80><80><8",
|
||||
\ "0><80> ",
|
||||
\ ]
|
||||
call s:compare_lines(expect, lines)
|
||||
call s:close_windows('setl brk&vim')
|
||||
endfunc
|
||||
|
||||
func Test_multibyte_wrap_and_breakat()
|
||||
call s:test_windows("setl sbr= brk+=>")
|
||||
call setline(1, repeat('a', 17) . repeat('あ', 2))
|
||||
redraw!
|
||||
let lines = s:screen_lines([1, 2], winwidth(0))
|
||||
let expect = [
|
||||
\ "aaaaaaaaaaaaaaaaaあ>",
|
||||
\ "あ ",
|
||||
\ ]
|
||||
call s:compare_lines(expect, lines)
|
||||
call s:close_windows('setl brk&vim')
|
||||
endfunc
|
||||
|
||||
func Test_chinese_char_on_wrap_column()
|
||||
call s:test_windows("setl nolbr wrap sbr=")
|
||||
syntax off
|
||||
call setline(1, [
|
||||
\ 'aaaaaaaaaaaaaaaaaaa中'.
|
||||
\ 'aaaaaaaaaaaaaaaaa中'.
|
||||
\ 'aaaaaaaaaaaaaaaaa中'.
|
||||
\ 'aaaaaaaaaaaaaaaaa中'.
|
||||
\ 'aaaaaaaaaaaaaaaaa中'.
|
||||
\ 'aaaaaaaaaaaaaaaaa中'.
|
||||
\ 'aaaaaaaaaaaaaaaaa中'.
|
||||
\ 'aaaaaaaaaaaaaaaaa中'.
|
||||
\ 'aaaaaaaaaaaaaaaaa中'.
|
||||
\ 'aaaaaaaaaaaaaaaaa中'.
|
||||
\ 'hello'])
|
||||
call cursor(1,1)
|
||||
norm! $
|
||||
redraw!
|
||||
let expect=[
|
||||
\ '中aaaaaaaaaaaaaaaaa>',
|
||||
\ '中aaaaaaaaaaaaaaaaa>',
|
||||
\ '中aaaaaaaaaaaaaaaaa>',
|
||||
\ '中aaaaaaaaaaaaaaaaa>',
|
||||
\ '中aaaaaaaaaaaaaaaaa>',
|
||||
\ '中aaaaaaaaaaaaaaaaa>',
|
||||
\ '中aaaaaaaaaaaaaaaaa>',
|
||||
\ '中aaaaaaaaaaaaaaaaa>',
|
||||
\ '中aaaaaaaaaaaaaaaaa>',
|
||||
\ '中hello ']
|
||||
let lines = s:screen_lines([1, 10], winwidth(0))
|
||||
call s:compare_lines(expect, lines)
|
||||
call s:close_windows()
|
||||
endfu
|
||||
|
||||
@@ -128,6 +128,14 @@ func XlistTests(cchar)
|
||||
let l = split(result, "\n")
|
||||
call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
|
||||
\ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
|
||||
|
||||
" Test for '+'
|
||||
redir => result
|
||||
Xlist! +2
|
||||
redir END
|
||||
let l = split(result, "\n")
|
||||
call assert_equal([' 2 Xtestfile1:1 col 3: Line1',
|
||||
\ ' 3: non-error 2', ' 4 Xtestfile2:2 col 2: Line2'], l)
|
||||
endfunc
|
||||
|
||||
func Test_clist()
|
||||
@@ -925,6 +933,11 @@ func Test_efm2()
|
||||
\ "(67,3) warning: 's' already defined"
|
||||
\]
|
||||
set efm=%+P[%f],(%l\\,%c)%*[\ ]%t%*[^:]:\ %m,%-Q
|
||||
" To exercise the push/pop file functionality in quickfix, the test files
|
||||
" need to be created.
|
||||
call writefile(['Line1'], 'Xtestfile1')
|
||||
call writefile(['Line2'], 'Xtestfile2')
|
||||
call writefile(['Line3'], 'Xtestfile3')
|
||||
cexpr ""
|
||||
for l in lines
|
||||
caddexpr l
|
||||
@@ -935,6 +948,9 @@ func Test_efm2()
|
||||
call assert_equal(2, l[2].col)
|
||||
call assert_equal('w', l[2].type)
|
||||
call assert_equal('e', l[3].type)
|
||||
call delete('Xtestfile1')
|
||||
call delete('Xtestfile2')
|
||||
call delete('Xtestfile3')
|
||||
|
||||
" Tests for %E, %C and %Z format specifiers
|
||||
let lines = ["Error 275",
|
||||
@@ -1369,11 +1385,25 @@ func Test_switchbuf()
|
||||
call assert_equal(2, winnr('$'))
|
||||
call assert_equal(1, bufwinnr('Xqftestfile3'))
|
||||
|
||||
" If only quickfix window is open in the current tabpage, jumping to an
|
||||
" entry with 'switchubf' set to 'usetab' should search in other tabpages.
|
||||
enew | only
|
||||
set switchbuf=usetab
|
||||
tabedit Xqftestfile1
|
||||
tabedit Xqftestfile2
|
||||
tabedit Xqftestfile3
|
||||
tabfirst
|
||||
copen | only
|
||||
clast
|
||||
call assert_equal(4, tabpagenr())
|
||||
tabfirst | tabonly | enew | only
|
||||
|
||||
call delete('Xqftestfile1')
|
||||
call delete('Xqftestfile2')
|
||||
call delete('Xqftestfile3')
|
||||
set switchbuf&vim
|
||||
|
||||
enew | only
|
||||
endfunc
|
||||
|
||||
func Xadjust_qflnum(cchar)
|
||||
@@ -1691,3 +1721,56 @@ func Test_dirstack_cleanup()
|
||||
caddbuffer
|
||||
let &efm = save_efm
|
||||
endfunc
|
||||
|
||||
" Tests for jumping to entries from the location list window and quickfix
|
||||
" window
|
||||
func Test_cwindow_jump()
|
||||
set efm=%f%%%l%%%m
|
||||
lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
|
||||
lopen | only
|
||||
lfirst
|
||||
call assert_true(winnr('$') == 2)
|
||||
call assert_true(winnr() == 1)
|
||||
" Location list for the new window should be set
|
||||
call assert_true(getloclist(0)[2].text == 'Line 30')
|
||||
|
||||
" Open a scratch buffer
|
||||
" Open a new window and create a location list
|
||||
" Open the location list window and close the other window
|
||||
" Jump to an entry.
|
||||
" Should create a new window and jump to the entry. The scrtach buffer
|
||||
" should not be used.
|
||||
enew | only
|
||||
set buftype=nofile
|
||||
below new
|
||||
lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
|
||||
lopen
|
||||
2wincmd c
|
||||
lnext
|
||||
call assert_true(winnr('$') == 3)
|
||||
call assert_true(winnr() == 2)
|
||||
|
||||
" Open two windows with two different location lists
|
||||
" Open the location list window and close the previous window
|
||||
" Jump to an entry in the location list window
|
||||
" Should open the file in the first window and not set the location list.
|
||||
enew | only
|
||||
lgetexpr ["F1%5%Line 5"]
|
||||
below new
|
||||
lgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
|
||||
lopen
|
||||
2wincmd c
|
||||
lnext
|
||||
call assert_true(winnr() == 1)
|
||||
call assert_true(getloclist(0)[0].text == 'Line 5')
|
||||
|
||||
enew | only
|
||||
cgetexpr ["F1%10%Line 10", "F2%20%Line 20", "F3%30%Line 30"]
|
||||
copen
|
||||
cnext
|
||||
call assert_true(winnr('$') == 2)
|
||||
call assert_true(winnr() == 1)
|
||||
|
||||
enew | only
|
||||
set efm&vim
|
||||
endfunc
|
||||
|
||||
@@ -294,3 +294,10 @@ func Test_searchpair()
|
||||
q!
|
||||
endfunc
|
||||
|
||||
func Test_searchc()
|
||||
" These commands used to cause memory overflow in searchc().
|
||||
new
|
||||
norm ixx
|
||||
exe "norm 0t\u93cf"
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
@@ -183,3 +183,17 @@ func Test_read_stdin()
|
||||
endif
|
||||
call delete('Xtestout')
|
||||
endfunc
|
||||
|
||||
func Test_progpath()
|
||||
" Tests normally run with "./vim" or "../vim", these must have been expanded
|
||||
" to a full path.
|
||||
if has('unix')
|
||||
call assert_equal('/', v:progpath[0])
|
||||
elseif has('win32')
|
||||
call assert_equal(':', v:progpath[1])
|
||||
call assert_match('[/\\]', v:progpath[2])
|
||||
endif
|
||||
|
||||
" Only expect "vim" to appear in v:progname.
|
||||
call assert_match('vim\c', v:progname)
|
||||
endfunc
|
||||
|
||||
@@ -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
|
||||
|
||||
12
src/undo.c
12
src/undo.c
@@ -1385,7 +1385,7 @@ unserialize_uep(bufinfo_T *bi, int *error, char_u *file_name)
|
||||
{
|
||||
int i;
|
||||
u_entry_T *uep;
|
||||
char_u **array;
|
||||
char_u **array = NULL;
|
||||
char_u *line;
|
||||
int line_len;
|
||||
|
||||
@@ -1402,7 +1402,8 @@ unserialize_uep(bufinfo_T *bi, int *error, char_u *file_name)
|
||||
uep->ue_size = undo_read_4c(bi);
|
||||
if (uep->ue_size > 0)
|
||||
{
|
||||
array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
|
||||
if (uep->ue_size < LONG_MAX / (int)sizeof(char_u *))
|
||||
array = (char_u **)U_ALLOC_LINE(sizeof(char_u *) * uep->ue_size);
|
||||
if (array == NULL)
|
||||
{
|
||||
*error = TRUE;
|
||||
@@ -1410,8 +1411,6 @@ unserialize_uep(bufinfo_T *bi, int *error, char_u *file_name)
|
||||
}
|
||||
vim_memset(array, 0, sizeof(char_u *) * uep->ue_size);
|
||||
}
|
||||
else
|
||||
array = NULL;
|
||||
uep->ue_array = array;
|
||||
|
||||
for (i = 0; i < uep->ue_size; ++i)
|
||||
@@ -1787,7 +1786,7 @@ u_read_undo(char_u *name, char_u *hash, char_u *orig_name)
|
||||
linenr_T line_lnum;
|
||||
colnr_T line_colnr;
|
||||
linenr_T line_count;
|
||||
int num_head = 0;
|
||||
long num_head = 0;
|
||||
long old_header_seq, new_header_seq, cur_header_seq;
|
||||
long seq_last, seq_cur;
|
||||
long last_save_nr = 0;
|
||||
@@ -1974,7 +1973,8 @@ u_read_undo(char_u *name, char_u *hash, char_u *orig_name)
|
||||
* When there are no headers uhp_table is NULL. */
|
||||
if (num_head > 0)
|
||||
{
|
||||
uhp_table = (u_header_T **)U_ALLOC_LINE(
|
||||
if (num_head < LONG_MAX / (long)sizeof(u_header_T *))
|
||||
uhp_table = (u_header_T **)U_ALLOC_LINE(
|
||||
num_head * sizeof(u_header_T *));
|
||||
if (uhp_table == NULL)
|
||||
goto error;
|
||||
|
||||
@@ -764,6 +764,68 @@ static char *(features[]) =
|
||||
|
||||
static int included_patches[] =
|
||||
{ /* Add new patch number below this line */
|
||||
/**/
|
||||
405,
|
||||
/**/
|
||||
404,
|
||||
/**/
|
||||
403,
|
||||
/**/
|
||||
402,
|
||||
/**/
|
||||
401,
|
||||
/**/
|
||||
400,
|
||||
/**/
|
||||
399,
|
||||
/**/
|
||||
398,
|
||||
/**/
|
||||
397,
|
||||
/**/
|
||||
396,
|
||||
/**/
|
||||
395,
|
||||
/**/
|
||||
394,
|
||||
/**/
|
||||
393,
|
||||
/**/
|
||||
392,
|
||||
/**/
|
||||
391,
|
||||
/**/
|
||||
390,
|
||||
/**/
|
||||
389,
|
||||
/**/
|
||||
388,
|
||||
/**/
|
||||
387,
|
||||
/**/
|
||||
386,
|
||||
/**/
|
||||
385,
|
||||
/**/
|
||||
384,
|
||||
/**/
|
||||
383,
|
||||
/**/
|
||||
382,
|
||||
/**/
|
||||
381,
|
||||
/**/
|
||||
380,
|
||||
/**/
|
||||
379,
|
||||
/**/
|
||||
378,
|
||||
/**/
|
||||
377,
|
||||
/**/
|
||||
376,
|
||||
/**/
|
||||
375,
|
||||
/**/
|
||||
374,
|
||||
/**/
|
||||
|
||||
Reference in New Issue
Block a user