首页 > 解决方案 > 如何用 Vim 替换 () 和 &commentstring 注释整行

问题描述

我一直在尝试编写一个 vimscript 来读取 shell 命令 ( figlet) 的输出并注释它的每一行。我想使用该&commentstring变量,因为我希望此脚本适用于任何文件类型。

到目前为止,我只取得了不一致的结果。这是和示例:

  1. 提示用户输入他/她的姓名首字母并将其传递给 shell 命令figlet以在文件顶部打印 ascii 艺术:
let g:initials = input('Authors initials: ')
execute '0r! figlet -W ' . toupper(g:initials)

输出如下(例如 g:initials = JT):

      _   _____ 
     | | |_   _|
  _  | |   | |  
 | |_| |   | |  
  \___/    |_|  
  1. 获取输出的行数:
let s:line_count = system("figlet -W " . g:signit_initials . "| wc -l")
  1. 使用 vim 函数substitute()注释每一行:
let s:i = 1
while s:i < s:line_count
execute 'silent' . s:i . 's/^.*$/\=substitute(&commentstring, "%s", "\t" . getline(".") . "\t", "")'
let s:i += 1
endwhile

输出如下:

/*      _   _____ */
/*     | | |_   _|*/
/*  _  | |   | |  */
/* | |_| |   | |  */
/*  ___/    |_|  */

如您所见,它一直运行良好,直到最后一行,我不明白为什么。也许有更好的方法来解决这个问题。无论如何,如果有人能为我提供一些关于如何解决这个小问题的帮助,我真的很感激。

标签: vimpluginsstring-substitution

解决方案


直到最后一行都运行良好,我不明白为什么

最后一行包含一个反斜杠。并根据:h sub-replace-special. 所以,至少,你必须用另一个来逃避它。有点escape(getline('.'), '\')。但是,对于这种特殊情况,我宁愿选择printf,因为它看起来更容易、更自然:printf(&cms, "\t"..getline(".").."\t")

也不需要“while”循环,因为许多命令和函数都接受行范围:它更有效,更容易编写。

也许有更好的方法来解决这个问题。

IMO 这看起来更好:

call append(0, map(systemlist("figlet -W "..toupper(g:initials)),
    \ {_, v -> printf(&cms, "\t" .. v .. "\t")}))

推荐阅读