我可以用逗号(或其他字符)加入行吗?


19

我知道我可以在Vim中加入行J以及它们的几个变体(gJ,等等);J“删除缩进并最多插入两个空格”

但是,还有插入其他字符而不是两个空格的简单方法吗?例如逗号(,)或逗号和空格(,)?

鉴于:

8
9
10
32

我想结束于:

8, 9, 10, 32

要么:

8,9,10,32

您还可能喜欢github.com/sk1418/Join(未经测试)。
VanLaser

Answers:


5

我写了一个Join插件,可以做你想做的事情,还有更多。

除了内置:join命令提供的所有功能之外,Join可以:

  • 用分隔符(字符串)连接线
  • 在有或没有修剪前导/尾随空白的情况下连接线
  • 连接数为负的行(向后连接)
  • 反向连接线
  • 连接线并保持连接线(不删除连接线)
  • 用以上选项的任意组合连接线

更多详细信息和屏幕截图:

https://github.com/sk1418/加入


23

一种简单的方法是:只需选择您的行(最后一行除外)-或使用%-并运行:

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

要么

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

(当然,Vim '<,'>已经在其中插入了零件:,以定位选择)


(第二次)更新:

在上面的内容(以及Sato Katsura的评论)的基础上,这是一个可能的“交互式联接”实现,具有计数和可选的重复支持:

" ================ script ===============================================
" interactive 'J', 'gJ' replacement with optional 'vim-repeat' support
" The last used separator is automatically reused as:
" a. default choice
" b. when repeating (=> non-interactive repeats: same range, same separator)
let g:last_join_separator = " "
function! s:interactiveJoin(use_last_sep,...) range
    if (a:use_last_sep == 0) "interactive, ask for separator to use
        call inputsave()
        echohl Question
        let l:sep = input("Separator:", g:last_join_separator)
        echohl None
        call inputrestore()
        redraw!
        let g:last_join_separator = l:sep "update last separator value
    else "non-interactive (when repeating with '.')
        let l:sep = g:last_join_separator
    endif
    if (a:0 == 0) "with no argument, remove indentation *and trailing spaces*
        let l:subst = 's/\s*\n\+\s*/\=' . "'" . l:sep . "'/"
    else " don't remove indentation or trailing spaces (act like 'gJ')
        let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"
    endif
    if a:firstline < a:lastline "join given range
        execute a:firstline . ',' . (a:lastline - 1) . l:subst
        let l:count = a:lastline - a:firstline + 1 "default count for repeat
    else "or join only with next line
        execute l:subst
        let l:count = 1 "default count for repeat
    endif
    "make command repeatable
    "(with the tpope/vim-repeat plugin: optional, recommended)
    if (a:0 == 0)
        silent! call repeat#set("\<Plug>(repeatJoin)", l:count)
    else
        silent! call repeat#set("\<Plug>(repeatGJoin)", l:count)
    endif
endfunction

noremap <silent> <Plug>(interactiveJoin)  :call <SID>interactiveJoin(0)<CR>
noremap <silent> <Plug>(interactiveGJoin) :call <SID>interactiveJoin(0,'g')<CR>
noremap <silent> <Plug>(repeatJoin)       :call <SID>interactiveJoin(1)<CR>
noremap <silent> <Plug>(repeatGJoin)      :call <SID>interactiveJoin(1,'g')<CR>

并进行实际映射:

"================= vimrc ================================================
nmap J <Plug>(interactiveJoin)
xmap J <Plug>(interactiveJoin)
nmap gJ <Plug>(interactiveGJoin)
xmap gJ <Plug>(interactiveGJoin)

这有点像(*)J,但是是交互式的-它会提示您输入分隔符字符串。默认字符串是一个空格-例如,要连接不带分隔符的行,Backspace在出现提示时点击,删除默认的空格字符,并Enter接受(现在)空的分隔符。计数,例如3J,也可以。如果tpope/vim-repeat已安装插件,请以“。”重复。也可以使用,重新使用最后一个分隔符和(如果未更改,例如10.)最后一个计数或可视行范围。


(*)这不正是J,虽然:虽然它会删除缩进,也不会检查.!?(词组结束)插入2个空格,而不是一个,或插入只要缺少一个空格(这是很难做到像(因为分隔符字符串现在可以是任何东西)。它还将删除尾随空格(更有意义)。

我认为这可能是重载有限运算符字母空间的好方法:)

嗯,从技术上讲,J它不是一个运算符,而是一个运算符-例如,您不能做Jaw“一个单词”的联接。

(欢迎提出建议)

在此处输入图片说明


2
更好的是::'<,'>-1s/\n/, /对于标记的行或:1,$-1s/\n/, /整个文件。
佐藤桂2015年

确实,这甚至更好:)
VanLaser

@SatoKatsura你能解释一下-1吗?
alxndr

1
@alxndr-它用于跳过范围/文件中的最后一行:例如,在OP示例中,您不希望逗号在32后,并且您也不想将其与下一行连接(如果存在) 。你甚至可以使用'<,'>-s/\n/, /1,$-s/\n/, /作为-是一样的-1
VanLaser

1
如果l:sep&,则您的替换将无法正常工作,因为&替换中有魔术。最好使用\=来使用文字字符串let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"--而不是尝试转义。
jamessan

3

这是使用外部命令的示例:

:%!paste -sd,

其中%!,用以下命令替换当前缓冲区(文件内容):(paste -sd,参数-s用于连接多行并将-d定界符设置为,)。


3

以防万一有人不喜欢输入正则表达式并记住更多的Plugin Ex命令:

视觉障碍追加

视觉块追加是在可视块模式(可用<C-v>),并可以做一个块 PPEND(并阻止 nsert为前置)。(参考::help v_b_A:help v_b_I

并且,如果“块可视模式”中的最后一个动作是$,则将在所有选择的结尾处完成追加;否则将在您添加的文本之前插入空格(可以想象)在代码中多个方法调用的末尾对齐对齐)。

在下面的示例文本和光标上8

8
9
10
12

<C-v>}$A,<C-c>。回到正常模式后,我们可以看到,追加到所有选中的行。(不尝试$

然后gv重新选择区域和JgJ。我们有一个结尾,8,9,10,12,$x我们就大功告成了。

使用插入无拖尾 ,

让我们撤消文本(无论uu..u是花哨的还是花哨的:ea 1d<cr>:lat 1),然后尝试使用Visual Insert:

j<C-v>}I, <C-c>然后我们就可以加入行,中间gJ没有空格。

等等等等,有些东西丢失了。如何重新选择整个“数组”?这次我们没有选择第一行...所以gv没有帮助。

-否则可能会有所帮助,请gvok重新选择(gv),o将角k朝上并向上。

PS我的小指不是快速,准确,足以型/\/\n,所以我喜欢Vim的结合内建的操作和运动,以避免使用正则表达式。但是,如果我经常这样做,请使用映射-也许映射到插件的映射应该更好。


1

无需插件或外部命令即可将连接(J)从空格重新映射到您喜欢的任何字符的简单得多的方法。例如,要用逗号和空格连接:

:nmap J :s/\n/, /^M

对于末尾的特殊字符换行符(^MCtrl-V,然后按Return / Enter。如果你想用一个标签来代替同去(^I),键入Ctrl-I然后Tab

:nmap J :s/\n/^I/^M

这样做是用当前行上的选项卡替换换行符,然后将该行为重新映射到J字符。

这也可以与组合一起使用,如4J加入下4行。


0

您可以记录宏以逗号分隔行。如果这是一项罕见的任务或一次性任务,这很有用,并且您不记得如何编写替代命令和正则表达式来执行该任务,但是您确实记得如何记录和运行宏。

要用逗号连接行,请键入qjgJi,Escq以将宏记录在register中j。然后,您可以使用运行宏@j。您可以使用来重新运行宏@@,这样可以节省连续运行多次时的键入次数,甚至可以按住@直到您要加入的行的末尾为止。您还可以在上使用数字前缀@j@@将其重复设置一定的次数。这将保留前导和尾随空格,因此,如果您的原始文本中有空格,则在逗号之前或之后会有空格。

要用逗号和空格连接,请Space,和之间插入Esc在录制宏时。

您也可以在录制宏时使用,J而不是gJ在录制宏时使用,该宏通常会用逗号和空格连接行。但是,如果当前行的末尾有空格,则逗号将出现在空格之后,后面没有空格。此外,它不包括空间,如果下一行开头),如果逗号之后它把两个空间joinspaces设置,并与当前线两端.!?。这些注意事项在下描述:help J

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.