mirror of
https://github.com/neovim/neovim.git
synced 2024-12-20 11:15:14 -07:00
vim-patch:8.1.1838: there is :spellwrong and :spellgood but not :spellrare
Problem: There is :spellwrong and :spellgood but not :spellrare.
Solution: Add :spellrare. (Martin Tournoij, closes vim/vim#4291)
08cc374dab
This commit is contained in:
parent
d3bdde0bad
commit
61117d89a3
@ -110,6 +110,23 @@ zuG Undo |zW| and |zG|, remove the word from the internal
|
||||
:spellw[rong]! {word} Add {word} as a wrong (bad) word to the internal word
|
||||
list, like with |zW|.
|
||||
|
||||
*:spellr* *:spellrare*
|
||||
:[count]spellr[are] {word}
|
||||
Add {word} as a rare word to 'spellfile', similar to
|
||||
|zw|. Without count the first name is used, with
|
||||
a count of two the second entry, etc.
|
||||
|
||||
There are no normal mode commands to mark words as
|
||||
rare as this is a fairly uncommon command and all
|
||||
intuitive commands for this are already taken. If you
|
||||
want you can add mappings with e.g.: >
|
||||
nnoremap z? :exe ':spellrare ' . expand('<cWORD>')<CR>
|
||||
nnoremap z/ :exe ':spellrare! ' . expand('<cWORD>')<CR>
|
||||
< |:spellundo|, |zuw|, or |zuW| can be used to undo this.
|
||||
|
||||
:spellr[rare]! {word} Add {word} as a rare word to the internal word
|
||||
list, similar to |zW|.
|
||||
|
||||
:[count]spellu[ndo] {word} *:spellu* *:spellundo*
|
||||
Like |zuw|. [count] used as with |:spellgood|.
|
||||
|
||||
|
@ -2549,6 +2549,12 @@ module.cmds = {
|
||||
addr_type='ADDR_OTHER',
|
||||
func='ex_spell',
|
||||
},
|
||||
{
|
||||
command='spellrare',
|
||||
flags=bit.bor(BANG, RANGE, NEEDARG, EXTRA, TRLBAR),
|
||||
addr_type='ADDR_OTHER',
|
||||
func='ex_spell',
|
||||
},
|
||||
{
|
||||
command='spelldump',
|
||||
flags=bit.bor(BANG, TRLBAR),
|
||||
|
@ -4604,7 +4604,9 @@ dozet:
|
||||
if (ptr == NULL && (len = find_ident_under_cursor(&ptr, FIND_IDENT)) == 0)
|
||||
return;
|
||||
assert(len <= INT_MAX);
|
||||
spell_add_word(ptr, (int)len, nchar == 'w' || nchar == 'W',
|
||||
spell_add_word(ptr, (int)len,
|
||||
nchar == 'w' || nchar == 'W'
|
||||
? SPELL_ADD_BAD : SPELL_ADD_GOOD,
|
||||
(nchar == 'G' || nchar == 'W') ? 0 : (int)cap->count1,
|
||||
undo);
|
||||
}
|
||||
|
@ -284,4 +284,11 @@ extern int did_set_spelltab;
|
||||
|
||||
extern char *e_format;
|
||||
|
||||
// Values for "what" argument of spell_add_word()
|
||||
typedef enum {
|
||||
SPELL_ADD_GOOD = 0,
|
||||
SPELL_ADD_BAD = 1,
|
||||
SPELL_ADD_RARE = 2,
|
||||
} SpellAddType;
|
||||
|
||||
#endif // NVIM_SPELL_DEFS_H
|
||||
|
@ -5292,9 +5292,12 @@ static void spell_message(const spellinfo_T *spin, char_u *str)
|
||||
// ":[count]spellgood {word}"
|
||||
// ":[count]spellwrong {word}"
|
||||
// ":[count]spellundo {word}"
|
||||
// ":[count]spellrare {word}"
|
||||
void ex_spell(exarg_T *eap)
|
||||
{
|
||||
spell_add_word(eap->arg, (int)STRLEN(eap->arg), eap->cmdidx == CMD_spellwrong,
|
||||
spell_add_word(eap->arg, (int)STRLEN(eap->arg),
|
||||
eap->cmdidx == CMD_spellwrong ? SPELL_ADD_BAD :
|
||||
eap->cmdidx == CMD_spellrare ? SPELL_ADD_RARE : SPELL_ADD_GOOD,
|
||||
eap->forceit ? 0 : (int)eap->line2,
|
||||
eap->cmdidx == CMD_spellundo);
|
||||
}
|
||||
@ -5304,7 +5307,7 @@ void
|
||||
spell_add_word (
|
||||
char_u *word,
|
||||
int len,
|
||||
int bad,
|
||||
SpellAddType what, // SPELL_ADD_ values
|
||||
int idx, // "zG" and "zW": zero, otherwise index in
|
||||
// 'spellfile'
|
||||
bool undo // true for "zug", "zuG", "zuw" and "zuW"
|
||||
@ -5364,7 +5367,7 @@ spell_add_word (
|
||||
fname = fnamebuf;
|
||||
}
|
||||
|
||||
if (bad || undo) {
|
||||
if (what == SPELL_ADD_BAD || undo) {
|
||||
// When the word appears as good word we need to remove that one,
|
||||
// since its flags sort before the one with WF_BANNED.
|
||||
fd = os_fopen((char *)fname, "r");
|
||||
@ -5422,13 +5425,16 @@ spell_add_word (
|
||||
}
|
||||
}
|
||||
|
||||
if (fd == NULL)
|
||||
if (fd == NULL) {
|
||||
EMSG2(_(e_notopen), fname);
|
||||
else {
|
||||
if (bad)
|
||||
} else {
|
||||
if (what == SPELL_ADD_BAD) {
|
||||
fprintf(fd, "%.*s/!\n", len, word);
|
||||
else
|
||||
} else if (what == SPELL_ADD_RARE) {
|
||||
fprintf(fd, "%.*s/?\n", len, word);
|
||||
} else {
|
||||
fprintf(fd, "%.*s\n", len, word);
|
||||
}
|
||||
fclose(fd);
|
||||
|
||||
home_replace(NULL, fname, NameBuff, MAXPATHL, TRUE);
|
||||
|
@ -1111,161 +1111,6 @@ func Test_normal18_z_fold()
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
func Test_normal19_z_spell()
|
||||
if !has("spell") || !has('syntax')
|
||||
return
|
||||
endif
|
||||
new
|
||||
call append(0, ['1 good', '2 goood', '3 goood'])
|
||||
set spell spellfile=./Xspellfile.add spelllang=en
|
||||
let oldlang=v:lang
|
||||
lang C
|
||||
|
||||
" Test for zg
|
||||
1
|
||||
norm! ]s
|
||||
call assert_equal('2 goood', getline('.'))
|
||||
norm! zg
|
||||
1
|
||||
let a=execute('unsilent :norm! ]s')
|
||||
call assert_equal('1 good', getline('.'))
|
||||
call assert_equal('search hit BOTTOM, continuing at TOP', a[1:])
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('goood', cnt[0])
|
||||
|
||||
" Test for zw
|
||||
2
|
||||
norm! $zw
|
||||
1
|
||||
norm! ]s
|
||||
call assert_equal('2 goood', getline('.'))
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('#oood', cnt[0])
|
||||
call assert_equal('goood/!', cnt[1])
|
||||
|
||||
" Test for zg in visual mode
|
||||
let a=execute('unsilent :norm! V$zg')
|
||||
call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
|
||||
1
|
||||
norm! ]s
|
||||
call assert_equal('3 goood', getline('.'))
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('2 goood', cnt[2])
|
||||
" Remove "2 good" from spellfile
|
||||
2
|
||||
let a=execute('unsilent norm! V$zw')
|
||||
call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('2 goood/!', cnt[3])
|
||||
|
||||
" Test for zG
|
||||
let a=execute('unsilent norm! V$zG')
|
||||
call assert_match("Word '2 goood' added to .*", a)
|
||||
let fname=matchstr(a, 'to\s\+\zs\f\+$')
|
||||
let fname=Fix_truncated_tmpfile(fname)
|
||||
let cnt=readfile(fname)
|
||||
call assert_equal('2 goood', cnt[0])
|
||||
|
||||
" Test for zW
|
||||
let a=execute('unsilent norm! V$zW')
|
||||
call assert_match("Word '2 goood' added to .*", a)
|
||||
let cnt=readfile(fname)
|
||||
call assert_equal('# goood', cnt[0])
|
||||
call assert_equal('2 goood/!', cnt[1])
|
||||
|
||||
" Test for zuW
|
||||
let a=execute('unsilent norm! V$zuW')
|
||||
call assert_match("Word '2 goood' removed from .*", a)
|
||||
let cnt=readfile(fname)
|
||||
call assert_equal('# goood', cnt[0])
|
||||
call assert_equal('# goood/!', cnt[1])
|
||||
|
||||
" Test for zuG
|
||||
let a=execute('unsilent norm! $zG')
|
||||
call assert_match("Word 'goood' added to .*", a)
|
||||
let cnt=readfile(fname)
|
||||
call assert_equal('# goood', cnt[0])
|
||||
call assert_equal('# goood/!', cnt[1])
|
||||
call assert_equal('goood', cnt[2])
|
||||
let a=execute('unsilent norm! $zuG')
|
||||
let cnt=readfile(fname)
|
||||
call assert_match("Word 'goood' removed from .*", a)
|
||||
call assert_equal('# goood', cnt[0])
|
||||
call assert_equal('# goood/!', cnt[1])
|
||||
call assert_equal('#oood', cnt[2])
|
||||
" word not found in wordlist
|
||||
let a=execute('unsilent norm! V$zuG')
|
||||
let cnt=readfile(fname)
|
||||
call assert_match("", a)
|
||||
call assert_equal('# goood', cnt[0])
|
||||
call assert_equal('# goood/!', cnt[1])
|
||||
call assert_equal('#oood', cnt[2])
|
||||
|
||||
" Test for zug
|
||||
call delete('./Xspellfile.add')
|
||||
2
|
||||
let a=execute('unsilent norm! $zg')
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('goood', cnt[0])
|
||||
let a=execute('unsilent norm! $zug')
|
||||
call assert_match("Word 'goood' removed from \./Xspellfile.add", a)
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('#oood', cnt[0])
|
||||
" word not in wordlist
|
||||
let a=execute('unsilent norm! V$zug')
|
||||
call assert_match('', a)
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('#oood', cnt[0])
|
||||
|
||||
" Test for zuw
|
||||
call delete('./Xspellfile.add')
|
||||
2
|
||||
let a=execute('unsilent norm! Vzw')
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('2 goood/!', cnt[0])
|
||||
let a=execute('unsilent norm! Vzuw')
|
||||
call assert_match("Word '2 goood' removed from \./Xspellfile.add", a)
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('# goood/!', cnt[0])
|
||||
" word not in wordlist
|
||||
let a=execute('unsilent norm! $zug')
|
||||
call assert_match('', a)
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('# goood/!', cnt[0])
|
||||
|
||||
" add second entry to spellfile setting
|
||||
set spellfile=./Xspellfile.add,./Xspellfile2.add
|
||||
call delete('./Xspellfile.add')
|
||||
2
|
||||
let a=execute('unsilent norm! $2zg')
|
||||
let cnt=readfile('./Xspellfile2.add')
|
||||
call assert_match("Word 'goood' added to ./Xspellfile2.add", a)
|
||||
call assert_equal('goood', cnt[0])
|
||||
|
||||
" Test for :spellgood!
|
||||
let temp = execute(':spe!0/0')
|
||||
call assert_match('Invalid region', temp)
|
||||
let spellfile = matchstr(temp, 'Invalid region nr in \zs.*\ze line \d: 0')
|
||||
call assert_equal(['# goood', '# goood/!', '#oood', '0/0'], readfile(spellfile))
|
||||
call delete(spellfile)
|
||||
|
||||
" clean up
|
||||
exe "lang" oldlang
|
||||
call delete("./Xspellfile.add")
|
||||
call delete("./Xspellfile2.add")
|
||||
call delete("./Xspellfile.add.spl")
|
||||
call delete("./Xspellfile2.add.spl")
|
||||
|
||||
" zux -> no-op
|
||||
2
|
||||
norm! $zux
|
||||
call assert_equal([], glob('Xspellfile.add',0,1))
|
||||
call assert_equal([], glob('Xspellfile2.add',0,1))
|
||||
|
||||
set spellfile=
|
||||
bw!
|
||||
endfunc
|
||||
|
||||
func Test_normal20_exmode()
|
||||
if !has("unix")
|
||||
" Reading from redirected file doesn't work on MS-Windows
|
||||
|
172
src/nvim/testdir/test_spellfile.vim
Normal file
172
src/nvim/testdir/test_spellfile.vim
Normal file
@ -0,0 +1,172 @@
|
||||
" Test for commands that operate on the spellfile.
|
||||
|
||||
source shared.vim
|
||||
source check.vim
|
||||
|
||||
CheckFeature spell
|
||||
CheckFeature syntax
|
||||
|
||||
func Test_spell_normal()
|
||||
new
|
||||
call append(0, ['1 good', '2 goood', '3 goood'])
|
||||
set spell spellfile=./Xspellfile.add spelllang=en
|
||||
let oldlang=v:lang
|
||||
lang C
|
||||
|
||||
" Test for zg
|
||||
1
|
||||
norm! ]s
|
||||
call assert_equal('2 goood', getline('.'))
|
||||
norm! zg
|
||||
1
|
||||
let a=execute('unsilent :norm! ]s')
|
||||
call assert_equal('1 good', getline('.'))
|
||||
call assert_equal('search hit BOTTOM, continuing at TOP', a[1:])
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('goood', cnt[0])
|
||||
|
||||
" Test for zw
|
||||
2
|
||||
norm! $zw
|
||||
1
|
||||
norm! ]s
|
||||
call assert_equal('2 goood', getline('.'))
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('#oood', cnt[0])
|
||||
call assert_equal('goood/!', cnt[1])
|
||||
|
||||
" Test for :spellrare
|
||||
spellrare rare
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal(['#oood', 'goood/!', 'rare/?'], cnt)
|
||||
|
||||
" Make sure :spellundo works for rare words.
|
||||
spellundo rare
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal(['#oood', 'goood/!', '#are/?'], cnt)
|
||||
|
||||
" Test for zg in visual mode
|
||||
let a=execute('unsilent :norm! V$zg')
|
||||
call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
|
||||
1
|
||||
norm! ]s
|
||||
call assert_equal('3 goood', getline('.'))
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('2 goood', cnt[3])
|
||||
" Remove "2 good" from spellfile
|
||||
2
|
||||
let a=execute('unsilent norm! V$zw')
|
||||
call assert_equal("Word '2 goood' added to ./Xspellfile.add", a[1:])
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('2 goood/!', cnt[4])
|
||||
|
||||
" Test for zG
|
||||
let a=execute('unsilent norm! V$zG')
|
||||
call assert_match("Word '2 goood' added to .*", a)
|
||||
let fname=matchstr(a, 'to\s\+\zs\f\+$')
|
||||
let cnt=readfile(fname)
|
||||
call assert_equal('2 goood', cnt[0])
|
||||
|
||||
" Test for zW
|
||||
let a=execute('unsilent norm! V$zW')
|
||||
call assert_match("Word '2 goood' added to .*", a)
|
||||
let cnt=readfile(fname)
|
||||
call assert_equal('# goood', cnt[0])
|
||||
call assert_equal('2 goood/!', cnt[1])
|
||||
|
||||
" Test for zuW
|
||||
let a=execute('unsilent norm! V$zuW')
|
||||
call assert_match("Word '2 goood' removed from .*", a)
|
||||
let cnt=readfile(fname)
|
||||
call assert_equal('# goood', cnt[0])
|
||||
call assert_equal('# goood/!', cnt[1])
|
||||
|
||||
" Test for zuG
|
||||
let a=execute('unsilent norm! $zG')
|
||||
call assert_match("Word 'goood' added to .*", a)
|
||||
let cnt=readfile(fname)
|
||||
call assert_equal('# goood', cnt[0])
|
||||
call assert_equal('# goood/!', cnt[1])
|
||||
call assert_equal('goood', cnt[2])
|
||||
let a=execute('unsilent norm! $zuG')
|
||||
let cnt=readfile(fname)
|
||||
call assert_match("Word 'goood' removed from .*", a)
|
||||
call assert_equal('# goood', cnt[0])
|
||||
call assert_equal('# goood/!', cnt[1])
|
||||
call assert_equal('#oood', cnt[2])
|
||||
" word not found in wordlist
|
||||
let a=execute('unsilent norm! V$zuG')
|
||||
let cnt=readfile(fname)
|
||||
call assert_match("", a)
|
||||
call assert_equal('# goood', cnt[0])
|
||||
call assert_equal('# goood/!', cnt[1])
|
||||
call assert_equal('#oood', cnt[2])
|
||||
|
||||
" Test for zug
|
||||
call delete('./Xspellfile.add')
|
||||
2
|
||||
let a=execute('unsilent norm! $zg')
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('goood', cnt[0])
|
||||
let a=execute('unsilent norm! $zug')
|
||||
call assert_match("Word 'goood' removed from \./Xspellfile.add", a)
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('#oood', cnt[0])
|
||||
" word not in wordlist
|
||||
let a=execute('unsilent norm! V$zug')
|
||||
call assert_match('', a)
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('#oood', cnt[0])
|
||||
|
||||
" Test for zuw
|
||||
call delete('./Xspellfile.add')
|
||||
2
|
||||
let a=execute('unsilent norm! Vzw')
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('2 goood/!', cnt[0])
|
||||
let a=execute('unsilent norm! Vzuw')
|
||||
call assert_match("Word '2 goood' removed from \./Xspellfile.add", a)
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('# goood/!', cnt[0])
|
||||
" word not in wordlist
|
||||
let a=execute('unsilent norm! $zug')
|
||||
call assert_match('', a)
|
||||
let cnt=readfile('./Xspellfile.add')
|
||||
call assert_equal('# goood/!', cnt[0])
|
||||
|
||||
" add second entry to spellfile setting
|
||||
set spellfile=./Xspellfile.add,./Xspellfile2.add
|
||||
call delete('./Xspellfile.add')
|
||||
2
|
||||
let a=execute('unsilent norm! $2zg')
|
||||
let cnt=readfile('./Xspellfile2.add')
|
||||
call assert_match("Word 'goood' added to ./Xspellfile2.add", a)
|
||||
call assert_equal('goood', cnt[0])
|
||||
|
||||
" Test for :spellgood!
|
||||
let temp = execute(':spe!0/0')
|
||||
call assert_match('Invalid region', temp)
|
||||
let spellfile = matchstr(temp, 'Invalid region nr in \zs.*\ze line \d: 0')
|
||||
call assert_equal(['# goood', '# goood/!', '#oood', '0/0'], readfile(spellfile))
|
||||
|
||||
" Test for :spellrare!
|
||||
:spellrare! raare
|
||||
call assert_equal(['# goood', '# goood/!', '#oood', '0/0', 'raare/?'], readfile(spellfile))
|
||||
call delete(spellfile)
|
||||
|
||||
" clean up
|
||||
exe "lang" oldlang
|
||||
call delete("./Xspellfile.add")
|
||||
call delete("./Xspellfile2.add")
|
||||
call delete("./Xspellfile.add.spl")
|
||||
call delete("./Xspellfile2.add.spl")
|
||||
|
||||
" zux -> no-op
|
||||
2
|
||||
norm! $zux
|
||||
call assert_equal([], glob('Xspellfile.add',0,1))
|
||||
call assert_equal([], glob('Xspellfile2.add',0,1))
|
||||
|
||||
set spellfile=
|
||||
bw!
|
||||
endfunc
|
@ -36,7 +36,7 @@ describe("'spell'", function()
|
||||
feed('ggJJJJJJ0')
|
||||
screen:expect([[
|
||||
{1:^Lorem} {1:ipsum} dolor sit {1:amet}, {1:consectetur} {1:adipiscing} {1:elit}, {1:sed} do {1:eiusmod} {1:tempor} {1:i}|
|
||||
{1:ncididunt} {1:ut} {1:labore} {1:et} {1:dolore} {1:magna} {1:aliqua}. {1:Ut} {1:enim} ad minim {1:veniam}, {1:quis} {1:nostru}|
|
||||
{1:ncididunt} {1:ut} {1:labore} et {1:dolore} {1:magna} {1:aliqua}. {1:Ut} {1:enim} ad minim {1:veniam}, {1:quis} {1:nostru}|
|
||||
{1:d} {1:exercitation} {1:ullamco} {1:laboris} {1:nisi} {1:ut} {1:aliquip} ex ea {1:commodo} {1:consequat}. {1:Duis} {1:aut}|
|
||||
{1:e} {1:irure} dolor in {1:reprehenderit} in {1:voluptate} {1:velit} {1:esse} {1:cillum} {1:dolore} {1:eu} {1:fugiat} {1:n}|
|
||||
{1:ulla} {1:pariatur}. {1:Excepteur} {1:sint} {1:occaecat} {1:cupidatat} non {1:proident}, {1:sunt} in culpa {1:qui}|
|
||||
@ -44,6 +44,7 @@ describe("'spell'", function()
|
||||
{0:~ }|
|
||||
|
|
||||
]])
|
||||
|
||||
end)
|
||||
|
||||
it('has correct highlight at start of line', function()
|
||||
|
Loading…
Reference in New Issue
Block a user