aboutsummaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJustin M. Keyes <justinkz@gmail.com>2018-01-15 22:42:52 +0100
committerJustin M. Keyes <justinkz@gmail.com>2018-01-15 22:42:52 +0100
commit726197d8907891eda99299a2920b0d1d98148a3c (patch)
tree4345e1beaa8e9f5856bf1278679dfb8b22da044f /src
parentf09a30d5b0abb8f12d2e6a10cebaf87ca11aa135 (diff)
parentb9f3805447f9e0ff277aa655dfb9513f41db5ce6 (diff)
downloadrneovim-726197d8907891eda99299a2920b0d1d98148a3c.tar.gz
rneovim-726197d8907891eda99299a2920b0d1d98148a3c.tar.bz2
rneovim-726197d8907891eda99299a2920b0d1d98148a3c.zip
Merge #7850 'vim patches'
Diffstat (limited to 'src')
-rw-r--r--src/nvim/arabic.c1070
-rw-r--r--src/nvim/screen.c26
-rw-r--r--src/nvim/testdir/Makefile1
-rw-r--r--src/nvim/testdir/test_arabic.vim472
-rw-r--r--src/nvim/testdir/test_diffmode.vim75
-rw-r--r--src/nvim/testdir/test_listlbr_utf8.vim27
6 files changed, 799 insertions, 872 deletions
diff --git a/src/nvim/arabic.c b/src/nvim/arabic.c
index 1ef51d2a2a..e120e6d492 100644
--- a/src/nvim/arabic.c
+++ b/src/nvim/arabic.c
@@ -393,491 +393,141 @@ static bool A_is_f(int cur_c)
// Change shape - from ISO-8859-6/Isolated to Form-B Isolated
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;
}
// Change shape - from ISO-8859-6/Isolated to Initial
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_HAMZA: // exceptions
- tempc = a_s_HAMZA;
- break;
-
- case a_ALEF_MADDA: // exceptions
- tempc = a_s_ALEF_MADDA;
- break;
-
- case a_ALEF_HAMZA_ABOVE: // exceptions
- tempc = a_s_ALEF_HAMZA_ABOVE;
- break;
-
- case a_WAW_HAMZA: // exceptions
- tempc = a_s_WAW_HAMZA;
- break;
-
- case a_ALEF_HAMZA_BELOW: // exceptions
- tempc = a_s_ALEF_HAMZA_BELOW;
- break;
-
- case a_ALEF: // exceptions
- tempc = a_s_ALEF;
- break;
-
- case a_TEH_MARBUTA: // exceptions
- tempc = a_s_TEH_MARBUTA;
- break;
-
- case a_DAL: // exceptions
- tempc = a_s_DAL;
- break;
-
- case a_THAL: // exceptions
- tempc = a_s_THAL;
- break;
-
- case a_REH: // exceptions
- tempc = a_s_REH;
- break;
-
- case a_ZAIN: // exceptions
- tempc = a_s_ZAIN;
- break;
-
- case a_TATWEEL: // exceptions
- tempc = cur_c;
- break;
-
- case a_WAW: // exceptions
- tempc = a_s_WAW;
- break;
-
- 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;
+ case a_YEH_HAMZA: return a_i_YEH_HAMZA;
+ case a_HAMZA: return a_s_HAMZA; // exceptions
+ case a_ALEF_MADDA: return a_s_ALEF_MADDA; // exceptions
+ case a_ALEF_HAMZA_ABOVE: return a_s_ALEF_HAMZA_ABOVE; // exceptions
+ case a_WAW_HAMZA: return a_s_WAW_HAMZA; // exceptions
+ case a_ALEF_HAMZA_BELOW: return a_s_ALEF_HAMZA_BELOW; // exceptions
+ case a_ALEF: return a_s_ALEF; // exceptions
+ case a_TEH_MARBUTA: return a_s_TEH_MARBUTA; // exceptions
+ case a_DAL: return a_s_DAL; // exceptions
+ case a_THAL: return a_s_THAL; // exceptions
+ case a_REH: return a_s_REH; // exceptions
+ case a_ZAIN: return a_s_ZAIN; // exceptions
+ case a_TATWEEL: return cur_c; // exceptions
+ case a_WAW: return a_s_WAW; // exceptions
+ case a_ALEF_MAKSURA: return a_s_ALEF_MAKSURA; // exceptions
+ 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;
}
// Change shape - from ISO-8859-6/Isolated to Medial
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;
}
// Change shape - from ISO-8859-6/Isolated to final
static int chg_c_a2f(int cur_c)
{
- int tempc;
-
// NOTE: these encodings need to be accounted for
//
// a_f_ALEF_MADDA;
@@ -888,280 +538,87 @@ static int chg_c_a2f(int cur_c)
// a_f_LAM_ALEF_HAMZA_BELOW;
switch (cur_c) {
- case a_HAMZA: // exception
- tempc = a_s_HAMZA;
- break;
-
- case a_ALEF_MADDA:
- tempc = a_f_ALEF_MADDA;
- break;
-
- case a_ALEF_HAMZA_ABOVE:
- tempc = a_f_ALEF_HAMZA_ABOVE;
- break;
-
- case a_WAW_HAMZA:
- tempc = a_f_WAW_HAMZA;
- break;
-
- case a_ALEF_HAMZA_BELOW:
- tempc = a_f_ALEF_HAMZA_BELOW;
- break;
-
- case a_YEH_HAMZA:
- tempc = a_f_YEH_HAMZA;
- break;
-
- case a_ALEF:
- tempc = a_f_ALEF;
- break;
-
- case a_BEH:
- tempc = a_f_BEH;
- break;
-
- case a_TEH_MARBUTA:
- tempc = a_f_TEH_MARBUTA;
- break;
-
- case a_TEH:
- tempc = a_f_TEH;
- break;
-
- case a_THEH:
- tempc = a_f_THEH;
- break;
-
- case a_JEEM:
- tempc = a_f_JEEM;
- break;
-
- case a_HAH:
- tempc = a_f_HAH;
- break;
-
- case a_KHAH:
- tempc = a_f_KHAH;
- break;
-
- case a_DAL:
- tempc = a_f_DAL;
- break;
-
- case a_THAL:
- tempc = a_f_THAL;
- break;
-
- case a_REH:
- tempc = a_f_REH;
- break;
-
- case a_ZAIN:
- tempc = a_f_ZAIN;
- break;
-
- case a_SEEN:
- tempc = a_f_SEEN;
- break;
-
- case a_SHEEN:
- tempc = a_f_SHEEN;
- break;
-
- case a_SAD:
- tempc = a_f_SAD;
- break;
-
- case a_DAD:
- tempc = a_f_DAD;
- break;
-
- case a_TAH:
- tempc = a_f_TAH;
- break;
-
- case a_ZAH:
- tempc = a_f_ZAH;
- break;
-
- case a_AIN:
- tempc = a_f_AIN;
- break;
-
- case a_GHAIN:
- tempc = a_f_GHAIN;
- break;
-
- case a_TATWEEL: // exception
- tempc = cur_c;
- break;
-
- case a_FEH:
- tempc = a_f_FEH;
- break;
-
- case a_QAF:
- tempc = a_f_QAF;
- break;
-
- case a_KAF:
- tempc = a_f_KAF;
- break;
-
- case a_LAM:
- tempc = a_f_LAM;
- break;
-
- case a_MEEM:
- tempc = a_f_MEEM;
- break;
-
- case a_NOON:
- tempc = a_f_NOON;
- break;
-
- case a_HEH:
- tempc = a_f_HEH;
- break;
-
- case a_WAW:
- tempc = a_f_WAW;
- break;
-
- case a_ALEF_MAKSURA:
- tempc = a_f_ALEF_MAKSURA;
- break;
-
- case a_YEH:
- tempc = a_f_YEH;
- break;
-
- default:
- tempc = 0;
+ case a_HAMZA: return a_s_HAMZA; // exception
+ case a_ALEF_MADDA: return a_f_ALEF_MADDA;
+ case a_ALEF_HAMZA_ABOVE: return a_f_ALEF_HAMZA_ABOVE;
+ case a_WAW_HAMZA: return a_f_WAW_HAMZA;
+ case a_ALEF_HAMZA_BELOW: return a_f_ALEF_HAMZA_BELOW;
+ case a_YEH_HAMZA: return a_f_YEH_HAMZA;
+ case a_ALEF: return a_f_ALEF;
+ case a_BEH: return a_f_BEH;
+ case a_TEH_MARBUTA: return a_f_TEH_MARBUTA;
+ case a_TEH: return a_f_TEH;
+ case a_THEH: return a_f_THEH;
+ case a_JEEM: return a_f_JEEM;
+ case a_HAH: return a_f_HAH;
+ case a_KHAH: return a_f_KHAH;
+ case a_DAL: return a_f_DAL;
+ case a_THAL: return a_f_THAL;
+ case a_REH: return a_f_REH;
+ case a_ZAIN: return a_f_ZAIN;
+ case a_SEEN: return a_f_SEEN;
+ case a_SHEEN: return a_f_SHEEN;
+ case a_SAD: return a_f_SAD;
+ case a_DAD: return a_f_DAD;
+ case a_TAH: return a_f_TAH;
+ case a_ZAH: return a_f_ZAH;
+ case a_AIN: return a_f_AIN;
+ case a_GHAIN: return a_f_GHAIN;
+ case a_TATWEEL: return cur_c; // exception
+ case a_FEH: return a_f_FEH;
+ case a_QAF: return a_f_QAF;
+ case a_KAF: return a_f_KAF;
+ case a_LAM: return a_f_LAM;
+ case a_MEEM: return a_f_MEEM;
+ case a_NOON: return a_f_NOON;
+ case a_HEH: return a_f_HEH;
+ case a_WAW: return a_f_WAW;
+ case a_ALEF_MAKSURA: return a_f_ALEF_MAKSURA;
+ case a_YEH: return a_f_YEH;
}
-
- return tempc;
+ return 0;
}
// Change shape - from Initial to Medial
static int chg_c_i2m(int cur_c)
{
- int tempc;
-
switch (cur_c) {
- case a_i_YEH_HAMZA:
- tempc = a_m_YEH_HAMZA;
- break;
-
- case a_i_BEH:
- tempc = a_m_BEH;
- break;
-
- case a_i_TEH:
- tempc = a_m_TEH;
- break;
-
- case a_i_THEH:
- tempc = a_m_THEH;
- break;
-
- case a_i_JEEM:
- tempc = a_m_JEEM;
- break;
-
- case a_i_HAH:
- tempc = a_m_HAH;
- break;
-
- case a_i_KHAH:
- tempc = a_m_KHAH;
- break;
-
- case a_i_SEEN:
- tempc = a_m_SEEN;
- break;
-
- case a_i_SHEEN:
- tempc = a_m_SHEEN;
- break;
-
- case a_i_SAD:
- tempc = a_m_SAD;
- break;
-
- case a_i_DAD:
- tempc = a_m_DAD;
- break;
-
- case a_i_TAH:
- tempc = a_m_TAH;
- break;
-
- case a_i_ZAH:
- tempc = a_m_ZAH;
- break;
-
- case a_i_AIN:
- tempc = a_m_AIN;
- break;
-
- case a_i_GHAIN:
- tempc = a_m_GHAIN;
- break;
-
- case a_i_FEH:
- tempc = a_m_FEH;
- break;
-
- case a_i_QAF:
- tempc = a_m_QAF;
- break;
-
- case a_i_KAF:
- tempc = a_m_KAF;
- break;
-
- case a_i_LAM:
- tempc = a_m_LAM;
- break;
-
- case a_i_MEEM:
- tempc = a_m_MEEM;
- break;
-
- case a_i_NOON:
- tempc = a_m_NOON;
- break;
-
- case a_i_HEH:
- tempc = a_m_HEH;
- break;
-
- case a_i_YEH:
- tempc = a_m_YEH;
- break;
-
- default:
- tempc = 0;
+ case a_i_YEH_HAMZA: return a_m_YEH_HAMZA;
+ case a_i_BEH: return a_m_BEH;
+ case a_i_TEH: return a_m_TEH;
+ case a_i_THEH: return a_m_THEH;
+ case a_i_JEEM: return a_m_JEEM;
+ case a_i_HAH: return a_m_HAH;
+ case a_i_KHAH: return a_m_KHAH;
+ case a_i_SEEN: return a_m_SEEN;
+ case a_i_SHEEN: return a_m_SHEEN;
+ case a_i_SAD: return a_m_SAD;
+ case a_i_DAD: return a_m_DAD;
+ case a_i_TAH: return a_m_TAH;
+ case a_i_ZAH: return a_m_ZAH;
+ case a_i_AIN: return a_m_AIN;
+ case a_i_GHAIN: return a_m_GHAIN;
+ case a_i_FEH: return a_m_FEH;
+ case a_i_QAF: return a_m_QAF;
+ case a_i_KAF: return a_m_KAF;
+ case a_i_LAM: return a_m_LAM;
+ case a_i_MEEM: return a_m_MEEM;
+ case a_i_NOON: return a_m_NOON;
+ case a_i_HEH: return a_m_HEH;
+ case a_i_YEH: return a_m_YEH;
}
-
- return tempc;
+ return 0;
}
// Change shape - from Final to Medial
static int chg_c_f2m(int cur_c)
{
- int tempc;
-
switch (cur_c) {
// NOTE: these encodings are multi-positional, no ?
// case a_f_ALEF_MADDA:
// case a_f_ALEF_HAMZA_ABOVE:
// case a_f_ALEF_HAMZA_BELOW:
- case a_f_YEH_HAMZA:
- tempc = a_m_YEH_HAMZA;
- break;
-
+ case a_f_YEH_HAMZA: return a_m_YEH_HAMZA;
case a_f_WAW_HAMZA: // exceptions
case a_f_ALEF:
case a_f_TEH_MARBUTA:
@@ -1171,165 +628,60 @@ static int chg_c_f2m(int cur_c)
case a_f_ZAIN:
case a_f_WAW:
case a_f_ALEF_MAKSURA:
- tempc = cur_c;
- break;
-
- case a_f_BEH:
- tempc = a_m_BEH;
- break;
-
- case a_f_TEH:
- tempc = a_m_TEH;
- break;
-
- case a_f_THEH:
- tempc = a_m_THEH;
- break;
-
- case a_f_JEEM:
- tempc = a_m_JEEM;
- break;
-
- case a_f_HAH:
- tempc = a_m_HAH;
- break;
-
- case a_f_KHAH:
- tempc = a_m_KHAH;
- break;
-
- case a_f_SEEN:
- tempc = a_m_SEEN;
- break;
-
- case a_f_SHEEN:
- tempc = a_m_SHEEN;
- break;
-
- case a_f_SAD:
- tempc = a_m_SAD;
- break;
-
- case a_f_DAD:
- tempc = a_m_DAD;
- break;
-
- case a_f_TAH:
- tempc = a_m_TAH;
- break;
-
- case a_f_ZAH:
- tempc = a_m_ZAH;
- break;
-
- case a_f_AIN:
- tempc = a_m_AIN;
- break;
-
- case a_f_GHAIN:
- tempc = a_m_GHAIN;
- break;
-
- case a_f_FEH:
- tempc = a_m_FEH;
- break;
-
- case a_f_QAF:
- tempc = a_m_QAF;
- break;
-
- case a_f_KAF:
- tempc = a_m_KAF;
- break;
-
- case a_f_LAM:
- tempc = a_m_LAM;
- break;
-
- case a_f_MEEM:
- tempc = a_m_MEEM;
- break;
-
- case a_f_NOON:
- tempc = a_m_NOON;
- break;
-
- case a_f_HEH:
- tempc = a_m_HEH;
- break;
-
- case a_f_YEH:
- tempc = a_m_YEH;
- break;
-
+ return cur_c;
+ case a_f_BEH: return a_m_BEH;
+ case a_f_TEH: return a_m_TEH;
+ case a_f_THEH: return a_m_THEH;
+ case a_f_JEEM: return a_m_JEEM;
+ case a_f_HAH: return a_m_HAH;
+ case a_f_KHAH: return a_m_KHAH;
+ case a_f_SEEN: return a_m_SEEN;
+ case a_f_SHEEN: return a_m_SHEEN;
+ case a_f_SAD: return a_m_SAD;
+ case a_f_DAD: return a_m_DAD;
+ case a_f_TAH: return a_m_TAH;
+ case a_f_ZAH: return a_m_ZAH;
+ case a_f_AIN: return a_m_AIN;
+ case a_f_GHAIN: return a_m_GHAIN;
+ case a_f_FEH: return a_m_FEH;
+ case a_f_QAF: return a_m_QAF;
+ case a_f_KAF: return a_m_KAF;
+ case a_f_LAM: return a_m_LAM;
+ case a_f_MEEM: return a_m_MEEM;
+ case a_f_NOON: return a_m_NOON;
+ case a_f_HEH: return a_m_HEH;
+ case a_f_YEH: return a_m_YEH;
// NOTE: these encodings are multi-positional, no ?
// case a_f_LAM_ALEF_MADDA_ABOVE:
// case a_f_LAM_ALEF_HAMZA_ABOVE:
// case a_f_LAM_ALEF_HAMZA_BELOW:
// case a_f_LAM_ALEF:
- default:
- tempc = 0;
}
-
- return tempc;
+ return 0;
}
// Change shape - from Combination (2 char) to an Isolated.
static int chg_c_laa2i(int hid_c)
{
- int tempc;
-
switch (hid_c) {
- case a_ALEF_MADDA:
- tempc = a_s_LAM_ALEF_MADDA_ABOVE;
- break;
-
- case a_ALEF_HAMZA_ABOVE:
- tempc = a_s_LAM_ALEF_HAMZA_ABOVE;
- break;
-
- case a_ALEF_HAMZA_BELOW:
- tempc = a_s_LAM_ALEF_HAMZA_BELOW;
- break;
-
- case a_ALEF:
- tempc = a_s_LAM_ALEF;
- break;
-
- default:
- tempc = 0;
+ case a_ALEF_MADDA: return a_s_LAM_ALEF_MADDA_ABOVE;
+ case a_ALEF_HAMZA_ABOVE: return a_s_LAM_ALEF_HAMZA_ABOVE;
+ case a_ALEF_HAMZA_BELOW: return a_s_LAM_ALEF_HAMZA_BELOW;
+ case a_ALEF: return a_s_LAM_ALEF;
}
-
- return tempc;
+ return 0;
}
// Change shape - from Combination-Isolated to Final.
static int chg_c_laa2f(int hid_c)
{
- int tempc;
-
switch (hid_c) {
- case a_ALEF_MADDA:
- tempc = a_f_LAM_ALEF_MADDA_ABOVE;
- break;
-
- case a_ALEF_HAMZA_ABOVE:
- tempc = a_f_LAM_ALEF_HAMZA_ABOVE;
- break;
-
- case a_ALEF_HAMZA_BELOW:
- tempc = a_f_LAM_ALEF_HAMZA_BELOW;
- break;
-
- case a_ALEF:
- tempc = a_f_LAM_ALEF;
- break;
-
- default:
- tempc = 0;
+ case a_ALEF_MADDA: return a_f_LAM_ALEF_MADDA_ABOVE;
+ case a_ALEF_HAMZA_ABOVE: return a_f_LAM_ALEF_HAMZA_ABOVE;
+ case a_ALEF_HAMZA_BELOW: return a_f_LAM_ALEF_HAMZA_BELOW;
+ case a_ALEF: return a_f_LAM_ALEF;
}
-
- return tempc;
+ return 0;
}
// Do "half-shaping" on character "c". Return zero if no shaping.
diff --git a/src/nvim/screen.c b/src/nvim/screen.c
index ed96e98d32..8a29734025 100644
--- a/src/nvim/screen.c
+++ b/src/nvim/screen.c
@@ -3143,14 +3143,15 @@ win_line (
}
--n_extra;
} else {
+ int c0;
+
if (p_extra_free != NULL) {
xfree(p_extra_free);
p_extra_free = NULL;
}
- /*
- * Get a character from the line itself.
- */
- c = *ptr;
+
+ // Get a character from the line itself.
+ c0 = c = *ptr;
if (has_mbyte) {
mb_c = c;
if (enc_utf8) {
@@ -3160,11 +3161,12 @@ win_line (
mb_utf8 = FALSE;
if (mb_l > 1) {
mb_c = utfc_ptr2char(ptr, u8cc);
- /* Overlong encoded ASCII or ASCII with composing char
- * is displayed normally, except a NUL. */
- if (mb_c < 0x80)
- c = mb_c;
- mb_utf8 = TRUE;
+ // Overlong encoded ASCII or ASCII with composing char
+ // is displayed normally, except a NUL.
+ if (mb_c < 0x80) {
+ c0 = c = mb_c;
+ }
+ mb_utf8 = true;
/* At start of the line we can have a composing char.
* Draw it as a space with a composing char. */
@@ -3428,10 +3430,8 @@ win_line (
char_attr = hl_combine_attr(char_attr, term_attrs[vcol]);
}
- /*
- * Found last space before word: check for line break.
- */
- if (wp->w_p_lbr && vim_isbreak(c) && !vim_isbreak(*ptr)) {
+ // Found last space before word: check for line break.
+ if (wp->w_p_lbr && c0 == c && vim_isbreak(c) && !vim_isbreak(*ptr)) {
int mb_off = has_mbyte ? (*mb_head_off)(line, ptr - 1) : 0;
char_u *p = ptr - (mb_off + 1);
// TODO: is passing p for start of the line OK?
diff --git a/src/nvim/testdir/Makefile b/src/nvim/testdir/Makefile
index a23dacba15..0c25945274 100644
--- a/src/nvim/testdir/Makefile
+++ b/src/nvim/testdir/Makefile
@@ -40,6 +40,7 @@ SCRIPTS ?= $(SCRIPTS_DEFAULT)
# Tests using runtest.vim.
# Keep test_alot*.res as the last one, sort the others.
NEW_TESTS ?= \
+ test_arabic.vim \
test_autocmd.res \
test_bufwintabinfo.res \
test_changedtick.res \
diff --git a/src/nvim/testdir/test_arabic.vim b/src/nvim/testdir/test_arabic.vim
new file mode 100644
index 0000000000..9a16833a4c
--- /dev/null
+++ b/src/nvim/testdir/test_arabic.vim
@@ -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
+
diff --git a/src/nvim/testdir/test_diffmode.vim b/src/nvim/testdir/test_diffmode.vim
index 88f73cdb5b..33617c9cbe 100644
--- a/src/nvim/testdir/test_diffmode.vim
+++ b/src/nvim/testdir/test_diffmode.vim
@@ -273,6 +273,81 @@ func Test_setting_cursor()
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
+
func Test_diff_lastline()
enew!
only!
diff --git a/src/nvim/testdir/test_listlbr_utf8.vim b/src/nvim/testdir/test_listlbr_utf8.vim
index 980d67d49d..56a4cc9b31 100644
--- a/src/nvim/testdir/test_listlbr_utf8.vim
+++ b/src/nvim/testdir/test_listlbr_utf8.vim
@@ -194,6 +194,33 @@ func Test_multibyte_sign_and_colorcolumn()
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