mirror of
https://github.com/neovim/neovim.git
synced 2024-12-19 10:45:16 -07:00
vim-patch:9.1.0418: Cannot move to previous/next rare word (#28822)
Problem: Cannot move to previous/next rare word
(Colin Kennedy)
Solution: Add the ]r and [r motions (Christ van Willegen)
fixes: vim/vim#14773
closes: vim/vim#14780
8e4c4c7d87
Co-authored-by: Christ van Willegen - van Noort <github.com@vanwillegen-vannoort.nl>
This commit is contained in:
parent
5947f249f8
commit
62eb7e79a5
@ -51,6 +51,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:
|
||||
|
||||
|
@ -1415,7 +1415,7 @@ int win_line(win_T *wp, linenr_T lnum, int startrow, int endrow, int col_rows, s
|
||||
pos_T pos = wp->w_cursor;
|
||||
wp->w_cursor.lnum = lnum;
|
||||
wp->w_cursor.col = linecol;
|
||||
size_t len = spell_move_to(wp, FORWARD, true, true, &spell_hlf);
|
||||
size_t 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);
|
||||
|
@ -8308,7 +8308,7 @@ static void f_spellbadword(typval_T *argvars, typval_T *rettv, EvalFuncData fptr
|
||||
size_t len = 0;
|
||||
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 = get_cursor_pos_ptr();
|
||||
curwin->w_set_curswant = true;
|
||||
|
@ -4570,7 +4570,7 @@ void free_insexpand_stuff(void)
|
||||
static void 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);
|
||||
}
|
||||
|
@ -2710,7 +2710,7 @@ static int 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);
|
||||
@ -4272,12 +4272,15 @@ static void nv_brackets(cmdarg_T *cap)
|
||||
cap->count1) == false) {
|
||||
clearopbeep(cap->oap);
|
||||
}
|
||||
} else if (cap->nchar == 's' || cap->nchar == 'S') {
|
||||
// "[s", "[S", "]s" and "]S": move to next spell error.
|
||||
} else if (cap->nchar == 'r' || cap->nchar == 's' || cap->nchar == 'S') {
|
||||
// "[r", "[s", "[S", "]r", "]s" and "]S": move to next spell error.
|
||||
setpcmark();
|
||||
for (n = 0; n < cap->count1; n++) {
|
||||
if (spell_move_to(curwin, cap->cmdchar == ']' ? FORWARD : BACKWARD,
|
||||
cap->nchar == 's', false, NULL) == 0) {
|
||||
cap->nchar == 's'
|
||||
? SMT_ALL
|
||||
: cap->nchar == 'r' ? SMT_RARE : SMT_BAD,
|
||||
false, NULL) == 0) {
|
||||
clearopbeep(cap->oap);
|
||||
break;
|
||||
}
|
||||
|
@ -1290,11 +1290,11 @@ static inline bool can_syn_spell(win_T *wp, linenr_T lnum, int col)
|
||||
/// to after badly spelled word before the cursor.
|
||||
///
|
||||
/// @param dir FORWARD or BACKWARD
|
||||
/// @param allwords true for "[s"/"]s", false for "[S"/"]S"
|
||||
/// @param behaviour Behaviour of the function
|
||||
/// @param attrp return: attributes of bad word or NULL (only when "dir" is FORWARD)
|
||||
///
|
||||
/// @return 0 if not found, length of the badly spelled word otherwise.
|
||||
size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *attrp)
|
||||
size_t spell_move_to(win_T *wp, int dir, smt_T behaviour, bool curline, hlf_T *attrp)
|
||||
{
|
||||
pos_T found_pos;
|
||||
size_t found_len = 0;
|
||||
@ -1398,7 +1398,9 @@ size_t spell_move_to(win_T *wp, int dir, bool allwords, bool curline, hlf_T *att
|
||||
|
||||
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.
|
||||
if (dir == BACKWARD
|
||||
|
@ -21,6 +21,13 @@ extern char *e_format;
|
||||
extern char *repl_from;
|
||||
extern char *repl_to;
|
||||
|
||||
/// 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;
|
||||
|
||||
#ifdef INCLUDE_GENERATED_DECLARATIONS
|
||||
# include "spell.h.generated.h"
|
||||
#endif
|
||||
|
@ -484,7 +484,7 @@ void spell_suggest(int count)
|
||||
badlen = get_cursor_line_len() - 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
|
||||
// cursor.
|
||||
|
61
test/old/testdir/test_spellrare.vim
Normal file
61
test/old/testdir/test_spellrare.vim
Normal file
@ -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
|
Loading…
Reference in New Issue
Block a user