neovim

Neovim text editor
git clone https://git.dasho.dev/neovim.git
Log | Files | Refs | README

test_arabic.vim (17592B)


      1 " Simplistic testing of Arabic mode.
      2 " NOTE: This just checks if the code works. If you know Arabic please add
      3 " functional tests that check the shaping works with real text.
      4 
      5 source check.vim
      6 CheckFeature arabic
      7 
      8 source view_util.vim
      9 
     10 " Return list of Unicode characters at line lnum.
     11 " Combining characters are treated as a single item.
     12 func s:get_chars(lnum)
     13  call cursor(a:lnum, 1)
     14  let chars = []
     15  let numchars = strchars(getline('.'), 1)
     16  for i in range(1, numchars)
     17    exe 'norm ' i . '|'
     18    let c = execute('ascii')
     19    let c = substitute(c, '\n\?<.\{-}Hex\s*', 'U+', 'g')
     20    let c = substitute(c, ',\s*Oct\(al\)\=\s\d*\(, Digr ..\)\=', '', 'g')
     21    call add(chars, c)
     22  endfor
     23  return chars
     24 endfunc
     25 
     26 func Test_arabic_toggle()
     27  set arabic
     28  call assert_equal(1, &rightleft)
     29  call assert_equal(1, &arabicshape)
     30  call assert_equal('arabic', &keymap)
     31  call assert_equal(1, &delcombine)
     32 
     33  set iminsert=1 imsearch=1
     34  set arabic&
     35  call assert_equal(0, &rightleft)
     36  call assert_equal(1, &arabicshape)
     37  call assert_equal('arabic', &keymap)
     38  call assert_equal(1, &delcombine)
     39  call assert_equal(0, &iminsert)
     40  call assert_equal(-1, &imsearch)
     41 
     42  set arabicshape& keymap= delcombine&
     43 endfunc
     44 
     45 func Test_arabic_input()
     46  new
     47  set arabic
     48  " Typing sghl in Arabic insert mode should show the
     49  " Arabic word 'Salaam' i.e. 'peace', spelled:
     50  " SEEN, LAM, ALEF, MEEM.
     51  " See: https://www.mediawiki.org/wiki/VisualEditor/Typing/Right-to-left
     52  call feedkeys('isghl!', 'tx')
     53  call assert_match("^ *!\uFEE1\uFEFC\uFEB3$", ScreenLines(1, &columns)[0])
     54  call assert_equal([
     55  \ 'U+0633',
     56  \ 'U+0644 U+0627',
     57  \ 'U+0645',
     58  \ 'U+21'], s:get_chars(1))
     59 
     60  " Without shaping, it should give individual Arabic letters.
     61  set noarabicshape
     62  call assert_match("^ *!\u0645\u0627\u0644\u0633$", ScreenLines(1, &columns)[0])
     63  call assert_equal([
     64  \ 'U+0633',
     65  \ 'U+0644',
     66  \ 'U+0627',
     67  \ 'U+0645',
     68  \ 'U+21'], s:get_chars(1))
     69 
     70  set arabic& arabicshape&
     71  bwipe!
     72 endfunc
     73 
     74 func Test_arabic_toggle_keymap()
     75  new
     76  set arabic
     77  call feedkeys("i12\<C-^>12\<C-^>12abcd", 'tx')
     78  call assert_match("^ *.*ﺷ212121$", ScreenLines(1, &columns)[0])
     79  call assert_equal('121212شلاؤي', getline('.'))
     80  set arabic&
     81  bwipe!
     82 endfunc
     83 
     84 func Test_delcombine()
     85  new
     86  set arabic
     87  call feedkeys("isghl\<BS>\<BS>", 'tx')
     88  call assert_match("^ *\uFEDE\uFEB3$", ScreenLines(1, &columns)[0])
     89  call assert_equal(['U+0633', 'U+0644'], s:get_chars(1))
     90 
     91  " Now the same with 'nodelcombine'
     92  set nodelcombine
     93  %d
     94  call feedkeys("isghl\<BS>\<BS>", 'tx')
     95  call assert_match("^ *\uFEB1$", ScreenLines(1, &columns)[0])
     96  call assert_equal(['U+0633'], s:get_chars(1))
     97  set arabic&
     98  bwipe!
     99 endfunc
    100 
    101 " Values from src/arabic.h (not all used yet)
    102 let s:a_COMMA = "\u060C"
    103 let s:a_SEMICOLON = "\u061B"
    104 let s:a_QUESTION = "\u061F"
    105 let s:a_HAMZA = "\u0621"
    106 let s:a_ALEF_MADDA = "\u0622"
    107 let s:a_ALEF_HAMZA_ABOVE = "\u0623"
    108 let s:a_WAW_HAMZA = "\u0624"
    109 let s:a_ALEF_HAMZA_BELOW = "\u0625"
    110 let s:a_YEH_HAMZA = "\u0626"
    111 let s:a_ALEF = "\u0627"
    112 let s:a_BEH = "\u0628"
    113 let s:a_TEH_MARBUTA = "\u0629"
    114 let s:a_TEH = "\u062a"
    115 let s:a_THEH = "\u062b"
    116 let s:a_JEEM = "\u062c"
    117 let s:a_HAH = "\u062d"
    118 let s:a_KHAH = "\u062e"
    119 let s:a_DAL = "\u062f"
    120 let s:a_THAL = "\u0630"
    121 let s:a_REH = "\u0631"
    122 let s:a_ZAIN = "\u0632"
    123 let s:a_SEEN = "\u0633"
    124 let s:a_SHEEN = "\u0634"
    125 let s:a_SAD = "\u0635"
    126 let s:a_DAD = "\u0636"
    127 let s:a_TAH = "\u0637"
    128 let s:a_ZAH = "\u0638"
    129 let s:a_AIN = "\u0639"
    130 let s:a_GHAIN = "\u063a"
    131 let s:a_TATWEEL = "\u0640"
    132 let s:a_FEH = "\u0641"
    133 let s:a_QAF = "\u0642"
    134 let s:a_KAF = "\u0643"
    135 let s:a_LAM = "\u0644"
    136 let s:a_MEEM = "\u0645"
    137 let s:a_NOON = "\u0646"
    138 let s:a_HEH = "\u0647"
    139 let s:a_WAW = "\u0648"
    140 let s:a_ALEF_MAKSURA = "\u0649"
    141 let s:a_YEH = "\u064a"
    142 
    143 let s:a_FATHATAN = "\u064b"
    144 let s:a_DAMMATAN = "\u064c"
    145 let s:a_KASRATAN = "\u064d"
    146 let s:a_FATHA = "\u064e"
    147 let s:a_DAMMA = "\u064f"
    148 let s:a_KASRA = "\u0650"
    149 let s:a_SHADDA = "\u0651"
    150 let s:a_SUKUN = "\u0652"
    151 
    152 let s:a_MADDA_ABOVE = "\u0653"
    153 let s:a_HAMZA_ABOVE = "\u0654"
    154 let s:a_HAMZA_BELOW = "\u0655"
    155 
    156 let s:a_ZERO = "\u0660"
    157 let s:a_ONE = "\u0661"
    158 let s:a_TWO = "\u0662"
    159 let s:a_THREE = "\u0663"
    160 let s:a_FOUR = "\u0664"
    161 let s:a_FIVE = "\u0665"
    162 let s:a_SIX = "\u0666"
    163 let s:a_SEVEN = "\u0667"
    164 let s:a_EIGHT = "\u0668"
    165 let s:a_NINE = "\u0669"
    166 let s:a_PERCENT = "\u066a"
    167 let s:a_DECIMAL = "\u066b"
    168 let s:a_THOUSANDS = "\u066c"
    169 let s:a_STAR = "\u066d"
    170 let s:a_MINI_ALEF = "\u0670"
    171 
    172 let s:a_s_FATHATAN = "\ufe70"
    173 let s:a_m_TATWEEL_FATHATAN = "\ufe71"
    174 let s:a_s_DAMMATAN = "\ufe72"
    175 
    176 let s:a_s_KASRATAN = "\ufe74"
    177 
    178 let s:a_s_FATHA = "\ufe76"
    179 let s:a_m_FATHA = "\ufe77"
    180 let s:a_s_DAMMA = "\ufe78"
    181 let s:a_m_DAMMA = "\ufe79"
    182 let s:a_s_KASRA = "\ufe7a"
    183 let s:a_m_KASRA = "\ufe7b"
    184 let s:a_s_SHADDA = "\ufe7c"
    185 let s:a_m_SHADDA = "\ufe7d"
    186 let s:a_s_SUKUN = "\ufe7e"
    187 let s:a_m_SUKUN = "\ufe7f"
    188 
    189 let s:a_s_HAMZA = "\ufe80"
    190 let s:a_s_ALEF_MADDA = "\ufe81"
    191 let s:a_f_ALEF_MADDA = "\ufe82"
    192 let s:a_s_ALEF_HAMZA_ABOVE = "\ufe83"
    193 let s:a_f_ALEF_HAMZA_ABOVE = "\ufe84"
    194 let s:a_s_WAW_HAMZA = "\ufe85"
    195 let s:a_f_WAW_HAMZA = "\ufe86"
    196 let s:a_s_ALEF_HAMZA_BELOW = "\ufe87"
    197 let s:a_f_ALEF_HAMZA_BELOW = "\ufe88"
    198 let s:a_s_YEH_HAMZA = "\ufe89"
    199 let s:a_f_YEH_HAMZA = "\ufe8a"
    200 let s:a_i_YEH_HAMZA = "\ufe8b"
    201 let s:a_m_YEH_HAMZA = "\ufe8c"
    202 let s:a_s_ALEF = "\ufe8d"
    203 let s:a_f_ALEF = "\ufe8e"
    204 let s:a_s_BEH = "\ufe8f"
    205 let s:a_f_BEH = "\ufe90"
    206 let s:a_i_BEH = "\ufe91"
    207 let s:a_m_BEH = "\ufe92"
    208 let s:a_s_TEH_MARBUTA = "\ufe93"
    209 let s:a_f_TEH_MARBUTA = "\ufe94"
    210 let s:a_s_TEH = "\ufe95"
    211 let s:a_f_TEH = "\ufe96"
    212 let s:a_i_TEH = "\ufe97"
    213 let s:a_m_TEH = "\ufe98"
    214 let s:a_s_THEH = "\ufe99"
    215 let s:a_f_THEH = "\ufe9a"
    216 let s:a_i_THEH = "\ufe9b"
    217 let s:a_m_THEH = "\ufe9c"
    218 let s:a_s_JEEM = "\ufe9d"
    219 let s:a_f_JEEM = "\ufe9e"
    220 let s:a_i_JEEM = "\ufe9f"
    221 let s:a_m_JEEM = "\ufea0"
    222 let s:a_s_HAH = "\ufea1"
    223 let s:a_f_HAH = "\ufea2"
    224 let s:a_i_HAH = "\ufea3"
    225 let s:a_m_HAH = "\ufea4"
    226 let s:a_s_KHAH = "\ufea5"
    227 let s:a_f_KHAH = "\ufea6"
    228 let s:a_i_KHAH = "\ufea7"
    229 let s:a_m_KHAH = "\ufea8"
    230 let s:a_s_DAL = "\ufea9"
    231 let s:a_f_DAL = "\ufeaa"
    232 let s:a_s_THAL = "\ufeab"
    233 let s:a_f_THAL = "\ufeac"
    234 let s:a_s_REH = "\ufead"
    235 let s:a_f_REH = "\ufeae"
    236 let s:a_s_ZAIN = "\ufeaf"
    237 let s:a_f_ZAIN = "\ufeb0"
    238 let s:a_s_SEEN = "\ufeb1"
    239 let s:a_f_SEEN = "\ufeb2"
    240 let s:a_i_SEEN = "\ufeb3"
    241 let s:a_m_SEEN = "\ufeb4"
    242 let s:a_s_SHEEN = "\ufeb5"
    243 let s:a_f_SHEEN = "\ufeb6"
    244 let s:a_i_SHEEN = "\ufeb7"
    245 let s:a_m_SHEEN = "\ufeb8"
    246 let s:a_s_SAD = "\ufeb9"
    247 let s:a_f_SAD = "\ufeba"
    248 let s:a_i_SAD = "\ufebb"
    249 let s:a_m_SAD = "\ufebc"
    250 let s:a_s_DAD = "\ufebd"
    251 let s:a_f_DAD = "\ufebe"
    252 let s:a_i_DAD = "\ufebf"
    253 let s:a_m_DAD = "\ufec0"
    254 let s:a_s_TAH = "\ufec1"
    255 let s:a_f_TAH = "\ufec2"
    256 let s:a_i_TAH = "\ufec3"
    257 let s:a_m_TAH = "\ufec4"
    258 let s:a_s_ZAH = "\ufec5"
    259 let s:a_f_ZAH = "\ufec6"
    260 let s:a_i_ZAH = "\ufec7"
    261 let s:a_m_ZAH = "\ufec8"
    262 let s:a_s_AIN = "\ufec9"
    263 let s:a_f_AIN = "\ufeca"
    264 let s:a_i_AIN = "\ufecb"
    265 let s:a_m_AIN = "\ufecc"
    266 let s:a_s_GHAIN = "\ufecd"
    267 let s:a_f_GHAIN = "\ufece"
    268 let s:a_i_GHAIN = "\ufecf"
    269 let s:a_m_GHAIN = "\ufed0"
    270 let s:a_s_FEH = "\ufed1"
    271 let s:a_f_FEH = "\ufed2"
    272 let s:a_i_FEH = "\ufed3"
    273 let s:a_m_FEH = "\ufed4"
    274 let s:a_s_QAF = "\ufed5"
    275 let s:a_f_QAF = "\ufed6"
    276 let s:a_i_QAF = "\ufed7"
    277 let s:a_m_QAF = "\ufed8"
    278 let s:a_s_KAF = "\ufed9"
    279 let s:a_f_KAF = "\ufeda"
    280 let s:a_i_KAF = "\ufedb"
    281 let s:a_m_KAF = "\ufedc"
    282 let s:a_s_LAM = "\ufedd"
    283 let s:a_f_LAM = "\ufede"
    284 let s:a_i_LAM = "\ufedf"
    285 let s:a_m_LAM = "\ufee0"
    286 let s:a_s_MEEM = "\ufee1"
    287 let s:a_f_MEEM = "\ufee2"
    288 let s:a_i_MEEM = "\ufee3"
    289 let s:a_m_MEEM = "\ufee4"
    290 let s:a_s_NOON = "\ufee5"
    291 let s:a_f_NOON = "\ufee6"
    292 let s:a_i_NOON = "\ufee7"
    293 let s:a_m_NOON = "\ufee8"
    294 let s:a_s_HEH = "\ufee9"
    295 let s:a_f_HEH = "\ufeea"
    296 let s:a_i_HEH = "\ufeeb"
    297 let s:a_m_HEH = "\ufeec"
    298 let s:a_s_WAW = "\ufeed"
    299 let s:a_f_WAW = "\ufeee"
    300 let s:a_s_ALEF_MAKSURA = "\ufeef"
    301 let s:a_f_ALEF_MAKSURA = "\ufef0"
    302 let s:a_s_YEH = "\ufef1"
    303 let s:a_f_YEH = "\ufef2"
    304 let s:a_i_YEH = "\ufef3"
    305 let s:a_m_YEH = "\ufef4"
    306 let s:a_s_LAM_ALEF_MADDA_ABOVE = "\ufef5"
    307 let s:a_f_LAM_ALEF_MADDA_ABOVE = "\ufef6"
    308 let s:a_s_LAM_ALEF_HAMZA_ABOVE = "\ufef7"
    309 let s:a_f_LAM_ALEF_HAMZA_ABOVE = "\ufef8"
    310 let s:a_s_LAM_ALEF_HAMZA_BELOW = "\ufef9"
    311 let s:a_f_LAM_ALEF_HAMZA_BELOW = "\ufefa"
    312 let s:a_s_LAM_ALEF = "\ufefb"
    313 let s:a_f_LAM_ALEF = "\ufefc"
    314 
    315 let s:a_BYTE_ORDER_MARK = "\ufeff"
    316 
    317 func Test_shape_initial()
    318  new
    319  set arabicshape
    320 
    321  " Shaping arabic {testchar} non-arabic   Tests chg_c_a2i().
    322  " pair[0] = testchar, pair[1] = next-result, pair[2] = current-result
    323  for pair in [[s:a_YEH_HAMZA, s:a_f_GHAIN, s:a_i_YEH_HAMZA],
    324 \ [s:a_HAMZA, s:a_s_GHAIN, s:a_s_HAMZA],
    325 \ [s:a_ALEF_MADDA, s:a_s_GHAIN, s:a_s_ALEF_MADDA],
    326 \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_GHAIN, s:a_s_ALEF_HAMZA_ABOVE],
    327 \ [s:a_WAW_HAMZA, s:a_s_GHAIN, s:a_s_WAW_HAMZA],
    328 \ [s:a_ALEF_HAMZA_BELOW, s:a_s_GHAIN, s:a_s_ALEF_HAMZA_BELOW],
    329 \ [s:a_ALEF, s:a_s_GHAIN, s:a_s_ALEF],
    330 \ [s:a_TEH_MARBUTA, s:a_s_GHAIN, s:a_s_TEH_MARBUTA],
    331 \ [s:a_DAL, s:a_s_GHAIN, s:a_s_DAL],
    332 \ [s:a_THAL, s:a_s_GHAIN, s:a_s_THAL],
    333 \ [s:a_REH, s:a_s_GHAIN, s:a_s_REH],
    334 \ [s:a_ZAIN, s:a_s_GHAIN, s:a_s_ZAIN],
    335 \ [s:a_TATWEEL, s:a_f_GHAIN, s:a_TATWEEL],
    336 \ [s:a_WAW, s:a_s_GHAIN, s:a_s_WAW],
    337 \ [s:a_ALEF_MAKSURA, s:a_s_GHAIN, s:a_s_ALEF_MAKSURA],
    338 \ [s:a_BEH, s:a_f_GHAIN, s:a_i_BEH],
    339 \ [s:a_TEH, s:a_f_GHAIN, s:a_i_TEH],
    340 \ [s:a_THEH, s:a_f_GHAIN, s:a_i_THEH],
    341 \ [s:a_JEEM, s:a_f_GHAIN, s:a_i_JEEM],
    342 \ [s:a_HAH, s:a_f_GHAIN, s:a_i_HAH],
    343 \ [s:a_KHAH, s:a_f_GHAIN, s:a_i_KHAH],
    344 \ [s:a_SEEN, s:a_f_GHAIN, s:a_i_SEEN],
    345 \ [s:a_SHEEN, s:a_f_GHAIN, s:a_i_SHEEN],
    346 \ [s:a_SAD, s:a_f_GHAIN, s:a_i_SAD],
    347 \ [s:a_DAD, s:a_f_GHAIN, s:a_i_DAD],
    348 \ [s:a_TAH, s:a_f_GHAIN, s:a_i_TAH],
    349 \ [s:a_ZAH, s:a_f_GHAIN, s:a_i_ZAH],
    350 \ [s:a_AIN, s:a_f_GHAIN, s:a_i_AIN],
    351 \ [s:a_GHAIN, s:a_f_GHAIN, s:a_i_GHAIN],
    352 \ [s:a_FEH, s:a_f_GHAIN, s:a_i_FEH],
    353 \ [s:a_QAF, s:a_f_GHAIN, s:a_i_QAF],
    354 \ [s:a_KAF, s:a_f_GHAIN, s:a_i_KAF],
    355 \ [s:a_LAM, s:a_f_GHAIN, s:a_i_LAM],
    356 \ [s:a_MEEM, s:a_f_GHAIN, s:a_i_MEEM],
    357 \ [s:a_NOON, s:a_f_GHAIN, s:a_i_NOON],
    358 \ [s:a_HEH, s:a_f_GHAIN, s:a_i_HEH],
    359 \ [s:a_YEH, s:a_f_GHAIN, s:a_i_YEH],
    360 \ ]
    361    call setline(1, s:a_GHAIN . pair[0] . ' ')
    362    call assert_equal([pair[1] . pair[2] . ' '], ScreenLines(1, 3))
    363  endfor
    364 
    365  set arabicshape&
    366  bwipe!
    367 endfunc
    368 
    369 func Test_shape_isolated()
    370  new
    371  set arabicshape
    372 
    373  " Shaping non-arabic {testchar} non-arabic   Tests chg_c_a2s().
    374  " pair[0] = testchar, pair[1] = current-result
    375  for pair in [[s:a_HAMZA, s:a_s_HAMZA],
    376 \ [s:a_ALEF_MADDA, s:a_s_ALEF_MADDA],
    377 \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_ALEF_HAMZA_ABOVE],
    378 \ [s:a_WAW_HAMZA, s:a_s_WAW_HAMZA],
    379 \ [s:a_ALEF_HAMZA_BELOW, s:a_s_ALEF_HAMZA_BELOW],
    380 \ [s:a_YEH_HAMZA, s:a_s_YEH_HAMZA],
    381 \ [s:a_ALEF, s:a_s_ALEF],
    382 \ [s:a_TEH_MARBUTA, s:a_s_TEH_MARBUTA],
    383 \ [s:a_DAL, s:a_s_DAL],
    384 \ [s:a_THAL, s:a_s_THAL],
    385 \ [s:a_REH, s:a_s_REH],
    386 \ [s:a_ZAIN, s:a_s_ZAIN],
    387 \ [s:a_TATWEEL, s:a_TATWEEL],
    388 \ [s:a_WAW, s:a_s_WAW],
    389 \ [s:a_ALEF_MAKSURA, s:a_s_ALEF_MAKSURA],
    390 \ [s:a_BEH, s:a_s_BEH],
    391 \ [s:a_TEH, s:a_s_TEH],
    392 \ [s:a_THEH, s:a_s_THEH],
    393 \ [s:a_JEEM, s:a_s_JEEM],
    394 \ [s:a_HAH, s:a_s_HAH],
    395 \ [s:a_KHAH, s:a_s_KHAH],
    396 \ [s:a_SEEN, s:a_s_SEEN],
    397 \ [s:a_SHEEN, s:a_s_SHEEN],
    398 \ [s:a_SAD, s:a_s_SAD],
    399 \ [s:a_DAD, s:a_s_DAD],
    400 \ [s:a_TAH, s:a_s_TAH],
    401 \ [s:a_ZAH, s:a_s_ZAH],
    402 \ [s:a_AIN, s:a_s_AIN],
    403 \ [s:a_GHAIN, s:a_s_GHAIN],
    404 \ [s:a_FEH, s:a_s_FEH],
    405 \ [s:a_QAF, s:a_s_QAF],
    406 \ [s:a_KAF, s:a_s_KAF],
    407 \ [s:a_LAM, s:a_s_LAM],
    408 \ [s:a_MEEM, s:a_s_MEEM],
    409 \ [s:a_NOON, s:a_s_NOON],
    410 \ [s:a_HEH, s:a_s_HEH],
    411 \ [s:a_YEH, s:a_s_YEH],
    412 \ ]
    413    call setline(1, ' ' . pair[0] . ' ')
    414    call assert_equal([' ' . pair[1] . ' '], ScreenLines(1, 3))
    415  endfor
    416 
    417  set arabicshape&
    418  bwipe!
    419 endfunc
    420 
    421 func Test_shape_iso_to_medial()
    422  new
    423  set arabicshape
    424 
    425  " Shaping arabic {testchar} arabic   Tests chg_c_a2m().
    426  " pair[0] = testchar, pair[1] = next-result, pair[2] = current-result,
    427  " pair[3] = previous-result
    428  for pair in [[s:a_HAMZA, s:a_s_GHAIN, s:a_s_HAMZA, s:a_s_BEH],
    429 \[s:a_ALEF_MADDA, s:a_s_GHAIN, s:a_f_ALEF_MADDA, s:a_i_BEH],
    430 \[s:a_ALEF_HAMZA_ABOVE, s:a_s_GHAIN, s:a_f_ALEF_HAMZA_ABOVE, s:a_i_BEH],
    431 \[s:a_WAW_HAMZA, s:a_s_GHAIN, s:a_f_WAW_HAMZA, s:a_i_BEH],
    432 \[s:a_ALEF_HAMZA_BELOW, s:a_s_GHAIN, s:a_f_ALEF_HAMZA_BELOW, s:a_i_BEH],
    433 \[s:a_YEH_HAMZA, s:a_f_GHAIN, s:a_m_YEH_HAMZA, s:a_i_BEH],
    434 \[s:a_ALEF, s:a_s_GHAIN, s:a_f_ALEF, s:a_i_BEH],
    435 \[s:a_BEH, s:a_f_GHAIN, s:a_m_BEH, s:a_i_BEH],
    436 \[s:a_TEH_MARBUTA, s:a_s_GHAIN, s:a_f_TEH_MARBUTA, s:a_i_BEH],
    437 \[s:a_TEH, s:a_f_GHAIN, s:a_m_TEH, s:a_i_BEH],
    438 \[s:a_THEH, s:a_f_GHAIN, s:a_m_THEH, s:a_i_BEH],
    439 \[s:a_JEEM, s:a_f_GHAIN, s:a_m_JEEM, s:a_i_BEH],
    440 \[s:a_HAH, s:a_f_GHAIN, s:a_m_HAH, s:a_i_BEH],
    441 \[s:a_KHAH, s:a_f_GHAIN, s:a_m_KHAH, s:a_i_BEH],
    442 \[s:a_DAL, s:a_s_GHAIN, s:a_f_DAL, s:a_i_BEH],
    443 \[s:a_THAL, s:a_s_GHAIN, s:a_f_THAL, s:a_i_BEH],
    444 \[s:a_REH, s:a_s_GHAIN, s:a_f_REH, s:a_i_BEH],
    445 \[s:a_ZAIN, s:a_s_GHAIN, s:a_f_ZAIN, s:a_i_BEH],
    446 \[s:a_SEEN, s:a_f_GHAIN, s:a_m_SEEN, s:a_i_BEH],
    447 \[s:a_SHEEN, s:a_f_GHAIN, s:a_m_SHEEN, s:a_i_BEH],
    448 \[s:a_SAD, s:a_f_GHAIN, s:a_m_SAD, s:a_i_BEH],
    449 \[s:a_DAD, s:a_f_GHAIN, s:a_m_DAD, s:a_i_BEH],
    450 \[s:a_TAH, s:a_f_GHAIN, s:a_m_TAH, s:a_i_BEH],
    451 \[s:a_ZAH, s:a_f_GHAIN, s:a_m_ZAH, s:a_i_BEH],
    452 \[s:a_AIN, s:a_f_GHAIN, s:a_m_AIN, s:a_i_BEH],
    453 \[s:a_GHAIN, s:a_f_GHAIN, s:a_m_GHAIN, s:a_i_BEH],
    454 \[s:a_TATWEEL, s:a_f_GHAIN, s:a_TATWEEL, s:a_i_BEH],
    455 \[s:a_FEH, s:a_f_GHAIN, s:a_m_FEH, s:a_i_BEH],
    456 \[s:a_QAF, s:a_f_GHAIN, s:a_m_QAF, s:a_i_BEH],
    457 \[s:a_KAF, s:a_f_GHAIN, s:a_m_KAF, s:a_i_BEH],
    458 \[s:a_LAM, s:a_f_GHAIN, s:a_m_LAM, s:a_i_BEH],
    459 \[s:a_MEEM, s:a_f_GHAIN, s:a_m_MEEM, s:a_i_BEH],
    460 \[s:a_NOON, s:a_f_GHAIN, s:a_m_NOON, s:a_i_BEH],
    461 \[s:a_HEH, s:a_f_GHAIN, s:a_m_HEH, s:a_i_BEH],
    462 \[s:a_WAW, s:a_s_GHAIN, s:a_f_WAW, s:a_i_BEH],
    463 \[s:a_ALEF_MAKSURA, s:a_s_GHAIN, s:a_f_ALEF_MAKSURA, s:a_i_BEH],
    464 \[s:a_YEH, s:a_f_GHAIN, s:a_m_YEH, s:a_i_BEH],
    465 \ ]
    466    call setline(1, s:a_GHAIN . pair[0] . s:a_BEH)
    467    call assert_equal([pair[1] . pair[2] . pair[3]], ScreenLines(1, 3))
    468  endfor
    469 
    470  set arabicshape&
    471  bwipe!
    472 endfunc
    473 
    474 func Test_shape_final()
    475  new
    476  set arabicshape
    477 
    478  " Shaping arabic {testchar} arabic   Tests chg_c_a2f().
    479  " pair[0] = testchar,  pair[1] = current-result, pair[2] = previous-result
    480  for pair in [[s:a_HAMZA, s:a_s_HAMZA, s:a_s_BEH],
    481 \[s:a_ALEF_MADDA, s:a_f_ALEF_MADDA, s:a_i_BEH],
    482 \[s:a_ALEF_HAMZA_ABOVE, s:a_f_ALEF_HAMZA_ABOVE, s:a_i_BEH],
    483 \[s:a_WAW_HAMZA, s:a_f_WAW_HAMZA, s:a_i_BEH],
    484 \[s:a_ALEF_HAMZA_BELOW, s:a_f_ALEF_HAMZA_BELOW, s:a_i_BEH],
    485 \[s:a_YEH_HAMZA, s:a_f_YEH_HAMZA, s:a_i_BEH],
    486 \[s:a_ALEF, s:a_f_ALEF, s:a_i_BEH],
    487 \[s:a_BEH, s:a_f_BEH, s:a_i_BEH],
    488 \[s:a_TEH_MARBUTA, s:a_f_TEH_MARBUTA, s:a_i_BEH],
    489 \[s:a_TEH, s:a_f_TEH, s:a_i_BEH],
    490 \[s:a_THEH, s:a_f_THEH, s:a_i_BEH],
    491 \[s:a_JEEM, s:a_f_JEEM, s:a_i_BEH],
    492 \[s:a_HAH, s:a_f_HAH, s:a_i_BEH],
    493 \[s:a_KHAH, s:a_f_KHAH, s:a_i_BEH],
    494 \[s:a_DAL, s:a_f_DAL, s:a_i_BEH],
    495 \[s:a_THAL, s:a_f_THAL, s:a_i_BEH],
    496 \[s:a_REH, s:a_f_REH, s:a_i_BEH],
    497 \[s:a_ZAIN, s:a_f_ZAIN, s:a_i_BEH],
    498 \[s:a_SEEN, s:a_f_SEEN, s:a_i_BEH],
    499 \[s:a_SHEEN, s:a_f_SHEEN, s:a_i_BEH],
    500 \[s:a_SAD, s:a_f_SAD, s:a_i_BEH],
    501 \[s:a_DAD, s:a_f_DAD, s:a_i_BEH],
    502 \[s:a_TAH, s:a_f_TAH, s:a_i_BEH],
    503 \[s:a_ZAH, s:a_f_ZAH, s:a_i_BEH],
    504 \[s:a_AIN, s:a_f_AIN, s:a_i_BEH],
    505 \[s:a_GHAIN, s:a_f_GHAIN, s:a_i_BEH],
    506 \[s:a_TATWEEL, s:a_TATWEEL, s:a_i_BEH],
    507 \[s:a_FEH, s:a_f_FEH, s:a_i_BEH],
    508 \[s:a_QAF, s:a_f_QAF, s:a_i_BEH],
    509 \[s:a_KAF, s:a_f_KAF, s:a_i_BEH],
    510 \[s:a_LAM, s:a_f_LAM, s:a_i_BEH],
    511 \[s:a_MEEM, s:a_f_MEEM, s:a_i_BEH],
    512 \[s:a_NOON, s:a_f_NOON, s:a_i_BEH],
    513 \[s:a_HEH, s:a_f_HEH, s:a_i_BEH],
    514 \[s:a_WAW, s:a_f_WAW, s:a_i_BEH],
    515 \[s:a_ALEF_MAKSURA, s:a_f_ALEF_MAKSURA, s:a_i_BEH],
    516 \[s:a_YEH, s:a_f_YEH, s:a_i_BEH],
    517 \ ]
    518    call setline(1, ' ' . pair[0] . s:a_BEH)
    519    call assert_equal([' ' . pair[1] . pair[2]], ScreenLines(1, 3))
    520  endfor
    521 
    522  set arabicshape&
    523  bwipe!
    524 endfunc
    525 
    526 func Test_shape_combination_final()
    527  new
    528  set arabicshape
    529 
    530  " Shaping arabic {testchar} arabic   Tests chg_c_laa2f().
    531  " pair[0] = testchar,  pair[1] = current-result
    532  for pair in [[s:a_ALEF_MADDA, s:a_f_LAM_ALEF_MADDA_ABOVE],
    533 \ [s:a_ALEF_HAMZA_ABOVE, s:a_f_LAM_ALEF_HAMZA_ABOVE],
    534 \ [s:a_ALEF_HAMZA_BELOW, s:a_f_LAM_ALEF_HAMZA_BELOW],
    535 \ [s:a_ALEF, s:a_f_LAM_ALEF],
    536 \ ]
    537    " The test char is a composing char, put on s:a_LAM.
    538    call setline(1, ' ' . s:a_LAM . pair[0] . s:a_BEH)
    539    call assert_equal([' ' . pair[1] . s:a_i_BEH], ScreenLines(1, 3))
    540  endfor
    541 
    542  set arabicshape&
    543  bwipe!
    544 endfunc
    545 
    546 func Test_shape_combination_isolated()
    547  new
    548  set arabicshape
    549 
    550  " Shaping arabic {testchar} arabic   Tests chg_c_laa2i().
    551  " pair[0] = testchar,  pair[1] = current-result
    552  for pair in [[s:a_ALEF_MADDA, s:a_s_LAM_ALEF_MADDA_ABOVE],
    553 \ [s:a_ALEF_HAMZA_ABOVE, s:a_s_LAM_ALEF_HAMZA_ABOVE],
    554 \ [s:a_ALEF_HAMZA_BELOW, s:a_s_LAM_ALEF_HAMZA_BELOW],
    555 \ [s:a_ALEF, s:a_s_LAM_ALEF],
    556 \ ]
    557    " The test char is a composing char, put on s:a_LAM.
    558    call setline(1, ' ' . s:a_LAM . pair[0] . ' ')
    559    call assert_equal([' ' . pair[1] . ' '], ScreenLines(1, 3))
    560  endfor
    561 
    562  set arabicshape&
    563  bwipe!
    564 endfunc
    565 
    566 " Test for entering arabic character in a search command
    567 func Test_arabic_chars_in_search_cmd()
    568  new
    569  set arabic
    570  call feedkeys("i\nsghl!\<C-^>vim\<C-^>", 'tx')
    571  call cursor(1, 1)
    572  call feedkeys("/^sghl!\<C-^>vim$\<C-^>\<CR>", 'tx')
    573  call assert_equal([2, 1], [line('.'), col('.')])
    574 
    575  " Try searching in left-to-right mode
    576  set rightleftcmd=
    577  call cursor(1, 1)
    578  call feedkeys("/^sghl!\<C-^>vim$\<CR>", 'tx')
    579  call assert_equal([2, 1], [line('.'), col('.')])
    580 
    581  set rightleftcmd&
    582  set rightleft&
    583  set arabic&
    584  bwipe!
    585 endfunc
    586 
    587 " vim: shiftwidth=2 sts=2 expandtab