2

Can anyone show me how to catch the last badly spelled word when vim says ...hit BOTTOM? I tried to do it like this:

while 1
    try
        " Jump to the next
        silent keepjumps normal! ]s                                                                                
        let counter += 1
    catch /^Vim[^)]\+):E38[45]\D/
        " do some stuff
        break
    endtry
endwhile

Cycling through the badly spelled words works (as it seems to me) like cycling through the searched words. Indeed, if I replace ]s with n and then do some search the try-catch works fine.

1 Answer 1

3

Why don't you disable the wrapping momentarily while the function is executing?

function! CountAll() abort
  let ws = &wrapscan
  set nowrapscan
  try
    keepjumps normal! gg
    " FIXME: If the first word is an error, count it
    " - may be with a reverse search? 
    " - Or by testing the syntax highlighting under the cursor
    let nb = 0
    let p = getcurpos()
    while 1
      silent! keepjumps normal! ]s

      let p2 = getcurpos()
      if p == p2
        " echomsg "No more errors"
        break
      endif
      " else, found...
      let p = p2
      let nb += 1
    endwhile
  finally
    let &wrapscan = ws
  endtry
  return nb
endfunction

PS: I was hoping that catch would be able to recognize the "no more error" case. Alas, with :silent it just makes Vim blink. We need to track cursor positions.

4
  • thanks, Luc. It seems to me that I've already tried something like this... The problem is that you have to count them one-by-one. As we well know, many if statements (plus setting/getting/moving of the cursor) when cycling slow down the program, and in fact after cycling the first 100 wrong words in the document the benchmarks starts to fail down seriously.
    – Max_Payne
    Commented Jan 7, 2020 at 18:30
  • My goal is to try to move in tens (silent! keepjumps normal! 10]s), then maybe to approximate a little, if the document is greater than 1000 lines so go with 50]s. This will be faster than counting them one-by-one since it runs in C. The dilemma is that you don't know if 10]s is actually 10 jumps maybe is 9? If is less than 10 the try-catch will stop you before making let nb += 10 so in the catch section you know that the last ten words you need to count them one-by-one, and at the same time you know that you will never count progressively more than 9 times, I think...
    – Max_Payne
    Commented Jan 7, 2020 at 18:30
  • 1
    Another possible approach could be to transform/filter line parts that exhibit misspellings syntax-hl. I was able to have acceptable performances to filter out comments with my lh#syntax#line_filter(). May be it could be adapted. The important trick for good performances is to loop with map(), filter() and reduce with join(). Commented Jan 7, 2020 at 18:54
  • 1
    Back to my initial answer, you could remember the n-2 position, and start back from this position to increment with step/2, and again recursively until the step is 1. Commented Jan 7, 2020 at 18:58

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Not the answer you're looking for? Browse other questions tagged or ask your own question.