如何在Vim中使用v:count来切换第n行到第n行?

时间:2018-09-02 19:27:55

标签: vim keyboard-shortcuts move

我想在vim中创建一个映射,将当前行换成key('index1',@name)行之外的行。

到目前为止,我有这样的事情:

n

但是它不起作用。在这种情况下如何使用v:count变量?

1 个答案:

答案 0 :(得分:1)

映射完全按照键入的方式求值。像v:count之类的东西是Vimscript的特殊变量,因此需要以某种方式将其值插值到右侧的键中。使用映射有两种可能性:

执行

使用:execute,您可以从普通模式(由:nnoremap开始)进入Ex模式并汇编命令;您需要:normal!来运行以前仅放在右侧的普通模式命令。 Vim会自动将赋予映射的任何[count]转换为Ex范围,因此<C-u>必不可少。

nnoremap <silent> gl :<C-u>execute 'normal! yyma' . v:count1 . "jVp'aVp"<CR>

map-expr

<expr>修饰符为映射添加了一层间接作用:对右侧进行求值,仅将结果作为要运行的命令。这里的[count]也有类似的麻烦;前面的<Esc>命令将其取消(因此,您只需要拖动一行即可)。

nnoremap <expr> gl '<Esc>yyma' . v:count1 . "jVp'aVp"

您的实施情况

我假设您选择gl作为左侧,而:<C-U>是一种转义尝试,就像我第一种方法所做的那样。左侧和右侧的分隔空间也消失了,:normal也消失了。

我对实现进行了以下更改:

  • 删除并粘贴在其​​旁边会使计数复杂化;相反,我在视觉选择(Vp)上使用了粘贴功能;这会自动将删除的文本放入未命名的寄存器中(以便可以在交换的第二部分重复使用)。
  • 为了简单起见,我设置了一个标记(ma),而不是第二次使用该计数。您也许还可以使用跳转列表<C-o>)。

其他实现

对于简单的交换,您的实现可能就足够了,但这远非完美。可能希望交换多条(例如,从视觉上选择的)行,并用.在其他地方重做交换,并检查目标行是否确实存在。

unimpaired.vim插件具有交换映射[e。我的LineJuggler plugin还具有健壮且通用的实现(以及许多其他相关的实现)。