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