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.

Biggybi
  • 2,740
  • 9
  • 29

1 Answers1

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
Matt
  • 20,685
  • 1
  • 11
  • 24
  • 1
    Perfect! I did not think of using :g this way. Your nomove command is a great bonus too, thanks! – Biggybi Jul 27 '20 at 19:35