0

Say I have a line 1234text5678, where I have selected text in visual mode. I would like to have a command <Shift>+, that moves text to the right one character and selects text again. I.e. the result should be 12345text678, and text being selected. From playing around, I got

xnoremap * dpgv=gv

but this selects 5tex after the movement. How can it be adjusted? (I don't know if this is standard, but on German keyboards <Shift>+ is the same as *.)

Then I would also like to create a similar command to move to the left, but probably I can figure that one out myself once I got the other version.

2

Choice of Mapping

I personnally like to use v_* for searching the visually selected text, similar to what n_* does in normal mode for the word under the cursor. Using v_* for shifting a visual selection sideways is in conflict with vim-visualstar which I think could actually be the default behavior of vanilla vim.

Using viwdp or with an additional movement between d and p here is good enough for me.

A typical related feature request is shifting lines up and down. Greg Hurrell has produced a screencast how to do this (youtube). However, he does not recommend it because:

it encourages bad habits ... do not mash keys ... not the vim way

I agree and would say that repeat is an anti-pattern here.

If you want such behaviour and a direct key to press, consider also following plugins and their suggestions for mappings:

Plugins and their Suggested Mappings

  • vim-move

    The default mappings use the Alt-key as prefix which does not work in all circumstances:

    <A-k>   Move current line/selection up
    <A-j>   Move current line/selection down
    <A-h>   Move current character/selection left
    <A-l>   Move current character/selection right
    
  • vim-textmanip

    xmap <C-j> <Plug>(textmanip-move-down)
    xmap <C-k> <Plug>(textmanip-move-up)
    xmap <C-h> <Plug>(textmanip-move-left)
    xmap <C-l> <Plug>(textmanip-move-right)
    

    The plugin vim-tmux-navigator uses the same set in normal mode to switch windows. This makes them a little bit inconsistent between modes.

  • vim-schlepp

    vmap <unique> <up>    <Plug>SchleppUp
    vmap <unique> <down>  <Plug>SchleppDown
    vmap <unique> <left>  <Plug>SchleppLeft
    vmap <unique> <right> <Plug>SchleppRight
    

    Some may argue arrow keys are too far away from the homerow.

Related Plugins

  • If you want to shift list items, function arguments and similar, consider the plugins sideways.vim and vim-swap. Suggested mappings by the plugin author Andrew Radev are again:

    nnoremap <c-h> :SidewaysLeft<cr>
    nnoremap <c-l> :SidewaysRight<cr>
    

    vim-swap defines following two which I think are a quite good choice:

    nmap g< <Plug>(swap-prev)
    nmap g> <Plug>(swap-next)
    
  • vim-exchange works differently by not shifting things around. I think this plugin fits better to the vim way. The mappings are

    call s:create_map('n', 'cx', '<Plug>(Exchange)')
    call s:create_map('x', 'X', '<Plug>(Exchange)')
    call s:create_map('n', 'cxx', '<Plug>(ExchangeLine)')
    

    and allows to use . if the target is addressed by the same mapping. E.g. swapping distant lines cxx, <no>G and then press . or cxiw, move and then ..

    I point the reader to the screencast by Drew Neil to see it in action.

1
xnoremap * dp`[v`]
  • dp shift right
  • `[v`] select newly pasted content.
    • :h `[ mark start of last changed or yanked text.
    • :h `] mark end of last changed or yanked text.
1

Here’s two alternative solutions:

xnoremap * dp`[1v

xnoremap * dpgvlol
  • `[ — Jump to start of pasted text
  • 1v — reselect the same amount of text as the last visual operation, but starting from the current cursor position
  • gv — reselect the same visual area as last selection,
  • lol — move visual selection right by moving the end one character to the right, and then jumping to the start and moving that one character to the right also.
  • 1
    Didn't know [count]v, thanks +1. But to be precise, it should be last visual operation instead of last selection, it's quite different. – dedowsdi May 19 at 0:06
  • Yes, I was sloppy there. I’ll correct. Thanks! – Rich May 19 at 6:27

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service, privacy policy and cookie policy

Not the answer you're looking for? Browse other questions tagged or ask your own question.