Skip to content

Commit

Permalink
patch 9.1.0418: Cannot move to previous/next rare word
Browse files Browse the repository at this point in the history
Problem:  Cannot move to previous/next rare word
          (Colin Kennedy)
Solution: Add the ]r and [r motions (Christ van Willegen)

fixes: #14773
closes: #14780

Signed-off-by: Christ van Willegen - van Noort <github.com@vanwillegen-vannoort.nl>
Signed-off-by: Christian Brabandt <cb@256bit.org>
  • Loading branch information
cvwillegen authored and chrisbra committed May 17, 2024
1 parent cf78d0d commit 8e4c4c7
Show file tree
Hide file tree
Showing 14 changed files with 108 additions and 15 deletions.
13 changes: 12 additions & 1 deletion runtime/doc/spell.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*spell.txt* For Vim version 9.1. Last change: 2024 May 11
*spell.txt* For Vim version 9.1. Last change: 2024 May 17


VIM REFERENCE MANUAL by Bram Moolenaar
Expand Down Expand Up @@ -62,6 +62,17 @@ To search for the next misspelled word:
*[S*
[S Like "]S" but search backwards.

*]r*
]r Move to next "rare" word after the cursor.
A count before the command can be used to repeat.
'wrapscan' applies.

*[r*
[r Like "]r" but search backwards, find the "rare"
word before the cursor. Doesn't recognize words
split over two lines, thus may stop at words that are
not highlighted as rare.


To add words to your own word list:

Expand Down
2 changes: 2 additions & 0 deletions runtime/doc/tags
Original file line number Diff line number Diff line change
Expand Up @@ -5876,6 +5876,7 @@ ZZ editing.txt /*ZZ*
[p change.txt /*[p*
[pattern] pattern.txt /*[pattern]*
[quotex] intro.txt /*[quotex]*
[r spell.txt /*[r*
[range] cmdline.txt /*[range]*
[s spell.txt /*[s*
[star motion.txt /*[star*
Expand Down Expand Up @@ -5904,6 +5905,7 @@ ZZ editing.txt /*ZZ*
]i tagsrch.txt /*]i*
]m motion.txt /*]m*
]p change.txt /*]p*
]r spell.txt /*]r*
]s spell.txt /*]s*
]star motion.txt /*]star*
]z fold.txt /*]z*
Expand Down
8 changes: 5 additions & 3 deletions runtime/doc/version9.txt
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
*version9.txt* For Vim version 9.1. Last change: 2024 May 05
*version9.txt* For Vim version 9.1. Last change: 2024 May 17


VIM REFERENCE MANUAL by Bram Moolenaar
Expand Down Expand Up @@ -41587,15 +41587,17 @@ Autocommands: ~

Highlighting: ~

|hl-MsgArea| highlighting of the Command-line and messages area.
|hl-MsgArea| highlighting of the Command-line and messages area

Commands: ~

|[r| and |]r| to move the cursor to previous/next rare word


Options: ~

'winfixbuf' Keep buffer focused in a window
't_xo' Terminal uses XON/XOFF handshaking (e.g. vt420).
't_xo' Terminal uses XON/XOFF handshaking (e.g. vt420)

==============================================================================
INCOMPATIBLE CHANGES *incompatible-9.2*
Expand Down
2 changes: 1 addition & 1 deletion src/drawline.c
Original file line number Diff line number Diff line change
Expand Up @@ -1801,7 +1801,7 @@ win_line(
pos = wp->w_cursor;
wp->w_cursor.lnum = lnum;
wp->w_cursor.col = linecol;
len = spell_move_to(wp, FORWARD, TRUE, TRUE, &spell_hlf);
len = spell_move_to(wp, FORWARD, SMT_ALL, TRUE, &spell_hlf);

// spell_move_to() may call ml_get() and make "line" invalid
line = ml_get_buf(wp->w_buffer, lnum, FALSE);
Expand Down
2 changes: 1 addition & 1 deletion src/evalfunc.c
Original file line number Diff line number Diff line change
Expand Up @@ -10959,7 +10959,7 @@ f_spellbadword(typval_T *argvars UNUSED, typval_T *rettv)
if (argvars[0].v_type == VAR_UNKNOWN)
{
// Find the start and length of the badly spelled word.
len = spell_move_to(curwin, FORWARD, TRUE, TRUE, &attr);
len = spell_move_to(curwin, FORWARD, SMT_ALL, TRUE, &attr);
if (len != 0)
{
word = ml_get_cursor();
Expand Down
2 changes: 1 addition & 1 deletion src/insexpand.c
Original file line number Diff line number Diff line change
Expand Up @@ -5195,7 +5195,7 @@ spell_back_to_badword(void)
{
pos_T tpos = curwin->w_cursor;

spell_bad_len = spell_move_to(curwin, BACKWARD, TRUE, TRUE, NULL);
spell_bad_len = spell_move_to(curwin, BACKWARD, SMT_ALL, TRUE, NULL);
if (curwin->w_cursor.col != tpos.col)
start_arrow(&tpos);
}
Expand Down
10 changes: 6 additions & 4 deletions src/normal.c
Original file line number Diff line number Diff line change
Expand Up @@ -2593,7 +2593,7 @@ nv_zg_zw(cmdarg_T *cap, int nchar)
// off this fails and find_ident_under_cursor() is
// used below.
emsg_off++;
len = spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL);
len = spell_move_to(curwin, FORWARD, SMT_ALL, TRUE, NULL);
emsg_off--;
if (len != 0 && curwin->w_cursor.col <= pos.col)
ptr = ml_get_pos(&curwin->w_cursor);
Expand Down Expand Up @@ -4529,13 +4529,15 @@ nv_brackets(cmdarg_T *cap)
#endif

#ifdef FEAT_SPELL
// "[s", "[S", "]s" and "]S": move to next spell error.
else if (cap->nchar == 's' || cap->nchar == 'S')
// "[r", "[s", "[S", "]r", "]s" and "]S": move to next spell error.
else if (cap->nchar == 'r' || cap->nchar == 's' || cap->nchar == 'S')
{
setpcmark();
for (n = 0; n < cap->count1; ++n)
if (spell_move_to(curwin, cap->cmdchar == ']' ? FORWARD : BACKWARD,
cap->nchar == 's' ? TRUE : FALSE, FALSE, NULL) == 0)
cap->nchar == 's' ? SMT_ALL :
cap->nchar == 'r' ? SMT_RARE :
SMT_BAD, FALSE, NULL) == 0)
{
clearopbeep(cap->oap);
break;
Expand Down
2 changes: 1 addition & 1 deletion src/proto/spell.pro
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@ int match_compoundrule(slang_T *slang, char_u *compflags);
int valid_word_prefix(int totprefcnt, int arridx, int flags, char_u *word, slang_T *slang, int cond_req);
int spell_valid_case(int wordflags, int treeflags);
int spell_check_window(win_T *wp);
int spell_move_to(win_T *wp, int dir, int allwords, int curline, hlf_T *attrp);
int spell_move_to(win_T *wp, int dir, smt_T behaviour, int curline, hlf_T *attrp);
void spell_cat_line(char_u *buf, char_u *line, int maxlen);
char_u *spell_enc(void);
slang_T *slang_alloc(char_u *lang);
Expand Down
6 changes: 4 additions & 2 deletions src/spell.c
Original file line number Diff line number Diff line change
Expand Up @@ -1336,7 +1336,7 @@ no_spell_checking(win_T *wp)
spell_move_to(
win_T *wp,
int dir, // FORWARD or BACKWARD
int allwords, // TRUE for "[s"/"]s", FALSE for "[S"/"]S"
smt_T behaviour, // Behaviour of the function
int curline,
hlf_T *attrp) // return: attributes of bad word or NULL
// (only when "dir" is FORWARD)
Expand Down Expand Up @@ -1441,7 +1441,9 @@ spell_move_to(
if (attr != HLF_COUNT)
{
// We found a bad word. Check the attribute.
if (allwords || attr == HLF_SPB)
if (behaviour == SMT_ALL
|| (behaviour == SMT_BAD && attr == HLF_SPB)
|| (behaviour == SMT_RARE && attr == HLF_SPR))
{
// When searching forward only accept a bad word after
// the cursor.
Expand Down
2 changes: 1 addition & 1 deletion src/spellsuggest.c
Original file line number Diff line number Diff line change
Expand Up @@ -512,7 +512,7 @@ spell_suggest(int count)
badlen = ml_get_curline_len() - (int)curwin->w_cursor.col;
}
// Find the start of the badly spelled word.
else if (spell_move_to(curwin, FORWARD, TRUE, TRUE, NULL) == 0
else if (spell_move_to(curwin, FORWARD, SMT_ALL, TRUE, NULL) == 0
|| curwin->w_cursor.col > prev_cursor.col)
{
// No bad word or it starts after the cursor: use the word under the
Expand Down
2 changes: 2 additions & 0 deletions src/testdir/Make_all.mak
Original file line number Diff line number Diff line change
Expand Up @@ -278,6 +278,7 @@ NEW_TESTS = \
test_spell \
test_spell_utf8 \
test_spellfile \
test_spellrare \
test_startup \
test_startup_utf8 \
test_stat \
Expand Down Expand Up @@ -521,6 +522,7 @@ NEW_TESTS_RES = \
test_spell.res \
test_spell_utf8.res \
test_spellfile.res \
test_spellrare.res \
test_startup.res \
test_stat.res \
test_statusline.res \
Expand Down
61 changes: 61 additions & 0 deletions src/testdir/test_spellrare.vim
Original file line number Diff line number Diff line change
@@ -0,0 +1,61 @@
" Test spell checking

source check.vim
CheckFeature spell

" Test spellbadword() with argument, specifically to move to "rare" words
" in normal mode.
func Test_spellrareword()
set spell

" Create a small word list to test that spellbadword('...')
" can return ['...', 'rare'].
let lines =<< trim END
foo
foobar/?
foobara/?
END
call writefile(lines, 'Xwords', 'D')

mkspell! Xwords.spl Xwords
set spelllang=Xwords.spl
call assert_equal(['foobar', 'rare'], spellbadword('foo foobar'))

new
call setline(1, ['foo', '', 'foo bar foo bar foobara foo foo foo foobar', '', 'End'])
set spell wrapscan
normal ]s
call assert_equal('foo', expand('<cword>'))
normal ]s
call assert_equal('bar', expand('<cword>'))

normal ]r
call assert_equal('foobara', expand('<cword>'))
normal ]r
call assert_equal('foobar', expand('<cword>'))
normal ]r
call assert_equal('foobara', expand('<cword>'))
normal 2]r
call assert_equal('foobara', expand('<cword>'))

normal [r
call assert_equal('foobar', expand('<cword>'))
normal [r
call assert_equal('foobara', expand('<cword>'))
normal [r
call assert_equal('foobar', expand('<cword>'))
normal 2[r
call assert_equal('foobar', expand('<cword>'))

bwipe!
set nospell

call delete('Xwords.spl')
set spelllang&
set spell&

" set 'encoding' to clear the word list
set encoding=utf-8
endfunc

" vim: shiftwidth=2 sts=2 expandtab
2 changes: 2 additions & 0 deletions src/version.c
Original file line number Diff line number Diff line change
Expand Up @@ -704,6 +704,8 @@ static char *(features[]) =

static int included_patches[] =
{ /* Add new patch number below this line */
/**/
418,
/**/
417,
/**/
Expand Down
9 changes: 9 additions & 0 deletions src/vim.h
Original file line number Diff line number Diff line change
Expand Up @@ -1529,6 +1529,15 @@ typedef enum
'*', '#', '_', '!', '.', 'o', 'q', \
'z', 'Z', 'g'}

/*
* Values for behaviour in spell_move_to
*/
typedef enum
{
SMT_ALL = 0 // Move to "all" words
, SMT_BAD // Move to "bad" words only
, SMT_RARE // Move to "rare" words only
} smt_T;
/*
* Boolean constants
*/
Expand Down

0 comments on commit 8e4c4c7

Please sign in to comment.