xref: /vim-8.2.3635/src/testdir/test_spell.vim (revision 98be7fec)
1" Test spell checking
2" Note: this file uses latin1 encoding, but is used with utf-8 encoding.
3
4source check.vim
5CheckFeature spell
6
7source screendump.vim
8
9func TearDown()
10  set nospell
11  call delete('Xtest.aff')
12  call delete('Xtest.dic')
13  call delete('Xtest.latin1.add')
14  call delete('Xtest.latin1.add.spl')
15  call delete('Xtest.latin1.spl')
16  call delete('Xtest.latin1.sug')
17endfunc
18
19func Test_wrap_search()
20  new
21  call setline(1, ['The', '', 'A plong line with two zpelling mistakes', '', 'End'])
22  set spell wrapscan
23  normal ]s
24  call assert_equal('plong', expand('<cword>'))
25  normal ]s
26  call assert_equal('zpelling', expand('<cword>'))
27  normal ]s
28  call assert_equal('plong', expand('<cword>'))
29  bwipe!
30  set nospell
31endfunc
32
33func Test_curswant()
34  new
35  call setline(1, ['Another plong line', 'abcdefghijklmnopq'])
36  set spell wrapscan
37  normal 0]s
38  call assert_equal('plong', expand('<cword>'))
39  normal j
40  call assert_equal(9, getcurpos()[2])
41  normal 0[s
42  call assert_equal('plong', expand('<cword>'))
43  normal j
44  call assert_equal(9, getcurpos()[2])
45
46  normal 0]S
47  call assert_equal('plong', expand('<cword>'))
48  normal j
49  call assert_equal(9, getcurpos()[2])
50  normal 0[S
51  call assert_equal('plong', expand('<cword>'))
52  normal j
53  call assert_equal(9, getcurpos()[2])
54
55  normal 1G0
56  call assert_equal('plong', spellbadword()[0])
57  normal j
58  call assert_equal(9, getcurpos()[2])
59
60  bwipe!
61  set nospell
62endfunc
63
64func Test_z_equal_on_invalid_utf8_word()
65  split
66  set spell
67  call setline(1, "\xff")
68  norm z=
69  set nospell
70  bwipe!
71endfunc
72
73" Test spellbadword() with argument
74func Test_spellbadword()
75  set spell
76
77  call assert_equal(['bycycle', 'bad'],  spellbadword('My bycycle.'))
78  call assert_equal(['another', 'caps'], 'A sentence. another sentence'->spellbadword())
79
80  set spelllang=en
81  call assert_equal(['', ''],            spellbadword('centre'))
82  call assert_equal(['', ''],            spellbadword('center'))
83  set spelllang=en_us
84  call assert_equal(['centre', 'local'], spellbadword('centre'))
85  call assert_equal(['', ''],            spellbadword('center'))
86  set spelllang=en_gb
87  call assert_equal(['', ''],            spellbadword('centre'))
88  call assert_equal(['center', 'local'], spellbadword('center'))
89
90  " Create a small word list to test that spellbadword('...')
91  " can return ['...', 'rare'].
92  e Xwords
93  insert
94foo
95foobar/?
96.
97   w!
98   mkspell! Xwords.spl Xwords
99   set spelllang=Xwords.spl
100   call assert_equal(['foobar', 'rare'], spellbadword('foo foobar'))
101
102  " Typo should not be detected without the 'spell' option.
103  set spelllang=en_gb nospell
104  call assert_equal(['', ''], spellbadword('centre'))
105  call assert_equal(['', ''], spellbadword('My bycycle.'))
106  call assert_equal(['', ''], spellbadword('A sentence. another sentence'))
107
108  call delete('Xwords.spl')
109  call delete('Xwords')
110  set spelllang&
111  set spell&
112endfunc
113
114func Test_spellreall()
115  new
116  set spell
117  call assert_fails('spellrepall', 'E752:')
118  call setline(1, ['A speling mistake. The same speling mistake.',
119        \                'Another speling mistake.'])
120  call feedkeys(']s1z=', 'tx')
121  call assert_equal('A spelling mistake. The same speling mistake.', getline(1))
122  call assert_equal('Another speling mistake.', getline(2))
123  spellrepall
124  call assert_equal('A spelling mistake. The same spelling mistake.', getline(1))
125  call assert_equal('Another spelling mistake.', getline(2))
126  call assert_fails('spellrepall', 'E753:')
127  set spell&
128  bwipe!
129endfunc
130
131" Test spellsuggest({word} [, {max} [, {capital}]])
132func Test_spellsuggest()
133  " No suggestions when spell checking is not enabled.
134  set nospell
135  call assert_equal([], spellsuggest('marrch'))
136
137  set spell
138
139  " With 1 argument.
140  call assert_equal(['march', 'March'], spellsuggest('marrch')[0:1])
141
142  " With 2 arguments.
143  call assert_equal(['march', 'March'], spellsuggest('marrch', 2))
144
145  " With 3 arguments.
146  call assert_equal(['march'], spellsuggest('marrch', 1, 0))
147  call assert_equal(['March'], spellsuggest('marrch', 1, 1))
148
149  " Test with digits and hyphen.
150  call assert_equal('Carbon-14', spellsuggest('Carbon-15')[0])
151
152  " Comment taken from spellsuggest.c explains the following test cases:
153  "
154  " If there are more UPPER than lower case letters suggest an
155  " ALLCAP word.  Otherwise, if the first letter is UPPER then
156  " suggest ONECAP.  Exception: "ALl" most likely should be "All",
157  " require three upper case letters.
158  call assert_equal(['THIRD', 'third'], spellsuggest('thIRD', 2))
159  call assert_equal(['third', 'THIRD'], spellsuggest('tHIrd', 2))
160  call assert_equal(['Third'], spellsuggest('THird', 1))
161  call assert_equal(['All'],      spellsuggest('ALl', 1))
162
163  set spell&
164endfunc
165
166" Test 'spellsuggest' option with methods fast, best and double.
167func Test_spellsuggest_option_methods()
168  set spell
169
170  for e in ['latin1', 'utf-8']
171    exe 'set encoding=' .. e
172
173    set spellsuggest=fast
174    call assert_equal(['Stick', 'Stitch'], spellsuggest('Stich', 2), e)
175
176    " With best or double option, "Stitch" should become the top suggestion
177    " because of better phonetic matching.
178    set spellsuggest=best
179    call assert_equal(['Stitch', 'Stick'], spellsuggest('Stich', 2), e)
180
181    set spellsuggest=double
182    call assert_equal(['Stitch', 'Stick'], spellsuggest('Stich', 2), e)
183  endfor
184
185  set spell& spellsuggest& encoding&
186endfunc
187
188" Test 'spellsuggest' option with value file:{filename}
189func Test_spellsuggest_option_file()
190  set spell spellsuggest=file:Xspellsuggest
191  call writefile(['emacs/vim',
192        \         'theribal/terrible',
193        \         'teribal/terrrible',
194        \         'terribal'],
195        \         'Xspellsuggest')
196
197  call assert_equal(['vim'],      spellsuggest('emacs', 2))
198  call assert_equal(['terrible'], spellsuggest('theribal',2))
199
200  " If the suggestion is misspelled (*terrrible* with 3 r),
201  " it should not be proposed.
202  " The entry for "terribal" should be ignored because of missing slash.
203  call assert_equal([], spellsuggest('teribal', 2))
204  call assert_equal([], spellsuggest('terribal', 2))
205
206  set spell spellsuggest=best,file:Xspellsuggest
207  call assert_equal(['vim', 'Emacs'],       spellsuggest('emacs', 2))
208  call assert_equal(['terrible', 'tribal'], spellsuggest('theribal', 2))
209  call assert_equal(['tribal'],             spellsuggest('teribal', 1))
210  call assert_equal(['tribal'],             spellsuggest('terribal', 1))
211
212  call delete('Xspellsuggest')
213  call assert_fails("call spellsuggest('vim')", "E484: Can't open file Xspellsuggest")
214
215  set spellsuggest& spell&
216endfunc
217
218" Test 'spellsuggest' option with value {number}
219" to limit the number of suggestions
220func Test_spellsuggest_option_number()
221  set spell spellsuggest=2,best
222  new
223
224  " We limited the number of suggestions to 2, so selecting
225  " the 1st and 2nd suggestion should correct the word, but
226  " selecting a 3rd suggestion should do nothing.
227  call setline(1, 'A baord')
228  norm $1z=
229  call assert_equal('A board', getline(1))
230
231  call setline(1, 'A baord')
232  norm $2z=
233  call assert_equal('A bard', getline(1))
234
235  call setline(1, 'A baord')
236  norm $3z=
237  call assert_equal('A baord', getline(1))
238
239  let a = execute('norm $z=')
240  call assert_equal(
241  \    "\n"
242  \ .. "Change \"baord\" to:\n"
243  \ .. " 1 \"board\"\n"
244  \ .. " 2 \"bard\"\n"
245  \ .. "Type number and <Enter> or click with mouse (empty cancels): ", a)
246
247  set spell spellsuggest=0
248  call assert_equal("\nSorry, no suggestions", execute('norm $z='))
249
250  " Unlike z=, function spellsuggest(...) should not be affected by the
251  " max number of suggestions (2) set by the 'spellsuggest' option.
252  call assert_equal(['board', 'bard', 'broad'], spellsuggest('baord', 3))
253
254  set spellsuggest& spell&
255  bwipe!
256endfunc
257
258" Test 'spellsuggest' option with value expr:{expr}
259func Test_spellsuggest_option_expr()
260  " A silly 'spellsuggest' function which makes suggestions all uppercase
261  " and makes the score of each suggestion the length of the suggested word.
262  " So shorter suggestions are preferred.
263  func MySuggest()
264    let spellsuggest_save = &spellsuggest
265    set spellsuggest=3,best
266    let result = map(spellsuggest(v:val, 3), "[toupper(v:val), len(v:val)]")
267    let &spellsuggest = spellsuggest_save
268    return result
269  endfunc
270
271  set spell spellsuggest=expr:MySuggest()
272  call assert_equal(['BARD', 'BOARD', 'BROAD'], spellsuggest('baord', 3))
273
274  new
275  call setline(1, 'baord')
276  let a = execute('norm z=')
277  call assert_equal(
278  \    "\n"
279  \ .. "Change \"baord\" to:\n"
280  \ .. " 1 \"BARD\"\n"
281  \ .. " 2 \"BOARD\"\n"
282  \ .. " 3 \"BROAD\"\n"
283  \ .. "Type number and <Enter> or click with mouse (empty cancels): ", a)
284
285  " With verbose, z= should show the score i.e. word length with
286  " our SpellSuggest() function.
287  set verbose=1
288  let a = execute('norm z=')
289  call assert_equal(
290  \    "\n"
291  \ .. "Change \"baord\" to:\n"
292  \ .. " 1 \"BARD\"                      (4 - 0)\n"
293  \ .. " 2 \"BOARD\"                     (5 - 0)\n"
294  \ .. " 3 \"BROAD\"                     (5 - 0)\n"
295  \ .. "Type number and <Enter> or click with mouse (empty cancels): ", a)
296
297  set spell& spellsuggest& verbose&
298  bwipe!
299endfunc
300
301" Test for 'spellsuggest' expr errrors
302func Test_spellsuggest_expr_errors()
303  " 'spellsuggest'
304  func MySuggest()
305    return range(3)
306  endfunc
307  set spell spellsuggest=expr:MySuggest()
308  call assert_equal([], spellsuggest('baord', 3))
309
310  " Test for 'spellsuggest' expression returning a non-list value
311  func! MySuggest2()
312    return 'good'
313  endfunc
314  set spellsuggest=expr:MySuggest2()
315  call assert_equal([], spellsuggest('baord'))
316
317  " Test for 'spellsuggest' expression returning a list with dict values
318  func! MySuggest3()
319    return [[{}, {}]]
320  endfunc
321  set spellsuggest=expr:MySuggest3()
322  call assert_fails("call spellsuggest('baord')", 'E728:')
323
324  set nospell spellsuggest&
325  delfunc MySuggest
326  delfunc MySuggest2
327  delfunc MySuggest3
328endfunc
329
330func Test_spellinfo()
331  new
332  let runtime = substitute($VIMRUNTIME, '\\', '/', 'g')
333
334  set enc=latin1 spell spelllang=en
335  call assert_match("^\nfile: " .. runtime .. "/spell/en.latin1.spl\n$", execute('spellinfo'))
336
337  set enc=cp1250 spell spelllang=en
338  call assert_match("^\nfile: " .. runtime .. "/spell/en.ascii.spl\n$", execute('spellinfo'))
339
340  set enc=utf-8 spell spelllang=en
341  call assert_match("^\nfile: " .. runtime .. "/spell/en.utf-8.spl\n$", execute('spellinfo'))
342
343  set enc=latin1 spell spelllang=en_us,en_nz
344  call assert_match("^\n" .
345                 \  "file: " .. runtime .. "/spell/en.latin1.spl\n" .
346                 \  "file: " .. runtime.. "/spell/en.latin1.spl\n$", execute('spellinfo'))
347
348  set spell spelllang=
349  call assert_fails('spellinfo', 'E756:')
350
351  set nospell spelllang=en
352  call assert_fails('spellinfo', 'E756:')
353
354  call assert_fails('set spelllang=foo/bar', 'E474:')
355  call assert_fails('set spelllang=foo\ bar', 'E474:')
356  call assert_fails("set spelllang=foo\\\nbar", 'E474:')
357  call assert_fails("set spelllang=foo\\\rbar", 'E474:')
358  call assert_fails("set spelllang=foo+bar", 'E474:')
359
360  set enc& spell& spelllang&
361  bwipe
362endfunc
363
364func Test_zz_basic()
365  call LoadAffAndDic(g:test_data_aff1, g:test_data_dic1)
366  call RunGoodBad("wrong OK puts. Test the end",
367        \ "bad: inputs comment ok Ok. test d\xE9\xF4l end the",
368        \["Comment", "deol", "d\xE9\xF4r", "input", "OK", "output", "outputs", "outtest", "put", "puts",
369        \  "test", "testen", "testn", "the end", "uk", "wrong"],
370        \[
371        \   ["bad", ["put", "uk", "OK"]],
372        \   ["inputs", ["input", "puts", "outputs"]],
373        \   ["comment", ["Comment", "outtest", "the end"]],
374        \   ["ok", ["OK", "uk", "put"]],
375        \   ["Ok", ["OK", "Uk", "Put"]],
376        \   ["test", ["Test", "testn", "testen"]],
377        \   ["d\xE9\xF4l", ["deol", "d\xE9\xF4r", "test"]],
378        \   ["end", ["put", "uk", "test"]],
379        \   ["the", ["put", "uk", "test"]],
380        \ ]
381        \ )
382
383  call assert_equal("gebletegek", soundfold('goobledygoook'))
384  call assert_equal("kepereneven", 'k�op�r�n�ven'->soundfold())
385  call assert_equal("everles gesvets etele", soundfold('oeverloos gezwets edale'))
386endfunc
387
388" Postponed prefixes
389func Test_zz_prefixes()
390  call LoadAffAndDic(g:test_data_aff2, g:test_data_dic1)
391  call RunGoodBad("puts",
392        \ "bad: inputs comment ok Ok end the. test d\xE9\xF4l",
393        \ ["Comment", "deol", "d\xE9\xF4r", "OK", "put", "input", "output", "puts", "outputs", "test", "outtest", "testen", "testn", "the end", "uk", "wrong"],
394        \ [
395        \   ["bad", ["put", "uk", "OK"]],
396        \   ["inputs", ["input", "puts", "outputs"]],
397        \   ["comment", ["Comment"]],
398        \   ["ok", ["OK", "uk", "put"]],
399        \   ["Ok", ["OK", "Uk", "Put"]],
400        \   ["end", ["put", "uk", "deol"]],
401        \   ["the", ["put", "uk", "test"]],
402        \   ["test", ["Test", "testn", "testen"]],
403        \   ["d\xE9\xF4l", ["deol", "d\xE9\xF4r", "test"]],
404        \ ])
405endfunc
406
407"Compound words
408func Test_zz_compound()
409  call LoadAffAndDic(g:test_data_aff3, g:test_data_dic3)
410  call RunGoodBad("foo m\xEF foobar foofoobar barfoo barbarfoo",
411        \ "bad: bar la foom\xEF barm\xEF m\xEFfoo m\xEFbar m\xEFm\xEF lala m\xEFla lam\xEF foola labar",
412        \ ["foo", "m\xEF"],
413        \ [
414        \   ["bad", ["foo", "m\xEF"]],
415        \   ["bar", ["barfoo", "foobar", "foo"]],
416        \   ["la", ["m\xEF", "foo"]],
417        \   ["foom\xEF", ["foo m\xEF", "foo", "foofoo"]],
418        \   ["barm\xEF", ["barfoo", "m\xEF", "barbar"]],
419        \   ["m\xEFfoo", ["m\xEF foo", "foo", "foofoo"]],
420        \   ["m\xEFbar", ["foobar", "barbar", "m\xEF"]],
421        \   ["m\xEFm\xEF", ["m\xEF m\xEF", "m\xEF"]],
422        \   ["lala", []],
423        \   ["m\xEFla", ["m\xEF", "m\xEF m\xEF"]],
424        \   ["lam\xEF", ["m\xEF", "m\xEF m\xEF"]],
425        \   ["foola", ["foo", "foobar", "foofoo"]],
426        \   ["labar", ["barbar", "foobar"]],
427        \ ])
428
429  call LoadAffAndDic(g:test_data_aff4, g:test_data_dic4)
430  call RunGoodBad("word util bork prebork start end wordutil wordutils pro-ok bork borkbork borkborkbork borkborkborkbork borkborkborkborkbork tomato tomatotomato startend startword startwordword startwordend startwordwordend startwordwordwordend prebork preborkbork preborkborkbork nouword",
431        \ "bad: wordutilize pro borkborkborkborkborkbork tomatotomatotomato endstart endend startstart wordend wordstart preborkprebork  preborkpreborkbork startwordwordwordwordend borkpreborkpreborkbork utilsbork  startnouword",
432        \ ["bork", "prebork", "end", "pro-ok", "start", "tomato", "util", "utilize", "utils", "word", "nouword"],
433        \ [
434        \   ["bad", ["end", "bork", "word"]],
435        \   ["wordutilize", ["word utilize", "wordutils", "wordutil"]],
436        \   ["pro", ["bork", "word", "end"]],
437        \   ["borkborkborkborkborkbork", ["bork borkborkborkborkbork", "borkbork borkborkborkbork", "borkborkbork borkborkbork"]],
438        \   ["tomatotomatotomato", ["tomato tomatotomato", "tomatotomato tomato", "tomato tomato tomato"]],
439        \   ["endstart", ["end start", "start"]],
440        \   ["endend", ["end end", "end"]],
441        \   ["startstart", ["start start"]],
442        \   ["wordend", ["word end", "word", "wordword"]],
443        \   ["wordstart", ["word start", "bork start"]],
444        \   ["preborkprebork", ["prebork prebork", "preborkbork", "preborkborkbork"]],
445        \   ["preborkpreborkbork", ["prebork preborkbork", "preborkborkbork", "preborkborkborkbork"]],
446        \   ["startwordwordwordwordend", ["startwordwordwordword end", "startwordwordwordword", "start wordwordwordword end"]],
447        \   ["borkpreborkpreborkbork", ["bork preborkpreborkbork", "bork prebork preborkbork", "bork preborkprebork bork"]],
448        \   ["utilsbork", ["utilbork", "utils bork", "util bork"]],
449        \   ["startnouword", ["start nouword", "startword", "startborkword"]],
450        \ ])
451
452endfunc
453
454"Test affix flags with two characters
455func Test_zz_affix()
456  call LoadAffAndDic(g:test_data_aff5, g:test_data_dic5)
457  call RunGoodBad("fooa1 fooa\xE9 bar prebar barbork prebarbork  startprebar start end startend  startmiddleend nouend",
458        \ "bad: foo fooa2 prabar probarbirk middle startmiddle middleend endstart startprobar startnouend",
459        \ ["bar", "barbork", "end", "fooa1", "fooa\xE9", "nouend", "prebar", "prebarbork", "start"],
460        \ [
461        \   ["bad", ["bar", "end", "fooa1"]],
462        \   ["foo", ["fooa1", "fooa\xE9", "bar"]],
463        \   ["fooa2", ["fooa1", "fooa\xE9", "bar"]],
464        \   ["prabar", ["prebar", "bar", "bar bar"]],
465        \   ["probarbirk", ["prebarbork"]],
466        \   ["middle", []],
467        \   ["startmiddle", ["startmiddleend", "startmiddlebar"]],
468        \   ["middleend", []],
469        \   ["endstart", ["end start", "start"]],
470        \   ["startprobar", ["startprebar", "start prebar", "startbar"]],
471        \   ["startnouend", ["start nouend", "startend"]],
472        \ ])
473
474  call LoadAffAndDic(g:test_data_aff6, g:test_data_dic6)
475  call RunGoodBad("meea1 meea\xE9 bar prebar barbork prebarbork  leadprebar lead end leadend  leadmiddleend",
476        \  "bad: mee meea2 prabar probarbirk middle leadmiddle middleend endlead leadprobar",
477        \ ["bar", "barbork", "end", "lead", "meea1", "meea\xE9", "prebar", "prebarbork"],
478        \ [
479        \   ["bad", ["bar", "end", "lead"]],
480        \   ["mee", ["meea1", "meea\xE9", "bar"]],
481        \   ["meea2", ["meea1", "meea\xE9", "lead"]],
482        \   ["prabar", ["prebar", "bar", "leadbar"]],
483        \   ["probarbirk", ["prebarbork"]],
484        \   ["middle", []],
485        \   ["leadmiddle", ["leadmiddleend", "leadmiddlebar"]],
486        \   ["middleend", []],
487        \   ["endlead", ["end lead", "lead", "end end"]],
488        \   ["leadprobar", ["leadprebar", "lead prebar", "leadbar"]],
489        \ ])
490
491  call LoadAffAndDic(g:test_data_aff7, g:test_data_dic7)
492  call RunGoodBad("meea1 meezero meea\xE9 bar prebar barmeat prebarmeat  leadprebar lead tail leadtail  leadmiddletail",
493        \ "bad: mee meea2 prabar probarmaat middle leadmiddle middletail taillead leadprobar",
494        \ ["bar", "barmeat", "lead", "meea1", "meea\xE9", "meezero", "prebar", "prebarmeat", "tail"],
495        \ [
496        \   ["bad", ["bar", "lead", "tail"]],
497        \   ["mee", ["meea1", "meea\xE9", "bar"]],
498        \   ["meea2", ["meea1", "meea\xE9", "lead"]],
499        \   ["prabar", ["prebar", "bar", "leadbar"]],
500        \   ["probarmaat", ["prebarmeat"]],
501        \   ["middle", []],
502        \   ["leadmiddle", ["leadmiddlebar"]],
503        \   ["middletail", []],
504        \   ["taillead", ["tail lead", "tail"]],
505        \   ["leadprobar", ["leadprebar", "lead prebar", "leadbar"]],
506        \ ])
507endfunc
508
509func Test_zz_NOSLITSUGS()
510  call LoadAffAndDic(g:test_data_aff8, g:test_data_dic8)
511  call RunGoodBad("foo bar faabar", "bad: foobar barfoo",
512        \ ["bar", "faabar", "foo"],
513        \ [
514        \   ["bad", ["bar", "foo"]],
515        \   ["foobar", ["faabar", "foo bar", "bar"]],
516        \   ["barfoo", ["bar foo", "bar", "foo"]],
517        \ ])
518endfunc
519
520" Numbers
521func Test_zz_Numbers()
522  call LoadAffAndDic(g:test_data_aff9, g:test_data_dic9)
523  call RunGoodBad("0b1011 0777 1234 0x01ff", "",
524        \ ["bar", "foo"],
525        \ [
526        \ ])
527endfunc
528
529" Affix flags
530func Test_zz_affix_flags()
531  call LoadAffAndDic(g:test_data_aff10, g:test_data_dic10)
532  call RunGoodBad("drink drinkable drinkables drinktable drinkabletable",
533	\ "bad: drinks drinkstable drinkablestable",
534        \ ["drink", "drinkable", "drinkables", "table"],
535        \ [['bad', []],
536	\ ['drinks', ['drink']],
537	\ ['drinkstable', ['drinktable', 'drinkable', 'drink table']],
538        \ ['drinkablestable', ['drinkabletable', 'drinkables table', 'drinkable table']],
539	\ ])
540endfunc
541
542function FirstSpellWord()
543  call feedkeys("/^start:\n", 'tx')
544  normal ]smm
545  let [str, a] = spellbadword()
546  return str
547endfunc
548
549function SecondSpellWord()
550  normal `m]s
551  let [str, a] = spellbadword()
552  return str
553endfunc
554
555"Test with SAL instead of SOFO items; test automatic reloading
556func Test_zz_sal_and_addition()
557  set enc=latin1
558  set spellfile=
559  call writefile(g:test_data_dic1, "Xtest.dic")
560  call writefile(g:test_data_aff_sal, "Xtest.aff")
561  mkspell! Xtest Xtest
562  set spl=Xtest.latin1.spl spell
563  call assert_equal('kbltykk', soundfold('goobledygoook'))
564  call assert_equal('kprnfn', soundfold('k�op�r�n�ven'))
565  call assert_equal('*fls kswts tl', soundfold('oeverloos gezwets edale'))
566
567  "also use an addition file
568  call writefile(["/regions=usgbnz", "elequint/2", "elekwint/3"], "Xtest.latin1.add")
569  mkspell! Xtest.latin1.add.spl Xtest.latin1.add
570
571  bwipe!
572  call setline(1, ["start: elequint test elekwint test elekwent asdf"])
573
574  set spellfile=Xtest.latin1.add
575  call assert_equal("elekwent", FirstSpellWord())
576
577  set spl=Xtest_us.latin1.spl
578  call assert_equal("elequint", FirstSpellWord())
579  call assert_equal("elekwint", SecondSpellWord())
580
581  set spl=Xtest_gb.latin1.spl
582  call assert_equal("elekwint", FirstSpellWord())
583  call assert_equal("elekwent", SecondSpellWord())
584
585  set spl=Xtest_nz.latin1.spl
586  call assert_equal("elequint", FirstSpellWord())
587  call assert_equal("elekwent", SecondSpellWord())
588
589  set spl=Xtest_ca.latin1.spl
590  call assert_equal("elequint", FirstSpellWord())
591  call assert_equal("elekwint", SecondSpellWord())
592endfunc
593
594func Test_spellfile_value()
595  set spellfile=Xdir/Xtest.latin1.add
596  set spellfile=Xdir/Xtest.utf-8.add,Xtest_other.add
597endfunc
598
599func Test_region_error()
600  messages clear
601  call writefile(["/regions=usgbnz", "elequint/0"], "Xtest.latin1.add")
602  mkspell! Xtest.latin1.add.spl Xtest.latin1.add
603  call assert_match('Invalid region nr in Xtest.latin1.add line 2: 0', execute('messages'))
604  call delete('Xtest.latin1.add')
605  call delete('Xtest.latin1.add.spl')
606endfunc
607
608" Check using z= in new buffer (crash fixed by patch 7.4a.028).
609func Test_zeq_crash()
610  new
611  set maxmem=512 spell
612  call feedkeys('iasdz=:\"', 'tx')
613
614  bwipe!
615endfunc
616
617" Check handling a word longer than MAXWLEN.
618func Test_spell_long_word()
619  set enc=utf-8
620  new
621  call setline(1, "d\xCC\xB4\xCC\xBD\xCD\x88\xCD\x94a\xCC\xB5\xCD\x84\xCD\x84\xCC\xA8\xCD\x9Cr\xCC\xB5\xCC\x8E\xCD\x85\xCD\x85k\xCC\xB6\xCC\x89\xCC\x9D \xCC\xB6\xCC\x83\xCC\x8F\xCC\xA4\xCD\x8Ef\xCC\xB7\xCC\x81\xCC\x80\xCC\xA9\xCC\xB0\xCC\xAC\xCC\xA2\xCD\x95\xCD\x87\xCD\x8D\xCC\x9E\xCD\x99\xCC\xAD\xCC\xAB\xCC\x97\xCC\xBBo\xCC\xB6\xCC\x84\xCC\x95\xCC\x8C\xCC\x8B\xCD\x9B\xCD\x9C\xCC\xAFr\xCC\xB7\xCC\x94\xCD\x83\xCD\x97\xCC\x8C\xCC\x82\xCD\x82\xCD\x80\xCD\x91\xCC\x80\xCC\xBE\xCC\x82\xCC\x8F\xCC\xA3\xCD\x85\xCC\xAE\xCD\x8D\xCD\x99\xCC\xBC\xCC\xAB\xCC\xA7\xCD\x88c\xCC\xB7\xCD\x83\xCC\x84\xCD\x92\xCC\x86\xCC\x83\xCC\x88\xCC\x92\xCC\x94\xCC\xBE\xCC\x9D\xCC\xAF\xCC\x98\xCC\x9D\xCC\xBB\xCD\x8E\xCC\xBB\xCC\xB3\xCC\xA3\xCD\x8E\xCD\x99\xCC\xA5\xCC\xAD\xCC\x99\xCC\xB9\xCC\xAE\xCC\xA5\xCC\x9E\xCD\x88\xCC\xAE\xCC\x9E\xCC\xA9\xCC\x97\xCC\xBC\xCC\x99\xCC\xA5\xCD\x87\xCC\x97\xCD\x8E\xCD\x94\xCC\x99\xCC\x9D\xCC\x96\xCD\x94\xCC\xAB\xCC\xA7\xCC\xA5\xCC\x98\xCC\xBB\xCC\xAF\xCC\xABe\xCC\xB7\xCC\x8E\xCC\x82\xCD\x86\xCD\x9B\xCC\x94\xCD\x83\xCC\x85\xCD\x8A\xCD\x8C\xCC\x8B\xCD\x92\xCD\x91\xCC\x8F\xCC\x81\xCD\x95\xCC\xA2\xCC\xB9\xCC\xB2\xCD\x9C\xCC\xB1\xCC\xA6\xCC\xB3\xCC\xAF\xCC\xAE\xCC\x9C\xCD\x99s\xCC\xB8\xCC\x8C\xCC\x8E\xCC\x87\xCD\x81\xCD\x82\xCC\x86\xCD\x8C\xCD\x8C\xCC\x8B\xCC\x84\xCC\x8C\xCD\x84\xCD\x9B\xCD\x86\xCC\x93\xCD\x90\xCC\x85\xCC\x94\xCD\x98\xCD\x84\xCD\x92\xCD\x8B\xCC\x90\xCC\x83\xCC\x8F\xCD\x84\xCD\x81\xCD\x9B\xCC\x90\xCD\x81\xCC\x8F\xCC\xBD\xCC\x88\xCC\xBF\xCC\x88\xCC\x84\xCC\x8E\xCD\x99\xCD\x94\xCC\x99\xCD\x99\xCC\xB0\xCC\xA8\xCC\xA3\xCC\xA8\xCC\x96\xCC\x99\xCC\xAE\xCC\xBC\xCC\x99\xCD\x9A\xCC\xB2\xCC\xB1\xCC\x9F\xCC\xBB\xCC\xA6\xCD\x85\xCC\xAA\xCD\x89\xCC\x9D\xCC\x99\xCD\x96\xCC\xB1\xCC\xB1\xCC\x99\xCC\xA6\xCC\xA5\xCD\x95\xCC\xB2\xCC\xA0\xCD\x99 within")
622  set spell spelllang=en
623  redraw
624  redraw!
625  bwipe!
626  set nospell
627endfunc
628
629func LoadAffAndDic(aff_contents, dic_contents)
630  set enc=latin1
631  set spellfile=
632  call writefile(a:aff_contents, "Xtest.aff")
633  call writefile(a:dic_contents, "Xtest.dic")
634  " Generate a .spl file from a .dic and .aff file.
635  mkspell! Xtest Xtest
636  " use that spell file
637  set spl=Xtest.latin1.spl spell
638endfunc
639
640func ListWords()
641  spelldump
642  %yank
643  quit
644  return split(@", "\n")
645endfunc
646
647func TestGoodBadBase()
648  exe '1;/^good:'
649  normal 0f:]s
650  let prevbad = ''
651  let result = []
652  while 1
653    let [bad, a] = spellbadword()
654    if bad == '' || bad == prevbad || bad == 'badend'
655      break
656    endif
657    let prevbad = bad
658    let lst = bad->spellsuggest(3)
659    normal mm
660
661    call add(result, [bad, lst])
662    normal `m]s
663  endwhile
664  return result
665endfunc
666
667func RunGoodBad(good, bad, expected_words, expected_bad_words)
668  bwipe!
669  call setline(1, ["good: ", a:good,  a:bad, " badend "])
670  let words = ListWords()
671  call assert_equal(a:expected_words, words[1:-1])
672  let bad_words = TestGoodBadBase()
673  call assert_equal(a:expected_bad_words, bad_words)
674  bwipe!
675endfunc
676
677func Test_spell_screendump()
678  CheckScreendump
679
680  let lines =<< trim END
681       call setline(1, [
682             \ "This is some text without any spell errors.  Everything",
683             \ "should just be black, nothing wrong here.",
684             \ "",
685             \ "This line has a sepll error. and missing caps.",
686             \ "And and this is the the duplication.",
687             \ "with missing caps here.",
688             \ ])
689       set spell spelllang=en_nz
690  END
691  call writefile(lines, 'XtestSpell')
692  let buf = RunVimInTerminal('-S XtestSpell', {'rows': 8})
693  call VerifyScreenDump(buf, 'Test_spell_1', {})
694
695  " clean up
696  call StopVimInTerminal(buf)
697  call delete('XtestSpell')
698endfunc
699
700let g:test_data_aff1 = [
701      \"SET ISO8859-1",
702      \"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ",
703      \"",
704      \"FOL  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
705      \"LOW  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
706      \"UPP  \xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xFF",
707      \"",
708      \"SOFOFROM abcdefghijklmnopqrstuvwxyzABCDEFGHIJKLMNOPQRSTUVWXYZ\xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF\xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xBF",
709      \"SOFOTO   ebctefghejklnnepkrstevvkesebctefghejklnnepkrstevvkeseeeeeeeceeeeeeeedneeeeeeeeeeepseeeeeeeeceeeeeeeedneeeeeeeeeeep?",
710      \"",
711      \"MIDWORD\t'-",
712      \"",
713      \"KEP =",
714      \"RAR ?",
715      \"BAD !",
716      \"",
717      \"PFX I N 1",
718      \"PFX I 0 in .",
719      \"",
720      \"PFX O Y 1",
721      \"PFX O 0 out .",
722      \"",
723      \"SFX S Y 2",
724      \"SFX S 0 s [^s]",
725      \"SFX S 0 es s",
726      \"",
727      \"SFX N N 3",
728      \"SFX N 0 en [^n]",
729      \"SFX N 0 nen n",
730      \"SFX N 0 n .",
731      \"",
732      \"REP 3",
733      \"REP g ch",
734      \"REP ch g",
735      \"REP svp s.v.p.",
736      \"",
737      \"MAP 9",
738      \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
739      \"MAP e\xE8\xE9\xEA\xEB",
740      \"MAP i\xEC\xED\xEE\xEF",
741      \"MAP o\xF2\xF3\xF4\xF5\xF6",
742      \"MAP u\xF9\xFA\xFB\xFC",
743      \"MAP n\xF1",
744      \"MAP c\xE7",
745      \"MAP y\xFF\xFD",
746      \"MAP s\xDF",
747      \ ]
748let g:test_data_dic1 = [
749      \"123456",
750      \"test/NO",
751      \"# comment",
752      \"wrong",
753      \"Comment",
754      \"OK",
755      \"uk",
756      \"put/ISO",
757      \"the end",
758      \"deol",
759      \"d\xE9\xF4r",
760      \ ]
761let g:test_data_aff2 = [
762      \"SET ISO8859-1",
763      \"",
764      \"FOL  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
765      \"LOW  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
766      \"UPP  \xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xFF",
767      \"",
768      \"PFXPOSTPONE",
769      \"",
770      \"MIDWORD\t'-",
771      \"",
772      \"KEP =",
773      \"RAR ?",
774      \"BAD !",
775      \"",
776      \"PFX I N 1",
777      \"PFX I 0 in .",
778      \"",
779      \"PFX O Y 1",
780      \"PFX O 0 out [a-z]",
781      \"",
782      \"SFX S Y 2",
783      \"SFX S 0 s [^s]",
784      \"SFX S 0 es s",
785      \"",
786      \"SFX N N 3",
787      \"SFX N 0 en [^n]",
788      \"SFX N 0 nen n",
789      \"SFX N 0 n .",
790      \"",
791      \"REP 3",
792      \"REP g ch",
793      \"REP ch g",
794      \"REP svp s.v.p.",
795      \"",
796      \"MAP 9",
797      \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
798      \"MAP e\xE8\xE9\xEA\xEB",
799      \"MAP i\xEC\xED\xEE\xEF",
800      \"MAP o\xF2\xF3\xF4\xF5\xF6",
801      \"MAP u\xF9\xFA\xFB\xFC",
802      \"MAP n\xF1",
803      \"MAP c\xE7",
804      \"MAP y\xFF\xFD",
805      \"MAP s\xDF",
806      \ ]
807let g:test_data_aff3 = [
808      \"SET ISO8859-1",
809      \"",
810      \"COMPOUNDMIN 3",
811      \"COMPOUNDRULE m*",
812      \"NEEDCOMPOUND x",
813      \ ]
814let g:test_data_dic3 = [
815      \"1234",
816      \"foo/m",
817      \"bar/mx",
818      \"m\xEF/m",
819      \"la/mx",
820      \ ]
821let g:test_data_aff4 = [
822      \"SET ISO8859-1",
823      \"",
824      \"FOL  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
825      \"LOW  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
826      \"UPP  \xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xFF",
827      \"",
828      \"COMPOUNDRULE m+",
829      \"COMPOUNDRULE sm*e",
830      \"COMPOUNDRULE sm+",
831      \"COMPOUNDMIN 3",
832      \"COMPOUNDWORDMAX 3",
833      \"COMPOUNDFORBIDFLAG t",
834      \"",
835      \"COMPOUNDSYLMAX 5",
836      \"SYLLABLE a\xE1e\xE9i\xEDo\xF3\xF6\xF5u\xFA\xFC\xFBy/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui",
837      \"",
838      \"MAP 9",
839      \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
840      \"MAP e\xE8\xE9\xEA\xEB",
841      \"MAP i\xEC\xED\xEE\xEF",
842      \"MAP o\xF2\xF3\xF4\xF5\xF6",
843      \"MAP u\xF9\xFA\xFB\xFC",
844      \"MAP n\xF1",
845      \"MAP c\xE7",
846      \"MAP y\xFF\xFD",
847      \"MAP s\xDF",
848      \"",
849      \"NEEDAFFIX x",
850      \"",
851      \"PFXPOSTPONE",
852      \"",
853      \"MIDWORD '-",
854      \"",
855      \"SFX q N 1",
856      \"SFX q   0    -ok .",
857      \"",
858      \"SFX a Y 2",
859      \"SFX a 0 s .",
860      \"SFX a 0 ize/t .",
861      \"",
862      \"PFX p N 1",
863      \"PFX p 0 pre .",
864      \"",
865      \"PFX P N 1",
866      \"PFX P 0 nou .",
867      \ ]
868let g:test_data_dic4 = [
869      \"1234",
870      \"word/mP",
871      \"util/am",
872      \"pro/xq",
873      \"tomato/m",
874      \"bork/mp",
875      \"start/s",
876      \"end/e",
877      \ ]
878let g:test_data_aff5 = [
879      \"SET ISO8859-1",
880      \"",
881      \"FLAG long",
882      \"",
883      \"NEEDAFFIX !!",
884      \"",
885      \"COMPOUNDRULE ssmm*ee",
886      \"",
887      \"NEEDCOMPOUND xx",
888      \"COMPOUNDPERMITFLAG pp",
889      \"",
890      \"SFX 13 Y 1",
891      \"SFX 13 0 bork .",
892      \"",
893      \"SFX a1 Y 1",
894      \"SFX a1 0 a1 .",
895      \"",
896      \"SFX a\xE9 Y 1",
897      \"SFX a\xE9 0 a\xE9 .",
898      \"",
899      \"PFX zz Y 1",
900      \"PFX zz 0 pre/pp .",
901      \"",
902      \"PFX yy Y 1",
903      \"PFX yy 0 nou .",
904      \ ]
905let g:test_data_dic5 = [
906      \"1234",
907      \"foo/a1a\xE9!!",
908      \"bar/zz13ee",
909      \"start/ss",
910      \"end/eeyy",
911      \"middle/mmxx",
912      \ ]
913let g:test_data_aff6 = [
914      \"SET ISO8859-1",
915      \"",
916      \"FLAG caplong",
917      \"",
918      \"NEEDAFFIX A!",
919      \"",
920      \"COMPOUNDRULE sMm*Ee",
921      \"",
922      \"NEEDCOMPOUND Xx",
923      \"",
924      \"COMPOUNDPERMITFLAG p",
925      \"",
926      \"SFX N3 Y 1",
927      \"SFX N3 0 bork .",
928      \"",
929      \"SFX A1 Y 1",
930      \"SFX A1 0 a1 .",
931      \"",
932      \"SFX A\xE9 Y 1",
933      \"SFX A\xE9 0 a\xE9 .",
934      \"",
935      \"PFX Zz Y 1",
936      \"PFX Zz 0 pre/p .",
937      \ ]
938let g:test_data_dic6 = [
939      \"1234",
940      \"mee/A1A\xE9A!",
941      \"bar/ZzN3Ee",
942      \"lead/s",
943      \"end/Ee",
944      \"middle/MmXx",
945      \ ]
946let g:test_data_aff7 = [
947      \"SET ISO8859-1",
948      \"",
949      \"FLAG num",
950      \"",
951      \"NEEDAFFIX 9999",
952      \"",
953      \"COMPOUNDRULE 2,77*123",
954      \"",
955      \"NEEDCOMPOUND 1",
956      \"COMPOUNDPERMITFLAG 432",
957      \"",
958      \"SFX 61003 Y 1",
959      \"SFX 61003 0 meat .",
960      \"",
961      \"SFX 0 Y 1",
962      \"SFX 0 0 zero .",
963      \"",
964      \"SFX 391 Y 1",
965      \"SFX 391 0 a1 .",
966      \"",
967      \"SFX 111 Y 1",
968      \"SFX 111 0 a\xE9 .",
969      \"",
970      \"PFX 17 Y 1",
971      \"PFX 17 0 pre/432 .",
972      \ ]
973let g:test_data_dic7 = [
974      \"1234",
975      \"mee/0,391,111,9999",
976      \"bar/17,61003,123",
977      \"lead/2",
978      \"tail/123",
979      \"middle/77,1",
980      \ ]
981let g:test_data_aff8 = [
982      \"SET ISO8859-1",
983      \"",
984      \"NOSPLITSUGS",
985      \ ]
986let g:test_data_dic8 = [
987      \"1234",
988      \"foo",
989      \"bar",
990      \"faabar",
991      \ ]
992let g:test_data_aff9 = [
993      \ ]
994let g:test_data_dic9 = [
995      \"1234",
996      \"foo",
997      \"bar",
998      \ ]
999let g:test_data_aff10 = [
1000      \"COMPOUNDRULE se",
1001      \"COMPOUNDPERMITFLAG p",
1002      \"",
1003      \"SFX A Y 1",
1004      \"SFX A 0 able/Mp .",
1005      \"",
1006      \"SFX M Y 1",
1007      \"SFX M 0 s .",
1008      \ ]
1009let g:test_data_dic10 = [
1010      \"1234",
1011      \"drink/As",
1012      \"table/e",
1013      \ ]
1014let g:test_data_aff_sal = [
1015      \"SET ISO8859-1",
1016      \"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ",
1017      \"",
1018      \"FOL  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
1019      \"LOW  \xE0\xE1\xE2\xE3\xE4\xE5\xE6\xE7\xE8\xE9\xEA\xEB\xEC\xED\xEE\xEF\xF0\xF1\xF2\xF3\xF4\xF5\xF6\xF8\xF9\xFA\xFB\xFC\xFD\xFE\xDF\xFF",
1020      \"UPP  \xC0\xC1\xC2\xC3\xC4\xC5\xC6\xC7\xC8\xC9\xCA\xCB\xCC\xCD\xCE\xCF\xD0\xD1\xD2\xD3\xD4\xD5\xD6\xD8\xD9\xDA\xDB\xDC\xDD\xDE\xDF\xFF",
1021      \"",
1022      \"MIDWORD\t'-",
1023      \"",
1024      \"KEP =",
1025      \"RAR ?",
1026      \"BAD !",
1027      \"",
1028      \"PFX I N 1",
1029      \"PFX I 0 in .",
1030      \"",
1031      \"PFX O Y 1",
1032      \"PFX O 0 out .",
1033      \"",
1034      \"SFX S Y 2",
1035      \"SFX S 0 s [^s]",
1036      \"SFX S 0 es s",
1037      \"",
1038      \"SFX N N 3",
1039      \"SFX N 0 en [^n]",
1040      \"SFX N 0 nen n",
1041      \"SFX N 0 n .",
1042      \"",
1043      \"REP 3",
1044      \"REP g ch",
1045      \"REP ch g",
1046      \"REP svp s.v.p.",
1047      \"",
1048      \"MAP 9",
1049      \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
1050      \"MAP e\xE8\xE9\xEA\xEB",
1051      \"MAP i\xEC\xED\xEE\xEF",
1052      \"MAP o\xF2\xF3\xF4\xF5\xF6",
1053      \"MAP u\xF9\xFA\xFB\xFC",
1054      \"MAP n\xF1",
1055      \"MAP c\xE7",
1056      \"MAP y\xFF\xFD",
1057      \"MAP s\xDF",
1058      \"",
1059      \"SAL AH(AEIOUY)-^         *H",
1060      \"SAL AR(AEIOUY)-^         *R",
1061      \"SAL A(HR)^               *",
1062      \"SAL A^                   *",
1063      \"SAL AH(AEIOUY)-          H",
1064      \"SAL AR(AEIOUY)-          R",
1065      \"SAL A(HR)                _",
1066      \"SAL \xC0^                   *",
1067      \"SAL \xC5^                   *",
1068      \"SAL BB-                  _",
1069      \"SAL B                    B",
1070      \"SAL CQ-                  _",
1071      \"SAL CIA                  X",
1072      \"SAL CH                   X",
1073      \"SAL C(EIY)-              S",
1074      \"SAL CK                   K",
1075      \"SAL COUGH^               KF",
1076      \"SAL CC<                  C",
1077      \"SAL C                    K",
1078      \"SAL DG(EIY)              K",
1079      \"SAL DD-                  _",
1080      \"SAL D                    T",
1081      \"SAL \xC9<                   E",
1082      \"SAL EH(AEIOUY)-^         *H",
1083      \"SAL ER(AEIOUY)-^         *R",
1084      \"SAL E(HR)^               *",
1085      \"SAL ENOUGH^$             *NF",
1086      \"SAL E^                   *",
1087      \"SAL EH(AEIOUY)-          H",
1088      \"SAL ER(AEIOUY)-          R",
1089      \"SAL E(HR)                _",
1090      \"SAL FF-                  _",
1091      \"SAL F                    F",
1092      \"SAL GN^                  N",
1093      \"SAL GN$                  N",
1094      \"SAL GNS$                 NS",
1095      \"SAL GNED$                N",
1096      \"SAL GH(AEIOUY)-          K",
1097      \"SAL GH                   _",
1098      \"SAL GG9                  K",
1099      \"SAL G                    K",
1100      \"SAL H                    H",
1101      \"SAL IH(AEIOUY)-^         *H",
1102      \"SAL IR(AEIOUY)-^         *R",
1103      \"SAL I(HR)^               *",
1104      \"SAL I^                   *",
1105      \"SAL ING6                 N",
1106      \"SAL IH(AEIOUY)-          H",
1107      \"SAL IR(AEIOUY)-          R",
1108      \"SAL I(HR)                _",
1109      \"SAL J                    K",
1110      \"SAL KN^                  N",
1111      \"SAL KK-                  _",
1112      \"SAL K                    K",
1113      \"SAL LAUGH^               LF",
1114      \"SAL LL-                  _",
1115      \"SAL L                    L",
1116      \"SAL MB$                  M",
1117      \"SAL MM                   M",
1118      \"SAL M                    M",
1119      \"SAL NN-                  _",
1120      \"SAL N                    N",
1121      \"SAL OH(AEIOUY)-^         *H",
1122      \"SAL OR(AEIOUY)-^         *R",
1123      \"SAL O(HR)^               *",
1124      \"SAL O^                   *",
1125      \"SAL OH(AEIOUY)-          H",
1126      \"SAL OR(AEIOUY)-          R",
1127      \"SAL O(HR)                _",
1128      \"SAL PH                   F",
1129      \"SAL PN^                  N",
1130      \"SAL PP-                  _",
1131      \"SAL P                    P",
1132      \"SAL Q                    K",
1133      \"SAL RH^                  R",
1134      \"SAL ROUGH^               RF",
1135      \"SAL RR-                  _",
1136      \"SAL R                    R",
1137      \"SAL SCH(EOU)-            SK",
1138      \"SAL SC(IEY)-             S",
1139      \"SAL SH                   X",
1140      \"SAL SI(AO)-              X",
1141      \"SAL SS-                  _",
1142      \"SAL S                    S",
1143      \"SAL TI(AO)-              X",
1144      \"SAL TH                   @",
1145      \"SAL TCH--                _",
1146      \"SAL TOUGH^               TF",
1147      \"SAL TT-                  _",
1148      \"SAL T                    T",
1149      \"SAL UH(AEIOUY)-^         *H",
1150      \"SAL UR(AEIOUY)-^         *R",
1151      \"SAL U(HR)^               *",
1152      \"SAL U^                   *",
1153      \"SAL UH(AEIOUY)-          H",
1154      \"SAL UR(AEIOUY)-          R",
1155      \"SAL U(HR)                _",
1156      \"SAL V^                   W",
1157      \"SAL V                    F",
1158      \"SAL WR^                  R",
1159      \"SAL WH^                  W",
1160      \"SAL W(AEIOU)-            W",
1161      \"SAL X^                   S",
1162      \"SAL X                    KS",
1163      \"SAL Y(AEIOU)-            Y",
1164      \"SAL ZZ-                  _",
1165      \"SAL Z                    S",
1166      \ ]
1167