我知道我可以在Vim中加入行J
以及它们的几个变体(gJ
,等等);J
将“删除缩进并最多插入两个空格”。
但是,还有插入其他字符而不是两个空格的简单方法吗?例如逗号(,
)或逗号和空格(,
)?
鉴于:
8
9
10
32
我想结束于:
8, 9, 10, 32
要么:
8,9,10,32
我知道我可以在Vim中加入行J
以及它们的几个变体(gJ
,等等);J
将“删除缩进并最多插入两个空格”。
但是,还有插入其他字符而不是两个空格的简单方法吗?例如逗号(,
)或逗号和空格(,
)?
鉴于:
8
9
10
32
我想结束于:
8, 9, 10, 32
要么:
8,9,10,32
Answers:
我写了一个Join插件,可以做你想做的事情,还有更多。
除了内置:join命令提供的所有功能之外,Join可以:
- 用分隔符(字符串)连接线
- 在有或没有修剪前导/尾随空白的情况下连接线
- 连接数为负的行(向后连接)
- 反向连接线
- 连接线并保持连接线(不删除连接线)
- 用以上选项的任意组合连接线
更多详细信息和屏幕截图:
一种简单的方法是:只需选择您的行(最后一行除外)-或使用%
-并运行:
:'<,'>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
“一个单词”的联接。
(欢迎提出建议)
:'<,'>-1s/\n/, /
对于标记的行或:1,$-1s/\n/, /
整个文件。
-1
吗?
'<,'>-s/\n/, /
或1,$-s/\n/, /
作为-
是一样的-1
。
l:sep
是&
,则您的替换将无法正常工作,因为&
替换中有魔术。最好使用\=
来使用文字字符串let l:subst = 's/\n\+/\=' . "'" . l:sep . "'/"
--而不是尝试转义。
以防万一有人不喜欢输入正则表达式并记住更多的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
重新选择区域和J
或gJ
。我们有一个结尾,
: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的结合内建的操作和运动,以避免使用正则表达式。但是,如果我经常这样做,请使用映射-也许映射到插件的映射应该更好。
您可以记录宏以逗号分隔行。如果这是一项罕见的任务或一次性任务,这很有用,并且您不记得如何编写替代命令和正则表达式来执行该任务,但是您确实记得如何记录和运行宏。
要用逗号连接行,请键入qjgJi,Escq以将宏记录在register中j
。然后,您可以使用运行宏@j。您可以使用来重新运行宏@@,这样可以节省连续运行多次时的键入次数,甚至可以按住@直到您要加入的行的末尾为止。您还可以在上使用数字前缀@j或@@将其重复设置一定的次数。这将保留前导和尾随空格,因此,如果您的原始文本中有空格,则在逗号之前或之后会有空格。
要用逗号和空格连接,请Space在,和之间插入Esc在录制宏时。
您也可以在录制宏时使用,J而不是gJ在录制宏时使用,该宏通常会用逗号和空格连接行。但是,如果当前行的末尾有空格,则逗号将出现在空格之后,后面没有空格。此外,它不包括空间,如果下一行开头)
,如果逗号之后它把两个空间joinspaces
设置,并与当前线两端.
,!
或?
。这些注意事项在下描述:help J
。