配置Vim以插入代码行的文本

配置Vim以插入代码行的文本,vim,count,lines,Vim,Count,Lines,我使用Vim进行所有程序编辑,并且在所有源代码文件的顶部都有一个标准头文件。我设置了一个.vimrc文件,以便在使用:w保存任何更改时更新此标题中的某些字段(如上次修改的字段) 我的问题是,我如何在一个函数中输入代码行数,遵循只计算非空行的基本规则 我知道在开放的vim缓冲区内,我可以使用 :%s/\n//gn 计算所有行数,以及 :%s/\n\n//gn 计算空行数(基本上计算一行中出现两个换行符的次数,表示一个空行)。但是如何将其放入.vimrc文件中 下面是my.vimrc中更新标

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

我的问题是,我如何在一个函数中输入代码行数,遵循只计算非空行的基本规则

我知道在开放的vim缓冲区内,我可以使用

:%s/\n//gn 
计算所有行数,以及

:%s/\n\n//gn 
计算空行数(基本上计算一行中出现两个换行符的次数,表示一个空行)。但是如何将其放入.vimrc文件中

下面是my.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
另外,我想补充一点,我知道还有很多其他方法可以做到这一点(比如使用wc——shell中的行),但我对学习如何真正配置编辑器感兴趣(所以称之为学习练习)。

这可能会有帮助:

function! CountNonEmpty()
  redir => g:nonblank
  silent %s/^.\+$/&/n
  redir END
  return substitute(g:nonblank, '\n\s*\(\d\+\)\D.*$', '\1', '')
endfunction
  • :redir=>将以下ex命令的输出存储到给定变量中。请参见:帮助:重拨
    • 这可能有助于:

      function! CountNonEmpty()
        redir => g:nonblank
        silent %s/^.\+$/&/n
        redir END
        return substitute(g:nonblank, '\n\s*\(\d\+\)\D.*$', '\1', '')
      endfunction
      • :redir=>将以下ex命令的输出存储到给定变量中。请参见:帮助:重拨

      您实际上不应该在此处使用
      :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
      
      函数!LastModified()
      if&modified
      如果缓冲行数小于20,则getline(1,20)
      “将只返回没有任何错误的现有行”
      调用setline(1,map(getline(1,20)),替换。
      \“^\\v(.{,10}上次修改:).*”,“\\1”.strftime(“%s%b%d,%Y%I:%M%p”),“),”。
      \“^\\v(.{,10}文件名:).*”,“\\1”。转义(@%,“&\\\ ~”,”)。
      \“^\\v(.{,10}LOC:).*”、“\\1”和“)”)
      恩迪夫
      端功能
      
      您实际上不应该在此处使用
      :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
      
      函数!LastModified()
      if&modified
      如果缓冲行数小于20,则getline(1,20)
      “将只返回没有任何错误的现有行”
      调用setline(1,map(getline(1,20)),替换。
      \“^\\v(.{,10}上次修改:).*”,“\\1”.strftime(“%s%b%d,%Y%I:%M%p”),“),”。
      \“^\\v(.{,10}文件名:).*”,“\\1”。转义(@%,“&\\\ ~”,”)。
      \“^\\v(.{,10}LOC:).*”、“\\1”和“)”)
      恩迪夫
      端功能
      
      您还可以将行计数设置为
      行($”
      。您还可以将行计数设置为
      行($”
      。这更接近我想要的,效果很好。有没有一种方法可以让我无法计算包含3个或更少字符的行数?@dvanaria:您可以替换
      !空(v:val)
      ,带有任何返回数字的表达式。对于您的请求,它是
      v:val=~#“^.\{,3}$”
      。我是否可以替换中的表达式!第二个示例为空(v:val)?例如:return len(filter(getline(1,line(“$”),“!empty(v:val=~#“^.\{,2}$”))@dvanaria您应该将整个第二个参数替换为
      filter()
      ,而不是
      empty()
      参数
      empty()
      是一个检查其参数是否为空的函数,对于字符串,它等效于
      v:val==#“”
      v:val=~#“^$”
      =~#
      是一个检查其左参数是否匹配其右参数的正则表达式的运算符<代码>!empty(v:val=~#“^.\{,2}$”将起作用,因为
      empty(number)
      相当于
      number==0
      =~
      将在左str与右regex不匹配时返回0,否则返回1,因此
      !空的(v:val=~\\“^.\{,2}$”
      v:val=~\\“^.\{,2}$”
      将产生相同的结果。这更接近我想要的结果,效果很好。有没有一种方法可以让我无法计算包含3个或更少字符的行数?@dvanaria:您可以替换
      !空(v:val)
      ,带有任何返回数字的表达式。对于您的请求,它是
      v:val=~#“^.\{,3}$”
      。我是否可以替换中的表达式!第二个示例为空(v:val)?例如:return len(filter(getline(1,line(“$”),“!empty(v:val=~#“^.\{,2}$”))@dvanaria您应该将整个第二个参数替换为
      filter()
      ,而不是
      empty()
      参数
      empty()
      是一个检查其参数是否为空的函数,对于字符串,它等效于
      v:val==#“”
      v:val=~#“^$”
      =~#
      是一个检查其左参数是否匹配其右参数的正则表达式的运算符<代码>!empty(v:val=~#“^.\{,2}$”将起作用,因为
      empty(number)
      相当于
      number==0
      =~
      将在左str与右regex不匹配时返回0,否则返回1,因此
      !空(v:val=~“^.\{,2}$”
      v:val=~“^.\{,2}$”
      将产生相同的结果。