5

I'm trying to obtain the number of lines matching a pattern, from a function. I would like the cursor not to be moved at all during the process.

In this case, non-empty and non-comment lines. Here's what I have so far:

function! CountRealLines()
  :%s/^[^$,\"]//gn
endfunction

This displays the expected result, but I'm not sure how to return the count value (rather than printing the default message).

I also tried:

  • substitute(): I can't seem to make it work like the :s command in this case.

  • search(): It could be looped, but I think there must be a better way to go.

1

1 Answer 1

6

I would like the cursor not to be moved at all during the process.

You have to use winsaveview() and winrestview() functions. I believe there were similar questions answered earlier, but anyway here is my solution in form of a "command modifier":

command! -nargs=1 -complete=command Nomove
    \   try
    \ |     let s:svpos = winsaveview()
    \ |     execute <q-mods> <q-args>
    \ | finally
    \ |     call winrestview(s:svpos)
    \ |     unlet s:svpos
    \ | endtry

I'm not sure how to return the count value

The simplest thing is to increment the counter by :global hits

function! CountRealLines()
    let l:count = 0
    Nomove g/^[^$,\"]/let l:count += 1
    return l:count
endfunction
1
  • 1
    Perfect! I did not think of using :g this way. Your nomove command is a great bonus too, thanks!
    – Biggybi
    Commented Jul 27, 2020 at 19:35

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.