我想在Vim中创建一个宏或脚本来执行以下操作:
例如:
<html>
<head></head>
<body>
<h1>High Score Server</h1>
<table>
ROWS
</table>
</body>
</html>
会变成:
"<html> "
"<head></head> "
"<body> "
"<h1>High Score Server</h1>"
"<table> "
"ROWS "
"</table> "
"</body> "
"</html> ";
我可以通过宏来实现这一点,但是没有右侧引号的垂直对齐。任何人都可以帮我这个吗?
答案 0 :(得分:5)
我要做什么:
使用“环绕”和“对齐”插件:
1)将光标放在第一行(0,0)上,键入<C-V>)$s"
2)然后<S-V>):Align "
和<Enter>
。
没有插件的另一种解决方案:
1)设置虚拟模式
:set ve=all
2)<C-V>
进行逐块选择,光标位于0,0
3)向下翻到文本底部,然后Shift-I
,输入"
和Esc
。这应该在引号之前。
4)现在进入左端(因为ve = all,你可以去没有文字的地方)
5)<C-V>
,向下到底,输入r"
这很难解释,但很容易做和重现。在许多情况下也很有用。
答案 1 :(得分:2)
function Enquote()
let [startline, endline]=sort([line("'<"), line("'>")])
let lines=getline(startline, endline)
let lengths=map(copy(lines), 'len(split(v:val, ''\zs''))')
let maxlen=max(lengths)
call map(lines, '''"''.v:val.repeat(" ", maxlen-lengths[v:key]).''"''')
return setline(startline, lines)
endfunction
说明:
line("'<")
和line("'>")
获取上次视觉选择的开头和结尾的行号。
sort([...])
对此行号进行排序,因为您可能已经开始从所选内容中选择行。
let [a, b]=[c, d]
是并行分配:sort
将生成两个项目的排序列表,其中第一个项目小于或等于第二个项目。显然,较小的是第一个选定的行。
len(split(v:val, '\zs'))
是一个支持unicode的高级strlen()
。
max(list)
找到最大值。明显。
因此,map(copy(lines), 'len(split(v:val, ''\zs''))')
将此strlen
应用于列表中的所有项目。 copy()
是必需的,因为我们不希望修改列表。
map(lines, '''"''.v:val.repeat(" ", maxlen-lengths[v:key]).''"''')
以您需要的方式修改线条。我从printf
切换到repeat
因为printf没有正确处理多字节字符(通过«正确»我的意思是«¥»是一个字符长,而printf认为它长两个字节)。
setlines(linenumber, listoflines)
实际上修改了缓冲区。
答案 2 :(得分:1)
利用unix程序“par”来做到这一点可能很好地解决了你的问题。有一个Vimcast显示如何在http://vimcasts.org/episodes/formatting-text-with-par/
将其集成到vim中答案 3 :(得分:0)
是否可以在vim脚本中的行列表上进行两次传递?然后你可以做这样的事情(伪代码):
let N = length of longest line
for each line L:
insert a " character at the beginning
append N - len(L) spaces
append a " character
答案 4 :(得分:0)
我得到的最好的是3遍正则表达式。
在可视模式下选择块,然后使用:
:'<,'>s#^#"#
:'<,'>s#$# #
:'<,'>s#\(.\{28\}\).*#\1"
28是你最长线的长度。
答案 5 :(得分:0)
一定要注意以前的答案,让你的vim-fu成型。或者安装/修改/ poke这个插件的作者:
http://www.vim.org/scripts/script.php?script_id=4727
从插件页面:
此脚本将C ++文件中的多行文本转换为多行 字符串文字,转义引号和制表符。它也有 反向转换,取消一些字符。它不是 现在已经完成,但如果有需要,它将在某一天完成。
如果您需要进行更改,请使用源代码存储库:
答案 6 :(得分:-1)
两遍:
let l = max(map(getline("'<", "'>"), 'strwidth(v:val)'))
'<,'>s/.*/\=('"'.submatch(0).repeat(' ', l-strwidth(submatch(0)) )).'"'