我知道这一定很简单。
为什么vnoremap <leader>rl di[<esc>pa]
将所选文本括在括号中,但是:
vnoremap <leader>rl :call VisAddRefLink()<CR>
function! VisAddRefLink()
execute "normal! di[\<esc>pa]"
endfunction
不?!
任何帮助表示赞赏!
答案 0 :(得分:2)
您需要让您的函数处理范围。实现这一目标的一种方法是:
vnoremap <leader>rl :call VisAddRefLink()<CR>
function! VisAddRefLink() range
exe a:firstline . "normal! ^i["
exe a:lastline . "normal! $a]"
endfunction
你的例子不起作用的原因是因为exe不按照所谓的视觉选择进行操作。例如,尝试直观地选择一些内容,然后执行:norm d
。你会注意到它没有删除。如果您为函数添加范围,例如:help function-range-example
,则可以通过以类似方式(逐行)操作来帮助进行视觉选择。但是,它仍然不是真正的视觉选择。范围添加确实允许您使用a:firstline
和a:lastline
变量,这可用于实现此目的。您也可以通过以下方式完成此操作:
vnoremap <leader>rl <esc>:norm! '<^x2Phr['>$x2pr]<cr>
首先使用<esc>
结束视觉选择。然后它执行一个只运行一次的普通命令。如果保留了视觉选择,那么它将在视觉选择中为每一行运行一次。一旦它运行了
'<^
跳转到视觉选择的第一行和该行的第一个非空白区域。
x2Phr[
删除该字符,在前面粘贴两次,向左移动以便我们覆盖新角色,并将其替换为开头[
'>$
移动到视觉选择最后一行的最后一个字符
x2pr]
和以前一样,但方向相反
像往常一样,皮肤猫的方法不止一种,尤其是vimscript。随着您的了解越来越多,您会看到很多可能性来完成任务。
答案 1 :(得分:2)
试试这个:
vnoremap <leader>rl :<C-u>call VisAddRefLink()<CR>
function! VisAddRefLink()
execute "normal! gvdi[\<esc>pa]"
endfunction
<C-u>
前面的call
可以避免地图在其前面插入'<,'>
视觉范围;我们希望函数只调用一次,而不是一次调用范围内的每一行。
在功能内部,我们需要在操作前先重新建立视觉选择; gv
做到了。