summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorChrist van Willegen - van Noort <github.com@vanwillegen-vannoort.nl>2024-05-17 18:49:27 +0200
committerChristian Brabandt <cb@256bit.org>2024-05-17 18:52:45 +0200
commit8e4c4c7d87def2b100a5d64dc518ef85d9de8765 (patch)
tree52e523d63196ca353a18d0fb13d2f98ffbd80ca3
parentcf78d0df51f2737f278a2410f166862001d875ae (diff)
patch 9.1.0418: Cannot move to previous/next rare wordv9.1.0418
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>
-rw-r--r--runtime/doc/spell.txt13
-rw-r--r--runtime/doc/tags2
-rw-r--r--runtime/doc/version9.txt8
-rw-r--r--src/drawline.c2
-rw-r--r--src/evalfunc.c2
-rw-r--r--src/insexpand.c2
-rw-r--r--src/normal.c10
-rw-r--r--src/proto/spell.pro2
-rw-r--r--src/spell.c6
-rw-r--r--src/spellsuggest.c2
-rw-r--r--src/testdir/Make_all.mak2
-rw-r--r--src/testdir/test_spellrare.vim61
-rw-r--r--src/version.c2
-rw-r--r--src/vim.h9
14 files changed, 108 insertions, 15 deletions
diff --git a/runtime/doc/spell.txt b/runtime/doc/spell.txt
index ab3b120457..809e3a8d3c 100644
--- a/runtime/doc/spell.txt
+++ b/runtime/doc/spell.txt
@@ -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
@@ -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:
diff --git a/runtime/doc/tags b/runtime/doc/tags
index d354df1ee5..2c3fd7f9da 100644
--- a/runtime/doc/tags
+++ b/runtime/doc/tags
@@ -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*
@@ -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*
diff --git a/runtime/doc/version9.txt b/runtime/doc/version9.txt
index 192c3ee751..1c5a29f200 100644
--- a/runtime/doc/version9.txt
+++ b/runtime/doc/version9.txt
@@ -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
@@ -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*
diff --git a/src/drawline.c b/src/drawline.c
index 81577be42a..9502fc53a5 100644
--- a/src/drawline.c
+++ b/src/drawline.c
@@ -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);
diff --git a/src/evalfunc.c b/src/evalfunc.c
index fecdc43514..cd3a6fd80a 100644
--- a/src/evalfunc.c
+++ b/src/evalfunc.c
@@ -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();
diff --git a/src/insexpand.c b/src/insexpand.c
index 93a56a8bd3..1520d57609 100644
--- a/src/insexpand.c
+++ b/src/insexpand.c
@@ -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);
}
diff --git a/src/normal.c b/src/normal.c
index fef282647f..580eb72298 100644
--- a/src/normal.c
+++ b/src/normal.c
@@ -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);
@@ -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;
diff --git a/src/proto/spell.pro b/src/proto/spell.pro
index 98a1353493..680bf34f4f 100644
--- a/src/proto/spell.pro
+++ b/src/proto/spell.pro
@@ -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);
diff --git a/src/spell.c b/src/spell.c
index 43c521dde6..3ae484c145 100644
--- a/src/spell.c
+++ b/src/spell.c
@@ -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)
@@ -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.
diff --git a/src/spellsuggest.c b/src/spellsuggest.c
index c6e61832da..b305bfb83e 100644
--- a/src/spellsuggest.c
+++ b/src/spellsuggest.c
@@ -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
diff --git a/src/testdir/Make_all.mak b/src/testdir/Make_all.mak
index b41f5f49fc..a80b1300e5 100644
--- a/src/testdir/Make_all.mak
+++ b/src/testdir/Make_all.mak
@@ -278,6 +278,7 @@ NEW_TESTS = \
test_spell \
test_spell_utf8 \
test_spellfile \
+ test_spellrare \
test_startup \
test_startup_utf8 \
test_stat \
@@ -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 \
diff --git a/src/testdir/test_spellrare.vim b/src/testdir/test_spellrare.vim
new file mode 100644
index 0000000000..bbb13c27c2
--- /dev/null
+++ b/src/testdir/test_spellrare.vim
@@ -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
diff --git a/src/version.c b/src/version.c
index 682a46873a..ad3b585cdc 100644
--- a/src/version.c
+++ b/src/version.c
@@ -705,6 +705,8 @@ static char *(features[]) =
static int included_patches[] =
{ /* Add new patch number below this line */
/**/
+ 418,
+/**/
417,
/**/
416,
diff --git a/src/vim.h b/src/vim.h
index f359245fa2..654e52344d 100644
--- a/src/vim.h
+++ b/src/vim.h
@@ -1530,6 +1530,15 @@ typedef enum
'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
*/
#ifndef TRUE