【问题标题】:Simple Vim Programming (vimrc file)简单的 Vim 编程(vimrc 文件)
【发布时间】:2011-03-13 17:45:43
【问题描述】:

我正在尝试学习如何使用我自己的函数配置我的 .vimrc 文件。

我想编写一个函数,它遍历文件中的每一行并计算字符总数,但忽略所有空格。这是一个编程练习,也是更复杂程序的垫脚石(我知道还有其他方法可以使用 Vim 或外部程序获得这个示例值)。

这是我目前所拥有的:

function countchars()
    let line = 0
    let count = 0
    while line < line("$")
        " update count here, don't count whitespace
        let line = getline(".")
    return count
endfun

我可以用什么功能代码替换该注释行?

【问题讨论】:

    标签: count vim character


    【解决方案1】:

    如果我正确理解了这个问题,您希望计算一行中非空白字符的数量。一个相当简单的方法是删除空格并查看结果行的长度。因此,像这样:

    function! Countchars()
        let l = 1
        let char_count = 0
        while l <= line("$")
            let char_count += len(substitute(getline(l), '\s', '', 'g'))
            let l += 1
        endwhile
        return char_count
    endfunction
    

    问题答案的关键部分是使用替代品。命令是:

    substitute(expr,pattern,repl,flags)
    

    expr 在这种情况下是getline(l),其中l 是被迭代的行号。 getline() 返回该行的内容,所以这就是正在解析的内容。该模式是匹配任何单个空白字符的正则表达式\s。它被替换为'',即一个空字符串。标志g 使它重复替换的次数与在行上找到空格一样多。

    替换完成后,len() 会给出非空白字符的数量,并将其添加到 char_count 的当前值和 +=。


    我对您的示例进行了一些更改:

    • 函数名以大写字母开头(这是用户定义函数的要求:参见:help user-functions)
    • 我已将 count 重命名为 char_count,因为您不能拥有与函数同名的变量,而 count() 是一个内置函数
    • line 也是如此:我将其重命名为 l
    • 文件的第一行是第 1 行,而不是第 0 行,所以我将 l 初始化为 1
    • while 循环计数到但不包括最后一行,我假设您想要文件中的所有行(这可能与从 1 开始的行编号有关):我将您的代码更改为使用 &lt;= &lt;
    • 块不是基于vim中的缩进,所以while需要endwhile
    • 在你的函数中,你有let line = getline('.')
    • 我在function 定义上添加了!,因为它使增量开发变得更加容易(每次重新获取文件时,它都会用新版本覆盖该函数,而不是已经吐出有关它的错误消息现有)。
    • 文件递增的工作方式略有不同...

    在你的函数中,你有let line = getline('.')。忽略变量名,这个实现还是有一些问题。我想你的意思是let l = line('.'),它给出了当前行的行号。 getline('.') 给出了当前行的内容,因此 while 行的比较会将当前行的内容与最后一行的编号进行比较,这将失败。另一个问题是您实际上并没有在文件中移动,因此当前行将是您调用函数时所在的任何一行并且永远不会更改,从而导致无限循环。我已将其替换为简单的 += 1 以单步执行文件。

    有一些方法可以使当前行成为一种有用的方法,例如,如果您正在编写一个需要一系列行的函数,但我认为我现在已经写得足够多了,上面的内容将希望让你现在开始。无论如何,stackoverflow 上有很多人可以帮助解决任何问题!

    看看:

    :help usr_41.txt
    :help function-list
    :help user-functions
    :help substitute()
    

    以及:help,后面是我在函数中使用的各种东西(getline()、line()、let+= 等)。

    希望对您有所帮助。

    【讨论】:

    • len('ñ') 将返回 2,处理多字节字符使用 len(split(getline(l),'\zs\s*'))
    【解决方案2】:

    这种方法使用列表:

    function! Countchars()
      let n = 0
      for line in getline(1,line('$'))
        let n += len(split(line,'\zs\s*'))
      endfor
      return n
    endfunction

    【讨论】:

      【解决方案3】:

      我想你已经找到了解决方案。

      仅供参考: 我用它来计算 Vim 中没有空格的字符: %s/\S/&amp;/gn

      【讨论】:

        猜你喜欢
        • 2020-09-01
        • 1970-01-01
        • 2012-02-17
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多