通过Ruby处理vim选择并替换内容

通过Ruby处理vim选择并替换内容,ruby,vim,Ruby,Vim,如何通过Ruby脚本运行选择并用该脚本的最后一个返回值替换它 例如,我有这样一行 12|22|33 我想要两位数 24|44|66 我不知道vim的方法(但我想知道是否有人能帮忙)但我知道Ruby的方法 # assuming the text is in variable "line" line.split("|").map(&:to_i).map { |no| no*2 }.join("|") 当然,我可以编写一个Ruby脚本,它接受参数并使用::调用它!my_script.rb

如何通过Ruby脚本运行选择并用该脚本的最后一个返回值替换它

例如,我有这样一行

12|22|33
我想要两位数

24|44|66
我不知道vim的方法(但我想知道是否有人能帮忙)但我知道Ruby的方法

# assuming the text is in variable "line"
line.split("|").map(&:to_i).map { |no| no*2 }.join("|")

当然,我可以编写一个Ruby脚本,它接受参数并使用
::调用它!my_script.rb%
,但我想直接在vim中提供Ruby代码。

您可以使用
:hs/\\=
进行匹配计算:

:s/\d\+/\=submatch(0)*2/g

Ruby有一个
-e
选项,在提供少量代码时非常有用:

:!ruby -e 'puts $_.split("|").map(&:to_i).map { |no| no*2 }.join("|") while gets'
如果您只想为一行执行代码,可以省去while循环:

当执行终端命令时,所选行作为标准输入发送到终端<代码>获取将从标准输入中读取

文件:

获取(sep=$/[,getline\u args])→ string或nil单击以切换源 获取(限制[,获取行参数])→ 字符串或零 获取(sep,limit[,getline_参数])→ 字符串或零 返回中文件列表的下一行(,并将其分配给
$。
ARGV
(或
$*
)、或标准输入(如果服务器上没有文件) 命令行。在文件末尾返回
nil
。可选的 参数指定记录分隔符。包括分离器 每个记录的内容。分隔符
nil
读取 整个内容,零长度分隔符读取输入内容 一次一段,其中段落被两个连续的 新行。如果第一个参数是整数,或者第二个参数是可选的 参数,则返回的字符串不会长于 以字节为单位的给定值。如果
ARGV
中存在多个文件名,
get(nil)
将一次读取一个文件的内容

ARGV << "testfile"
print while gets
使用
$作为隐式参数的编程风格是
逐渐失去Ruby社区的支持

您可以通过使用
-p
-n
标志来缩短上述内容,该标志将代码包装在
中,同时获取
循环:

:!ruby -ne 'puts $_.split("|").map(&:to_i).map { |no| no*2 }.join("|")'

manruby
页面:

-n使Ruby在您的
脚本,使其在文件名参数上迭代
有点像sed-n或awk。
当得到
...
结束
-p的作用与-n开关基本相同,但打印
循环每一端的变量$。例如:
%echo matz | ruby-p-e'$\ tr!“a-z”,“a-z”
马茨

谢谢,我缺少的链接是
get
方法,该方法读取光标下的当前行。您也可以使用
-p
标志和
$\u
变量来进行此操作。@Hauleth我忘记了它们,因为我不经常使用此模式。但是他们把代码缩短了很多。更新了答案。值得注意的是
作为常规命令,是一个预先填充范围的运算符。
This is line one
This is line two
This is line three
And so on...
:!ruby -ne 'puts $_.split("|").map(&:to_i).map { |no| no*2 }.join("|")'
:!ruby -pe '$_ = $_.split("|").map(&:to_i).map { |no| no*2 }.join("|")'