如何在vim中连接多行

4
我正在使用名为vim-screen的插件,它使我能够编写脚本,在同一窗口中启动解释器并将行发送到解释器。问题是解释器不接受跨多行编写的语句。例如:这个可以工作:f:{[x] y:y+1; Z:y+1; :Z; };但这样就不行了。
f:{[x] y:y+1;
    Z:y+1;
    :Z;
 };

我该如何编写一个vim函数,以便调用来重塑行的顺序以便发送给解释器?

编辑:我尝试过编写此功能,但未取得成功。我想创建一个函数,从这样的输入(将被视觉选择)中重塑行的顺序。

F:{[a;b;r]
//ccc1
   aaa1;
aaa2;
  //ccc2
    aaa3;
};

输出类似于这样的内容F:{[a;b;r] aaa1; aaa2; aaa3; }; 所以我创建了一个赏金


这个答案或许可以帮助你:https://dev59.com/d2865IYBdhLWcg3wHKte#3983437 - albusshin
你能解释一下为什么Ingo的答案不起作用吗? - FDinoff
当我尝试在 VISUAL 模式下选择 4 行并执行 :'<,'>command! -range Invoke echomsg join(getline(1,2), '') 时没有任何反应,我应该如何调用这段代码? - statquant
这个想法是定义 :command 一次,然后调用 :'<,'>Invoke。当然,为命令本身选择更好的名称 :-) - Ingo Karkat
2个回答

6

如果你想实际修改缓冲区,可以使用J / :join 命令。如果你只是想将发送到解释器的行连接起来(但保持它们在缓冲区中分开),你可以使用 getline() 获取选定的行,然后使用 join() 命令连接它们。

以下是一个示例命令:

:command! -range Invoke echomsg join(getline(<line1>,<line2>), '')

编辑

基于此,您可以“调整”getline()返回的行列表。例如,忽略注释行:

:command! -range Invoke echomsg join(filter(getline(<line1>,<line2>), 'v:val !~# "^\\s*//"'), '')

此外,还需要删除前导空格(在单行中变得难以处理,最好现在使用函数):
:command! -range Invoke echomsg join(map(filter(getline(<line1>,<line2>), 'v:val !~# "^\\s*//"'), 'substitute(v:val, "^\\s\\+", " ", "g")'), '')

这里的 <line1><line2> 是范围的边界,而不是单独的行。我认为这可能会让 @statquant 感到困惑。 - Randy Morris
有人能给我一个调用这段代码的例子吗?我有点困惑。 - statquant
如果您的函数F:从第2行开始,以第8行的};结束,则可以使用:2,8Invoke调用它。 - Ingo Karkat
嗨Ingo,这就是目的了 :) 我们能否去掉行号,这样我就可以用视觉上选择的文本来调用它? - statquant
当您在可视模式下按下:时,Vim会自动为您插入:'<,'>。将其补充为 :'<,'>Invoke,就完成了。行号可以是数字,也可以是标记!定义:vnoremap <F5> :Invoke<CR>,您就有了一个针对可视模式的映射! - Ingo Karkat
显示剩余3条评论

0

Vimscript脚本中的标准续行符是反斜杠在下一行的开头。因此,这样写:

f:{[x] y:y+1;
  \  Z:y+1;
  \  :Z;
 \ };

应该可以工作。


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接