在一个邮件线程中,Alice 和 Bob 都给我发了一封很长的邮件。我想发送如下回复:
alice> blah blah blah, foo dee bar dee baz, ho hum and then
alice> she said: "what do you think I am, a top poster?"
Teh lulz
bob> that's not funny
Yes it is lol :D
我希望每行的最大宽度为 n 个字符,并且我希望每行都有一个前缀“${name}>”。我不想摆弄每一行,也就是说,我想输入一些非常接近最小值 [name 1, name 2, go wrap stuff] 的内容,但无论哪种情况,输入行的长度都是 O(1)(可能长行数为 O(k),每行一行g q })。
这可能吗?如何实现?如果不可能,我怎样才能最好地近似它?
答案1
:set formatoptions+=n
一种选择是与自定义 结合使用formatlistpat
。该n
选项重新格式化编号列表,在换行时添加相同数量的空格。可以通过定义适当的列表前导符来适应这种情况:
set fo+=n
let &flp='\w\+> '
为了说明其效果,请考虑以下示例:
alice> foo bar baz qux foo bar baz qux
bob> foo bar baz qux foo bar baz qux
tw=20
在这种情况下使用,gq}产生:
alice> foo bar baz
qux foo bar
baz qux
bob> foo bar baz qux
foo bar baz qux
此方法可以正确换行而不更改tw
,但它只会添加空格。如果name>
必须在每个新行前面添加 ,则需要另一个操作,但这至少可以处理换行。
或者,这种格式的引号可以被视为comments
。不幸的是,这种方法不接受正则表达式,因此需要明确的名称。b
可以使用标志来要求注释前导后有空格:
set comments+=b:alice>,b:bob>
这样,使用与上面相同的例子,重新格式化会产生:
alice> foo bar baz
alice> qux foo bar
alice> baz qux
bob> foo bar baz qux
bob> foo bar baz qux
这是一个利用此功能的简单函数,以及为方便起见的相应命令:
function! Format(name1, name2)
execute "set comments+=b:" . a:name1 . ">,b:" . a:name2 . ">"
execute "normal gq}"
execute "set comments-=b:" . a:name1 . ">,b:" . a:name2 . ">"
endfunction
command! -nargs=* F call Format(<f-args>)
因此:F alice bob
可以用来产生上述的示例结果。
答案2
如果您拥有较新版本的 Vim ( echo v:version > 703 || v:version == 703 && has("patch541")
),那么您可以使用set formatoptions+=j
。
这告诉 Vim,当使用 重新格式化时gqq
,保留注释前导符(例如#
在大多数脚本语言中,或*
对于 javadoc 样式的注释)。
剩下要做的就是comments
正确设置:
set comments+=b:alice>,b:bob>
如前所述,comments
尚不支持正则表达式,因此您需要明确指定所有受访者的姓名。
答案3
我发现有一种非常不令人满意的方法是:
- 计算长行文本的换行宽度
- 相应地设置换行宽度(呃,
textwidth
不是吗?) - 绕行
- :'<,'>s/^/爱丽丝/
- 重复下一行
- 当所有长行完成后,将换行宽度恢复到正常。
具体来说,我很懒,不想做计算。不过,输入是 O(1) 和 O(k),所以我的需求列表显然不完整。这就是生活 :-)