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