blob: aa5744475338fae570c03379efba506c0995708f [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
Bram Moolenaar362b44b2020-06-10 21:47:00 +020080 call assert_equal(['TheCamelWord', 'bad'], 'TheCamelWord asdf'->spellbadword())
81 set spelloptions=camel
82 call assert_equal(['asdf', 'bad'], 'TheCamelWord asdf'->spellbadword())
83 set spelloptions=
84
Bram Moolenaar872e4512018-07-20 23:36:26 +020085 set spelllang=en
86 call assert_equal(['', ''], spellbadword('centre'))
87 call assert_equal(['', ''], spellbadword('center'))
88 set spelllang=en_us
89 call assert_equal(['centre', 'local'], spellbadword('centre'))
90 call assert_equal(['', ''], spellbadword('center'))
91 set spelllang=en_gb
92 call assert_equal(['', ''], spellbadword('centre'))
93 call assert_equal(['center', 'local'], spellbadword('center'))
94
95 " Create a small word list to test that spellbadword('...')
96 " can return ['...', 'rare'].
97 e Xwords
98 insert
99foo
100foobar/?
101.
102 w!
103 mkspell! Xwords.spl Xwords
104 set spelllang=Xwords.spl
105 call assert_equal(['foobar', 'rare'], spellbadword('foo foobar'))
106
Bram Moolenaar152e79e2020-06-10 15:32:08 +0200107 " Typo should be detected even without the 'spell' option.
Bram Moolenaar872e4512018-07-20 23:36:26 +0200108 set spelllang=en_gb nospell
109 call assert_equal(['', ''], spellbadword('centre'))
Bram Moolenaar152e79e2020-06-10 15:32:08 +0200110 call assert_equal(['bycycle', 'bad'], spellbadword('My bycycle.'))
111 call assert_equal(['another', 'caps'], spellbadword('A sentence. another sentence'))
112
113 set spelllang=
114 call assert_fails("call spellbadword('maxch')", 'E756:')
Bram Moolenaar96fdf432020-09-11 18:11:50 +0200115 call assert_fails("spelldump", 'E756:')
Bram Moolenaar872e4512018-07-20 23:36:26 +0200116
117 call delete('Xwords.spl')
118 call delete('Xwords')
119 set spelllang&
120 set spell&
121endfunc
122
Bram Moolenaard569a9e2020-09-28 23:13:15 +0200123func Test_spell_file_missing()
124 let s:spell_file_missing = 0
125 augroup TestSpellFileMissing
126 autocmd! SpellFileMissing * let s:spell_file_missing += 1
127 augroup END
128
129 set spell spelllang=ab_cd
130 let messages = GetMessages()
131 call assert_equal('Warning: Cannot find word list "ab.utf-8.spl" or "ab.ascii.spl"', messages[-1])
132 call assert_equal(1, s:spell_file_missing)
133
134 new XTestSpellFileMissing
135 augroup TestSpellFileMissing
136 autocmd! SpellFileMissing * bwipe
137 augroup END
138 call assert_fails('set spell spelllang=ab_cd', 'E797:')
139
Bram Moolenaarfc9f0fd2022-06-15 16:57:44 +0100140 " clean up
141 augroup TestSpellFileMissing
142 autocmd! SpellFileMissing
143 augroup END
Bram Moolenaard569a9e2020-09-28 23:13:15 +0200144 augroup! TestSpellFileMissing
145 unlet s:spell_file_missing
146 set spell& spelllang&
147 %bwipe!
148endfunc
149
Bram Moolenaarf12f0022020-10-07 12:58:44 +0200150func Test_spelldump()
Bram Moolenaarfc9f0fd2022-06-15 16:57:44 +0100151 " In case the spell file is not found avoid getting the download dialog, we
152 " would get stuck at the prompt.
153 let g:en_not_found = 0
154 augroup TestSpellFileMissing
155 au! SpellFileMissing * let g:en_not_found = 1
156 augroup END
Bram Moolenaarf12f0022020-10-07 12:58:44 +0200157 set spell spelllang=en
158 spellrare! emacs
Bram Moolenaarfc9f0fd2022-06-15 16:57:44 +0100159 if g:en_not_found
160 call assert_report("Could not find English spell file")
161 else
162 spelldump
Bram Moolenaarf12f0022020-10-07 12:58:44 +0200163
Bram Moolenaarfc9f0fd2022-06-15 16:57:44 +0100164 " Check assumption about region: 1: us, 2: au, 3: ca, 4: gb, 5: nz.
165 call assert_equal('/regions=usaucagbnz', getline(1))
166 call assert_notequal(0, search('^theater/1$')) " US English only.
167 call assert_notequal(0, search('^theatre/2345$')) " AU, CA, GB or NZ English.
Bram Moolenaarf12f0022020-10-07 12:58:44 +0200168
Bram Moolenaarfc9f0fd2022-06-15 16:57:44 +0100169 call assert_notequal(0, search('^emacs/?$')) " ? for a rare word.
170 call assert_notequal(0, search('^the the/!$')) " ! for a wrong word.
171 endif
Bram Moolenaarf12f0022020-10-07 12:58:44 +0200172
Bram Moolenaarfc9f0fd2022-06-15 16:57:44 +0100173 " clean up
174 unlet g:en_not_found
175 augroup TestSpellFileMissing
176 autocmd! SpellFileMissing
177 augroup END
178 augroup! TestSpellFileMissing
Bram Moolenaarf12f0022020-10-07 12:58:44 +0200179 bwipe
180 set spell&
181endfunc
182
183func Test_spelldump_bang()
184 new
185 call setline(1, 'This is a sample sentence.')
186 redraw
Bram Moolenaarfc9f0fd2022-06-15 16:57:44 +0100187
188 " In case the spell file is not found avoid getting the download dialog, we
189 " would get stuck at the prompt.
190 let g:en_not_found = 0
191 augroup TestSpellFileMissing
192 au! SpellFileMissing * let g:en_not_found = 1
193 augroup END
194
Bram Moolenaarf12f0022020-10-07 12:58:44 +0200195 set spell
Bram Moolenaarf12f0022020-10-07 12:58:44 +0200196
Bram Moolenaarfc9f0fd2022-06-15 16:57:44 +0100197 if g:en_not_found
198 call assert_report("Could not find English spell file")
199 else
200 redraw
201 spelldump!
Bram Moolenaarf12f0022020-10-07 12:58:44 +0200202
Bram Moolenaarfc9f0fd2022-06-15 16:57:44 +0100203 " :spelldump! includes the number of times a word was found while updating
204 " the screen.
205 " Common word count starts at 10, regular word count starts at 0.
206 call assert_notequal(0, search("^is\t11$")) " common word found once.
207 call assert_notequal(0, search("^the\t10$")) " common word never found.
208 call assert_notequal(0, search("^sample\t1$")) " regular word found once.
209 call assert_equal(0, search("^screen\t")) " regular word never found.
210 endif
211
212 " clean up
213 unlet g:en_not_found
214 augroup TestSpellFileMissing
215 autocmd! SpellFileMissing
216 augroup END
217 augroup! TestSpellFileMissing
Bram Moolenaarf12f0022020-10-07 12:58:44 +0200218 %bwipe!
219 set spell&
220endfunc
221
Bram Moolenaar8c7ad362020-09-27 13:58:38 +0200222func Test_spelllang_inv_region()
223 set spell spelllang=en_xx
224 let messages = GetMessages()
225 call assert_equal('Warning: region xx not supported', messages[-1])
226 set spell& spelllang&
227endfunc
228
229func Test_compl_with_CTRL_X_CTRL_K_using_spell()
230 " When spell checking is enabled and 'dictionary' is empty,
231 " CTRL-X CTRL-K in insert mode completes using the spelling dictionary.
232 new
233 set spell spelllang=en dictionary=
234
235 set ignorecase
236 call feedkeys("Senglis\<c-x>\<c-k>\<esc>", 'tnx')
237 call assert_equal(['English'], getline(1, '$'))
238 call feedkeys("SEnglis\<c-x>\<c-k>\<esc>", 'tnx')
239 call assert_equal(['English'], getline(1, '$'))
240
241 set noignorecase
242 call feedkeys("Senglis\<c-x>\<c-k>\<esc>", 'tnx')
243 call assert_equal(['englis'], getline(1, '$'))
244 call feedkeys("SEnglis\<c-x>\<c-k>\<esc>", 'tnx')
245 call assert_equal(['English'], getline(1, '$'))
246
247 set spelllang=en_us
248 call feedkeys("Stheat\<c-x>\<c-k>\<esc>", 'tnx')
249 call assert_equal(['theater'], getline(1, '$'))
250 set spelllang=en_gb
251 call feedkeys("Stheat\<c-x>\<c-k>\<esc>", 'tnx')
252 " FIXME: commented out, expected theatre bug got theater. See issue #7025.
253 " call assert_equal(['theatre'], getline(1, '$'))
254
255 bwipe!
256 set spell& spelllang& dictionary& ignorecase&
257endfunc
258
Bram Moolenaar545cb792017-05-23 11:31:22 +0200259func Test_spellreall()
260 new
261 set spell
262 call assert_fails('spellrepall', 'E752:')
263 call setline(1, ['A speling mistake. The same speling mistake.',
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200264 \ 'Another speling mistake.'])
Bram Moolenaar545cb792017-05-23 11:31:22 +0200265 call feedkeys(']s1z=', 'tx')
266 call assert_equal('A spelling mistake. The same speling mistake.', getline(1))
267 call assert_equal('Another speling mistake.', getline(2))
268 spellrepall
269 call assert_equal('A spelling mistake. The same spelling mistake.', getline(1))
270 call assert_equal('Another spelling mistake.', getline(2))
271 call assert_fails('spellrepall', 'E753:')
272 set spell&
273 bwipe!
274endfunc
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200275
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100276" Test spellsuggest({word} [, {max} [, {capital}]])
277func Test_spellsuggest()
Bram Moolenaar152e79e2020-06-10 15:32:08 +0200278 " Verify suggestions are given even when spell checking is not enabled.
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100279 set nospell
Bram Moolenaar152e79e2020-06-10 15:32:08 +0200280 call assert_equal(['march', 'March'], spellsuggest('marrch', 2))
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100281
282 set spell
283
284 " With 1 argument.
Bram Moolenaar76734052019-12-26 14:30:15 +0100285 call assert_equal(['march', 'March'], spellsuggest('marrch')[0:1])
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100286
287 " With 2 arguments.
Bram Moolenaar76734052019-12-26 14:30:15 +0100288 call assert_equal(['march', 'March'], spellsuggest('marrch', 2))
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100289
290 " With 3 arguments.
Bram Moolenaar76734052019-12-26 14:30:15 +0100291 call assert_equal(['march'], spellsuggest('marrch', 1, 0))
292 call assert_equal(['March'], spellsuggest('marrch', 1, 1))
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100293
294 " Test with digits and hyphen.
295 call assert_equal('Carbon-14', spellsuggest('Carbon-15')[0])
296
297 " Comment taken from spellsuggest.c explains the following test cases:
298 "
299 " If there are more UPPER than lower case letters suggest an
300 " ALLCAP word. Otherwise, if the first letter is UPPER then
301 " suggest ONECAP. Exception: "ALl" most likely should be "All",
302 " require three upper case letters.
Bram Moolenaar76734052019-12-26 14:30:15 +0100303 call assert_equal(['THIRD', 'third'], spellsuggest('thIRD', 2))
304 call assert_equal(['third', 'THIRD'], spellsuggest('tHIrd', 2))
305 call assert_equal(['Third'], spellsuggest('THird', 1))
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100306 call assert_equal(['All'], spellsuggest('ALl', 1))
307
Dominique Pellef645ee42021-12-05 13:21:18 +0000308 " Special suggestion for repeated 'the the'.
309 call assert_inrange(0, 2, index(spellsuggest('the the', 3), 'the'))
310 call assert_inrange(0, 2, index(spellsuggest('the the', 3), 'the'))
311 call assert_inrange(0, 2, index(spellsuggest('The the', 3), 'The'))
312
Bram Moolenaar0e05de42020-03-25 22:23:46 +0100313 call assert_fails("call spellsuggest('maxch', [])", 'E745:')
314 call assert_fails("call spellsuggest('maxch', 2, [])", 'E745:')
315
Bram Moolenaar152e79e2020-06-10 15:32:08 +0200316 set spelllang=
317 call assert_fails("call spellsuggest('maxch')", 'E756:')
318 set spelllang&
319
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100320 set spell&
321endfunc
322
323" Test 'spellsuggest' option with methods fast, best and double.
324func Test_spellsuggest_option_methods()
325 set spell
326
Bram Moolenaar76734052019-12-26 14:30:15 +0100327 for e in ['latin1', 'utf-8']
328 exe 'set encoding=' .. e
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100329
Bram Moolenaar76734052019-12-26 14:30:15 +0100330 set spellsuggest=fast
331 call assert_equal(['Stick', 'Stitch'], spellsuggest('Stich', 2), e)
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100332
Bram Moolenaar76734052019-12-26 14:30:15 +0100333 " With best or double option, "Stitch" should become the top suggestion
334 " because of better phonetic matching.
335 set spellsuggest=best
336 call assert_equal(['Stitch', 'Stick'], spellsuggest('Stich', 2), e)
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100337
Bram Moolenaar76734052019-12-26 14:30:15 +0100338 set spellsuggest=double
339 call assert_equal(['Stitch', 'Stick'], spellsuggest('Stich', 2), e)
340 endfor
341
342 set spell& spellsuggest& encoding&
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100343endfunc
344
345" Test 'spellsuggest' option with value file:{filename}
346func Test_spellsuggest_option_file()
347 set spell spellsuggest=file:Xspellsuggest
348 call writefile(['emacs/vim',
349 \ 'theribal/terrible',
350 \ 'teribal/terrrible',
351 \ 'terribal'],
352 \ 'Xspellsuggest')
353
354 call assert_equal(['vim'], spellsuggest('emacs', 2))
355 call assert_equal(['terrible'], spellsuggest('theribal',2))
356
357 " If the suggestion is misspelled (*terrrible* with 3 r),
358 " it should not be proposed.
359 " The entry for "terribal" should be ignored because of missing slash.
360 call assert_equal([], spellsuggest('teribal', 2))
361 call assert_equal([], spellsuggest('terribal', 2))
362
363 set spell spellsuggest=best,file:Xspellsuggest
364 call assert_equal(['vim', 'Emacs'], spellsuggest('emacs', 2))
365 call assert_equal(['terrible', 'tribal'], spellsuggest('theribal', 2))
366 call assert_equal(['tribal'], spellsuggest('teribal', 1))
367 call assert_equal(['tribal'], spellsuggest('terribal', 1))
368
369 call delete('Xspellsuggest')
370 call assert_fails("call spellsuggest('vim')", "E484: Can't open file Xspellsuggest")
371
372 set spellsuggest& spell&
373endfunc
374
375" Test 'spellsuggest' option with value {number}
376" to limit the number of suggestions
377func Test_spellsuggest_option_number()
378 set spell spellsuggest=2,best
379 new
380
381 " We limited the number of suggestions to 2, so selecting
382 " the 1st and 2nd suggestion should correct the word, but
383 " selecting a 3rd suggestion should do nothing.
Bram Moolenaar76734052019-12-26 14:30:15 +0100384 call setline(1, 'A baord')
385 norm $1z=
386 call assert_equal('A board', getline(1))
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100387
Bram Moolenaar76734052019-12-26 14:30:15 +0100388 call setline(1, 'A baord')
389 norm $2z=
390 call assert_equal('A bard', getline(1))
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100391
Bram Moolenaar76734052019-12-26 14:30:15 +0100392 call setline(1, 'A baord')
393 norm $3z=
394 call assert_equal('A baord', getline(1))
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100395
Bram Moolenaar76734052019-12-26 14:30:15 +0100396 let a = execute('norm $z=')
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100397 call assert_equal(
398 \ "\n"
Bram Moolenaar76734052019-12-26 14:30:15 +0100399 \ .. "Change \"baord\" to:\n"
400 \ .. " 1 \"board\"\n"
401 \ .. " 2 \"bard\"\n"
Bram Moolenaard281b7c2020-06-10 16:39:32 +0200402 \ .. "Type number and <Enter> or click with the mouse (q or empty cancels): ", a)
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100403
404 set spell spellsuggest=0
Bram Moolenaar76734052019-12-26 14:30:15 +0100405 call assert_equal("\nSorry, no suggestions", execute('norm $z='))
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100406
407 " Unlike z=, function spellsuggest(...) should not be affected by the
408 " max number of suggestions (2) set by the 'spellsuggest' option.
Bram Moolenaar76734052019-12-26 14:30:15 +0100409 call assert_equal(['board', 'bard', 'broad'], spellsuggest('baord', 3))
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100410
411 set spellsuggest& spell&
412 bwipe!
413endfunc
414
415" Test 'spellsuggest' option with value expr:{expr}
416func Test_spellsuggest_option_expr()
417 " A silly 'spellsuggest' function which makes suggestions all uppercase
418 " and makes the score of each suggestion the length of the suggested word.
419 " So shorter suggestions are preferred.
420 func MySuggest()
421 let spellsuggest_save = &spellsuggest
Bram Moolenaar76734052019-12-26 14:30:15 +0100422 set spellsuggest=3,best
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100423 let result = map(spellsuggest(v:val, 3), "[toupper(v:val), len(v:val)]")
424 let &spellsuggest = spellsuggest_save
425 return result
426 endfunc
427
Bram Moolenaar76734052019-12-26 14:30:15 +0100428 set spell spellsuggest=expr:MySuggest()
429 call assert_equal(['BARD', 'BOARD', 'BROAD'], spellsuggest('baord', 3))
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100430
431 new
Bram Moolenaar76734052019-12-26 14:30:15 +0100432 call setline(1, 'baord')
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100433 let a = execute('norm z=')
434 call assert_equal(
435 \ "\n"
Bram Moolenaar76734052019-12-26 14:30:15 +0100436 \ .. "Change \"baord\" to:\n"
437 \ .. " 1 \"BARD\"\n"
438 \ .. " 2 \"BOARD\"\n"
439 \ .. " 3 \"BROAD\"\n"
Bram Moolenaard281b7c2020-06-10 16:39:32 +0200440 \ .. "Type number and <Enter> or click with the mouse (q or empty cancels): ", a)
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100441
442 " With verbose, z= should show the score i.e. word length with
443 " our SpellSuggest() function.
444 set verbose=1
445 let a = execute('norm z=')
446 call assert_equal(
447 \ "\n"
Bram Moolenaar76734052019-12-26 14:30:15 +0100448 \ .. "Change \"baord\" to:\n"
449 \ .. " 1 \"BARD\" (4 - 0)\n"
450 \ .. " 2 \"BOARD\" (5 - 0)\n"
451 \ .. " 3 \"BROAD\" (5 - 0)\n"
Bram Moolenaard281b7c2020-06-10 16:39:32 +0200452 \ .. "Type number and <Enter> or click with the mouse (q or empty cancels): ", a)
Bram Moolenaare9a8d1f2019-12-25 13:36:36 +0100453
454 set spell& spellsuggest& verbose&
455 bwipe!
456endfunc
457
Dominique Pelle81b573d2022-03-22 21:14:55 +0000458" Test for 'spellsuggest' expr errors
Bram Moolenaar8dfcce32020-03-18 19:32:26 +0100459func Test_spellsuggest_expr_errors()
460 " 'spellsuggest'
461 func MySuggest()
462 return range(3)
463 endfunc
464 set spell spellsuggest=expr:MySuggest()
465 call assert_equal([], spellsuggest('baord', 3))
466
467 " Test for 'spellsuggest' expression returning a non-list value
468 func! MySuggest2()
469 return 'good'
470 endfunc
471 set spellsuggest=expr:MySuggest2()
472 call assert_equal([], spellsuggest('baord'))
473
474 " Test for 'spellsuggest' expression returning a list with dict values
475 func! MySuggest3()
476 return [[{}, {}]]
477 endfunc
478 set spellsuggest=expr:MySuggest3()
Bram Moolenaar9b7bf9e2020-07-11 22:14:59 +0200479 call assert_fails("call spellsuggest('baord')", 'E731:')
Bram Moolenaar8dfcce32020-03-18 19:32:26 +0100480
481 set nospell spellsuggest&
482 delfunc MySuggest
483 delfunc MySuggest2
484 delfunc MySuggest3
485endfunc
486
Bram Moolenaar585ee072022-01-29 11:22:17 +0000487func Test_spellsuggest_timeout()
488 set spellsuggest=timeout:30
489 set spellsuggest=timeout:-123
490 set spellsuggest=timeout:999999
491 call assert_fails('set spellsuggest=timeout', 'E474:')
492 call assert_fails('set spellsuggest=timeout:x', 'E474:')
493 call assert_fails('set spellsuggest=timeout:-x', 'E474:')
494 call assert_fails('set spellsuggest=timeout:--9', 'E474:')
495endfunc
496
Bram Moolenaar5c686172022-03-13 20:12:25 +0000497func Test_spellsuggest_visual_end_of_line()
498 let enc_save = &encoding
499 set encoding=iso8859
500
501 " This was reading beyond the end of the line.
502 norm R00000000000
503 sil norm 0
504 sil! norm i00000)
505 sil! norm i00000)
506 call feedkeys("\<CR>")
507 norm z=
508
509 let &encoding = enc_save
510endfunc
511
Bram Moolenaar9049b682018-08-31 22:26:53 +0200512func Test_spellinfo()
513 new
Bram Moolenaarc25e7022019-10-10 14:08:26 +0200514 let runtime = substitute($VIMRUNTIME, '\\', '/', 'g')
Bram Moolenaar9049b682018-08-31 22:26:53 +0200515
516 set enc=latin1 spell spelllang=en
Bram Moolenaarc25e7022019-10-10 14:08:26 +0200517 call assert_match("^\nfile: " .. runtime .. "/spell/en.latin1.spl\n$", execute('spellinfo'))
Bram Moolenaar9049b682018-08-31 22:26:53 +0200518
519 set enc=cp1250 spell spelllang=en
Bram Moolenaarc25e7022019-10-10 14:08:26 +0200520 call assert_match("^\nfile: " .. runtime .. "/spell/en.ascii.spl\n$", execute('spellinfo'))
Bram Moolenaar9049b682018-08-31 22:26:53 +0200521
Bram Moolenaar30276f22019-01-24 17:59:39 +0100522 set enc=utf-8 spell spelllang=en
Bram Moolenaarc25e7022019-10-10 14:08:26 +0200523 call assert_match("^\nfile: " .. runtime .. "/spell/en.utf-8.spl\n$", execute('spellinfo'))
Bram Moolenaar9049b682018-08-31 22:26:53 +0200524
525 set enc=latin1 spell spelllang=en_us,en_nz
526 call assert_match("^\n" .
Bram Moolenaarc25e7022019-10-10 14:08:26 +0200527 \ "file: " .. runtime .. "/spell/en.latin1.spl\n" .
528 \ "file: " .. runtime.. "/spell/en.latin1.spl\n$", execute('spellinfo'))
Bram Moolenaar9049b682018-08-31 22:26:53 +0200529
530 set spell spelllang=
531 call assert_fails('spellinfo', 'E756:')
532
533 set nospell spelllang=en
534 call assert_fails('spellinfo', 'E756:')
535
Bram Moolenaar8f130ed2019-04-10 22:15:19 +0200536 call assert_fails('set spelllang=foo/bar', 'E474:')
537 call assert_fails('set spelllang=foo\ bar', 'E474:')
538 call assert_fails("set spelllang=foo\\\nbar", 'E474:')
539 call assert_fails("set spelllang=foo\\\rbar", 'E474:')
540 call assert_fails("set spelllang=foo+bar", 'E474:')
541
Bram Moolenaar9049b682018-08-31 22:26:53 +0200542 set enc& spell& spelllang&
543 bwipe
544endfunc
545
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200546func Test_zz_basic()
547 call LoadAffAndDic(g:test_data_aff1, g:test_data_dic1)
548 call RunGoodBad("wrong OK puts. Test the end",
549 \ "bad: inputs comment ok Ok. test d\xE9\xF4l end the",
550 \["Comment", "deol", "d\xE9\xF4r", "input", "OK", "output", "outputs", "outtest", "put", "puts",
551 \ "test", "testen", "testn", "the end", "uk", "wrong"],
552 \[
553 \ ["bad", ["put", "uk", "OK"]],
554 \ ["inputs", ["input", "puts", "outputs"]],
555 \ ["comment", ["Comment", "outtest", "the end"]],
556 \ ["ok", ["OK", "uk", "put"]],
557 \ ["Ok", ["OK", "Uk", "Put"]],
558 \ ["test", ["Test", "testn", "testen"]],
559 \ ["d\xE9\xF4l", ["deol", "d\xE9\xF4r", "test"]],
560 \ ["end", ["put", "uk", "test"]],
561 \ ["the", ["put", "uk", "test"]],
562 \ ]
563 \ )
564
565 call assert_equal("gebletegek", soundfold('goobledygoook'))
Bram Moolenaarf6ed61e2019-09-07 19:05:09 +0200566 call assert_equal("kepereneven", 'kóopërÿnôven'->soundfold())
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200567 call assert_equal("everles gesvets etele", soundfold('oeverloos gezwets edale'))
568endfunc
569
570" Postponed prefixes
571func Test_zz_prefixes()
572 call LoadAffAndDic(g:test_data_aff2, g:test_data_dic1)
573 call RunGoodBad("puts",
574 \ "bad: inputs comment ok Ok end the. test d\xE9\xF4l",
575 \ ["Comment", "deol", "d\xE9\xF4r", "OK", "put", "input", "output", "puts", "outputs", "test", "outtest", "testen", "testn", "the end", "uk", "wrong"],
576 \ [
577 \ ["bad", ["put", "uk", "OK"]],
578 \ ["inputs", ["input", "puts", "outputs"]],
579 \ ["comment", ["Comment"]],
580 \ ["ok", ["OK", "uk", "put"]],
581 \ ["Ok", ["OK", "Uk", "Put"]],
582 \ ["end", ["put", "uk", "deol"]],
583 \ ["the", ["put", "uk", "test"]],
584 \ ["test", ["Test", "testn", "testen"]],
585 \ ["d\xE9\xF4l", ["deol", "d\xE9\xF4r", "test"]],
586 \ ])
587endfunc
588
589"Compound words
590func Test_zz_compound()
591 call LoadAffAndDic(g:test_data_aff3, g:test_data_dic3)
592 call RunGoodBad("foo m\xEF foobar foofoobar barfoo barbarfoo",
593 \ "bad: bar la foom\xEF barm\xEF m\xEFfoo m\xEFbar m\xEFm\xEF lala m\xEFla lam\xEF foola labar",
594 \ ["foo", "m\xEF"],
595 \ [
596 \ ["bad", ["foo", "m\xEF"]],
597 \ ["bar", ["barfoo", "foobar", "foo"]],
598 \ ["la", ["m\xEF", "foo"]],
599 \ ["foom\xEF", ["foo m\xEF", "foo", "foofoo"]],
600 \ ["barm\xEF", ["barfoo", "m\xEF", "barbar"]],
601 \ ["m\xEFfoo", ["m\xEF foo", "foo", "foofoo"]],
602 \ ["m\xEFbar", ["foobar", "barbar", "m\xEF"]],
603 \ ["m\xEFm\xEF", ["m\xEF m\xEF", "m\xEF"]],
604 \ ["lala", []],
605 \ ["m\xEFla", ["m\xEF", "m\xEF m\xEF"]],
606 \ ["lam\xEF", ["m\xEF", "m\xEF m\xEF"]],
607 \ ["foola", ["foo", "foobar", "foofoo"]],
608 \ ["labar", ["barbar", "foobar"]],
609 \ ])
610
611 call LoadAffAndDic(g:test_data_aff4, g:test_data_dic4)
612 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",
613 \ "bad: wordutilize pro borkborkborkborkborkbork tomatotomatotomato endstart endend startstart wordend wordstart preborkprebork preborkpreborkbork startwordwordwordwordend borkpreborkpreborkbork utilsbork startnouword",
614 \ ["bork", "prebork", "end", "pro-ok", "start", "tomato", "util", "utilize", "utils", "word", "nouword"],
615 \ [
616 \ ["bad", ["end", "bork", "word"]],
617 \ ["wordutilize", ["word utilize", "wordutils", "wordutil"]],
618 \ ["pro", ["bork", "word", "end"]],
619 \ ["borkborkborkborkborkbork", ["bork borkborkborkborkbork", "borkbork borkborkborkbork", "borkborkbork borkborkbork"]],
620 \ ["tomatotomatotomato", ["tomato tomatotomato", "tomatotomato tomato", "tomato tomato tomato"]],
621 \ ["endstart", ["end start", "start"]],
622 \ ["endend", ["end end", "end"]],
623 \ ["startstart", ["start start"]],
624 \ ["wordend", ["word end", "word", "wordword"]],
625 \ ["wordstart", ["word start", "bork start"]],
626 \ ["preborkprebork", ["prebork prebork", "preborkbork", "preborkborkbork"]],
627 \ ["preborkpreborkbork", ["prebork preborkbork", "preborkborkbork", "preborkborkborkbork"]],
628 \ ["startwordwordwordwordend", ["startwordwordwordword end", "startwordwordwordword", "start wordwordwordword end"]],
629 \ ["borkpreborkpreborkbork", ["bork preborkpreborkbork", "bork prebork preborkbork", "bork preborkprebork bork"]],
630 \ ["utilsbork", ["utilbork", "utils bork", "util bork"]],
631 \ ["startnouword", ["start nouword", "startword", "startborkword"]],
632 \ ])
633
634endfunc
635
636"Test affix flags with two characters
637func Test_zz_affix()
638 call LoadAffAndDic(g:test_data_aff5, g:test_data_dic5)
639 call RunGoodBad("fooa1 fooa\xE9 bar prebar barbork prebarbork startprebar start end startend startmiddleend nouend",
640 \ "bad: foo fooa2 prabar probarbirk middle startmiddle middleend endstart startprobar startnouend",
641 \ ["bar", "barbork", "end", "fooa1", "fooa\xE9", "nouend", "prebar", "prebarbork", "start"],
642 \ [
643 \ ["bad", ["bar", "end", "fooa1"]],
644 \ ["foo", ["fooa1", "fooa\xE9", "bar"]],
645 \ ["fooa2", ["fooa1", "fooa\xE9", "bar"]],
646 \ ["prabar", ["prebar", "bar", "bar bar"]],
647 \ ["probarbirk", ["prebarbork"]],
648 \ ["middle", []],
649 \ ["startmiddle", ["startmiddleend", "startmiddlebar"]],
650 \ ["middleend", []],
651 \ ["endstart", ["end start", "start"]],
652 \ ["startprobar", ["startprebar", "start prebar", "startbar"]],
653 \ ["startnouend", ["start nouend", "startend"]],
654 \ ])
655
656 call LoadAffAndDic(g:test_data_aff6, g:test_data_dic6)
657 call RunGoodBad("meea1 meea\xE9 bar prebar barbork prebarbork leadprebar lead end leadend leadmiddleend",
658 \ "bad: mee meea2 prabar probarbirk middle leadmiddle middleend endlead leadprobar",
659 \ ["bar", "barbork", "end", "lead", "meea1", "meea\xE9", "prebar", "prebarbork"],
660 \ [
661 \ ["bad", ["bar", "end", "lead"]],
662 \ ["mee", ["meea1", "meea\xE9", "bar"]],
663 \ ["meea2", ["meea1", "meea\xE9", "lead"]],
664 \ ["prabar", ["prebar", "bar", "leadbar"]],
665 \ ["probarbirk", ["prebarbork"]],
666 \ ["middle", []],
667 \ ["leadmiddle", ["leadmiddleend", "leadmiddlebar"]],
668 \ ["middleend", []],
669 \ ["endlead", ["end lead", "lead", "end end"]],
670 \ ["leadprobar", ["leadprebar", "lead prebar", "leadbar"]],
671 \ ])
672
673 call LoadAffAndDic(g:test_data_aff7, g:test_data_dic7)
Bram Moolenaar3d2a47c2019-11-07 20:48:42 +0100674 call RunGoodBad("meea1 meezero meea\xE9 bar prebar barmeat prebarmeat leadprebar lead tail leadtail leadmiddletail",
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200675 \ "bad: mee meea2 prabar probarmaat middle leadmiddle middletail taillead leadprobar",
Bram Moolenaar3d2a47c2019-11-07 20:48:42 +0100676 \ ["bar", "barmeat", "lead", "meea1", "meea\xE9", "meezero", "prebar", "prebarmeat", "tail"],
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200677 \ [
678 \ ["bad", ["bar", "lead", "tail"]],
679 \ ["mee", ["meea1", "meea\xE9", "bar"]],
680 \ ["meea2", ["meea1", "meea\xE9", "lead"]],
681 \ ["prabar", ["prebar", "bar", "leadbar"]],
682 \ ["probarmaat", ["prebarmeat"]],
683 \ ["middle", []],
684 \ ["leadmiddle", ["leadmiddlebar"]],
685 \ ["middletail", []],
686 \ ["taillead", ["tail lead", "tail"]],
687 \ ["leadprobar", ["leadprebar", "lead prebar", "leadbar"]],
688 \ ])
689endfunc
690
691func Test_zz_NOSLITSUGS()
692 call LoadAffAndDic(g:test_data_aff8, g:test_data_dic8)
693 call RunGoodBad("foo bar faabar", "bad: foobar barfoo",
694 \ ["bar", "faabar", "foo"],
695 \ [
696 \ ["bad", ["bar", "foo"]],
697 \ ["foobar", ["faabar", "foo bar", "bar"]],
698 \ ["barfoo", ["bar foo", "bar", "foo"]],
699 \ ])
700endfunc
701
702" Numbers
703func Test_zz_Numbers()
704 call LoadAffAndDic(g:test_data_aff9, g:test_data_dic9)
705 call RunGoodBad("0b1011 0777 1234 0x01ff", "",
706 \ ["bar", "foo"],
707 \ [
708 \ ])
709endfunc
710
Bram Moolenaar37ff4cf2019-11-17 20:10:20 +0100711" Affix flags
712func Test_zz_affix_flags()
713 call LoadAffAndDic(g:test_data_aff10, g:test_data_dic10)
714 call RunGoodBad("drink drinkable drinkables drinktable drinkabletable",
715 \ "bad: drinks drinkstable drinkablestable",
716 \ ["drink", "drinkable", "drinkables", "table"],
717 \ [['bad', []],
718 \ ['drinks', ['drink']],
719 \ ['drinkstable', ['drinktable', 'drinkable', 'drink table']],
720 \ ['drinkablestable', ['drinkabletable', 'drinkables table', 'drinkable table']],
721 \ ])
722endfunc
723
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200724function FirstSpellWord()
725 call feedkeys("/^start:\n", 'tx')
726 normal ]smm
727 let [str, a] = spellbadword()
728 return str
729endfunc
730
731function SecondSpellWord()
732 normal `m]s
733 let [str, a] = spellbadword()
734 return str
735endfunc
736
737"Test with SAL instead of SOFO items; test automatic reloading
738func Test_zz_sal_and_addition()
739 set enc=latin1
740 set spellfile=
Bram Moolenaar1a0f2002017-07-28 15:38:10 +0200741 call writefile(g:test_data_dic1, "Xtest.dic")
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200742 call writefile(g:test_data_aff_sal, "Xtest.aff")
743 mkspell! Xtest Xtest
744 set spl=Xtest.latin1.spl spell
745 call assert_equal('kbltykk', soundfold('goobledygoook'))
746 call assert_equal('kprnfn', soundfold('kóopërÿnôven'))
747 call assert_equal('*fls kswts tl', soundfold('oeverloos gezwets edale'))
748
749 "also use an addition file
750 call writefile(["/regions=usgbnz", "elequint/2", "elekwint/3"], "Xtest.latin1.add")
751 mkspell! Xtest.latin1.add.spl Xtest.latin1.add
752
753 bwipe!
754 call setline(1, ["start: elequint test elekwint test elekwent asdf"])
755
756 set spellfile=Xtest.latin1.add
757 call assert_equal("elekwent", FirstSpellWord())
758
759 set spl=Xtest_us.latin1.spl
760 call assert_equal("elequint", FirstSpellWord())
761 call assert_equal("elekwint", SecondSpellWord())
762
763 set spl=Xtest_gb.latin1.spl
764 call assert_equal("elekwint", FirstSpellWord())
765 call assert_equal("elekwent", SecondSpellWord())
766
767 set spl=Xtest_nz.latin1.spl
768 call assert_equal("elequint", FirstSpellWord())
769 call assert_equal("elekwent", SecondSpellWord())
770
771 set spl=Xtest_ca.latin1.spl
772 call assert_equal("elequint", FirstSpellWord())
773 call assert_equal("elekwint", SecondSpellWord())
774endfunc
775
Bram Moolenaar862f1e12019-04-10 22:33:41 +0200776func Test_spellfile_value()
777 set spellfile=Xdir/Xtest.latin1.add
778 set spellfile=Xdir/Xtest.utf-8.add,Xtest_other.add
779endfunc
780
Bram Moolenaaree03b942017-10-27 00:57:05 +0200781func Test_region_error()
782 messages clear
783 call writefile(["/regions=usgbnz", "elequint/0"], "Xtest.latin1.add")
784 mkspell! Xtest.latin1.add.spl Xtest.latin1.add
785 call assert_match('Invalid region nr in Xtest.latin1.add line 2: 0', execute('messages'))
786 call delete('Xtest.latin1.add')
787 call delete('Xtest.latin1.add.spl')
788endfunc
789
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200790" Check using z= in new buffer (crash fixed by patch 7.4a.028).
791func Test_zeq_crash()
792 new
793 set maxmem=512 spell
794 call feedkeys('iasdz=:\"', 'tx')
795
796 bwipe!
797endfunc
798
Bram Moolenaar152e79e2020-06-10 15:32:08 +0200799" Check that z= works even when 'nospell' is set. This test uses one of the
800" tests in Test_spellsuggest_option_number() just to verify that z= basically
801" works and that "E756: Spell checking is not enabled" is not generated.
802func Test_zeq_nospell()
803 new
804 set nospell spellsuggest=1,best
805 call setline(1, 'A baord')
806 try
807 norm $1z=
808 call assert_equal('A board', getline(1))
809 catch
810 call assert_report("Caught exception: " . v:exception)
811 endtry
812 set spell& spellsuggest&
813 bwipe!
814endfunc
815
816" Check that "E756: Spell checking is not possible" is reported when z= is
817" executed and 'spelllang' is empty.
818func Test_zeq_no_spelllang()
819 new
820 set spelllang= spellsuggest=1,best
821 call setline(1, 'A baord')
822 call assert_fails('normal $1z=', 'E756:')
823 set spelllang& spellsuggest&
824 bwipe!
825endfunc
826
Bram Moolenaar5bcc5a12019-08-06 22:48:02 +0200827" Check handling a word longer than MAXWLEN.
828func Test_spell_long_word()
829 set enc=utf-8
830 new
831 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")
832 set spell spelllang=en
833 redraw
834 redraw!
835 bwipe!
836 set nospell
837endfunc
838
Bram Moolenaar06f15412022-01-29 10:51:59 +0000839func Test_spellsuggest_too_deep()
840 " This was incrementing "depth" over MAXWLEN.
841 new
842 norm s000G00ý000000000000
843 sil norm ..vzG................vvzG0 v z=
844 bwipe!
845endfunc
846
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200847func LoadAffAndDic(aff_contents, dic_contents)
848 set enc=latin1
849 set spellfile=
850 call writefile(a:aff_contents, "Xtest.aff")
851 call writefile(a:dic_contents, "Xtest.dic")
852 " Generate a .spl file from a .dic and .aff file.
853 mkspell! Xtest Xtest
854 " use that spell file
855 set spl=Xtest.latin1.spl spell
856endfunc
857
858func ListWords()
859 spelldump
860 %yank
861 quit
862 return split(@", "\n")
863endfunc
864
865func TestGoodBadBase()
866 exe '1;/^good:'
867 normal 0f:]s
868 let prevbad = ''
869 let result = []
870 while 1
871 let [bad, a] = spellbadword()
872 if bad == '' || bad == prevbad || bad == 'badend'
873 break
874 endif
875 let prevbad = bad
Bram Moolenaarf6ed61e2019-09-07 19:05:09 +0200876 let lst = bad->spellsuggest(3)
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200877 normal mm
878
879 call add(result, [bad, lst])
880 normal `m]s
881 endwhile
882 return result
883endfunc
884
885func RunGoodBad(good, bad, expected_words, expected_bad_words)
886 bwipe!
887 call setline(1, ["good: ", a:good, a:bad, " badend "])
888 let words = ListWords()
889 call assert_equal(a:expected_words, words[1:-1])
890 let bad_words = TestGoodBadBase()
891 call assert_equal(a:expected_bad_words, bad_words)
892 bwipe!
893endfunc
894
Bram Moolenaar7751d1d2019-10-18 20:37:08 +0200895func Test_spell_screendump()
896 CheckScreendump
897
898 let lines =<< trim END
899 call setline(1, [
900 \ "This is some text without any spell errors. Everything",
901 \ "should just be black, nothing wrong here.",
902 \ "",
903 \ "This line has a sepll error. and missing caps.",
904 \ "And and this is the the duplication.",
905 \ "with missing caps here.",
906 \ ])
907 set spell spelllang=en_nz
908 END
909 call writefile(lines, 'XtestSpell')
910 let buf = RunVimInTerminal('-S XtestSpell', {'rows': 8})
911 call VerifyScreenDump(buf, 'Test_spell_1', {})
912
913 " clean up
914 call StopVimInTerminal(buf)
915 call delete('XtestSpell')
916endfunc
917
Bram Moolenaard2c061d2017-06-22 21:42:49 +0200918let g:test_data_aff1 = [
919 \"SET ISO8859-1",
920 \"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ",
921 \"",
922 \"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",
923 \"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",
924 \"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",
925 \"",
926 \"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",
927 \"SOFOTO ebctefghejklnnepkrstevvkesebctefghejklnnepkrstevvkeseeeeeeeceeeeeeeedneeeeeeeeeeepseeeeeeeeceeeeeeeedneeeeeeeeeeep?",
928 \"",
929 \"MIDWORD\t'-",
930 \"",
931 \"KEP =",
932 \"RAR ?",
933 \"BAD !",
934 \"",
935 \"PFX I N 1",
936 \"PFX I 0 in .",
937 \"",
938 \"PFX O Y 1",
939 \"PFX O 0 out .",
940 \"",
941 \"SFX S Y 2",
942 \"SFX S 0 s [^s]",
943 \"SFX S 0 es s",
944 \"",
945 \"SFX N N 3",
946 \"SFX N 0 en [^n]",
947 \"SFX N 0 nen n",
948 \"SFX N 0 n .",
949 \"",
950 \"REP 3",
951 \"REP g ch",
952 \"REP ch g",
953 \"REP svp s.v.p.",
954 \"",
955 \"MAP 9",
956 \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
957 \"MAP e\xE8\xE9\xEA\xEB",
958 \"MAP i\xEC\xED\xEE\xEF",
959 \"MAP o\xF2\xF3\xF4\xF5\xF6",
960 \"MAP u\xF9\xFA\xFB\xFC",
961 \"MAP n\xF1",
962 \"MAP c\xE7",
963 \"MAP y\xFF\xFD",
964 \"MAP s\xDF",
965 \ ]
966let g:test_data_dic1 = [
967 \"123456",
968 \"test/NO",
969 \"# comment",
970 \"wrong",
971 \"Comment",
972 \"OK",
973 \"uk",
974 \"put/ISO",
975 \"the end",
976 \"deol",
977 \"d\xE9\xF4r",
978 \ ]
979let g:test_data_aff2 = [
980 \"SET ISO8859-1",
981 \"",
982 \"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",
983 \"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",
984 \"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",
985 \"",
986 \"PFXPOSTPONE",
987 \"",
988 \"MIDWORD\t'-",
989 \"",
990 \"KEP =",
991 \"RAR ?",
992 \"BAD !",
993 \"",
994 \"PFX I N 1",
995 \"PFX I 0 in .",
996 \"",
997 \"PFX O Y 1",
998 \"PFX O 0 out [a-z]",
999 \"",
1000 \"SFX S Y 2",
1001 \"SFX S 0 s [^s]",
1002 \"SFX S 0 es s",
1003 \"",
1004 \"SFX N N 3",
1005 \"SFX N 0 en [^n]",
1006 \"SFX N 0 nen n",
1007 \"SFX N 0 n .",
1008 \"",
1009 \"REP 3",
1010 \"REP g ch",
1011 \"REP ch g",
1012 \"REP svp s.v.p.",
1013 \"",
1014 \"MAP 9",
1015 \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
1016 \"MAP e\xE8\xE9\xEA\xEB",
1017 \"MAP i\xEC\xED\xEE\xEF",
1018 \"MAP o\xF2\xF3\xF4\xF5\xF6",
1019 \"MAP u\xF9\xFA\xFB\xFC",
1020 \"MAP n\xF1",
1021 \"MAP c\xE7",
1022 \"MAP y\xFF\xFD",
1023 \"MAP s\xDF",
1024 \ ]
1025let g:test_data_aff3 = [
1026 \"SET ISO8859-1",
1027 \"",
1028 \"COMPOUNDMIN 3",
1029 \"COMPOUNDRULE m*",
1030 \"NEEDCOMPOUND x",
1031 \ ]
1032let g:test_data_dic3 = [
1033 \"1234",
1034 \"foo/m",
1035 \"bar/mx",
1036 \"m\xEF/m",
1037 \"la/mx",
1038 \ ]
1039let g:test_data_aff4 = [
1040 \"SET ISO8859-1",
1041 \"",
1042 \"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",
1043 \"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",
1044 \"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",
1045 \"",
1046 \"COMPOUNDRULE m+",
1047 \"COMPOUNDRULE sm*e",
1048 \"COMPOUNDRULE sm+",
1049 \"COMPOUNDMIN 3",
1050 \"COMPOUNDWORDMAX 3",
1051 \"COMPOUNDFORBIDFLAG t",
1052 \"",
1053 \"COMPOUNDSYLMAX 5",
1054 \"SYLLABLE a\xE1e\xE9i\xEDo\xF3\xF6\xF5u\xFA\xFC\xFBy/aa/au/ea/ee/ei/ie/oa/oe/oo/ou/uu/ui",
1055 \"",
1056 \"MAP 9",
1057 \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
1058 \"MAP e\xE8\xE9\xEA\xEB",
1059 \"MAP i\xEC\xED\xEE\xEF",
1060 \"MAP o\xF2\xF3\xF4\xF5\xF6",
1061 \"MAP u\xF9\xFA\xFB\xFC",
1062 \"MAP n\xF1",
1063 \"MAP c\xE7",
1064 \"MAP y\xFF\xFD",
1065 \"MAP s\xDF",
1066 \"",
1067 \"NEEDAFFIX x",
1068 \"",
1069 \"PFXPOSTPONE",
1070 \"",
1071 \"MIDWORD '-",
1072 \"",
1073 \"SFX q N 1",
1074 \"SFX q 0 -ok .",
1075 \"",
1076 \"SFX a Y 2",
1077 \"SFX a 0 s .",
1078 \"SFX a 0 ize/t .",
1079 \"",
1080 \"PFX p N 1",
1081 \"PFX p 0 pre .",
1082 \"",
1083 \"PFX P N 1",
1084 \"PFX P 0 nou .",
1085 \ ]
1086let g:test_data_dic4 = [
1087 \"1234",
1088 \"word/mP",
1089 \"util/am",
1090 \"pro/xq",
1091 \"tomato/m",
1092 \"bork/mp",
1093 \"start/s",
1094 \"end/e",
1095 \ ]
1096let g:test_data_aff5 = [
1097 \"SET ISO8859-1",
1098 \"",
1099 \"FLAG long",
1100 \"",
1101 \"NEEDAFFIX !!",
1102 \"",
1103 \"COMPOUNDRULE ssmm*ee",
1104 \"",
1105 \"NEEDCOMPOUND xx",
1106 \"COMPOUNDPERMITFLAG pp",
1107 \"",
1108 \"SFX 13 Y 1",
1109 \"SFX 13 0 bork .",
1110 \"",
1111 \"SFX a1 Y 1",
1112 \"SFX a1 0 a1 .",
1113 \"",
1114 \"SFX a\xE9 Y 1",
1115 \"SFX a\xE9 0 a\xE9 .",
1116 \"",
1117 \"PFX zz Y 1",
1118 \"PFX zz 0 pre/pp .",
1119 \"",
1120 \"PFX yy Y 1",
1121 \"PFX yy 0 nou .",
1122 \ ]
1123let g:test_data_dic5 = [
1124 \"1234",
1125 \"foo/a1a\xE9!!",
1126 \"bar/zz13ee",
1127 \"start/ss",
1128 \"end/eeyy",
1129 \"middle/mmxx",
1130 \ ]
1131let g:test_data_aff6 = [
1132 \"SET ISO8859-1",
1133 \"",
1134 \"FLAG caplong",
1135 \"",
1136 \"NEEDAFFIX A!",
1137 \"",
1138 \"COMPOUNDRULE sMm*Ee",
1139 \"",
1140 \"NEEDCOMPOUND Xx",
1141 \"",
1142 \"COMPOUNDPERMITFLAG p",
1143 \"",
1144 \"SFX N3 Y 1",
1145 \"SFX N3 0 bork .",
1146 \"",
1147 \"SFX A1 Y 1",
1148 \"SFX A1 0 a1 .",
1149 \"",
1150 \"SFX A\xE9 Y 1",
1151 \"SFX A\xE9 0 a\xE9 .",
1152 \"",
1153 \"PFX Zz Y 1",
1154 \"PFX Zz 0 pre/p .",
1155 \ ]
1156let g:test_data_dic6 = [
1157 \"1234",
1158 \"mee/A1A\xE9A!",
1159 \"bar/ZzN3Ee",
1160 \"lead/s",
1161 \"end/Ee",
1162 \"middle/MmXx",
1163 \ ]
1164let g:test_data_aff7 = [
1165 \"SET ISO8859-1",
1166 \"",
1167 \"FLAG num",
1168 \"",
1169 \"NEEDAFFIX 9999",
1170 \"",
1171 \"COMPOUNDRULE 2,77*123",
1172 \"",
1173 \"NEEDCOMPOUND 1",
1174 \"COMPOUNDPERMITFLAG 432",
1175 \"",
1176 \"SFX 61003 Y 1",
1177 \"SFX 61003 0 meat .",
1178 \"",
Bram Moolenaar3d2a47c2019-11-07 20:48:42 +01001179 \"SFX 0 Y 1",
1180 \"SFX 0 0 zero .",
1181 \"",
Bram Moolenaard2c061d2017-06-22 21:42:49 +02001182 \"SFX 391 Y 1",
1183 \"SFX 391 0 a1 .",
1184 \"",
1185 \"SFX 111 Y 1",
1186 \"SFX 111 0 a\xE9 .",
1187 \"",
1188 \"PFX 17 Y 1",
1189 \"PFX 17 0 pre/432 .",
1190 \ ]
1191let g:test_data_dic7 = [
1192 \"1234",
Bram Moolenaar3d2a47c2019-11-07 20:48:42 +01001193 \"mee/0,391,111,9999",
Bram Moolenaard2c061d2017-06-22 21:42:49 +02001194 \"bar/17,61003,123",
1195 \"lead/2",
1196 \"tail/123",
1197 \"middle/77,1",
1198 \ ]
1199let g:test_data_aff8 = [
1200 \"SET ISO8859-1",
1201 \"",
1202 \"NOSPLITSUGS",
1203 \ ]
1204let g:test_data_dic8 = [
1205 \"1234",
1206 \"foo",
1207 \"bar",
1208 \"faabar",
1209 \ ]
1210let g:test_data_aff9 = [
1211 \ ]
1212let g:test_data_dic9 = [
1213 \"1234",
1214 \"foo",
1215 \"bar",
1216 \ ]
Bram Moolenaar37ff4cf2019-11-17 20:10:20 +01001217let g:test_data_aff10 = [
1218 \"COMPOUNDRULE se",
1219 \"COMPOUNDPERMITFLAG p",
1220 \"",
1221 \"SFX A Y 1",
1222 \"SFX A 0 able/Mp .",
1223 \"",
1224 \"SFX M Y 1",
1225 \"SFX M 0 s .",
1226 \ ]
1227let g:test_data_dic10 = [
1228 \"1234",
1229 \"drink/As",
1230 \"table/e",
1231 \ ]
Bram Moolenaard2c061d2017-06-22 21:42:49 +02001232let g:test_data_aff_sal = [
1233 \"SET ISO8859-1",
1234 \"TRY esianrtolcdugmphbyfvkwjkqxz-\xEB\xE9\xE8\xEA\xEF\xEE\xE4\xE0\xE2\xF6\xFC\xFB'ESIANRTOLCDUGMPHBYFVKWJKQXZ",
1235 \"",
1236 \"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",
1237 \"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",
1238 \"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",
1239 \"",
1240 \"MIDWORD\t'-",
1241 \"",
1242 \"KEP =",
1243 \"RAR ?",
1244 \"BAD !",
1245 \"",
1246 \"PFX I N 1",
1247 \"PFX I 0 in .",
1248 \"",
1249 \"PFX O Y 1",
1250 \"PFX O 0 out .",
1251 \"",
1252 \"SFX S Y 2",
1253 \"SFX S 0 s [^s]",
1254 \"SFX S 0 es s",
1255 \"",
1256 \"SFX N N 3",
1257 \"SFX N 0 en [^n]",
1258 \"SFX N 0 nen n",
1259 \"SFX N 0 n .",
1260 \"",
1261 \"REP 3",
1262 \"REP g ch",
1263 \"REP ch g",
1264 \"REP svp s.v.p.",
1265 \"",
1266 \"MAP 9",
1267 \"MAP a\xE0\xE1\xE2\xE3\xE4\xE5",
1268 \"MAP e\xE8\xE9\xEA\xEB",
1269 \"MAP i\xEC\xED\xEE\xEF",
1270 \"MAP o\xF2\xF3\xF4\xF5\xF6",
1271 \"MAP u\xF9\xFA\xFB\xFC",
1272 \"MAP n\xF1",
1273 \"MAP c\xE7",
1274 \"MAP y\xFF\xFD",
1275 \"MAP s\xDF",
1276 \"",
1277 \"SAL AH(AEIOUY)-^ *H",
1278 \"SAL AR(AEIOUY)-^ *R",
1279 \"SAL A(HR)^ *",
1280 \"SAL A^ *",
1281 \"SAL AH(AEIOUY)- H",
1282 \"SAL AR(AEIOUY)- R",
1283 \"SAL A(HR) _",
1284 \"SAL \xC0^ *",
1285 \"SAL \xC5^ *",
1286 \"SAL BB- _",
1287 \"SAL B B",
1288 \"SAL CQ- _",
1289 \"SAL CIA X",
1290 \"SAL CH X",
1291 \"SAL C(EIY)- S",
1292 \"SAL CK K",
1293 \"SAL COUGH^ KF",
1294 \"SAL CC< C",
1295 \"SAL C K",
1296 \"SAL DG(EIY) K",
1297 \"SAL DD- _",
1298 \"SAL D T",
1299 \"SAL \xC9< E",
1300 \"SAL EH(AEIOUY)-^ *H",
1301 \"SAL ER(AEIOUY)-^ *R",
1302 \"SAL E(HR)^ *",
1303 \"SAL ENOUGH^$ *NF",
1304 \"SAL E^ *",
1305 \"SAL EH(AEIOUY)- H",
1306 \"SAL ER(AEIOUY)- R",
1307 \"SAL E(HR) _",
1308 \"SAL FF- _",
1309 \"SAL F F",
1310 \"SAL GN^ N",
1311 \"SAL GN$ N",
1312 \"SAL GNS$ NS",
1313 \"SAL GNED$ N",
1314 \"SAL GH(AEIOUY)- K",
1315 \"SAL GH _",
1316 \"SAL GG9 K",
1317 \"SAL G K",
1318 \"SAL H H",
1319 \"SAL IH(AEIOUY)-^ *H",
1320 \"SAL IR(AEIOUY)-^ *R",
1321 \"SAL I(HR)^ *",
1322 \"SAL I^ *",
1323 \"SAL ING6 N",
1324 \"SAL IH(AEIOUY)- H",
1325 \"SAL IR(AEIOUY)- R",
1326 \"SAL I(HR) _",
1327 \"SAL J K",
1328 \"SAL KN^ N",
1329 \"SAL KK- _",
1330 \"SAL K K",
1331 \"SAL LAUGH^ LF",
1332 \"SAL LL- _",
1333 \"SAL L L",
1334 \"SAL MB$ M",
1335 \"SAL MM M",
1336 \"SAL M M",
1337 \"SAL NN- _",
1338 \"SAL N N",
1339 \"SAL OH(AEIOUY)-^ *H",
1340 \"SAL OR(AEIOUY)-^ *R",
1341 \"SAL O(HR)^ *",
1342 \"SAL O^ *",
1343 \"SAL OH(AEIOUY)- H",
1344 \"SAL OR(AEIOUY)- R",
1345 \"SAL O(HR) _",
1346 \"SAL PH F",
1347 \"SAL PN^ N",
1348 \"SAL PP- _",
1349 \"SAL P P",
1350 \"SAL Q K",
1351 \"SAL RH^ R",
1352 \"SAL ROUGH^ RF",
1353 \"SAL RR- _",
1354 \"SAL R R",
1355 \"SAL SCH(EOU)- SK",
1356 \"SAL SC(IEY)- S",
1357 \"SAL SH X",
1358 \"SAL SI(AO)- X",
1359 \"SAL SS- _",
1360 \"SAL S S",
1361 \"SAL TI(AO)- X",
1362 \"SAL TH @",
1363 \"SAL TCH-- _",
1364 \"SAL TOUGH^ TF",
1365 \"SAL TT- _",
1366 \"SAL T T",
1367 \"SAL UH(AEIOUY)-^ *H",
1368 \"SAL UR(AEIOUY)-^ *R",
1369 \"SAL U(HR)^ *",
1370 \"SAL U^ *",
1371 \"SAL UH(AEIOUY)- H",
1372 \"SAL UR(AEIOUY)- R",
1373 \"SAL U(HR) _",
1374 \"SAL V^ W",
1375 \"SAL V F",
1376 \"SAL WR^ R",
1377 \"SAL WH^ W",
1378 \"SAL W(AEIOU)- W",
1379 \"SAL X^ S",
1380 \"SAL X KS",
1381 \"SAL Y(AEIOU)- Y",
1382 \"SAL ZZ- _",
1383 \"SAL Z S",
1384 \ ]
Bram Moolenaar0e05de42020-03-25 22:23:46 +01001385
1386" vim: shiftwidth=2 sts=2 expandtab