0

我使用 Vim 进行所有程序编辑,并且在所有源代码文件的顶部都有一个标准头文件。当我使用 :w 保存任何更改时,我设置了一个 .vimrc 文件来更新此标头中的某些字段(如上次修改)

我的问题是,如何按照只计算非空行的基本规则放入一个函数来计算代码行数?

我知道在打开的 vim 缓冲区中,我可以使用

:%s/\n//gn 

计算所有行,以及

:%s/\n\n//gn 

计算空行(基本上是计算两个换行符连续出现多少次,表示一个空行)。但是我如何把它放在我的 .vimrc 文件中呢?

这是我的 .vimrc 中更新标头字段的代码片段:

function! LastModified()
  if &modified
    let save_cursor = getpos(".")
    let n = min([20, line("$")])
    keepjumps exe '1,' . n . 's#^\(.\{,10}Last Modified:\).*#\1' .
          \ strftime(' %a %b %d, %Y  %I:%M%p') . '#e'
    keepjumps exe '1,' . n . 's#^\(.\{,10}Filename:\).*#\1' .
          \ ' ' . @% . '#e'
    keepjumps exe '1,' . n . 's#^\(.\{,10}LOC:\).*#\1' .
          \ ' ' . '' . '#e'
    call histdel('search', -1)
    call setpos('.', save_cursor)
  endif
endfun

另外,我想补充一下,我知道还有很多其他方法可以做到这一点(比如使用 shell 中的 wc --lines),但我有兴趣学习如何真正配置我的编辑器(所以称之为学习练习)。

4

2 回答 2

3

您实际上不应该:s在这里使用:

function! CountNonEmpty()
    return len(filter(getline(1, line('$')), '!empty(v:val)'))
endfunction

顺便说一句,我会使用 getline+map+setline 来实现您的标头更新程序:

function! LastModified()
    if &modified
        " If number of buffer lines is < 20, then getline(1, 20)"
        " will return only existing lines without any errors "
        call setline(1, map(getline(1, 20), 'substitute(substitute(substitute(v:val, '.
        \'"^\\v(.{,10}Last Modified:).*", "\\1 ".strftime("%s %b %d, %Y  %I:%M%p"), ""),'.
        \'"^\\v(.{,10}Filename:).*",      "\\1 ".escape(@%, "&\\~"), ""),'.
        \'"^\\v(.{,10}LOC:).*",           "\\1 ", "")'))
    endif
endfunction
于 2011-03-11T19:44:44.853 回答
1

这可能会有所帮助:

function! CountNonEmpty()
  redir => g:nonblank
  silent %s/^.\+$/&/n
  redir END
  return substitute(g:nonblank, '\n\s*\(\d\+\)\D.*$', '\1', '')
endfunction
  • :redir => 将以下 ex 命令的输出存储到给定变量中。看:help :redir
于 2011-03-11T19:35:30.170 回答