在 vim 中,当我选择了一个垂直块(例如单列文本)时,我希望能够重复放置(粘贴)当前寄存器中的任何内容。例如,如果我有类似以下内容:
用户名0 密码0 个人信息0 用户名1 密码1 个人信息1 ... 用户名9 密码9 个人信息9
并且我选择了用户名和密码之间的文本列(即两者之间的空格列),我希望能够将内容放在那里(粘贴)。从某种意义上说,这很好:我可以放一些东西,但如果选择的长度超过寄存器,则选择的其余部分将被替换为空。相反,我希望它做一些事情,比如重复选择寄存器。除了使用正则表达式之外,还有什么方法可以做到这一点?
答案1
如果新列在每一行上都有相同的值(即,您最初复制的内容在一行上),那么可能更容易在视觉上阻止选择用户名和密码列之间的空格,然后键入A
(或I
)以开始追加(插入)。当您返回正常模式(Esc
)时,Vim 也会将文本附加到原始选择的其余部分。
如果您确实需要做重复模式,那么您可以使用这样的函数和映射:
:function! PutRegFilledToRange() range
: let l:fill = ''
: let l:lines = getreg()
: let l:lineStart = 0
: let l:linesLen = strlen(l:lines)
: let l:lineIndex = 0
: let l:linesNeeded = a:lastline - a:firstline + 1
: while l:lineIndex < l:linesNeeded
: let l:lineEnd = matchend(l:lines, "\n\\|$", l:lineStart)
: let l:line = strpart(l:lines, l:lineStart, l:lineEnd - l:lineStart)
: if l:lines[l:lineEnd - 1] != "\n"
: let l:line = l:line . "\n"
: endif
: let l:fill = l:fill . l:line
: let l:lineStart = l:lineEnd < l:linesLen ? l:lineEnd : 0
: let l:lineIndex = l:lineIndex + 1
: endwhile
:
: normal gv
: " This probably does not make much sense in any mode
: " other than block modes, but we will try to cope.
: if mode() == "\<C-V>" || mode() == "\<C-S>"
: let l:newMode = "\<C-V>"
: elseif mode() == 'v' || mode() == 's'
: let l:newMode = 'v'
: else
: let l:newMode = 'V'
: endif
: let l:origReg = getreg('')
: let l:origRegType = getregtype('')
: try
: call setreg('', l:fill, l:newMode)
: execute 'normal ' . v:count1 . 'p'
: finally
: call setreg('', l:origReg, l:origRegType)
: endtry
:endfunction
:vmap _f :call PutRegFilledToRange()<CR>
放入你的 .vimrc 或其他文件(并运行 :source /path/to/file)。或者直接将其粘贴到 Vim 会话中。
使用方法:
C-V{motion}y
:以可视方式块选择并拖拽要重复使用的文本{motion}C-V{motion}
:选择要替换的块_f
:用当前寄存器的重复行填充选定的块(用"a_f
寄存器 a 中的行填充块)