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