2

我知道这一定很简单。

为什么vnoremap <leader>rl di[<esc>pa]将所选文本括在括号中,但是:

vnoremap <leader>rl :call VisAddRefLink()<CR>

function! VisAddRefLink()
    execute "normal! di[\<esc>pa]"
endfunction

没有?!

任何帮助表示赞赏!

4

2 回答 2

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:firstlineanda:lastline变量,这可用于完成此操作。您也可以通过以下方式使用单个like 来完成此操作:

vnoremap <leader>rl <esc>:norm! '<^x2Phr['>$x2pr]<cr>

这首先用于<esc>结束视觉选择。然后它执行一个只会运行一次的普通命令。如果留下了视觉选择,那么它将为视觉选择中的每一行运行一次。一旦它运行一次

'<^跳转到视觉选择的第一行和该行的第一个非空白区域。

x2Phr[删除那个字符,在前面粘贴两次,向左移动,所以我们在新字符上方,并用开头替换它 [

'>$移动到视觉选择的最后一行的最后一个字符

x2pr]与以前相同,但方向相反

像往常一样,给猫剥皮的方法不止一种,尤其是使用 vimscript。随着您了解更多,您会看到很多完成事情的可能性。

于 2012-09-20T00:44:54.863 回答
2

试试这个:

vnoremap <leader>rl :<C-u>call VisAddRefLink()<CR>

function! VisAddRefLink()
    execute "normal! gvdi[\<esc>pa]"
endfunction

<C-u>前面的call避免了映射在其前面插入可视'<,'>范围;我们希望该函数只调用一次,而不是对范围内的每一行调用一次。

在函数内部,我们需要先重新建立视觉选择,然后再对其进行操作;这样gv做的。

于 2012-09-20T07:14:18.953 回答