Reputation: 4947
How can I join two lines in Vim and leave the cursor in its original position instead of it jumping to the merge point?
For example, take the the following two lines with the cursor at the position indicated by the caret:
this is ^line one
this is line two
Merging by J produces:
this is line one ^this is line two
How can I produce:
this is ^line one this is line two
I have tried things like Ctrl + O and variations of ''. None of these seem to work. They go to the beginning of the line, not to the original cursor position.
Upvotes: 6
Views: 865
Reputation: 11790
Utility function that you can use for other purposes:
" Utility function that save last search and cursor position
" http://technotales.wordpress.com/2010/03/31/preserve-a-vim-function-that-keeps-your-state/
" video from vimcasts.org: http://vimcasts.org/episodes/tidying-whitespace
if !exists('*Preserve')
function! Preserve(command)
try
" Preparation: save last search, and cursor position.
let l:win_view = winsaveview()
let l:old_query = getreg('/')
silent! execute 'keepjumps ' . a:command
finally
" Clean up: restore previous search history, and cursor position
call winrestview(l:win_view)
call setreg('/', l:old_query)
endtry
endfunction
endif
The advantage of the solution using the above function is: Does not occupy any register
" Join lines without moving the cursor (gJ prevent adding spaces between lines joined)
nnoremap J :call Preserve("exec 'normal! J'")<cr>
nnoremap gJ :call Preserve("exec 'normal! gJ'")<cr>
BTW: Two more examples on how you can use the Preserve function -
" Remove extra spaces at the end of the line
fun! CleanExtraSpaces()
call Preserve('%s/\s\+$//ge')
endfun
com! Cls :call CleanExtraSpaces()
au! BufwritePre * :call CleanExtraSpaces()
" Reident the whole file
call Preserve('exec "normal! gg=G"')
Upvotes: 0
Reputation: 51593
You can do it like:
:nnoremap <F2> mbJ`b
This assigns the following actions to the F2 key:
b
mark, than it gets overwritten!)Upvotes: 4
Reputation: 40927
Another approach that wouldn't stomp on marks would be this:
:nnoremap <silent> J :let p=getpos('.')<bar>join<bar>call setpos('.', p)<cr>
Much more verbose but it prevents you from losing a mark.
:nnoremap
- Non-recursive map<silent>
- Do not echo anything when the mapping is pressedJ
- Key to map:let p=getpos('.')
- Store cursor position<bar>
- Command separator (|
for maps, see :help map_bar
)join
- The ex command for normal's J
<bar>
- ...call setpos('.', p)
- Restore cursor position<cr>
- Run the commandsUpvotes: 13