A simple way is this: simply select your lines (all but the last one) - or use %
- and run:
:'<,'>s/\n/,/
or
:'<,'>s/\n/, /
(where, of course, the '<,'>
part was already inserted after :
by Vim, to target the selection)
(2nd) Update:
Building on the above (and Sato Katsura's comment), here's a possible "interactive join" implementation, with count and optional repeat support:
" ================ 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>
And an actual mapping:
"================= vimrc ================================================
nmap J <Plug>(interactiveJoin)
xmap J <Plug>(interactiveJoin)
nmap gJ <Plug>(interactiveGJoin)
xmap gJ <Plug>(interactiveGJoin)
This is kinda(*) like J
, but interactive - it will prompt for the separator string. The default string is a space - so, for example, to join lines with no separator, hit Backspace
when prompted, to remove the default space character, and Enter
to accept the (now) empty separator. Count, e.g. 3J
, also works. If tpope/vim-repeat
plugin is installed, repeating with '.' will also work, reusing the last separator and (if not changed - e.g. 10.
) the last count or visual line range.
(*) It's not exactly like J
,though: while it will remove indentation, it won't check for .!?
(end of phrase) to insert 2 spaces instead of one, or insert a space only if it's missing (it's hard to do something like this, since the separator string can be anything now). It will also remove trailing spaces (makes more sense).
I think this might be a nice way to overload the limited operators letter-space :)
Well, technically J
is not quite an operator, but close to one - for example, you can't do Jaw
, to join "a word".
(suggestions are welcome)

sed
is more or less the same as:%s/../../
?