Vim visual block filter

vim visual block下添加自定义filter进行行处理

起因

使用flutter开发中用到插件 flutter_json_format,插件根据后台json生成bean,但是后台返回的数据带有null,所以需要bean解析的时候对null数据处理,给一个默认值.开始使用vim宏,修改效率太低,改用visual block行操作,对于尾部不齐的字段处理也很麻烦,同时该模式在IdeaVim下有bug。

filter

那有没有visual block模式下,自己处理选中文本的方案呢,带着疑问,在网上找了一圈,并没有发现什么有用的信息,但是在某个博主的文章下发现一段有意思的代码

1
:!cat -n

上述代码可以在选中块前面添加行号,那么是不是存在自己处理block的方案呢,查询vim文档 :! 相关操作,发现了 filter:

1
2
3
4
5
6
7
8
9
10
11
4.1 Filter commands					*filter*

A filter is a program that accepts text at standard input, changes it in some
way, and sends it to standard output. You can use the commands below to send
some text through a filter, so that it is replaced by the filter output.
Examples of filters are "sort", which sorts lines alphabetically, and
"indent", which formats C program files (you need a version of indent that
works like a filter; not all versions do). The 'shell' option specifies the
shell Vim uses to execute the filter command (See also the 'shelltype'
option). You can repeat filter commands with ".". Vim does not recognize a
comment (starting with '"'') after the ":!" command.

A filter is a program that accepts text at standard input, changes it in some way, and sends it to standard output.

就是这个了,使用filter处理选中行,只需要一个接收标准输入的脚本程序即可。

实现

综上,只需要自己实现一个filter program就可以了,于是用ruby写了一个cs脚本

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
#!/bin/ruby
#ideavim下对flutter bean文件的判空处理filter
#fileName: cs
if __FILE__ == $0
begin
#补全 flutter 默认生成字段 - 只处理String、int、bool
input = STDIN.read.dup
type = (ARGV[0] || 0).to_i
input.split("\n").each { |line|
if line =~ /String (.*);/
puts line.gsub!(";", " = \"\";");
elsif line =~ /int (.*);/
puts line.gsub!(";", " = 0;");
elsif line =~ /bool (.*);/
puts line.gsub!(";", " = false;");
elsif line =~ /map\['(.*)'\];/
#补全 flutter map解析,为null赋值 - 默认处理String
if type == 0
puts line.gsub!(";", " ?? \"\";");
end
if type == 1
puts line.gsub!(";", " ?? 0;");
end
if type == 2
puts line.gsub!(";", " ?? false;");
end
end
}
end
end

将该脚本放到可执行路径下,vim中 V 选中需要修改的行,按两下!,输入cs 对字段默认赋值,输入cs 1 对map解析的Integer为null时,设置默认值0.