vim:加入段落中的所有行

Rem*_*man 14 vim join lines

我正在尝试使用vimscript加入段落(文本块)中的所有行,但没有成功.
我想为每个段落(文本块)执行此操作,并希望在它们之间保留空行.
(我不想使用宏)

当我使用}w命令转到下一段中的第一个单词时,我注意到它不能识别空格中的空行或者在段落之间有多个空行.那不是我想要的.

所以我试过这个:
做一个搜索:
\(^.*\S\+.*\n\)\{2,}
做:
normal vipgJ
再做上面的搜索等.

我手动操作时工作正常,但我不能把它放在脚本中.

我试过这个脚本:

function! <SID>JoinParagraphs()
let i = 1
normal gg
while i <= 200
call search("\\(^.*\\S\\+.*\\n\\)\\{2,})", "")
normal vipgJ
let i=i+1
endwhile
endfunction

不起作用......
我也尝试改变"呼叫搜索..."这一行,
let @/ = "\\(^.*\\S\\+.*\\n\\)\\{2,})"
但这样可以将所有行连接在一起(不保留空行).

我错了什么?

seh*_*ehe 25

刚刚找到这个答案

:set tw=1000000
gggqG
Run Code Online (Sandbox Code Playgroud)

哪个是绝对的赢家恕我直言.

它使用文本宽度1000000 在从(开始)到(文档结尾)的运动上执行gq.ggG


JSB*_*ոգչ 17

使用第二个匹配的字符替换所有换行符,后跟除换行符之外的其他内容:

:%s/\(\S\)\n\(\S\)/\1 \2/
Run Code Online (Sandbox Code Playgroud)

另一种方法:

:%s/\n\([^\n]\)/\1/
Run Code Online (Sandbox Code Playgroud)


小智 6

正如函数中提到的,最简单的方法是使用

贵宾J

可视化选择内段连接


seh*_*ehe 5

点击:增加了务实的方法

被低估的命令模式和 :global

更新正确的意见后修正。它仅在包含Tab-character(s)... 的纯空格行中发生。

:g#\v[^\s\t]#normal vipJ
Run Code Online (Sandbox Code Playgroud)

如何为您工作?(如果需要,可以替换vipJ-> vipgJ

更新这里是一种不使用普通模式的模式(受彼得的评论启发)

最大的好处是它可以在消极和积极意义上重用相同的模式。这样可以将其通用化为

:let @/='\v^\s*$'
:v//.,//-1 join
Run Code Online (Sandbox Code Playgroud)

现在,第二行显示了此方法的简单性(对于每一个不匹配的行,请连接到下一个匹配的行)。最好的是,您可以改用任何奇数搜索模式

当然,您可以将这一特定任务写成一行,但是它并不那么优雅:

:v#\v^\s*$#.,//-1 join
Run Code Online (Sandbox Code Playgroud)


kge*_*ter 5

从 Berkeley UNIX 开始,在 vim 出现之前就已经存在的另一种方法......如果你在 linux/unix 系统上,你可以像这样调用 fmt 命令:

:%!fmt -w 9999

这将对整个文件进行,这可能会搞砸编号列表之类的内容。您可以通过以下方式按段落完成:

!}fmt -w 9999

或者从 vi 之外的命令行执行:

$ fmt -w 9999 file.txt

我喜欢这种方法,因为我不必记得重置 textwidth=80