blob: 79fb8927cb5d0b7a6c4f4a8a065725827d8c721b [file] [log] [blame]
Bram Moolenaard3f78dc2017-02-25 14:21:10 +01001" Test spell checking
Bram Moolenaar5bcc5a12019-08-06 22:48:02 +02002" Note: this file uses latin1 encoding, but is used with utf-8 encoding.
Bram Moolenaard3f78dc2017-02-25 14:21:10 +01003
Bram Moolenaarb46fecd2019-06-15 17:58:09 +02004source check.vim
5CheckFeature spell
Bram Moolenaard3f78dc2017-02-25 14:21:10 +01006
Bram Moolenaar7751d1d2019-10-18 20:37:08 +02007source screendump.vim
8
Bram Moolenaar1a0f2002017-07-28 15:38:10 +02009func 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
Bram Moolenaard3f78dc2017-02-25 14:21:10 +010019func 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
Bram Moolenaar5b276aa2017-04-22 23:49:52 +020032
Bram Moolenaarb73fa622017-12-21 20:27:47 +010033func 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
Bram Moolenaar5b276aa2017-04-22 23:49:52 +020064func 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
Bram Moolenaar545cb792017-05-23 11:31:22 +020072
Bram Moolenaar872e4512018-07-20 23:36:26 +020073" Test spellbadword() with argument
74func Test_spellbadword()
75 set spell
76
77 call assert_equal(['bycycle', 'bad'], spellbadword('My bycycle.'))
Bram Moolenaarf6ed61e2019-09-07 19:05:09 +020078 call assert_equal(['another', 'caps'], 'A sentence. another sentence'->spellbadword())
Bram Moolenaar872e4512018-07-20 23:36:26 +020079
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
Bram Moolenaar545cb792017-05-23 11:31:22 +0200114func Test_spellreall()
115 new
116 set spell
117 call assert_fails('spellrepall', 'E752:')
118 call setline(1, ['A speling mistake. The same speling mistake.',
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200119 \ 'Another speling mistake.'])
Bram Moolenaar545cb792017-05-23 11:31:22 +0200120 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
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200130
Bram Moolenaar9049b682018-08-31 22:26:53 +0200131func Test_spellinfo()
132 new
Bram Moolenaarc25e7022019-10-10 14:08:26 +0200133 let runtime = substitute($VIMRUNTIME, '\\', '/', 'g')
Bram Moolenaar9049b682018-08-31 22:26:53 +0200134
135 set enc=latin1 spell spelllang=en
Bram Moolenaarc25e7022019-10-10 14:08:26 +0200136 call assert_match("^\nfile: " .. runtime .. "/spell/en.latin1.spl\n$", execute('spellinfo'))
Bram Moolenaar9049b682018-08-31 22:26:53 +0200137
138 set enc=cp1250 spell spelllang=en
Bram Moolenaarc25e7022019-10-10 14:08:26 +0200139 call assert_match("^\nfile: " .. runtime .. "/spell/en.ascii.spl\n$", execute('spellinfo'))
Bram Moolenaar9049b682018-08-31 22:26:53 +0200140
Bram Moolenaar30276f22019-01-24 17:59:39 +0100141 set enc=utf-8 spell spelllang=en
Bram Moolenaarc25e7022019-10-10 14:08:26 +0200142 call assert_match("^\nfile: " .. runtime .. "/spell/en.utf-8.spl\n$", execute('spellinfo'))
Bram Moolenaar9049b682018-08-31 22:26:53 +0200143
144 set enc=latin1 spell spelllang=en_us,en_nz
145 call assert_match("^\n" .
Bram Moolenaarc25e7022019-10-10 14:08:26 +0200146 \ "file: " .. runtime .. "/spell/en.latin1.spl\n" .
147 \ "file: " .. runtime.. "/spell/en.latin1.spl\n$", execute('spellinfo'))
Bram Moolenaar9049b682018-08-31 22:26:53 +0200148
149 set spell spelllang=
150 call assert_fails('spellinfo', 'E756:')
151
152 set nospell spelllang=en
153 call assert_fails('spellinfo', 'E756:')
154
Bram Moolenaar8f130ed2019-04-10 22:15:19 +0200155 call assert_fails('set spelllang=foo/bar', 'E474:')
156 call assert_fails('set spelllang=foo\ bar', 'E474:')
157 call assert_fails("set spelllang=foo\\\nbar", 'E474:')
158 call assert_fails("set spelllang=foo\\\rbar", 'E474:')
159 call assert_fails("set spelllang=foo+bar", 'E474:')
160
Bram Moolenaar9049b682018-08-31 22:26:53 +0200161 set enc& spell& spelllang&
162 bwipe
163endfunc
164
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200165func Test_zz_basic()
166 call LoadAffAndDic(g:test_data_aff1, g:test_data_dic1)
167 call RunGoodBad("wrong OK puts. Test the end",
168 \ "bad: inputs comment ok Ok. test d\xE9\xF4l end the",
169 \["Comment", "deol", "d\xE9\xF4r", "input", "OK", "output", "outputs", "outtest", "put", "puts",
170 \ "test", "testen", "testn", "the end", "uk", "wrong"],
171 \[
172 \ ["bad", ["put", "uk", "OK"]],
173 \ ["inputs", ["input", "puts", "outputs"]],
174 \ ["comment", ["Comment", "outtest", "the end"]],
175 \ ["ok", ["OK", "uk", "put"]],
176 \ ["Ok", ["OK", "Uk", "Put"]],
177 \ ["test", ["Test", "testn", "testen"]],
178 \ ["d\xE9\xF4l", ["deol", "d\xE9\xF4r", "test"]],
179 \ ["end", ["put", "uk", "test"]],
180 \ ["the", ["put", "uk", "test"]],
181 \ ]
182 \ )
183
184 call assert_equal("gebletegek", soundfold('goobledygoook'))
Bram Moolenaarf6ed61e2019-09-07 19:05:09 +0200185 call assert_equal("kepereneven", 'kóopërÿnôven'->soundfold())
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200186 call assert_equal("everles gesvets etele", soundfold('oeverloos gezwets edale'))
187endfunc
188
189" Postponed prefixes
190func Test_zz_prefixes()
191 call LoadAffAndDic(g:test_data_aff2, g:test_data_dic1)
192 call RunGoodBad("puts",
193 \ "bad: inputs comment ok Ok end the. test d\xE9\xF4l",
194 \ ["Comment", "deol", "d\xE9\xF4r", "OK", "put", "input", "output", "puts", "outputs", "test", "outtest", "testen", "testn", "the end", "uk", "wrong"],
195 \ [
196 \ ["bad", ["put", "uk", "OK"]],
197 \ ["inputs", ["input", "puts", "outputs"]],
198 \ ["comment", ["Comment"]],
199 \ ["ok", ["OK", "uk", "put"]],
200 \ ["Ok", ["OK", "Uk", "Put"]],
201 \ ["end", ["put", "uk", "deol"]],
202 \ ["the", ["put", "uk", "test"]],
203 \ ["test", ["Test", "testn", "testen"]],
204 \ ["d\xE9\xF4l", ["deol", "d\xE9\xF4r", "test"]],
205 \ ])
206endfunc
207
208"Compound words
209func Test_zz_compound()
210 call LoadAffAndDic(g:test_data_aff3, g:test_data_dic3)
211 call RunGoodBad("foo m\xEF foobar foofoobar barfoo barbarfoo",
212 \ "bad: bar la foom\xEF barm\xEF m\xEFfoo m\xEFbar m\xEFm\xEF lala m\xEFla lam\xEF foola labar",
213 \ ["foo", "m\xEF"],
214 \ [
215 \ ["bad", ["foo", "m\xEF"]],
216 \ ["bar", ["barfoo", "foobar", "foo"]],
217 \ ["la", ["m\xEF", "foo"]],
218 \ ["foom\xEF", ["foo m\xEF", "foo", "foofoo"]],
219 \ ["barm\xEF", ["barfoo", "m\xEF", "barbar"]],
220 \ ["m\xEFfoo", ["m\xEF foo", "foo", "foofoo"]],
221 \ ["m\xEFbar", ["foobar", "barbar", "m\xEF"]],
222 \ ["m\xEFm\xEF", ["m\xEF m\xEF", "m\xEF"]],
223 \ ["lala", []],
224 \ ["m\xEFla", ["m\xEF", "m\xEF m\xEF"]],
225 \ ["lam\xEF", ["m\xEF", "m\xEF m\xEF"]],
226 \ ["foola", ["foo", "foobar", "foofoo"]],
227 \ ["labar", ["barbar", "foobar"]],
228 \ ])
229
230 call LoadAffAndDic(g:test_data_aff4, g:test_data_dic4)
231 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",
232 \ "bad: wordutilize pro borkborkborkborkborkbork tomatotomatotomato endstart endend startstart wordend wordstart preborkprebork preborkpreborkbork startwordwordwordwordend borkpreborkpreborkbork utilsbork startnouword",
233 \ ["bork", "prebork", "end", "pro-ok", "start", "tomato", "util", "utilize", "utils", "word", "nouword"],
234 \ [
235 \ ["bad", ["end", "bork", "word"]],
236 \ ["wordutilize", ["word utilize", "wordutils", "wordutil"]],
237 \ ["pro", ["bork", "word", "end"]],
238 \ ["borkborkborkborkborkbork", ["bork borkborkborkborkbork", "borkbork borkborkborkbork", "borkborkbork borkborkbork"]],
239 \ ["tomatotomatotomato", ["tomato tomatotomato", "tomatotomato tomato", "tomato tomato tomato"]],
240 \ ["endstart", ["end start", "start"]],
241 \ ["endend", ["end end", "end"]],
242 \ ["startstart", ["start start"]],
243 \ ["wordend", ["word end", "word", "wordword"]],
244 \ ["wordstart", ["word start", "bork start"]],
245 \ ["preborkprebork", ["prebork prebork", "preborkbork", "preborkborkbork"]],
246 \ ["preborkpreborkbork", ["prebork preborkbork", "preborkborkbork", "preborkborkborkbork"]],
247 \ ["startwordwordwordwordend", ["startwordwordwordword end", "startwordwordwordword", "start wordwordwordword end"]],
248 \ ["borkpreborkpreborkbork", ["bork preborkpreborkbork", "bork prebork preborkbork", "bork preborkprebork bork"]],
249 \ ["utilsbork", ["utilbork", "utils bork", "util bork"]],
250 \ ["startnouword", ["start nouword", "startword", "startborkword"]],
251 \ ])
252
253endfunc
254
255"Test affix flags with two characters
256func Test_zz_affix()
257 call LoadAffAndDic(g:test_data_aff5, g:test_data_dic5)
258 call RunGoodBad("fooa1 fooa\xE9 bar prebar barbork prebarbork startprebar start end startend startmiddleend nouend",
259 \ "bad: foo fooa2 prabar probarbirk middle startmiddle middleend endstart startprobar startnouend",
260 \ ["bar", "barbork", "end", "fooa1", "fooa\xE9", "nouend", "prebar", "prebarbork", "start"],
261 \ [
262 \ ["bad", ["bar", "end", "fooa1"]],
263 \ ["foo", ["fooa1", "fooa\xE9", "bar"]],
264 \ ["fooa2", ["fooa1", "fooa\xE9", "bar"]],
265 \ ["prabar", ["prebar", "bar", "bar bar"]],
266 \ ["probarbirk", ["prebarbork"]],
267 \ ["middle", []],
268 \ ["startmiddle", ["startmiddleend", "startmiddlebar"]],
269 \ ["middleend", []],
270 \ ["endstart", ["end start", "start"]],
271 \ ["startprobar", ["startprebar", "start prebar", "startbar"]],
272 \ ["startnouend", ["start nouend", "startend"]],
273 \ ])
274
275 call LoadAffAndDic(g:test_data_aff6, g:test_data_dic6)
276 call RunGoodBad("meea1 meea\xE9 bar prebar barbork prebarbork leadprebar lead end leadend leadmiddleend",
277 \ "bad: mee meea2 prabar probarbirk middle leadmiddle middleend endlead leadprobar",
278 \ ["bar", "barbork", "end", "lead", "meea1", "meea\xE9", "prebar", "prebarbork"],
279 \ [
280 \ ["bad", ["bar", "end", "lead"]],
281 \ ["mee", ["meea1", "meea\xE9", "bar"]],
282 \ ["meea2", ["meea1", "meea\xE9", "lead"]],
283 \ ["prabar", ["prebar", "bar", "leadbar"]],
284 \ ["probarbirk", ["prebarbork"]],
285 \ ["middle", []],
286 \ ["leadmiddle", ["leadmiddleend", "leadmiddlebar"]],
287 \ ["middleend", []],
288 \ ["endlead", ["end lead", "lead", "end end"]],
289 \ ["leadprobar", ["leadprebar", "lead prebar", "leadbar"]],
290 \ ])
291
292 call LoadAffAndDic(g:test_data_aff7, g:test_data_dic7)
Bram Moolenaar3d2a47c2019-11-07 20:48:42 +0100293 call RunGoodBad("meea1 meezero meea\xE9 bar prebar barmeat prebarmeat leadprebar lead tail leadtail leadmiddletail",
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200294 \ "bad: mee meea2 prabar probarmaat middle leadmiddle middletail taillead leadprobar",
Bram Moolenaar3d2a47c2019-11-07 20:48:42 +0100295 \ ["bar", "barmeat", "lead", "meea1", "meea\xE9", "meezero", "prebar", "prebarmeat", "tail"],
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200296 \ [
297 \ ["bad", ["bar", "lead", "tail"]],
298 \ ["mee", ["meea1", "meea\xE9", "bar"]],
299 \ ["meea2", ["meea1", "meea\xE9", "lead"]],
300 \ ["prabar", ["prebar", "bar", "leadbar"]],
301 \ ["probarmaat", ["prebarmeat"]],
302 \ ["middle", []],
303 \ ["leadmiddle", ["leadmiddlebar"]],
304 \ ["middletail", []],
305 \ ["taillead", ["tail lead", "tail"]],
306 \ ["leadprobar", ["leadprebar", "lead prebar", "leadbar"]],
307 \ ])
308endfunc
309
310func Test_zz_NOSLITSUGS()
311 call LoadAffAndDic(g:test_data_aff8, g:test_data_dic8)
312 call RunGoodBad("foo bar faabar", "bad: foobar barfoo",
313 \ ["bar", "faabar", "foo"],
314 \ [
315 \ ["bad", ["bar", "foo"]],
316 \ ["foobar", ["faabar", "foo bar", "bar"]],
317 \ ["barfoo", ["bar foo", "bar", "foo"]],
318 \ ])
319endfunc
320
321" Numbers
322func Test_zz_Numbers()
323 call LoadAffAndDic(g:test_data_aff9, g:test_data_dic9)
324 call RunGoodBad("0b1011 0777 1234 0x01ff", "",
325 \ ["bar", "foo"],
326 \ [
327 \ ])
328endfunc
329
Bram Moolenaar37ff4cf2019-11-17 20:10:20 +0100330" Affix flags
331func Test_zz_affix_flags()
332 call LoadAffAndDic(g:test_data_aff10, g:test_data_dic10)
333 call RunGoodBad("drink drinkable drinkables drinktable drinkabletable",
334 \ "bad: drinks drinkstable drinkablestable",
335 \ ["drink", "drinkable", "drinkables", "table"],
336 \ [['bad', []],
337 \ ['drinks', ['drink']],
338 \ ['drinkstable', ['drinktable', 'drinkable', 'drink table']],
339 \ ['drinkablestable', ['drinkabletable', 'drinkables table', 'drinkable table']],
340 \ ])
341endfunc
342
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200343function FirstSpellWord()
344 call feedkeys("/^start:\n", 'tx')
345 normal ]smm
346 let [str, a] = spellbadword()
347 return str
348endfunc
349
350function SecondSpellWord()
351 normal `m]s
352 let [str, a] = spellbadword()
353 return str
354endfunc
355
356"Test with SAL instead of SOFO items; test automatic reloading
357func Test_zz_sal_and_addition()
358 set enc=latin1
359 set spellfile=
Bram Moolenaar1a0f2002017-07-28 15:38:10 +0200360 call writefile(g:test_data_dic1, "Xtest.dic")
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200361 call writefile(g:test_data_aff_sal, "Xtest.aff")
362 mkspell! Xtest Xtest
363 set spl=Xtest.latin1.spl spell
364 call assert_equal('kbltykk', soundfold('goobledygoook'))
365 call assert_equal('kprnfn', soundfold('kóopërÿnôven'))
366 call assert_equal('*fls kswts tl', soundfold('oeverloos gezwets edale'))
367
368 "also use an addition file
369 call writefile(["/regions=usgbnz", "elequint/2", "elekwint/3"], "Xtest.latin1.add")
370 mkspell! Xtest.latin1.add.spl Xtest.latin1.add
371
372 bwipe!
373 call setline(1, ["start: elequint test elekwint test elekwent asdf"])
374
375 set spellfile=Xtest.latin1.add
376 call assert_equal("elekwent", FirstSpellWord())
377
378 set spl=Xtest_us.latin1.spl
379 call assert_equal("elequint", FirstSpellWord())
380 call assert_equal("elekwint", SecondSpellWord())
381
382 set spl=Xtest_gb.latin1.spl
383 call assert_equal("elekwint", FirstSpellWord())
384 call assert_equal("elekwent", SecondSpellWord())
385
386 set spl=Xtest_nz.latin1.spl
387 call assert_equal("elequint", FirstSpellWord())
388 call assert_equal("elekwent", SecondSpellWord())
389
390 set spl=Xtest_ca.latin1.spl
391 call assert_equal("elequint", FirstSpellWord())
392 call assert_equal("elekwint", SecondSpellWord())
393endfunc
394
Bram Moolenaar862f1e12019-04-10 22:33:41 +0200395func Test_spellfile_value()
396 set spellfile=Xdir/Xtest.latin1.add
397 set spellfile=Xdir/Xtest.utf-8.add,Xtest_other.add
398endfunc
399
Bram Moolenaaree03b942017-10-27 00:57:05 +0200400func Test_region_error()
401 messages clear
402 call writefile(["/regions=usgbnz", "elequint/0"], "Xtest.latin1.add")
403 mkspell! Xtest.latin1.add.spl Xtest.latin1.add
404 call assert_match('Invalid region nr in Xtest.latin1.add line 2: 0', execute('messages'))
405 call delete('Xtest.latin1.add')
406 call delete('Xtest.latin1.add.spl')
407endfunc
408
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200409" Check using z= in new buffer (crash fixed by patch 7.4a.028).
410func Test_zeq_crash()
411 new
412 set maxmem=512 spell
413 call feedkeys('iasdz=:\"', 'tx')
414
415 bwipe!
416endfunc
417
Bram Moolenaar5bcc5a12019-08-06 22:48:02 +0200418" Check handling a word longer than MAXWLEN.
419func Test_spell_long_word()
420 set enc=utf-8
421 new
422 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")
423 set spell spelllang=en
424 redraw
425 redraw!
426 bwipe!
427 set nospell
428endfunc
429
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200430func LoadAffAndDic(aff_contents, dic_contents)
431 set enc=latin1
432 set spellfile=
433 call writefile(a:aff_contents, "Xtest.aff")
434 call writefile(a:dic_contents, "Xtest.dic")
435 " Generate a .spl file from a .dic and .aff file.
436 mkspell! Xtest Xtest
437 " use that spell file
438 set spl=Xtest.latin1.spl spell
439endfunc
440
441func ListWords()
442 spelldump
443 %yank
444 quit
445 return split(@", "\n")
446endfunc
447
448func TestGoodBadBase()
449 exe '1;/^good:'
450 normal 0f:]s
451 let prevbad = ''
452 let result = []
453 while 1
454 let [bad, a] = spellbadword()
455 if bad == '' || bad == prevbad || bad == 'badend'
456 break
457 endif
458 let prevbad = bad
Bram Moolenaarf6ed61e2019-09-07 19:05:09 +0200459 let lst = bad->spellsuggest(3)
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200460 normal mm
461
462 call add(result, [bad, lst])
463 normal `m]s
464 endwhile
465 return result
466endfunc
467
468func RunGoodBad(good, bad, expected_words, expected_bad_words)
469 bwipe!
470 call setline(1, ["good: ", a:good, a:bad, " badend "])
471 let words = ListWords()
472 call assert_equal(a:expected_words, words[1:-1])
473 let bad_words = TestGoodBadBase()
474 call assert_equal(a:expected_bad_words, bad_words)
475 bwipe!
476endfunc
477
Bram Moolenaar7751d1d2019-10-18 20:37:08 +0200478func Test_spell_screendump()
479 CheckScreendump
480
481 let lines =<< trim END
482 call setline(1, [
483 \ "This is some text without any spell errors. Everything",
484 \ "should just be black, nothing wrong here.",
485 \ "",
486 \ "This line has a sepll error. and missing caps.",
487 \ "And and this is the the duplication.",
488 \ "with missing caps here.",
489 \ ])
490 set spell spelllang=en_nz
491 END
492 call writefile(lines, 'XtestSpell')
493 let buf = RunVimInTerminal('-S XtestSpell', {'rows': 8})
494 call VerifyScreenDump(buf, 'Test_spell_1', {})
495
496 " clean up
497 call StopVimInTerminal(buf)
498 call delete('XtestSpell')
499endfunc
500
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200501let g:test_data_aff1 = [
502 \"SET ISO8859-1",
503 \"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ",
504 \"",
505 \"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",
506 \"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",
507 \"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",
508 \"",
509 \"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",
510 \"SOFOTO ebctefghejklnnepkrstevvkesebctefghejklnnepkrstevvkeseeeeeeeceeeeeeeedneeeeeeeeeeepseeeeeeeeceeeeeeeedneeeeeeeeeeep?",
511 \"",
512 \"MIDWORD\t'-",
513 \"",
514 \"KEP =",
515 \"RAR ?",
516 \"BAD !",
517 \"",
518 \"PFX I N 1",
519 \"PFX I 0 in .",
520 \"",
521 \"PFX O Y 1",
522 \"PFX O 0 out .",
523 \"",
524 \"SFX S Y 2",
525 \"SFX S 0 s [^s]",
526 \"SFX S 0 es s",
527 \"",
528 \"SFX N N 3",
529 \"SFX N 0 en [^n]",
530 \"SFX N 0 nen n",
531 \"SFX N 0 n .",
532 \"",
533 \"REP 3",
534 \"REP g ch",
535 \"REP ch g",
536 \"REP svp s.v.p.",
537 \"",
538 \"MAP 9",
539 \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
540 \"MAP e\xE8\xE9\xEA\xEB",
541 \"MAP i\xEC\xED\xEE\xEF",
542 \"MAP o\xF2\xF3\xF4\xF5\xF6",
543 \"MAP u\xF9\xFA\xFB\xFC",
544 \"MAP n\xF1",
545 \"MAP c\xE7",
546 \"MAP y\xFF\xFD",
547 \"MAP s\xDF",
548 \ ]
549let g:test_data_dic1 = [
550 \"123456",
551 \"test/NO",
552 \"# comment",
553 \"wrong",
554 \"Comment",
555 \"OK",
556 \"uk",
557 \"put/ISO",
558 \"the end",
559 \"deol",
560 \"d\xE9\xF4r",
561 \ ]
562let g:test_data_aff2 = [
563 \"SET ISO8859-1",
564 \"",
565 \"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",
566 \"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",
567 \"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",
568 \"",
569 \"PFXPOSTPONE",
570 \"",
571 \"MIDWORD\t'-",
572 \"",
573 \"KEP =",
574 \"RAR ?",
575 \"BAD !",
576 \"",
577 \"PFX I N 1",
578 \"PFX I 0 in .",
579 \"",
580 \"PFX O Y 1",
581 \"PFX O 0 out [a-z]",
582 \"",
583 \"SFX S Y 2",
584 \"SFX S 0 s [^s]",
585 \"SFX S 0 es s",
586 \"",
587 \"SFX N N 3",
588 \"SFX N 0 en [^n]",
589 \"SFX N 0 nen n",
590 \"SFX N 0 n .",
591 \"",
592 \"REP 3",
593 \"REP g ch",
594 \"REP ch g",
595 \"REP svp s.v.p.",
596 \"",
597 \"MAP 9",
598 \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
599 \"MAP e\xE8\xE9\xEA\xEB",
600 \"MAP i\xEC\xED\xEE\xEF",
601 \"MAP o\xF2\xF3\xF4\xF5\xF6",
602 \"MAP u\xF9\xFA\xFB\xFC",
603 \"MAP n\xF1",
604 \"MAP c\xE7",
605 \"MAP y\xFF\xFD",
606 \"MAP s\xDF",
607 \ ]
608let g:test_data_aff3 = [
609 \"SET ISO8859-1",
610 \"",
611 \"COMPOUNDMIN 3",
612 \"COMPOUNDRULE m*",
613 \"NEEDCOMPOUND x",
614 \ ]
615let g:test_data_dic3 = [
616 \"1234",
617 \"foo/m",
618 \"bar/mx",
619 \"m\xEF/m",
620 \"la/mx",
621 \ ]
622let g:test_data_aff4 = [
623 \"SET ISO8859-1",
624 \"",
625 \"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",
626 \"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",
627 \"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",
628 \"",
629 \"COMPOUNDRULE m+",
630 \"COMPOUNDRULE sm*e",
631 \"COMPOUNDRULE sm+",
632 \"COMPOUNDMIN 3",
633 \"COMPOUNDWORDMAX 3",
634 \"COMPOUNDFORBIDFLAG t",
635 \"",
636 \"COMPOUNDSYLMAX 5",
637 \"SYLLABLE a\xE1e\xE9i\xEDo\xF3\xF6\xF5u\xFA\xFC\xFBy/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui",
638 \"",
639 \"MAP 9",
640 \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
641 \"MAP e\xE8\xE9\xEA\xEB",
642 \"MAP i\xEC\xED\xEE\xEF",
643 \"MAP o\xF2\xF3\xF4\xF5\xF6",
644 \"MAP u\xF9\xFA\xFB\xFC",
645 \"MAP n\xF1",
646 \"MAP c\xE7",
647 \"MAP y\xFF\xFD",
648 \"MAP s\xDF",
649 \"",
650 \"NEEDAFFIX x",
651 \"",
652 \"PFXPOSTPONE",
653 \"",
654 \"MIDWORD '-",
655 \"",
656 \"SFX q N 1",
657 \"SFX q 0 -ok .",
658 \"",
659 \"SFX a Y 2",
660 \"SFX a 0 s .",
661 \"SFX a 0 ize/t .",
662 \"",
663 \"PFX p N 1",
664 \"PFX p 0 pre .",
665 \"",
666 \"PFX P N 1",
667 \"PFX P 0 nou .",
668 \ ]
669let g:test_data_dic4 = [
670 \"1234",
671 \"word/mP",
672 \"util/am",
673 \"pro/xq",
674 \"tomato/m",
675 \"bork/mp",
676 \"start/s",
677 \"end/e",
678 \ ]
679let g:test_data_aff5 = [
680 \"SET ISO8859-1",
681 \"",
682 \"FLAG long",
683 \"",
684 \"NEEDAFFIX !!",
685 \"",
686 \"COMPOUNDRULE ssmm*ee",
687 \"",
688 \"NEEDCOMPOUND xx",
689 \"COMPOUNDPERMITFLAG pp",
690 \"",
691 \"SFX 13 Y 1",
692 \"SFX 13 0 bork .",
693 \"",
694 \"SFX a1 Y 1",
695 \"SFX a1 0 a1 .",
696 \"",
697 \"SFX a\xE9 Y 1",
698 \"SFX a\xE9 0 a\xE9 .",
699 \"",
700 \"PFX zz Y 1",
701 \"PFX zz 0 pre/pp .",
702 \"",
703 \"PFX yy Y 1",
704 \"PFX yy 0 nou .",
705 \ ]
706let g:test_data_dic5 = [
707 \"1234",
708 \"foo/a1a\xE9!!",
709 \"bar/zz13ee",
710 \"start/ss",
711 \"end/eeyy",
712 \"middle/mmxx",
713 \ ]
714let g:test_data_aff6 = [
715 \"SET ISO8859-1",
716 \"",
717 \"FLAG caplong",
718 \"",
719 \"NEEDAFFIX A!",
720 \"",
721 \"COMPOUNDRULE sMm*Ee",
722 \"",
723 \"NEEDCOMPOUND Xx",
724 \"",
725 \"COMPOUNDPERMITFLAG p",
726 \"",
727 \"SFX N3 Y 1",
728 \"SFX N3 0 bork .",
729 \"",
730 \"SFX A1 Y 1",
731 \"SFX A1 0 a1 .",
732 \"",
733 \"SFX A\xE9 Y 1",
734 \"SFX A\xE9 0 a\xE9 .",
735 \"",
736 \"PFX Zz Y 1",
737 \"PFX Zz 0 pre/p .",
738 \ ]
739let g:test_data_dic6 = [
740 \"1234",
741 \"mee/A1A\xE9A!",
742 \"bar/ZzN3Ee",
743 \"lead/s",
744 \"end/Ee",
745 \"middle/MmXx",
746 \ ]
747let g:test_data_aff7 = [
748 \"SET ISO8859-1",
749 \"",
750 \"FLAG num",
751 \"",
752 \"NEEDAFFIX 9999",
753 \"",
754 \"COMPOUNDRULE 2,77*123",
755 \"",
756 \"NEEDCOMPOUND 1",
757 \"COMPOUNDPERMITFLAG 432",
758 \"",
759 \"SFX 61003 Y 1",
760 \"SFX 61003 0 meat .",
761 \"",
Bram Moolenaar3d2a47c2019-11-07 20:48:42 +0100762 \"SFX 0 Y 1",
763 \"SFX 0 0 zero .",
764 \"",
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200765 \"SFX 391 Y 1",
766 \"SFX 391 0 a1 .",
767 \"",
768 \"SFX 111 Y 1",
769 \"SFX 111 0 a\xE9 .",
770 \"",
771 \"PFX 17 Y 1",
772 \"PFX 17 0 pre/432 .",
773 \ ]
774let g:test_data_dic7 = [
775 \"1234",
Bram Moolenaar3d2a47c2019-11-07 20:48:42 +0100776 \"mee/0,391,111,9999",
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200777 \"bar/17,61003,123",
778 \"lead/2",
779 \"tail/123",
780 \"middle/77,1",
781 \ ]
782let g:test_data_aff8 = [
783 \"SET ISO8859-1",
784 \"",
785 \"NOSPLITSUGS",
786 \ ]
787let g:test_data_dic8 = [
788 \"1234",
789 \"foo",
790 \"bar",
791 \"faabar",
792 \ ]
793let g:test_data_aff9 = [
794 \ ]
795let g:test_data_dic9 = [
796 \"1234",
797 \"foo",
798 \"bar",
799 \ ]
Bram Moolenaar37ff4cf2019-11-17 20:10:20 +0100800let g:test_data_aff10 = [
801 \"COMPOUNDRULE se",
802 \"COMPOUNDPERMITFLAG p",
803 \"",
804 \"SFX A Y 1",
805 \"SFX A 0 able/Mp .",
806 \"",
807 \"SFX M Y 1",
808 \"SFX M 0 s .",
809 \ ]
810let g:test_data_dic10 = [
811 \"1234",
812 \"drink/As",
813 \"table/e",
814 \ ]
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200815let g:test_data_aff_sal = [
816 \"SET ISO8859-1",
817 \"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ",
818 \"",
819 \"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",
820 \"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",
821 \"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",
822 \"",
823 \"MIDWORD\t'-",
824 \"",
825 \"KEP =",
826 \"RAR ?",
827 \"BAD !",
828 \"",
829 \"PFX I N 1",
830 \"PFX I 0 in .",
831 \"",
832 \"PFX O Y 1",
833 \"PFX O 0 out .",
834 \"",
835 \"SFX S Y 2",
836 \"SFX S 0 s [^s]",
837 \"SFX S 0 es s",
838 \"",
839 \"SFX N N 3",
840 \"SFX N 0 en [^n]",
841 \"SFX N 0 nen n",
842 \"SFX N 0 n .",
843 \"",
844 \"REP 3",
845 \"REP g ch",
846 \"REP ch g",
847 \"REP svp s.v.p.",
848 \"",
849 \"MAP 9",
850 \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
851 \"MAP e\xE8\xE9\xEA\xEB",
852 \"MAP i\xEC\xED\xEE\xEF",
853 \"MAP o\xF2\xF3\xF4\xF5\xF6",
854 \"MAP u\xF9\xFA\xFB\xFC",
855 \"MAP n\xF1",
856 \"MAP c\xE7",
857 \"MAP y\xFF\xFD",
858 \"MAP s\xDF",
859 \"",
860 \"SAL AH(AEIOUY)-^ *H",
861 \"SAL AR(AEIOUY)-^ *R",
862 \"SAL A(HR)^ *",
863 \"SAL A^ *",
864 \"SAL AH(AEIOUY)- H",
865 \"SAL AR(AEIOUY)- R",
866 \"SAL A(HR) _",
867 \"SAL \xC0^ *",
868 \"SAL \xC5^ *",
869 \"SAL BB- _",
870 \"SAL B B",
871 \"SAL CQ- _",
872 \"SAL CIA X",
873 \"SAL CH X",
874 \"SAL C(EIY)- S",
875 \"SAL CK K",
876 \"SAL COUGH^ KF",
877 \"SAL CC< C",
878 \"SAL C K",
879 \"SAL DG(EIY) K",
880 \"SAL DD- _",
881 \"SAL D T",
882 \"SAL \xC9< E",
883 \"SAL EH(AEIOUY)-^ *H",
884 \"SAL ER(AEIOUY)-^ *R",
885 \"SAL E(HR)^ *",
886 \"SAL ENOUGH^$ *NF",
887 \"SAL E^ *",
888 \"SAL EH(AEIOUY)- H",
889 \"SAL ER(AEIOUY)- R",
890 \"SAL E(HR) _",
891 \"SAL FF- _",
892 \"SAL F F",
893 \"SAL GN^ N",
894 \"SAL GN$ N",
895 \"SAL GNS$ NS",
896 \"SAL GNED$ N",
897 \"SAL GH(AEIOUY)- K",
898 \"SAL GH _",
899 \"SAL GG9 K",
900 \"SAL G K",
901 \"SAL H H",
902 \"SAL IH(AEIOUY)-^ *H",
903 \"SAL IR(AEIOUY)-^ *R",
904 \"SAL I(HR)^ *",
905 \"SAL I^ *",
906 \"SAL ING6 N",
907 \"SAL IH(AEIOUY)- H",
908 \"SAL IR(AEIOUY)- R",
909 \"SAL I(HR) _",
910 \"SAL J K",
911 \"SAL KN^ N",
912 \"SAL KK- _",
913 \"SAL K K",
914 \"SAL LAUGH^ LF",
915 \"SAL LL- _",
916 \"SAL L L",
917 \"SAL MB$ M",
918 \"SAL MM M",
919 \"SAL M M",
920 \"SAL NN- _",
921 \"SAL N N",
922 \"SAL OH(AEIOUY)-^ *H",
923 \"SAL OR(AEIOUY)-^ *R",
924 \"SAL O(HR)^ *",
925 \"SAL O^ *",
926 \"SAL OH(AEIOUY)- H",
927 \"SAL OR(AEIOUY)- R",
928 \"SAL O(HR) _",
929 \"SAL PH F",
930 \"SAL PN^ N",
931 \"SAL PP- _",
932 \"SAL P P",
933 \"SAL Q K",
934 \"SAL RH^ R",
935 \"SAL ROUGH^ RF",
936 \"SAL RR- _",
937 \"SAL R R",
938 \"SAL SCH(EOU)- SK",
939 \"SAL SC(IEY)- S",
940 \"SAL SH X",
941 \"SAL SI(AO)- X",
942 \"SAL SS- _",
943 \"SAL S S",
944 \"SAL TI(AO)- X",
945 \"SAL TH @",
946 \"SAL TCH-- _",
947 \"SAL TOUGH^ TF",
948 \"SAL TT- _",
949 \"SAL T T",
950 \"SAL UH(AEIOUY)-^ *H",
951 \"SAL UR(AEIOUY)-^ *R",
952 \"SAL U(HR)^ *",
953 \"SAL U^ *",
954 \"SAL UH(AEIOUY)- H",
955 \"SAL UR(AEIOUY)- R",
956 \"SAL U(HR) _",
957 \"SAL V^ W",
958 \"SAL V F",
959 \"SAL WR^ R",
960 \"SAL WH^ W",
961 \"SAL W(AEIOU)- W",
962 \"SAL X^ S",
963 \"SAL X KS",
964 \"SAL Y(AEIOU)- Y",
965 \"SAL ZZ- _",
966 \"SAL Z S",
967 \ ]