0

我正在尝试映射 Ctrl-j 键以使用逗号连接两行。我的 .vimrc 文件中有以下行

:map <C-j> A<space>,<ESC>J

当我按一次 Ctrl-j 时,这工作正常

Before           After
test             test , test
test             test
test

但是当我尝试通过按“2Ctrl-j”一次加入多行时,我得到以下信息

Before           After
test             test , , test
test             test
test

我究竟做错了什么?如何将多行加入一个逗号分隔的行?我尝试用 替换<Esc><C-[>但这没有用。

另外,有没有办法参数化连接符号?例如,如果我想映射 Ctrl-k 后跟任何字符以使用指定字符连接两行,那么映射将是什么?

4

2 回答 2

2

如果您不介意使用其中一个寄存器,您可以将命令存储在寄存器中。

例如,您可以将以下内容添加到您的 vimrc

let @j = "A,\eJ"
nnoremap <C-j> @j

使用寄存器@jj存储命令。当您键入一个数字后跟,@j否则<C-j>您将运行命令 n 次,这将加入以逗号分隔的下 n 行。


将多条线连接在一起的另一种方法是使用下面的函数。

function! CustomJoinLines(delim) range
    for i in range(a:firstline, a:lastline) 
        exec "normal A" . a:delim . "\eJ"
    endfor
endfunction

此功能将使用您传入的分隔符将多行连接在一起。它还将保留J通常添加的空间。

要映射此命令,请将函数添加到您的 vimrc 和以下 nnoremaps

nnoremap <C-j> :call CustomJoinLines(" ,")<CR>
nnoremap <C-k> :call CustomJoinLines("!")<CR>
于 2013-04-24T01:46:44.857 回答
2

您的方法有缺陷,因为2<C-j>

  • 告诉 Vim 在当前行附加逗号 2 次 ( 2A<space>,)
  • 并且J不会计数,因此只工作一次(即使这样做,J也与......相同2J)。

类似的命令序列A<space>,<ESC>J也更适合宏。如果您希望您的映射使用计数,您应该在映射的右侧只使用一个命令(最好是 Ex 命令),并且如果可能的话,使用较少“行人”的方法。

这是一个更好的方法:

:nnoremap <C-j> :s/\n/ , <CR>
:xnoremap <C-j> :s/\n/ , <CR>

<C-j>使用这些映射,您可以3<C-j>在正常模式<C-j>下毫无问题地进行操作。这是 Vim 在上述三个场景中所做的:

  • 正常模式<C-j>将 EOL 替换,为当前行

    :s/\n/ , <CR>
    
  • 正常模式用这一行和下面的两个3<C-j>替换 EOL,

    :.,.+2s/\n/ , <CR>
    
  • 视觉模式<C-j>将 EOL 替换,为视觉选择中的每一行

    :'<,'>s/\n/ , <CR>
    

如您所见,使用 Ex 命令会自动插入正确的范围,并使您的映射更加可预测。

编辑

基本上,当您在 Ex 命令之前使用计数或在可视模式下发出 Ex 命令时,Vim 会自动在命令本身之前插入与该计数或可视选择相对应的范围,以节省您的打字时间。

3<C-j>

做:

3:s/\n/ , 

转换为:

:.             " from this line
:.,            " to
:.,.+2         " two lines below this line
:.,.+2s/\n/ ,  " do this substitution
于 2013-04-24T05:36:57.047 回答