我知道可以使用Awk,但是我在Windows系统上,并且我正在创建一个函数给那些可能没有Awk的人使用。我也知道可以写C程序,但是对于我正在制作的一个小型Vim工具而言,我希望不需要编译和维护。
原始文件可能是:
THE DAY WAS LONG
THE WAY WAS FAST
转置后应变成:
TT
HH
EE
DW
AA
YY
WW
AA
SS
LF
OA
NS
GT
更新
- 高尔夫规则适用于选择正确答案。
- Python 爱好者应该查看下面Charles Duffy的回答。
我知道可以使用Awk,但是我在Windows系统上,并且我正在创建一个函数给那些可能没有Awk的人使用。我也知道可以写C程序,但是对于我正在制作的一个小型Vim工具而言,我希望不需要编译和维护。
原始文件可能是:
THE DAY WAS LONG
THE WAY WAS FAST
转置后应变成:
TT
HH
EE
DW
AA
YY
WW
AA
SS
LF
OA
NS
GT
这是一条 Vim 语言的命令,因此您不需要编译带有 +python 支持的 Vim。
function! s:transpose()
let maxcol = 0
let lines = getline(1, line('$'))
for line in lines
let len = len(line)
if len > maxcol
let maxcol = len
endif
endfor
let newlines = []
for col in range(0, maxcol - 1)
let newline = ''
for line in lines
let line_with_extra_spaces = printf('%-'.maxcol.'s', line)
let newline .= line_with_extra_spaces[col]
endfor
call add(newlines, newline)
endfor
1,$"_d
call setline(1, newlines)
endfunction
command! TransposeBuffer call s:transpose()
将以下内容放入vim/plugin目录下新创建的.vim文件中,或者放入[._]vimrc文件中。
执行:TransposeBuffer
命令以转置当前缓冲区。
1,$"_d
不会做你想要的事情。我会将那行代码写成sil %d_
。 - ib.:1,$"_d
- 没有任何内容将被删除。您试图像普通模式命令 d
一样使用 Ex 命令 :delete
。然而,这些命令的语法和语义都是不同的!:delete
命令在命令名称之前接受一个可选范围,在命令名称之后接受一个可选的寄存器名称 (不带 "
)。您编写的是范围 1,$
,后面跟着一个注释文本 _d
(请参见 :quote
)。因此,您的命令唯一的效果是将光标移动到当前缓冲区的最后一行。 - ib.Vim内置了对多种脚本语言的支持 -- 以Python接口为例。
只需适当修改vim.current.buffer
即可完成设置。
更具体地说:
function! Rotate()
python <<EOF
import vim, itertools
max_len = max((len(n) for n in vim.current.buffer))
vim.current.buffer[:] = [
''.join(n) for n in itertools.izip(
*( n + ' ' * (max_len - len(n))
for n in vim.current.buffer))]
EOF
endfunction
max(map(len, vim.current.buffer))
代替max((len(n) for n in vim.current.buffer))
,我相信这样会更好。 - Tadeckqa
1G0
xGo<Esc>p
1G0j
xGp
q
这将为您提供一个宏,您可以对上面的示例或任何具有相同长度的2行字符串运行该宏。您只需要知道字符串的长度,以便正确地迭代操作的次数。
16@a
fu!T()
let[m,n,@s]=[0,line('$'),"lDG:pu\r``j@s"]
g/^/let m=max([m,col('$')])
exe'%norm!'.m."A \e".m.'|D'
sil1norm!@s
exe'%norm!'.n.'gJ'
endf
为了“高尔夫”,这是它的一行版本:
let[m,n,@s]=[0,line('$'),"lDG:pu\r``j@s"]|exe'g/^/let m=max([m,col("$")])'|exe'%norm!'.m."A \e".m.'|D'|exe'sil1norm!@s'|exe'%norm!'.n.'gJ'
Charles Duffy的代码可以使用izip_longest
代替izip
来缩短/改进:
function! Rotate()
:py import vim, itertools
:py vim.current.buffer[:] = [''.join(c) for c in itertools.izip_longest(*vim.current.buffer, fillvalue=" ")]
endfunction